!------------------------------------------------------------------------------
!        IST/MARETEC, Water Modelling Group, Mohid modelling system
!------------------------------------------------------------------------------
!
! TITLE         : Mohid Hydrodynamic
! PROJECT       : Mohid Water
! MODULE        : ModuleHydrodynamic
! URL           : http://www.mohid.com
! AFFILIATION   : IST/MARETEC, Marine Modelling Group
! DATE          : Jun 2003
! REVISION      : Paulo Leitão - v4.0
! DESCRIPTION   : Module responsbile for computing non-turbulent hydrodynamic processes
!
!------------------------------------------------------------------------------
!
! Use this for the occasional introduction to a long file.
!

!-------------------------------------------------------------------------
!        IST/MARETEC, Marine Modelling Group, Mohid2000 modelling system
!-------------------------------------------------------------------------
!BOI
! !TITLE: Mohid2000 hydrodynamic model 
! !AUTHORS: Paulo Chambel
! !AFFILIATION: IST/MARETEC, Marine Modelling Group
! !DATE: 15Nov2000
! !INTRODUCTION: General description of the hydrodynamic model
!  The hydrodynamic class solves the three-dimensional primitive 
!  equations in Cartesian coordinates for incompressible flows. 
!  Hydrostatic equilibrium is assumed as well as Boussinesq Objroximation.  
!  The mass and momentum evolution equations solve by the model are:
!  $$
!   \frac{\partial \int dV}{\partial t}=\oint 
!   \overrightarrow{F}_{Water}\cdot d\overrightarrow{n}
!  $$
!  $$
!   \frac{\partial \int \overrightarrow{\text{v}}dV}
!   {\partial t}= \oint 
!   \overrightarrow{\text{v}}\left( \overrightarrow
!   {\text{v}}+v\nabla \cdot 
!   \overrightarrow{\text{v}}\right) \cdot 
!   d\overrightarrow{n}-\nabla \eta \int
!   dV-\frac 1\rho \stackunder{\eta +z}
!   {\nabla \cdot \stackrel{\eta }{\int }\rho
!   dz}\cdot \int dV
!  $$
!  $$
!  \nabla =\left( \frac \partial {\partial x},\frac 
!  \partial {\partial y}\right) 
!  $$
!
!EOI
!-------------------------------------------------------------------------


Module ModuleHydrodynamic
!-------------------------------------------------------------------------
!        IST/MARETEC, Marine Modelling Group, Mohid2000 modelling system
!-------------------------------------------------------------------------

!BOP
!
! !MODULE: ModuleHydrodynamic

!    !DESCRIPTION: 
!     This model is responsible for all hydrodynamic properties:
!     Water level, velocites, water fluxes
 
! !REVISION HISTORY: 
!   1Jan2000   Paulo Chambel       First experimental version.
!  16Nov2000   Paulo Chambel       Comments are introduce in the Protex format 
!                                  to produce a manual
!  21Dec2000   Frank Braunschweig  Writes Velocity Modulus to HDF file
!
! !FILES USED:   
!  'nomfich.dat' file is where the name files are given .
!  The keywords relevant for the hydrodynamic model are:
!    IN_DAD3D : input file  
!    OUT_DESF : output file 
!    IN_CNDI  : restart file  
!    OUT_FIN  : final output use to restart the model
!              
!
! !SEE ALSO:    
!  http://194.65.82.103/manuais/default.htm     
!

! !USES:
    use ModuleGlobalData
    use ModuleFunctions         
    use ModuleTime              
    use ModuleEnterData           
    use ModuleGridData,         only : GetGridData, UngetGridData 
    use ModuleProfile,          only : StartProfile, WriteProfile, KillProfile
    use ModuleDischarges,       only : Construct_Discharges, GetDischargesNumber,        &
                                       GetDischargesGridLocalization,                    &
                                       GetDischargeWaterFlow, GetDischargeFlowVelocity,  &
                                       Kill_Discharges
    use ModuleTimeSerie,        only : StartTimeSerie, WriteTimeSerie, KillTimeSerie         
    use ModuleHorizontalMap,    only : GetWaterPoints2D, GetBoundaries, GetBoundaryFaces,&
                                       GetExteriorBoundaryFaces, UnGetHorizontalMap
    use ModuleHorizontalGrid,   only : WriteHorizontalGrid, GetComputeZUV,               &
                                       GetCoriolisFrequency, GetHorizontalGrid,          &
                                       InterpolRegularGrid, UnGetHorizontalGrid,         &
                                       GetGridCoordType, GetCoordTypeList, GetGridOrigin,&
                                       GetGridLatitudeLongitude, GetHorizontalGridSize,  &
                                       GetCheckDistortion, GetGridRotation, GetGridAngle,&
                                       RotateVectorFieldToGrid
    use ModuleGeometry,         only : GetGeometrySize, GetGeometryWaterColumn,          &
                                       GetGeometryDistances, GetGeometryKFloor,          &
                                       GetGeometryMinWaterColumn, UnGetGeometry,         &
                                       ReadGeometry, ComputeInitialGeometry,             &
                                       ComputeVerticalGeometry, WriteGeometry,           &
                                       GetGeometryVolumes, GetGeometryAreas
    use ModuleMap,              only : GetWaterPoints3D, GetOpenPoints3D,                &
                                       GetComputeFaces3D, GetImposedTangentialFaces,     &
                                       GetImposedNormalFaces, UnGetMap,                  &
                                       UpdateComputeFaces3D, SetComputesFaces3D,         &
                                       GetLandBoundaryFaces3D         
    use ModuleBoxDif,           only : StartBoxDif, GetBoxes, BoxDif, UngetBoxDif,       &
                                       KillBoxDif
    use ModuleOpenBoundary,     only : ConstructOpenBoundary, Modify_OpenBoundary,       &
                                       GetAverageImposedElevation, GetImposedElevation,  &
                                       UnGetOpenBoundary, GetOldImposedElevation,        &
                                       GetOpenBoundParameter, GetImposedVelocity,        &
                                       GetBoundaryReferenceLevel, KillOpenBoundary
    use ModuleTurbulence,       only : GetContinuousGOTM, GetMLD_Surf, UnGetTurbulence,  &
                                       GetHorizontalViscosity, GetVerticalViscosity   
    use ModuleHydrodynamicFile, only : StartHydrodynamicFile, GetHydrodynamicFileIOState,&
                                       ModifyHydrodynamicFile, GetFileWaterLevel,        &
                                       GetFileFluxes, GetFileMapping,                    &
                                       UnGetHydrodynamicFile, KillHydrodynamicFile

    use ModuleAssimilation,     only : StartAssimilation, GetAssimilationField,          &
                                       GetAssimilationCoef, UnGetAssimilation,           &
                                       KillAssimilation, GetAssimilationAltimetry,       &
                                       GetAssimilationAltimetryDT, GetAltimetryDecayTime
    use ModuleStopWatch,        only : StartWatch, StopWatch         
    use ModuleStatistic,        only : ConstructStatistic, GetStatisticMethod,           &
                                       GetStatisticParameters, GetStatisticLayersNumber, &
                                       GetStatisticLayerDef, ModifyStatistic,            &
                                       AddStatisticLayers, KillStatistic         
    use ModuleHDF5       
#ifndef _WAVES_
    use ModuleWaves,            only : GetWavesStress, UnGetWaves       
#endif
    use ModuleFillMatrix,       only : ConstructFillMatrix, ModifyFillMatrix, KillFillMatrix

    implicit none 

    private

!   !PUBLIC SUBROUTINES

    !Constructor
        !  StartHydrodynamic
    !Modifier
        !  Modify_Hydrodynamic
    !Selector 
        !  GetWaterFluxes
        !  GetHorizontalVelocity
        !  GetOldHorizontalVelocity
        !  GetVerticalVelocity
        !  GetWaterLevel
        !  GetChezy
        !  GetDirection
        !  GetHydrodynamicSource
        !  GetDischargesFluxes
        !  GetPointDischargesState
        !  UngetHydrodynamic
    !Destructor
        !  KillHydrodynamic

    !PUBLIC TYPES: 
        !  T_Hydrodynamic

 !EOP

    !subroutines tree---------------------------------------------------------------



    !Should be transfer for a Bottom boundary module 
    private :: Bottom_Boundary
    private :: Modify_ChezyZ
    private :: Modify_ChezyVelUV


    !Constructor
    public  :: StartHydrodynamic
    private ::      Construct_Hydrodynamic
    private ::          Construct_HydrodynamicTime
    private ::          Read_Hydrodynamic_Files_Name
    private ::          Construct_Numerical_Options
    private ::          Verify_Numerical_Options
    private ::          Actualize_HydrodynamicTimeStep
    private ::          InitialHydrodynamicField
    private ::          StartOutputBoxFluxes
    private ::          AllocateVariables
    private ::          Construct_Sub_Modules
    private ::          Construct_OutPutTime
    private ::          Construct_Time_Serie
    private ::          ConstructMatrixesOutput
    private ::          ConstructHydrodynamicProperties
    private ::              Read_Final_Hydrodynamic_File
    private ::          ReadInitialImposedSolution
    private ::          Initial_Geometry

    private ::          InitialReferenceWaterFluxes
    private ::          Open_HDF5_OutPut_File
    private ::          ConstructEnergy
    private ::          ConstructTidePotential

    private ::          ConstructRelaxation
    private ::          ConstructHydroStatistic

    private ::      CourantGH
    private ::          F_Courant                   !Function
    private ::          OutputCourant
 
    !Modifier
    public  :: Modify_Hydrodynamic
    private ::      Actualises_Hydrodynamic
    private ::      CalcNewDT

    private ::      One_Iteration
    private ::      MomentumMassConservation
    private ::          ReadImposedSolution            
    private ::          Abbott_Scheme
    private ::          Leendertse_Scheme
    private ::              ChangeDirection
    private ::                  AssociateDirectionX
    private ::                  AssociateDirectionY
    private ::              Explicit_Forces
    private ::                  Modify_Horizontal_Transport
    private ::                      Modify_Advection_UX_VY
    private ::                      Modify_Advection_UY_VX
    private ::                      Modify_Advection_Bound
    private ::                          Modify_UX_VY_Boundary
    private ::                          Modify_UY_VX_Boundary
    private ::                          Modify_UX_VY_SubModel
    private ::                          Modify_UY_VX_SubModel
    private ::                      Modify_Diffusion_UX_VY
    private ::                      Modify_Diffusion_UY_VX
    private ::                      ModifyDiffSub_UX_VY
    private ::                      ModifyDiffSub_UY_VX
    private ::                      ModifyVolumeVariation
    private ::                      ModifyMomentumDischarge
    private ::                  ModifyRelaxHorizAdv
    private ::                  Modify_InertiaForces
    private ::                  Modify_ROX3
    private ::                  ModifyTidePotential
    private ::                  ModifyRelaxAceleration
    private ::              VerticalMomentum
    private ::              NonHydroStaticCorrection
    private ::                  NonHydroCorrectionBoundary

    private ::          ReadHydrodynamicFile
    !private ::          ModifyBackgroundVelocity

    private ::              Compute_Velocity
    private ::                  Velocity_ExplicitForces
    private ::                  Velocity_VerticalAdvection
    private ::                  Velocity_VerticalDiffusion
    private ::                  VelVerticalDiffusionBoundaries
    private ::                  Velocity_OpenBoundary
    private ::                      Compute_BaroclinicHorVelocity
    private ::                      VelTangentialOpenBoundary
    private ::                      VelNormalOpenBoundary
    private ::                      VelSubModelNormalOB 
    private ::                      VelSubModelTangentialOB 
    private ::                      CyclicBoundVectTangential
    private ::                      CyclicBoundVectNormal
    private ::                      CyclicBoundVertical
    private ::                  Modify_Implicit_UX_VY

    private ::              Compute_WaterLevel
    private ::                  WaterLevel_BarotropicPressure
    private ::                  WaterLevel_BottomFriction
    private ::                  WaterLevel_ExplicitForces
    private ::                  WaterLevel_WaterFluxes
    private ::                  WaterLevel_OpenBoundary
    private ::                      WaterLevel_ImposedWave
    private ::                      WaterLevel_FlatherWindWave
    private ::                      WaterLevel_FlatherLocalSolution
    private ::                      WaterLevel_BlumbergKantha
    private ::                  WaterLevelDischarges
    private ::                  WaterLevelRelaxation
    private ::                  WaterLevelRelaxationAltimetry   ! nogueira e guillaume
    private ::                  WaterLevelCorrection

    private ::                  Waterlevel_CyclicBoundary
    private ::                      CyclicCoef2D

    private ::              Modify_HorizontalWaterFlow

    private ::          New_Geometry
    private ::          New_VerticalHydrodynamic
    private ::              Modify_VerticalWaterFlow
    private ::              Filter_3D_Fluxes
    private ::              Compute_VerticalVelocity
    private ::              ComputeCartesianVertVelocity  
    private ::              ComputeCartesianNH
    private ::              Boundary_VerticalFlow
    private ::                  ComputeBaroclinicVertVelocity  
    private ::                  Compute_BoundaryVertFlux

    private ::          ModifyWaterDischarges

    private ::      ComputeResidualFlowProperties
    private ::      ComputeSystemEnergy
    private ::          WriteEnergyDataFile
    private ::      Hydrodynamic_OutPut
    private ::          Write_HDF5_Format
    private ::              CenterVelocity
    private ::              Statistics_OutPut
    private ::          OutPut_TimeSeries
    private ::          ModifyMatrixesOutput


    !private ::         ASCII_Format
    
    !Selector 
    public  :: GetWaterFluxes
    public  :: GetHorizontalVelocity
    public  :: GetOldHorizontalVelocity
    public  :: GetVerticalVelocity
    public  :: GetWaterLevel
    public  :: GetChezy
    public  :: GetHydrodynamicAirOptions
    public  :: GetDirection
    public  :: GetHydrodynamicSource
    public  :: GetDischargesFluxes
    public  :: GetPointDischargesState
    public  :: GetHydroNeedsFather 
    public  :: GetWavesStressON
    public  :: GetHydroAltimAssim    ! guillaume nogueira
    public  :: GetVertical1D
    
    public  :: SetHydroFather
    private ::      ConstructTimeInterpolation
    private ::      TestSubModelOptionsConsistence
    private ::      ReadNextOrInitialField
    private ::          ReadLockFather
    private ::          ReadUnLockFather
    private ::      ActualizeSubModelValues
    private ::      ActualizeSon3DWithFather2D
    private ::          RemoveLowerSpikes
    private ::          ReadLockSon
    private ::          ReadUnLockSon
    public  :: SetHydrodynamicManning
    public  :: SetHydrodynamicChezy
    public  :: SetHydrodynamicRugosityMatrix
    public  :: SetSurfaceWaterFlux
    public  :: SetBottomWaterFlux
    public  :: SetWindStress
    public  :: SetAtmosphericPressure
    public  :: SetWaveChezyVel

    public  :: UngetHydrodynamic


    !Destructor
    public  :: KillHydrodynamic
    private ::      KillHydroStatistics
    private ::      Write_Final_Hydrodynamic_File
    private ::      Deassociate_External_Modules               
    private ::      Kill_Sub_Modules
    private ::          KillEnergy
    private ::          KillTidePotential
    private ::          KillSubModel
    private ::      DeallocateVariables 
    private ::          KillMatrixesOutput


    !Management
    private :: ReadLock_External_Modules
    private ::      ReadLock_ModuleHorizontalGrid 
    private ::      ReadLock_ModuleHorizontalMap 
    private ::      ReadLock_ModuleGeometry 
    private ::      ReadLock_ModuleMap 
    private :: ReadLock_ModuleTurbulence
#ifndef _WAVES_
    private :: ReadLock_ModuleWaves
#endif
    private ::          Read_Lock

    private :: ReadUnLock_External_Modules
    private ::      ReadUnLock_ModuleHorizontalGrid 
    private ::      ReadUnLock_ModuleHorizontalMap 
    private ::      ReadUnLock_ModuleGeometry 
    private ::      ReadUnLock_ModuleMap 
    private :: ReadUnLock_ModuleTurbulence
#ifndef _WAVES_
    private :: ReadUnLock_ModuleWaves
#endif
    private ::          Read_UnLock

    !Functions
    private :: TangentialVelInterpolation
    private :: spythag
    private :: dpythag
    private :: Locate_Layer
    private :: Face_Interpolation
    private :: FrictionCoefficient
    private :: Face_Velocity_Modulus


    !Interfaces----------------------------------------------------------------

    private :: UngetHydrodynamic2Dreal4
    private :: UngetHydrodynamic2Dreal8
    private :: UngetHydrodynamic3Dreal4
    private :: UngetHydrodynamic3Dreal8
    interface  UngetHydrodynamic
        module procedure UngetHydrodynamic2Dreal4
        module procedure UngetHydrodynamic2Dreal8
        module procedure UngetHydrodynamic3Dreal4
        module procedure UngetHydrodynamic3Dreal8
    end interface UngetHydrodynamic

    private :: pythag
    interface  pythag
        module procedure spythag
        module procedure dpythag
    end interface pythag

    private :: HydroPropAssimilation3D
    private :: HydroPropAssimilation2D

    private HydroPropAssimilation
    interface  HydroPropAssimilation
        module procedure HydroPropAssimilation3D
        module procedure HydroPropAssimilation2D
    end interface HydroPropAssimilation

#ifdef _USE_MPI
    public  :: SendHydrodynamicMPI
    public  :: RecvHydrodynamicMPI
    public  :: UpdateHydroMPI
    include "mpif.f90"
#endif

    !ModuleHydrodynamic parameters---------------------------------------------------------------------------


    !Direction
    integer, parameter :: DirectionX_      = 1
    integer, parameter :: DirectionY_      = 2
    integer, parameter :: DirectionXY_     = 3
    integer, parameter :: WestSouth        = 1
    integer, parameter :: EastNorth        = 2


    !Numeric Options
    integer, parameter :: UpWind_Scheme   = 1
    integer, parameter :: Quick_Scheme    = 2

    !Parameters
    character(LEN = StringLength), parameter :: Char_Upwind_Scheme          = trim(adjustl('Upwind'               ))
    character(LEN = StringLength), parameter :: Char_Quick_Scheme           = trim(adjustl('Quick'                ))


    real,    parameter :: Abbott          = 1.
    real,    parameter :: Leendertse      = 2.

    integer, parameter :: CurrentVelocity    = 0
    integer, parameter :: ResidualVelocity   = 1
    integer, parameter :: ResidualFlux       = 2
    integer, parameter :: ResidualFluxVel    = 3
    integer, parameter :: BaroclinicVelocity = 4

    integer, parameter :: Solve_Equations_       = 1
    integer, parameter :: Read_File_             = 2
    integer, parameter :: No_hydrodynamic_       = 3
    integer, parameter :: Residual_hydrodynamic_ = 4
    integer, parameter :: Run_Off_               = 5
    integer, parameter :: ImposedSolution_       = 6
    !Guillaume
    integer, parameter :: Vertical1D_            = 7

    !Parameters
    character(LEN = StringLength), parameter :: Char_Solve_Equations        = trim(adjustl('Solve_Equations'      ))
    character(LEN = StringLength), parameter :: Char_Read_File              = trim(adjustl('Read_File'            ))
    character(LEN = StringLength), parameter :: Char_No_hydrodynamic        = trim(adjustl('No_hydrodynamic'      ))
    character(LEN = StringLength), parameter :: Char_Residual_hydrodynamic  = trim(adjustl('Residual_hydrodynamic'))
    character(LEN = StringLength), parameter :: Char_Run_Off                = trim(adjustl('Run_Off'              ))
    character(LEN = StringLength), parameter :: Char_ImposedSolution        = trim(adjustl('Imposed Solution'     ))
    character(LEN = StringLength), parameter :: Char_Vertical1D             = trim(adjustl('Vertical1D'          ))



    integer, parameter :: NULL_VALUE           = 1
    integer, parameter :: NULL_GRADIENT        = 2

    !Input / Output
    integer, parameter :: FileOpen = 1, FileClose = 0
    integer, parameter :: EnergyBufferSize        = 1000

    !Geometry
    integer, parameter :: Fix         = 1
    integer, parameter :: Variable    = 2



    !Boxes
    real,    parameter :: Boxes_MinDepth = 0.0

    !Water
    character(5), parameter :: Char_Water = 'water'

    !Internal Waves Celerity 
    integer, parameter :: Orlanski_    = 0
    integer, parameter :: Constant_    = 1
    integer, parameter :: OeyAndChen_  = 2

    !Maximum internal wave velocity allowed is 10 m/s.
    real,    parameter :: MaxInternalCelerity = 10. 

    !Internal waves radiation
    integer, parameter :: NoRadiation_ = 0
    integer, parameter :: Horizontal_  = 1
    integer, parameter :: Vertical_    = 2


    !Barotropic boundary radiation conditions
    integer, parameter :: FlatherWindWave_      = 1
    integer, parameter :: FlatherLocalSolution_ = 2
    integer, parameter :: BlumbergKantha_       = 3

    !Local solution type
    integer, parameter :: NoLocalSolution_      = 1
    integer, parameter :: Submodel_             = 2
    integer, parameter :: AssimilationField_    = 3
    integer, parameter :: Gauge_                = 4
    integer, parameter :: AssimilaPlusSubModel_ = 5

    !Baroclinic open boundary conditio discretization options
    integer, parameter :: Explicit_  = 1
    integer, parameter :: Implicit_  = 2
    integer, parameter :: StoreWave_ = 3


    ! Velocity use in the process of relaxation 
    integer, parameter :: TotalVel_    = 1
    integer, parameter :: BarotrVel_   = 2
    integer, parameter :: BaroclVel_   = 3

    ! Wind forcing type
    integer, parameter :: NoWind_           = 0
    integer, parameter :: WithWind_         = 1
    integer, parameter :: InitialSmoothWind_= 2

    !Tidal components use to compute the tide potential effect
    integer, parameter     :: M2=1, S2=2, K2=3, N2=4, K1=5, O1=6, P1=7, Q1=8, Ssa = 9,   &
                              Mm =10, Mf = 11 

    !Ways of computing the tide potential phase of each constituint using the doodson numbers
    integer, parameter     :: Kantha = 1, Lefevre=2


    !Types---------------------------------------------------------------------

    private :: T_State
    type       T_State
        logical :: BOXFLUXES  = OFF         !Calculates fluxes among boxes, concentracions, etc.
        logical :: SURFACE    = OFF 
        logical :: Initial    = OFF         
    end type T_State


    private :: T_Direction
    type       T_Direction
        integer  :: XY, YX
        integer  :: di   
        integer  :: dj
    end type       T_Direction

    private :: T_Files
    type       T_Files
         character(len=PathLength) :: InitialHydrodynamic
         character(len=PathLength) :: FinalHydrodynamic
         character(len=PathLength) :: OutPutFields
         character(len=PathLength) :: ConstructData
         character(len=PathLength) :: BoxFluxesFileName
         character(len=PathLength) :: Energy
    end type T_Files

    !NonHydrostatic
    private :: T_NonHydrostatic
    type T_NonHydrostatic
        real, dimension (:, :, :), pointer :: PressureCorrect, PrevisionalQ
        real, dimension (:, :, :), pointer :: CCoef, GCoef
        logical                            :: ON
        real                               :: ThetaU, ThetaV, ThetaUV, ThetaW
        real                               :: Residual = 1.e-6
        logical                            :: NormalizedResidual = .false.
        real                               :: alphaLU = 0.5
        integer                            :: MaxIt = 500
    end type T_NonHydrostatic

    private :: T_WaterLevel
    type T_WaterLevel
        type(T_PropertyID)              :: ID
        real, dimension (:, :), pointer :: New
        real, dimension (:, :), pointer :: Old
        real, dimension (:, :), pointer :: VolumeCreated
        real                            :: DT
        real                            :: Default
    end type T_WaterLevel

    private :: T_Vel_UV
    type T_Vel_UV    
        type(T_PropertyID)                 :: ID
        real, dimension (:, :, :), pointer :: New
        real, dimension (:, :, :), pointer :: Old
        real                               :: Default
        integer                            :: InTypeZUV
    end type T_Vel_UV 

    private :: T_Horizontal
    type T_Horizontal
        type(T_Vel_UV)   ::   U
        type(T_Vel_UV)   ::   V
        type(T_Vel_UV)   ::   UV
        type(T_Vel_UV)   ::   VU
    end type T_Horizontal

    private :: T_Vertical
    type T_Vertical
        real, dimension (:, :, :), pointer :: Cartesian
        real, dimension (:, :, :), pointer :: CartesianOld
        real, dimension (:, :, :), pointer :: Across
    end type T_Vertical

    private :: T_Velocity
    type T_Velocity
        type (T_Horizontal)  :: Horizontal
        type (T_Vertical)    :: Vertical
        real                 :: DT
    end type T_Velocity

    private :: T_WaterFluxes
    type T_WaterFluxes
        real(8), dimension(:,:,:), pointer     :: X, Y, Z
        real(8), dimension(:,:,:), pointer     :: XY, YX
        real(8), dimension(:,:,:), pointer     :: Discharges
        real                                   :: New_Old
    end type T_WaterFluxes

    private :: T_Residual
    type T_Residual
        real                                :: ResidualTime
        real, dimension(:,:),   pointer     :: WaterLevel
        real, dimension(:,:,:), pointer     :: Velocity_U, Velocity_V, Vertical_Velocity
        real, dimension(:,:,:), pointer     :: DWZ
        real(8), dimension(:,:,:), pointer  :: WaterFlux_X, WaterFlux_Y
    end type T_Residual



    private :: T_Forces
    type T_Forces
        real,    dimension (:, :, :), pointer :: Rox3XY, Rox3X, Rox3Y ! Baroclinic
        real(8), dimension (:, :, :), pointer :: Horizontal_Transport
        real,    dimension (:, :, :), pointer :: Inertial_Aceleration
        real,    dimension (:, :, :), pointer :: Relax_Aceleration
        real,    dimension (:, :, :), pointer :: ObstacleDrag_Aceleration
        real,    dimension (:,:),     pointer :: TidePotentialLevel
    end type T_Forces

    private :: T_HorAdvection
    type T_HorAdvection

        real :: Coef1_Up
        real :: Coef2_Up
        real :: Coef3_Up

    end type T_HorAdvection

    private :: T_Coef_1D
    type T_Coef_1D
        real,    dimension (:), pointer :: a, c, r, x, u, z
        real(8), dimension (:), pointer :: b, bb, gam
    end type T_Coef_1D


    private :: T_Coef_2D
    type T_Coef_2D
        real,    dimension (:, :), pointer :: D, F, Ti, Rad, TiRad
        real(8), dimension (:, :), pointer :: E
    end type T_Coef_2D


    private :: T_Coef_3D
    type T_Coef_3D
        real,    dimension (:, :, :), pointer :: D, F, Ti
        real(8), dimension (:, :, :), pointer :: E
    end type T_Coef_3D

    private :: T_Coef_Baroc
    type T_Coef_Baroc

        Integer, dimension( : ), pointer   :: Kleft,Kright

        Real(8), dimension( : ), pointer   :: Depth_integ, Hcenter, Hleft,&
                                              Hright, HroLeft, HroRight, DensRight, DensLeft
    end type T_Coef_Baroc

    private :: T_InstantBound
    type T_InstantBound

        type (T_Time)                  :: TimeB  
        real                           :: BaroclVel
        type (T_InstantBound), pointer :: Next, Prev

    end type T_InstantBound


    private :: T_Imposed
    type T_Imposed

        integer                        :: Number
        real                           :: DTInterval
        type (T_InstantBound), pointer :: FirstInstant, LastInstant

    end type T_Imposed

    private :: T_VelBaroclinic
    type T_VelBaroclinic

        type(T_Vel_UV)   ::   U
        type(T_Vel_UV)   ::   V
        type(T_Vel_UV)   ::   UV
        type(T_Vel_UV)   ::   VU
        !This velocity is compute for the cartesian referential
        real, dimension (:, :, :), pointer :: W_New, W_Old

        real, dimension (:, :   ), pointer :: U2D, V2D, UV2D

        type (T_Imposed), dimension(:), pointer :: ImposedNormX, ImposedNormY, ImposedNormXY
        type (T_Imposed), dimension(:), pointer :: ImposedTangX, ImposedTangY, ImposedTangXY


        integer :: CelerityType
        real    :: InternalCelerity
        real    :: TRelaxOut, TRelaxIn
        real    :: MinLeavingBaroclincVel
        logical :: BaroclinicNormalRadiation
        integer :: BaroclinicOBCDiscret
        logical :: StoreBaroclinicWave

        real    :: DTWave


    end type T_VelBaroclinic

    private :: T_Coefficients
    type T_Coefficients
        type(T_Coef_1D)                    :: D1
        type(T_Coef_2D)                    :: D2
        type(T_Coef_3D)                    :: D3
        type(T_Coef_Baroc)                 :: Baroc
    end type T_Coefficients


    private :: T_External
    type T_External
        !Horizontal Mapping

        !Boundary faces : boundary point in one side and a interior point in another
        integer, dimension(:,:),   pointer :: BoundaryFacesUV, BoundaryFacesVU, BoundaryFacesU, &
                                              BoundaryFacesV, BoundaryPoints, WaterPoints2D

        !3D Mapping

        !Compute faces. Faces where is possible to compute a velocity
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_U, ComputeFaces3D_V, ComputeFaces3D_UV, ComputeFaces3D_VU,   &
!                                              WaterPoints3D, UnCoveredFaces3D_U, UnCoveredFaces3D_V, UnCoveredFaces3D_UV, &
                                              WaterPoints3D, ComputeFaces3D_W, OpenPoints3D !Flavio


        !Land Water faces. Faces that have a land point in one side and a interior point in another
        integer, dimension(:,:,:), pointer :: LandBoundaryFacesUV, LandBoundaryFacesVU, LandBoundaryFacesU, LandBoundaryFacesV


        !Imposed faces  : faces where the model do not compute velocites 
        !                 but need to imposed values to define the 
        !                 the velocities boundary condition
        integer, dimension(:,:,:),   pointer :: ImposedNormalFacesUV    , ImposedNormalFacesU    , ImposedNormalFacesV
        integer, dimension(:,:,:),   pointer :: ImposedTangentialFacesU , ImposedTangentialFacesV, &
                                                ImposedTangentialFacesUV, ImposedTangentialFacesVU         



        !Horizontal Grid
        !DUX - distance between the West face and the East face of a cell along the center cell
        !DVY - distance between the South face and the North face of a cell along the center cell
        !DZX - distance between the cell center and the center of the West cell (X direction)
        !DZY - distance between the cell center and the center of the South cell (Y direction)
        !DYY - width of the West face of a cell 
        !DXX - width of the South face of a cell 
        real,    dimension(:,:  ), pointer :: DUX, DVY, DZX, DZY, DYY, DXX
        !Auxiliar pointers
        real,    dimension(:,:  ), pointer :: DUX_VY, DZX_ZY, DZY_ZX, DYY_XX, DXX_YY, DVY_UX

        real,    dimension(:, :),  pointer :: Coriolis_Freq, RotationX, RotationY
        logical                            :: Distortion
        real                               :: GridRotation
        
        !3D Geometry 

        !Volume_Z_New - Last compute control volume of the water level compute point, 
        !               basically is the volume of our grid
        !Volume_Z_Old - Previous compute control volume of the water level compute point
        !Volume_U     - Last compute control volume of the velocity U compute point
        !Volume_V     - Last compute control volume of the velocity V compute point
        !Volume_W     - Last compute control volume of the velocity W compute point
        !Area_U       - Area of the grid cell West face
        !Area_V       - Area of the grid cell South face
        !DWZ          - Thickness of the cell grid
        real(8), dimension(:,:,:), pointer :: Volume_Z_Old, Volume_Z_New, Volume_U, Volume_V, Volume_W
        real,    dimension(:,:,:), pointer :: Area_U, Area_V, DWZ, SZZ, DUZ, DVZ, DUZ_VZ, DZZ
        real,    dimension(:,:),   pointer :: WaterColumn, WaterColumnU, WaterColumnV, WaterColumnUV, WaterColumnVU

        
        !Auxiliar
        real(8), dimension(:,:,:), pointer :: Volume_UV
        real,    dimension(:,:,:), pointer :: Area_UV, Area_VU


        !KFloor variables (matrix that stores the first layer of the water column)
        integer, dimension(:,:),   pointer :: KFloor_Z, KFloor_U, KFloor_V

        !Auxiliar
        integer, dimension(:,:),   pointer :: KFloor_UV, KFloor_VU



        !Turbulence
        !Visc_H_Corner - Turbulent horizontal viscosity in the cell SW corner
        !Visc_H_Corner - Turbulent horizontal viscosity in the cell center
        !Visc_H_Corner - Turbulent vertical   viscosity 
        real,    dimension(:,:,:), pointer :: Visc_H_Corner, Visc_H_Center, Vertical_Viscosity
        
        
        !Water Properties
        real,    dimension(:,:,:), pointer :: Density, SigmaDens

        !Bottom
        real,    dimension(:,:),   pointer :: ChezyZ, ChezyVelUV, WaveChezyVel, RugosityMatrix
        real                               :: Hmin_Chezy, Vmin_Chezy, ChezyCoef
        logical                            :: Manning, Chezy

        
        !Surface
        real,    dimension(:,:),   pointer :: TauWindU, TauWindV, TauWind_UV
        real,    dimension(:,:  ), pointer :: SurfaceWaterFlux
        real(8), dimension(:,:  ), pointer :: BottomWaterFlux
        real,    dimension(:,:  ), pointer :: WindStress_X
        real,    dimension(:,:  ), pointer :: WindStress_Y
        real,    dimension(:,:  ), pointer :: AtmosphericPressure

        !Waves 
        real,    dimension(:,:),   pointer :: TauWavesU, TauWavesV, TauWaves_UV

    end type T_External

    type T_Drag
        type(T_PropertyID)              :: ID
        real, dimension(:,:,:), pointer :: Coef
    end type T_Drag

    !guillaume nogueira
    type       T_HydroCoupling                  
         type(T_Time)                           :: NextCompute
         real                                   :: DT_Compute = FillValueReal
         logical                                :: Yes                  = .false.
         logical                                :: flag                 = .false.
    end type T_HydroCoupling  

    private :: T_HydroOptions
    type       T_HydroOptions
        real(8) :: EnteringWaveDirection
        real, dimension(:,:,:), pointer :: BiHarmonicUX_VY, BiHarmonicUY_VX
        real, dimension(:,:),   pointer :: Tlag        
        
        real                            :: BiHarmonicCoef   
        real                            :: BottomViscCoef     

        real    :: UpStream_CenterDif
        real    :: ImplicitVertAdvection
        real    :: ImplicitVertDiffusion
        real    :: Num_Discretization
        real    :: MinLeavingVelocity
        real    :: MinLeavingComponent
        real    :: InertialPeriods
        real    :: TideSlowStartCoef
        real    :: Hmin_Advection

        integer :: UpStream
        integer :: Evolution 
        integer :: VelTangentialBoundary
        integer :: VelNormalBoundary
        
        logical :: Baroclinic
        logical :: BoundaryBaroclinic
        integer :: BaroclinicMethod
        logical :: Coriolis
        logical :: Continuous
        logical :: Compute_Tide
        logical :: Imposed_BoundaryWave
        logical :: WaterDischarges
        logical :: Residual
        logical :: ComputeEnteringWave
        logical :: Energy
        logical :: VolumeVariation
        logical :: HorizontalDiffusion
        logical :: HorizontalAdvection
        logical :: VerticalDiffusion
        logical :: VerticalAdvection
        logical :: BaroclinicRAMP
        logical :: NullBoundaryHorAdv
        integer :: Wind
        real    :: SmoothInitialPeriod
        logical :: AtmPressure
        logical :: SurfaceWaterFlux
        logical :: BottomWaterFlux
        logical :: Relaxation
        type(T_HydroCoupling) :: AltimetryAssimilation ! guillaume nogueira
        logical :: CoriolisBoundary
        logical :: ImplicitAdvection
        logical :: Recording
        logical :: MomentumDischarge
        logical :: LocalDensity
        logical :: BlumbergKantha
        logical :: InitialElevation
        logical :: ConservativeHorDif
        logical :: BiHarmonic
        logical :: BottomVisc_LIM         !MRV

        integer :: BarotropicRadia
        integer :: BaroclinicRadia

        integer :: LocalSolution

        logical :: CorrectWaterLevel
        real    :: WaterLevelMin
        real    :: WaterColumn2D

        logical :: SlippingCondition
     
        logical :: WaveStress 

        logical :: Obstacle

        type (T_Time) :: RAMP_BeginTime

        logical :: CentrifugalForce
        logical :: InertiaForces

        integer :: AdvectionMethodH, TVD_LimH
        integer :: AdvectionMethodV, TVD_LimV
        logical :: Upwind2H, Upwind2V
        real    :: VolumeRelMax

        integer :: BaroclinicPoliDegree

        integer :: Vertical_AxiSymmetric_Model

        real    :: FlatherColdPeriod, FlatherColdSeaLevel

    end type T_HydroOptions


    private :: T_OutPut
    type       T_OutPut
         type (T_Time), dimension(:), pointer     :: OutTime
         integer                                  :: FirstInstant, DTInstant        !GUI
         integer                                  :: NextOutPut, Number
         logical                                  :: hdf5ON, Run_End
         logical                                  :: TimeSerieON
         logical                                  :: ProfileON
         real,          dimension(:,:,:), pointer :: ModulusH, CenterU, CenterV, CenterW, DirectionH
    end type T_OutPut


    type T_Energy
        integer                         :: FileID
        integer                         :: BufferCount
        real(8)                            :: PotentialEnergyReference
        logical                         :: FirstTime = .true.
        real, dimension(:), pointer     :: YearBuffer
        real, dimension(:), pointer     :: MonthBuffer
        real, dimension(:), pointer     :: DayBuffer
        real, dimension(:), pointer     :: HourBuffer
        real, dimension(:), pointer     :: MinuteBuffer
        real, dimension(:), pointer     :: SecondBuffer
        real, dimension(:), pointer     :: RelativeKEBuffer
        real, dimension(:), pointer     :: RelativePEBuffer
        real, dimension(:), pointer     :: KineticBuffer
        real, dimension(:), pointer     :: PotentialBuffer
        real, dimension(:), pointer     :: VorticityBuffer
        real, dimension(:), pointer     :: MassBuffer
        real, dimension(:), pointer     :: VolumeBuffer
        real, dimension(:), pointer     :: OpenVolumeBuffer
        real, dimension(:), pointer     :: WaterLevelBuffer
        real, dimension(:), pointer     :: BarotropicKEBuffer
        real, dimension(:), pointer     :: BaroclinicKEBuffer
        real, dimension(:), pointer     :: VelMaxBaroclinicBuffer
        real, dimension(:), pointer     :: VelMaxBuffer

        type (T_Size3D)                 :: Window
        type (T_Time)                   :: NextOutPut
        real                            :: DtOut
    end type T_Energy

    
    private :: T_Astro
    type       T_Astro
        logical                           :: Compute
        integer                           :: ComponentsNumber = 11
        real,    pointer, dimension (:  ) :: Beta, Amplitude, Frequency, Arguments, L
        integer, pointer, dimension (:  ) :: m
        type (T_Time)                     :: TimeRef
        real                              :: Alpha
        integer                           :: Algorithm 
    end type T_Astro
     
    private :: T_Relaxation
    type       T_Relaxation
        logical                             :: Rox3                 = .false.
        logical                             :: HorizAdv             = .false.
        logical                             :: Coriolis             = .false.
        logical                             :: Velocity             = .false.       
        logical                             :: WaterLevel           = .false.
        logical                             :: RefBoundWaterLevel   = .false.
        logical                             :: Force                = .false.
        logical                             :: Geometry             = .false.
        integer                             :: ReferenceVelocity    = TotalVel_
        real,   dimension(:,:,:), pointer   :: DecayTimeGeo         
    endtype      

    private :: T_SubModel
    type       T_SubModel
        logical                              :: ON, Set, InterPolTime, DeadZone, MissingNull
        !PCL - temporary
        logical                              :: ON22
        character (Len = StringLength)       :: DeadZoneFile
        integer                              :: VertComunic

        logical, dimension(:,:,:), pointer   :: DeadZonePoint

        real,    dimension(:,:  ), pointer   :: Z
        real,    dimension(:,:,:), pointer   :: U_New, V_New, UV_New, VU_New
        real,    dimension(:,:,:), pointer   :: U_Old, V_Old, UV_Old
        real,    dimension(:,:,:), pointer   :: DUZ_Old, DVZ_Old, DUVZ_Old
        real,    dimension(:,:,:), pointer   :: DUZ_New, DVZ_New
        real(8), dimension(:,:,:), pointer   :: qX, qY, qXY, qYX

        !Time Interpolation
        type(T_Time)                         :: NextTime, PreviousTime
        real,    dimension(:,:  ), pointer   :: Z_Previous, Z_Next
        real,    dimension(:,:,:), pointer   :: U_Previous, V_Previous, U_Next, V_Next
        real,    dimension(:,:,:), pointer   :: DUZ_Previous, DUZ_Next, DVZ_Previous, DVZ_Next

        integer                              :: ObjBoxDif

    endtype   

    type T_HydroStatistic           
        logical                              :: ON
        character(len=StringLength)          :: File
        integer                              :: NProp = 3
        integer, dimension(3)                :: PropList, ID

    end type T_HydroStatistic

    type T_CyclicBoundary
        logical                              :: ON
        integer                              :: Direction
    end type T_CyclicBoundary

       
    private :: T_Hydrodynamic
    type       T_Hydrodynamic
        private
        type(T_Direction     ) :: Direction 
        type(T_State         ) :: State
        integer                :: InstanceID
        type(T_Size3D        ) :: Size
        type(T_Size3D        ) :: WorkSize
        type(T_Files         ) :: Files
        type(T_Time          ) :: BeginTime  
        type(T_Time          ) :: CurrentTime  
        type(T_Time          ) :: EndTime
        type(T_Time          ) :: LastIteration 
        type(T_WaterLevel    ) :: Waterlevel
        type(T_Velocity      ) :: Velocity
        type(T_WaterFluxes   ) :: WaterFluxes
        type(T_Residual      ) :: Residual
        type(T_Forces        ) :: Forces
        type(T_HorAdvection  ) :: HorAdvection
        type(T_Coefficients  ) :: Coef
        type(T_External      ) :: External_Var
        type(T_HydroOptions  ) :: ComputeOptions
        type(T_OutPut        ) :: OutPut
        type(T_Energy        ) :: Energy
        type(T_Astro         ) :: TidePotential
        type(T_Relaxation    ) :: Relaxation
        type(T_SubModel      ) :: SubModel
        type(T_VelBaroclinic ) :: VelBaroclinic
        type(T_HydroStatistic) :: Statistics
        type(T_CyclicBoundary) :: CyclicBoundary 
        type(T_NonHydrostatic) :: NonHydrostatic
        type(T_Drag          ) :: Drag


        !Auxiliar thomas arrays
        real(8), pointer, dimension(:) :: VECG_3D  
        real(8), pointer, dimension(:) :: VECW_3D
        real(8), pointer, dimension(:) :: VECG_2D  
        real(8), pointer, dimension(:) :: VECW_2D
   

        !Instance of ModuleGridData
        integer :: ObjGridData              = 0
      
        !Instance of ModuleHorizontalGrid
        integer :: ObjHorizontalGrid        = 0

        !Instance of ModuleTime
        integer :: ObjTime                  = 0

        !Instance of ModuleGeometry
        integer :: ObjGeometry              = 0

        !Instance of ModuleHorizontalMap
        integer :: ObjHorizontalMap         = 0

        !Instance of ModuleMap
        integer :: ObjMap                   = 0


        !Modules construct INSIDE the hydrodynamic module

        !Instance of Module HDF5
        integer :: ObjHDF5                  = 0

        !Instance of Module_EnterData
        integer :: ObjEnterData             = 0
       
        !Instance of Module_EnterData
        integer :: ObjEnterData1            = 0
        
        !Instance of ModuleOpenBoundary
        integer :: ObjOpenBoundary          = 0

        !Instance of ModuleTurbulence
        integer :: ObjTurbulence            = 0

        !Instance of ModuleSurface
        integer :: ObjDischarges            = 0

        !Instance of ModuleBoxDif
        integer :: ObjBoxDif                = 0           

        !Instance of ModuleTimeSerie
        integer :: ObjTimeSerie             = 0

        !!Instance of ModuleProfile
        integer :: ObjProfile               = 0

        !Instance of ModuleHydrodynamicFile (Input)
        integer :: ObjHydrodynamicFileIn    = 0

        !Instance of ModuleHydrodynamicFile (Output)
        integer :: ObjHydrodynamicFileOut   = 0

        !Instance of ModuleAssimilation      
        integer :: ObjAssimilation          = 0

        !Instance of Waves      
        integer :: ObjWaves                 = 0

        type (T_Hydrodynamic), pointer :: Next

    end type T_Hydrodynamic

    !Global Module Variables
    type (T_Hydrodynamic), pointer                  :: FirstHydrodynamic
    type (T_Hydrodynamic), pointer                  :: Me



    contains

    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    !CONSTRUCTOR CONSTRUCTOR CONSTRUCTOR CONSTRUCTOR CONSTRUCTOR CONSTRUCTOR CO

    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

!-------------------------------------------------------------------------
!        IST/MARETEC, Marine Modelling Group, Mohid2000 modelling system
!-------------------------------------------------------------------------


!BOP
!
! !ROUTINE: StartHydrodynamic

! !DESCRIPTION: 
!     This routine is responsible for the initialization of the 
!     hydrodynamic model: numerical options, hydrodynamic initial values, etc.
 
! !REVISION HISTORY: 
!  1Jan2000    Paulo Chambel  First experimental version.
!  16Nov2000   Paulo Chambel  Comments are introduce in the Protex format 
!                             to produce a manual
!            

! !INTERFACE:

    subroutine StartHydrodynamic (HydrodynamicID,                                        &
                                  GridDataID,                                            &
                                  HorizontalGridID,                                      & 
                                  GeometryID,                                            &
                                  HorizontalMapID,                                       &
                                  MapID,                                                 &
                                  AssimilationID,                                        &
                                  TimeID,                                                &
                                  TurbulenceID,                                          &
                                  DischargesID,                                          &
                                  WavesID,                                               &
                                  STAT)

!
! !INPUT PARAMETERS:

        !Arguments-------------------------------------------------------------
        integer, intent (INOUT)       :: HydrodynamicID 
        integer, intent (IN)          :: GridDataID     
        integer, intent (IN)          :: HorizontalGridID
        integer, intent (IN)          :: GeometryID     
        integer, intent (IN)          :: HorizontalMapID
        integer, intent (IN)          :: MapID          
        integer                       :: AssimilationID 
        integer, intent (IN)          :: TimeID         
        integer, intent (IN)          :: TurbulenceID
        integer, intent (IN)          :: WavesID
        integer                       :: DischargesID

! !OUTPUT PARAMETERS:                                          
        
        integer, optional, intent(OUT):: STAT                          


!EOP

        !Local-----------------------------------------------------------------

        integer :: ready_
        integer :: STAT_       
        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        !Assures nullification of the global variable
        if (.not. ModuleIsRegistered(mHydrodynamic_)) then
            nullify (FirstHydrodynamic)
            call RegisterModule (mHydrodynamic_) 
        endif


        call Ready(HydrodynamicID, ready_)    

cd0 :   if (ready_ .EQ. OFF_ERR_) then

      
            call AllocateInstance 
            
            !Associates External Instances
            Me%ObjTime           = AssociateInstance (mTIME_,           TimeID          )
            Me%ObjGridData       = AssociateInstance (mGRIDDATA_,       GridDataID      ) 
            Me%ObjHorizontalGrid = AssociateInstance (mHORIZONTALGRID_, HorizontalGridID)
            Me%ObjHorizontalMap  = AssociateInstance (mHORIZONTALMAP_,  HorizontalMapID )
            Me%ObjGeometry       = AssociateInstance (mGEOMETRY_,       GeometryID      )
            Me%ObjMap            = AssociateInstance (mMAP_,            MapID           )
            Me%ObjTurbulence     = AssociateInstance (mTURBULENCE_,     TurbulenceID    )

            if(WavesID /= 0)then
                Me%ObjWaves      = AssociateInstance (mWAVES_,          WavesID)
            end if


            call Construct_Hydrodynamic (DischargesID,  AssimilationID)

            if (Me%ComputeOptions%Evolution .NE. Read_File_)        &
                call CourantGH()

            

            call null_time   (Me%LastIteration)
            call null_time   (Me%CurrentTime)

            !Returns ID 
            HydrodynamicID = Me%InstanceID

            STAT_ = SUCCESS_

        else cd0
            
            STAT_ = UNKNOWN_

        end if cd0


        if (present(STAT)) STAT = STAT_


        !----------------------------------------------------------------------

    end subroutine StartHydrodynamic

    !--------------------------------------------------------------------------

    !--------------------------------------------------------------------------

    subroutine AllocateInstance

        !Local-----------------------------------------------------------------
        type (T_Hydrodynamic), pointer              :: NewHydrodynamic
        type (T_Hydrodynamic), pointer              :: PreviousHydrodynamic

        !Allocates new instance
        allocate (NewHydrodynamic)
        nullify  (NewHydrodynamic%Next)

        !Insert New Instance into list and makes Current point to it
        if (.not. associated(FirstHydrodynamic)) then
            FirstHydrodynamic         => NewHydrodynamic
            Me                        => NewHydrodynamic
        else
            PreviousHydrodynamic      => FirstHydrodynamic
            Me                        => FirstHydrodynamic%Next
            do while (associated(Me))
                PreviousHydrodynamic  => Me
                Me                    => Me%Next
            enddo
            Me                        => NewHydrodynamic
            PreviousHydrodynamic%Next => NewHydrodynamic
        endif

        Me%InstanceID = RegisterNewInstance (mHYDRODYNAMIC_)


    end subroutine AllocateInstance


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Geometry, Mapping                                                            !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Construct_Hydrodynamic(DischargesID,  AssimilationID)

        !Arguments 
        integer             :: DischargesID
        integer             :: AssimilationID
        !Local
        integer :: STAT_CALL

        !----------------------------------------------------------------------

        Me%State%Initial = ON

        call GetGeometrySize(Me%ObjGeometry,                                             &
                             Size = Me%Size, WorkSize = Me%WorkSize,                     &
                             STAT = STAT_CALL)
    
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Construct_Hydrodynamic - ModuleHydrodynamic - ERR01'


        call Construct_HydrodynamicTime(  )

    
        call Read_Hydrodynamic_Files_Name(  )

       
        !Construct enter data 
        call ConstructEnterData(Me%ObjEnterData, Me%Files%ConstructData,   &
                                STAT = STAT_CALL) 

        if (STAT_CALL /= SUCCESS_)                                     &
            stop 'Subroutine Construct_Hydrodynamic; Module ModuleHydrodynamic. ERR02.'


        call Construct_Numerical_Options
        
        call Verify_Numerical_Options   
     
        !Opens the HDF 5 file
        call Open_HDF5_OutPut_File

        call Actualize_HydrodynamicTimeStep


        call InitialHydrodynamicField (DischargesID, AssimilationID) 

        call StartOutputBoxFluxes          


        call Construct_OutPutTime

        
        !Construct the Time Serie Obj
        if (Me%OutPut%TimeSerieON) call Construct_Time_Serie

        if (Me%OutPut%TimeSerieON .or. Me%OutPut%hdf5ON .or. Me%OutPut%ProfileON) &
            call ConstructMatrixesOutput

        if (Me%OutPut%ProfileON) call Construct_Output_Profile

        !call External Modules
        call ReadLock_External_Modules

        !Do the first output
        call Hydrodynamic_OutPut


        !call External Modules
        call ReadUnLock_External_Modules

        call KillEnterData(Me%ObjEnterData, STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine Construct_Hydrodynamic; Module ModuleHydrodynamic. ERR03.'

        !To let the model take access to the Mapping and geometry variables
        call ReadLock_External_Modules  

        !Call this subroutine to actualize the variabel DUZ_VY 
        !Only this way the subroutine ModifyChezyVelUV nows the 
        !face direction where the chezy coeficient must be compute. 
        !
        call MaintainDirection

        !Initialize bottom boundary (Chezy coefficient is computed for the first time)
!        call Bottom_Boundary            

        !Unget the Mapping and geometry variables
        call ReadUnLock_External_Modules

        Me%State%Initial = OFF


    End Subroutine Construct_Hydrodynamic

    !End----------------------------------------------------------------



    Subroutine InitialHydrodynamicField(DischargesID, AssimilationID)

        !Arguments-------------------------------------------------------------
        
        integer             :: DischargesID
        integer             :: AssimilationID

        !Local-----------------------------------------------------------------

        integer :: OutputStateEx, STAT_CALL

        !----------------------------------------------------------------------

        if (Me%ComputeOptions%BaroclinicRadia /= NoRadiation_)              &
            call Construct_RadiaBaroclinic

        
        call AllocateVariables


        !This must be called before initial_geometry. Elevation is needed.
        call ConstructHydrodynamicProperties

        if (.not. Me%ComputeOptions%Continuous) call ReadInitialImposedSolution 

        !Guillaume
        if (Me%ComputeOptions%Evolution == Vertical1D_) then
            Me%WaterFluxes%X (:,:,:) = 0.
            Me%WaterFluxes%Y (:,:,:) = 0.
            Me%WaterFluxes%Z (:,:,:) = 0.
            Me%Waterlevel%New(:,:  ) = 0.
        endif
    

        call Initial_Geometry


        call Construct_Sub_Modules (DischargesID, AssimilationID) 


        call ReadLock_ModuleMap
        
        call ReadLock_ModuleGeometry
        call ModifyWaterDischarges 
        call ReadUnLock_ModuleGeometry

        !The subroutine StartHydrodynamicFile in RECORDING mode must be called
        !after the Initial_Geometry where the Mapping update is done because 
        !to record the intial field is necessary to have have the Mapping of 
        !the compute points
cd11:   if (Me%ComputeOptions%Recording) then

            call GetHydrodynamicFileIOState(OutputStateEx = OutputStateEx)
            call StartHydrodynamicFile (Me%ObjHydrodynamicFileOut,          &
                                        Me%ObjGridData,                     &
                                        Me%ObjHorizontalGrid,               &
                                        Me%ObjGeometry,                     &
                                        Me%ObjMap,                          &
                                        Me%ObjHorizontalMap,                &
                                        Me%ObjTime,                         &
                                        OutputStateEx,                      &
                                        InitialWaterLevel      =            &
                                        Me%WaterLevel%New,                  &
                                        InitialWaterFluxX      =            &
                                        Me%WaterFluxes%X,                   &
                                        InitialWaterFluxY      =            &
                                        Me%WaterFluxes%Y,                   &
                                        InitialDischarges      =            &
                                        Me%WaterFluxes%Discharges,          &
                                        InitialComputeFacesU3D =            &
                                        Me%External_Var%ComputeFaces3D_U,   &
                                        InitialComputeFacesV3D =            &
                                        Me%External_Var%ComputeFaces3D_V,   &
                                        STAT = STAT_CALL)            

            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine InitialHydrodynamicField; Module ModuleHydrodynamic. ERR01' 

        endif cd11

        call ReadUnLock_ModuleMap

        !PCL - This initial field is only constructed 
        !if the run is new and the user wants to imposed 
        !a flow relaxation scheme OR hydrodynamic field is equal to the residual one (Evolution == Residual_hydrodynamic_)
        call InitialReferenceWaterFluxes

        !PCL - This initial field is only constructed 
        !if the transisent hydrodynamic is read from a file
        call InitialHydrodynamicFileVel

        if (.not. Me%ComputeOptions%Continuous)                             &
            call NewEqualsOld



    End Subroutine InitialHydrodynamicField

    !End----------------------------------------------------------------


   !----------------------------------------------------------------------------

    subroutine ReadInitialImposedSolution 

        !Arguments-------------------------------------------------------------
        

        !Local-----------------------------------------------------------------
        real,    dimension(:,:,:), pointer :: Matrix3D
        integer, dimension(:,:,:), pointer :: PointsToFill3D
        character(len = StringLength)      :: BeginBlock, EndBlock, Char_TypeZUV
        integer                            :: STAT_CALL, ClientNumber, i, j, k, iflag 
        logical                            :: BlockFound

        !----------------------------------------------------------------------


        BeginBlock = "<begin_waterlevel>"
        EndBlock   = "<end_waterlevel>"

        !Searches for water level 
        call ExtractBlockFromBuffer (Me%ObjEnterData, ClientNumber,                     &
                                     BeginBlock, EndBlock,                              &
                                     BlockFound, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR10'

        if (BlockFound) then

            !Gets WaterPoints2D
            call GetWaterPoints2D(Me%ObjHorizontalMap,                                  &
                                  Me%External_Var%WaterPoints2D, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                  &
                stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR20'

            call ConstructPropertyID  (Me%WaterLevel%ID, Me%ObjEnterData, FromBlock)

            call ConstructFillMatrix  (PropertyID           = Me%WaterLevel%ID,             &
                                       EnterDataID          = Me%ObjEnterData,              &
                                       TimeID               = Me%ObjTime,                   &
                                       HorizontalGridID     = Me%ObjHorizontalGrid,         &
                                       ExtractType          = FromBlock,                    &
                                       PointsToFill2D       = Me%External_Var%WaterPoints2D,&
                                       Matrix2D             = Me%WaterLevel%New,            &
                                       TypeZUV              = TypeZ_,                       &
                                       STAT                 = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR30'

            !UnGets WaterPoints2D
            call UnGetHorizontalMap(Me%ObjHorizontalMap,                                &                      
                                  Me%External_Var%WaterPoints2D, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                  &
                stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR40'


            if(.not. Me%WaterLevel%ID%SolutionFromFile)then
                call KillFillMatrix(Me%WaterLevel%ID%ObjFillMatrix, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR50'
            end if

        else 
            if (Me%ComputeOptions%Evolution == ImposedSolution_) then
                write(*,*) 'Block not found'
                write(*,*) 'Begin = ',trim(BeginBlock)
                write(*,*) 'End   = ',trim(EndBlock)
                stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR60'
            endif

        endif

        call RewindBuffer(Me%ObjEnterData, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR70'

        call Block_Unlock(Me%ObjEnterData, ClientNumber, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR80'

        call Initial_Geometry


        !Module - ModuleMap
        !3D Mapping Properties
        call GetComputeFaces3D(Me%ObjMap,                                               &
                               ComputeFacesU3D = Me%External_Var%ComputeFaces3D_U,      &
                               ComputeFacesV3D = Me%External_Var%ComputeFaces3D_V,      &
                               STAT            = STAT_CALL)

        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR90'

        call GetOpenPoints3D(Me%ObjMap, Me%External_Var%OpenPoints3D, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR100'

        BeginBlock = "<begin_velocity_u>"
        EndBlock   = "<end_velocity_u>"

        !Searches for velocity u
        call ExtractBlockFromBuffer (Me%ObjEnterData, ClientNumber,                     &
                                     BeginBlock, EndBlock,                              &
                                     BlockFound, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR110'

        if (BlockFound) then

            call ConstructPropertyID  (Me%Velocity%Horizontal%U%ID, Me%ObjEnterData, FromBlock)

            call GetData(Char_TypeZUV, Me%ObjEnterData, iflag,                          &
                         keyword        = 'TYPE_ZUV',                                   &  
                         SearchType     = FromBlock,                                    &
                         ClientModule   = 'ModuleHydrodynamic',                         &
                         default        = "Z",                                          &
                         STAT           = STAT_CALL)            
            if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR120'

            Me%Velocity%Horizontal%U%InTypeZUV = TranslateTypeZUV(Char_TypeZUV)

            if      (Me%Velocity%Horizontal%U%InTypeZUV == TypeU_) then
            
                PointsToFill3D => Me%External_Var%ComputeFaces3D_U
                Matrix3D       => Me%Velocity%Horizontal%U%New

            else if (Me%Velocity%Horizontal%U%InTypeZUV == TypeZ_) then

                PointsToFill3D => Me%External_Var%OpenPoints3D
                
                allocate (Matrix3D(Me%Size%ILB:Me%Size%IUB,Me%Size%JLB:Me%Size%JUB,Me%Size%KLB:Me%Size%KUB))
                Matrix3D(:,:,:) = FillValueReal

            else if (Me%Velocity%Horizontal%U%InTypeZUV == TypeV_) then

                stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR130'

            else

                stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR140'

            endif

            !Uncovered cells are set to zero
            call ConstructFillMatrix  (PropertyID           = Me%Velocity%Horizontal%U%ID,      &
                                       EnterDataID          = Me%ObjEnterData,                  &
                                       TimeID               = Me%ObjTime,                       &
                                       HorizontalGridID     = Me%ObjHorizontalGrid,             &
                                       GeometryID           = Me%ObjGeometry,                   &
                                       ExtractType          = FromBlock,                        &
                                       PointsToFill3D       = PointsToFill3D,                   &
                                       Matrix3D             = Matrix3D,                         &
                                       TypeZUV              = Me%Velocity%Horizontal%U%InTypeZUV,&
                                       FillMatrix           = 0.,                               &             
                                       STAT                 = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR150'

            if (Me%Velocity%Horizontal%U%InTypeZUV == TypeZ_) then

                Me%Velocity%Horizontal%U%New(:,:,:) = 0.

                do k = Me%WorkSize%KLB,Me%WorkSize%KUB
                do j = Me%WorkSize%JLB,Me%WorkSize%JUB
                do i = Me%WorkSize%ILB,Me%WorkSize%IUB
                    
                    if (PointsToFill3D(i,j-1,k) == OpenPoint .and.                      &
                        PointsToFill3D(i,j  ,k) == OpenPoint) then
                        Me%Velocity%Horizontal%U%New(i,j,k) = (Matrix3D(i,j-1,k) + Matrix3D(i,j,k)) / 2.
                    endif

                enddo
                enddo
                enddo

                deallocate(Matrix3D)

            endif

            nullify   (PointsToFill3D)
            nullify   (Matrix3D)

            if(.not. Me%Velocity%Horizontal%U%ID%SolutionFromFile)then
                
                call KillFillMatrix(Me%Velocity%Horizontal%U%ID%ObjFillMatrix, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR160'
            end if

        else

            if (Me%ComputeOptions%Evolution == ImposedSolution_) then
                write(*,*) 'Block not found'
                write(*,*) 'Begin = ',trim(BeginBlock)
                write(*,*) 'End   = ',trim(EndBlock)
                stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR170'
            endif

        endif

        call RewindBuffer(Me%ObjEnterData, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR180'

        call Block_Unlock(Me%ObjEnterData, ClientNumber, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR190'



        BeginBlock = "<begin_velocity_v>"
        EndBlock   = "<end_velocity_v>"

        !Searches for velocity v
        call ExtractBlockFromBuffer (Me%ObjEnterData, ClientNumber,                             &
                                     BeginBlock, EndBlock,                                      &
                                     BlockFound, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR200'

        if (BlockFound) then

            call ConstructPropertyID  (Me%Velocity%Horizontal%V%ID, Me%ObjEnterData, FromBlock)

            call GetData(Char_TypeZUV, Me%ObjEnterData, iflag,                          &
                         keyword        = 'TYPE_ZUV',                                   &  
                         SearchType     = FromBlock,                                    &
                         ClientModule   = 'ModuleHydrodynamic',                         &
                         default        = "Z",                                          &
                         STAT           = STAT_CALL)            
            if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR210'

            Me%Velocity%Horizontal%V%InTypeZUV = TranslateTypeZUV(Char_TypeZUV)

            if      (Me%Velocity%Horizontal%V%InTypeZUV == TypeV_) then
            
                PointsToFill3D => Me%External_Var%ComputeFaces3D_V
                Matrix3D       => Me%Velocity%Horizontal%V%New

            else if (Me%Velocity%Horizontal%V%InTypeZUV == TypeZ_) then

                PointsToFill3D => Me%External_Var%OpenPoints3D
                
                allocate (Matrix3D(Me%Size%ILB:Me%Size%IUB,Me%Size%JLB:Me%Size%JUB,Me%Size%KLB:Me%Size%KUB))
                Matrix3D(:,:,:) = FillValueReal

            else if (Me%Velocity%Horizontal%V%InTypeZUV == TypeU_) then

                stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR220'

            else

                stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR230'

            endif


            !Uncovered cells are set to zero
            call ConstructFillMatrix  (PropertyID           = Me%Velocity%Horizontal%V%ID,      &
                                       EnterDataID          = Me%ObjEnterData,                  &
                                       TimeID               = Me%ObjTime,                       &
                                       HorizontalGridID     = Me%ObjHorizontalGrid,             &
                                       GeometryID           = Me%ObjGeometry,                   &
                                       ExtractType          = FromBlock,                        &
                                       PointsToFill3D       = PointsToFill3D,                   &
                                       Matrix3D             = Matrix3D,                         &
                                       TypeZUV              = Me%Velocity%Horizontal%V%InTypeZUV,&
                                       FillMatrix           = 0.,                               &             
                                       STAT                 = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR240'

            if (Me%Velocity%Horizontal%V%InTypeZUV == TypeZ_) then

                Me%Velocity%Horizontal%V%New(:,:,:) = 0.

                do k = Me%WorkSize%KLB,Me%WorkSize%KUB
                do j = Me%WorkSize%JLB,Me%WorkSize%JUB
                do i = Me%WorkSize%ILB,Me%WorkSize%IUB
                    
                    if (PointsToFill3D(i-1,j,k) == OpenPoint .and.                       &
                        PointsToFill3D(i  ,j,k) == OpenPoint) then
                        Me%Velocity%Horizontal%V%New(i,j,k) = (Matrix3D(i-1,j,k) + Matrix3D(i,j,k)) / 2.
                    endif

                enddo
                enddo
                enddo

                deallocate(Matrix3D)

            endif

            nullify   (PointsToFill3D)
            nullify   (Matrix3D)

            if(.not. Me%Velocity%Horizontal%V%ID%SolutionFromFile)then
                
                call KillFillMatrix(Me%Velocity%Horizontal%V%ID%ObjFillMatrix, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR250'
            end if

        else

            if (Me%ComputeOptions%Evolution == ImposedSolution_) then

                write(*,*) 'Block not found'
                write(*,*) 'Begin = ',trim(BeginBlock)
                write(*,*) 'End   = ',trim(EndBlock)
                stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR260'

            endif

        endif


        call RewindBuffer(Me%ObjEnterData, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR270'

        call Block_Unlock(Me%ObjEnterData, ClientNumber, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR280'

        !Module - ModuleMap
        !3D Mapping Properties
        call UnGetMap(Me%ObjMap, Me%External_Var%ComputeFaces3D_U,                       &
                      STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR290'

        call UnGetMap(Me%ObjMap, Me%External_Var%ComputeFaces3D_V,                       &
                      STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR300'

        call UnGetMap(Me%ObjMap, Me%External_Var%OpenPoints3D, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ReadInitialImposedSolution  - ModuleHydrodynamic - ERR310'


    end subroutine ReadInitialImposedSolution 


    subroutine ConstructDragCoefficients

        !Local-----------------------------------------------------------------
        character(len = StringLength)           :: BeginBlock, EndBlock
        integer                                 :: STAT_CALL, ClientNumber
        logical                                 :: BlockFound

        !----------------------------------------------------------------------
 
        call GetWaterPoints3D(Me%ObjMap, Me%External_Var%WaterPoints3D, STAT = STAT_CALL)
        if (STAT_CALL .NE. SUCCESS_) stop 'StartOutputBoxFluxes - ModuleHydrodynamic - ERR01'

        BeginBlock = "<begin_dragcoef>"
        EndBlock   = "<end_dragcoef>"

        !Searches for drag coefficients block
        call ExtractBlockFromBuffer (Me%ObjEnterData, ClientNumber,                             &
                                     BeginBlock, EndBlock,                                      &
                                     BlockFound, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ConstructDragCoefficients - ModuleHydrodynamic - ERR01'

        if (BlockFound) then

            call ConstructPropertyID  (Me%Drag%ID, Me%ObjEnterData, FromBlock)

            !Uncovered cells are set to zero
            call ConstructFillMatrix  (PropertyID           = Me%Drag%ID,                       &
                                       EnterDataID          = Me%ObjEnterData,                  &
                                       TimeID               = Me%ObjTime,                       &
                                       HorizontalGridID     = Me%ObjHorizontalGrid,             &
                                       GeometryID           = Me%ObjGeometry,                   &
                                       ExtractType          = FromBlock,                        &
                                       PointsToFill3D       = Me%External_Var%WaterPoints3D,    &
                                       Matrix3D             = Me%Drag%Coef,                     &
                                       TypeZUV              = TypeZ_,                           &
                                       FillMatrix           = 0.,                               &             
                                       STAT                 = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'ConstructDragCoefficients - ModuleHydrodynamic - ERR08'

            if(.not. Me%Drag%ID%SolutionFromFile)then
                
                call KillFillMatrix(Me%Drag%ID%ObjFillMatrix, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'ConstructDragCoefficients - ModuleHydrodynamic - ERR10'
            end if

        else

            write(*,*) 'Block not found'
            write(*,*) 'Begin = ',trim(BeginBlock)
            write(*,*) 'End   = ',trim(EndBlock)
            stop 'ConstructDragCoefficients - ModuleHydrodynamic - ERR11'

        endif

        call RewindBuffer(Me%ObjEnterData, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ConstructDragCoefficients - ModuleHydrodynamic - ERR12'

        call Block_Unlock(Me%ObjEnterData, ClientNumber, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_) stop 'ConstructDragCoefficients - ModuleHydrodynamic - ERR13'
        
        call UnGetMap (Me%ObjMap, Me%External_Var%WaterPoints3D, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ConstructDragCoefficients - ModuleHydrodynamic - ERR14'


    end subroutine ConstructDragCoefficients


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : ASCII data                                                                   !
    ! OutPut: Time                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine Construct_HydrodynamicTime 
                      
        !Arguments-----------------------------------------------------------------
           

        !Local---------------------------------------------------------------------
        type (T_Time)   :: CurrentTime, EndTime, BeginTime
        integer         :: STAT_CALL

        !Begin---------------------------------------------------------------------

        call GetComputeCurrentTime(Me%ObjTime, CurrentTime, STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_) &
            stop 'Sub. Construct_HydrodynamicTime - ModuleHydrodynamic - Error01'


        call GetComputeTimeLimits(Me%ObjTime, BeginTime = BeginTime, &
                                  EndTime = EndTime, STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_) &
            stop 'Sub. Construct_HydrodynamicTime - ModuleHydrodynamic - Error02'


        Me%BeginTime   = BeginTime

        Me%CurrentTime = CurrentTime

        Me%EndTime     = EndTime

    End Subroutine Construct_HydrodynamicTime

    !End-----------------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : ASCII data                                                                   !
    ! OutPut: Time                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine Actualize_HydrodynamicTimeStep 
                      
        !Arguments-----------------------------------------------------------------
           
        


        !Local---------------------------------------------------------------------
        real            :: DT_Model
        integer         :: Num_Discretization, STAT_CALL, Evolution

        !Begin---------------------------------------------------------------------
        call GetComputeTimeStep(Me%ObjTime, DT_Model, STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_) &
            stop 'Sub. Actualize_HydrodynamicTime - ModuleHydrodynamic - Error01'

        Evolution = Me%ComputeOptions%Evolution

cd1:    if (Evolution == Solve_Equations_) then 

            Num_Discretization      = Me%ComputeOptions%Num_Discretization
        
            if (Num_Discretization == Leendertse) then 

                Me%Velocity%DT = DT_Model ! 6 equations - velocities compute every DT

            else if (Num_Discretization == Abbott) then 

                Me%Velocity%DT = 2 * DT_Model    ! 4 equations - velocities compute every 2 * DT

            endif

            Me%WaterLevel%DT = DT_Model          ! In both numerical discretizations elevations are compute every DT

        else

            Me%WaterLevel%DT = DT_Model

            Me%Velocity%DT   = DT_Model

        endif cd1

    End Subroutine Actualize_HydrodynamicTimeStep

    !End-----------------------------------------------------------------------

    !--------------------------------------------------------------------------
    !Read the name of the files need to construct and modify
    ! the hydrodynamic properties 

    subroutine Read_Hydrodynamic_Files_Name

        !Arguments-------------------------------------------------------------




        !External--------------------------------------------------------------

        integer :: STAT_CALL 

        character(len = StringLength) :: Message, RootPath

        logical :: exist

        !----------------------------------------------------------------------


        ! ---> ASCII file used to construct a new hydrodynamic
        Message   ='ASCII file used to construct a new hydrodynamic.'
        Message   = trim(Message)

        call ReadFileName('IN_DAD3D', Me%Files%ConstructData, &
                           Message = Message, STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                           &
            stop 'Subroutine Read_Hydrodynamic_Files_Name; Module ModuleHydrodynamic. ERR02.' 


        inquire(FILE   = Me%Files%ConstructData,                   &
                EXIST  = exist,                                                 &
                IOSTAT = STAT_CALL)
        if (STAT_CALL .NE. SUCCESS_)                                            &
            stop 'Subroutine Read_Hydrodynamic_Files_Name; Module ModuleHydrodynamic. ERR02a.' 
        if (.NOT. exist)                                                        &
            stop 'Subroutine Read_Hydrodynamic_Files_Name; Module ModuleHydrodynamic. ERR02b.' 



        ! ---> File in HDF format where is written instant fields of hydrodynamic properties
        Message   ='Instant fields of hydrodynamic properties in HDF format.'
        Message   = trim(Message)

        call ReadFileName('OUT_DESF', Me%Files%OutPutFields,          &
                           Message = Message, TIME_END = Me%EndTime, &
                           Extension = 'hyt', STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                                  &
            stop 'Subroutine Read_Hydrodynamic_Files_Name; Module ModuleHydrodynamic. ERR03.' 



        ! ---> hydrodynamic properties final values in HDF format
        Message   ='Hydrodynamic properties final values in HDF format.'
        Message   = trim(Message)

        call ReadFileName('OUT_FIN', Me%Files%FinalHydrodynamic,     &
                           Message = Message, TIME_END = Me%EndTime, &
                           Extension = 'hyf', STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                &
            stop 'Subroutine Read_Hydrodynamic_Files_Name; Module ModuleHydrodynamic. ERR04.' 



        ! ---> Hydrodynamic properties initial values in HDF format
        Message   ='Water properties initial values in HDF format.'
        Message   = trim(Message)

        call ReadFileName('IN_CNDI', Me%Files%InitialHydrodynamic,          &
                           Message = Message, TIME_END = Me%BeginTime,      &
                           STAT = STAT_CALL)
cd1 :   if      (STAT_CALL .EQ. FILE_NOT_FOUND_ERR_   ) then

            stop 'Subroutine Read_Hydrodynamic_Files_Name; Module ModuleHydrodynamic. ERR06'

        else if (STAT_CALL .EQ. KEYWORD_NOT_FOUND_ERR_) then


!This message just confuses the user. 
!
!            write(*,*)  
!            write(*,*) 'Keyword for the inicial file not found in nomfich.dat. '
!            write(*,*) 'Subroutine Read_Hydrodynamic_Files_Name; Module ModuleHydrodynamic. WRN01'
!            write(*,*) 
 
            call SetError(WARNING_, KEYWORD_, 'Keyword IN_CNDI not found - ModuleHydrodynamic', &
                          Screen = .false.)

        else if (STAT_CALL .EQ. SUCCESS_              ) then

            continue

        else

            write(*,*) 
            write(*,*) 'Error calling ReadFileName. '
            stop       'Subroutine Read_Hydrodynamic_Files_Name; Module ModuleHydrodynamic. ERR05.' 
        end if cd1  
                                                                             
        ! ---> File where to store the energy evolution of the system
        Message   ='System Energy result file'
        Message   = trim(Message)



        call ReadFileName("ROOT_SRT", RootPath, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) then
            call ReadFileName("ROOT", RootPath, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) then
                call ReadFileName("RAIZ", RootPath, STAT = STAT_CALL)
                stop 'Subroutine Read_Hydrodynamic_Files_Name; Module ModuleHydrodynamic. ERR06.' 
            endif
        endif

        Me%Files%Energy = trim(adjustl(RootPath))//"TotalEnergy.dat"


        !----------------------------------------------------------------------

    end subroutine Read_Hydrodynamic_Files_Name

    !End--------------------------------------------------------------------------

    Subroutine Construct_Numerical_Options

        !Arguments-------------------------------------------------------------

        !Local-----------------------------------------------------------------

        integer :: FromFile
        integer :: STAT_CALL, iflag, BarotropicRadia

        logical :: Baroclinic, Continuous_Compute, Compute_Tide,                         &
                   WaterDischarges, Residual,                                            &
                   Coriolis,                                                             &
                   BoundaryBaroclinic, Energy, VolumeVariation,                          &
                   HorizontalAdvection, HorizontalDiffusion,                             &
                   BaroclinicRamp, VerticalAdvection,                                    &
                   VerticalDiffusion, NullBoundaryHorAdv,                                &
                   ComputeTidePotential,                                                 &
                   ComputeAtmPressure, ComputeSurfaceWaterFlux,                          &
                   Relaxation,                                                           &
                   ImplicitAdvection,                                                    &
                   InitialElevation

        real    :: UpStream_CenterDif
        real    :: ImplicitVertAdvection
        real    :: ImplicitVertDiffusion
        real    :: Num_Discretization
        real    :: MinLeavingVelocity, MinLeavingComponent
        real    :: InitialElevationValue, InitialVelocityU, InitialVelocityV
        real(8) :: EnteringWaveDirection

        real    :: Hmin_Chezy, Vmin_Chezy, Hmin_Advection

        real    :: InertialPeriods

        real    :: TideSlowStartCoef, SmoothInitialPeriod
        
        integer :: VelTangentialBoundary, VelNormalBoundary, ComputeWind

        integer :: WorkKUB

        character(LEN = StringLength)            :: String

        !Begin-----------------------------------------------------------------
        
       
        call GetExtractType(FromFile = FromFile)

        WorkKUB = Me%WorkSize%KUB

        !<BeginKeyword>
            !Keyword          : BAROCLINIC
            !<BeginDescription>       
               ! 
               ! Checks if the user pretends to compute the baroclinic pressure
               ! 
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Multiple Options : Do not have
            !Search Type      : FromFile
        !<EndKeyword>

        call GetData(Baroclinic,                                                         &
                     Me%ObjEnterData, iflag,                                &
                     SearchType = FromFile,                                              &
                     keyword    = 'BAROCLINIC',                                          &
                     Default    = .false.,                                               &                                           
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR01') 


        Me%ComputeOptions%Baroclinic = Baroclinic

        !<BeginKeyword>
            !Keyword          : CONTINUOUS
            !<BeginDescription>       
               ! 
               ! Checks if the user pretends to continue a old run 
               ! 
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Multiple Options : Do not have
            !Search Type      : FromFile
        !<EndKeyword>



        call GetData(Continuous_Compute,                                                 &
                     Me%ObjEnterData, iflag,                                &
                     SearchType = FromFile,                                              &
                     keyword    = 'CONTINUOUS',                                          &
                     Default    = .false.,                                               &                                           
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR03.')

        Me%ComputeOptions%Continuous = Continuous_Compute


        !<BeginKeyword>
            !Keyword          : TIDE
            !<BeginDescription>       
               ! 
               ! Checks if the user pretends to impose a wave tide in the open boundary 
               ! 
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Multiple Options : Do not have
            !Search Type      : FromFile
        !<EndKeyword>
        call GetData(Compute_Tide,                                                       &
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'TIDE',                                                & 
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR04.')


        Me%ComputeOptions%Compute_Tide = Compute_Tide


        !<BeginKeyword>
            !Keyword          : ENTERING_WAVE
            !<BeginDescription>       
               ! 
               ! Checks if the wave imposed in the boundary is entering in the domain or leaving it 
               ! 
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Multiple Options : Do not have
            !Search Type      : FromFile
        !<EndKeyword>
        call GetData(Me%ComputeOptions%ComputeEnteringWave,                 &
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'ENTERING_WAVE',                                       & 
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR04a.')


        if (Compute_tide) Me%ComputeOptions%ComputeEnteringWave = .true.

        !<BeginKeyword>
            !Keyword          : RADIATION
            !<BeginDescription>       
               ! 
               ! Checks if the user wants to imposed the Flather 1974 radiation boundary condition
               ! 
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Multiple Options : Do not have
            !Search Type      : FromFile
        !<EndKeyword>


        call GetData(BarotropicRadia,                                                    &
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'RADIATION',                                           & 
                     default    = NoRadiation_,                                          &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR05.')


        Me%ComputeOptions%BarotropicRadia = BarotropicRadia

        


        if (BarotropicRadia == NoRadiation_) then

            Me%ComputeOptions%Imposed_BoundaryWave = .true.

        else
        
            Me%ComputeOptions%Imposed_BoundaryWave = .false.

        endif

ifRadia: if (BarotropicRadia == FlatherWindWave_) then
        
            !<BeginKeyword>
                !Keyword          : WAVE_DIRECTION
                !<BeginDescription>       
                   ! 
                   ! The user with this keyword give a direction to a wave entering the domain
                   ! 
                !<EndDescription>
                !Type             : Real 
                !Units            : Degrees 
                !Default          : 0.
                !File keyword     : IN_DAD3D
                !Multiple Options : Do Not Have
                !Search Type      : From File
            !<EndKeyword>
            call GetData(EnteringWaveDirection,                                          &
                         Me%ObjEnterData, iflag,                            &
                         keyword    = 'WAVE_DIRECTION',                                  & 
                         default    = dble(0.),                                          &
                         SearchType = FromFile,                                          &
                         ClientModule ='ModuleHydrodynamic',                             &
                         STAT       = STAT_CALL)            
            if (STAT_CALL /= SUCCESS_)                                                   &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR09.')


            Me%ComputeOptions%EnteringWaveDirection = EnteringWaveDirection * Pi / 180.


        endif IfRadia

ifFla: if (BarotropicRadia == FlatherWindWave_ .or. BarotropicRadia == FlatherLocalSolution_) then


            !<BeginKeyword>
                !Keyword          : MIN_VELOCITY
                !<BeginDescription>       
                   ! 
                   ! The minimum velocity in the open boundary below which the radiation is canceled 
                   ! 
                !<EndDescription>
                !Type             : Real 
                !Units            : m/s 
                !Default          : 1e-6
                !File keyword     : IN_DAD3D
                !Multiple Options : Do Not Have
                !Search Type      : From File
            !<EndKeyword>
            call GetData(MinLeavingVelocity,                                             &
                         Me%ObjEnterData, iflag,                            &
                         keyword    = 'MIN_VELOCITY',                                    & 
                         default    = 1e-6,                                              &
                         SearchType = FromFile,                                          &
                         ClientModule ='ModuleHydrodynamic',                             &
                         STAT       = STAT_CALL)            
            if (STAT_CALL /= SUCCESS_)                                            &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR10.' )





            Me%ComputeOptions%MinLeavingVelocity = MinLeavingVelocity


            !<BeginKeyword>
                !Keyword          : MIN_COMPONENT
                !<BeginDescription>       
                   ! 
                   ! The minimum component of the radiative wave below which 
                   ! the radiation process is canceled
                   ! 
                !<EndDescription>
                !Type             : Real 
                !Units            : m/m 
                !Default          : 1e-3
                !File keyword     : IN_DAD3D
                !Multiple Options : Do Not Have
                !Search Type      : From File
            !<EndKeyword>
            call GetData(MinLeavingComponent,                                            &
                         Me%ObjEnterData, iflag,                            &
                         keyword    = 'MIN_COMPONENT',                                   & 
                         default    = 1e-3,                                              &
                         SearchType = FromFile,                                          &
                         ClientModule ='ModuleHydrodynamic',                             &
                         STAT       = STAT_CALL)            
            if (STAT_CALL /= SUCCESS_)                                            &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR11.')

            Me%ComputeOptions%MinLeavingComponent = MinLeavingComponent


        endif ifFla

        !<BeginKeyword>
            !Keyword          : WATER_DISCHARGES
            !<BeginDescription>       
               ! 
               ! Check if the user want to water discharges 
               ! 
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Multiple Options : 0 (false), 1 (true)
            !Search Type      : From File
        !<EndKeyword>
        call GetData(WaterDischarges,                                                    &
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'WATER_DISCHARGES',                                    & 
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic -ERR12.') 

        Me%ComputeOptions%WaterDischarges = WaterDischarges


        !<BeginKeyword>
            !Keyword          : RESIDUAL
            !<BeginDescription>       
               ! 
               ! Check if the user want to compute the residual flow 
               ! 
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Multiple Options : 0 (false), 1 (true)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Residual,                                                           &
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'RESIDUAL',                                            & 
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR14.')

        Me%ComputeOptions%Residual = Residual

        !<BeginKeyword>
            !Keyword          : ENERGY
            !<BeginDescription>       
               ! 
               ! Check if the user want to compute the potential and kinetic energy of the entire domain 
               ! 
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Multiple Options : 0 (false), 1 (true)
            !Search Type      : From File
        !<EndKeyword>
        call GetData(Energy,                                                             &
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'ENERGY',                                              &
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR15.') 

        Me%ComputeOptions%Energy = Energy



        !<BeginKeyword>
            !Keyword          : UP_CENTER
            !<BeginDescription>       
               ! 
               ! Check if the horizontal advection discretization 
               ! is upstream or center differences 
               ! By default advection is computed using a Upstream scheme
               ! 
            !<EndDescription>
            !Type             : Real (0,1) 
            !Default          : 1
            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (Center Difference), 1 (Upstream), >0 and <1 (hybrid)
            !Search Type      : From File
        !<EndKeyword>

        call GetData( UpStream_CenterDif,                                                &
                      Me%ObjEnterData, iflag,                               &
                      keyword    = 'UP_CENTER',                                          &           
                      default    =  1.,                                                  &
                      SearchType =  FromFile,                                            &
                      ClientModule ='ModuleHydrodynamic',                                 &
                      STAT       =  STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic -ERR16.' )


        Me%ComputeOptions%UpStream_CenterDif = UpStream_CenterDif


        !<BeginKeyword>
            !Keyword          : IMPLICIT_VERTADVECTION
            !<BeginDescription>       
               ! 
               ! Check if the vertical advection is implicit
               ! 
            !<EndDescription>
            !Type             : Real (0,1) 
            !Default          : 1
            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (explicit), 1 (implicit), >0 and <1 (hybrid)
            !Search Type      : From File
        !<EndKeyword>
        call GetData(ImplicitVertAdvection,                                              &
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'IMPLICIT_VERTADVECTION',                              &
                    !By default vertical advection is implicit
                     default    = 1.,                                                    &  
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR18.')

        ! If the new keyword is not find the model tries to read the old one.
        if (iflag == 0) then

            call GetData(ImplicitVertAdvection,                                          &
                         Me%ObjEnterData, iflag,                            &
                         keyword    = 'IMPLICIT_VERTCONVECTION',                         &
                        !By default vertical advection is implicit
                         default    = 1.,                                                &  
                         SearchType = FromFile,                                          &
                         ClientModule ='ModuleHydrodynamic',                             &
                         STAT       = STAT_CALL)            
            if (STAT_CALL /= SUCCESS_)                                                   &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR18a.')


            if (iflag == 1)                                                              &
                call SetError (WARNING_, KEYWORD_,                                       &
                               'Change keyword IMPLICIT_VERTCONVECTION to IMPLICIT_VERTADVECTION; ModuleHydrodynamics')

                                                         

        endif



        Me%ComputeOptions%ImplicitVertAdvection = ImplicitVertAdvection


        !<BeginKeyword>
            !Keyword          : IMPLICIT_VERTDIFFUSION
            !<BeginDescription>       
               ! 
               ! Check if the vertical advection is implicit
               ! 
            !<EndDescription>
            !Type             : Real (0,1) 
            !Default          : 1
            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (explicit), 1 (implicit), >0 and <1 (hybrid)
            !Search Type      : From File
        !<EndKeyword>
 
        call GetData(ImplicitVertDiffusion,                                   &
                     Me%ObjEnterData, iflag,                     &
                     keyword    = 'IMPLICIT_VERTDIFFUSION',                   &
                    !By default vertical diffusion is computed implicit
                     Default    = 1.,                                         &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR20.')

        Me%ComputeOptions%ImplicitVertDiffusion = ImplicitVertDiffusion

        !<BeginKeyword>
            !Keyword          : DISCRETIZATION
            !<BeginDescription>       
               ! 
               ! Check what type of implicit discretization in time 
               ! is choose for the global equations
               ! 
            !<EndDescription>
            !Type             : Integer 
            !Default          : 2
            !File keyword     : IN_DAD3D 
            !Multiple Options : 2 (Leendertse Scheme - 6 equations per iteration), 1 (Abbott Scheme - 4 equations per iteration)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Num_Discretization,                    &
                     Me%ObjEnterData, iflag,                     &
                     keyword    = 'DISCRETIZATION',                           & 
                    !By default is use the Leendertse Scheme (6 equations per iteration)
                     Default    = Leendertse,                                 &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR22.')


        Me%ComputeOptions%Num_Discretization = Num_Discretization

        !<BeginKeyword>
            !Keyword          : UPSTREAM
            !<BeginDescription>       
               ! 
               ! Check what type of upstream scheme is used in the horizontal advection
               ! 
            !<EndDescription>
            !Type             : Character 
            !Default          : Upwind
            !File keyword     : IN_DAD3D 
            !Multiple Options : Upwind , Quick
            !Search Type      : From File
        !<EndKeyword>

        call GetData(string,                                                    &
                     Me%ObjEnterData,                              &
                     iflag,                                                     &
                     SearchType   = FromFile,                                   &
                     keyword      ='UPSTREAM',                                  &
                     ClientModule ='ModuleHydrodynamic',                        &
                     default      = Char_Upwind_Scheme,                         &
                     STAT         = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                              &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR24.')

        String = trim(adjustl(String))
case2 : select case(String)
            case(Char_Upwind_Scheme)

                Me%ComputeOptions%UpStream = Upwind_Scheme

                Me%HorAdvection%Coef1_Up =  0.0
                Me%HorAdvection%Coef2_Up =  1.0
                Me%HorAdvection%Coef3_Up =  0.0
                      
            case(Char_Quick_Scheme )

                Me%ComputeOptions%UpStream = Quick_Scheme

                Me%HorAdvection%Coef1_Up = -1.0 / 8.0
                Me%HorAdvection%Coef2_Up =  6.0 / 8.0
                Me%HorAdvection%Coef3_Up =  3.0 / 8.0
                      
            case default

                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR25.')
        end select case2


        !<BeginKeyword>
            !Keyword          : TIME_SERIE
            !<BeginDescription>       
               ! 
               !Checks out if the user pretends to write a time serie
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. , .false.
            !Search Type      : From File
        !<EndKeyword>
        call GetData(Me%Output%TimeSerieON,                                   &
                     Me%ObjEnterData, iflag,                                  &
                     keyword    = 'TIME_SERIE',                               &
                     Default    = .false.,                                    &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR26.')


        !<BeginKeyword>
            !Keyword          : OUTPUT_PROFILE
            !<BeginDescription>       
               ! 
               !Checks out if the user pretends to write a profile output
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. , .false.
            !Search Type      : From File
        !<EndKeyword>
        call GetData(Me%OutPut%ProfileON,                                     &
                     Me%ObjEnterData, iflag,                                  &
                     keyword    = 'OUTPUT_PROFILE',                           &
                     Default    = .false.,                                    &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR260.')



        !<BeginKeyword>
            !Keyword          : EVOLUTION
            !<BeginDescription>       
               ! 
               !Checks out if the user pretends to actualize the hydrodynamic
               !properties computing the equations or reading them from a file 
               !there is also the possibility of read the residual flow of the 
               !last run and maintain the instant properties equal to the residual ones
               !The user can also say that the hydrodynamic properties have always null value
               !
            !<EndDescription>
            !Type             : Character 
            !Default          : Solve_Equations
            !File keyword     : IN_DAD3D 
            !Multiple Options : Solve_Equations, Read_File, No_hydrodynamic, Residual_hydrodynamic
            !Search Type      : From File
        !<EndKeyword>

        call GetData(string,                                                    &
                     Me%ObjEnterData,                                           &
                     iflag,                                                     &
                     SearchType   = FromFile,                                   &
                     keyword      ='EVOLUTION',                                 &
                     ClientModule ='ModuleHydrodynamic',                        &
                     !By default the model solve the momentum equations and the continuity equation
                     default      = Char_Solve_Equations,                       &
                     STAT         = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                              &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR27.')


        String = trim(adjustl(String))
case1 : select case(String)
            case(Char_Solve_Equations      )

                Me%ComputeOptions%Evolution = Solve_Equations_
                      
            case(Char_Read_File            )

                Me%ComputeOptions%Evolution = Read_File_
                      
            case(Char_No_hydrodynamic      ) 

                Me%ComputeOptions%Evolution = No_hydrodynamic_
                      
            case(Char_Residual_hydrodynamic)

                Me%ComputeOptions%Evolution = Residual_hydrodynamic_

            case(Char_Run_Off              )

                Me%ComputeOptions%Evolution = Run_Off_

            case(Char_ImposedSolution      )

                Me%ComputeOptions%Evolution = ImposedSolution_

            case(Char_Vertical1D           )

                Me%ComputeOptions%Evolution = Vertical1D_


            case default

                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR27a.')

        end select case1




        !<BeginKeyword>
            !Keyword          : CORIOLIS
            !<BeginDescription>       
               ! 
               !Checks  if the user pretends to compute the coriolis force effect
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .true.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (compute coriolis) , .false.  (do not compute coriolis)
            !Search Type      : From File
        !<EndKeyword>
        call GetData(Coriolis,                                                &
                     Me%ObjEnterData, iflag,                     &
                     Keyword    = 'CORIOLIS',                                 &
                    !By default the model compute always the coriolis force
                     Default    = .True.,                                     &  
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR28.')


        Me%ComputeOptions%Coriolis = Coriolis

        !<BeginKeyword>
            !Keyword          : VOLUMEVARIATION
            !<BeginDescription>       
               ! 
               !Checks  if the user pretends to compute the volume variation effect
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .true.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true.  , .false. 
            !Search Type      : From File
        !<EndKeyword>

        call GetData(VolumeVariation,                                         &
                     Me%ObjEnterData, iflag,                     &
                     Keyword    = 'VOLUMEVARIATION',                          &
                    !By default the model compute always the volume variation effect
                     Default    = .True.,                                     &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR29.')

        Me%ComputeOptions%VolumeVariation = VolumeVariation



        !<BeginKeyword>
            !Keyword          : HORIZONTALADVECTION
            !<BeginDescription>       
               ! 
               !Checks  if the user pretends to compute the horizontal advection effect 
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .true.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true.  , .false. 
            !Search Type      : From File
        !<EndKeyword>

        call GetData(HorizontalAdvection,                                                &
                     Me%ObjEnterData, iflag,                                &
                     Keyword    = 'HORIZONTALADVECTION',                                 &
                     !By default compute always the Horizontal Advection
                     Default    = .True.,                                                &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR30.')

        ! If the new keyword is not find the model tries to read the old one.
        if (iflag == 0) then

            call GetData(HorizontalAdvection,                                            &
                         Me%ObjEnterData, iflag,                            &
                         Keyword    = 'HORIZONTALCONVECTION',                            &
                         !By default compute always the Horizontal Advection
                         Default    = .True.,                                            &
                         SearchType = FromFile,                                          &
                         ClientModule ='ModuleHydrodynamic',                             &
                         STAT       = STAT_CALL)            

            if (STAT_CALL /= SUCCESS_)                                                   &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR30a.')



            if (iflag == 1)then
                call SetError (WARNING_, KEYWORD_,                                       &
                     'Change keyword HORIZONTALCONVECTION to HORIZONTALADVECTION; ModuleHydrodynamics')
            end if
                                                    

        endif



        Me%ComputeOptions%HorizontalAdvection = HorizontalAdvection

        !<BeginKeyword>
            !Keyword          : HORIZONTALDIFFUSION
            !<BeginDescription>       
               ! 
               !Checks  if the user pretends to compute the horizontal diffusion effect 
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .true.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true.  , .false. 
            !Search Type      : From File
        !<EndKeyword>

        call GetData(HorizontalDiffusion,                                     &
                     Me%ObjEnterData, iflag,                     &
                     Keyword    = 'HORIZONTALDIFFUSION',                      &
                     !By default compute always the Horizontal Diffusion
                     Default    = .True.,                                     &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR31.')


        Me%ComputeOptions%HorizontalDiffusion = HorizontalDiffusion

        !<BeginKeyword>
            !Keyword          : INITIAL_ELEVATION
            !<BeginDescription>       
               ! 
               !Checks if the user wants to impose a initial elevation 
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : Do not Have 
            !Search Type      : From File
        !<EndKeyword>


        call GetData(InitialElevation,                                                   &
                     Me%ObjEnterData, iflag,                                &
                     Keyword    = 'INITIAL_ELEVATION',                                   &
                     Default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR32b.')

        Me%ComputeOptions%InitialElevation = InitialElevation



        !<BeginKeyword>
            !Keyword          : INITIAL_ELEVATION_VALUE
            !<BeginDescription>       
               ! 
               !The user define with this keyword the initial elevation value 
               ! 
            !<EndDescription>
            !Type             : Real
            !Default          : 0.
            !File keyword     : IN_DAD3D 
            !Multiple Options : Do not Have 
            !Search Type      : From File
        !<EndKeyword>


        call GetData(InitialElevationValue,                                   &
                     Me%ObjEnterData, iflag,                     &
                     Keyword    = 'INITIAL_ELEVATION_VALUE',                  &
                     !By default the initial elevation is zero
                     Default    = 0.,                                         &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR33.')

        Me%WaterLevel%Default = InitialElevationValue

        !<BeginKeyword>
            !Keyword          : INITIAL_VEL_U
            !<BeginDescription>       
               ! 
               !Checks  if the user pretends to impose a initial U (X) velocity
               ! 
            !<EndDescription>
            !Type             : Real
            !Default          : 0.
            !File keyword     : IN_DAD3D 
            !Search Type      : From File
        !<EndKeyword>

        call GetData(InitialVelocityU,                                        &
                     Me%ObjEnterData, iflag,                     &
                     Keyword    = 'INITIAL_VEL_U',                            &
                    !By default do not impose a initial U velocity
                     Default    = 0.,                                         &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR32.')

        Me%Velocity%Horizontal%U%Default = InitialVelocityU

        !<BeginKeyword>
            !Keyword          : INITIAL_VEL_V
            !<BeginDescription>       
               ! 
               !Checks  if the user pretends to impose a initial V (Y) velocity
               ! 
            !<EndDescription>
            !Type             : Real
            !Default          : 0.
            !File keyword     : IN_DAD3D 
            !Search Type      : From File
        !<EndKeyword>

        call GetData(InitialVelocityV,                                        &
                     Me%ObjEnterData, iflag,                     &
                     Keyword    = 'INITIAL_VEL_V',                            &
                    !By default do not impose a initial V velocity
                     Default    = 0.,                                         &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR32a.')

        Me%Velocity%Horizontal%V%Default = InitialVelocityV



cd21:   if (Baroclinic) then



            !<BeginKeyword>
                !Keyword          : BOUNDARYBAROCLINIC
                !<BeginDescription>       
                   ! 
                   !Check if the user wants to compute the baroclinic force in the boundary faces
                   ! 
                !<EndDescription>
                !Type             : Logical
                !Default          : .true.
                !File keyword     : IN_DAD3D 
                !Multiple Options : .true. (Yes), .false. (No)
                !Search Type      : From File
            !<EndKeyword>

            call GetData(BoundaryBaroclinic,                                      &
                         Me%ObjEnterData, iflag,                     &
                         Keyword    = 'BOUNDARYBAROCLINIC',                       & 
                         !By default the model computes always the baroclinic force in the boundary
                         Default    = .true.,                                     &
                         SearchType = FromFile,                                   &
                         ClientModule ='ModuleHydrodynamic',                      &
                         STAT       = STAT_CALL)            
        
            if (STAT_CALL /= SUCCESS_)                                            &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR35.')



            Me%ComputeOptions%BoundaryBaroclinic = BoundaryBaroclinic


            !<BeginKeyword>
                !Keyword          : RAMP
                !<BeginDescription>       
                   ! 
                   !Check if the user wants to start with baroclinic 
                   !force null and only after a specific period the total force is compute
                   !
                   ! 
                !<EndDescription>
                !Type             : Logical
                !Default          : .false.
                !File keyword     : IN_DAD3D 
                !Multiple Options : .true. (Yes), .false. (No)
                !Search Type      : From File
            !<EndKeyword>

            call GetData(BaroclinicRamp,                                          &
                         Me%ObjEnterData, iflag,                     &
                        !BaroclinicRamp option by default is false
                         Keyword    = 'RAMP',                                     &
                         Default    = .false.,                                    & 
                         SearchType = FromFile,                                   &
                         ClientModule ='ModuleHydrodynamic',                      &
                         STAT       = STAT_CALL)            

            if (STAT_CALL /= SUCCESS_)                                            &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR36.')

            Me%ComputeOptions%BaroclinicRamp = BaroclinicRamp

            if (BaroclinicRamp) then

                !<BeginKeyword>
                    !Keyword          : INERTIAL_PERIODS
                    !<BeginDescription>       
                       ! 
                       !The period after which the total effect of the baroclinic force is compute
                       !
                       ! 
                    !<EndDescription>
                    !Type             : Real
                    !Default          : 1
                    !File keyword     : IN_DAD3D 
                    !Multiple Options : Do Not Have
                    !Search Type      : From File
                !<EndKeyword>

                call GetData(InertialPeriods,                                         &
                             Me%ObjEnterData, iflag,                     &
                             Keyword    = 'INERTIAL_PERIODS',                         &
                             Default    = 1.,                                         &
                             SearchType = FromFile,                                   &
                             ClientModule ='ModuleHydrodynamic',                      &
                             STAT       = STAT_CALL)            

                if (STAT_CALL /= SUCCESS_)                                            &
                    call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR36a.')

                Me%ComputeOptions%InertialPeriods = InertialPeriods

              if (Me%ComputeOptions%Continuous) then

              !<beginkeyword>
              !Keyword      : RAMP_START
              !Description  : This keyword is used to read the initial data Year Month Day Hour Minutes Seconds
              !Default      : *
              !File keyword : 
              !<endkeyword>
               call GetData(Me%ComputeOptions%RAMP_BeginTime,                                                 &
                      Me%ObjEnterData,                                             &
                      iflag,                                                             &
                      keyword      = 'RAMP_START',                                            &
                      SearchType   = FromFile,                                           &
                      ClientModule ='ModuleHydrodynamic',                                &
                      STAT       = STAT_CALL)          
           
                 if (STAT_CALL /= SUCCESS_)                                            &
                    call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR36b.')
            
                 if (iflag == 0) &
                    stop 'Define RAMP_START!!! Construct_Numerical_Options - Hydrodynamic - ERR36b.' 
              else
               
                Me%ComputeOptions%RAMP_BeginTime = Me%BeginTime
             
              endif
                 
            endif
              
       
        endif cd21



        !<BeginKeyword>
            !Keyword          : VERTICALADVECTION
            !<BeginDescription>       
               ! 
               !Checks  if the user pretends to compute the vertical advection effect 
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .true.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true.  , .false. 
            !Search Type      : From File
        !<EndKeyword>

        call GetData(VerticalAdvection,                                                  &
                     Me%ObjEnterData, iflag,                                             &
                     Keyword    = 'VERTICALADVECTION',                                   &
                    !By default compute always the Vertical Advection
                     Default    = .True.,                                                &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR37.')

        ! If the new keyword is not find the model tries to read the old one.
        if (iflag == 0) then

            call GetData(VerticalAdvection,                                              &
                         Me%ObjEnterData, iflag,                                         &
                         Keyword    = 'VERTICALCONVECTION',                              &
                        !By default compute always the Vertical Advection
                         Default    = .True.,                                            &
                         SearchType = FromFile,                                          &
                         ClientModule ='ModuleHydrodynamic',                             &
                         STAT       = STAT_CALL)            

            if (STAT_CALL /= SUCCESS_)                                                   &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR37a.')



            if (iflag == 1)then
                call SetError (WARNING_, KEYWORD_,                                   &
                     'Change keyword VERTICALCONVECTION to VERTICALADVECTION; ModuleHydrodynamics')
            end if
                                                                   

        endif




        Me%ComputeOptions%VerticalAdvection = VerticalAdvection


        !<BeginKeyword>
            !Keyword          : VERTICALDIFFUSION
            !<BeginDescription>       
               ! 
               !Checks  if the user pretends to compute the vertical diffusion effect 
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .true.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true.  , .false. 
            !Search Type      : From File
        !<EndKeyword>


        call GetData(VerticalDiffusion,                                       &
                     Me%ObjEnterData, iflag,                                  &
                     Keyword    = 'VERTICALDIFFUSION',                        &
                    !By default compute always the Vertical Diffusion
                     Default    = .True.,                                     &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR38.')

        Me%ComputeOptions%VerticalDiffusion = VerticalDiffusion


        !<BeginKeyword>
            !Keyword          : VELTANGENTIALBOUNDARY
            !<BeginDescription>       
               ! 
               !Checks the velocities the user want to impose between two boundary points
               ! 
            !<EndDescription>
            !Type             : Integer
            !Default          : 1
            !File keyword     : IN_DAD3D 
            !Multiple Options : 1 (null value)  , 2 (null gradient)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(VelTangentialBoundary,                                   &
                     Me%ObjEnterData, iflag,                     &
                     Keyword    = 'VELTANGENTIALBOUNDARY',                    &
                    !By default impose a null velocity tangential to the boundary
                     Default    = NULL_GRADIENT,                              & 
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR39.')


        if (VelTangentialBoundary /= NULL_VALUE    .and. &
            VelTangentialBoundary /= NULL_GRADIENT) then

            call SetError(FATAL_, KEYWORD_, 'Construct_Numerical_Options - Hydrodynamic - ERR40.')

        endif

        Me%ComputeOptions%VelTangentialBoundary = VelTangentialBoundary


        !<BeginKeyword>
            !Keyword          : VELNORMALBOUNDARY
            !<BeginDescription>       
               ! 
               !Checks the velocities the user want to impose in the exterior faces
               ! 
            !<EndDescription>
            !Type             : Integer
            !Default          : 1
            !File keyword     : IN_DAD3D 
            !Multiple Options : 1 (null value)  , 2 (null gradient)
            !Search Type      : From File
        !<EndKeyword>


        call GetData(VelNormalBoundary,                                       &
                     Me%ObjEnterData, iflag,                     &
                    !By default is imposed a velocity in the exterior faces equal to the nearest compute face 
                    !The exterior faces have in one side a boundary point and in another a exterior point
                    !The model don't compute advection and diffusion in the boundary points
                     Keyword    = 'VELNORMALBOUNDARY',                        &
                     Default    = NULL_GRADIENT,                              &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR41.')


        if (VelNormalBoundary /= NULL_VALUE .and. &
            VelNormalBoundary /= NULL_GRADIENT) then

            call SetError(FATAL_, KEYWORD_, 'Construct_Numerical_Options - Hydrodynamic - ERR42.')

        endif

        Me%ComputeOptions%VelNormalBoundary = VelNormalBoundary


        !<BeginKeyword>
            !Keyword          : NULL_BOUND_HORADV
            !<BeginDescription>       
               ! 
               !Checks if the user want to assumed null horizontal advection in the open boundary
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .true.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Null Horizontal boundary advection), .false. (compute boundary advection)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(NullBoundaryHorAdv,                                                 &
                     Me%ObjEnterData, iflag,                                &
                     Keyword    = 'NULL_BOUND_HORADV',                                   &
                    !By default the model do not compute advection and diffusion in the boundary points
                     Default    = .true.,                                                &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR43.')


        ! If the new keyword is not find the model tries to read the old one.
        if (iflag == 0) then


            call GetData(NullBoundaryHorAdv,                                             &
                         Me%ObjEnterData, iflag,                            &
                         Keyword    = 'NULL_BOUND_HORCONV',                              &
                        !By default the model do not compute advection and diffusion in the boundary points
                         Default    = .true.,                                            &
                         SearchType = FromFile,                                          &
                         ClientModule ='ModuleHydrodynamic',                             &
                         STAT       = STAT_CALL)            

            if (STAT_CALL /= SUCCESS_)                                                   &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR43a.')


            if (iflag == 1)                                                              &
                call SetError (WARNING_, KEYWORD_,                                       &
                               'Change keyword NULL_BOUND_HORCONV to NULL_BOUND_HORADV; ModuleHydrodynamics')                                                   

        endif


        Me%ComputeOptions%NullBoundaryHorAdv = NullBoundaryHorAdv


        !<BeginKeyword>
            !Keyword          : TIDEPOTENTIAL
            !<BeginDescription>       
               ! 
               !Checks if the user want to consider the effect of the potential tide
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(ComputeTidePotential,                                               &
                     Me%ObjEnterData, iflag,                                &
                     Keyword    = 'TIDEPOTENTIAL',                                       &
                    !By default the tide potential is not compute
                     Default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR44.')


        Me%TidePotential%Compute = ComputeTidePotential


        !<BeginKeyword>
            !Keyword          : WIND
            !<BeginDescription>       
               ! 
               !Checks if the user want to consider the effect of the wind stress
               !By default the wind stress is not compute
               ! 
            !<EndDescription>
            !Type             : integer
            !Default          : 0 (No wind forcing)
            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (No wind forcing), 1(wind forcing), 2(wind forcing with a smooth start)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(ComputeWind,                                              & 
                     Me%ObjEnterData, iflag,                      & 
                     Keyword    = 'WIND',                                      &
                     Default    = NoWind_,                                     &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR45.')

        Me%ComputeOptions%Wind = ComputeWind


        !<BeginKeyword>
            !Keyword          : WIND_SMOOTH_PERIOD
            !<BeginDescription>       
               ! 
               !The user specify the wind smooth period
               ! 
            !<EndDescription>
            !Type             : real
            !Default          : 86400. 
            !File keyword     : IN_DAD3D 
            !Search Type      : From File
        !<EndKeyword>

        call GetData(SmoothInitialPeriod,                                      & 
                     Me%ObjEnterData, iflag,                      & 
                     Keyword    = 'WIND_SMOOTH_PERIOD',                        &
                     Default    = 86400.,                                      &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                             &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR45a.')

        Me%ComputeOptions%SmoothInitialPeriod = SmoothInitialPeriod

        if (Me%ComputeOptions%SmoothInitialPeriod <= 0.)          &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR45b.')
        
        if ( .not. Me%State%Surface .and. ComputeWind /= NoWind_) &
            Me%State%Surface = .true.

        !<BeginKeyword>
            !Keyword          : ATM_PRESSURE
            !<BeginDescription>       
               ! 
               !Checks if the user wants to consider the effect of the Atmospheric Pressure
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(ComputeAtmPressure,                                       &
                     Me%ObjEnterData, iflag,                      &
                     Keyword    = 'ATM_PRESSURE',                              &
                    !By default the Atmospheric Pressure is not compute
                     Default    = .false.,                                     &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR46.')

        Me%ComputeOptions%AtmPressure = ComputeAtmPressure

        if (.not. Me%State%Surface) &
            Me%State%Surface = ComputeAtmPressure

        !<BeginKeyword>
            !Keyword          : SURFACEWATERFLUX
            !<BeginDescription>       
               ! 
               !Checks if the user want to consider the effect of precipitation and evaporation
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>
        

        call GetData(ComputeSurfaceWaterFlux,                                  &
                     Me%ObjEnterData, iflag,                      &
                     Keyword    = 'SURFACEWATERFLUX',                          &
                     !By default the SurfaceWaterFlux is not compute
                     Default    = .false.,                                     &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR47.')

        Me%ComputeOptions%SurfaceWaterFlux = ComputeSurfaceWaterFlux

        if (.not. Me%State%Surface) &
            Me%State%Surface = ComputeSurfaceWaterFlux


        !<BeginKeyword>
            !Keyword          : HMIN_CHEZY
            !<BeginDescription>       
               ! 
               !Checks the minimum water column height below which the chezy coefficient is constant
               !By default Hmin_Chezy is equal to 10 cm 
               ! 
            !<EndDescription>
            !Type             : Real
            !Default          : 0.10  
            !Units            : meters
            !File keyword     : IN_DAD3D 
            !Search Type      : From File
        !<EndKeyword>
        
        call GetData(Hmin_Chezy,                                               &
                     Me%ObjEnterData, iflag,                      &
                     Keyword    = 'HMIN_CHEZY',                                &
                     Default    = 0.10,                                        &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                             &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR48.')
        

        Me%External_Var%Hmin_Chezy = Hmin_Chezy

        !<BeginKeyword>
            !Keyword          : VMIN_CHEZY
            !<BeginDescription>       
               ! 
               !Checks the minimum velocity (Vmin_Chezy) below which the chezy coefficient 
               !is constant if the water column is smaller than Hmin_Chezy
               !By default Vmin_Chezy is equal to 0.10 m/s
               ! 
            !<EndDescription>
            !Type             : Real
            !Default          : 0.10  
            !Units            : m/s
            !File keyword     : IN_DAD3D 
            !Search Type      : From File
        !<EndKeyword>
        
        call GetData(Vmin_Chezy,                                               &
                     Me%ObjEnterData, iflag,                      &
                     Keyword    = 'VMIN_CHEZY',                                &
                     Default    = 0.10,                                        &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                             &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR48a.')
        

        Me%External_Var%Vmin_Chezy = Vmin_Chezy



        !<BeginKeyword>
            !Keyword          : DATA_ASSIMILATION
            !<BeginDescription>       
               ! 
               !Checks if the user want to impose a flow relaxation boundary condition
               !By default do not use flow relaxation boundary condition
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>
        
        call GetData(Relaxation,                                                         &
                     Me%ObjEnterData, iflag,                                &
                     Keyword    = 'DATA_ASSIMILATION',                                   &
                     Default    = .false.,                                               & 
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            

        
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR49.') 

        Me%ComputeOptions%Relaxation = Relaxation

        !<BeginKeyword> guillaume nogueira
            !Keyword          : ALTIMETRIC_ASSIMILATION
            !<BeginDescription>       
               ! 
               ! Checks if the user wants to assimilate altimetry with Cooper-Haines
               ! method.
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>
        
        call GetData(Me%ComputeOptions%AltimetryAssimilation%Yes,                                                         &
                     Me%ObjEnterData, iflag,                                &
                     Keyword    = 'ALTIMETRIC_ASSIMILATION',                                   &
                     Default    = .false.,                                               & 
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR49.') 


        !<BeginKeyword>
            !Keyword          : IMPLICIT_HORADVECTION
            !<BeginDescription>       
               ! 
               !Checks if the user wants to compute the horizontal advection implicitly
               !By default the model do not compute the horizontal advection implicitly
               !
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>



        call GetData(ImplicitAdvection,                                                  & 
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'IMPLICIT_HORADVECTION',                               & 
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            

        
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR51.') 

        ! If the new keyword is not find the model tries to read the old one.
        if (iflag == 0) then

            call GetData(ImplicitAdvection,                                              & 
                         Me%ObjEnterData, iflag,                            &
                         keyword    = 'IMPLICIT_HORCONVECTION',                          & 
                         default    = .false.,                                           &
                         SearchType = FromFile,                                          &
                         ClientModule ='ModuleHydrodynamic',                             &
                         STAT       = STAT_CALL)            

        
            if (STAT_CALL /= SUCCESS_)                                                   &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR51a.') 



            if (iflag == 1)                                                              &
                call SetError (WARNING_, KEYWORD_,                                       &
                               'Change keyword IMPLICIT_HORCONVECTION to IMPLICIT_HORADVECTION; ModuleHydrodynamics')                                                   

        endif




        Me%ComputeOptions%ImplicitAdvection = ImplicitAdvection


        !<BeginKeyword>
            !Keyword          : RECORDING
            !<BeginDescription>       
               ! 
               !Checks if the user wants to record the hydrodynamic properties in binary format
               !that can be used latter by the option 'Read_File' of the Keyword = EVOLUTION
               !By default the model do not record the flow properties
               !
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>


        call GetData(Me%ComputeOptions%Recording,                          &
                     Me%ObjEnterData, iflag,                               &
                     Keyword    = 'RECORDING',                                          &
                     Default    = .false.,                                              &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR52.')


        !<BeginKeyword>
            !Keyword          : MOMENTUM_DISCHARGE
            !<BeginDescription>       
               ! 
               !Checks if the user wants to do a discharge of momentum
               !By default the model do not have momentum discharges
               !
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%ComputeOptions%MomentumDischarge,                   &
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'MOMENTUM_DISCHARGE',                                  &
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR53.')


        !<BeginKeyword>
            !Keyword          : SLOWSTART
            !<BeginDescription>       
               ! 
               !Imposed a specific period in seconds after which
               !the model consider the total imposed boundary wave 
               !Along this period the wave amplitude is multiplie by
               !coefficiente that has linear evolution between 0 and 1.
               !By default this period is zero seconds
               !
            !<EndDescription>
            !Type             : Real
            !Default          : 0
            !Units            : seconds
            !File keyword     : IN_DAD3D 
            !Multiple Options : Do not 
            !Search Type      : From File
        !<EndKeyword>


        !By default do not make a slow start TideSlowStartCoef = 0.
        call GetData(TideSlowStartCoef,                                       & 
                     Me%ObjEnterData, iflag,                     &
                     keyword    = 'SLOWSTART',                                & 
                     default    = 0.,                                         &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        
        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR54.') 


        Me%ComputeOptions%TideSlowStartCoef = TideSlowStartCoef

        !<BeginKeyword>
            !Keyword          : HMIN_ADVECTION
            !<BeginDescription>       
               ! 
               !The user can impose a specific water column heigth below which the 
               !horizontal advection is not compute
               !By default when the water column has less then 0.5 m the advection in not compute
               !
            !<EndDescription>
            !Type             : Real
            !Default          : 0.5 
            !Units            : meters
            !File keyword     : IN_DAD3D 
            !Multiple Options : Do not 
            !Search Type      : From File
        !<EndKeyword>



        call GetData(Hmin_Advection,                                          & 
                     Me%ObjEnterData, iflag,                     &
                     keyword    = 'HMIN_ADVECTION',                           & 
                     default    = 0.50,                                       &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        
        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR55.') 

        ! If the new keyword is not find the model tries to read the old one.
        if (iflag == 0) then

            call GetData(Hmin_Advection,                                          & 
                         Me%ObjEnterData, iflag,                     &
                         keyword    = 'HMIN_CONVECTION',                          & 
                         default    = 0.50,                                       &
                         SearchType = FromFile,                                   &
                         ClientModule ='ModuleHydrodynamic',                      &
                         STAT       = STAT_CALL)            

        
            if (STAT_CALL /= SUCCESS_)                                            &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR55a.') 


            if (iflag == 1)                                                              &
                call SetError (WARNING_, KEYWORD_,                                       &
                               'Change keyword HMIN_CONVECTION to HMIN_ADVECTION; ModuleHydrodynamics')                                                   

        endif




        Me%ComputeOptions%Hmin_Advection = Hmin_Advection


        !<BeginKeyword>
            !Keyword          : LOCAL_DENSITY
            !<BeginDescription>       
               ! 
               ! Check if the user want to devide the baroclinic pressure by the 
               ! local density to compute. if this option is false is used the reference density 
               !  
               ! 
            !<EndDescription>
            !Type             : Logical 
            !Default          : .true.
            !File keyword     : IN_DAD3D
            !Multiple Options : 0 (false), 1 (true)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%ComputeOptions%LocalDensity,                          & 
                     Me%ObjEnterData, iflag,                                  &
                     keyword    = 'LOCAL_DENSITY',                            & 
                     default    = .true.,                                     &
                     SearchType = FromFile,                                   &
                     ClientModule ='ModuleHydrodynamic',                      &
                     STAT       = STAT_CALL)            

        
        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR56.') 


        
        !<BeginKeyword>
            !Keyword          : CYCLIC_BOUNDARY
            !<BeginDescription>       
               ! 
               ! Check if the user wants to impose a CYCLIC boundary condition
               !  
               ! 
            !<EndDescription>
            !Type             : logical
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Multiple Options : .false. (without Cyclic boundary), .true. (with Cyclic boundary)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%CyclicBoundary%ON,                                               & 
                     Me%ObjEnterData, iflag,                                             &
                     keyword    = 'CYCLIC_BOUNDARY',                                     & 
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            

        
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR57.') 


        !<BeginKeyword>
            !Keyword          : CYCLIC_DIRECTION
            !<BeginDescription>       
               ! 
               ! Check along which direction the user wants to impose a CYCLIC boundary condition
               !  
               ! 
            !<EndDescription>
            !Type             : integer
            !Default          : DirectionXY_
            !File keyword     : IN_DAD3D
            !Multiple Options : DirectionXY_ (Directions X and Y), DirectionX_ (X direction), DirectionY_ (Y direction)
            !Search Type      : From File
        !<EndKeyword>



        if (Me%CyclicBoundary%ON) then

            call GetData(Me%CyclicBoundary%Direction,                                    & 
                         Me%ObjEnterData, iflag,                                         &
                         keyword    = 'CYCLIC_DIRECTION',                                & 
                         default    = DirectionXY_,                                      &
                         SearchType = FromFile,                                          &
                         ClientModule ='ModuleHydrodynamic',                             &
                         STAT       = STAT_CALL)            
        
            if (STAT_CALL /= SUCCESS_)                                                   &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR57a.') 

        endif

        !<BeginKeyword>
            !Keyword          : CONSERVATIVE_HOR_DIF
            !<BeginDescription>       
               ! 
               ! Check if the user wants to compute the horizontal 
               ! diffusion in a conservative way.
               !  
               ! 
            !<EndDescription>
            !Type             : logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%ComputeOptions%ConservativeHorDif,                  & 
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'CONSERVATIVE_HOR_DIF',                                & 
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR58.') 

    
        !<BeginKeyword>
            !Keyword          : BIHARMONIC
            !<BeginDescription>       
               ! 
               ! Check if the user wants to compute the horizontal diffusion 
               ! of momentum with a bi-harmonic formulation
               !  
               ! 
            !<EndDescription>
            !Type             : logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%ComputeOptions%BiHarmonic,                                      & 
                     Me%ObjEnterData, iflag,                                            &
                     keyword    = 'BIHARMONIC',                                         & 
                     default    = .false.,                                              &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            
        
        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR59.') 

        !<BeginKeyword>
            !Keyword          : BIHARMONIC_COEF
            !<BeginDescription>       
               ! 
               ! horizontal diffusion ocefficent used when the bi-harmonic option is on
               !  
               ! 
            !<EndDescription>
            !Type             : real 
            !Default          : 1e9
            !File keyword     : IN_DAD3D
            !Search Type      : From File
        !<EndKeyword>

        if (Me%ComputeOptions%BiHarmonic) then

            call GetData(Me%ComputeOptions%BiHarmonicCoef,                              & 
                         Me%ObjEnterData, iflag,                                        &
                         keyword    = 'BIHARMONIC_COEF',                                & 
                         default    = 1e9,                                              &
                         SearchType = FromFile,                                         &
                         ClientModule ='ModuleHydrodynamic',                            &
                         STAT       = STAT_CALL)            
        
            if (STAT_CALL /= SUCCESS_)                                                  &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR60.') 
        endif

        !<BeginKeyword>
            !Keyword          : SUBMODEL
            !<BeginDescription>       
               ! 
               ! Check if the user wants to run this model as a submodel
               !  
               ! 
            !<EndDescription>
            !Type             : logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%SubModel%ON,                                        & 
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'SUBMODEL',                                            & 
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR61.') 

        !PCL - temporary
        Me%SubModel%ON22 = .false.


        !<BeginKeyword>
            !Keyword          : MISSING_NULL
            !<BeginDescription>       
               ! 
               ! Check if the user wants to replace the missing values by zero 
               !  
               ! 
            !<EndDescription>
            !Type             : logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%SubModel%MissingNull,                               & 
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'MISSING_NULL',                                        & 
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR61c.') 




        !<BeginKeyword>
            !Keyword          : DEADZONE
            !<BeginDescription>       
               ! 
               ! Check if the user wants to define a dead zone where the submodel do not 
               ! look for information in the father model
               !  
               ! 
            !<EndDescription>
            !Type             : logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%SubModel%DeadZone,                                  & 
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'DEADZONE',                                            & 
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR61a.') 

        !<BeginKeyword>
            !Keyword          : DEADZONE_FILE
            !<BeginDescription>       
               ! 
               ! file name where the dead zone is defined was polygon 
               !  
               ! 
            !<EndDescription>
            !Type             : logical 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%SubModel%DeadZoneFile,                              & 
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'DEADZONE_FILE',                                       & 
                     default    = '******.***',                                          &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR61b.') 


!Manuel MRV

        !<BeginKeyword>
            !Keyword          : BOTTOMVISC_LIM
            !<BeginDescription>       
               ! 
               !Limitation of viscosity at the bottom due to semi-implicit discretization of shear stress on hydrodynamic
               ! equations.
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Multiple Options : .true. , .false.
            !Search Type      : From File
        !<EndKeyword> 
        
        call GetData(Me%ComputeOptions%BottomVisc_LIM,                      &
             Me%ObjEnterData, iflag,                                        &
             keyword    = 'BOTTOMVISC_LIM',                                              &
             Default    = .false.,                                                       &
             ClientModule ='ModuleHydrodynamic',                                         &
             STAT       = STAT_CALL)            
    
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR61.')
        
        if (Me%ComputeOptions%BottomVisc_LIM) then

        !<BeginKeyword>
            !Keyword          : BOTTOMVISC_COEF
            !<BeginDescription>       
               ! 
               ! Factor that multiplies diffusion number for imposing a maximum viscosity at bottom layer 
               ! ( coefficient of turbulence transport between layers kbottom and kbottom +1, i.e. viscosity(kbottom+1) )
               ! Maximum viscosity = BottomVisc_MAX*dz*dz/2/dt/Viscosity(kbottom+1)
               ! 
            !<EndDescription>
            !Type             : Real
            !Default          : 5.
            !File keyword     : IN_DAD3D
            !Search Type      : From File
        !<EndKeyword>         
                              
            call GetData(Me%ComputeOptions%BottomViscCoef,                  & 
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'BOTTOMVISC_COEF',                                     & 
                     default    = 5.,                                                    &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)                                            
                                                                                        
            if (STAT_CALL /= SUCCESS_)                                                   &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR62.') 

        endif
        
!EndManuel

        !<BeginKeyword>
            !Keyword          : BAROCLINIC_RADIATION
            !<BeginDescription>       
               ! 
               ! Check if the user wants to radiate internal tides
               !  
               ! 
            !<EndDescription>
            !Type             : integer 
            !Default          : NoRadiation_
            !Options          : 0 - NoRadiation_, 1 - Horizontal_, 2 - Vertical_
            !File keyword     : IN_DAD3D
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%ComputeOptions%BaroclinicRadia,                     & 
                     Me%ObjEnterData, iflag,                                &
                     keyword    = 'BAROCLINIC_RADIATION',                                & 
                     default    = NoRadiation_,                                          &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = STAT_CALL)            
        
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR63')


        !<BeginKeyword>
            !Keyword          : LOCAL_SOLUTION
            !<BeginDescription>       
               ! 
               !Check what type o local (or reference) solution the user wants to use as a reference for the radiative and 
               !relaxation boundary conditions
               !  
               ! 
            !<EndDescription>
            !Type             : integer 
            !Default          : NoRadiation_
            !Options          : 1 - NoLocalSolution_, 2 - Submodel_, 3 - AssimilationField_, 4 - Gauge_, 5 - AssimilaPlusSubModel_
            !File keyword     : IN_DAD3D
            !Search Type      : From File
        !<EndKeyword>


        call GetData(Me%ComputeOptions%LocalSolution,                   &  
                     Me%ObjEnterData, iflag,                            &
                     keyword    = 'LOCAL_SOLUTION',                                  & 
                     default    = NoLocalSolution_,                                  &
                     SearchType = FromFile,                                          &
                     ClientModule ='ModuleHydrodynamic',                             &
                     STAT       = STAT_CALL)            
    
        if (STAT_CALL /= SUCCESS_)                                                   &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR72')

        if (BarotropicRadia == FlatherLocalSolution_ .and.                              &
            (Me%ComputeOptions%LocalSolution == AssimilationField_ .or.                 &
             Me%ComputeOptions%LocalSolution == AssimilaPlusSubModel_)) then 


            !<BeginKeyword>
                !Keyword          : FLAHER_COLD_PERIOD
                !<BeginDescription>       
                   ! 
                   !Periode along each the local solution defined in the assimilation module is slowly
                   !connected
                   ! 
                !<EndDescription>
                !Type             : real 
                !Default          : 0.
                !File keyword     : IN_DAD3D
                !Search Type      : From File
            !<EndKeyword>


            call GetData(Me%ComputeOptions%FlatherColdPeriod,                           &  
                         Me%ObjEnterData, iflag,                                        &
                         keyword    = 'FLATHER_COLD_PERIOD',                            & 
                         default    = 0.,                                               &
                         SearchType = FromFile,                                         &
                         ClientModule ='ModuleHydrodynamic',                            &
                         STAT       = STAT_CALL)                                            
                                                                                        
            if (STAT_CALL /= SUCCESS_)                                                  &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR72a')

            if (Me%ComputeOptions%FlatherColdPeriod > (Me%EndTime - Me%BeginTime))      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR72b')


            !<BeginKeyword>
                !Keyword          : FLAHER_COLD_SEALEVEL
                !<BeginDescription>       
                   ! 
                   !Average water level for SSH defined in the assimilation module
                   ! 
                !<EndDescription>
                !Type             : real 
                !Default          : 0.
                !File keyword     : IN_DAD3D
                !Search Type      : From File
            !<EndKeyword>


            call GetData(Me%ComputeOptions%FlatherColdSeaLevel,                         &  
                         Me%ObjEnterData, iflag,                                        &
                         keyword    = 'FLATHER_COLD_SEALEVEL',                          & 
                         default    = 0.,                                               &
                         SearchType = FromFile,                                         &
                         ClientModule ='ModuleHydrodynamic',                            &
                         STAT       = STAT_CALL)                                            
                                                                                        
            if (STAT_CALL /= SUCCESS_)                                                  &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR72c')

  
        endif

        !<BeginKeyword>
            !Keyword          : CORRECT_WATERLEVEL
            !<BeginDescription>       
               ! 
               !check if the user wants to corrected the water level when it is lower than a
               !reference water level
               ! 
            !<EndDescription>
            !Type             : logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>
        

        call GetData(Me%ComputeOptions%CorrectWaterLevel,               &  
                     Me%ObjEnterData, iflag,                            &
                     keyword    = 'CORRECT_WATERLEVEL',                              & 
                     default    = .false.,                                           &
                     SearchType = FromFile,                                          &
                     ClientModule ='ModuleHydrodynamic',                             &
                     STAT       = STAT_CALL)            
    
        if (STAT_CALL /= SUCCESS_)                                                   &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR73')

        !<BeginKeyword>
            !Keyword          : MIN_WATERLEVEL
            !<BeginDescription>       
               ! 
               !reference level below which the water level is corrected.
               !
            !<EndDescription>
            !Type             : real
            !Default          : 0.
            !File keyword     : IN_DAD3D 
            !Multiple Options : 
            !Search Type      : From File
        !<EndKeyword>
        

        call GetData(Me%ComputeOptions%WaterLevelMin,                   &  
                     Me%ObjEnterData, iflag,                            &
                     keyword    = 'MIN_WATERLEVEL',                                  & 
                     default    = 0.,                                                &
                     SearchType = FromFile,                                          &
                     ClientModule ='ModuleHydrodynamic',                             &
                     STAT       = STAT_CALL)            
    
        if (STAT_CALL /= SUCCESS_)                                                   &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR74')


        !<BeginKeyword>
            !Keyword          : BOTTOMWATERFLUX
            !<BeginDescription>       
               ! 
               !Checks if the user want to consider the effect of the soil infiltration or consolidation
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>
        

        call GetData(Me%ComputeOptions%BottomWaterFlux,           &
                     Me%ObjEnterData, iflag,                      &
                     Keyword    = 'BOTTOMWATERFLUX',                           &
                     !By default the SurfaceWaterFlux is not compute
                     Default    = .false.,                                     &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR75.')

        !<BeginKeyword>
            !Keyword          : SLIPPING_CONDITION
            !<BeginDescription>       
               ! 
               !Checks if the user want to consider the slipping conditition for horizontal diffusion
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .true.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>
        

        call GetData(Me%ComputeOptions%SlippingCondition,         &
                     Me%ObjEnterData, iflag,                      &
                     Keyword    = 'SLIPPING_CONDITION',                        &
                     !By default the splipping condition is on
                     Default    = .true.,                                      &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR76.')


        if (Me%TidePotential%Compute) then

            !<BeginKeyword>
                !Keyword          : POTENTIAL_ALGORITHM 
                !<BeginDescription>       
                   ! 
                   ! 
                   ! 
                !<EndDescription>
                !Type             : integer 
                !Default          : .false.
                !File keyword     : IN_DAD3D
                !Multiple Options : Do not have
                !Search Type      : FromFile
            !<EndKeyword>
            call GetData(Me%TidePotential%Algorithm,                            &
                         Me%ObjEnterData, iflag,                                &
                         keyword    = 'POTENTIAL_ALGORITHM',                                 & 
                         default    = Lefevre,                                               &
                         SearchType = FromFile,                                              &
                         ClientModule ='ModuleHydrodynamic',                                 &
                         STAT       = STAT_CALL)            
            if (STAT_CALL /= SUCCESS_)                                                       &
                call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR78.')

        endif

        !<BeginKeyword>
            !Keyword          : NONHYDROSTATIC
            !<BeginDescription>       
               ! 
               !Checks if the user want to compute the effect of local vertical aceleration over the pressure field
               ! 
            !<EndDescription>
            !Type             : Logical
            !Default          : .false.
            !File keyword     : IN_DAD3D 
            !Multiple Options : .true. (Yes), .false. (No)
            !Search Type      : From File
        !<EndKeyword>
        

        call GetData(Me%NonHydrostatic%ON,                                     &
                     Me%ObjEnterData, iflag,                                   &
                     Keyword    = 'NONHYDROSTATIC',                            &
                     !By default the model is hydrostatic
                     Default    = .false.,                                     &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR79.')

        !NonHydrostatic
        if (Me%NonHydrostatic%ON) then
            Me%NonHydrostatic%ThetaW = 0.5
        else
            Me%NonHydrostatic%ThetaW = FillValueReal
        endif


        !<BeginKeyword>
            !Keyword          : WATERCOLUMN2D
            !<BeginDescription>       
               ! 
               !water column thickness below which the 3D proceesses are disconnected 
               ! 
            !<EndDescription>
            !Type             : real
            !Default          : -9e+15
            !File keyword     : IN_DAD3D 
            !Multiple Options : 
            !Search Type      : From File
        !<EndKeyword>
        

        call GetData(Me%ComputeOptions%WaterColumn2D,             &
                     Me%ObjEnterData, iflag,                      &
                     Keyword    = 'WATERCOLUMN2D',                             &
                     !By default the model do not disconnect the 3D processes
                     Default    = FillValueReal,                               &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                            &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR80.')

        !<BeginKeyword>
            !Keyword          : WAVE_STRESS
            !<BeginDescription>       
               ! 
               !Checks if the user want to consider the effect of the waves stress
               !By default the waves stress is not compute
               ! 
            !<EndDescription>
            !Type             : logical
            !Default          : 0 (No wave stress)
            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (No), 1(Yes)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%ComputeOptions%WaveStress,                             & 
                     Me%ObjEnterData, iflag,                                   & 
                     Keyword    = 'WAVE_STRESS',                               &
                     Default    = .false.,                                     &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                             &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR81.')

        !<BeginKeyword>
            !Keyword          : OBSTACLE
            !<BeginDescription>       
               ! 
               !Checks if the user want to parameteriza the influence of an
               !OBSTACLE in the flow, giving a determined drag coefficient
               !By default the OBSTACLE force is not compute
               ! 
            !<EndDescription>
            !Type             : logical
            !Default          : 0 (No OBSTACLE)
            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (No OBSTACLE, 1(OBSTACLE parameterization)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%ComputeOptions%Obstacle,                                & 
                     Me%ObjEnterData, iflag,                                    & 
                     Keyword    = 'OBSTACLE',                                   &
                     Default    = .false.,                                      &
                     SearchType = FromFile,                                     &
                     ClientModule ='ModuleHydrodynamic',                        &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                              &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR282.')


        !<BeginKeyword>
            !Keyword          : CENTRIFUGAL
            !<BeginDescription>       
               ! 
               !Checks if the user want to consider the CENTRIFUGAL force
               !By default the CENTRIFUGAL force is not compute
               ! 
            !<EndDescription>
            !Type             : logical
            !Default          : 0 (No CENTRIFUGAL force)
            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (No CENTRIFUGAL force), 1(CENTRIFUGAL force)
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%ComputeOptions%CentrifugalForce,                       & 
                     Me%ObjEnterData, iflag,                                   & 
                     Keyword    = 'CENTRIFUGAL',                               &
                     Default    = .false.,                                     &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                             &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR82.')


        if (Me%ComputeOptions%CentrifugalForce .or. Me%ComputeOptions%Coriolis) then

            Me%ComputeOptions%InertiaForces = .true.

        else

            Me%ComputeOptions%InertiaForces = .false.

        endif

        call GetData(Me%ComputeOptions%AdvectionMethodH,                                & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'ADV_METHOD_H',                                       &
                     Default    = UpwindOrder1,                                         &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR182.')


        call GetData(Me%ComputeOptions%AdvectionMethodV,                                & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'ADV_METHOD_V',                                       &     
                     Default    = UpwindOrder1,                                         &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR187.')

        call GetData(Me%ComputeOptions%TVD_LimH,                                        & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'TVD_LIMIT_H',                                        &
                     Default    = Superbee,                                             &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR192.')


        call GetData(Me%ComputeOptions%TVD_LimV,                                        & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'TVD_LIMIT_V',                                        &
                     Default    = Superbee,                                             &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR197.')


        call GetData(Me%ComputeOptions%VolumeRelMax,                                    & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'VOLUME_RELATION_MAX',                                &
                     Default    = 5.,                                                   &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR202.')

        if (Me%ComputeOptions%AdvectionMethodH == UpwindOrder2 .or.                      &
            Me%ComputeOptions%AdvectionMethodH == UpwindOrder3 .or.                      &
            Me%ComputeOptions%AdvectionMethodH == P2_TVD) then
            Me%ComputeOptions%Upwind2H = .true.
        else
            Me%ComputeOptions%Upwind2H = .false.
        endif

        if (Me%ComputeOptions%AdvectionMethodV == UpwindOrder2 .or.                      &
            Me%ComputeOptions%AdvectionMethodV == UpwindOrder3 .or.                      &
            Me%ComputeOptions%AdvectionMethodV == P2_TVD) then
            Me%ComputeOptions%Upwind2V = .true.
        else
            Me%ComputeOptions%Upwind2V = .false.
        endif


        call GetData(Me%ComputeOptions%BaroclinicMethod,                                & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'BAROCLINIC_METHOD',                                  &
                     Default    = Leibniz2,                                             &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR207.')

        call GetData(Me%ComputeOptions%BaroclinicPoliDegree,                            & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'BAROCLINIC_POLIDEGREE',                              &
                     Default    = 3,                                                    &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR217.')

        call GetData(Me%NonHydroStatic%Residual,                                        & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'NH_RESIDUAL',                                        &
                     Default    = 10e-6,                                                &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR218.')        

        call GetData(Me%NonHydroStatic%Maxit,                                           & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'NH_MAXIT',                                           &
                     Default    = 500,                                                  &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR220.')        

         call GetData(Me%NonHydroStatic%NormalizedResidual,                             & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'NH_NORMALIZED_RESIDUAL',                             &
                     Default    = .false.,                                              &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR221.')        

        call GetData(Me%NonHydroStatic%ThetaW,                                          & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'NH_IMPLICIT_COEF_W',                                 &
                     Default    = 0.5,                                                  &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR222.')        

        if((Me%NonHydroStatic%ThetaW<0.5).or.(Me%NonHydroStatic%ThetaW>1.0)) then
            Me%NonHydroStatic%ThetaW = 0.5
        endif

        call GetData(Me%NonHydroStatic%AlphaLU,                                         & 
                     Me%ObjEnterData, iflag,                                            & 
                     Keyword    = 'NH_ALPHA_LU',                                        &
                     Default    = 0.5,                                                  &
                     SearchType = FromFile,                                             &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR223.')        

        if((Me%NonHydroStatic%AlphaLU<0.).or.(Me%NonHydroStatic%AlphaLU>1.0)) then
            Me%NonHydroStatic%AlphaLU = 0.5
        endif


        call GetData(Me%ComputeOptions%Vertical_AxiSymmetric_Model,            & 
                     Me%ObjEnterData, iflag,                                   &
                     Keyword    = 'VERTICAL_AXISYMMETRIC',                     &
                     Default    = 0,                                           &
                     SearchType = FromFile,                                    &
                     ClientModule ='ModuleHydrodynamic',                       &
                     STAT       = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR224.')    
            
        if (Me%ComputeOptions%Vertical_AxiSymmetric_Model /= 0           .and.          &
            Me%ComputeOptions%Vertical_AxiSymmetric_Model /= DirectionX_ .and.          &                 
            Me%ComputeOptions%Vertical_AxiSymmetric_Model /= DirectionY_ ) then
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR234.')    
        endif 

        if (Me%ComputeOptions%Vertical_AxiSymmetric_Model == DirectionX_ .and. Me%WorkSize%IUB /= 3) &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR244.')    

        if (Me%ComputeOptions%Vertical_AxiSymmetric_Model == DirectionY_ .and. Me%WorkSize%JUB /= 3) &
            call SetError(FATAL_, INTERNAL_, 'Construct_Numerical_Options - Hydrodynamic - ERR254.')    


    End Subroutine Construct_Numerical_Options

    !End-----------------------------------------------------------------------

    Subroutine Construct_RadiaBaroclinic
    
        !Arguments-------------------------------------------------------------

        !Local-----------------------------------------------------------------

        integer :: FromFile
        integer :: status, iflag

        integer :: ILB, IUB
        integer :: JLB, JUB
        integer :: KLB, KUB
        integer :: MaxNormX, MaxNormY
        integer :: MaxTangX, MaxTangY, i

        !Begin-----------------------------------------------------------------

        ILB = Me%Size%ILB 
        IUB = Me%Size%IUB 

        JLB = Me%Size%JLB 
        JUB = Me%Size%JUB 

        KLB = Me%Size%KLB 
        KUB = Me%Size%KUB 

        
     
        call GetExtractType(FromFile = FromFile)


        call GetData(Me%VelBaroclinic%CelerityType,                                      & 
                     Me%ObjEnterData, iflag,                                             &
                     keyword    = 'CELERITY_TYPE',                                       &  
                     default    = Constant_,                                             &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = status)            
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, KEYWORD_, 'Construct_RadiaBaroclinic - Hydrodynamic - ERR01')


        call GetData(Me%VelBaroclinic%InternalCelerity,                                  & 
                     Me%ObjEnterData, iflag,                                             &
                     keyword    = 'INTERNAL_CELERITY',                                   & 
                     default    = 2.,                                                    &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = status)            
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, KEYWORD_, 'Construct_RadiaBaroclinic - Hydrodynamic - ERR02')

        call GetData(Me%VelBaroclinic%TRelaxIn,                                          &  
                     Me%ObjEnterData, iflag,                                             &
                     keyword    = 'DECAY_IN',                                            & 
                     default    = 86400.,                                                &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = status)            
    
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, KEYWORD_, 'Construct_RadiaBaroclinic - Hydrodynamic - ERR03')


        call GetData(Me%VelBaroclinic%TRelaxOut,                                         &  
                     Me%ObjEnterData, iflag,                                             &
                     keyword    = 'DECAY_OUT',                                           & 
                     default    = 8640000.,                                              &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = status)            
    
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, KEYWORD_, 'Construct_RadiaBaroclinic - Hydrodynamic - ERR04')


        call GetData(Me%VelBaroclinic%MinLeavingBaroclincVel,                            &  
                     Me%ObjEnterData, iflag,                                             &
                     keyword    = 'MINVEL_BAROCLINIC',                                   & 
                     default    = 1e-6,                                                  &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = status)            
    
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, KEYWORD_, 'Construct_RadiaBaroclinic - Hydrodynamic - ERR05')

        call GetData(Me%VelBaroclinic%BaroclinicNormalRadiation,                         &  
                     Me%ObjEnterData, iflag,                                             &
                     keyword    = 'NORMAL_BAROCLINIC',                                   & 
                     default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = status)            
    
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, KEYWORD_, 'Construct_RadiaBaroclinic - Hydrodynamic - ERR06')




        call GetData(Me%VelBaroclinic%BaroclinicOBCDiscret,                              &  
                     Me%ObjEnterData, iflag,                                             &
                     keyword    = 'BAROCLINIC_OBC_DISCRET',                              & 
                     default    = Implicit_,                                             &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = status)            
    
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, KEYWORD_, 'Construct_RadiaBaroclinic - Hydrodynamic - ERR07')

        if (Me%VelBaroclinic%BaroclinicOBCDiscret == StoreWave_) then

            call GetData(Me%VelBaroclinic%DTWave,                                        &    
                         Me%ObjEnterData, iflag,                                         &
                         keyword    = 'BAROCLINIC_WAVE_DT',                              & 
                         default    = Me%Velocity%DT,                                    &
                         SearchType = FromFile,                                          &
                         ClientModule ='ModuleHydrodynamic',                             &
                         STAT       = status)            
    
            if (status /= SUCCESS_)                                                      &
                call SetError(FATAL_, KEYWORD_, 'Construct_RadiaBaroclinic - Hydrodynamic - ERR07a')

        endif
                   
                   
        allocate (Me%VelBaroclinic%W_New(ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%VelBaroclinic%W_Old(ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%VelBaroclinic%U%New(ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%VelBaroclinic%U%Old(ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%VelBaroclinic%V%New(ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%VelBaroclinic%V%Old(ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%VelBaroclinic%U2D  (ILB:IUB, JLB:JUB))
        allocate (Me%VelBaroclinic%V2D  (ILB:IUB, JLB:JUB)) 

        Me%VelBaroclinic%W_New(:,:,:) = FillValueReal
        Me%VelBaroclinic%W_Old(:,:,:) = FillValueReal
        Me%VelBaroclinic%U%New(:,:,:) = FillValueReal
        Me%VelBaroclinic%U%Old(:,:,:) = FillValueReal
        Me%VelBaroclinic%V%New(:,:,:) = FillValueReal
        Me%VelBaroclinic%V%Old(:,:,:) = FillValueReal
        Me%VelBaroclinic%U2D(:,:)     = 0.
        Me%VelBaroclinic%V2D(:,:)     = 0.

       !Auxiliar horizontal baroclinic velocity pointers
        nullify (Me%VelBaroclinic%UV%New) 
        nullify (Me%VelBaroclinic%UV%Old) 

        nullify (Me%VelBaroclinic%VU%New) 
        nullify (Me%VelBaroclinic%VU%Old) 

        nullify (Me%VelBaroclinic%UV2D) 



        if (Me%VelBaroclinic%BaroclinicOBCDiscret == StoreWave_) then

            MaxTangX = (JUB - JLB    ) * 2 * (KUB - KLB + 1) 
            MaxNormY = (JUB - JLB - 1) * 2 * (KUB - KLB + 1) 

            MaxTangY = (IUB - ILB    ) * 2 * (KUB - KLB + 1) 
            MaxNormX = (IUB - ILB - 1) * 2 * (KUB - KLB + 1) 

            allocate(Me%VelBaroclinic%ImposedNormX(MaxNormX))
            do i = 1, MaxNormX
                nullify(Me%VelBaroclinic%ImposedNormX(i)%FirstInstant)
                nullify(Me%VelBaroclinic%ImposedNormX(i)%LastInstant)
            enddo
                        
            allocate(Me%VelBaroclinic%ImposedNormY(MaxNormY))
            do i = 1, MaxNormY
                nullify(Me%VelBaroclinic%ImposedNormY(i)%FirstInstant)
                nullify(Me%VelBaroclinic%ImposedNormY(i)%LastInstant)
            enddo

            allocate(Me%VelBaroclinic%ImposedTangX(MaxTangX))
            do i = 1, MaxTangX
                nullify(Me%VelBaroclinic%ImposedTangX(i)%FirstInstant)
                nullify(Me%VelBaroclinic%ImposedTangX(i)%LastInstant)
            enddo
 
                        
            allocate(Me%VelBaroclinic%ImposedTangY(MaxTangY))
            do i = 1, MaxTangY
                nullify(Me%VelBaroclinic%ImposedTangY(i)%FirstInstant)
                nullify(Me%VelBaroclinic%ImposedTangY(i)%LastInstant)
            enddo
 
        endif

    end subroutine Construct_RadiaBaroclinic

    !End--------------------------------------------------------------------------

    !--------------------------------------------------------------------------

    Subroutine Verify_Numerical_Options 

        !Arguments-------------------------------------------------------------


        !Local-----------------------------------------------------------------

        integer :: WorkKUB, WorkIUB, WorkJUB, WorkILB, WorkJLB, STAT_CALL
        real    :: Total_RunPeriod, InertialPeriods, RampPeriod

        !Begin-----------------------------------------------------------------
        

        WorkKUB = Me%WorkSize%KUB

        WorkIUB = Me%WorkSize%IUB
        WorkILB = Me%WorkSize%ILB

        WorkJUB = Me%WorkSize%JUB
        WorkJLB = Me%WorkSize%JLB


        if (Me%ComputeOptions%Baroclinic .and. WorkKUB == 1)                &
            call SetError(FATAL_, KEYWORD_, 'Inconsistency: mode baroclinic active in a 2D model - ERR01') 
        


        if (Me%ComputeOptions%BarotropicRadia /= NoRadiation_ .and.         &
            Me%ComputeOptions%Imposed_BoundaryWave)                         &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR02.')

        if (Me%ComputeOptions%BarotropicRadia /= NoRadiation_ .and.         &
            Me%ComputeOptions%Compute_Tide)                                 &
            call SetError(WARNING_, KEYWORD_, 'The model is imposing in the open boundary tide together with radiation')

        !MRV A clamped condition or a BK condition should be imposed
        if (Me%ComputeOptions%BarotropicRadia == BlumbergKantha_ .and.      &
            Me%ComputeOptions%Imposed_BoundaryWave)                         &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR02.')


        if (Me%ComputeOptions%UpStream_CenterDif < 0 .or.                   &
            Me%ComputeOptions%UpStream_CenterDif > 1)                       &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR04.') 

        !This variable must greather then 0 (total explicit) and smaller then 1 (total implicit)
        if (Me%ComputeOptions%ImplicitVertAdvection < 0 .or.               &
            Me%ComputeOptions%ImplicitVertAdvection > 1)                   &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR05.')

        !This variable must greather then 0 (total explicit) and smaller then 1 (total implicit)
        if (Me%ComputeOptions%ImplicitVertDiffusion < 0 .or.                &
            Me%ComputeOptions%ImplicitVertDiffusion > 1)                    &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR06.')

        !The model only know how to compute hydrodynamic using the Abbott scheme (time-split with 4 equations)
        ! or the Leendertse scheme (time-split with 6 equations)
        if (.not. (Me%ComputeOptions%Num_Discretization == Abbott .or.      &
                   Me%ComputeOptions%Num_Discretization == Leendertse))     & 
            call SetError(FATAL_, KEYWORD_,  'Verify_Numerical_Options - Hydrodynamic - ERR07.')

        !The model only know how to compute horizontal advection using central differences or a 
        !upstream scheme. There are only two upstream schemes implemented (first order Upwind and 
        !second order Upwind that we call Quick). The true Quick scheme is more complex see Leonard, 1979 ????
        if (.not. (Me%ComputeOptions%UpStream == Upwind_Scheme .or.         &
                   Me%ComputeOptions%UpStream == Quick_Scheme))             &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR08.')

        
cd1:    if (Me%ComputeOptions%Baroclinic) then
            
cd2:        if (Me%ComputeOptions%BaroclinicRamp) then 
                
                Total_RunPeriod = Me%EndTime - Me%BeginTime

                InertialPeriods = Me%ComputeOptions%InertialPeriods

                RampPeriod = 86400. * InertialPeriods
            
                if (Total_RunPeriod < RampPeriod )                                       &
                    call SetError (WARNING_, KEYWORD_, &
                                  'The RAMP option only work for bigger runs. Check RAMP_START in following files')
                

cd3:            if (Me%ComputeOptions%Continuous) then
                                          
                     call SetError(WARNING_, KEYWORD_, 'You are using the RAMP option with continuous calculus. Check RAMP_START')

                end if cd3

            end if cd2

        endif cd1

        if (Me%ComputeOptions%VelTangentialBoundary /= NULL_VALUE    .and.  &
            Me%ComputeOptions%VelTangentialBoundary /= NULL_GRADIENT)       &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR09.')

        if (Me%ComputeOptions%VelNormalBoundary /= NULL_VALUE .and.         &
            Me%ComputeOptions%VelNormalBoundary /= NULL_GRADIENT)           &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR10.')

        if (Me%ComputeOptions%Evolution /= Solve_Equations_       .and.     &
            Me%ComputeOptions%Evolution /= Read_File_             .and.     &
            Me%ComputeOptions%Evolution /= No_hydrodynamic_       .and.     &
            Me%ComputeOptions%Evolution /= Run_Off_               .and.     &
            Me%ComputeOptions%Evolution /= ImposedSolution_       .and.     &
            Me%ComputeOptions%Evolution /= Vertical1D_            .and.     &
            Me%ComputeOptions%Evolution /= Residual_hydrodynamic_         ) &   
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR11.')

        if (Me%ComputeOptions%Evolution == Residual_hydrodynamic_ .and.     &
            .not. Me%ComputeOptions%Continuous )                            &        
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR12.')


        if (Me%ComputeOptions%Evolution == Residual_hydrodynamic_ .and.     &
            .not. Me%ComputeOptions%Residual)                               &        
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR13.')

       !Guillaume
       if ( Me%ComputeOptions%Evolution == Vertical1D_ ) then
       if (    Me%ComputeOptions%Obstacle  .or. & 
               Me%TidePotential%Compute    .or. &
               Me%TidePotential%Compute    .or. &
               Me%Relaxation%Force         .or. &
               Me%ComputeOptions%HorizontalAdvection   .or. &
               Me%ComputeOptions%HorizontalDiffusion   .or. &
               Me%ComputeOptions%VolumeVariation       .or. &
               Me%ComputeOptions%MomentumDischarge     ) then
                
            call SetError(WARNING_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR13a.')
       endif
       endif

        if ((Me%ComputeOptions%Evolution == Read_File_             .or.     &
             Me%ComputeOptions%Evolution == No_hydrodynamic_       .or.     &
             Me%ComputeOptions%Evolution == Run_Off_               .or.     &
             Me%ComputeOptions%Evolution == ImposedSolution_      ).and.    &
             Me%ComputeOptions%Continuous)                                  &        
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR14.')



        if (Me%ComputeOptions%ImplicitAdvection .and.                      &
            .not. Me%ComputeOptions%UpStream == Upwind_Scheme)              &
            call SetError(FATAL_, INTERNAL_, 'Verify_Numerical_Options - Hydrodynamic - ERR17.') 


        if (Me%ComputeOptions%SurfaceWaterFlux .and.                           &
            Me%ComputeOptions%Evolution == Read_File_)                       &
            call SetError(FATAL_, INTERNAL_, 'Verify_Numerical_Options - Hydrodynamic - ERR18.') 

!        if (Me%ComputeOptions%SurfaceWaterFlux .and.                           &
!            Me%ComputeOptions%Recording             )                       &
!            call SetError(FATAL_, INTERNAL_, 'Verify_Numerical_Options - Hydrodynamic - ERR19.') 

        
        if (Me%ComputeOptions%TideSlowStartCoef > 0. .and.                  &
            .not. (Me%ComputeOptions%Compute_Tide    .or.                   &
                   Me%TidePotential%Compute    ))                           &
            call SetError(FATAL_, INTERNAL_, 'Verify_Numerical_Options - Hydrodynamic - ERR20.') 

        if (Me%ComputeOptions%TideSlowStartCoef > 0. .and.                  &
            Me%ComputeOptions%Continuous)                                   & 
            call SetError(FATAL_, INTERNAL_, 'Verify_Numerical_Options - Hydrodynamic - ERR20a.') 


        if (.not. Me%ComputeOptions%Compute_Tide .and.                      &
                  Me%TidePotential%Compute )                                &
            call SetError(WARNING_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR21.') 



!        if (Me%ComputeOptions%BarotropicRadia /= FlatherLocalSolution_ .and.&
!            Me%SubModel%ON)                                                 &
!            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR25.')

        if (Me%ComputeOptions%BarotropicRadia == FlatherLocalSolution_ .and.&
            Me%ComputeOptions%LocalSolution   /= SubModel_             .and.&
            Me%ComputeOptions%LocalSolution   /= AssimilaPlusSubModel_ .and.&
            Me%SubModel%ON)                                                 &
            call SetError(WARNING_, KEYWORD_, 'The model is not using in the flather OBC the submodel as the local solution')
        

!        if (.not. Me%ComputeOptions%Imposed_BoundaryWave .and.              &
!            Me%SubModel%ON)                                                 &
!            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR26.')


        if (Me%ComputeOptions%BaroclinicRadia /= Horizontal_ .and.          &
            Me%ComputeOptions%BaroclinicRadia /= Vertical_   .and.          &
            Me%ComputeOptions%BaroclinicRadia /= NoRadiation_)              &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR28.')            

        if (Me%ComputeOptions%LocalSolution /= NoLocalSolution_      .and.  &
            Me%ComputeOptions%LocalSolution /= Submodel_             .and.  &
            Me%ComputeOptions%LocalSolution /= AssimilationField_    .and.  &
            Me%ComputeOptions%LocalSolution /= AssimilaPlusSubModel_ .and.  &
            Me%ComputeOptions%LocalSolution /= Gauge_)                      &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR29.')            

        if (.not. Me%SubModel%ON .and.                                           &
            Me%ComputeOptions%LocalSolution == Submodel_                       ) &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR30.')            

        if (Me%ComputeOptions%Wind /= NoWind_             .and.             &
            Me%ComputeOptions%Wind /= WithWind_           .and.             &
            Me%ComputeOptions%Wind /= InitialSmoothWind_)                   &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR31.')            

        if (Me%ComputeOptions%Wind == InitialSmoothWind_  .and.             &
            Me%ComputeOptions%Continuous )                                  &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR32.')            

        call GetCheckDistortion (Me%ObjHorizontalGrid,           &
                                 Me%External_Var%Distortion,     &
                                 STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                      &
            call SetError(FATAL_, KEYWORD_, 'Verify_Numerical_Options - Hydrodynamic - ERR62.')            

        if (Me%External_Var%Distortion .and. .not. Me%ComputeOptions%CentrifugalForce) then
            write(*,*) 'The grid has a distortion but the centrifugal force is not actvie'
            write(*,*) 'Verify_Numerical_Options - Hydrodynamic - WARN62.'
        endif

        if (Me%ComputeOptions%ImplicitVertAdvection> 0.         .and.                            &
           (Me%ComputeOptions%AdvectionMethodV == UpwindOrder2  .or.                             &
            Me%ComputeOptions%AdvectionMethodV == UpwindOrder3)) then

            write(*,*) 'If the advection of momentum in the vertical is implicit'
            write(*,*) 'the advection method can not be a second or third order upwind' 
            stop 'Verify_Numerical_Options - Hydrodynamic - ERR40.'            

        endif

       if ((Me%ComputeOptions%Residual).and. &
           (Me%ComputeOptions%Evolution /= Solve_Equations_)) then

            write(*,*) 'Unable to retrieve residuals if not solving equations.'
            write(*,*) 'Check either RESIDUAL or EVOLUTION keywords.' 
            stop 'Verify_Numerical_Options - Hydrodynamic - ERR41.'            

        endif

        if (Me%ComputeOptions%LocalSolution   == NoLocalSolution_      .and.            &
            Me%ComputeOptions%BarotropicRadia == FlatherLocalSolution_ .and.            &
            Me%ComputeOptions%Relaxation) then
            write(*,*) 'NUDGING option ON '
            write(*,*) 'FLATHER RADIATION ON radiating over a null local solution' 
            write(*,*) 'Verify_Numerical_Options - Hydrodynamic - ERR42.'            
        endif
            


    End Subroutine Verify_Numerical_Options

    !-----------------------------------------------------------------

    Subroutine ConstructBlumbergKantha

        !Arguments-------------------------------------------------------------



        !Local-----------------------------------------------------------------
        real, dimension(:), allocatable     :: AuxVector
        integer                             :: ILB, IUB, JLB, JUB
        integer                             :: ILBWork, IUBWork, JLBWork, JUBWork
        integer                             :: STATUS
       
        integer                             :: ClientNumber
        integer                             :: FirstLine, LastLine    
        integer                             :: Line, iflag, FromFile
        integer                             :: i,j

        Character(LEN = StringLength)       :: FileName
        Character(LEN = StringLength)       :: block_begin, block_end

        logical                             :: BlockFound

        !Begin Algorithm -------------------------------------------------------- 
        

        call GetExtractType( FromFile = FromFile)


        IUB = Me%Size%IUB
        ILB = Me%Size%ILB
        JUB = Me%Size%JUB
        JLB = Me%Size%JLB



        IUBWork = Me%WorkSize%IUB
        ILBWork = Me%WorkSize%ILB
        JUBWork = Me%WorkSize%JUB
        JLBWork = Me%WorkSize%JLB

        allocate (Me%ComputeOptions%Tlag(ILB : IUB, JLB : JUB), STAT = status)

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR01") 

        Me%ComputeOptions%Tlag(ILBWork : IUBWork, JLBWork : JUBWork) = 1E-12

        !<BeginKeyword>
            !Keyword          : TLAG_FILE
            !<BeginDescription>      
                ! The name file where are the relaxation times defined for the radiation boundary condition 
            !<EndDescription>
            !Type             : Character  
            !Default          : Do not have
            !File keyword     : IN_DAD3D
            !Multiple Options : Do not have
            !Search Type      : From File
        !<EndKeyword>


        call GetData(FileName,    Me%ObjEnterData, iflag,                   &  
                     SearchType = FromFile,                                              &
                     keyword    = 'TLAG_FILE',                                           &   
                     default    = '******.***',                                          &    
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = status)

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR02") 
        
        if (iflag == 0) &
            call SetError (FATAL_, OUT_OF_MEM_, "ConstructBlumbergKantha - Hydrodynamic - ERR03")


        call ConstructEnterData(Me%ObjEnterData1, FileName, STAT = status) 

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR04") 


        block_begin = '<TlagBegin>'
        block_begin = trim(block_begin)

        block_end   = '<TlagEnd>'
        block_end   = trim(block_end)


        call ExtractBlockFromBuffer(Me%ObjEnterData1, ClientNumber,         &
                                    block_begin, block_end, BlockFound,                  &
                                    FirstLine, LastLine,                                 &  
                                    STAT = status)
        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR05") 


cd43:   if (.NOT. BlockFound) then   

            write(*,*) 
            write(*,'(a)') 'Error reading file: ', FileName
            write(*,*)     '    Values should be detween labels:'
            write(*,*)     '        <TlagBegin>'
            write(*,*)     '            .'
            write(*,*)     '            .'
            write(*,*)     '            .'
            write(*,*)     '        <TlagEnd>'
           call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR06") 

        end if cd43



        allocate (AuxVector(3), STAT = status) 

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR07") 



        do Line = FirstLine + 1, LastLine - 1        !Frank -start one line after firstline

        
            call GetData(AuxVector,                                                      &
                         Me%ObjEnterData1,                                  &
                         iflag, Buffer_Line  = Line, STAT = status)

            if (status /= SUCCESS_)                                                      &
                call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR08") 

            if (iflag /= 3)                                                              &          
                call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR09") 


            i = int(AuxVector(1))
            j = int(AuxVector(2))

            if (i < ILBWork .or. i > IUBWork .or. j < JLBWork .or. j > JUBWork)          &          
                call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR10") 


            Me%ComputeOptions%Tlag(i, j) = AuxVector(3)

            if(Me%ComputeOptions%Tlag(i, j) < Me%WaterLevel%DT ) &
               Me%ComputeOptions%Tlag(i, j) = Me%WaterLevel%DT 
    
        enddo

        deallocate (AuxVector, STAT = status) 

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR11") 


        call Block_Unlock(Me%ObjEnterData1, ClientNumber, STAT = status) 

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR12") 


        call KillEnterData(Me%ObjEnterData1, STAT = status)

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructBlumbergKantha - Hydrodynamic - ERR13") 

    End Subroutine ConstructBlumbergKantha


    Subroutine AllocateVariables

        !Arguments-------------------------------------------------------------

        

        !Local-----------------------------------------------------------------

        integer :: ILB, IUB
        integer :: JLB, JUB
        integer :: KLB, KUB

        integer :: IJKLB, IJKUB, imin, imax

        integer :: STAT_CALL

        integer :: JImin, JImax

        !Begin------------------------------------------------------------------

        ILB = Me%Size%ILB 
        IUB = Me%Size%IUB 

        JLB = Me%Size%JLB 
        JUB = Me%Size%JUB 

        KLB = Me%Size%KLB 
        KUB = Me%Size%KUB 

        !Variables allocation
        allocate (Me%WaterLevel%New             (ILB:IUB, JLB:JUB         )) 
        allocate (Me%WaterLevel%Old             (ILB:IUB, JLB:JUB         )) 
        allocate (Me%WaterLevel%VolumeCreated   (ILB:IUB, JLB:JUB         )) 
        allocate (Me%Velocity%Horizontal%U%New  (ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%Velocity%Horizontal%U%Old  (ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%Velocity%Horizontal%V%New  (ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%Velocity%Horizontal%V%Old  (ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%Velocity%Vertical%Across   (ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%Velocity%Vertical%Cartesian(ILB:IUB, JLB:JUB, KLB:KUB)) 



        Me%WaterLevel%New(:,:)                  = FillValueReal
        Me%WaterLevel%Old(:,:)                  = FillValueReal
        Me%WaterLevel%VolumeCreated(:,:)        = 0.
        Me%Velocity%Horizontal%U%New(:,:,:)     = FillValueReal     
        Me%Velocity%Horizontal%U%Old(:,:,:)     = FillValueReal    
        Me%Velocity%Horizontal%V%New(:,:,:)     = FillValueReal
        Me%Velocity%Horizontal%V%Old(:,:,:)     = FillValueReal
        Me%Velocity%Vertical%Across(:,:,:)      = FillValueReal
        Me%Velocity%Vertical%Cartesian(:,:,:)   = FillValueReal
             

        !Auxiliar horizontal velocity pointers
        nullify (Me%Velocity%Horizontal%UV%New) 
        nullify (Me%Velocity%Horizontal%UV%Old) 

        nullify (Me%Velocity%Horizontal%VU%New) 
        nullify (Me%Velocity%Horizontal%VU%Old) 

        !NonHydrostatic
        if (Me%NonHydrostatic%ON) then

            allocate (Me%Velocity%Vertical%CartesianOld(ILB:IUB, JLB:JUB, KLB:KUB)) 
            allocate (Me%NonHydrostatic%PressureCorrect(ILB:IUB, JLB:JUB, KLB:KUB))
            allocate (Me%NonHydrostatic%PrevisionalQ(ILB:IUB, JLB:JUB, KLB:KUB))
            allocate (Me%NonHydrostatic%CCoef(ILB:IUB, JLB:JUB, KLB:KUB))
            allocate (Me%NonHydrostatic%GCoef(ILB:IUB, JLB:JUB, KLB:KUB))
            Me%Velocity%Vertical%CartesianOld (:,:,:) = FillValueReal
            Me%NonHydrostatic%PressureCorrect (:,:,:) = FillValueReal
            Me%NonHydrostatic%PrevisionalQ(:, : ,:)   = FillValueReal
        endif



        allocate (Me%WaterFluxes%X          (ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%WaterFluxes%Y          (ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%WaterFluxes%Z          (ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%WaterFluxes%Discharges (ILB:IUB, JLB:JUB, KLB:KUB))
 
        Me%WaterFluxes%X         (:,:,:) = FillValueReal
        Me%WaterFluxes%Y         (:,:,:) = FillValueReal
        Me%WaterFluxes%Z         (:,:,:) = FillValueReal
        Me%WaterFluxes%Discharges(:,:,:) = FillValueReal

 
        !If compute Residual properties then must allocate residual variables
        nullify (Me%Residual%WaterLevel) 

        nullify (Me%Residual%Velocity_U)
        nullify (Me%Residual%Velocity_V) 

        nullify (Me%Residual%DWZ)

        nullify (Me%Residual%Vertical_Velocity)

        !Residual water fluxes
        nullify (Me%Residual%WaterFlux_X) 
        nullify (Me%Residual%WaterFlux_Y) 

        Me%Residual%ResidualTime = FillValueReal

cd1:    if (Me%ComputeOptions%Residual) then 

            !Can be interesting to compute the average water level
            allocate (Me%Residual%WaterLevel        (ILB:IUB, JLB:JUB))        
            allocate (Me%Residual%Velocity_U        (ILB:IUB, JLB:JUB, KLB:KUB)) 
            allocate (Me%Residual%Velocity_V        (ILB:IUB, JLB:JUB, KLB:KUB)) 
            allocate (Me%Residual%Vertical_Velocity (ILB:IUB, JLB:JUB, KLB:KUB)) 
            allocate (Me%Residual%WaterFlux_X       (ILB:IUB, JLB:JUB, KLB:KUB)) 
            allocate (Me%Residual%WaterFlux_Y       (ILB:IUB, JLB:JUB, KLB:KUB)) 
            allocate (Me%Residual%DWZ               (ILB:IUB, JLB:JUB, KLB:KUB)) 

            Me%Residual%WaterLevel(:,:) = FillValueReal
            Me%Residual%Velocity_U(:,:,:) = FillValueReal
            Me%Residual%Velocity_V(:,:,:) = FillValueReal
            Me%Residual%Vertical_Velocity(:,:,:) = FillValueReal
            Me%Residual%WaterFlux_X(:,:,:) = FillValueReal
            Me%Residual%WaterFlux_Y(:,:,:) = FillValueReal
            Me%Residual%DWZ(:,:,:) = FillValueReal

        endif cd1


        !Forces 
        allocate (Me%Forces%Rox3X                   (ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%Forces%Rox3Y                   (ILB:IUB, JLB:JUB, KLB:KUB)) 

        allocate (Me%Forces%Horizontal_Transport    (ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%Forces%Inertial_Aceleration    (ILB:IUB, JLB:JUB, KLB:KUB)) 
        allocate (Me%Forces%TidePotentialLevel      (ILB:IUB, JLB:JUB)) 
        allocate (Me%Coef%D2%D                      (ILB:IUB, JLB:JUB)) 
        allocate (Me%Coef%D2%E                      (ILB:IUB, JLB:JUB)) 
        allocate (Me%Coef%D2%F                      (ILB:IUB, JLB:JUB)) 
        allocate (Me%Coef%D2%Ti                     (ILB:IUB, JLB:JUB)) 


        Me%Forces%Rox3X(:,:,:)                  = FillValueReal
        Me%Forces%Rox3Y(:,:,:)                  = FillValueReal
        Me%Forces%Horizontal_Transport(:,:,:)   = FillValueReal
        Me%Forces%Inertial_Aceleration(:,:,:)   = FillValueReal
        Me%Forces%TidePotentialLevel(:,:)       = FillValueReal
        Me%Coef%D2%D(:,:)                       = FillValueReal
        Me%Coef%D2%E(:,:)                       = FillValueReal
        Me%Coef%D2%F                            = FillValueReal
        Me%Coef%D2%Ti                           = FillValueReal


        nullify (Me%Coef%D2%Rad  ) 
        nullify (Me%Coef%D2%TiRad) 

cd2:    if (Me%ComputeOptions%BarotropicRadia == FlatherWindWave_ .or.      &
            Me%ComputeOptions%BarotropicRadia == FlatherLocalSolution_) then 

            allocate (Me%Coef%D2%Rad  (ILB:IUB, JLB:JUB)) 
            allocate (Me%Coef%D2%TiRad(ILB:IUB, JLB:JUB)) 

            Me%Coef%D2%Rad   = FillValueReal
            Me%Coef%D2%TiRad = FillValueReal
        endif cd2


        allocate (Me%Coef%D3%D(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STAT_CALL) 
        allocate (Me%Coef%D3%E(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STAT_CALL) 
        allocate (Me%Coef%D3%F(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STAT_CALL) 
        allocate (Me%Coef%D3%Ti(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STAT_CALL) 

        Me%Coef%D3%D = FillValueReal
        Me%Coef%D3%E = FillValueReal 
        Me%Coef%D3%F = FillValueReal     
        Me%Coef%D3%Ti = FillValueReal


        !Bottom boundary: these variables in the future must migrate to the module ModuleBottom
        allocate (Me%External_Var%ChezyZ    (ILB:IUB, JLB:JUB)) 
        allocate (Me%External_Var%ChezyVelUV(ILB:IUB, JLB:JUB)) 

        Me%External_Var%ChezyZ    (:,:) = 0.
        Me%External_Var%ChezyVelUV(:,:) = 0.

        
        nullify (Me%Coef%Baroc%Hright     )
        nullify (Me%Coef%Baroc%Hleft      )
        nullify (Me%Coef%Baroc%Hcenter    )
        nullify (Me%Coef%Baroc%Depth_integ)
        nullify (Me%Coef%Baroc%Kright     )
        nullify (Me%Coef%Baroc%Kleft      )
        nullify (Me%Coef%Baroc%HroLeft    )
        nullify (Me%Coef%Baroc%HroRight   )
        nullify (Me%Coef%Baroc%DensRight  )
        nullify (Me%Coef%Baroc%DensLeft   )
                
cd3:    if (Me%ComputeOptions%Baroclinic) then 

            allocate (Me%Coef%Baroc%Kleft       (KLB : KUB+1))
            allocate (Me%Coef%Baroc%Kright      (KLB : KUB+1))
            allocate (Me%Coef%Baroc%Depth_integ (KLB : KUB+1))
            allocate (Me%Coef%Baroc%Hcenter     (KLB : KUB+1))
            allocate (Me%Coef%Baroc%Hleft       (KLB : KUB+1))
            allocate (Me%Coef%Baroc%Hright      (KLB : KUB+1))
            allocate (Me%Coef%Baroc%HroLeft     (KLB : KUB+1))
            allocate (Me%Coef%Baroc%HroRight    (KLB : KUB+1))
            allocate (Me%Coef%Baroc%DensLeft    (KLB : KUB+1))
            allocate (Me%Coef%Baroc%DensRight   (KLB : KUB+1))



            Me%Coef%Baroc%Kleft         = FillValueInt
            Me%Coef%Baroc%Kright        = FillValueInt
            Me%Coef%Baroc%Depth_integ   = FillValueReal
            Me%Coef%Baroc%Hcenter       = FillValueReal 
            Me%Coef%Baroc%Hleft         = FillValueReal
            Me%Coef%Baroc%Hright        = FillValueReal
            Me%Coef%Baroc%HroLeft       = FillValueReal
            Me%Coef%Baroc%HroRight      = FillValueReal
            Me%Coef%Baroc%DensLeft      = FillValueReal
            Me%Coef%Baroc%DensRight     = FillValueReal


        endif cd3

        IJKLB = MIN(ILB, JLB, KLB)
        IJKUB = MAX(IUB, JUB, KUB)

        allocate (Me%VECG_3D(IJKLB : IJKUB))
        allocate (Me%VECW_3D(IJKLB : IJKUB))

        Me%VECG_3D = FillValueReal
        Me%VECW_3D = FillValueReal


        JImin = MIN(ILB,JLB)
        JImax = MAX(IUB,JUB)

        allocate (Me%VECG_2D(JImin : JImax), STAT = STAT_CALL)
        allocate (Me%VECW_2D(JImin : JImax),    STAT = STAT_CALL)

        Me%VECG_2D = FillValueReal
        Me%VECW_2D = FillValueReal


        if (Me%ComputeOptions%BarotropicRadia == BlumbergKantha_)           &
            call ConstructBlumbergKantha


        if (Me%ComputeOptions%BiHarmonic) then

            allocate (Me%ComputeOptions%BiHarmonicUX_VY(ILB:IUB, JLB:JUB, KLB:KUB))
            allocate (Me%ComputeOptions%BiHarmonicUY_VX(ILB:IUB, JLB:JUB, KLB:KUB))
            
            Me%ComputeOptions%BiHarmonicUX_VY(:,:,:) = FillValueReal
            Me%ComputeOptions%BiHarmonicUY_VX(:,:,:) = FillValueReal


        endif

ic1:    if (Me%CyclicBoundary%ON) then

            imin = min (ILB, JLB, KLB)
            imax = max (IUB, JUB, KUB)

            allocate (Me%Coef%D1%a  (imin : imax)) 
            allocate (Me%Coef%D1%b  (imin : imax)) 
            allocate (Me%Coef%D1%bb (imin : imax)) 
            allocate (Me%Coef%D1%c  (imin : imax)) 
            allocate (Me%Coef%D1%r  (imin : imax)) 
            allocate (Me%Coef%D1%u  (imin : imax)) 
            allocate (Me%Coef%D1%x  (imin : imax)) 
            allocate (Me%Coef%D1%z  (imin : imax)) 
            allocate (Me%Coef%D1%gam(imin : imax)) 

            Me%Coef%D1%a(:)     = FillValueReal
            Me%Coef%D1%b(:)     = FillValueReal
            Me%Coef%D1%bb(:)    = FillValueReal
            Me%Coef%D1%c(:)     = FillValueReal
            Me%Coef%D1%r(:)     = FillValueReal
            Me%Coef%D1%u(:)     = FillValueReal
            Me%Coef%D1%x(:)     = FillValueReal
            Me%Coef%D1%z(:)     = FillValueReal
            Me%Coef%D1%gam(:)   = FillValueReal

        endif ic1

        if(Me%ComputeOptions%Obstacle)then

            allocate (Me%Drag%Coef                          (ILB:IUB, JLB:JUB, KLB:KUB))
            allocate (Me%Forces%ObstacleDrag_Aceleration    (ILB:IUB, JLB:JUB, KLB:KUB)) 

            Me%Forces%ObstacleDrag_Aceleration(:,:,:) = 0.
            Me%Drag%Coef                      (:,:,:) = FillValueReal
  
        endif


      !----------------------------------------------------------------------

    end subroutine AllocateVariables   

    !--------------------------------------------------------------------------
    !If needed the sub-modules responsible for the:
    !   - Turbulence
    !   - OpenBoundary
    !   - Discharges
    !   - Surface conditions
    !   - Bottom Conditions
    !will be construct in this subroutine

    subroutine Construct_Sub_Modules(DischargesID, AssimilationID)

        !Arguments-------------------------------------------------------------
        integer              :: DischargesID
        integer              :: AssimilationID
    
        !Local-----------------------------------------------------------------

        logical              :: WaterDischarges, ModelGOTM, ContinuousGOTM
        integer              :: STAT_CALL
        !----------------------------------------------------------------------

        
        WaterDischarges = Me%ComputeOptions%WaterDischarges

        if (WaterDischarges) then
            
            if (DischargesID == 0) then
                call Construct_Discharges(Me%ObjDischarges,                              &
                                          Me%ObjTime,                                    &
                                          STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Construct_Sub_Modules - ModuleHydrodynamic - ERR01'  

                DischargesID = Me%ObjDischarges

            else
                Me%ObjDischarges = AssociateInstance (mDISCHARGES_, DischargesID)
            endif

        endif

        if (Me%ComputeOptions%Relaxation .or. Me%ComputeOptions%AltimetryAssimilation%Yes) then

            if (AssimilationID == 0) then   
                call StartAssimilation(Me%ObjAssimilation,                               &
                                       Me%ObjTime,                                       &
                                       Me%ObjGridData,                                   &
                                       Me%ObjHorizontalGrid,                             &
                                       Me%ObjHorizontalMap,                              &
                                       Me%ObjMap,                                        &
                                       Me%ObjGeometry,                                   &
                                       STAT = STAT_CALL)

                 if (STAT_CALL /= SUCCESS_) stop 'Construct_Sub_Modules - ModuleHydrodynamic - ERR02'  
                                
                 AssimilationID = Me%ObjAssimilation
            else
                Me%ObjAssimilation = AssociateInstance (mASSIMILATION_, AssimilationID)
            endif       
        
        endif


        call GetContinuousGOTM(Me%ObjTurbulence, ContinuousGOTM, ModelGOTM, STAT = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'Construct_Sub_Modules - Hydrodynamic - ERR03.')

        if (ModelGOTM) then
            if (Me%ComputeOptions%Continuous) then
                if (.not. ContinuousGOTM)  then
                    write(*,*) 'Construct_Sub_Modules - Hydrodynamic - WARN01.'
                    write(*,*) 'Hydrodynamic - Continuous YES'
                    write(*,*) 'GOTM         - Continuous NO'
                    write(*,*) 'Press enter to procede OR controle break to stop the run'
                    read (*,*)
                endif
            endif

            if (.not.Me%ComputeOptions%Continuous) then
                if (ContinuousGOTM)                                                      &
                    call SetError(FATAL_, INTERNAL_, 'Construct_Sub_Modules - Hydrodynamic - ERR05.')
            endif
        endif


        !Opens the energy result file and allocates the buffer to store the data
        if (Me%ComputeOptions%Energy) &
            call ConstructEnergy

        if (Me%ComputeOptions%Relaxation) &
            call ConstructRelaxation     


        !Allocates and initialise the variables necessary to compute 
        !the tide potential
        if (Me%TidePotential%Compute)                                       &
            call ConstructTidePotential 


        !Allocates and initialise the variables necessary to run this model as submodel
        if (Me%SubModel%ON)                                                 &
            call ConstructSubModel 


        call ConstructHydroStatistic
        

    end subroutine Construct_Sub_Modules   

    !End----------------------------------------------------------------------

!-------------------------------------------------------------------------
!        IST/MARETEC, Marine Modelling Group, Mohid2000 modelling system
!-------------------------------------------------------------------------

!BOP
!
! !ROUTINE: ConstructHydroStatistic

! !INTERFACE:

    subroutine ConstructHydroStatistic

! !INPUT PARAMETERS:


! !DESCRIPTION: 
!   This subroutine reads all the information needed to construct a statistic
!   object 
!   


 
! !REVISION HISTORY: 
!  01Nov2002   Paulo Chambel  the ConstructHydroStatistic routine calls from
!                             the ModuleStatistic the routine ConstructStatistic           

           
!EOP

!       Local ------------------------------------------------------------------------------
        integer                     :: Status
        integer                     :: iflag, FromFile, i
               
        !Begin----------------------------------------------------------------------------


        call GetExtractType     (FromFile = FromFile)

        !<BeginKeyword>
            !Keyword          : STATISTICS
            !<BeginDescription>       
               ! 
               ! Checks out if the user pretends the statistics of the hydrodynamic properties
               ! 
            !<EndDescription>
            !Type             : Boolean 
            !Default          : .false.
            !File keyword     : IN_DAD3D
            !Multiple Options : Do not have
            !Search Type      : FromFile
        !<EndKeyword>
        call GetData(Me%Statistics%ON,                                       &
                     Me%ObjEnterData, iflag,                                &
                     Keyword      = 'STATISTICS',                                        &
                     Default      = .false.,                                             &
                     SearchType   =  FromFile,                                           &
                     ClientModule = 'ModuleHydrodynamic',                                &
                     STAT = Status)
        if (Status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, 'ConstructHydroStatistic - Hydrodynamic - ERR01') 

        
        if (Me%Statistics%ON) then

            !<BeginKeyword>
                !Keyword          : STATISTICS_FILE
                !<BeginDescription>       
                   ! 
                   ! The statistics definition file of the hydrodynamic properties
                   ! 
                !<EndDescription>
                !Type             : Character
                !Default          : Do not have
                !File keyword     : IN_DAD3D
                !Multiple Options : Do not have
                !Search Type      : FromFile
            !<EndKeyword>
            call GetData(Me%Statistics%File,                                &
                 Me%ObjEnterData, iflag,                                    &
                 Keyword      = 'STATISTICS_FILE',                                       &
                 SearchType   = FromFile,                                                &
                 ClientModule = 'ModuleHydrodynamic',                                    &
                 STAT = Status)
            if (Status /= SUCCESS_ .or. iflag /= 1)                                      &
                call SetError(FATAL_, INTERNAL_, 'ConstructHydroStatistic - Hydrodynamic - ERR02') 


            Me%Statistics%PropList(1) = VelocityU_
            Me%Statistics%PropList(2) = VelocityV_
            Me%Statistics%PropList(3) = VelocityW_

            do i=1, Me%Statistics%NProp

                call ConstructStatistic (Me%Statistics%ID(i),                               &
                                         Me%ObjTime,                                        &
                                         Me%ObjHDF5,                                        &
                                         Me%Size,                                           &
                                         Me%WorkSize,                                       &
                                         Me%Statistics%File,                                &
                                         GetPropertyName (Me%Statistics%PropList(i)),       &
                                         STAT = Status)
                if (Status /= SUCCESS_)                                                     &
                    call SetError(FATAL_, INTERNAL_, 'ConstructHydroStatistic - Hydrodynamic - ERR04') 
            enddo

        endif    


    end subroutine ConstructHydroStatistic

    !--------------------------------------------------------------------------




    !--------------------------------------------------------------------------

    subroutine StartOutputBoxFluxes

        !Arguments-------------------------------------------------------------

         

        !External--------------------------------------------------------------

        integer :: STAT_CALL
        integer :: iflag, FromFile
        integer :: ILB, IUB
        integer :: JLB, JUB
        integer :: KLB, KUB

        logical :: exist, opened
        character(len=StringLength), dimension(:),  pointer :: FluxesOutputList
        character(len=StringLength), dimension(:),  pointer :: ScalarOutputList

        !----------------------------------------------------------------------

        ILB = Me%Size%ILB 
        IUB = Me%Size%IUB 

        JLB = Me%Size%JLB 
        JUB = Me%Size%JUB 

        KLB = Me%Size%KLB 
        KUB = Me%Size%KUB 

        call GetWaterPoints3D(Me%ObjMap, Me%External_Var%WaterPoints3D, STAT = STAT_CALL)
        if (STAT_CALL .NE. SUCCESS_) stop 'StartOutputBoxFluxes - ModuleHydrodynamic - ERR01'
        
        call GetExtractType  (FromFile = FromFile)

        !<BeginKeyword>
            !Keyword          : BOXFLUXES
            !<BeginDescription>       
               ! 
               !The user can give the name of the file boxes definition
               !If this file exist then the model computes water fluxes between boxes
               !
            !<EndDescription>
            !Type             : Character 
            !Default          : ******.***

            !File keyword     : IN_DAD3D 
            !Multiple Options : Do not 
            !Search Type      : From File
        !<EndKeyword>

        call GetData(Me%Files%BoxFluxesFileName,                                        &
                     Me%ObjEnterData, iflag,                                            &
                     Keyword        = 'BOXFLUXES',                                      &
                     Default        = '******.***',                                     &
                     SearchType     = FromFile,                                         &
                     ClientModule   ='ModuleHydrodynamic',                              &
                     STAT           = STAT_CALL)                                      

        if (STAT_CALL .NE. SUCCESS_)                                                    &
            stop 'Subroutine StartOutputBoxFluxes; Module ModuleHydrodynamic. ERR02.'

cd6 :   if (iflag .EQ. 1) then
            inquire(FILE = Me%Files%BoxFluxesFileName, EXIST = exist)
cd4 :       if (exist) then
                Me%State%BOXFLUXES = ACTIVE

                inquire(FILE = Me%Files%BoxFluxesFileName, OPENED  = opened)
cd5 :           if (opened) then
                    write(*,*    ) 
                    write(*,'(A)') 'BoxFluxesFileName = ', Me%Files%BoxFluxesFileName
                    write(*,*    ) 'Already opened.'
                    stop           'Subroutine StartOutputBoxFluxes; Module Hydrodynamic. ERR04'    
                end if cd5

                allocate(FluxesOutputList(1), ScalarOutputList(1)) 

                FluxesOutputList = Char_Water
                ScalarOutputList = Char_Water

                call StartBoxDif(BoxDifID         = Me%ObjBoxDif,                    &
                                 TimeID           = Me%ObjTime,                      &
                                 HorizontalGridID = Me%ObjHorizontalGrid,            &
                                 BoxesFilePath    = Me%Files%BoxFluxesFileName,      &
                                 FluxesOutputList = FluxesOutputList,                &
                                 ScalarOutputList = ScalarOutputList,                &
                                 WaterPoints3D    = Me%External_Var%WaterPoints3D,   &
                                 Size3D           = Me%Size,                         &
                                 WorkSize3D       = Me%WorkSize,                     &
                                 STAT             = STAT_CALL)
                if (STAT_CALL .NE. SUCCESS_)                                         &
                    stop 'Subroutine StartOutputBoxFluxes; module ModuleWaterProperties. ERR15.'

                deallocate(FluxesOutputList, ScalarOutputList) 
                nullify   (FluxesOutputList, ScalarOutputList)
                
            else
                write(*,*) 
                write(*,*)     'Error dont have the file box.'
                write(*,'(A)') 'BoxFileName = ', Me%Files%BoxFluxesFileName
                stop           'Subroutine StartOutputBoxFluxes; Module Hydrodynamic. ERR03'    
            end if cd4

        else
            Me%State%BOXFLUXES = IDLE
        end if cd6
        
        call UnGetMap (Me%ObjMap, Me%External_Var%WaterPoints3D, STAT = STAT_CALL)
        if (STAT_CALL .NE. SUCCESS_) stop 'StartOutputBoxFluxes - ModuleHydrodynamic - ERR99'


        !----------------------------------------------------------------------

    end subroutine StartOutputBoxFluxes

    !--------------------------------------------------------------------------
!-------------------------------------------------------------------------
!        IST/MARETEC, Marine Modelling Group, Mohid2000 modelling system
!-------------------------------------------------------------------------

!BOP
!
! !ROUTINE: Construct_OutPutTime

! !INTERFACE:

    subroutine Construct_OutPutTime

! !INPUT PARAMETERS:

! !DESCRIPTION: 
!     This routine is a public one and is responsible for the definition 
!     of the hydrodynamic output results

 
! !REVISION HISTORY: 
!  20Nov2000   Paulo Chambel  the Construct_OutPutTime calls from
!                             the ModuleEnterData the routine GetOutPutTime           


           
!EOP

!       Local ------------------------------------------------------------------------------
        integer                     :: Status, FromFile

       
        !Begin----------------------------------------------------------------------------



        call GetExtractType  (FromFile = FromFile)

        call GetOutPutTime(Me%ObjEnterData,                                 &
                           CurrentTime   = Me%CurrentTime,                  &
                           EndTime       = Me%EndTime,                      &
                           keyword       = 'OUTPUT_TIME',                   &
                           SearchType    = FromFile,                        &
                           OutPutsTime   = Me%OutPut%OutTime,               &
                           OutPutsOn     = Me%OutPut%hdf5ON,                &
                           OutPutsNumber = Me%OutPut%Number,                &
                           STAT = Status)

        if (Status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, 'Construct_OutPutTime - Hydrodynamic - ERR01') 

                    
cd3:    if (Me%OutPut%hdf5ON) then 

            Me%OutPut%NextOutPut = 1

        endif cd3




        !----------------------------------------------------------------------

    end subroutine Construct_OutPutTime

    !----------------------------------------------------------------------------



    !----------------------------------------------------------------------------

    subroutine ConstructHydrodynamicProperties

        !Arguments------------------------------------------------------------


        !Local----------------------------------------------------------------
        real,    dimension(:,:), pointer :: Bathymetry
        integer, dimension(:,:,:),pointer:: InitialComputeFacesU3D, InitialComputeFacesV3D

        logical :: Compute_Tide

        real    :: InitialReferenceLevel, TideSlowStartCoef

        logical :: Continuous_Compute
        real    :: InteriorElevation, AverageBoundaryElevation, MinWaterColumn

        integer :: ILB, IUB
        integer :: JLB, JUB
        integer :: KLB, KUB
        integer :: i, j, k, STAT_CALL, Evolution
        integer :: InputStateEx

        !Begin----------------------------------------------------------------
        
        ILB = Me%WorkSize%ILB
        IUB = Me%WorkSize%IUB

        JLB = Me%WorkSize%JLB
        JUB = Me%WorkSize%JUB

        KLB = Me%WorkSize%KLB
        KUB = Me%WorkSize%KUB

        Compute_Tide          = Me%ComputeOptions%Compute_Tide

        InitialReferenceLevel = Me%WaterLevel%Default

        TideSlowStartCoef     = Me%ComputeOptions%TideSlowStartCoef


        !The open boundary module must be initialised here because the OpenBoundary is
        !used in this subroutine to estimate the initial water level.
        call ConstructOpenBoundary(Me%ObjOpenBoundary,   &
                                   Me%ObjGridData,     &
                                   Me%ObjHorizontalMap,  &
                                   Me%ObjTime,           &
                                   Compute_Tide,                      &
                                   InitialReferenceLevel,             &
                                   TideSlowStartCoef,                 &
                                   STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                    &
            stop 'Subroutine ConstructHydrodynamicProperties; ModuleHydrodynamic. ERR01.'  







do1:    do  j=JLB, JUB
do2:    do  i=ILB, IUB

do3:    do  k=KLB, KUB
            !Explicit Forces
            Me%Forces%Horizontal_Transport (i, j, k) = 0.
            Me%Forces%Inertial_Aceleration (i, j, k) = 0.
            Me%Forces%Rox3X                (i, j, k) = 0.
            Me%Forces%Rox3Y                (i, j, k) = 0.
        enddo do3

        do  k=KLB, KUB+1
            !Vertical velocity
            Me%Velocity%Vertical%Across      (i, j, k) = 0.
            Me%Velocity%Vertical%Cartesian   (i, j, k) = 0.
            !NonHydrostatic
            if (Me%NonHydrostatic%ON) then
                Me%Velocity%Vertical%CartesianOld(i, j, k) = 0.
                Me%NonHydrostatic%PressureCorrect(i, j, k) = 0.
                Me%NonHydrostatic%PrevisionalQ(i, j , k)    = 0.
            endif
        enddo 
 

        !Tide potential
        Me%Forces%TidePotentialLevel   (i, j) = 0.

        enddo do2   
        enddo do1

    


        Continuous_Compute = Me%ComputeOptions%Continuous

cd1:    if (Continuous_Compute) then

            call Read_Final_Hydrodynamic_File

        else cd1


cd2:        if (Me%ComputeOptions%Num_Discretization == Leendertse) then

                !By default the previous direction is X to alow the model start 
                !the calculations in X direction when using the Leendertse Scheme
                Me%Direction%XY = DirectionX_
                Me%Direction%YX = DirectionY_

            else if (Me%ComputeOptions%Num_Discretization == Abbott) then cd2


                !By default the previous direction is Y to alow the model start 
                !the calculations in X direction when using the Abbott Scheme
                Me%Direction%XY = DirectionY_  
                Me%Direction%YX = DirectionX_  


            endif cd2


            if      (Me%ComputeOptions%Vertical_AxiSymmetric_Model == DirectionX_) then

                Me%Direction%XY = DirectionX_
                Me%Direction%YX = DirectionY_

            else if (Me%ComputeOptions%Vertical_AxiSymmetric_Model == DirectionY_) then

                Me%Direction%XY = DirectionY_
                Me%Direction%YX = DirectionX_

            endif 

            !Gets Bathymetry
            call GetGridData(Me%ObjGridData, &
                               Bathymetry, STAT = STAT_CALL)
            
            if (STAT_CALL /= SUCCESS_) &
                stop 'ConstructHydrodynamicProperties - ModuleHydrodynamic - ERR02'


            call GetGeometryMinWaterColumn(Me%ObjGeometry, &
                                           MinWaterColumn, STAT = STAT_CALL)
            
            if (STAT_CALL /= SUCCESS_) &
                stop 'ConstructHydrodynamicProperties - ModuleHydrodynamic - ERR04'

            !Water elevation initialization
            call Modify_OpenBoundary(Me%ObjOpenBoundary,                    &
                                     Me%CurrentTime,                        &
                                     STAT = STAT_CALL)

            call GetAverageImposedElevation (Me%ObjOpenBoundary, &
                                             AverageBoundaryElevation, STAT =STAT_CALL )

            if (STAT_CALL /= SUCCESS_)                                        &
                stop 'ConstructHydrodynamicProperties - ModuleHydrodynamic - ERR05'


cd3:        if (Me%ComputeOptions%InitialElevation) then
                
                InteriorElevation = Me%WaterLevel%Default

            else  cd3

                InteriorElevation = AverageBoundaryElevation 

            endif cd3

            !Gets WaterPoints2D
            call GetWaterPoints2D(Me%ObjHorizontalMap, &
                                  Me%External_Var%WaterPoints2D, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                       &
                stop 'ConstructHydrodynamicProperties - ModuleHydrodynamic - ERR40'


do4:        do  j=JLB, JUB
do5:        do  i=ILB, IUB
                    
cd4:            if (Me%External_Var%WaterPoints2D(i, j) == WaterPoint) then
                    
cd5:                if (InteriorElevation > (- Bathymetry(i, j) + MinWaterColumn)) then

                        Me%WaterLevel%New(i, j) =  InteriorElevation            

                    else  cd5
               
                        !The next line is changed to avoid rounding erros.
                        !Frank Jan 2001
!                        Me%WaterLevel%New(i, j) =  - Bathymetry(i, j) + MinWaterColumn
                        Me%WaterLevel%New(i, j) =  - Bathymetry(i, j) + 0.999 * MinWaterColumn

                    endif cd5

                    Me%WaterLevel%Old(i, j) = Me%WaterLevel%New(i, j)

                endif cd4

            enddo do5
            enddo do4   

            !UnGets WaterPoints2D
            call UnGetHorizontalMap(Me%ObjHorizontalMap, &
                                  Me%External_Var%WaterPoints2D, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                       &
                stop 'ConstructHydrodynamicProperties - ModuleHydrodynamic - ERR44'


cd6:        if (Me%ComputeOptions%Residual) then 

do8:            do  j=JLB, JUB
do9:            do  i=ILB, IUB

                    Me%Residual%WaterLevel(i, j) = Me%WaterLevel%New(i, j)

                enddo do9
                enddo do8
            
            endif cd6


            ! Z direction
do10:       do  k=KLB, KUB+1
do11:       do  j=JLB, JUB
do12:       do  i=ILB, IUB

                Me%WaterFluxes%Z(i, j, k) =    0.

                if (.not. Me%ComputeOptions%BaroclinicRadia == NoRadiation_)  then

                    Me%VelBaroclinic%W_New   (i, j, k) =   0.
                    Me%VelBaroclinic%W_Old   (i, j, k) =   0.

                endif

                
cd7:            if (Me%ComputeOptions%Residual) then 

                    !Vertical velocity
                    Me%Residual%Vertical_Velocity (i, j, k) = 0.

                endif cd7

            enddo do12
            enddo do11  
            enddo do10

            if (Me%ComputeOptions%Residual) then
                !Number of iterations where residual properties was compute
                Me%Residual%ResidualTime    = 0
                !Residual Layer Thickness
                Me%Residual%DWZ(ILB:IUB, JLB:JUB, KLB:KUB) = 0.

            endif
                

            !X direction
do13:       do  k=KLB, KUB
do14:       do  j=JLB, JUB + 1
do15:       do  i=ILB, IUB

                !Horizontal Velocity
                Me%Velocity%Horizontal%U%New(i, j, k) =                     &
                    Me%Velocity%Horizontal%U%Default

                !Water fluxes D3
                Me%WaterFluxes%X(i, j, k)             =   0.

                if (.not. Me%ComputeOptions%BaroclinicRadia == NoRadiation_)  then

                    Me%VelBaroclinic%U%New(i, j, k) =   0.
                    Me%VelBaroclinic%U%Old(i, j, k) =   0.

                endif


                
cd8:            if (Me%ComputeOptions%Residual) then 


                    !Horizontal velocity
                    Me%Residual%Velocity_U(i, j, k)   =   0.

                    !Residual specific water fluxes
                    Me%Residual%WaterFlux_X(i, j, k)  =   0. 

                endif cd8

            enddo do15
            enddo do14  
            enddo do13


            ! Y direction
do16:       do  k=KLB, KUB
do17:       do  j=JLB, JUB
do18:       do  i=ILB, IUB + 1

                !Horizontal Velocity
                Me%Velocity%Horizontal%V%New(i, j, k) =                     &
                    Me%Velocity%Horizontal%V%Default



                !Water fluxes D3
                Me%WaterFluxes%Y(i, j, k)                =   0.

                if (.not. Me%ComputeOptions%BaroclinicRadia == NoRadiation_)  then

                    Me%VelBaroclinic%V%New(i, j, k) =   0.
                    Me%VelBaroclinic%V%Old(i, j, k) =   0.

                endif

               
cd9:            if (Me%ComputeOptions%Residual) then 

                    !Horizontal velocity
                    Me%Residual%Velocity_V (i, j, k)  =   0.

                    !Residual water fluxes
                    Me%Residual%WaterFlux_Y(i, j, k)  =   0.  

                endif cd9

            enddo do18
            enddo do17  
            enddo do16


            !Disposes pointer to the Bathymetry
            call UngetGridData(Me%ObjGridData, Bathymetry, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                        &
                stop 'ConstructHydrodynamicProperties - ModuleHydrodynamic - ERR06'



        endif cd1




        !If the hydrodynamic is read from a file
        Evolution = Me%ComputeOptions%Evolution


cd10:   if (Evolution == Read_File_) then
            call GetHydrodynamicFileIOState(InputStateEx = InputStateEx)
            call StartHydrodynamicFile (Me%ObjHydrodynamicFileIn,           &
                                        Me%ObjGridData,                   &
                                        Me%ObjHorizontalGrid,               &
                                        Me%ObjGeometry,                     &
                                        Me%ObjMap,                          &
                                        Me%ObjHorizontalMap,                &
                                        Me%ObjTime,                         &
                                        InputStateEx,                                    &
                                        InitialWaterLevel      =                         &
                                        Me%WaterLevel%New,                  &
                                        InitialWaterFluxX      =                         &
                                        Me%WaterFluxes%X,                   &
                                        InitialWaterFluxY      =                         &
                                        Me%WaterFluxes%Y,                   &
                                        InitialDischarges      =                         &
                                        Me%WaterFluxes%Discharges,          &
                                        InitialComputeFacesU3D =                         &
                                        InitialComputeFacesU3D,                          &
                                        InitialComputeFacesV3D =                         &
                                        InitialComputeFacesV3D,                          &
                                        STAT = STAT_CALL)            

             if (STAT_CALL /= SUCCESS_)                                                  &
                stop 'Subroutine Construct_Sub_Modules; Module ModuleHydrodynamic. ERR08.' 

             call SetComputesFaces3D(Me%ObjMap,                             &
                                InitialComputeFacesU3D,                                  &
                                InitialComputeFacesV3D,                                  &
                                Me%CurrentTime,                             &
                                STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine Construct_Sub_Modules; Module ModuleHydrodynamic. ERR09.' 
 
            nullify(InitialComputeFacesU3D, InitialComputeFacesV3D)

        endif cd10

        if(Me%ComputeOptions%Obstacle)then

            call ConstructDragCoefficients

        end if
        !------------------------------------------------------------------------

    end subroutine ConstructHydrodynamicProperties
    
    !----------------------------------------------------------------------------


    !----------------------------------------------------------------------------

    subroutine InitialReferenceWaterFluxes

        !Arguments------------------------------------------------------------


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_X, WaterFlux_Y
        real,    dimension(:,:,:), pointer :: Velocity_U, Velocity_V, Area_U, Area_V

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_U, ComputeFaces3D_V
        integer, dimension(:,:),   pointer :: KFloor_U, KFloor_V

        integer                            :: I, J, K, Kbottom

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB, Grid, Evolution

        !--------------------------------------------------------------------------

        !If the hydrodynamic is read from a file
        Evolution = Me%ComputeOptions%Evolution


        !PCL
cd1:    if (.not. Me%ComputeOptions%Continuous .and.                        &
            .not. Evolution == Read_File_ .and. Me%Relaxation%Velocity )  then               
            

            !To let the model take access to the Mapping and geometry variables
            call ReadLock_External_Modules


            !Begin - Shorten variables name 
            IUB = Me%WorkSize%IUB
            ILB = Me%WorkSize%ILB
            JUB = Me%WorkSize%JUB
            JLB = Me%WorkSize%JLB
            KUB = Me%WorkSize%KUB
            KLB = Me%WorkSize%KLB


            WaterFlux_X      => Me%WaterFluxes%X
            WaterFlux_Y      => Me%WaterFluxes%Y

            Velocity_U       => Me%Velocity%Horizontal%U%New
            Velocity_V       => Me%Velocity%Horizontal%V%New

            ComputeFaces3D_U => Me%External_Var%ComputeFaces3D_U
            ComputeFaces3D_V => Me%External_Var%ComputeFaces3D_V

            KFloor_U         => Me%External_Var%KFloor_U
            KFloor_V         => Me%External_Var%KFloor_V

            Area_U           => Me%External_Var%Area_U
            Area_V           => Me%External_Var%Area_V


            !End - Shorten variables name 



            WaterFlux_X = 0.

        doj: do j = JLB, JUB
        doi: do i = ILB, IUB

        Cov1:   if (ComputeFaces3D_U(I, J, KUB) == Covered) then

                    Kbottom = KFloor_U(i, j)

        dok:        do  k = Kbottom, KUB
 
                        ![m^3/s]              = [ ] * [m/s] * [m^2]
                        WaterFlux_X(i, j, k) = Velocity_U(i, j, k) * &
                                                dble(Area_U(i, j, k))
                    enddo dok

                endif Cov1

            enddo doi
            enddo doj


            WaterFlux_Y = 0.

        doj1: do j = JLB, JUB
        doi1: do i = ILB, IUB

        Cov2:   if (ComputeFaces3D_V(I, J, KUB) == Covered) then

                    Kbottom = KFloor_V(i, j)

        dok1:        do  k = Kbottom, KUB
 
                        ![m^3/s]              = [ ] * [m/s] * [m^2]
                        WaterFlux_Y(i, j, k) = Velocity_V(i, j, k) * &
                                                dble(Area_V(i, j, k))
                    enddo dok1

                endif Cov2

            enddo doi1
            enddo doj1

            !Nullify auxiliar variables
            nullify (WaterFlux_X)
            nullify (WaterFlux_Y)
            nullify (Velocity_U)
            nullify (Velocity_V)

            nullify (ComputeFaces3D_U)
            nullify (ComputeFaces3D_V)
            
            nullify (KFloor_U)
            nullify (KFloor_V)

            nullify (Area_U) 
            nullify (Area_V)

            call ModifyWaterDischarges 

            Grid = Fix

            call New_VerticalHydrodynamic( Grid)

            !Unget the Mapping and geometry variables
            call ReadUnLock_External_Modules

        endif cd1


        !This is necessary because the Residual Vertical flux is not been compute
cd2:    if (Me%ComputeOptions%Evolution == Residual_hydrodynamic_ .or.      &
            Me%ComputeOptions%Evolution == No_hydrodynamic_) then

            !To let the model take access to the Mapping and geometry variables
            call ReadLock_External_Modules

            Grid = Fix

            call New_VerticalHydrodynamic( Grid)

            !Unget the Mapping and geometry variables
            call ReadUnLock_External_Modules

        endif cd2


    end subroutine InitialReferenceWaterFluxes

    !----------------------------------------------------------------------------

    subroutine InitialHydrodynamicFileVel

        !Arguments------------------------------------------------------------


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_X, WaterFlux_Y
        real,    dimension(:,:,:), pointer :: Velocity_U, Velocity_V, Area_U, Area_V

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_U, ComputeFaces3D_V
        integer, dimension(:,:),   pointer :: KFloor_U, KFloor_V

        integer                            :: I, J, K, Kbottom

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB, Evolution, Grid

        !--------------------------------------------------------------------------

        !If the hydrodynamic is read from a file
        Evolution = Me%ComputeOptions%Evolution

cd1:    if (Evolution == Read_File_) then

            !To let the model take access to the Mapping and geometry variables
            call ReadLock_External_Modules


            !Begin - Shorten variables name 
            IUB = Me%WorkSize%IUB
            ILB = Me%WorkSize%ILB
            JUB = Me%WorkSize%JUB
            JLB = Me%WorkSize%JLB
            KUB = Me%WorkSize%KUB
            KLB = Me%WorkSize%KLB


            WaterFlux_X      => Me%WaterFluxes%X
            WaterFlux_Y      => Me%WaterFluxes%Y

            Velocity_U       => Me%Velocity%Horizontal%U%New
            Velocity_V       => Me%Velocity%Horizontal%V%New

            ComputeFaces3D_U => Me%External_Var%ComputeFaces3D_U
            ComputeFaces3D_V => Me%External_Var%ComputeFaces3D_V

            KFloor_U         => Me%External_Var%KFloor_U
            KFloor_V         => Me%External_Var%KFloor_V

            Area_U           => Me%External_Var%Area_U
            Area_V           => Me%External_Var%Area_V


            !End - Shorten variables name 



            Velocity_U(:,:,:) = 0.

        doj: do j = JLB, JUB
        doi: do i = ILB, IUB

        Cov1:   if (ComputeFaces3D_U(I, J, KUB) == Covered) then

                    Kbottom = KFloor_U(i, j)

        dok:        do  k = Kbottom, KUB
 
                        ! [m/s]               = [m^3/s] / [m^2]
                        Velocity_U(i, j, k)   = real(WaterFlux_X(i, j, k) /              &
                                                dble(Area_U(i, j, k)))
                    enddo dok

                endif Cov1

            enddo doi
            enddo doj


            Velocity_V(:,:,:) = 0.

        doj1: do j = JLB, JUB
        doi1: do i = ILB, IUB

        Cov2:   if (ComputeFaces3D_V(I, J, KUB) == Covered) then

                    Kbottom = KFloor_V(i, j)

        dok1:        do  k = Kbottom, KUB
 
                        ! [m/s]               = [m^3/s] / [m^2]
                        Velocity_V(i, j, k)   = real(WaterFlux_Y(i, j, k) /              &
                                                dble(Area_V(i, j, k)))
                    enddo dok1

                endif Cov2

            enddo doi1
            enddo doj1

            !Nullify auxiliar variables
            nullify (WaterFlux_X)
            nullify (WaterFlux_Y)
            nullify (Velocity_U)
            nullify (Velocity_V)

            nullify (ComputeFaces3D_U)
            nullify (ComputeFaces3D_V)
            
            nullify (KFloor_U)
            nullify (KFloor_V)

            nullify (Area_U) 
            nullify (Area_V)

            call ModifyWaterDischarges 

            Grid = Fix

            call New_VerticalHydrodynamic( Grid)

            !Unget the Mapping and geometry variables
            call ReadUnLock_External_Modules

        endif cd1


    end subroutine InitialHydrodynamicFileVel


    !----------------------------------------------------------------------------

    subroutine NewEqualsOld

        !Arguments------------------------------------------------------------


        !Local---------------------------------------------------------------------

            Me%Velocity%Horizontal%U%Old(:,:,:) = Me%Velocity%Horizontal%U%New(:,:,:)
            Me%Velocity%Horizontal%V%Old(:,:,:) = Me%Velocity%Horizontal%V%New(:,:,:)

            Me%WaterLevel%Old(:,:)              = Me%WaterLevel%New(:,:)

    end subroutine NewEqualsOld


    !--------------------------------------------------------------------------
    !If the user want's to use the values of a previous   
    ! run the read the property values form the final      
    ! results file of a previous run. By default this      
    ! file is in HDF format                                

    subroutine Read_Final_Hydrodynamic_File

        !Arguments-------------------------------------------------------------

         

        !External--------------------------------------------------------------

        integer :: STAT_CALL

        !Local-----------------------------------------------------------------
        real   , dimension(:,:  ), pointer :: Aux2D
        real   , dimension(:,:,:), pointer :: Aux3D
        real(8), dimension(:,:,:), pointer :: Aux3DDouble

        type (T_Time)                      :: BeginTime, EndTimeFile, EndTime

        real                               :: Year_File, Month_File, Day_File,           &
                                              Hour_File, Minute_File, Second_File,       &
                                              DT_error
        real                               :: Previous_Discretization

        integer                            :: IUB, JUB, KUB, ILB, JLB, KLB
        integer                            :: InitialFile, i, j, k, Evolution
        integer                            :: BaroclinicRadia
        logical                            :: EXT, Residual
        !----------------------------------------------------------------------

        ILB = Me%Size%ILB 
        IUB = Me%Size%IUB

        JLB = Me%Size%JLB 
        JUB = Me%Size%JUB 

        KLB = Me%Size%KLB 
        KUB = Me%Size%KUB 


        inquire (FILE=Me%Files%InitialHydrodynamic, EXIST=EXT) 

        if (.not.EXT)                                                                    &
            call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR01.')


        call UnitsManager(InitialFile, FileOpen, STAT = STAT_CALL) 

        if (STAT_CALL /= SUCCESS_)                                                          &
             call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR02.')

        open(Unit = InitialFile, File = Me%Files%InitialHydrodynamic,       &
             Form = 'UNFORMATTED', status = 'OLD', IOSTAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                                          &
             call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR03.')

        !Start reading the end file of the previous run 
        read(InitialFile) Year_File, Month_File, Day_File, Hour_File, Minute_File, Second_File


        call SetDate(EndTimeFile, Year_File, Month_File, Day_File, Hour_File, Minute_File, Second_File)


        call GetComputeTimeLimits(Me%ObjTime, BeginTime = BeginTime, &
                                  EndTime = EndTime, STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                                          &
             call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR04.')
        
        DT_error = EndTimeFile - BeginTime

        !Avoid rounding erros - Frank 08-2001
        if (abs(DT_error) >= 0.01) then
            
            write(*,*) 'The end time of the previous run is different from the start time of this run'
            write(*,*) 'Date in the file'
            write(*,*) Year_File, Month_File, Day_File, Hour_File, Minute_File, Second_File
            write(*,*) 'DT_error', DT_error
            call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR05.')


        endif

        read(InitialFile) Previous_Discretization
        
        if (Previous_Discretization /= Me%ComputeOptions%Num_Discretization) then

            write(*,*) 'previous run time discretization is different from this one'

            call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR06.')


        endif


        read(InitialFile) Residual

        !Read the last direction computed implicit by the model
        read(InitialFile) Me%Direction%XY 
        

        !Water level

        read(InitialFile) ((Me%WaterLevel%New(i, j), &
                           i = ILB, IUB), j = JLB, JUB)

        Me%WaterLevel%Old (:,:) = Me%WaterLevel%New(:,:)


        !Horizontal velocity Old
        read(InitialFile) (((Me%Velocity%Horizontal%U%Old(i, j, k), &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )


        read(InitialFile) (((Me%Velocity%Horizontal%V%Old(i, j, k), &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

        !Horizontal velocity New
        read(InitialFile) (((Me%Velocity%Horizontal%U%New(i, j, k), &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

        read(InitialFile) (((Me%Velocity%Horizontal%V%New(i, j, k), &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )


        !Water fluxes
        read(InitialFile) (((Me%WaterFluxes%X(i, j, k), &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

        read(InitialFile) (((Me%WaterFluxes%Y(i, j, k) , &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )
                            
        read(InitialFile) (((Me%WaterFluxes%Z(i, j, k), &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )


        Evolution = Me%ComputeOptions%Evolution

        
        if (Evolution == Residual_hydrodynamic_ .and. .not. Residual) then

            write(*,*) 'Can not have a residual evolution with out a initial file with residual values'
                        
            call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR07.')


        endif 

      
cd1:    if (Residual .and. .not. Me%ComputeOptions%Residual) then
   
            write(*,*)  
            write(*,*)  
            write(*,*)  
            write(*,*) 'Warning: YOU HAVE STOPPED THE RESIDUAL CALCULATION, '                   
            write(*,*) 'In the run before this one you have compute residual currents, '                   
            write(*,*) 'In this run you dont want to compute residual currents ? '                   
            write(*,*) '                        '
            write(*,*) 'SUBROUTINE Read_Final_Hydrodynamic_File; Module ModuleHydrodynamic. WRN01.'
            write(*,*)  
            write(*,*)  
            write(*,*)  

            allocate (Aux2D         (ILB:IUB, JLB:JUB))
            allocate (Aux3D         (ILB:IUB, JLB:JUB, KLB:KUB))
            allocate (Aux3DDouble   (ILB:IUB, JLB:JUB, KLB:KUB))

            read(InitialFile) Me%Residual%ResidualTime

            !Average water level 
            read(InitialFile) ((Aux2D(i, j), i = ILB, IUB), j = JLB, JUB)

            !Residual horizontal velocities
            read(InitialFile) (((Aux3D(i, j, k), i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )
            read(InitialFile) (((Aux3D(i, j, k), i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            !Residual vertical velocity  
            read(InitialFile) (((Aux3D(i, j, k), i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            !Residual Water specific fluxes 
            read(InitialFile) (((Aux3DDouble(i, j, k), i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            read(InitialFile) (((Aux3DDouble(i, j, k), i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )


            deallocate (Aux2D)
            deallocate (Aux3D)
            deallocate (Aux3DDouble)
       
        else if (Residual .and. Me%ComputeOptions%Residual) then cd1

           
            read(InitialFile) Me%Residual%ResidualTime

            !Average water level 
            read(InitialFile) ((Me%Residual%WaterLevel(i, j),               &
                               i = ILB, IUB), j = JLB, JUB)

            !Residual horizontal velocities
            read(InitialFile) (((Me%Residual%Velocity_U(i, j, k),           &
                               i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )
            read(InitialFile) (((Me%Residual%Velocity_V(i, j, k),           &
                               i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            !Residual vertical velocity  
            read(InitialFile) (((Me%Residual%Vertical_Velocity(i, j, k),    &
                               i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            !Residual Water specific fluxes 
            read(InitialFile) (((Me%Residual%WaterFlux_X(i, j, k),          &
                               i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            read(InitialFile) (((Me%Residual%WaterFlux_Y(i, j, k) ,         &
                               i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            
cd2:        if (Evolution == Residual_hydrodynamic_) then

                Me%WaterLevel%Old(:,:) = Me%Residual%WaterLevel(:,:)

                Me%WaterLevel%New(:,:) = Me%Residual%WaterLevel(:,:)


                Me%Velocity%Horizontal%U%Old(:,:,:) = Me%Residual%Velocity_U(:,:,:)

                Me%Velocity%Horizontal%U%New(:,:,:) = Me%Residual%Velocity_U(:,:,:)


                Me%Velocity%Horizontal%V%Old(:,:,:) = Me%Residual%Velocity_V(:,:,:)

                Me%Velocity%Horizontal%V%New(:,:,:) = Me%Residual%Velocity_V(:,:,:)

                !Module - ModuleHorizontalGrid
                !Horizontal Grid properties
                 call GetHorizontalGrid(Me%ObjHorizontalGrid,                           &
                                        DXX  = Me%External_Var%DXX,                     &
                                        DYY  = Me%External_Var%DYY,                     &
                                        STAT = STAT_CALL)

                if (STAT_CALL /= SUCCESS_)                                              &
                     call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR40.')

                do k = KLB, KUB
                do j = JLB, JUB
                do i = ILB, IUB

                    ![m3/s]                 = [m2/s] * [m]
                    Me%WaterFluxes%X(i,j,k) = Me%Residual%WaterFlux_X(i,j,k) * Me%External_Var%DYY(i, J)
                    Me%WaterFluxes%Y(i,j,k) = Me%Residual%WaterFlux_Y(i,j,k) * Me%External_Var%DXX(i, J)

                enddo
                enddo
                enddo
                    
                call UnGetHorizontalGrid(Me%ObjHorizontalGrid, Me%External_Var%DXX,     &
                                         STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_)                                              &
                     call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR50.')



                call UnGetHorizontalGrid(Me%ObjHorizontalGrid, Me%External_Var%DYY,     &
                                         STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_)                                              &
                     call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR60.')




            endif cd2


        else if (.not. Residual .and. Me%ComputeOptions%Residual) then cd1

                Me%Residual%ResidualTime    =  0


                do  j = JLB, JUB 
                do  i = ILB, IUB

                    Me%Residual%WaterLevel(i, j)    =  0.

                    do  k = KLB, KUB

                        !Residual horizontal velocity
                        Me%Residual%Velocity_U(i, j, k) =  0.
                        Me%Residual%Velocity_V(i, j, k) =  0.

                        !Residual vertical velocity
                        Me%Residual%Vertical_Velocity(i, j, k) =  0.              

                        !Residual Water fluxes
                        Me%Residual%WaterFlux_X(i, j, k) = 0.
                        Me%Residual%WaterFlux_Y(i, j, k) = 0.

                        !Read residual layer thickness
                        Me%Residual%DWZ(i, j, k) = 0

                    enddo

                enddo
                enddo
     
        endif cd1

        call ReadGeometry(Me%ObjGeometry, InitialFile, STAT = STAT_CALL) 

        if (STAT_CALL /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR14.')

cd3:    if (Residual .and. Me%ComputeOptions%Residual) then 
            !Read residual layer thickness
            read(InitialFile, END = 10) (((Me%Residual%DWZ(i, j, k),        &
                                i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

10          continue  

        endif cd3


        read(InitialFile, END = 20) BaroclinicRadia


cd4:    if (.not. BaroclinicRadia                                == NoRadiation_ .and.   &
            .not. Me%ComputeOptions%BaroclinicRadia == NoRadiation_) then


            !Horizontal baroclinic velocity Old
            read(InitialFile, END = 20) (((Me%VelBaroclinic%U%Old(i, j, k), &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )


            read(InitialFile, END = 20) (((Me%VelBaroclinic%V%Old(i, j, k), &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            !Horizontal baroclinic velocity New
            read(InitialFile, END = 20) (((Me%VelBaroclinic%U%New(i, j, k), &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            read(InitialFile, END = 20) (((Me%VelBaroclinic%V%New(i, j, k), &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            !vertical baroclinic velocity 
            read(InitialFile, END = 20) (((Me%VelBaroclinic%W_New(i, j, k), &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            read(InitialFile, END = 20) (((Me%VelBaroclinic%W_Old(i, j, k), &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

        endif cd4

20      continue 

        !NonHydrostatic
        if (Me%NonHydrostatic%ON) then

            read(InitialFile, IOSTAT = STAT_CALL)                                          &  
                (((Me%Velocity%Vertical%CartesianOld(i, j, k),                          &
                   i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            if (STAT_CALL /= SUCCESS_) then
                call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR15.')
            endif

        endif

        call UnitsManager(InitialFile, FileClose, STAT = STAT_CALL) 

        if (STAT_CALL /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_,'Read_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR16.')



    end subroutine Read_Final_Hydrodynamic_File

    !--------------------------------------------------------------------------


    subroutine Initial_Geometry( ExternalWaterLevel)

        !Arguments------------------------------------------------------------
        real, dimension(:,:), pointer, optional  :: ExternalWaterLevel

        !Local----------------------------------------------------------------
        integer, dimension(:,:,:), pointer  :: WaterPoints3D
        real,    dimension(:,:  ), pointer  :: SurfaceElevation, Bathymetry
        real                                :: MinWaterColumn
        type(T_Time)                        :: CurrentTime
        logical                             :: Continuous_Compute
        integer                             :: STAT_CALL, i, j

        !Begin----------------------------------------------------------------
        
        CurrentTime = Me%CurrentTime

        call GetWaterPoints3D(Me%ObjMap, WaterPoints3D,                                 &
                              STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                      &
            Stop 'Sub. Initial_Geometry - ModuleHydrodynamic - ERR10.'

        if (present(ExternalWaterLevel)) then

            SurfaceElevation   => ExternalWaterLevel

            !This is redundant in some cases but in the case of the Sea Surface High interpolate
            !directly from the Father model it avoid water columns with 0 meters of tickness 

            !Gets Bathymetry
            call GetGridData(Me%ObjGridData, Bathymetry, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                  &
                Stop 'Sub. Initial_Geometry - ModuleHydrodynamic - ERR20.'

            call GetGeometryMinWaterColumn(Me%ObjGeometry, MinWaterColumn, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                  &                    
                Stop 'Sub. Initial_Geometry - ModuleHydrodynamic - ERR30.'
            
do4:        do  j=Me%WorkSize%JLB, Me%WorkSize%JUB
do5:        do  i=Me%WorkSize%ILB, Me%WorkSize%IUB
                    
cd4:            if (WaterPoints3D(i, j, Me%WorkSize%KUB) == WaterPoint) then
                    
cd5:                if (SurfaceElevation(i,j) < (- Bathymetry(i, j) + 0.999 * MinWaterColumn)) then
                        SurfaceElevation(i,j) =  - Bathymetry(i, j) + 0.999 * MinWaterColumn
                    endif cd5
                endif cd4
            enddo do5
            enddo do4

            !UnGets Bathymetry
            call UnGetGridData(Me%ObjGridData, Bathymetry, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                  &
                Stop 'Sub. Initial_Geometry - ModuleHydrodynamic - ERR40.'

        else

            SurfaceElevation   => Me%WaterLevel%New

        endif

        Continuous_Compute =  Me%ComputeOptions%Continuous

        !Compute new volume 
        call ComputeInitialGeometry(Me%ObjGeometry, WaterPoints3D,                      &
                                    SurfaceElevation,                                   &
                                    ActualTime = Me%CurrentTime,                        &
                                    ContinuesCompute = Continuous_Compute,              &
                                    NonHydrostatic   = Me%NonHydrostatic%ON,            & 
                                    STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                      &                    
            Stop 'Sub. Initial_Geometry - ModuleHydrodynamic - ERR50.'


        call UnGetMap(Me%ObjMap, WaterPoints3D, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                      &
            Stop 'Sub. Initial_Geometry - ModuleHydrodynamic - ERR60.'


        !Update the moving boundary (boundary of the tidal areas covered)
        call UpdateComputeFaces3D(Me%ObjMap, SurfaceElevation,                          &
                                  CurrentTime, STAT = STAT_CALL)      
        if (STAT_CALL /= SUCCESS_)                                                      &
            stop 'Subroutine Initial_Geometry; module ModuleHydrodynamic. ERR70.'

        nullify(SurfaceElevation)
                    
    end subroutine Initial_Geometry
    
    !End----------------------------------------------------------------------



    subroutine Open_HDF5_OutPut_File

        !Arguments-------------------------------------------------------------
 

        !Local-----------------------------------------------------------------
        real, pointer, dimension(:, :)              :: Bathymetry
        integer, pointer, dimension(:, :, :)        :: WaterPoints3D
        integer                                     :: STAT_CALL
        integer                                     :: WorkILB, WorkIUB
        integer                                     :: WorkJLB, WorkJUB
        integer                                     :: WorkKLB, WorkKUB
        integer                                     :: HDF5_CREATE

        !----------------------------------------------------------------------

        !Bounds
        WorkILB = Me%WorkSize%ILB 
        WorkIUB = Me%WorkSize%IUB 

        WorkJLB = Me%WorkSize%JLB 
        WorkJUB = Me%WorkSize%JUB 

        WorkKLB = Me%WorkSize%KLB 
        WorkKUB = Me%WorkSize%KUB 

        !Gets a pointer to Bathymetry
        call GetGridData      (Me%ObjGridData, Bathymetry, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR01'

        !Gets WaterPoints3D
        call GetWaterPoints3D   (Me%ObjMap, WaterPoints3D, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR03'


        !Gets File Access Code
        call GetHDF5FileAccess  (HDF5_CREATE = HDF5_CREATE)

        !Opens HDF File
        call ConstructHDF5      (Me%ObjHDF5,                                &
                                 trim(Me%Files%OutPutFields)//"5",          &
                                 HDF5_CREATE, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR04'

        
        !Creates Groups
        call HDF5CreateGroup (Me%ObjHDF5, "/Grid",              STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR05'

        call HDF5CreateGroup (Me%ObjHDF5, "/Grid/VerticalZ",    STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR06'

        call HDF5CreateGroup (Me%ObjHDF5, "/Grid/OpenPoints",   STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR07'

        call HDF5CreateGroup (Me%ObjHDF5, "/Time",              STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR08'

        call HDF5CreateGroup (Me%ObjHDF5, "/Results",           STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR09'

        call HDF5CreateGroup (Me%ObjHDF5, "/Results/"//trim(GetPropertyName (WaterLevel_)),STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR10'

        call HDF5CreateGroup (Me%ObjHDF5, "/Results/"//trim(GetPropertyName (VelocityU_)),  STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR11'

        call HDF5CreateGroup (Me%ObjHDF5, "/Results/"//trim(GetPropertyName (VelocityV_)),STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR12'

        call HDF5CreateGroup (Me%ObjHDF5, "/Results/"//trim(GetPropertyName (VelocityW_)),STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR13'

        call HDF5CreateGroup (Me%ObjHDF5, "/Results/"//trim(GetPropertyName (VelocityModulus_)),STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR14'


        if (.not. Me%ComputeOptions%BaroclinicRadia == NoRadiation_) then

            call HDF5CreateGroup (Me%ObjHDF5, "/Results/Baroclinic",   STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR16'

            call HDF5CreateGroup (Me%ObjHDF5, "/Results/Baroclinic/X", STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR17'

            call HDF5CreateGroup (Me%ObjHDF5, "/Results/Baroclinic/Y", STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR18'

            call HDF5CreateGroup (Me%ObjHDF5, "/Results/Baroclinic/Z", STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR19'

        endif

        if (Me%ComputeOptions%Residual) then

            call HDF5CreateGroup (Me%ObjHDF5, "/Residual",   STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR20'

            call HDF5CreateGroup (Me%ObjHDF5, "/Residual/Velocity",   STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR21'

            call HDF5CreateGroup (Me%ObjHDF5, "/Residual/Velocity/X", STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR22'

            call HDF5CreateGroup (Me%ObjHDF5, "/Residual/Velocity/Y", STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR23'
            
            call HDF5CreateGroup (Me%ObjHDF5, "/Residual/Velocity/Z", STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR24'

            call HDF5CreateGroup (Me%ObjHDF5, "/Residual/Flux",    STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR25'

            call HDF5CreateGroup (Me%ObjHDF5, "/Residual/Flux/X",  STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR26'

            call HDF5CreateGroup (Me%ObjHDF5, "/Residual/Flux/Y",  STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR27'

            call HDF5CreateGroup (Me%ObjHDF5, "/Residual/FluxVel",    STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR28'

            call HDF5CreateGroup (Me%ObjHDF5, "/Residual/FluxVel/X",  STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR29'

            call HDF5CreateGroup (Me%ObjHDF5, "/Residual/FluxVel/Y",  STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR30'

            call HDF5CreateGroup (Me%ObjHDF5, "/Residual/Waterlevel", STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR31'

        endif

        call HDF5CreateGroup (Me%ObjHDF5, "/Results/Error", STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR32'

        call HDF5CreateGroup (Me%ObjHDF5, "/Results/VolumeCreated", STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR33'

        if (Me%TidePotential%Compute) then

            call HDF5CreateGroup (Me%ObjHDF5, "/Results/TidePotential", STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR34'

        endif

        if (Me%ComputeOptions%Baroclinic) then

            call HDF5CreateGroup (Me%ObjHDF5, "/Results/"//trim(GetPropertyName(BaroclinicForceX_)), STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR34a'

            call HDF5CreateGroup (Me%ObjHDF5, "/Results/"//trim(GetPropertyName(BaroclinicForceY_)), STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR34b'

        endif


        !Write the Horizontal Grid
        call WriteHorizontalGrid(Me%ObjHorizontalGrid, Me%ObjHDF5, &
                                 STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR35'

        !Sets limits for next write operations
        call HDF5SetLimits   (Me%ObjHDF5, WorkILB, WorkIUB, WorkJLB,        &
                              WorkJUB, WorkKLB, WorkKUB, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR35'


        !Writes the Grid
        call HDF5WriteData   (Me%ObjHDF5, "/Grid", "Bathymetry", "m",       &
                              Array2D = Bathymetry,                                      &
                              STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR36'

        call HDF5WriteData   (Me%ObjHDF5, "/Grid", "WaterPoints3D", "-",    &
                              Array3D = WaterPoints3D,                                   &
                              STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR37'

        call HDF5SetLimits   (Me%ObjHDF5, WorkILB, WorkIUB+1, WorkJLB,      &
                              WorkJUB+1, WorkKLB, WorkKUB, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR38'


        !Writes everything to disk
        call HDF5FlushMemory (Me%ObjHDF5, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR40'


        !Ungets the Bathymetry
        call UngetGridData (Me%ObjGridData, Bathymetry, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR41'

        !Ungets the WaterPoints
        call UnGetMap        (Me%ObjMap, WaterPoints3D, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR42'


        !----------------------------------------------------------------------

    end subroutine Open_HDF5_OutPut_File
    
    !--------------------------------------------------------------------------

    subroutine Construct_Time_Serie

        !Arguments-------------------------------------------------------------

        !External--------------------------------------------------------------
        character(len=StringLength), dimension(:), pointer  :: PropertyList

        !Local-----------------------------------------------------------------
        integer                                             :: nProperties
        integer                                             :: STATUS
        integer                                             :: iflag
        character(len=StringLength)                         :: TimeSerieLocationFile

        call GetWaterPoints3D(Me%ObjMap,                                    &
                              Me%External_Var%WaterPoints3D,                &
                              STAT = STATUS)
        
        if (STATUS /= SUCCESS_)                                              &
            call SetError (FATAL_, OUT_OF_MEM_, "Construct_Time_Serie - Hydrodynamic - ERR01")
        
        nProperties = 7 !3 velocity components  (West-East, North-South, vertical), intensity, direction, elevation and open points 

        !Allocates PropertyList
        allocate(PropertyList(nProperties), STAT = STATUS)

        if (STATUS /= SUCCESS_)                                              &
            call SetError (FATAL_, OUT_OF_MEM_, "Construct_Time_Serie - Hydrodynamic - ERR02")

        !Fills up PropertyList
        PropertyList(1) = 'West_East_Velocity'
        PropertyList(2) = 'South_North_Velocity'
        PropertyList(3) = 'Vertical'
        PropertyList(4) = 'Intensity'
        PropertyList(5) = 'Direction'
        PropertyList(6) = 'Elevation'
        PropertyList(7) = 'Open_Point'

        call GetData(TimeSerieLocationFile,                                             &
                     Me%ObjEnterData,iflag,                                             &
                     SearchType   = FromFile,                                           &
                     keyword      = 'TIME_SERIE_LOCATION',                              &
                     ClientModule = 'ModuleHydrodynamic',                               &
                     Default      = Me%Files%ConstructData,                             &
                     STAT         = STATUS)
        if (STATUS .NE. SUCCESS_)                                                       &
            stop 'Construct_Time_Serie - Hydrodynamic - ERR03' 

        !Constructs TimeSerie
        call StartTimeSerie(Me%ObjTimeSerie, Me%ObjTime,                                &
                            TimeSerieLocationFile,                                      &
                            PropertyList, "srh",                                        &
                            WaterPoints3D = Me%External_Var%WaterPoints3D,              &
                            STAT = STATUS)

        if (STATUS /= SUCCESS_)                                              &
            call SetError (FATAL_, OUT_OF_MEM_, "Construct_Time_Serie - Hydrodynamic - ERR04")


        !Deallocates PropertyList
        deallocate(PropertyList, STAT = STATUS)

        if (STATUS /= SUCCESS_)                                              &
            call SetError (FATAL_, OUT_OF_MEM_, "Construct_Time_Serie - Hydrodynamic - ERR05")


        call UnGetMap(Me%ObjMap,                                            &
                      Me%External_Var%WaterPoints3D,                        &
                      STAT = STATUS)
        
        if (STATUS /= SUCCESS_)                                              &
            call SetError (FATAL_, OUT_OF_MEM_, "Construct_Time_Serie - Hydrodynamic - ERR06")
    
        
    end subroutine Construct_Time_Serie

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------

    subroutine Construct_Output_Profile

        !Local-----------------------------------------------------------------
        integer                                             :: STAT_CALL, iflag
        character(len=StringLength)                         :: TimeSerieLocationFile
        integer                                             :: nProperties
        character(len=StringLength), dimension(:,:), pointer:: PropertyList

        !----------------------------------------------------------------------

        call ReadLock_ModuleHorizontalMap

        call GetData(TimeSerieLocationFile,                                             &
                     Me%ObjEnterData,iflag,                                             &
                     SearchType   = FromFile,                                           &
                     keyword      = 'TIME_SERIE_LOCATION',                              &
                     ClientModule = 'ModuleHydrodynamic',                               &
                     Default      = Me%Files%ConstructData,                             &
                     STAT         = STAT_CALL)
        if (STAT_CALL .NE. SUCCESS_)                                                    &
            stop 'Construct_Output_Profile - ModuleWaterProperties - ERR01' 
            
        nProperties = 5

        !Allocates PropertyList
        allocate(PropertyList(1:nProperties,1:2))

        PropertyList(1,1) = trim(GetPropertyName (VelocityU_      ))
        PropertyList(2,1) = trim(GetPropertyName (VelocityV_      ))
        PropertyList(3,1) = trim(GetPropertyName (VelocityW_      ))
        PropertyList(4,1) = trim(GetPropertyName (VelocityModulus_))
        PropertyList(5,1) = "Direction"

        PropertyList(1,2) = "m/s"
        PropertyList(2,2) = "m/s"
        PropertyList(3,2) = "m/s"
        PropertyList(4,2) = "m/s"
        PropertyList(5,2) = "º"

        call StartProfile  (ProfileID       = Me%ObjProfile,                            &
                            ObjTime         = Me%ObjTime,                               &
                            ProfileDataFile = trim(TimeSerieLocationFile),              &
                            WaterPoints2D   = Me%External_Var%WaterPoints2D,            &
                            KUB             = Me%WorkSize%KUB,                          &
                            nProperties     = nProperties,                              &
                            PropertyList    = PropertyList,                             &
                            ClientName      = "Hydrodynamic",                           &
                            STAT            = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                      &
            stop 'Construct_Output_Profile - ModuleWaterProperties - ERR02'
       
        deallocate(PropertyList)

        call ReadUnLock_ModuleHorizontalMap

    end subroutine Construct_Output_Profile

    !--------------------------------------------------------------------------

    subroutine ConstructMatrixesOutput

        !Arguments-------------------------------------------------------------
        

        !Local-----------------------------------------------------------------
        integer                             :: ILB, IUB, JLB, JUB, KLB, KUB
        integer                             :: STAT_CALL

        !----------------------------------------------------------------------

        !Bounds
        ILB = Me%Size%ILB 
        IUB = Me%Size%IUB 

        JLB = Me%Size%JLB 
        JUB = Me%Size%JUB 

        KLB = Me%Size%KLB 
        KUB = Me%Size%KUB 

        !Horizontal Velocity

        nullify  (Me%OutPut%CenterU   )
        nullify  (Me%OutPut%CenterV   )
        nullify  (Me%OutPut%ModulusH  )
        nullify  (Me%OutPut%DirectionH)

        allocate(Me%OutPut%CenterU   (ILB:IUB, JLB:JUB, KLB:KUB),                       &
                 Me%OutPut%CenterV   (ILB:IUB, JLB:JUB, KLB:KUB),                       &
                 Me%OutPut%ModulusH  (ILB:IUB, JLB:JUB, KLB:KUB),                       &
                 Me%OutPut%DirectionH(ILB:IUB, JLB:JUB, KLB:KUB),                       &
                 STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ConstructMatrixesOutput - ModuleHydrodynamic - ERR10'

        Me%OutPut%CenterU   (:,:,:) = 0.
        Me%OutPut%CenterV   (:,:,:) = 0.
        Me%OutPut%ModulusH  (:,:,:) = 0.
        Me%OutPut%DirectionH(:,:,:) = 0.

        !Vertical Velocity
        nullify  (Me%OutPut%CenterW)
        allocate (Me%OutPut%CenterW(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ConstructMatrixesOutput - ModuleHydrodynamic - ERR20'

        Me%OutPut%CenterW   (:,:,:) = 0.

    
    end subroutine ConstructMatrixesOutput

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------

    subroutine ConstructEnergy

        !Arguments-------------------------------------------------------------

        !Local-----------------------------------------------------------------
        integer                        :: status

        integer, dimension(:), pointer :: aux
        integer                        :: FromFile, iflag


        call GetExtractType  (FromFile = FromFile)

        allocate (aux(6))
        call GetData(aux,                                                                &
                     Me%ObjEnterData, iflag,                                &
                     SearchType = FromFile,                                              &
                     keyword    = 'ENERGY_WINDOW',                                       &
                     Default    = FillValueInt,                                          &                                           
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = status)            
        
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, KEYWORD_, 'ConstructEnergy - Hydrodynamic - ERR02') 

        if   (iflag == 0) then 

            Me%Energy%Window%ILB = Me%WorkSize%ILB
            Me%Energy%Window%IUB = Me%WorkSize%IUB

            Me%Energy%Window%JLB = Me%WorkSize%JLB
            Me%Energy%Window%JUB = Me%WorkSize%JUB

            Me%Energy%Window%KLB = Me%WorkSize%KLB
            Me%Energy%Window%KUB = Me%WorkSize%KUB


        else if (iflag == 6) then

            Me%Energy%Window%ILB = aux(1) 
            Me%Energy%Window%IUB = aux(2) 

            Me%Energy%Window%JLB = aux(3) 
            Me%Energy%Window%JUB = aux(4) 

            Me%Energy%Window%KLB = aux(5) 
            Me%Energy%Window%KUB = aux(6) 

        else

            call SetError(FATAL_, KEYWORD_, 'ConstructEnergy - Hydrodynamic - ERR03') 

        endif

        deallocate (aux)

       
        call UnitsManager(Me%Energy%FileID, FileOpen, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, 'ConstructEnergy - Hydrodynamic - ERR05') 

        open(unit = Me%Energy%FileID, file = Me%Files%Energy, &
             form = 'FORMATTED', status = 'UNKNOWN')

        !Inits the buffer count
        Me%Energy%BufferCount = 0

        write (Me%Energy%FileID,*)  'Year Month Day Hour Minute Second '  // &
                                    'KEtotal PEtotal KE PE M V '          // & 
                                    'OpenV Level BarotropicKE '           // &
                                    'BaroclinicKE VelMax VelMaxBaroclinic'// &
                                    'Enstrophy'   
                        
        !Allocates the buffer
        allocate(Me%Energy%YearBuffer            (1:EnergyBufferSize))
        allocate(Me%Energy%MonthBuffer           (1:EnergyBufferSize))
        allocate(Me%Energy%DayBuffer             (1:EnergyBufferSize))
        allocate(Me%Energy%HourBuffer            (1:EnergyBufferSize))
        allocate(Me%Energy%MinuteBuffer          (1:EnergyBufferSize))
        allocate(Me%Energy%SecondBuffer          (1:EnergyBufferSize))
        allocate(Me%Energy%KineticBuffer         (1:EnergyBufferSize))
        allocate(Me%Energy%PotentialBuffer       (1:EnergyBufferSize))
        allocate(Me%Energy%VorticityBuffer       (1:EnergyBufferSize))
        allocate(Me%Energy%MassBuffer            (1:EnergyBufferSize))
        allocate(Me%Energy%VolumeBuffer          (1:EnergyBufferSize))
        allocate(Me%Energy%OpenVolumeBuffer      (1:EnergyBufferSize))
        allocate(Me%Energy%WaterLevelBuffer      (1:EnergyBufferSize))
        allocate(Me%Energy%BarotropicKEBuffer    (1:EnergyBufferSize))
        allocate(Me%Energy%BaroclinicKEBuffer    (1:EnergyBufferSize))
        allocate(Me%Energy%RelativeKEBuffer      (1:EnergyBufferSize))
        allocate(Me%Energy%RelativePEBuffer      (1:EnergyBufferSize))
        allocate(Me%Energy%VelMaxBuffer          (1:EnergyBufferSize))
        allocate(Me%Energy%VelMaxBaroclinicBuffer(1:EnergyBufferSize))

        call GetData(Me%Energy%DtOut,                                                    &
                     Me%ObjEnterData, iflag,                                             &
                     SearchType = FromFile,                                              &
                     keyword    = 'ENERGY_DT',                                           &
                     Default    = 600.,                                                  &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = status)            
        
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, KEYWORD_, 'ConstructEnergy - Hydrodynamic - ERR21') 

        Me%Energy%NextOutPut = Me%BeginTime


    end subroutine ConstructEnergy


    !--------------------------------------------------------------------------

    Subroutine ConstructTidePotential

        !Arguments-------------------------------------------------------------

        

        !Local-----------------------------------------------------------------
        integer               :: ILB, IUB, JLB, JUB, NComp
        

        NComp = Me%TidePotential%ComponentsNumber


        IUB = Me%Size%IUB
        ILB = Me%Size%ILB
        JUB = Me%Size%JUB
        JLB = Me%Size%JLB

        allocate (Me%TidePotential%Frequency(NComp))
        allocate (Me%TidePotential%Amplitude(NComp))
        allocate (Me%TidePotential%Arguments(NComp))
        allocate (Me%TidePotential%Beta     (NComp))
        allocate (Me%TidePotential%m        (NComp))
        allocate (Me%TidePotential%L        (0:2  ))

!
! ---> Compute 
!
        !Load factor (Specie 0,2 Alpha = 0.953, Specie 1 (diurnal) Alpha = 0.940 (Kantha e Clayson, 2000)
        !Compromise value
        !Alpha = 0.95
        Me%TidePotential%Alpha = 0.95

        !Elasticity Factor (Table 6.1.1 Kantha and Clayson, 2000)
        Me%TidePotential%Beta (Ssa) = 0.693
        Me%TidePotential%Beta (Mm ) = 0.693
        Me%TidePotential%Beta (Mf ) = 0.693

        Me%TidePotential%Beta (K1 ) = 0.7364
        Me%TidePotential%Beta (O1 ) = 0.6950
        Me%TidePotential%Beta (P1 ) = 0.7059
        Me%TidePotential%Beta (Q1 ) = 0.6946

        Me%TidePotential%Beta (M2 ) = 0.693
        Me%TidePotential%Beta (S2 ) = 0.693
        Me%TidePotential%Beta (N2 ) = 0.693
        Me%TidePotential%Beta (K2 ) = 0.693

        !Equilibrium tide amplitude (m) (Table 6.1.1 Kantha and Clayson, 2000)
        Me%TidePotential%Amplitude (Ssa) = 0.019542
        Me%TidePotential%Amplitude (Mm ) = 0.022191
        Me%TidePotential%Amplitude (Mf ) = 0.042017

        Me%TidePotential%Amplitude (K1 ) = 0.142408
        Me%TidePotential%Amplitude (O1 ) = 0.101266
        Me%TidePotential%Amplitude (P1 ) = 0.047129
        Me%TidePotential%Amplitude (Q1 ) = 0.019387

        Me%TidePotential%Amplitude (M2 ) = 0.244102
        Me%TidePotential%Amplitude (S2 ) = 0.113572
        Me%TidePotential%Amplitude (N2 ) = 0.046735
        Me%TidePotential%Amplitude (K2 ) = 0.030875


        !frequency in radianos./hr. (Table 6.1.1 Kantha and Clayson, 2000)
        Me%TidePotential%Frequency (Ssa) = 0.0821373  * Pi / 180.
        Me%TidePotential%Frequency (Mm ) = 0.5443747  * Pi / 180.
        Me%TidePotential%Frequency (Mf ) = 1.0980331  * Pi / 180.

        Me%TidePotential%Frequency (K1 ) = 15.0410686 * Pi / 180.
        Me%TidePotential%Frequency (O1 ) = 13.9430356 * Pi / 180.
        Me%TidePotential%Frequency (P1 ) = 14.9589314 * Pi / 180.
        Me%TidePotential%Frequency (Q1 ) = 13.3986609 * Pi / 180.

        Me%TidePotential%Frequency (M2 ) = 28.9841042 * Pi / 180.
        Me%TidePotential%Frequency (S2 ) = 30.0000000 * Pi / 180. 
        Me%TidePotential%Frequency (N2 ) = 28.4397295 * Pi / 180.
        Me%TidePotential%Frequency (K2 ) = 30.0821373 * Pi / 180.


        !Species m
        Me%TidePotential%m(Ssa) = 0
        Me%TidePotential%m(Mm ) = 0
        Me%TidePotential%m(Mf ) = 0

        Me%TidePotential%m(K1 ) = 1
        Me%TidePotential%m(O1 ) = 1
        Me%TidePotential%m(P1 ) = 1
        Me%TidePotential%m(Q1 ) = 1

        Me%TidePotential%m(M2 ) = 2
        Me%TidePotential%m(S2 ) = 2
        Me%TidePotential%m(N2 ) = 2
        Me%TidePotential%m(K2 ) = 2


        call SetDate(Me%TidePotential%TimeRef, 1900, 1, 1, 0, 0, 0)


    end subroutine ConstructTidePotential


    !--------------------------------------------------------------------------

    Subroutine ConstructSubModel

        !Arguments-------------------------------------------------------------

        

        !Local-----------------------------------------------------------------
        integer, dimension(:,:,:), pointer :: IC3D
        integer               :: ILB, IUB, JLB, JUB, KLB, KUB
        integer               :: STATUS
        integer               :: i, j, k

        !Begin-----------------------------------------------------------------
       


        IUB = Me%Size%IUB
        ILB = Me%Size%ILB
        JUB = Me%Size%JUB
        JLB = Me%Size%JLB
        KUB = Me%Size%KUB
        KLB = Me%Size%KLB

        nullify(Me%SubModel%Z)

        nullify(Me%SubModel%U_New )
        nullify(Me%SubModel%V_New )
        nullify(Me%SubModel%UV_New)

        nullify(Me%SubModel%U_Old )
        nullify(Me%SubModel%V_Old )
        nullify(Me%SubModel%UV_Old)


        nullify(Me%SubModel%DUZ_New )
        nullify(Me%SubModel%DVZ_New )

        nullify(Me%SubModel%DUZ_Old )
        nullify(Me%SubModel%DVZ_Old )
        nullify(Me%SubModel%DUVZ_Old)

        nullify(Me%SubModel%qX      )
        nullify(Me%SubModel%qY      )
        nullify(Me%SubModel%qXY     )
        nullify(Me%SubModel%qYX     )


        allocate (Me%SubModel%Z         (ILB:IUB, JLB:JUB))
        allocate (Me%SubModel%U_New     (ILB:IUB, JLB:JUB, KLB:KUB))
        allocate (Me%SubModel%DUZ_New   (ILB:IUB, JLB:JUB, KLB:KUB))
        allocate (Me%SubModel%V_New     (ILB:IUB, JLB:JUB, KLB:KUB))
        allocate (Me%SubModel%DVZ_New   (ILB:IUB, JLB:JUB, KLB:KUB))
        allocate (Me%SubModel%qX        (ILB:IUB, JLB:JUB, KLB:KUB))
        allocate (Me%SubModel%qY        (ILB:IUB, JLB:JUB, KLB:KUB))
        allocate (Me%SubModel%DUZ_Old   (ILB:IUB, JLB:JUB, KLB:KUB))
        allocate (Me%SubModel%DVZ_Old   (ILB:IUB, JLB:JUB, KLB:KUB))
        allocate (Me%SubModel%U_Old     (ILB:IUB, JLB:JUB, KLB:KUB))
        allocate (Me%SubModel%V_Old     (ILB:IUB, JLB:JUB, KLB:KUB))

        Me%SubModel%Z  (:,:  )          = FillValueReal
        Me%SubModel%U_New  (:,:,:)      = FillValueReal
        Me%SubModel%DUZ_New  (:,:,:)    = FillValueReal
        Me%SubModel%V_New(:,:,:)        = FillValueReal
        Me%SubModel%DVZ_New  (:,:,:)    = FillValueReal
        Me%SubModel%qX(:,:,:)           = FillValueReal
        Me%SubModel%qY(:,:,:)           = FillValueReal
        Me%SubModel%DUZ_Old(:,:,:)      = FillValueReal
        Me%SubModel%DVZ_Old(:,:,:)      = FillValueReal
        Me%SubModel%U_Old  (:,:,:)      = FillValueReal
        Me%SubModel%V_Old  (:,:,:)      = FillValueReal


cd1:    if (Me%SubModel%DeadZone) then
            
            call GetWaterPoints3D(Me%ObjMap, Me%External_Var%WaterPoints3D, STAT = STATUS)
            if (STATUS .NE. SUCCESS_) stop 'ConstructSubModel - ModuleHydrodynamic - ERR01'

            allocate (Me%SubModel%DeadZonePoint(ILB:IUB, JLB:JUB, KLB:KUB))
            Me%SubModel%DeadZonePoint(:,:,:) = .false.

            call StartBoxDif(BoxDifID         = Me%SubModel%ObjBoxDif,           &
                             TimeID           = Me%ObjTime,                      &
                             HorizontalGridID = Me%ObjHorizontalGrid,            &
                             BoxesFilePath = Me%SubModel%DeadZoneFile,                   &
                             WaterPoints3D = Me%External_Var%WaterPoints3D,              &
                             Size3D        = Me%Size,                                    &
                             WorkSize3D    = Me%WorkSize,                                &
                             STAT          = STATUS)
            if (STATUS /= SUCCESS_) stop 'ConstructSubModel - Hydrodynamic - ERR02'

            call GetBoxes(Me%SubModel%ObjBoxDif, IC3D, STAT = STATUS)
            if (STATUS /= SUCCESS_) stop 'ConstructSubModel - Hydrodynamic - ERR03'

            do j = JLB, JUB
            do i = ILB, IUB
            do k = KLB, KUB
           
cd2 :           if (IC3D(i,j,k)>0) then

                    Me%SubModel%DeadZonePoint(i,j,k) = .true.
                
                end if cd2

            end do
            end do
            end do


            call UngetBoxDif(Me%SubModel%ObjBoxDif, IC3D, STAT = STATUS)
            if (STATUS /= SUCCESS_) stop 'ConstructSubModel - Hydrodynamic - ERR04'


            call KillBoxDif(Me%SubModel%ObjBoxDif, STAT = STATUS)
            if (STATUS /= SUCCESS_) stop 'ConstructSubModel - Hydrodynamic - ERR05'

            call UnGetMap(Me%ObjMap,Me%External_Var%WaterPoints3D, STAT = STATUS)
            if (STATUS /= SUCCESS_) stop 'ConstructSubModel - Hydrodynamic - ERR06'

        endif cd1


        Me%SubModel%Set = .false.

    end subroutine ConstructSubModel


    !-----------------------------------------------------------------
    Subroutine ConstructRelaxation

        !Arguments-------------------------------------------------------------

        

        !Local-----------------------------------------------------------------
        
        integer                          :: ILB, IUB, JLB, JUB, KLB, KUB
        integer                          :: ILBWork, IUBWork, JLBWork, JUBWork, KLBWork, KUBWork
        integer                          :: STATUS
        
        integer                          :: iflag,fromfile


        IUB = Me%Size%IUB
        ILB = Me%Size%ILB
        JUB = Me%Size%JUB
        JLB = Me%Size%JLB
        KUB = Me%Size%KUB
        KLB = Me%Size%KLB


        IUBWork = Me%WorkSize%IUB
        ILBWork = Me%WorkSize%ILB
        JUBWork = Me%WorkSize%JUB
        JLBWork = Me%WorkSize%JLB
        KUBWork = Me%WorkSize%KUB
        KLBWork = Me%WorkSize%KLB

        

        call GetExtractType(FromFile = FromFile)

! ---> Compute 
!

        !<BeginKeyword>
            !Keyword          : BOUNDARYFILE
            !<BeginDescription>       
               ! 
               !The file name of 3D file where the relaxation coefficient are. 
               !               
            !<EndDescription>
            !Type             : Character 
            !Default          : ******.***

            !File keyword     : IN_DAD3D 
            !Multiple Options : Do not 
            !Search Type      : From File
        !<EndKeyword>



!        call GetData(FileName, Me%ObjEnterData, iflag,                      &
!                     Keyword    = 'BOUNDARYFILE',                                        &
!                     Default    = '********.***',                                        &
!                     SearchType = FromFile,                                              &
!                     STAT       = status)

!        if (status /= SUCCESS_)                                                          &
!           call SetError(FATAL_, INTERNAL_, "ConstructDataAssimilation - Hydrodynamic - ERR02") 
                
!        if (iflag == 0) &
!           call SetError(FATAL_, INTERNAL_, "ConstructDataAssimilation - Hydrodynamic - ERR03") 

!        Me%DataAssimilation%BRfilename = FileName

        !<BeginKeyword>
            !Keyword          : BRCORIOLIS
            !<BeginDescription>       
               ! 
               !Checks if the user wants to relax the coriolis force
               !
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.

            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (.false.), 1 (.true.)
            !Search Type      : From File
        !<EndKeyword>

         call GetData(Me%Relaxation%coriolis,                         &
                     Me%ObjEnterData, iflag,                                &
                     Keyword    = 'BRCORIOLIS',                                          &
                     Default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                &
                     STAT       = status)

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR04")


        !<BeginKeyword>
            !Keyword          : BRROX3
            !<BeginDescription>       
               ! 
               !Checks if the user wants to relax the baroclinic force
               !
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.

            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (.false.), 1 (.true.)
            !Search Type      : From File
        !<EndKeyword>
      

         call GetData(Me%Relaxation%rox3,                                               &
                      Me%ObjEnterData, iflag,                                           &
                      Keyword    = 'BRROX3',                                            &
                      Default    = .false.,                                             &
                      SearchType = FromFile,                                            &
                      ClientModule ='ModuleHydrodynamic',                               &
                      STAT       = status)

        if (status /= SUCCESS_)                                                         &
           call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR05")
        
        
        !<BeginKeyword>
            !Keyword          : BRTRANSPORT
            !<BeginDescription>       
               ! 
               !Checks if the user wants to relax the horizontal momentum transport 
               !
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.

            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (.false.), 1 (.true.)
            !Search Type      : From File
        !<EndKeyword>
      


        call GetData(Me%Relaxation%HorizAdv,                                &
                     Me%ObjEnterData, iflag,                                &
                     Keyword    = 'BRHORIZ_ADV',                                         &
                     Default    = .false.,                                               &
                     SearchType = FromFile,                                              &
                     ClientModule ='ModuleHydrodynamic',                                 &
                     STAT       = status)

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR06")
           


! ---> Velocity field relaxation
!
        !<BeginKeyword>
            !Keyword          : BRVELOCITY
            !<BeginDescription>       
               ! 
               !Checks if the user wants to relax the horizontal velocity 
               !
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.

            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (.false.), 1 (.true.)
            !Search Type      : From File
        !<EndKeyword>
      

         call GetData(Me%Relaxation%Velocity,                         &
                      Me%ObjEnterData, iflag,                               &
                      keyword = 'BRVELOCITY',                                            &
                      default = .false.,                                                 &
                      SearchType = FromFile,                                             &
                      ClientModule ='ModuleHydrodynamic',                                &
                      STAT       = status)

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR14")



! ---> Water Level field relaxation
!
        !<BeginKeyword>
            !Keyword          : BRWATERLEVEL
            !<BeginDescription>       
               ! 
               !Checks if the user wants to relax the water level 
               !
            !<EndDescription>
            !Type             : Logical 
            !Default          : .false.

            !File keyword     : IN_DAD3D 
            !Multiple Options : 0 (.false.), 1 (.true.)
            !Search Type      : From File
        !<EndKeyword>
      

         call GetData(Me%Relaxation%WaterLevel,                             &
                      Me%ObjEnterData, iflag,                               &
                      keyword = 'BRWATERLEVEL',                                          &
                      default = .false.,                                                 &
                      SearchType = FromFile,                                             &
                      ClientModule ='ModuleHydrodynamic',                                &
                      STAT       = status)

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR15")



         call GetData(Me%Relaxation%RefBoundWaterLevel,                     &
                      Me%ObjEnterData, iflag,                               &
                      keyword = 'REF_BOUND_WATERLEVEL',                                  &
                      default = .false.,                                                 &
                      SearchType = FromFile,                                             &
                      ClientModule ='ModuleHydrodynamic',                                &
                      STAT       = status)

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR16")

        call GetData(Me%Relaxation%ReferenceVelocity,                       &
                      Me%ObjEnterData, iflag,                               &
                      keyword = 'RELAX_REF_VEL',                                         &
                      default = TotalVel_,                                               &
                      SearchType = FromFile,                                             &
                      ClientModule ='ModuleHydrodynamic',                                &
                      STAT       = status)

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR16a")

        if (Me%Relaxation%ReferenceVelocity /= TotalVel_          .and.     &
            Me%Relaxation%ReferenceVelocity /= BarotrVel_         .and.     &
            Me%Relaxation%ReferenceVelocity /= BaroclVel_)                  &
            call SetError(FATAL_, KEYWORD_, 'ConstructRelaxation - Hydrodynamic - ERR31.')            



         call GetData(Me%Relaxation%Force,                                  &
                      Me%ObjEnterData, iflag,                               &
                      keyword = 'BRFORCE',                                               &
                      default = .false.,                                                 &
                      SearchType = FromFile,                                             &
                      ClientModule ='ModuleHydrodynamic',                                &
                      STAT       = status)

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR17")

        if (Me%Relaxation%Force .and. Me%Relaxation%Velocity) then

            call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR18")

        endif


        if (Me%Relaxation%Force) then

            !Forces 
            allocate (Me%Forces%Relax_Aceleration(ILB:IUB, JLB:JUB, KLB:KUB), STAT = status)

            if (status /= SUCCESS_)                                                          &
               call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR19")
 
                Me%Forces%Relax_Aceleration(:,:,:) = FillValueReal


        endif 


         call GetData(Me%Relaxation%Geometry,                                           &
                      Me%ObjEnterData, iflag,                                           &
                      keyword = 'BRGEOMETRY',                                           &
                      default = .false.,                                                &
                      SearchType = FromFile,                                            &
                      ClientModule ='ModuleHydrodynamic',                               &
                      STAT       = status)

        if (status /= SUCCESS_)                                                          &
           call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR200")

        if (Me%Relaxation%Geometry) then

            !Forces 
            allocate (Me%Relaxation%DecayTimeGeo(ILB:IUB, JLB:JUB, KLB:KUB), STAT = status)

            if (status /= SUCCESS_)                                                          &
               call SetError(FATAL_, INTERNAL_, "ConstructRelaxation - Hydrodynamic - ERR210")
 
            Me%Relaxation%DecayTimeGeo(:,:,:) = FillValueReal


        endif 



    end subroutine ConstructRelaxation

    !----------------------------------------------------------------------------



    !----------------------------------------------------------------------------

    subroutine CourantGH

        !Arguments---------------------------------------------------------------

        

        !External----------------------------------------------------------------

        integer :: STAT_CALL
        integer :: I_Courant, J_Courant

        real    :: DT
        real    :: Velocity

        !Local-------------------------------------------------------------------

        integer :: I, J
        integer :: IUB, ILB
        integer :: JUB, JLB

        real    :: Courant, Courant_temp
        real    :: DX

        real,    dimension(:,:), pointer :: WaterColumn

        !------------------------------------------------------------------------

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB


        call ReadLock_External_Modules

        call GetComputeTimeStep(Me%ObjTime, DT = DT, STAT = STAT_CALL)                                       
        if (STAT_CALL /= SUCCESS_) stop 'CourantGH - ModuleHydrodynamic - ERR01'                               
                                                                                        
                                                                                        
        WaterColumn => Me%External_Var%WaterColumn



        Courant = FillValueReal

        I_Courant = FillValueInt
        J_Courant = FillValueInt

do2 :   do J = JLB, JUB
do3 :   do I = ILB, IUB
cd1 :   if (Me%External_Var%WaterPoints2D(I,J) .EQ. 1) then
            if (WaterColumn(I,J) < 0.) WaterColumn(I,J) = 0.

            Velocity     = SQRT(WaterColumn(I,J) * Gravity)
            DX           = MIN(Me%External_Var%DXX(I,J), Me%External_Var%DYY(I,J))

            Courant_temp = F_Courant(Velocity = Velocity,                       &
                                     DT       = 2. * DT,                        &
                                     DX       = DX)

cd2 :       if (Courant .LT. Courant_temp) then
                I_Courant = I
                J_Courant = J

                Courant = Courant_temp
            end if cd2
        end if cd1
        end do do3
        end do do2



        call OutputCourant(Courant, I_Courant, J_Courant)


        call ReadUnLock_External_Modules


        nullify(WaterColumn)

        !------------------------------------------------------------------------

    end subroutine CourantGH

    !----------------------------------------------------------------------------



    !----------------------------------------------------------------------------

    function F_Courant(Velocity, DT, DX)
    real ::  F_Courant

        !Arguments---------------------------------------------------------------
        
        real, intent(IN) :: Velocity, DT, DX

        !------------------------------------------------------------------------

        F_Courant = Velocity * DT / DX

        !------------------------------------------------------------------------

    end function F_Courant

    !----------------------------------------------------------------------------

    subroutine OutputCourant(Courant, I, J)

        !Arguments---------------------------------------------------------------
        
        integer, intent(IN) :: I, J
        real,    intent(IN) :: Courant

        !------------------------------------------------------------------------

        write(*, *)"---------------------- HYDRODYNAMICS ---------------------"
        write(*, *)
        write(*, *)"Courant Number is : ", Courant
        write(*, *)"In Grid Cell[i,j] : ", i, j
        write(*, *)

        !------------------------------------------------------------------------

    end subroutine OutputCourant



    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    !SELECTOR SELECTOR SELECTOR SELECTOR SELECTOR SELECTOR SELECTOR SELECTOR SELE

    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    !--------------------------------------------------------------------------

    subroutine GetDirection(HydrodynamicID, ImplicitDirection,                           &
                            DirectionX, DirectionY, STAT)

        !Arguments-------------------------------------------------------------
        integer,           intent(IN ) :: HydrodynamicID
        integer, optional, intent(OUT) :: ImplicitDirection
        integer, optional, intent(OUT) :: DirectionX, DirectionY
        integer, optional, intent(OUT) :: STAT

        

        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                            &
            (ready_ .EQ. READ_LOCK_ERR_)) then
            call Read_Lock(mHydrodynamic_, Me%InstanceID)

        
            if (present(DirectionX)) DirectionX = DirectionX_
            if (present(DirectionY)) DirectionY = DirectionY_

            if (present(ImplicitDirection))                                              &
                ImplicitDirection = Me%Direction%XY

            call Read_UnLock(mHydrodynamic_, Me%InstanceID, "GetDirection")

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))                                                               &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetDirection


    !--------------------------------------------------------------------------

    subroutine GetHydrodynamicSource(HydrodynamicID,                            &
                                     HydrodynamicSource,                        &
                                     Solve_Equations,                           &
                                     Read_File,                                 &
                                     No_hydrodynamic,                           &
                                     Residual_hydrodynamic,                     &
                                     Run_Off,                                   &
                                     ImposedSolution,                           &
                                     Vertical1D,                                &
                                     STAT)

        !Arguments-------------------------------------------------------------
        integer,           intent(IN ) :: HydrodynamicID
        integer,           intent(OUT) :: HydrodynamicSource
        integer, optional, intent(OUT) :: Solve_Equations, Read_File, No_hydrodynamic,  &
                                          Residual_hydrodynamic, Run_Off,               &
                                          ImposedSolution, Vertical1D
        integer, optional, intent(OUT) :: STAT

        

        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                            &
            (ready_ .EQ. READ_LOCK_ERR_)) then
            call Read_Lock(mHydrodynamic_, Me%InstanceID)

        
            if (present(Solve_Equations       )) Solve_Equations       = Solve_Equations_
            if (present(Read_File             )) Read_File             = Read_File_
            if (present(No_hydrodynamic       )) No_hydrodynamic       = No_hydrodynamic_
            if (present(Residual_hydrodynamic )) Residual_hydrodynamic = Residual_hydrodynamic_
            if (present(ImposedSolution       )) ImposedSolution       = ImposedSolution_
            if (present(Vertical1D            )) Vertical1D            = Vertical1D_
            if (present(Run_Off               )) Run_Off               = Run_Off_
            

            HydrodynamicSource = Me%ComputeOptions%Evolution

            call Read_UnLock(mHydrodynamic_, Me%InstanceID, "GetHydrodynamicSource")

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))                                                               &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetHydrodynamicSource
    !--------------------------------------------------------------------------

    !--------------------------------------------------------------------------

    subroutine GetWaterFluxes(HydrodynamicID, WaterFluxX, WaterFluxY, WaterFluxZ,        &
                              STAT)

        !Arguments-------------------------------------------------------------
        integer,                         intent(IN ) :: HydrodynamicID   
        real(8), dimension(:,:,:), pointer, optional :: WaterFluxX 
        real(8), dimension(:,:,:), pointer, optional :: WaterFluxY
        real(8), dimension(:,:,:), pointer, optional :: WaterFluxZ

        integer, optional, intent(OUT) :: STAT

        

        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                            &
            (ready_ .EQ. READ_LOCK_ERR_)) then


cd2 :       if (present(WaterFluxX)) then
                call Read_Lock(mHydrodynamic_, Me%InstanceID)
                WaterFluxX => Me%WaterFluxes%X
            end if cd2


cd3 :       if (present(WaterFluxY)) then
                call Read_Lock(mHydrodynamic_, Me%InstanceID)
                WaterFluxY => Me%WaterFluxes%Y
            end if cd3


cd4 :       if (present(WaterFluxZ)) then
                call Read_Lock(mHydrodynamic_, Me%InstanceID)
                WaterFluxZ => Me%WaterFluxes%Z
            end if cd4


            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))                                                    &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetWaterFluxes

    !--------------------------------------------------------------------------

    !--------------------------------------------------------------------------

    subroutine GetDischargesFluxes(HydrodynamicID, Discharges, STAT)

        !Arguments-------------------------------------------------------------
        integer,                         intent(IN ) :: HydrodynamicID   
        real(8), dimension(:,:,:), pointer, optional :: Discharges 

        integer, optional, intent(OUT)               :: STAT

        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                            &
            (ready_ .EQ. READ_LOCK_ERR_)) then

            call Read_Lock(mHydrodynamic_, Me%InstanceID)

            Discharges => Me%WaterFluxes%Discharges

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))                                                    &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetDischargesFluxes

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------

    subroutine GetWavesStressON(HydrodynamicID, WavesStressON, STAT)

        !Arguments-------------------------------------------------------------
   
        integer,           intent(IN ) :: HydrodynamicID
        logical                        :: WavesStressON
        integer, optional, intent(OUT) :: STAT

        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                            &
            (ready_ .EQ. READ_LOCK_ERR_)) then

            WavesStressON = Me%ComputeOptions%WaveStress
            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))                                                               &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetWavesStressON

    !--------------------------------------------------------------------------

    !--------------------------------------------------------------------------

    subroutine GetPointDischargesState(HydrodynamicID, DischargesON, STAT)

        !Arguments-------------------------------------------------------------
   
        integer,           intent(IN ) :: HydrodynamicID
        logical                        :: DischargesON
        integer, optional, intent(OUT) :: STAT

        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                            &
            (ready_ .EQ. READ_LOCK_ERR_)) then

            DischargesON = Me%ComputeOptions%WaterDischarges

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))                                                               &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetPointDischargesState

    !--------------------------------------------------------------------------




    !--------------------------------------------------------------------------

    subroutine GetHorizontalVelocity(HydrodynamicID, Velocity_U, Velocity_V, STAT)

        !Arguments-------------------------------------------------------------
        integer,              intent(IN ) :: HydrodynamicID   
        real, dimension(:,:,:), pointer   :: Velocity_U, Velocity_V

        integer, optional,    intent(OUT) :: STAT


        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                 &
            (ready_ .EQ. READ_LOCK_ERR_)) then
            
            call Read_Lock(mHydrodynamic_, Me%InstanceID)

            Velocity_U => Me%Velocity%Horizontal%U%New

            call Read_Lock(mHydrodynamic_, Me%InstanceID)

            Velocity_V => Me%Velocity%Horizontal%V%New

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))                                                    &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetHorizontalVelocity

    !--------------------------------------------------------------------------

    !--------------------------------------------------------------------------

    subroutine GetOldHorizontalVelocity(HydrodynamicID, OldVelocity_U, OldVelocity_V, STAT)

        !Arguments-------------------------------------------------------------
        integer,           intent(IN )   :: HydrodynamicID   
        real, dimension(:,:,:), pointer  :: OldVelocity_U, OldVelocity_V
        integer, optional, intent(OUT)   :: STAT


        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                 &
            (ready_ .EQ. READ_LOCK_ERR_)) then
            
            call Read_Lock(mHydrodynamic_, Me%InstanceID)

            OldVelocity_U => Me%Velocity%Horizontal%U%Old

            call Read_Lock(mHydrodynamic_, Me%InstanceID)

            OldVelocity_V => Me%Velocity%Horizontal%V%Old

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))                                                    &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetOldHorizontalVelocity

    !--------------------------------------------------------------------------

    !--------------------------------------------------------------------------

    subroutine GetVerticalVelocity(HydrodynamicID, Velocity_W, Velocity_Across, STAT)

        !Arguments-------------------------------------------------------------
        integer,           intent(IN )              :: HydrodynamicID   
        real, dimension(:,:,:), optional, pointer   :: Velocity_W
        real, dimension(:,:,:), optional, pointer   :: Velocity_Across

        integer, optional, intent(OUT) :: STAT


        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                 &
            (ready_ .EQ. READ_LOCK_ERR_)) then

            if (present(Velocity_W     )) then
                call Read_Lock(mHydrodynamic_, Me%InstanceID)
                Velocity_W      => Me%Velocity%Vertical%Cartesian
            endif

            if (present(Velocity_Across)) then
                call Read_Lock(mHydrodynamic_, Me%InstanceID)
                Velocity_Across => Me%Velocity%Vertical%Across
            endif

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))  STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetVerticalVelocity

    !--------------------------------------------------------------------------

    subroutine GetWaterLevel(HydrodynamicID, WaterLevel, STAT)

        !Arguments-------------------------------------------------------------
        integer,           intent(IN ) :: HydrodynamicID   
        real, dimension(:,:), pointer  :: WaterLevel
        integer, optional, intent(OUT) :: STAT


        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                 &
            (ready_ .EQ. READ_LOCK_ERR_)) then

            call Read_Lock(mHydrodynamic_, Me%InstanceID)
            WaterLevel => Me%WaterLevel%New

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))                                                    &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetWaterLevel

    !--------------------------------------------------------------------------
    
    subroutine GetHydrodynamicAirOptions (HydrodynamicID,      &
                                          SurfaceWaterFluxYes, &
                                          WindYes,             &
                                          AtmPressureYes,      &
                                          STAT)
        !Arguments-------------------------------------------------------------
        integer,           intent(IN ) :: HydrodynamicID   
        logical                        :: SurfaceWaterFluxYes, WindYes, AtmPressureYes 
        integer, optional, intent(OUT) :: STAT
        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                 &
            (ready_ .EQ. READ_LOCK_ERR_)) then

            SurfaceWaterFluxYes  = Me%ComputeOptions%SurfaceWaterFlux
            AtmPressureYes       = Me%ComputeOptions%AtmPressure
            if (Me%ComputeOptions%Wind == NoWind_) then
                WindYes = .false.
            else
                WindYes = .true.
            endif
            
            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT)) STAT = STAT_
            

        !----------------------------------------------------------------------
    end subroutine GetHydrodynamicAirOptions

    !--------------------------------------------------------------------------

    subroutine GetChezy(HydrodynamicID, Chezy, STAT)

        !Arguments-------------------------------------------------------------
        integer,           intent(IN ) :: HydrodynamicID   
        real, dimension(:,:), pointer  :: Chezy
        integer, optional, intent(OUT) :: STAT


        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                 &
            (ready_ .EQ. READ_LOCK_ERR_)) then

            call Read_Lock(mHydrodynamic_, Me%InstanceID)
            Chezy => Me%External_Var%ChezyZ

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))                                                    &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetChezy

    !--------------------------------------------------------------------------
    !--------------------------------------------------------------------------

    subroutine GetHydroNeedsFather (HydrodynamicID, cdsubModel, STAT)
         !Arguments-------------------------------------------------------------
        integer,           intent(IN ) :: HydrodynamicID
        logical,           intent(OUT) :: cdsubModel
        integer, optional, intent(OUT) :: STAT


        !External--------------------------------------------------------------

        integer :: ready_        

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
cd1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                 &
            (ready_ .EQ. READ_LOCK_ERR_)) then

            cdsubModel = Me%SubModel%ON 

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1


        if (present(STAT))                                                    &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine GetHydroNeedsFather

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------
    ! guillaume nogueira

    subroutine GetHydroAltimAssim (AssimilationID, AltimetricAssimilation, STAT)

        !Arguments------------------------------------------------------------ 
        integer                                     :: AssimilationID
        logical,        intent(OUT)                 :: AltimetricAssimilation
        integer,       intent(OUT),   optional      :: STAT

        !Local-----------------------------------------------------------------
        integer                                     :: STAT_, ready_

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(AssimilationID, ready_) 
        
if1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                            &
            (ready_ .EQ. READ_LOCK_ERR_)) then
    
            AltimetricAssimilation = Me%ComputeOptions%AltimetryAssimilation%Yes
                           
            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if if1

        if (present(STAT)) STAT = STAT_

    end subroutine GetHydroAltimAssim

    !--------------------------------------------------------------------------


    subroutine GetVertical1D (HydrodynamicID, Vertical1D, STAT)
         !Arguments-------------------------------------------------------------
        integer,           intent(IN ) :: HydrodynamicID
        logical,           intent(OUT) :: Vertical1D
        integer, optional, intent(OUT) :: STAT


        !Local-----------------------------------------------------------------
        integer                                     :: STAT_, ready_

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
if1 :   if ((ready_ .EQ. IDLE_ERR_     ) .OR.                                            &
            (ready_ .EQ. READ_LOCK_ERR_)) then
    
            if (Me%ComputeOptions%Evolution == Vertical1D_) then
            
                Vertical1D = .true.

            else
                Vertical1D = .false.
            endif
                           
            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if if1

        if (present(STAT)) STAT = STAT_

    end subroutine GetVertical1D

    !--------------------------------------------------------------------------

    !--------------------------------------------------------------------------

    subroutine UngetHydrodynamic3Dreal4(HydrodynamicID, Array, STAT)

        !Arguments-------------------------------------------------------------

        integer,               intent(IN ) :: HydrodynamicID
        real(4), pointer, dimension(:,:,:) :: Array
        integer, optional,     intent(OUT) :: STAT
   
        

        !External--------------------------------------------------------------

        integer :: ready_   

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 

cd1 :   if (ready_ .EQ. READ_LOCK_ERR_) then
            nullify(Array)

            call Read_UnLock(mHydrodynamic_, Me%InstanceID, "UngetHydrodynamic3Dreal4")

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1

        if (present(STAT)) STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine UngetHydrodynamic3Dreal4

    !--------------------------------------------------------------------------



    !--------------------------------------------------------------------------

    subroutine UngetHydrodynamic2Dreal4(HydrodynamicID, Array, STAT)

        !Arguments-------------------------------------------------------------
        integer,           intent(IN )   :: HydrodynamicID
        real(4), pointer, dimension(:,:) :: Array
        integer, optional, intent(OUT)   :: STAT
   
        

        !External--------------------------------------------------------------

        integer :: ready_   

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 

cd1 :   if (ready_ .EQ. READ_LOCK_ERR_) then
            nullify(Array)

            call Read_UnLock(mHydrodynamic_, Me%InstanceID, "UngetHydrodynamic2Dreal4")

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1

        if (present(STAT)) STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine UngetHydrodynamic2Dreal4

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------

    subroutine UngetHydrodynamic2Dreal8(HydrodynamicID, Array, STAT)

        !Arguments-------------------------------------------------------------
        integer,           intent(IN )   :: HydrodynamicID
        real(8), pointer, dimension(:,:) :: Array
        integer, optional, intent(OUT)   :: STAT
   
        

        !External--------------------------------------------------------------

        integer :: ready_   

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 

cd1 :   if (ready_ .EQ. READ_LOCK_ERR_) then
            nullify(Array)

            call Read_UnLock(mHydrodynamic_, Me%InstanceID, "UngetHydrodynamic2Dreal8")

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1

        if (present(STAT)) STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine UngetHydrodynamic2Dreal8

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------

    subroutine UngetHydrodynamic3Dreal8(HydrodynamicID, Array, STAT)

        !Arguments-------------------------------------------------------------

        integer,               intent(IN ) :: HydrodynamicID
        real(8), pointer, dimension(:,:,:) :: Array
        integer, optional,    intent (OUT) :: STAT
   
        

        !External--------------------------------------------------------------

        integer :: ready_   

        !Local-----------------------------------------------------------------

        integer :: STAT_              !Auxiliar local variable

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 

cd1 :   if (ready_ .EQ. READ_LOCK_ERR_) then
            nullify(Array)

            call Read_UnLock(mHydrodynamic_, Me%InstanceID, "UngetHydrodynamic3Dreal8")

            STAT_ = SUCCESS_
        else 
            STAT_ = ready_
        end if cd1

        if (present(STAT)) STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine UngetHydrodynamic3Dreal8

    !--------------------------------------------------------------------------

    subroutine SetHydrodynamicManning (HydrodynamicID, Manning, STAT)

        !Arguments-------------------------------------------------------------
        integer                         :: HydrodynamicID
        logical, intent(IN)             :: Manning
        integer, optional, intent(OUT)  :: STAT

        !Local-----------------------------------------------------------------
        integer                         :: ready_              
        integer                         :: STAT_            

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_)  
        
cd1 :   if (ready_ == IDLE_ERR_)then

            Me%External_Var%Manning = Manning            
   
            STAT_ = SUCCESS_

        else cd1

            STAT_ = ready_

        end if cd1

        if (present(STAT)) STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine SetHydrodynamicManning

    !--------------------------------------------------------------------------

    subroutine SetHydrodynamicChezy (HydrodynamicID, Chezy, ChezyCoef, STAT)

        !Arguments-------------------------------------------------------------
        integer                         :: HydrodynamicID
        logical, intent(IN)             :: Chezy
        real,    intent(IN)             :: ChezyCoef
        integer, optional, intent(OUT)  :: STAT

        !Local-----------------------------------------------------------------
        integer                         :: ready_              
        integer                         :: STAT_            

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_)  
        
cd1 :   if (ready_ == IDLE_ERR_)then

            Me%External_Var%Chezy     = Chezy            
            Me%External_Var%ChezyCoef = ChezyCoef            
   
            STAT_ = SUCCESS_

        else cd1

            STAT_ = ready_

        end if cd1

        if (present(STAT)) STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine SetHydrodynamicChezy
    
    !--------------------------------------------------------------------------

    subroutine SetHydrodynamicRugosityMatrix (HydrodynamicID, RugosityMatrix, STAT)

        !Arguments-------------------------------------------------------------
        integer                         :: HydrodynamicID
        real, dimension(:, :), pointer  :: RugosityMatrix
        integer, optional, intent(OUT)  :: STAT

        !Local-----------------------------------------------------------------
        integer                         :: ready_              
        integer                         :: STAT_            

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_)  
        
cd1 :   if (ready_ == IDLE_ERR_)then

            Me%External_Var%RugosityMatrix => RugosityMatrix            
   
            STAT_ = SUCCESS_

        else cd1

            STAT_ = ready_

        end if cd1

        if (present(STAT)) STAT = STAT_

    end subroutine SetHydrodynamicRugosityMatrix

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------
    subroutine SetSurfaceWaterFlux(HydrodynamicID, SurfaceWaterFlux, STAT)

        !Arguments---------------------------------------------------------------
        integer                                     :: HydrodynamicID
        real, pointer, dimension(:,:)               :: SurfaceWaterFlux
        integer,            optional, intent(OUT)   :: STAT

        !Local-------------------------------------------------------------------
        integer                                     :: ready_          
        integer                                     :: STAT_    

        !------------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
        if (ready_ .EQ. IDLE_ERR_)then

            Me%External_Var%SurfaceWaterFlux       => SurfaceWaterFlux

            STAT_ = SUCCESS_  

        else
            STAT_ = ready_
        end if


        if (present(STAT))STAT = STAT_
            
    end subroutine SetSurfaceWaterFlux
    
    
    !--------------------------------------------------------------------------

    
    subroutine SetBottomWaterFlux(HydrodynamicID, BottomWaterFlux, STAT)

        !Arguments---------------------------------------------------------------
        integer                                     :: HydrodynamicID
        real(8), pointer, dimension(:,:)            :: BottomWaterFlux
        integer,            optional, intent(OUT)   :: STAT

        !Local-------------------------------------------------------------------
        integer                                     :: ready_          
        integer                                     :: STAT_    

        !------------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
        if (ready_ .EQ. IDLE_ERR_)then

            Me%External_Var%BottomWaterFlux       => BottomWaterFlux

            STAT_ = SUCCESS_  

        else
            STAT_ = ready_
        end if


        if (present(STAT))STAT = STAT_
            
    end subroutine SetBottomWaterFlux

    !--------------------------------------------------------------------------
   
    subroutine SetWindStress(HydrodynamicID, WindStress_X, WindStress_Y, STAT)

        !Arguments---------------------------------------------------------------
        integer                                     :: HydrodynamicID
        real, pointer, dimension(:,:)               :: WindStress_X
        real, pointer, dimension(:,:)               :: WindStress_Y
        integer,            optional, intent(OUT)   :: STAT

        !Local-------------------------------------------------------------------
        integer                                     :: ready_          
        integer                                     :: STAT_    

        !------------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
        if (ready_ .EQ. IDLE_ERR_)then

            Me%External_Var%TauWindU       => WindStress_X
            Me%External_Var%TauWindV       => WindStress_Y

            STAT_ = SUCCESS_  

        else
            STAT_ = ready_
        end if


        if (present(STAT))STAT = STAT_
            
    end subroutine SetWindStress
    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------
    subroutine SetAtmosphericPressure(HydrodynamicID, AtmosphericPressure, STAT)

        !Arguments---------------------------------------------------------------
        integer                                     :: HydrodynamicID
        real, pointer, dimension(:,:)               :: AtmosphericPressure
        integer,            optional, intent(OUT)   :: STAT

        !Local-------------------------------------------------------------------
        integer                                     :: ready_          
        integer                                     :: STAT_    

        !------------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
        if (ready_ .EQ. IDLE_ERR_)then

            Me%External_Var%AtmosphericPressure       => AtmosphericPressure

            STAT_ = SUCCESS_  

        else
            STAT_ = ready_
        end if


        if (present(STAT))STAT = STAT_
            
    end subroutine SetAtmosphericPressure

    !--------------------------------------------------------------------------
    subroutine SetWaveChezyVel(HydrodynamicID, WaveChezyVel, STAT)

        !Arguments---------------------------------------------------------------
        integer                                     :: HydrodynamicID
        real, pointer, dimension(:,:)               :: WaveChezyVel
        integer,            optional, intent(OUT)   :: STAT

        !Local-------------------------------------------------------------------
        integer                                     :: ready_          
        integer                                     :: STAT_    

        !------------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_) 
        
        if (ready_ .EQ. IDLE_ERR_)then

            Me%External_Var%WaveChezyVel  => WaveChezyVel

            STAT_ = SUCCESS_  

        else
            STAT_ = ready_
        end if


        if (present(STAT))STAT = STAT_
            
    end subroutine SetWaveChezyVel

    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    !MODIFIER MODIFIER MODIFIER MODIFIER MODIFIER MODIFIER MODIFIER MODIFIER MO 

    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!BOP
!
! !ROUTINE: Modify_Hydrodynamic

! !DESCRIPTION: 
!     This routine is responsible for the evolution of flow properties: 
!     velocities, water fluxes and water level.
!     
 
! !REVISION HISTORY: 
!  1Jan2000    Paulo Chambel  First experimental version.
!  22Nov2000   Paulo Chambel  Comments are introduce in the Protex format 
!                             to produce a manual

!   !INTERFACE:

    subroutine Modify_Hydrodynamic(HydrodynamicID,                             &
                                   Density,                                    &
                                   SigmaDens,                                  &
                                   NewDT,                                      &
                                   STAT)
        

!   !INPUT PARAMETERS:        
        integer, intent (IN )           :: HydrodynamicID
        real, dimension(:,:,:), pointer :: Density
        real, dimension(:,:,:), pointer :: SigmaDens
        real,    intent (OUT)           :: NewDT

!   !OUTPUT PARAMETERS:        

        integer, optional, intent (OUT) :: STAT

!EOP

        !External--------------------------------------------------------------

        integer :: ready_ 

        !Local-----------------------------------------------------------------

        integer :: STAT_, STAT_CALL           !Auxiliar local variable
        logical :: VariableDT
        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_)

cd1 :   if (ready_ .EQ. IDLE_ERR_) then

            if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Modify_Hydrodynamic")


            !This hydrodynamic model do not has variable time step
            !NewDT    = FillValueReal


            !Time Properties - Actualises CurrentTime
            call GetComputeCurrentTime(Me%ObjTime, Me%CurrentTime, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) &
                stop 'Subroutine Modify_Hydrodynamic; module ModuleHydrodynamic. ERR01.'

            !Read density values
            Me%External_Var%SigmaDens   => SigmaDens
            Me%External_Var%Density     => Density

            call Actualises_Hydrodynamic 


            !Read Lock variables external variables
            !The modules responsible for this variables were 
            !built outside the hydrodynamic module. This modules are
            !call External Modules
            call ReadLock_External_Modules

            
            call ReadLock_ModuleTurbulence 
#ifndef _WAVES_
            if (Me%ComputeOptions%WaveStress) call ReadLock_ModuleWaves
#endif
            call One_Iteration 


            !Compute Water Fluxes
            call ComputeBoxesWaterFluxes

            !Compute Residual Flow Properties
            if (Me%ComputeOptions%Residual)                                 &
                call ComputeResidualFlowProperties

            !Calculates the energy of the system - Frank Out 99
            if (Me%ComputeOptions%Energy)                                   &
                call ComputeSystemEnergy

            call Hydrodynamic_OutPut 

            !Records results to binary file
            if (Me%ComputeOptions%Recording) then

                call ModifyHydrodynamicFile(Me%ObjHydrodynamicFileOut,                           &
                                            WaterLevel       = Me%WaterLevel%New,                &
                                            WaterFluxX       = Me%WaterFluxes%X,                 &
                                            WaterFluxY       = Me%WaterFluxes%Y,                 &
                                            Discharges       = Me%WaterFluxes%Discharges,        &
                                            ComputeFacesU3D  = Me%External_Var%ComputeFaces3D_U, &
                                            ComputeFacesV3D  = Me%External_Var%ComputeFaces3D_V, &
                                            HydrodynamicTime = Me%CurrentTime,                   &
                                            STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) &
                    stop 'Subroutine Modify_Hydrodynamic; module ModuleHydrodynamic. ERR02.'
            
            endif


            call GetVariableDT (Me%ObjTime, VariableDT, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Modify_Hydrodynamic - ModuleHydrodynamic - ERR02a'

            if (VariableDT) then
                call CalcNewDT (NewDT)
            endif
            


            !Output of the Turbulence variaveis
            call ReadUnLock_ModuleTurbulence  
#ifndef _WAVES_
            if (Me%ComputeOptions%WaveStress) call ReadUnLock_ModuleWaves
#endif
            !Read UnLock variables external variables
            !The modules responsible for this variables were 
            !built outside the hydrodynamic module. This modules are
            !call External Modules
            call ReadUnLock_External_Modules


            Me%LastIteration = Me%CurrentTime
            
            call null_time    (Me%CurrentTime)

            if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Modify_Hydrodynamic")
           
            STAT_ = SUCCESS_
        else              
         
            STAT_ = ready_

        end if cd1


        if (present(STAT))                                                               &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine Modify_Hydrodynamic

    !--------------------------------------------------------------------------

    subroutine CalcNewDT (NewDT)

        !Arguments-------------------------------------------------------------
        real                                        :: NewDT

        !Local-----------------------------------------------------------------
        integer                                     :: i, j, k
        real(8)                                     :: TotalFlux  
        real                                        :: AuxDT, CourantDT, VelDT, VolVarDT
        real(8)                                     :: MaxVariation

        !Test Frank.
        !Calculates new DT which guarantees a transport Courant < 1 for horizontal fluxes
        !Just consider Fluxes which leave cell
        CourantDT = -FillValueReal
        do k = Me%WorkSize%KLB, Me%WorkSize%KUB
        do j = Me%WorkSize%JLB, Me%WorkSize%JUB
        do i = Me%WorkSize%ILB, Me%WorkSize%IUB

            if (Me%External_Var%WaterPoints3D(i, j, k) == WaterPoint) then

                !Verifies the horizontal condition
                TotalFlux   = 0.0

                if (Me%External_Var%ComputeFaces3D_U(i, j, k) == Compute .and. &
                    Me%WaterFluxes%X(i, j, k) < 0.0) then
                    TotalFlux = TotalFlux - Me%WaterFluxes%X(i, j, k)
                endif
                if (Me%External_Var%ComputeFaces3D_U(i, j+1, k) == Compute .and. &
                    Me%WaterFluxes%X(i, j+1, k) > 0.0) then
                    TotalFlux = TotalFlux + Me%WaterFluxes%X(i, j+1, k)
                endif
                if (Me%External_Var%ComputeFaces3D_V(i, j, k) == Compute .and. &
                    Me%WaterFluxes%Y(i, j, k) < 0.0) then
                    TotalFlux = TotalFlux - Me%WaterFluxes%Y(i, j, k)
                endif
                if (Me%External_Var%ComputeFaces3D_V(i+1, j, k) == Compute .and. &
                    Me%WaterFluxes%Y(i+1, j, k) > 0.0) then
                    TotalFlux = TotalFlux + Me%WaterFluxes%Y(i+1, j, k)
                endif

                if (Me%External_Var%ComputeFaces3D_W(i, j, k) == Compute .and. &
                    Me%WaterFluxes%Z(i, j, k) < 0.0) then
                endif

                if (Me%External_Var%ComputeFaces3D_W(i, j, k+1) == Compute .and. &
                    Me%WaterFluxes%Z(i, j, k+1) > 0.0) then
                    TotalFlux = TotalFlux + Me%WaterFluxes%Z(i, j, k+1)
                endif

                if (TotalFlux > 0.1) then   !To avoid division by zero
                    AuxDT = Me%External_Var%Volume_Z_New(i, j, k) / TotalFlux
                    if (AuxDT < CourantDT) CourantDT = AuxDT
                endif

            endif
        enddo
        enddo
        enddo

        !Divide predicted Courant DT by the security factor
        !If 5 is a good option must be shown in the future
        CourantDT = CourantDT / 10.0

        !If in any place velocity variation is greater then 5% reduce DT
        VelDT   = -FillValueReal
        do k = Me%WorkSize%KLB, Me%WorkSize%KUB
        do j = Me%WorkSize%JLB, Me%WorkSize%JUB
        do i = Me%WorkSize%ILB, Me%WorkSize%IUB
            
            if (Me%External_Var%WaterPoints3D(i, j, k) == WaterPoint) then

                if (Me%External_Var%ComputeFaces3D_U(i, j, k) == Compute .and. &
                    Me%Velocity%Horizontal%U%New    (i, j, k) < 0.0) then
                    VelDT = min (VelDT, Me%External_Var%DUX(i, j) / (-Me%Velocity%Horizontal%U%New(i, j, k)))
                endif
                    
                if (Me%External_Var%ComputeFaces3D_U(i, j+1, k) == Compute .and. &
                    Me%Velocity%Horizontal%U%New    (i, j+1, k) > 0.0) then
                    VelDT = min (VelDT, Me%External_Var%DUX(i, j) / Me%Velocity%Horizontal%U%New(i, j+1, k))
                endif

                if (Me%External_Var%ComputeFaces3D_V(i, j, k) == Compute .and. &
                    Me%Velocity%Horizontal%V%New    (i, j, k) < 0.0) then
                    VelDT = min (VelDT, Me%External_Var%DVY(i, j) / (-Me%Velocity%Horizontal%V%New(i, j, k)))
                endif

                if (Me%External_Var%ComputeFaces3D_V(i+1, j, k) == Compute .and. &
                    Me%Velocity%Horizontal%V%New    (i+1, j, k) > 0.0) then
                    VelDT = min (VelDT, Me%External_Var%DVY(i, j) / Me%Velocity%Horizontal%V%New(i+1, j, k))
                endif

            endif

        enddo
        enddo
        enddo

        !Divide predicted Courant DT by the security factor
        !If 10 is a good option must be shown in the future
        VelDT = VelDT / 10.0


        MaxVariation = null_real
        do k = Me%WorkSize%KLB, Me%WorkSize%KUB
        do j = Me%WorkSize%JLB, Me%WorkSize%JUB
        do i = Me%WorkSize%ILB, Me%WorkSize%IUB
            
            if (Me%External_Var%WaterPoints3D(i, j, k) == WaterPoint) then
                MaxVariation = max (MaxVariation, abs((Me%External_Var%Volume_Z_New(i, j, k)  - &
                                                       Me%External_Var%Volume_Z_Old(i, j, k)) / &
                                                       Me%External_Var%Volume_Z_New(i, j, k)))
            endif

        enddo
        enddo
        enddo

        !If variation is over 10.0% shut down DT quickly
        if     (MaxVariation > 0.10) then
            VolVarDT = 0.5  * NewDT
        !If variation is over  2% shut down DT slowly
        elseif (MaxVariation > 0.02) then
            VolVarDT = 0.95 * NewDT
        !If variation is over  1%% keep DT
        elseif (MaxVariation > 0.01) then     
            VolVarDT = NewDT                !This will keep DT constant
        !Increase DT
        else
            VolVarDT = -null_real           !Vol Var is not determinate
        endif

        !write(988, *)VelDT, CourantDT, VolVarDT

        !Return Minimum DT
        NewDT = min(VelDT, CourantDT, VolVarDT)

    end subroutine CalcNewDT

    !End--------------------------------------------------------------------------

    subroutine Statistics_OutPut ( CenterU, CenterV, CenterW)

        !Arguments-------------------------------------------------------------
         
        real,    dimension(:,:,:), pointer      :: CenterU, CenterV, CenterW

        !Local-----------------------------------------------------------------
        real,    dimension(:,:,:), pointer      :: Value3D
        !real,    dimension(:,:  ), pointer      :: MLD_Surf
        real,    dimension(:,:  ), pointer      :: Bathymetry
        integer                                 :: MethodStatistic, LayerDefinition
        integer                                 :: Depth, Layer, Value3DStatLayers,      &
                                                   LayersNumber, np, ln
        integer                                 :: ILB, IUB, JLB, JUB, STAT_CALL
        integer                                 :: status
        !Begin-----------------------------------------------------------------

        ILB = Me%WorkSize%ILB
        IUB = Me%WorkSize%IUB

        JLB = Me%WorkSize%JLB
        JUB = Me%WorkSize%JUB


        if (Me%Statistics%ON) then

            do np = 1, Me%Statistics%NProp

                if (Me%Statistics%PropList(np) == VelocityU_)           &
                    Value3D => CenterU

                if (Me%Statistics%PropList(np) == VelocityV_)           &
                    Value3D => CenterV

                if (Me%Statistics%PropList(np) == VelocityW_)           &
                    Value3D => CenterW


                call GetStatisticMethod (Me%Statistics%ID(np), MethodStatistic, &
                                        STAT = status)
                                            
                if (status /= SUCCESS_)                                                  &
                    call SetError (FATAL_, INTERNAL_, 'Statistics_OutPut - ModuleHydrodynamic - ERR01')

                call GetStatisticParameters (Me%Statistics%ID(np),          &
                                             Value3DStatLayers = Value3DStatLayers,      &
                                             Depth             = Depth,                  &
                                             Layer             = Layer,                  &
                                             STAT = status)
                                            
                if (status /= SUCCESS_)                                                  &
                    call SetError (FATAL_, INTERNAL_, 'Statistics_OutPut - ModuleHydrodynamic - ERR02')


cd1:            if (MethodStatistic == Value3DStatLayers) then


!                    nullify(MLD_Surf)

                    !Gets Bathymetry
                    call GetGridData(Me%ObjGridData,                    &
                                       Bathymetry, STAT = status)
        
                    if (status /= SUCCESS_)                                              &
                        call SetError (FATAL_, INTERNAL_, 'Statistics_OutPut - ModuleHydrodynamic - ERR03')

                
                    call GetStatisticLayersNumber(Me%Statistics%ID(np), LayersNumber, STAT = status)
                                                
                    if (status /= SUCCESS_)                                              &
                            call SetError (FATAL_, INTERNAL_, 'Statistics_OutPut - ModuleHydrodynamic - ERR04')

                    do ln = 1, LayersNumber

                        call GetStatisticLayerDef(Me%Statistics%ID(np),     &
                                                  ln, LayerDefinition, STAT = status)
                                                    
                        if (status /= SUCCESS_)                                          &
                            call SetError (FATAL_, INTERNAL_, 'OutPut_Statistics - ModuleHydrodynamic - ERR06')
                       !Statistic of properties values along the bottom 
                        if (LayerDefinition == Layer) then 


                            call AddStatisticLayers (StatisticID    = Me%Statistics%ID(np),         &
                                                     Value3D        = Value3D,                      &
                                                     WaterPoints3D  = Me%External_Var%WaterPoints3D,&
                                                     DZ3D           = Me%External_Var%DWZ,          &
                                                     LayerNumber    = ln,                           &
                                                     STAT= STAT_CALL) 

                            if (STAT_CALL /= SUCCESS_)                                              &
                                call SetError (FATAL_, KEYWORD_, 'OutPut_Statistics - ModuleWaterProperties - ERR06')


                        !Statistic of properties values in the surface mixed layer 
                        else if (LayerDefinition == Depth) then 

!                            call GetMLD_Surf(Me%ObjTurbulence, MLD_Surf, STAT = status) 
!
!                            if (status /= SUCCESS_)                                              &
!                                call SetError (FATAL_, INTERNAL_, 'Statistics_OutPut - ModuleHydrodynamic - ERR08')

                            call AddStatisticLayers (Me%Statistics%ID(np),                          &
                                                     Value3D       = Value3D,                       &
                                                     WaterPoints3D = Me%External_Var%WaterPoints3D, &
                                                     DZ3D          = Me%External_Var%DWZ,           &
                                                     LayerNumber   = ln,                             &
!                                                     LowerDepth    = MLD_Surf,                      &
                                                     STAT= status) 

                            if (status /= SUCCESS_)                                              &
                                call SetError (FATAL_, INTERNAL_, 'Statistics_OutPut - ModuleHydrodynamic - ERR10')

                    
!                            call UnGetTurbulence(Me%ObjTurbulence, MLD_Surf, STAT = status) 

!                            if (status /= SUCCESS_)                                              &
!                                call SetError (FATAL_, INTERNAL_, 'Statistics_OutPut - ModuleHydrodynamic - ERR13')

                        endif
 

                    enddo



                endif  cd1

                call ModifyStatistic (Me%Statistics%ID(np),                              &
                                      Value3D       = Value3D,                           &
                                      WaterPoints3D = Me%External_Var%WaterPoints3D,     &
                                      STAT          = status)
                if (status /= SUCCESS_)                                                  &
                    call SetError (FATAL_, INTERNAL_, 'Statistics_OutPut - ModuleHydrodynamic - ERR12')


  
            enddo
            
        endif


    end subroutine Statistics_OutPut

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------

    subroutine SetHydroFather (HydrodynamicID, HydrodynamicFatherID, InitialField, STAT)

        !Arguments-------------------------------------------------------------
        integer,           intent(IN )              :: HydrodynamicID, HydrodynamicFatherID
        logical,           intent(IN )              :: InitialField
        integer, optional, intent(OUT)              :: STAT


        !Local-----------------------------------------------------------------
        type (T_Hydrodynamic), pointer              :: ObjHydrodynamicFather
        integer                                     :: ready_, readyFather_
        integer                                     :: STAT_
        real                                        :: DT_Father
        real,    dimension(:,:,:), pointer          :: UFather, VFather, DUZFather, DVZFather
        real(8), dimension(:,:,:), pointer          :: FluxXFather, FluxYFather
        real,    dimension(:,:  ), pointer          :: ZFather
        integer, dimension(:,:,:), pointer          :: Open3DFather     
        integer, dimension(:,:,:), pointer          :: Faces3D_UFather    
        integer, dimension(:,:,:), pointer          :: Faces3D_VFather  

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready      (HydrodynamicID, ready_)

        call ReadyFather(HydrodynamicFatherID, ObjHydrodynamicFather, readyFather_)

cd1 :   if (ready_ .EQ. IDLE_ERR_ .and. readyFather_ .EQ. IDLE_ERR_) then

            if(InitialField) then
                call TestSubModelOptionsConsistence (ObjHydrodynamicFather%ComputeOptions%Continuous)
                call GetComputeTimeStep             (ObjHydrodynamicFather%ObjTime, DT_Father)
                call ConstructTimeInterpolation     (ObjHydrodynamicFather%WorkSize%KLB, &
                                                     ObjHydrodynamicFather%WorkSize%KUB, &
                                                     DT_Father)
            endif

            Me%SubModel%DUZ_Old(:,:,:) = Me%SubModel%DUZ_New(:,:,:)
            Me%SubModel%DVZ_Old(:,:,:) = Me%SubModel%DVZ_New(:,:,:)

            if (ObjHydrodynamicFather%LastIteration > Me%SubModel%NextTime &
                .or. InitialField) then

                call ReadLockFather(ObjHydrodynamicFather,                               &
                                    FluxXFather, FluxYFather,                            &
                                    Open3DFather, Faces3D_UFather, Faces3D_VFather,      &
                                    UFather, VFather, ZFather, DUZFather, DVZFather)


                call ReadNextOrInitialField (UFather, VFather, DUZFather, DVZFather,     &
                                       FluxXFather, FluxYFather, ZFather, Open3DFather,  &
                                       Faces3D_UFather, Faces3D_VFather, InitialField,   &
                                       ObjHydrodynamicFather%WorkSize%KLB,               &
                                       ObjHydrodynamicFather%WorkSize%KUB,               &
                                       ObjHydrodynamicFather%ObjHorizontalGrid)


                !Unget Father information
                call ReadUnLockFather(ObjHydrodynamicFather,                             &
                                      FluxXFather, FluxYFather,                          &
                                      Open3DFather, Faces3D_UFather, Faces3D_VFather,    &
                                      UFather, VFather, ZFather, DUZFather, DVZFather)
           

                if (.not. InitialField) then
                    Me%SubModel%PreviousTime = Me%SubModel%NextTime
                    Me%SubModel%NextTime     = ObjHydrodynamicFather%LastIteration 
                endif

            endif
            if      (Me%SubModel%VertComunic == FatherSonEqualDim) then
                
                call ActualizeSubModelValues(InitialField)

            else if (Me%SubModel%VertComunic == Father2DSon3D) then

                call ActualizeSon3DWithFather2D (InitialField)

            endif

!            if (Me%SubModel%DeadZone .and. InitialField  .and.           &
            if (InitialField  .and.           &
                .not. Me%ComputeOptions%Continuous)                      &
                call Initial_Geometry(Me%WaterLevel%New)


            STAT_ = SUCCESS_
        else cd1
         
            STAT_ = ready_

        end if cd1


        if (present(STAT))  STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine SetHydroFather

    !--------------------------------------------------------------------------

    subroutine TestSubModelOptionsConsistence(FatherContinuous)

        !Arguments-------------------------------------------------------------
        logical                                     :: FatherContinuous

        !Local-----------------------------------------------------------------
        logical                                     :: ModelGOTM, ContinuousGOTM
        integer                                     :: STAT_CALL

        !----------------------------------------------------------------------
     
        !Begin - Shorten variables name 

        call GetContinuousGOTM(Me%ObjTurbulence, ContinuousGOTM, ModelGOTM, STAT = STAT_CALL)            

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError(FATAL_, INTERNAL_, 'TestSubModelOptionsConsistence - Hydrodynamic - ERR01.')


        if (FatherContinuous                      .and.                   &
           .not. Me%ComputeOptions%Continuous     .and.                   &
           .not. Me%ComputeOptions%BottomVisc_LIM .and.                   &
            ModelGOTM .and. .not. ContinuousGOTM) then

            write (*,*) 'In this case the submodel initial non-turbulent hydrodynamic properties' 
            write (*,*) 'are initialised based in the father model but the turbulent properties are not.'
            write (*,*) 'In areas of strong velocities numerical instabilities mabe hObjen.'
            write (*,*) 'In this case the user is advised to use the option BOTTOMVISC_LIM.' 
            write (*,*) 'See the user manual for more information about this option http://www.mohid.com.' 

        endif

    end subroutine TestSubModelOptionsConsistence
    
    !--------------------------------------------------------------------------

    subroutine ActualizeSubModelValues (InitialField)

        !Arguments-------------------------------------------------------------
        logical,           intent(IN )     :: InitialField

        !Local-----------------------------------------------------------------
        real,    dimension(:,:,:), pointer :: DUZ_Son, DVZ_Son
        real,    dimension(:,:  ), pointer :: DXX_Son, DYY_Son, Bathymetry
        integer, dimension(:,:  ), pointer :: Boundary2DSon
        integer, dimension(:,:,:), pointer :: Water3DSon
        integer, dimension(:,:,:), pointer :: Faces3D_USon  
        integer, dimension(:,:,:), pointer :: Faces3D_VSon
        integer, dimension(:,:,:), pointer :: ImposedTangFacesUSon, ImposedTangFacesVSon
        integer, dimension(:,:,:), pointer :: ImposedNormFacesUSon, ImposedNormFacesVSon
        real                               :: TimeCoef, MinWaterColumn
        integer                            :: status
        integer                            :: ILB, IUB, JLB, JUB, KLB, KUB
        integer                            :: i, j, k
        logical                            :: ErrorOccured, DeadZoneSon

        !Begin-----------------------------------------------------------------

        ILB = Me%WorkSize%ILB
        IUB = Me%WorkSize%IUB

        JLB = Me%WorkSize%JLB
        JUB = Me%WorkSize%JUB

        KLB = Me%WorkSize%KLB
        KUB = Me%WorkSize%KUB


        if (Me%SubModel%InterPolTime .and. .not. InitialField) then

            !Time Properties - Actualises CurrentTime
            call GetComputeCurrentTime(Me%ObjTime,                       &
                                       Me%CurrentTime, STAT = status)
            if (status /= SUCCESS_)                                                      &                    
                    call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR01") 

            TimeCoef = (Me%CurrentTime       - Me%SubModel%PreviousTime) / &
                       (Me%SubModel%NextTime - Me%SubModel%PreviousTime)

            call null_Time(Me%CurrentTime)


        else 
        
            TimeCoef = 1                    
            
        endif



        
        !Gets Bathymetry
        call GetGridData(Me%ObjGridData, Bathymetry, STAT = status)
        if (status /= SUCCESS_)                                                          &                    
                call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR02") 



        call GetGeometryMinWaterColumn(Me%ObjGeometry, MinWaterColumn, STAT = status)
        if (status /= SUCCESS_)                                                          &                    
            call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR03") 
            


        call ReadLockSon(ImposedTangFacesUSon, ImposedTangFacesVSon,                     &
                         ImposedNormFacesUSon, ImposedNormFacesVSon,                     &
                         Water3DSon, Boundary2DSon,                                       &
                         Faces3D_USon, Faces3D_VSon,                                     &
                         DUZ_Son, DVZ_Son,                                               &
                         DXX_Son, DYY_Son)


cd3:    if (InitialField) then

            ErrorOccured = .false.

            do k = KLB, KUB
            do j = JLB, JUB + 1
            do i = ILB, IUB

                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, k)

                else

                    DeadZoneSon = .false.

                endif
                
!cd4:            if (((Faces3D_USon        (i, j, k) == Covered              .and.        &
!                      .not. Me%ComputeOptions%Continuous)   .or.         &

cd4:            if (( Faces3D_USon        (i, j, k) == Covered              .or.         &
                      ImposedTangFacesUSon(i, j, k) == Imposed              .or.         &
                      ImposedNormFacesUSon(i, j, k) == Imposed)             .and.        & 
                      .not. DeadZoneSon) then
                
                    if (Me%SubModel%qX(i, j, k)  < FillValueReal / 2.) then
#ifndef _USE_MPI
                        write(*,*)'Point [i,j,k] not covered',i, j,k
#endif
                        ErrorOccured = .true.
                        if (Me%SubModel%MissingNull)                     &
                            Me%SubModel%qX(i, j, k) = 0.
                    endif
                    
                    if (.not. Me%ComputeOptions%Continuous) then

                        Me%WaterFluxes%X(i, j, k)               =        &
                            Me%SubModel%qX (i, j, k) * DYY_Son(i, j)

                    endif

            
                endif cd4

            enddo
            enddo
            enddo

            do k = KLB, KUB
            do j = JLB, JUB
            do i = ILB, IUB + 1


                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, k)

                else

                    DeadZoneSon = .false.

                endif
                
!cd5:            if (((Faces3D_VSon        (i, j, k) == Covered              .and.        &
!                      .not. Me%ComputeOptions%Continuous)   .or.         &
!                      ImposedTangFacesVSon(i, j, k) == Imposed              .or.         &
!                      ImposedNormFacesVSon(i, j, k) == Imposed)             .and.        & 
!                      .not. DeadZoneSon) then

cd5:            if (( Faces3D_VSon        (i, j, k) == Covered              .or.         &
                      ImposedTangFacesVSon(i, j, k) == Imposed              .or.         &
                      ImposedNormFacesVSon(i, j, k) == Imposed)             .and.        & 
                      .not. DeadZoneSon) then


                
                    if (Me%SubModel%qY  (i, j, k) < FillValueReal / 2.) then
#ifndef _USE_MPI
                        write(*,*)'Point [i,j,k] not covered',i, j,k
#endif
                        ErrorOccured = .true.
                        if (Me%SubModel%MissingNull)                     &
                            Me%SubModel%qY(i, j, k) = 0.
                    endif

                    if (.not. Me%ComputeOptions%Continuous) then

                        Me%WaterFluxes%Y(i, j, k)               =        &
                            Me%SubModel%qY  (i, j, k) * DXX_Son(i, j)

                    endif


                endif cd5

            enddo
            enddo
            enddo

            if (ErrorOccured .and. .not. Me%SubModel%MissingNull)        &
                call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR04") 


        endif cd3

            
cd66:   if ((InitialField .and. .not. Me%ComputeOptions%Continuous) .or. & 
             Me%Relaxation%WaterLevel                               .or. &
             Me%ComputeOptions%BarotropicRadia == FlatherLocalSolution_)  then

            do j = JLB, JUB
            do i = ILB, IUB

                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, KUB)

                else

                    DeadZoneSon = .false.

                endif

                !The test must be done for the water points because the water levels in the corner (no open points) 
                !are used to compute face areas where momentum fluxes are computed.
cd6:            if (Water3DSon(i, j, KUB) == WaterPoint .and. .not. DeadZoneSon) then
                
                    Me%SubModel%Z(i, j)  =                                   &
                            Me%SubModel%Z_Next    (i, j) * TimeCoef  +       &
                            Me%SubModel%Z_Previous(i, j) * (1 - TimeCoef)

                    if (Me%SubModel%Z(i, j) < (- Bathymetry(i, j) + 0.75 * MinWaterColumn)) then
                        Me%SubModel%Z(i, j) =  - Bathymetry(i, j) + 0.75 * MinWaterColumn
                    endif


                    if (Me%SubModel%Z_Next    (i, j) < FillValueReal / 2. .or.   &
                        Me%SubModel%Z_Previous(i, j) < FillValueReal / 2.) then


                        if (.not.Me%SubModel%MissingNull) then

                            call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR05") 

                        endif

                    endif

                    if (InitialField .and. .not. Me%ComputeOptions%Continuous) &
                        Me%WaterLevel%New(i, j) =                              &
                            Me%SubModel%Z(i, j)


                endif cd6

            enddo
            enddo

            if (Me%SubModel%MissingNull)                                                &
                call RemoveLowerSpikes (Me%WaterLevel%New, Water3DSon,                  &
                                        Bathymetry, MinWaterColumn,                     &
                                        Me%SubModel%DeadZonePoint, Me%SubModel%DeadZone,&
                                        ILB, IUB, JLB, JUB, KUB) 

        else cd66


            do j = JLB, JUB
            do i = ILB, IUB

                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, KUB)

                else

                    DeadZoneSon = .false.

                endif

                !The test must be done for the water points because the water levels in the corner (no open points) 
                !are used to compute face areas where momentum fluxes are computed.                    
cd67:           if (Boundary2DSon(i, j) == Boundary .and. Water3DSon(i, j, KUB) == WaterPoint  &
                   .and. .not. DeadZoneSon) then

                    Me%SubModel%Z(i, j)  =                                   &
                            Me%SubModel%Z_Next    (i, j) * TimeCoef  +       &
                            Me%SubModel%Z_Previous(i, j) * (1 - TimeCoef)
                
                    if (Me%SubModel%Z_Next    (i, j) < FillValueReal / 2. .or.   &
                        Me%SubModel%Z_Previous(i, j) < FillValueReal / 2.)   then

                        if (Me%SubModel%MissingNull) then
                            !The cell is considered uncovered if WaterColumn < MinWaterColumn 
                            !if WaterColumn < MinWaterColumn / 2 the model put WaterColumn = MinWaterColumn / 2 (creates water)
                            ! Using WaterColumn = 3/4MinWaterColumn garantes that the cell is uncovered but mass is not created
                            Me%SubModel%Z(i, j)  = - Bathymetry(i, j) + 0.75 * MinWaterColumn 

                        else

                            call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR06") 

                        endif
                    endif


                endif cd67

            enddo
            enddo

            if (Me%SubModel%MissingNull)                                                &
                call RemoveLowerSpikes (Me%SubModel%Z, Water3DSon,                      &
                                        Bathymetry, MinWaterColumn,                     &
                                        Me%SubModel%DeadZonePoint, Me%SubModel%DeadZone,&
                                        ILB, IUB, JLB, JUB, KUB, Boundary2DSon) 



        endif cd66
        

cd8:    if ((InitialField .and. .not. Me%ComputeOptions%Continuous)          .or. & 
             Me%Relaxation%Force .or. Me%Relaxation%Velocity .or. &
             Me%ComputeOptions%BarotropicRadia == FlatherLocalSolution_) then

            do k = KLB, KUB
            do j = JLB, JUB + 1
            do i = ILB, IUB

                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, k)

                else

                    DeadZoneSon = .false.

                endif
                    

cd7:            if (Faces3D_USon(i, j, k) == Covered .and. .not. DeadZoneSon) then
                
                    Me%SubModel%U_New(i, j, k)  =                            &
                            Me%SubModel%U_Next    (i, j, k) * TimeCoef  +    &
                            Me%SubModel%U_Previous(i, j, k) * (1 - TimeCoef)


                    if (Me%SubModel%U_Next    (i, j, k) < FillValueReal / 2. .or.&
                        Me%SubModel%U_Previous(i, j, k) < FillValueReal / 2.)   then

                        if (Me%SubModel%MissingNull) then 
                            Me%SubModel%U_New(i, j, k)  = 0.
                        else
                            call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR07") 
                        endif

                    endif

                    if (InitialField .and. .not. Me%ComputeOptions%Continuous) &
                        Me%Velocity%Horizontal%U%New(i, j, k) =                &
                                   Me%SubModel%U_New(i, j, k)

   
                    Me%SubModel%DUZ_New(i, j, k)  =                          &
                            Me%SubModel%DUZ_Next    (i, j, k) * TimeCoef  +  &
                            Me%SubModel%DUZ_Previous(i, j, k) * (1 - TimeCoef)

                    if (Me%SubModel%DUZ_Next    (i, j, k) < FillValueReal / 2. .or.&
                        Me%SubModel%DUZ_Previous(i, j, k) < FillValueReal / 2.)    then

                        if (Me%SubModel%MissingNull) then 
                            Me%SubModel%DUZ_New(i, j, k)  = 0.
                        else
                            call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR08") 
                        endif

                    endif




                endif cd7

            enddo
            enddo
            enddo
            
        endif cd8


        do k = KLB, KUB
        do j = JLB, JUB + 1
        do i = ILB, IUB

            if (Me%SubModel%DeadZone) then

                DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, k)

            else

                DeadZoneSon = .false.

            endif

            
cd77:       if ((ImposedTangFacesUSon(i, j, k) == Imposed  .or.                          &
                 ImposedNormFacesUSon(i, j, k) == Imposed) .and. .not. DeadZoneSon) then
                
                Me%SubModel%U_New(i, j, k)  =                            &
                        Me%SubModel%U_Next    (i, j, k) * TimeCoef  +    &
                        Me%SubModel%U_Previous(i, j, k) * (1 - TimeCoef)

                if (Me%SubModel%U_Next    (i, j, k) < FillValueReal / 2. .or.&
                    Me%SubModel%U_Previous(i, j, k) < FillValueReal / 2.)  then

                    if (Me%SubModel%MissingNull) then 
                        Me%SubModel%U_New(i, j, k)  = 0.
                    else
                        call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR09") 
                    endif
                endif


                if (InitialField .and. .not. Me%ComputeOptions%Continuous) &
                    Me%Velocity%Horizontal%U%New(i, j, k) =                &
                               Me%SubModel%U_New(i, j, k)

                Me%SubModel%DUZ_New(i, j, k)  =                          &
                        Me%SubModel%DUZ_Next    (i, j, k) * TimeCoef  +  &
                        Me%SubModel%DUZ_Previous(i, j, k) * (1 - TimeCoef)

                if (Me%SubModel%DUZ_Next    (i, j, k) < FillValueReal / 2. .or.&
                    Me%SubModel%DUZ_Previous(i, j, k) < FillValueReal / 2.)  then

                    if (Me%SubModel%MissingNull) then 
                        Me%SubModel%DUZ_New(i, j, k)  = 0.
                    else
                        call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR10") 
                    endif

                endif



            endif cd77

        enddo
        enddo
        enddo



cd10:   if ((InitialField .and. .not. Me%ComputeOptions%Continuous)          .or. & 
             Me%Relaxation%Force .or. Me%Relaxation%Velocity .or. &
             Me%ComputeOptions%BarotropicRadia == FlatherLocalSolution_) then

            do k = KLB, KUB
            do j = JLB, JUB
            do i = ILB, IUB + 1

                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, k)

                else

                    DeadZoneSon = .false.

                endif


cd9:            if (Faces3D_VSon(i, j, k) == Covered .and. .not. DeadZoneSon) then


                    Me%SubModel%V_New(i, j, k)      =                        &
                            Me%SubModel%V_Next    (i, j, k) * TimeCoef  +    &
                            Me%SubModel%V_Previous(i, j, k) * (1 - TimeCoef)

                    if (Me%SubModel%V_Next    (i, j, k) < FillValueReal / 2. .or.&
                        Me%SubModel%V_Previous(i, j, k) < FillValueReal / 2.) then

                        if (Me%SubModel%MissingNull) then 
                            Me%SubModel%V_New(i, j, k)  = 0.
                        else
                            call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR11") 
                        endif
                    endif


                    if (InitialField .and. .not. Me%ComputeOptions%Continuous) &
                        Me%Velocity%Horizontal%V%New(i, j, k) =                &
                                   Me%SubModel%V_New(i, j, k)


                    Me%SubModel%DVZ_New(i, j, k)  =                          &
                            Me%SubModel%DVZ_Next    (i, j, k) * TimeCoef  +  &
                            Me%SubModel%DVZ_Previous(i, j, k) * (1 - TimeCoef)


                    if (Me%SubModel%DVZ_Next    (i, j, k) < FillValueReal / 2. .or.&
                        Me%SubModel%DVZ_Previous(i, j, k) < FillValueReal / 2.)    then

                        if (Me%SubModel%MissingNull) then 
                            Me%SubModel%DVZ_New(i, j, k)  = 0.
                        else
                            call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR12") 
                        endif

                    endif


                endif cd9


            enddo
            enddo
            enddo

        endif cd10


        do k = KLB, KUB
        do j = JLB, JUB
        do i = ILB, IUB + 1

            if (Me%SubModel%DeadZone) then

                DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, k)

            else

                DeadZoneSon = .false.

            endif


cd99:       if ((ImposedTangFacesVSon(i, j, k) == Imposed  .or.                          &
                 ImposedNormFacesVSon(i, j, k) == Imposed) .and. .not. DeadZoneSon) then


                Me%SubModel%V_New(i, j, k)      =                        &
                        Me%SubModel%V_Next    (i, j, k) * TimeCoef  +    &
                        Me%SubModel%V_Previous(i, j, k) * (1 - TimeCoef)

                
                if (Me%SubModel%V_Next    (i, j, k) < FillValueReal / 2. .or.&
                    Me%SubModel%V_Previous(i, j, k) < FillValueReal / 2.)  then
 
                    if (Me%SubModel%MissingNull) then 
                        Me%SubModel%V_New(i, j, k)  = 0.
                    else
                        call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR13") 
                    endif

                endif

                if (InitialField .and. .not. Me%ComputeOptions%Continuous) &
                    Me%Velocity%Horizontal%V%New(i, j, k) =                &
                               Me%SubModel%V_New(i, j, k)

                Me%SubModel%DVZ_New(i, j, k)  =                          &
                        Me%SubModel%DVZ_Next    (i, j, k) * TimeCoef  +  &
                        Me%SubModel%DVZ_Previous(i, j, k) * (1 - TimeCoef)


                if (Me%SubModel%DVZ_Next    (i, j, k) < FillValueReal / 2. .or.&
                    Me%SubModel%DVZ_Previous(i, j, k) < FillValueReal / 2.)   then

                    if (Me%SubModel%MissingNull) then 
                        Me%SubModel%DVZ_New(i, j, k)  = 0.
                    else
                        call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR14") 
                    endif

                endif
                        
            endif cd99

        enddo
        enddo
        enddo

        !This is only done for graphical reasons
        if (InitialField .and. .not. Me%ComputeOptions%Continuous) then

            !U corners            
            Me%Velocity%Horizontal%U%New(ILB,JLB    , KLB:KUB)   =       &
            Me%SubModel%U_New           (ILB,JLB    , KLB:KUB)

            Me%Velocity%Horizontal%U%New(ILB,JUB + 1, KLB:KUB)   =       &
            Me%SubModel%U_New           (ILB,JUB + 1, KLB:KUB)

            Me%Velocity%Horizontal%U%New(IUB,JLB    , KLB:KUB)   =       &
            Me%SubModel%U_New           (IUB,JLB    , KLB:KUB)

            Me%Velocity%Horizontal%U%New(IUB,JUB + 1, KLB:KUB)   =       &
            Me%SubModel%U_New           (IUB,JUB + 1, KLB:KUB)

           
            !V corners
            Me%Velocity%Horizontal%V%New(ILB,JLB    , KLB:KUB)   =       &
            Me%SubModel%V_New           (ILB,JLB    , KLB:KUB)

            Me%Velocity%Horizontal%V%New(ILB,JUB    , KLB:KUB)   =       &
            Me%SubModel%V_New           (ILB,JUB    , KLB:KUB)

            Me%Velocity%Horizontal%V%New(IUB + 1,JLB, KLB:KUB)   =       &
            Me%SubModel%V_New           (IUB + 1,JLB, KLB:KUB)

            Me%Velocity%Horizontal%V%New(IUB + 1,JUB, KLB:KUB)   =       &
            Me%SubModel%V_New           (IUB + 1,JUB, KLB:KUB)

            
        endif

        Me%SubModel%Set      = .true.


        !UnGet son information 
        call ReadUnLockSon(ImposedTangFacesUSon, ImposedTangFacesVSon,                   &
                           ImposedNormFacesUSon, ImposedNormFacesVSon,                   &
                           Water3DSon, Boundary2DSon,                                     &
                           Faces3D_USon, Faces3D_VSon,                                   &
                           DUZ_Son, DVZ_Son,                                             &
                           DXX_Son, DYY_Son)


cd11:   if (InitialField .and. .not. Me%ComputeOptions%Continuous) then

            Me%WaterLevel%Old               (:,:  ) =                    &
                Me%WaterLevel%New           (:,:  )

            Me%Velocity%Horizontal%V%Old    (:,:,:) =                    &
                Me%Velocity%Horizontal%V%New(:,:,:)

            Me%Velocity%Horizontal%U%Old    (:,:,:) =                    &
                Me%Velocity%Horizontal%U%New(:,:,:)

            Me%SubModel%DUZ_Old(:,:,:)              =                    &
                Me%SubModel%DUZ_Next(:,:,:)


            Me%SubModel%DVZ_Old(:,:,:)              =                    &
                Me%SubModel%DVZ_Next(:,:,:)

        endif cd11


       !UnGets Bathymetry
        call UnGetGridData(Me%ObjGridData, Bathymetry, STAT = status)

        if (status /= SUCCESS_)                                                          &
                call SetError(FATAL_, INTERNAL_, "ActualizeSubModelValues; Hydrodynamic. ERR15") 

    end subroutine ActualizeSubModelValues


    !--------------------------------------------------------------------------
    subroutine ActualizeSon3DWithFather2D (InitialField)

        !Arguments-------------------------------------------------------------
        logical,           intent(IN )  :: InitialField

        !Local-----------------------------------------------------------------
        real,    dimension(:,:,:), pointer :: DUZ_Son, DVZ_Son
        real,    dimension(:,:  ), pointer :: DXX_Son, DYY_Son, WaterColumnU, WaterColumnV, Bathymetry
        integer, dimension(:,:  ), pointer :: Boundary2DSon, KFloor_U, KFloor_V
        integer, dimension(:,:,:), pointer :: Water3DSon
        integer, dimension(:,:,:), pointer :: Faces3D_USon  
        integer, dimension(:,:,:), pointer :: Faces3D_VSon
        integer, dimension(:,:,:), pointer :: ImposedTangFacesUSon, ImposedTangFacesVSon
        integer, dimension(:,:,:), pointer :: ImposedNormFacesUSon, ImposedNormFacesVSon
        real                               :: TimeCoef, RelativeThickness, MinWaterColumn
        integer                            :: status
        integer                            :: ILB, IUB, JLB, JUB, KLB, KUB
        integer                            :: i, j, k, Kbottom, i_Thick, j_Thick
        logical                            :: ErrorOccured, DeadZoneSon, NullValue


        !Begin-----------------------------------------------------------------


        call GetGeometryWaterColumn(Me%ObjGeometry,                          &
                                    WaterColumnU= WaterColumnU, WaterColumnV= WaterColumnV,  &
                                    STAT = status)

        if (status /= SUCCESS_)                                                          &
                call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR01") 


        call GetGeometryKFloor(Me%ObjGeometry,                           &
                               U = KFloor_U, V = KFloor_V, STAT = status)

        if (status /= SUCCESS_)                                                          &
                call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR02") 


       !Gets Bathymetry
        call GetGridData(Me%ObjGridData, Bathymetry, STAT = status)

        if (status /= SUCCESS_)                                                          &
                call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR03") 


        call GetGeometryMinWaterColumn(Me%ObjGeometry,                   &
                                       MinWaterColumn, STAT = status)

        if (status /= SUCCESS_)                                                          &                    
            call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR04") 


        ILB = Me%WorkSize%ILB
        IUB = Me%WorkSize%IUB

        JLB = Me%WorkSize%JLB
        JUB = Me%WorkSize%JUB

        KLB = Me%WorkSize%KLB
        KUB = Me%WorkSize%KUB

        if (Me%SubModel%InterPolTime .and. .not. InitialField) then

            !Time Properties - Actualises CurrentTime
            call GetComputeCurrentTime(Me%ObjTime,                       &
                                       Me%CurrentTime, STAT = status)
            if (status /= SUCCESS_)                                                      &                    
                    call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR05") 

            TimeCoef = (Me%CurrentTime       - Me%SubModel%PreviousTime) / &
                       (Me%SubModel%NextTime - Me%SubModel%PreviousTime)

            call null_Time(Me%CurrentTime)

        else 
        
            TimeCoef = 1                    
            
        endif


        call ReadLockSon(ImposedTangFacesUSon, ImposedTangFacesVSon,                     &
                         ImposedNormFacesUSon, ImposedNormFacesVSon,                     &
                         Water3DSon, Boundary2DSon,                                       &
                         Faces3D_USon, Faces3D_VSon,                                     &
                         DUZ_Son, DVZ_Son,                                               &
                         DXX_Son, DYY_Son)


cd3:    if (InitialField) then

            ErrorOccured = .false.



            do j = JLB, JUB + 1
            do i = ILB, IUB

                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, KUB)

                else

                    DeadZoneSon = .false.

                endif

                
cd4:            if ((Faces3D_USon        (i, j, KUB) == Covered   .or.                   &
                     ImposedTangFacesUSon(i, j, KUB) == Imposed   .or.                   &
                     ImposedNormFacesUSon(i, j, KUB) == Imposed)  .and.                  & 
                     .not. DeadZoneSon) then

                    NullValue = .false.
                
                    if (Me%SubModel%qX(i, j, KUB)  < FillValueReal / 2.) then
#ifndef _USE_MPI
                        write(*,*)'Point [i,j,k] not covered',i, j,KUB
#endif
                        ErrorOccured = .true.
                        if (Me%SubModel%MissingNull)                     &
                            NullValue = .true.

                    endif


                    if      (ImposedTangFacesUSon(i, j, KUB) == Imposed .or.             &
                             Faces3D_USon        (i, j, KUB) == Covered) then

                        i_thick = i
                        j_thick = j

                    else if (ImposedNormFacesUSon(i, j, KUB) == Imposed) then

                        i_thick = i

                        if      (j == JUB + 1) then

                            j_thick = j - 1

                        else if (j == JLB) then

                            j_thick = j + 1

                        else

                            j_thick = j + Faces3D_USon(i, j + 1, KUB) - Faces3D_USon(i, j - 1, KUB)

                        endif

                    endif

                    Kbottom = KFloor_U(i_thick, j_thick)

                    do k = Kbottom, KUB
                        
                        if (NullValue) then

                            Me%SubModel%qX  (i, j, k) = 0.

                        else

                            RelativeThickness = DUZ_Son(i_thick, j_thick, k) / WaterColumnU(i_thick, j_thick)

                            Me%SubModel%qX (i, j, k) =                       &
                                Me%SubModel%qX (i, j, KUB) * RelativeThickness

                        endif

                        if (.not. Me%ComputeOptions%Continuous) then

                            Me%WaterFluxes%X(i, j, k)               =    &
                                Me%SubModel%qX (i, j, k  ) * DYY_Son(i, j) 

                        endif


                    enddo

            
                endif cd4

            enddo
            enddo


            do j = JLB, JUB
            do i = ILB, IUB + 1


                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, KUB)

                else

                    DeadZoneSon = .false.

                endif

                
cd5:            if ((Faces3D_VSon        (i, j, KUB) == Covered   .or.                   &
                     ImposedTangFacesVSon(i, j, KUB) == Imposed   .or.                   &
                     ImposedNormFacesVSon(i, j, KUB) == Imposed)  .and.                  & 
                     .not. DeadZoneSon) then
                    
                    NullValue = .false.
                
                    if (Me%SubModel%qY  (i, j, KUB) < FillValueReal / 2.) then
#ifndef _USE_MPI
                        write(*,*)'Point [i,j,k] not covered',i, j,KUB
#endif
                        ErrorOccured = .true.
                        if (Me%SubModel%MissingNull)                     &
                            NullValue = .true.
                    endif


                    if (ImposedTangFacesVSon(i, j, KUB) == Imposed .or.                  &
                        Faces3D_VSon        (i, j, KUB) == Covered ) then

                        i_thick = i
                        j_thick = j

                    else if (ImposedNormFacesVSon(i, j, KUB) == Imposed) then

                        if      (i == IUB + 1) then

                            i_thick = i - 1

                        else if (i == ILB) then

                            i_thick = i + 1

                        else

                            i_thick = i + Faces3D_VSon(i + 1, j, KUB) - Faces3D_VSon(i - 1, j, KUB)

                        endif

                        j_thick = j 

                    endif

                    Kbottom = KFloor_V(i_thick, j_thick)


                    do k = Kbottom, KUB

                        if (NullValue) then

                            Me%SubModel%qY  (i, j, k) = 0.

                        else

                            RelativeThickness = DVZ_Son(i_thick, j_thick, k) / WaterColumnV(i_thick, j_thick)

                            Me%SubModel%qY  (i, j, k) =                      &
                                Me%SubModel%qY  (i, j, KUB) * RelativeThickness

                        endif

                        if (.not. Me%ComputeOptions%Continuous) then

                            Me%WaterFluxes%Y(i, j, k)               =    &
                                Me%SubModel%qY  (i, j, k)   * DXX_Son(i, j)

                        endif

                    enddo



                endif cd5

            enddo
            enddo

            if (ErrorOccured .and. .not. Me%SubModel%MissingNull)        &
                call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR06") 

        endif cd3

            
cd66:   if ((InitialField .and. .not. Me%ComputeOptions%Continuous) .or. & 
             Me%Relaxation%WaterLevel                               .or. &
             Me%ComputeOptions%BarotropicRadia == FlatherLocalSolution_)  then

            do j = JLB, JUB
            do i = ILB, IUB


                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, KUB)

                else

                    DeadZoneSon = .false.

                endif

                !The test must be done for the water points because the water levels in the corner (no open points) 
                !are used to compute face areas where momentum fluxes are computed.
cd6:            if (Water3DSon(i, j, KUB) == WaterPoint .and. .not. DeadZoneSon) then
                
                    Me%SubModel%Z(i, j)  =                                   &
                            Me%SubModel%Z_Next    (i, j) * TimeCoef  +       &
                            Me%SubModel%Z_Previous(i, j) * (1 - TimeCoef)


                    if (Me%SubModel%Z_Next    (i, j) < FillValueReal / 2. .or.   &
                        Me%SubModel%Z_Previous(i, j) < FillValueReal / 2.) then

                        if (Me%SubModel%MissingNull) then
                            !The cell is considered uncovered if WaterColumn < MinWaterColumn 
                            !if WaterColumn < MinWaterColumn / 2 the model put WaterColumn = MinWaterColumn / 2 (creates water)
                            ! Using WaterColumn = 3/4MinWaterColumn garantes that the cell is uncovered but mass is not created
                            Me%SubModel%Z(i, j)  = - Bathymetry(i, j) + 0.75 * MinWaterColumn 

                        else

                            call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR07") 

                        endif

                    endif

!                    if (InitialField .and. .not. Me%ComputeOptions%Continuous) &
!                        Me%WaterLevel%New(i, j) =                              &
!                            Me%SubModel%Z(i, j)


                endif cd6

            enddo
            enddo

            if (Me%SubModel%MissingNull) then

                 call RemoveLowerSpikes (Me%SubModel%Z, Water3DSon,                     &
                                        Bathymetry, MinWaterColumn,                     &
                                        Me%SubModel%DeadZonePoint, Me%SubModel%DeadZone,&
                                        ILB, IUB, JLB, JUB, KUB) 
            endif

            if (InitialField .and. .not. Me%ComputeOptions%Continuous) &
                Me%WaterLevel%New(:, :) =                              &
                    Me%SubModel%Z(:, :)



        else cd66


            do j = JLB, JUB
            do i = ILB, IUB


                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, KUB)

                else

                    DeadZoneSon = .false.

                endif

                !The test must be done for the water points because the water levels in the corner (no open points) 
                !are used to compute face areas where momentum fluxes are computed.
cd67:           if (Boundary2DSon(i, j) == Boundary .and. Water3DSon(i, j, KUB) == WaterPoint  &
                    .and. .not. DeadZoneSon) then
                
                    Me%SubModel%Z(i, j)  =                                   &
                            Me%SubModel%Z_Next    (i, j) * TimeCoef  +       &
                            Me%SubModel%Z_Previous(i, j) * (1 - TimeCoef)


                    if (Me%SubModel%Z_Next    (i, j) < FillValueReal / 2. .or.   &
                        Me%SubModel%Z_Previous(i, j) < FillValueReal / 2.) then

                        if (Me%SubModel%MissingNull) then
                            !The cell is considered uncovered if WaterColumn < MinWaterColumn 
                            !if WaterColumn < MinWaterColumn / 2 the model put WaterColumn = MinWaterColumn / 2 (creates water)
                            ! Using WaterColumn = 3/4MinWaterColumn garantes that the cell is uncovered but mass is not created
                            Me%SubModel%Z(i, j)  = - Bathymetry(i, j) + 0.75 * MinWaterColumn 

                        else

                            call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR08") 

                        endif

                    endif

                endif cd67

            enddo
            enddo

            if (Me%SubModel%MissingNull)                                                &
                call RemoveLowerSpikes (Me%SubModel%Z, Water3DSon,                      &
                                        Bathymetry, MinWaterColumn,                     &
                                        Me%SubModel%DeadZonePoint, Me%SubModel%DeadZone,&
                                        ILB, IUB, JLB, JUB, KUB, Boundary2DSon) 


        endif cd66



cd8:    if ((InitialField .and. .not. Me%ComputeOptions%Continuous)          .or. & 
             Me%Relaxation%Force .or. Me%Relaxation%Velocity .or. &
             Me%ComputeOptions%BarotropicRadia == FlatherLocalSolution_) then

            do j = JLB, JUB + 1
            do i = ILB, IUB


                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, KUB)

                else

                    DeadZoneSon = .false.

                endif




cd7:            if (Faces3D_USon(i, j, KUB) == Covered  .and. .not. DeadZoneSon) then
                
                    NullValue = .false.

                    if (Me%SubModel%U_Next    (i, j, KUB) < FillValueReal / 2. .or.&
                        Me%SubModel%U_Previous(i, j, KUB) < FillValueReal / 2.)  then


                        if (Me%SubModel%MissingNull) then 
                            NullValue = .true.
                        else
                            call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR09") 
                        endif

                    endif

                    Kbottom = KFloor_U(i, j)

                    do k = Kbottom, KUB

                        if (NullValue) then

                            Me%SubModel%U_New(i, j, k)  =  0.


                        else

                       
                            Me%SubModel%U_New(i, j, k)  =                                  &
                                     Me%SubModel%U_Next    (i, j, KUB) * TimeCoef  +       &
                                     Me%SubModel%U_Previous(i, j, KUB) * (1 - TimeCoef)


                        endif

                        if (InitialField .and. .not. Me%ComputeOptions%Continuous) &
                            Me%Velocity%Horizontal%U%New(i, j, k) = &
                                       Me%SubModel%U_New(i, j, k)


                    enddo

                    NullValue = .false.


                    if (Me%SubModel%DUZ_Next    (i, j, KUB) < FillValueReal / 2. .or.&
                        Me%SubModel%DUZ_Previous(i, j, KUB) < FillValueReal / 2.)    then

                        if (Me%SubModel%MissingNull) then 
                            
                            NullValue = .true.

                        else
                            call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR10") 
                        endif

                    endif


                    Kbottom = KFloor_U(i, j)

                    do k = Kbottom, KUB

                        if (NullValue) then

                            Me%SubModel%DUZ_New(i, j, k)  =  0.


                        else

                            RelativeThickness = DUZ_Son(i, j, k) / WaterColumnU(i, j)


                            Me%SubModel%DUZ_New(i, j, k)  =                                  &
                                    (Me%SubModel%DUZ_Next    (i, j, KUB) * TimeCoef        + &
                                     Me%SubModel%DUZ_Previous(i, j, KUB) * (1 - TimeCoef)) * &
                                     RelativeThickness

                        endif

                    enddo


                endif cd7

            enddo
            enddo
            
        endif cd8


        do j = JLB, JUB + 1
        do i = ILB, IUB

            if (Me%SubModel%DeadZone) then

                DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, KUB)

            else

                DeadZoneSon = .false.

            endif

            
cd77:       if ((ImposedTangFacesUSon(i, j, KUB) == Imposed  .or.                         &
                 ImposedNormFacesUSon(i, j, KUB) == Imposed)  .and. .not. DeadZoneSon) then
                

                if (ImposedTangFacesUSon(i, j, KUB) == Imposed) then

                    i_thick = i
                    j_thick = j

                else if (ImposedNormFacesUSon(i, j, KUB) == Imposed) then

                    i_thick = i

                    if      (j == JUB + 1) then

                        j_thick = j - 1

                    else if (j == JLB) then

                        j_thick = j + 1

                    else

                        j_thick = j + Faces3D_USon(i, j + 1, KUB) - Faces3D_USon(i, j - 1, KUB)

                    endif

                endif

                NullValue = .false.

                if (Me%SubModel%U_Next    (i, j, KUB) < FillValueReal / 2. .or.&
                    Me%SubModel%U_Previous(i, j, KUB) < FillValueReal / 2.)    then

                    if (Me%SubModel%MissingNull) then 

                        NullValue = .true.

                    else

                        call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR11") 

                    endif

                endif

                Kbottom = KFloor_U(i_thick, j_thick)

                do k = Kbottom, KUB

                    if (NullValue) then

                        Me%SubModel%U_New(i, j, k)  = 0.

                    else

                        Me%SubModel%U_New(i, j, k)  =                              &
                                 Me%SubModel%U_Next    (i, j, KUB) * TimeCoef  +   &
                                 Me%SubModel%U_Previous(i, j, KUB) * (1 - TimeCoef)

                    endif

                    if (InitialField .and. .not. Me%ComputeOptions%Continuous) &
                        Me%Velocity%Horizontal%U%New(i, j, k) =                &
                                   Me%SubModel%U_New(i, j, k)


                enddo

                NullValue = .false.

                if (Me%SubModel%DUZ_Next    (i, j, KUB) < FillValueReal / 2. .or.&
                    Me%SubModel%DUZ_Previous(i, j, KUB) < FillValueReal / 2.)    then

                    if (Me%SubModel%MissingNull) then 

                        NullValue = .true.

                    else

                        call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR12") 

                    endif

                endif

                Kbottom = KFloor_U(i_thick, j_thick)

                do k = Kbottom, KUB

                    if (NullValue) then

                        Me%SubModel%DUZ_New(i, j, k) = 0.

                    else

                        RelativeThickness = DUZ_Son(i_thick, j_thick, k) / WaterColumnU(i_thick, j_thick)

                        Me%SubModel%DUZ_New(i, j, k)  =                                  &
                                (Me%SubModel%DUZ_Next    (i, j, KUB) * TimeCoef        + &
                                 Me%SubModel%DUZ_Previous(i, j, KUB) * (1 - TimeCoef)) * &
                                 RelativeThickness

                    endif

                             
                enddo



            endif cd77

        enddo
        enddo


cd10:   if ((InitialField .and. .not. Me%ComputeOptions%Continuous)          .or. & 
             Me%Relaxation%Force .or. Me%Relaxation%Velocity .or. &
             Me%ComputeOptions%BarotropicRadia == FlatherLocalSolution_) then

            do j = JLB, JUB
            do i = ILB, IUB + 1

                if (Me%SubModel%DeadZone) then

                    DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, KUB)

                else

                    DeadZoneSon = .false.

                endif


cd9:            if (Faces3D_VSon(i, j, KUB) == Covered  .and. .not. DeadZoneSon) then

                    NullValue = .false.

                    if (Me%SubModel%V_Next    (i, j, KUB) < FillValueReal / 2. .or.&
                        Me%SubModel%V_Previous(i, j, KUB) < FillValueReal / 2.)  then

                        if (Me%SubModel%MissingNull) then 

                            NullValue = .true.

                        else

                            call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR13") 

                        endif

                    endif


                    Kbottom = KFloor_V(i, j)

                    do k = Kbottom, KUB

                        if (NullValue) then

                            Me%SubModel%V_New(i, j, k)      = 0.

                        else

                            Me%SubModel%V_New(i, j, k)      =                              &
                                     Me%SubModel%V_Next    (i, j, KUB) * TimeCoef        + &
                                     Me%SubModel%V_Previous(i, j, KUB) * (1 - TimeCoef)

                        endif

                        if (InitialField .and. .not. Me%ComputeOptions%Continuous) &
                            Me%Velocity%Horizontal%V%New(i, j, k) =                &
                                       Me%SubModel%V_New(i, j, k)

                    enddo

                    NullValue = .false.


                    if (Me%SubModel%DVZ_Next    (i, j, KUB) < FillValueReal / 2. .or.&
                        Me%SubModel%DVZ_Previous(i, j, KUB) < FillValueReal / 2.)    then

                        if (Me%SubModel%MissingNull) then 
                            NullValue = .true.
                        else
                            call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR14") 
                        endif
                        
                    endif

                    Kbottom = KFloor_V(i, j)

                    do k = Kbottom, KUB

                        if (NullValue) then

                            Me%SubModel%DVZ_New(i, j, k) = 0.

                        else

                            RelativeThickness = DVZ_Son(i, j, k) / WaterColumnV(i, j)


                            Me%SubModel%DVZ_New(i, j, k)  =                                 &
                                    (Me%SubModel%DVZ_Next    (i, j, KUB) * TimeCoef       + &
                                     Me%SubModel%DVZ_Previous(i, j, KUB) * (1 - TimeCoef))* &
                                     RelativeThickness

                        endif


                    enddo


                endif cd9


            enddo
            enddo

        endif cd10


        do j = JLB, JUB
        do i = ILB, IUB + 1

            if (Me%SubModel%DeadZone) then

                DeadZoneSon = Me%SubModel%DeadZonePoint(i, j, KUB)

            else

                DeadZoneSon = .false.

            endif



cd99:       if ((ImposedTangFacesVSon(i, j, KUB) == Imposed  .or.                           &
                 ImposedNormFacesVSon(i, j, KUB) == Imposed) .and. .not. DeadZoneSon) then

                if (ImposedTangFacesVSon(i, j, KUB) == Imposed) then

                    i_thick = i
                    j_thick = j

                else if (ImposedNormFacesVSon(i, j, KUB) == Imposed) then

                    if      (i == IUB + 1) then

                        i_thick = i - 1

                    else if (i == ILB) then

                        i_thick = i + 1

                    else

                        i_thick = i + Faces3D_VSon(i + 1, j, KUB) - Faces3D_VSon(i - 1, j, KUB)

                    endif

                    j_thick = j 

                endif

                NullValue = .false.

                if (Me%SubModel%V_Next    (i, j, KUB) < FillValueReal / 2. .or.&
                    Me%SubModel%V_Previous(i, j, KUB) < FillValueReal / 2.)  then

                    if (Me%SubModel%MissingNull) then 
                        NullValue = .true.
                    else
                        call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR15") 
                    endif

                endif

                Kbottom = KFloor_V(i_thick, j_thick)

                do k = Kbottom, KUB

                    if (NullValue) then

                        Me%SubModel%V_New(i, j, k)      = 0.

                    else

                        Me%SubModel%V_New(i, j, k)      =                              &
                                 Me%SubModel%V_Next    (i, j, KUB) * TimeCoef        + &
                                 Me%SubModel%V_Previous(i, j, KUB) * (1 - TimeCoef)

                    endif

                    if (InitialField .and. .not. Me%ComputeOptions%Continuous) &
                        Me%Velocity%Horizontal%V%New(i, j, k) =                &
                                   Me%SubModel%V_New(i, j, k)


                enddo

                NullValue = .false.


                if (Me%SubModel%DVZ_Next    (i, j, KUB) < FillValueReal / 2. .or.&
                    Me%SubModel%DVZ_Previous(i, j, KUB) < FillValueReal / 2.) then

                    if (Me%SubModel%MissingNull) then 
                        NullValue = .true.
                    else
                        call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR16") 
                    endif

                endif


                Kbottom = KFloor_V(i_thick, j_thick)

                do k = Kbottom, KUB

                    if (NullValue) then

                        Me%SubModel%DVZ_New(i, j, k)  = 0.

                    else


                        RelativeThickness = DVZ_Son(i_thick, j_thick, k) / WaterColumnV(i_thick, j_thick)


                        Me%SubModel%DVZ_New(i, j, k)  =                                  &
                                (Me%SubModel%DVZ_Next    (i, j, KUB) * TimeCoef        + &
                                 Me%SubModel%DVZ_Previous(i, j, KUB) * (1 - TimeCoef)) * &
                                RelativeThickness

                    endif

                enddo
                        
            endif cd99

        enddo
        enddo


        !Tihs is only done for graphical reasons
        if (InitialField .and. .not. Me%ComputeOptions%Continuous) then

            !U corners            
            Me%Velocity%Horizontal%U%New(ILB,JLB    , KLB:KUB)   =       &
            Me%SubModel%U_New           (ILB,JLB    ,     KUB)

            Me%Velocity%Horizontal%U%New(ILB,JUB + 1, KLB:KUB)   =       &
            Me%SubModel%U_New           (ILB,JUB + 1,     KUB)

            Me%Velocity%Horizontal%U%New(IUB,JLB    , KLB:KUB)   =       &
            Me%SubModel%U_New           (IUB,JLB    ,     KUB)

            Me%Velocity%Horizontal%U%New(IUB,JUB + 1, KLB:KUB)   =       &
            Me%SubModel%U_New           (IUB,JUB + 1,     KUB)

            
            !V corners
            Me%Velocity%Horizontal%V%New(ILB,JLB    , KLB:KUB)   =       &
            Me%SubModel%V_New           (ILB,JLB    ,     KUB)

            Me%Velocity%Horizontal%V%New(ILB,JUB    , KLB:KUB)   =       &
            Me%SubModel%V_New           (ILB,JUB    ,     KUB)

            Me%Velocity%Horizontal%V%New(IUB + 1,JLB, KLB:KUB)   =       &
            Me%SubModel%V_New           (IUB + 1,JLB,     KUB)

            Me%Velocity%Horizontal%V%New(IUB + 1,JUB, KLB:KUB)   =       &
            Me%SubModel%V_New           (IUB + 1,JUB,     KUB)

        endif



        Me%SubModel%Set      = .true.

        !UnGet son information 
        call ReadUnLockSon(ImposedTangFacesUSon, ImposedTangFacesVSon,               &
                           ImposedNormFacesUSon, ImposedNormFacesVSon,               &
                           Water3DSon, Boundary2DSon,                                 &
                           Faces3D_USon, Faces3D_VSon,                               &
                           DUZ_Son, DVZ_Son,                                         &
                           DXX_Son, DYY_Son)

cd11:   if (InitialField .and. .not. Me%ComputeOptions%Continuous) then

            Me%WaterLevel%Old               (:,:  ) =                &
                Me%WaterLevel%New           (:,:  )

            Me%Velocity%Horizontal%V%Old    (:,:,:) =                &
                Me%Velocity%Horizontal%V%New(:,:,:)

            Me%Velocity%Horizontal%U%Old    (:,:,:) =                &
                Me%Velocity%Horizontal%U%New(:,:,:)

            Me%SubModel%DUZ_Old(:,:,:)              =                &
                Me%SubModel%DUZ_Next(:,:,:)


            Me%SubModel%DVZ_Old(:,:,:)              =                &
                Me%SubModel%DVZ_Next(:,:,:)

        endif cd11


        call UnGetGeometry(Me%ObjGeometry,                               &
                           WaterColumnU, STAT = status)

        if (status /= SUCCESS_)                                                          &
                call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR17") 


        call UnGetGeometry(Me%ObjGeometry,                               &
                           WaterColumnV, STAT = status)

        if (status /= SUCCESS_)                                                          &
                call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR18") 


        call UnGetGeometry(Me%ObjGeometry,                               &
                           KFloor_U, STAT = status)

        if (status /= SUCCESS_)                                                          &
                call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR19") 


        call UnGetGeometry(Me%ObjGeometry,                               &
                           KFloor_V, STAT = status)

        if (status /= SUCCESS_)                                                          &
                call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR20") 


       !UnGets Bathymetry
        call UnGetGridData(Me%ObjGridData, Bathymetry, STAT = status)

        if (status /= SUCCESS_)                                                          &
                call SetError(FATAL_, INTERNAL_, "ActualizeSon3DWithFather2D; Hydrodynamic. ERR21") 


    end subroutine ActualizeSon3DWithFather2D

    !--------------------------------------------------------------------------

    subroutine RemoveLowerSpikes (Values2D, WaterPoints, Bathymetry, MinWaterColumn,   &
                                  DeadZonePoints, DeadZoneON, ILB, IUB, JLB, JUB, KUB, &
                                  BoundaryPoints) 

    !Arguments-----------------------------------------------------------------
    real,    dimension(:,:  ), pointer            :: Values2D, Bathymetry
    integer, dimension(:,:,:), pointer            :: WaterPoints
    logical, dimension(:,:,:), pointer            :: DeadZonePoints
    integer, dimension(:,:  ), pointer, optional  :: BoundaryPoints
    real                                          :: MinWaterColumn
    integer                                       :: ILB, IUB, JLB, JUB, KUB
    logical                                       :: DeadZoneON
    !Local---------------------------------------------------------------------
    integer                                       :: i, j, Counter, ComputePoint
    real                                          :: Average, Deviation, Dif
    logical                                       :: BoundaryON
    !Begin---------------------------------------------------------------------

        if (present(BoundaryPoints)) then
            BoundaryON = .true.
        else
            BoundaryON = .false.
        endif

        Average   = 0.
        Deviation = 0.
        Counter   = 0
        !Compute Averages
        do j= JLB, JUB
        do i= ILB, IUB

            ComputePoint = WaterPoints(i,j,KUB)
            if (BoundaryON) ComputePoint = ComputePoint * BoundaryPoints(i, j)
            if (DeadZoneON) then
                if (DeadZonePoints(i, j, KUB)) ComputePoint = 0
            endif
            !The uncovered points are not use to compute the average and the standard deviation
            if (Values2D(i, j) < -Bathymetry(i,j) + MinWaterColumn) &
                ComputePoint = 0

            if (ComputePoint == 1) then
                Counter = Counter + 1
                Average = Average + Values2D(i, j)

            endif

        enddo
        enddo

        Average = Average / real (Counter)

        !Standard Deviation
        do j= JLB, JUB
        do i= ILB, IUB

            ComputePoint = WaterPoints(i,j,KUB)
            if (BoundaryON) ComputePoint = ComputePoint * BoundaryPoints(i, j)
            if (DeadZoneON) then
                if (DeadZonePoints(i, j, KUB)) ComputePoint = 0
            endif

            !The uncovered points are not use to compute the average and the standard deviation
            if (Values2D(i, j) < -Bathymetry(i,j) + MinWaterColumn) &
                ComputePoint = 0

            if (ComputePoint == 1) then
           
                Deviation = Deviation + abs(Values2D(i, j) - Average)

            endif

        enddo
        enddo

        Deviation = Deviation / real (Counter)


        !Remove lower Spikes
        do j= JLB, JUB
        do i= ILB, IUB

            ComputePoint = WaterPoints(i,j,KUB)
            if (BoundaryON) ComputePoint = ComputePoint * BoundaryPoints(i, j)
            if (DeadZoneON) then
                if (DeadZonePoints(i, j, KUB)) ComputePoint = 0
            endif

            if (ComputePoint == 1) then

                Dif = Values2D(i, j) - Average

                if (Dif < 0 .and. abs(Dif) > 100. * Deviation) Values2D(i, j) = Average

            endif

        enddo
        enddo



    end subroutine RemoveLowerSpikes

    !--------------------------------------------------------------------------

    subroutine ReadNextOrInitialField (UFather, VFather, DUZFather, DVZFather,           &
                                       FluxXFather, FluxYFather, ZFather, Open3DFather,  &
                                       Faces3D_UFather, Faces3D_VFather, InitialField,   &
                                       KLBFather, KUBFather, FatherHorizontalGrid)

        !Arguments-------------------------------------------------------------
        real,    dimension(:,:,:), pointer          :: UFather, VFather, DUZFather, DVZFather
        real(8), dimension(:,:,:), pointer          :: FluxXFather, FluxYFather
        real,    dimension(:,:  ), pointer          :: ZFather
        integer, dimension(:,:,:), pointer          :: Open3DFather     
        integer, dimension(:,:,:), pointer          :: Faces3D_UFather    
        integer, dimension(:,:,:), pointer          :: Faces3D_VFather  
        logical,           intent(IN )              :: InitialField
        integer                                     :: KLBFather, KUBFather
        integer                                     :: FatherHorizontalGrid

        !Local-----------------------------------------------------------------
        integer                                     :: ComputeZ, ComputeU, ComputeV
        integer                                     :: status, KLBSon, KUBSon
        
        !----------------------------------------------------------------------


        KUBSon = Me%WorkSize%KUB
        KLBSon = Me%WorkSize%KLB

        call GetComputeZUV(Me%ObjHorizontalGrid, ComputeZ, ComputeU, ComputeV, STAT = status)
        if (status /= SUCCESS_) call SetError(FATAL_, INTERNAL_, "ReadNextOrInitialField; Hydrodynamic. ERR01") 

cd1:    if (Me%SubModel%InterPolTime .and. .not. InitialField) then

            Me%SubModel%Z_Previous  (:,:  ) = Me%SubModel%Z_Next  (:,:)
            Me%SubModel%U_Previous  (:,:,:) = Me%SubModel%U_Next  (:,:,:)
            Me%SubModel%V_Previous  (:,:,:) = Me%SubModel%V_Next  (:,:,:)
            Me%SubModel%DUZ_Previous(:,:,:) = Me%SubModel%DUZ_Next(:,:,:)
            Me%SubModel%DVZ_Previous(:,:,:) = Me%SubModel%DVZ_Next(:,:,:)

        endif cd1

        call InterpolRegularGrid   (Me%ObjHorizontalGrid,                                &
                                    FatherHorizontalGrid,                                &
                                    ZFather, Me%SubModel%Z_Next,                         &
                                    ComputeFather = Open3DFather,                        &
                                    Compute       = ComputeZ,                            &
                                    KUBFather     = KUBFather,                           &
                                    STAT          = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadNextOrInitialField; Hydrodynamic. ERR02") 

        if (InitialField  .and. .not. Me%ComputeOptions%Continuous)      &
            call Initial_Geometry(Me%SubModel%Z_Next)

            !The geometry is construct using the filed interpolated from the Father Water Level
            !The Mapping is also actualized by this subroutine
cd2:    if (InitialField) then  !.and. .not. Me%ComputeOptions%Continuous) then

            call InterpolRegularGrid   (Me%ObjHorizontalGrid,                            &
                                        FatherHorizontalGrid,                            &
                                        FluxXFather, Me%SubModel%qX,                     &
                                        Faces3D_UFather, ComputeU,                       &
                                        KLBFather, KUBFather, KUBSon,                    &
                                        FluxType = .true., STAT = status)
            if (status /= SUCCESS_)                                                      &
                call SetError(FATAL_, INTERNAL_, "ReadNextOrInitialField; Hydrodynamic. ERR03") 


            call InterpolRegularGrid   (Me%ObjHorizontalGrid,                            &
                                        FatherHorizontalGrid,                            &
                                        FluxYFather, Me%SubModel%qY,                     &
                                        Faces3D_VFather, ComputeV,                       &
                                        KLBFather, KUBFather, KUBSon,                    &
                                        FluxType = .true., STAT = status)

            if (status /= SUCCESS_)                                                      &
                call SetError(FATAL_, INTERNAL_, "ReadNextOrInitialField; Hydrodynamic. ERR04") 



            
        endif cd2
        
        call InterpolRegularGrid   (Me%ObjHorizontalGrid,                                &
                                    FatherHorizontalGrid,                                &
                                    UFather, Me%SubModel%U_Next,                         &
                                    Faces3D_UFather, ComputeU,                           &
                                    KLBFather, KUBFather, KUBSon,                        &
                                    STAT = status)
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadNextOrInitialField; Hydrodynamic. ERR05") 

        call InterpolRegularGrid   (Me%ObjHorizontalGrid,                                &
                                    FatherHorizontalGrid,                                &
                                    DUZFather, Me%SubModel%DUZ_Next,                     &
                                    Faces3D_UFather, ComputeU,                           &
                                    KLBFather, KUBFather, KUBSon,                        &
                                    STAT = status)
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadNextOrInitialField; Hydrodynamic. ERR06") 

        call InterpolRegularGrid   (Me%ObjHorizontalGrid,                                &
                                    FatherHorizontalGrid,                                &
                                    VFather, Me%SubModel%V_Next,                         &
                                    Faces3D_VFather, ComputeV,                           &
                                    KLBFather, KUBFather, KUBSon,                        &
                                    STAT = status)
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadNextOrInitialField; Hydrodynamic. ERR07") 

        call InterpolRegularGrid   (Me%ObjHorizontalGrid,                                &
                                    FatherHorizontalGrid,                                &
                                    DVZFather, Me%SubModel%DVZ_Next,                     &   
                                    Faces3D_VFather, ComputeV,                           &
                                    KLBFather, KUBFather, KUBSon,                        &
                                    STAT = status)
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadNextOrInitialField; Hydrodynamic. ERR08") 

cd12:   if (Me%SubModel%InterPolTime .and. InitialField) then

            Me%SubModel%Z_Previous  (:,:  ) = Me%SubModel%Z_Next  (:,:)
            Me%SubModel%U_Previous  (:,:,:) = Me%SubModel%U_Next  (:,:,:)
            Me%SubModel%V_Previous  (:,:,:) = Me%SubModel%V_Next  (:,:,:)
            Me%SubModel%DUZ_Previous(:,:,:) = Me%SubModel%DUZ_Next(:,:,:)
            Me%SubModel%DVZ_Previous(:,:,:) = Me%SubModel%DVZ_Next(:,:,:)

        endif cd12


    end subroutine ReadNextOrInitialField 

    !--------------------------------------------------------------------------


    subroutine ReadLockFather(ObjHydrodynamicFather,                                     &
                              FluxXFather, FluxYFather,                                  &
                              Open3DFather, Faces3D_UFather, Faces3D_VFather,            &
                              UFather, VFather, ZFather, DUZFather, DVZFather)

        !Arguments-------------------------------------------------------------
        type(T_Hydrodynamic),   pointer    :: ObjHydrodynamicFather
        real,    dimension(:,:,:), pointer :: UFather, VFather, DUZFather, DVZFather
        real(8), dimension(:,:,:), pointer :: FluxXFather, FluxYFather
        real,    dimension(:,:  ), pointer :: ZFather
        integer, dimension(:,:,:), pointer :: Open3DFather
        integer, dimension(:,:,:), pointer :: Faces3D_UFather
        integer, dimension(:,:,:), pointer :: Faces3D_VFather
   

        !Local---------------------------------------------------------------------
        integer :: status 


        !----------------------------------------------------------------------

        call GetOpenPoints3D(ObjHydrodynamicFather%ObjMap, Open3DFather, STAT = status)
        if (status /= SUCCESS_) call SetError(FATAL_, INTERNAL_, "ReadLockFather; Hydrodynamic. ERR02") 

        call GetComputeFaces3D(ObjHydrodynamicFather%ObjMap,                             &
                               ComputeFacesU3D = Faces3D_UFather,                        &
                               ComputeFacesV3D = Faces3D_VFather,                        &
                               STAT= status)
        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadLockFather; Hydrodynamic. ERR03") 

        call GetGeometryDistances(ObjHydrodynamicFather%ObjGeometry, DUZ =  DUZFather,   &
                                  DVZ =  DVZFather, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadLockFather; Hydrodynamic. ERR07") 

        UFather     => ObjHydrodynamicFather%Velocity%Horizontal%U%New
        VFather     => ObjHydrodynamicFather%Velocity%Horizontal%V%New
        ZFather     => ObjHydrodynamicFather%WaterLevel%New
        FluxXFather => ObjHydrodynamicFather%WaterFluxes%X
        FluxYFather => ObjHydrodynamicFather%WaterFluxes%Y


    end subroutine ReadLockFather

    !--------------------------------------------------------------------------

    !--------------------------------------------------------------------------

    subroutine ReadUnLockFather(ObjHydrodynamicFather,                                   &
                                FluxXFather, FluxYFather,                                &
                                Open3DFather, Faces3D_UFather, Faces3D_VFather,          &
                                UFather, VFather, ZFather, DUZFather, DVZFather)

        !Arguments-------------------------------------------------------------
        type(T_Hydrodynamic),   pointer    :: ObjHydrodynamicFather
        real,    dimension(:,:,:), pointer :: UFather, VFather, DUZFather, DVZFather
        real(8), dimension(:,:,:), pointer :: FluxXFather, FluxYFather
        real,    dimension(:,:  ), pointer :: ZFather
        integer, dimension(:,:,:), pointer :: Open3DFather
        integer, dimension(:,:,:), pointer :: Faces3D_UFather
        integer, dimension(:,:,:), pointer :: Faces3D_VFather
   

        !Local---------------------------------------------------------------------
        integer :: status 

   

        !----------------------------------------------------------------------

        call UnGetGeometry(ObjHydrodynamicFather%ObjGeometry, DUZFather, STAT = status)
        if (status /= SUCCESS_) stop "ReadUnLockFather - Hydrodynamic - ERR01"

        call UnGetGeometry(ObjHydrodynamicFather%ObjGeometry, DVZFather, STAT = status)
        if (status /= SUCCESS_) stop "ReadUnLockFather - Hydrodynamic - ERR02"

        call UnGetMap(ObjHydrodynamicFather%ObjMap, Open3DFather, STAT = status)
        if (status /= SUCCESS_) stop "ReadUnLockFather - Hydrodynamic - ERR03"

        call UnGetMap(ObjHydrodynamicFather%ObjMap, Faces3D_UFather, STAT = status)
        if (status /= SUCCESS_) stop "ReadUnLockFather - Hydrodynamic - ERR04"

        call UnGetMap(ObjHydrodynamicFather%ObjMap, Faces3D_VFather, STAT = status)
        if (status /= SUCCESS_) stop "ReadUnLockFather - Hydrodynamic - ERR05"

        nullify(UFather)
        nullify(VFather)
        nullify(ZFather)
        nullify(FluxXFather)
        nullify(FluxYFather)

    end subroutine ReadUnLockFather

    !--------------------------------------------------------------------------

    subroutine ReadLockSon(ImposedTangFacesUSon, ImposedTangFacesVSon,                   &
                           ImposedNormFacesUSon, ImposedNormFacesVSon,                   &
                           Water3DSon, Boundary2DSon,                                     &
                           Faces3D_USon, Faces3D_VSon,                                   &
                           DUZ_Son, DVZ_Son,                                             &
                           DXX_Son, DYY_Son)

        !Arguments-------------------------------------------------------------
        integer, dimension(:,:  ), pointer :: Boundary2DSon
        integer, dimension(:,:,:), pointer :: ImposedTangFacesUSon, ImposedTangFacesVSon
        integer, dimension(:,:,:), pointer :: ImposedNormFacesUSon, ImposedNormFacesVSon
        integer, dimension(:,:,:), pointer :: Water3DSon
        integer, dimension(:,:,:), pointer :: Faces3D_USon, Faces3D_VSon
        real   , dimension(:,:,:), pointer :: DUZ_Son, DVZ_Son
        real,    dimension(:,:  ), pointer :: DXX_Son, DYY_Son
   

        !Local---------------------------------------------------------------------
        integer                             :: status 


        !Module Horizontal Grid
        call GetHorizontalGrid(Me%ObjHorizontalGrid, DXX = DXX_Son, DYY = DYY_Son,       &
                               STAT = status)
        if (status /= SUCCESS_) stop "ReadLockSon - Hydrodynamic - ERR01"

        !Module - ModuleHorizontalMap
        call GetImposedTangentialFaces(Me%ObjMap, ImposedTangFacesUSon,                  &
                                       ImposedTangFacesVSon, STAT = status)      
        if (status /= SUCCESS_) stop "ReadLockSon - Hydrodynamic - ERR02"

        call GetImposedNormalFaces(Me%ObjMap, ImposedNormFacesUSon, ImposedNormFacesVSon,&
                                   STAT = status)      
        if (status /= SUCCESS_) stop "ReadLockSon - Hydrodynamic - ERR03"


        call GetGeometryDistances(Me%ObjGeometry, DUZ =  DUZ_Son, DVZ =  DVZ_Son,        &
                                  STAT = status)
        if (status /= SUCCESS_) stop "ReadLockSon - Hydrodynamic - ERR04"

        call GetWaterPoints3D(Me%ObjMap, Water3DSon, STAT = status)
        if (status /= SUCCESS_) stop "ReadLockSon - Hydrodynamic - ERR05"

        call GetBoundaries(Me%ObjHorizontalMap, Boundary2DSon, STAT = status)
        if (status /= SUCCESS_) stop "ReadLockSon - Hydrodynamic - ERR06"

        call GetComputeFaces3D(Me%ObjMap,                                                &
                               ComputeFacesU3D = Faces3D_USon,                           &
                               ComputeFacesV3D = Faces3D_VSon,                           & 
                               STAT= status)
        if (status /= SUCCESS_) stop "ReadLockSon - Hydrodynamic - ERR07"

    end subroutine ReadLockSon

    !--------------------------------------------------------------------------

    subroutine ReadUnLockSon(ImposedTangFacesUSon, ImposedTangFacesVSon,                 &
                             ImposedNormFacesUSon, ImposedNormFacesVSon,                 &
                             Water3DSon, Boundary2DSon,                                   &
                             Faces3D_USon, Faces3D_VSon,                                 &
                             DUZ_Son, DVZ_Son,                                           &
                             DXX_Son, DYY_Son)

        !Arguments-------------------------------------------------------------
        integer, dimension(:,:  ), pointer :: Boundary2DSon
        integer, dimension(:,:,:), pointer :: ImposedTangFacesUSon, ImposedTangFacesVSon
        integer, dimension(:,:,:), pointer :: ImposedNormFacesUSon, ImposedNormFacesVSon
        integer, dimension(:,:,:), pointer :: Water3DSon
        integer, dimension(:,:,:), pointer :: Faces3D_USon, Faces3D_VSon
        real   , dimension(:,:,:), pointer :: DUZ_Son, DVZ_Son
        real,    dimension(:,:  ), pointer :: DXX_Son, DYY_Son
  

        !Local---------------------------------------------------------------------
        integer :: status 
        !----------------------------------------------------------------------

        !Get son information

        call UnGetMap(Me%ObjMap, ImposedTangFacesUSon, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR01") 


        call UnGetMap(Me%ObjMap, ImposedTangFacesVSon, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR02") 


        call UnGetMap(Me%ObjMap, ImposedNormFacesUSon, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR03") 


        call UnGetMap(Me%ObjMap, ImposedNormFacesVSon, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR04") 


        call UnGetGeometry(Me%ObjGeometry, DUZ_Son, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR07") 


        call UnGetGeometry(Me%ObjGeometry, DVZ_Son, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR08") 



        call UnGetMap(Me%ObjMap, Water3DSon, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR09") 

        call UnGetHorizontalMap(Me%ObjHorizontalMap, Boundary2DSon, STAT = STATUS)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR09a") 

        call UnGetMap(Me%ObjMap, Faces3D_USon, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR10") 

        call UnGetMap(Me%ObjMap, Faces3D_VSon, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR11") 


        call UnGetHorizontalGrid(Me%ObjHorizontalGrid, DXX_Son, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR12") 

        call UnGetHorizontalGrid(Me%ObjHorizontalGrid,                   &
                                 DYY_Son, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ReadUnLockSon; Hydrodynamic. ERR13") 


    end subroutine ReadUnLockSon

    !--------------------------------------------------------------------------

    subroutine ConstructTimeInterpolation(FatherKLB, FatherKUB, DT_Father)

        !Arguments-------------------------------------------------------------
        integer                                     :: FatherKLB, FatherKUB 
        real                                        :: DT_Father

        !Local---------------------------------------------------------------------
        real                                        :: DT_Son, Aux1, Aux2
        integer                                     :: status 
        integer                                     :: ILB, IUB, JLB, JUB, KLB, KUB 
        integer                                     :: FatherLayers, SonLayers

        !----------------------------------------------------------------------
     
        !Begin - Shorten variables name 

        IUB       = Me%Size%IUB
        ILB       = Me%Size%ILB
        JUB       = Me%Size%JUB
        JLB       = Me%Size%JLB
        KUB       = Me%Size%KUB
        KLB       = Me%Size%KLB


        FatherLayers = FatherKUB       - FatherKLB       + 1
        SonLayers    = Me%WorkSize%KUB - Me%WorkSize%KLB + 1

        call GetComputeTimeStep(Me%ObjTime, DT_Son, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "ConstructTimeInterpolation; Hydrodynamic. ERR02") 

cd1:    if      (DT_Son <  DT_Father) then
        
            Aux1 = DT_Father / DT_Son
            Aux2 = real(int (Aux1))

            if (Aux1 /= Aux2)                                                            &
                call SetError(FATAL_, INTERNAL_, "ConstructTimeInterpolation; Hydrodynamic. ERR03") 


            Me%SubModel%InterpolTime  = .true.

        else if (DT_Son == DT_Father) then cd1

            Me%SubModel%InterpolTime  = .false.

        else  cd1

            call SetError(FATAL_, INTERNAL_, "ConstructTimeInterpolation; Hydrodynamic. ERR04") 

        endif cd1

        call Null_Time(Me%SubModel%PreviousTime)
        Me%SubModel%NextTime = Me%BeginTime


        if      ((FatherLayers == 1) .and. (SonLayers >  1)) then

            Me%SubModel%VertComunic = Father2DSon3D    

        else if ((FatherLayers >  1) .and. (SonLayers == 1)) then


            Me%SubModel%VertComunic = Father3DSon2D    

            call SetError (FATAL_, INTERNAL_, "ConstructTimeInterpolation - Hydrodynamic - ERR15")

        else if (FatherLayers         ==  SonLayers) then


            Me%SubModel%VertComunic = FatherSonEqualDim

        else

            Me%SubModel%VertComunic = FatherSonDifDim

            call SetError (FATAL_, INTERNAL_, "ConstructTimeInterpolation - Hydrodynamic - ERR16")

        endif




cd2:    if (Me%SubModel%InterpolTime) then

            allocate (Me%SubModel%Z_Previous(ILB:IUB, JLB:JUB), STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                      &
                call SetError (FATAL_, OUT_OF_MEM_, "ConstructTimeInterpolation - Hydrodynamic - ERR05")

            Me%SubModel%Z_Previous (:,:  ) = FillValueReal

            allocate (Me%SubModel%Z_Next(ILB:IUB, JLB:JUB), STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                      &
                call SetError (FATAL_, OUT_OF_MEM_, "ConstructTimeInterpolation - Hydrodynamic - ERR06")

            Me%SubModel%Z_Next (:,:  ) = FillValueReal

            allocate (Me%SubModel%U_Previous(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                      &
                call SetError (FATAL_, OUT_OF_MEM_, "ConstructTimeInterpolation - Hydrodynamic - ERR07")

            Me%SubModel%U_Previous  (:,:,:) = FillValueReal

            allocate (Me%SubModel%U_Next(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                      &
                call SetError (FATAL_, OUT_OF_MEM_, "ConstructTimeInterpolation - Hydrodynamic - ERR08")

            Me%SubModel%U_Next      (:,:,:) = FillValueReal


            allocate (Me%SubModel%V_Previous(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                      &
                call SetError (FATAL_, OUT_OF_MEM_, "ConstructTimeInterpolation - Hydrodynamic - ERR09")

            Me%SubModel%V_Previous  (:,:,:) = FillValueReal

            allocate (Me%SubModel%V_Next    (ILB:IUB, JLB:JUB, KLB:KUB), STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                      &
                call SetError (FATAL_, OUT_OF_MEM_, "ConstructTimeInterpolation - Hydrodynamic - ERR10")

            Me%SubModel%V_Next      (:,:,:) = FillValueReal


            allocate (Me%SubModel%DUZ_Previous(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                      &
                call SetError (FATAL_, OUT_OF_MEM_, "ConstructTimeInterpolation - Hydrodynamic - ERR11")

            Me%SubModel%DUZ_Previous  (:,:,:) = FillValueReal

            allocate (Me%SubModel%DUZ_Next(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                      &
                call SetError (FATAL_, OUT_OF_MEM_, "ConstructTimeInterpolation - Hydrodynamic - ERR12")

            Me%SubModel%DUZ_Next      (:,:,:) = FillValueReal


            allocate (Me%SubModel%DVZ_Previous(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                      &
                call SetError (FATAL_, OUT_OF_MEM_, "ConstructTimeInterpolation - Hydrodynamic - ERR13")

            Me%SubModel%DVZ_Previous  (:,:,:) = FillValueReal

            allocate (Me%SubModel%DVZ_Next    (ILB:IUB, JLB:JUB, KLB:KUB), STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                      &
                call SetError (FATAL_, OUT_OF_MEM_, "ConstructTimeInterpolation - Hydrodynamic - ERR14")

            Me%SubModel%DVZ_Next      (:,:,:) = FillValueReal

        else

            Me%SubModel%Z_Previous   => Me%SubModel%Z
            Me%SubModel%Z_Next       => Me%SubModel%Z

            Me%SubModel%U_Previous   => Me%SubModel%U_New
            Me%SubModel%U_Next       => Me%SubModel%U_New

            Me%SubModel%V_Previous   => Me%SubModel%V_New
            Me%SubModel%V_Next       => Me%SubModel%V_New

            Me%SubModel%DUZ_Previous => Me%SubModel%DUZ_New
            Me%SubModel%DUZ_Next     => Me%SubModel%DUZ_New

            Me%SubModel%DVZ_Previous => Me%SubModel%DVZ_New
            Me%SubModel%DVZ_Next     => Me%SubModel%DVZ_New

        endif cd2


    end subroutine ConstructTimeInterpolation


    Subroutine Actualises_Hydrodynamic


        !Arguments-------------------------------------------------------------------
        

        !Local 
        integer :: Num_Discretization, Previous_Direction

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Actualises_Hydrodynamic")

        !Update the moving boundary  (boundary of the tidal areas covered)
!        call UpdateComputeFaces3D(Me%ObjMap,                                &
!                                  Me%WaterLevel%New,                        &
!                                  Me%CurrentTime, STAT = STAT_CALL)      

!        if (STAT_CALL /= SUCCESS_)                                                       &
!            stop 'Actualises_Hydrodynamic; ModuleHydrodynamic. ERR01.'

        
        Me%WaterLevel%Old (:,:) = Me%WaterLevel%New(:,:)

        Num_Discretization = Me%ComputeOptions%Num_Discretization


cd2:    if (Num_Discretization == Abbott) then
            
            Previous_Direction = Me%Direction%XY
        
cd3:        if (Previous_Direction == DirectionY_) then

                Me%Velocity%Horizontal%U%Old(:,:,:) =                       &
                Me%Velocity%Horizontal%U%New(:,:,:)

                if (Me%SubModel%ON)                                         &
                    Me%SubModel%U_Old(:,:,:) =                              &
                    Me%SubModel%U_New(:,:,:)


            elseif (Previous_Direction == DirectionX_) then cd3

                Me%Velocity%Horizontal%V%Old(:,:,:) =                       &
                Me%Velocity%Horizontal%V%New(:,:,:)

                if (Me%SubModel%ON)                                         &
                    Me%SubModel%V_Old(:,:,:) =                              &
                    Me%SubModel%V_New(:,:,:)


            else

                Stop 'Sub. Actualises_Hydrodynamic - ModuleHydrodynamic - Err02.'

            endif cd3


        else if (Num_Discretization == Leendertse) then cd2

            Me%Velocity%Horizontal%U%Old(:,:,:) =                           &
            Me%Velocity%Horizontal%U%New(:,:,:)

            Me%Velocity%Horizontal%V%Old(:,:,:) =                           & 
            Me%Velocity%Horizontal%V%New(:,:,:)

            if (Me%SubModel%ON)   then

                Me%SubModel%U_Old(:,:,:) =                                  &
                Me%SubModel%U_New(:,:,:)

                Me%SubModel%V_Old(:,:,:) =                                  &
                Me%SubModel%V_New(:,:,:)

            endif


        else cd2

            Stop 'Sub. Actualises_Hydrodynamic - ModuleHydrodynamic - Err03.'

        endif cd2

        !NonHydrostatic
        if (Me%NonHydrostatic%ON) then

            Me%Velocity%Vertical%CartesianOld (:, :, :) =                   &
                Me%Velocity%Vertical%Cartesian(:,:,:)        

        endif

        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Actualises_Hydrodynamic")

    End Subroutine Actualises_Hydrodynamic


    !End------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Geometry, Mapping                                                            !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine One_Iteration 


        !Arguments-------------------------------------------------------------------
        


        !Local----------------------------------------------------------------------
        integer                                     :: Evolution
        logical, save                               :: FirstIteration = .true.
         

        !Begin----------------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "One_Iteration")


        call Actualize_HydrodynamicTimeStep 

        !Initialize bottom boundary (Chezy coefficient is computed for the first time)
        if (FirstIteration) then
            FirstIteration = .false.
            call Bottom_Boundary
        endif


        Evolution = Me%ComputeOptions%Evolution

cd1:    if (Evolution == Solve_Equations_) then 

            call MomentumMassConservation 

        else if (Evolution == Read_File_) then  cd1

            call ReadHydrodynamicFile 

            call Bottom_Boundary 

        else if (Evolution == No_hydrodynamic_ .or. Evolution == Residual_hydrodynamic_) then cd1

            !Don't make any hydrodynamic actualization
            !Update only the Geometry because the water properties evolution 
            !verifies always if the geometry is actualized 
            call New_Geometry

            call Bottom_Boundary 

        else if (Evolution == ImposedSolution_) then cd1

            call ReadImposedSolution

            call Modify_HorizontalWaterFlow
            
            call ChangeDirection    

            call Modify_HorizontalWaterFlow

            !Update only the Geometry because the water properties evolution 
            !verifies always if the geometry is actualized 
            call New_Geometry

            call Bottom_Boundary

        else if (Evolution == Vertical1D_) then cd1
            
        !Guillaume
            call AssociateDirectionX
            call Bottom_Boundary
            call Explicit_Forces    
            call Compute_Velocity       
            call AssociateDirectionY 
            call Bottom_Boundary
            call Explicit_Forces    
            call Compute_Velocity

        else cd1 
            
            Stop 'Sub. One_Iteration - ModuleHydrodynamic - Err04'
                    
        endif cd1


        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "One_Iteration")

    End Subroutine One_Iteration

    !End------------------------------------------------------------
   
    Subroutine ReadImposedSolution

        !Arguments-------------------------------------------------------------------
        


        !Local----------------------------------------------------------------------
        real,    dimension(:,:,:), pointer          :: Matrix3D
        integer, dimension(:,:,:), pointer          :: PointsToFill3D
        integer                                     :: STAT_CALL, i, j, k
        logical                                     :: RotateX, RotateY
        
        !Begin----------------------------------------------------------------------

        if (Me%WaterLevel%ID%SolutionFromFile) then
            call ModifyFillMatrix (FillMatrixID   = Me%WaterLevel%ID%ObjFillMatrix, &
                                   Matrix2D       = Me%WaterLevel%New,              &
                                   PointsToFill2D = Me%External_Var%WaterPoints2D,  &
                                   STAT           = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)  Stop 'ReadImposedSolution - ModuleHydrodynamic - ERR10'
        endif

        RotateX = .false. 
        RotateY = .false. 

        if (Me%Velocity%Horizontal%U%ID%SolutionFromFile) then

            if      (Me%Velocity%Horizontal%U%InTypeZUV == TypeU_) then
        
                PointsToFill3D => Me%External_Var%ComputeFaces3D_U
                Matrix3D       => Me%Velocity%Horizontal%U%New

            else if (Me%Velocity%Horizontal%U%InTypeZUV == TypeZ_) then

                PointsToFill3D => Me%External_Var%OpenPoints3D
            
                allocate (Matrix3D(Me%Size%ILB:Me%Size%IUB,Me%Size%JLB:Me%Size%JUB,Me%Size%KLB:Me%Size%KUB))

                Matrix3D(:,:,:) = FillValueReal

            endif

            call ModifyFillMatrix (FillMatrixID   = Me%Velocity%Horizontal%U%ID%ObjFillMatrix, &
                                   Matrix3D       = Matrix3D,                                  &
                                   PointsToFill3D = PointsToFill3D,                            &
                                   STAT           = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)  Stop 'ReadImposedSolution - ModuleHydrodynamic - ERR20'


            if (Me%Velocity%Horizontal%U%InTypeZUV == TypeZ_) then

                Me%Velocity%Horizontal%U%New(:,:,:) = 0.

                do k = Me%WorkSize%KLB,Me%WorkSize%KUB
                do j = Me%WorkSize%JLB,Me%WorkSize%JUB
                do i = Me%WorkSize%ILB,Me%WorkSize%IUB
                
                    if (PointsToFill3D(i,j-1,k) == OpenPoint .and.                      &
                        PointsToFill3D(i,j  ,k) == OpenPoint) then
                        Me%Velocity%Horizontal%U%New(i,j,k) = (Matrix3D(i,j-1,k) + Matrix3D(i,j,k)) / 2.
                    endif

                enddo
                enddo
                enddo

                deallocate(Matrix3D)

            endif

            nullify   (PointsToFill3D)
            nullify   (Matrix3D)


            RotateX = .true. 

        endif

        if (Me%Velocity%Horizontal%V%ID%SolutionFromFile) then

            if      (Me%Velocity%Horizontal%V%InTypeZUV == TypeV_) then

                PointsToFill3D => Me%External_Var%ComputeFaces3D_V
                Matrix3D       => Me%Velocity%Horizontal%V%New

            else if (Me%Velocity%Horizontal%V%InTypeZUV == TypeZ_) then

                PointsToFill3D => Me%External_Var%OpenPoints3D
                allocate (Matrix3D(Me%Size%ILB:Me%Size%IUB,Me%Size%JLB:Me%Size%JUB,Me%Size%KLB:Me%Size%KUB))

                Matrix3D(:,:,:) = FillValueReal

            endif

            call ModifyFillMatrix (FillMatrixID   = Me%Velocity%Horizontal%V%ID%ObjFillMatrix, &
                                   Matrix3D       = Matrix3D,                                  &
                                   PointsToFill3D = PointsToFill3D,                            &
                                   STAT           = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)  Stop 'ReadImposedSolution - ModuleHydrodynamic - ERR30'

            if (Me%Velocity%Horizontal%V%InTypeZUV == TypeZ_) then

                Me%Velocity%Horizontal%V%New(:,:,:) = 0.

                do k = Me%WorkSize%KLB,Me%WorkSize%KUB
                do j = Me%WorkSize%JLB,Me%WorkSize%JUB
                do i = Me%WorkSize%ILB,Me%WorkSize%IUB
                
                    if (PointsToFill3D(i-1,j,k) == OpenPoint .and.                  &
                        PointsToFill3D(i  ,j,k) == OpenPoint) then
                        Me%Velocity%Horizontal%V%New(i,j,k) = (Matrix3D(i-1,j,k) + Matrix3D(i,j,k)) / 2.
                    endif

                enddo
                enddo
                enddo

                deallocate(Matrix3D)

            endif

            nullify   (PointsToFill3D)
            nullify   (Matrix3D)

            RotateY = .true. 
        endif

        call RotateVectorFieldToGrid(HorizontalGridID  = Me%ObjHorizontalGrid,           &
                                     VectorInX         = Me%Velocity%Horizontal%U%New,   &
                                     VectorInY         = Me%Velocity%Horizontal%V%New,   &
                                     VectorOutX        = Me%Velocity%Horizontal%U%New,   &
                                     VectorOutY        = Me%Velocity%Horizontal%V%New,   &   
                                     WaterPoints3D     = Me%External_Var%WaterPoints3D,  &
                                     RotateX           = RotateX,                        &
                                     RotateY           = RotateY,                        &
                                     KLB               = Me%WorkSize%KLB,                &
                                     KUB               = Me%WorkSize%KUB,                &
                                     STAT              = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)  Stop 'ReadImposedSolution - ModuleHydrodynamic - ERR40'

    end subroutine ReadImposedSolution

    !End------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Geometry, Mapping                                                            !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (03/1)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine MomentumMassConservation 

        !Arguments-------------------------------------------------------------------
        

        !Local----------------------------------------------------------------------
        integer :: Num_Discretization, Grid


        !Begin----------------------------------------------------------------------


        call ModifyWaterDischarges 

        Num_Discretization = Me%ComputeOptions%Num_Discretization

i1:     if (Me%ComputeOptions%Vertical_AxiSymmetric_Model == 0) then

cd2:        if      (Num_Discretization == Abbott    ) then

                call Abbott_Scheme     

            else if (Num_Discretization == Leendertse) then cd2

                call Leendertse_Scheme 

            else cd2

                Stop 'Sub. MomentumMassConservation - ModuleHydrodynamic - Err01.'
 
            endif cd2

        else i1

            call Implicit_1DScheme

        endif i1


        !NonHydrostatic
        if (Me%NonHydrostatic%ON) then

            call VerticalMomentum

            call NonHydroStaticCorrection

            call Modify_HorizontalWaterFlow

            call NullifyAuxiliarPointers

        endif

        !Grid = Fix 
        !First prediction of the vertical fluxes and velocity for a fixed geometry
        !This is only important when one of the domains as vertical "Lagrangian" coordinate

        Grid = Fix

        call New_VerticalHydrodynamic( Grid)
        
        call New_Geometry

        !Grid = Variable
        !the vertical water flux is compute with the effect of variable volume
        Grid = Variable

        call New_VerticalHydrodynamic( Grid)  

    End Subroutine MomentumMassConservation
    !End------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                       
    ! Vertical Momentum                                                                    
    !
    ! Calculates the vertical velocity by resolving the momentum equation in z direction.  
    ! The routine computes a tri-diagonal system - that is coefficients and independent
    ! term - that is then solved using the Thomas algorithm.
    !
    ! 1) Pressure correction    
    ! 2) Diffusion
    ! 3) Advection
    ! 4) Boundary Condition
    ! 5) Solve by Thomas Algorithm
    !                                                                                      
    ! ----------------------------
    !
    ! author : Hernâni Theias
    ! last modified  : 06/2004 
    ! e-mail : hernanitheias@netcabo.pt                                                      
    !                                                                                      
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine VerticalMomentum
        !Local--------------------------------------------------
         real(8),    dimension(:,:,:), pointer  :: eCoef !coefficients
         real,    dimension(:,:,:), pointer     :: dCoef, fCoef, tiCoef !coefficients
         integer                                :: iub, ilb, jub, jlb, kub, klb
         integer                                :: i, j, k     !counters
         real(8),    dimension(:,:,:), pointer  :: fx, fy, fz
         real,       dimension(:,:,:), pointer  :: dz
         real,       dimension(:,:), pointer    :: dx, dy
         real                                   :: axy, az, kv
        !Begin---------------------------------------------------
        !----Shorten names
        iub = Me%WorkSize%IUB
        ilb = Me%WorkSize%ILB
        jub = Me%WorkSize%JUB
        jlb = Me%WorkSize%JLB
        kub = Me%WorkSize%KUB
        klb = Me%WorkSize%KLB
        dCoef => Me%Coef%D3%D
        eCoef => Me%Coef%D3%E
        fCoef => Me%Coef%D3%F
        tiCoef => Me%Coef%D3%Ti
        !----Initialize values
        dCoef(:,:,:) = 0.0
        eCoef(:,:,:) = 1.0
        fCoef(:,:,:) = 0.0 
        tiCoef(:,:,:) = 0.0 !do not put FillValueReal here, please. Not healthy. 
        !----Non-Hydrostatic correction, explicit part
        do k = klb, kub
        do j = jlb, jub
        do i = ilb, iub
            if(Me%External_Var%ComputeFaces3D_W(i, j, k) == Compute) then
                tiCoef(i, j, k) =   Me%Velocity%Vertical%CartesianOld(i, j, k) +             &
                                    (1- Me%NonHydroStatic%ThetaW) *                          &
                                    Me%WaterLevel%DT   /  Me%External_Var%DWZ(i,j,k) *       &
                                    (Me%NonHydroStatic%PressureCorrect(i, j ,k - 1)  -       &
                                    Me%NonHydroStatic%PressureCorrect(i, j ,k))
            endif
        enddo !do i
        enddo !do j
        enddo !do k
        !----Allocate...
        allocate(fx(ilb-1:iub+1,jlb-1:jub+1,klb-1:kub+1))
        allocate(fy(ilb-1:iub+1,jlb-1:jub+1,klb-1:kub+1))
        allocate(fz(ilb-1:iub+1,jlb-1:jub+1,klb-1:kub+1))
        allocate(dx(ilb-1:iub+1,jlb-1:jub+1))
        allocate(dy(ilb-1:iub+1,jlb-1:jub+1))
        allocate(dz(ilb-1:iub+1,jlb-1:jub+1,klb-1:kub+1))
        fx(:,:,:) = FillValueReal
        fy(:,:,:) = FillValueReal
        fz(:,:,:) = FillValueReal
        dx(:,:  ) = FillValueReal
        dy(:,:  ) = FillValueReal
        dz(:,:,:) = FillValueReal
        !----Calculate Diffusive Fluxes
        do j = jlb, jub
        do i = ilb, iub
            az = Me%External_Var%DXX(i,j) * Me%External_Var%DYY(i,j)
            do k = klb, kub
                !X
                if((Me%External_Var%WaterPoints3D(i,j,k)==OpenPoint).and.        &
                   (Me%External_Var%WaterPoints3D(i,j-1,k)==OpenPoint).and.       &
                   (Me%External_Var%WaterPoints3D(i,j,k-1)==OpenPoint).and.       &
                   (Me%External_Var%WaterPoints3D(i,j-1,k-1)==OpenPoint)) then
                    axy = Me%External_Var%DUZ(i,j,k) * Me%External_Var%DYY(i,j)
                    kv = interpolate3D(Me%External_Var%Visc_H_Center,            &  
                                       Me%External_Var%DUX, Me%External_Var%DVY, &
                                       Me%External_Var%DWZ, i, j, k, 0, -1, -1)
                    fx(i,j,k) = kv * axy
                    dx(i,j) = Me%External_Var%DZX(i,j-1)
                else
                    fx(i,j,k) = 0.0
                endif
                !Y
                if((Me%External_Var%WaterPoints3D(i,j,k)==OpenPoint).and.         &
                   (Me%External_Var%WaterPoints3D(i-1,j,k)==OpenPoint).and.       &
                   (Me%External_Var%WaterPoints3D(i,j,k-1)==OpenPoint).and.       &
                   (Me%External_Var%WaterPoints3D(i-1,j,k-1)==OpenPoint)) then
                    axy = Me%External_Var%DVZ(i,j,k) * Me%External_Var%DXX(i,j)
                    kv = interpolate3D(Me%External_Var%Visc_H_Center,            &  
                                       Me%External_Var%DUX, Me%External_Var%DVY, &
                                       Me%External_Var%DWZ, i, j, k, -1, 0, -1)
                    fy(i,j,k) = kv * axy
                    dy(i,j) = Me%External_Var%DZY(i,j-1)
                else
                    fy(i,j,k) = 0.0
                endif
                !Z
                if((Me%External_Var%ComputeFaces3D_W(i,j,k)==Compute).and. &
                   (Me%External_Var%ComputeFaces3D_W(i,j,k-1)==Compute)) then
                    kv = interpolate3D(Me%External_Var%Vertical_Viscosity,       &  
                                       Me%External_Var%DUX, Me%External_Var%DVY, &
                                       Me%External_Var%DZZ, i, j, k, 0, 0, -1)
                    fz(i,j,k) = kv * az
                    dz(i,j,k) = Me%External_Var%DZZ(i,j-1,k)
                else
                    fz(i,j,k) = 0.0
                endif
            enddo !do k 
        enddo !do i
        enddo !do j
        !----Diffusion          
         call ComputeDiffusion3D (ilb, iub, jlb, jub, klb, kub,                          &
                dx, dy, dz,                                                              &
                Me%External_Var%ComputeFaces3D_U,                                        &
                Me%External_Var%ComputeFaces3D_V,                                        &
                Me%External_Var%ComputeFaces3D_W,                                        &
                fx, fy, fz,                                                              &
                Me%WaterLevel%DT, Me%Velocity%Vertical%Cartesian,                        &
                Me%External_Var%Volume_W,                                                &
                Ticoef, Ecoef, DCoef, Fcoef,                                             &
                0.,                                                                      &
                0.,                                                                      &
                Me%ComputeOptions%ImplicitVertDiffusion,                                 &
                Me%ComputeOptions%HorizontalDiffusion,                                   &
                Me%ComputeOptions%HorizontalDiffusion,                                   &
                Me%ComputeOptions%VerticalDiffusion)
        !----Interpolate Fluxes to W-Grid
        do k = klb, kub
        do j = jlb, jub
        do i = ilb, iub
            fx(i,j,k) = interpolate3D(Me%WaterFluxes%X,                                  &  
                                   Me%External_Var%DUX, Me%External_Var%DVY,             &
                                   Me%External_Var%DWZ, i, j, k, 0, 0, -1)
            fy(i,j,k) = interpolate3D(Me%WaterFluxes%X,                                  &  
                                   Me%External_Var%DUX, Me%External_Var%DVY,             &
                                   Me%External_Var%DWZ, i, j, k, 0, 0, -1)
            fz(i,j,k) = interpolate3D(Me%WaterFluxes%X,                                  &  
                                   Me%External_Var%DUX, Me%External_Var%DVY,             &
                                   Me%External_Var%DWZ, i, j, k, 0, 0, -1)
        enddo !do k 
        enddo !do i
        enddo !do j
        !----Advection
        call ComputeAdvection3D(ilb, iub, jlb, jub, klb, kub,                            &
                    dx, dy, dz,                                                          &
                    Me%External_Var%ComputeFaces3D_U,                                    &
                    Me%External_Var%ComputeFaces3D_V,                                    &
                    Me%External_Var%ComputeFaces3D_W,                                    &
                    fx, fy, fz,                                                          &
                    Me%WaterLevel%DT, Me%Velocity%Vertical%Cartesian,                    &
                    Me%External_Var%Volume_W,                                            &
                    Ticoef, Ecoef, DCoef, Fcoef,                                         &
                    0.0,                                                                 &
                    0.0,                                                                 &
                    Me%ComputeOptions%ImplicitVertAdvection,                             &
                    Me%ComputeOptions%HorizontalAdvection,                               &
                    Me%ComputeOptions%HorizontalAdvection,                               &
                    Me%ComputeOptions%VerticalAdvection,                                 &
                    Me%ComputeOptions%AdvectionMethodH,                                  &
                    Me%ComputeOptions%AdvectionMethodV,                                  &
                    Me%ComputeOptions%TVD_LimH,                                          &
                    Me%ComputeOptions%TVD_LimV,                                          &
                    Me%ComputeOptions%VolumeRelMax,                                      &
                    Me%ComputeOptions%Upwind2H,                                          &
                    Me%ComputeOptions%Upwind2V) 
        !----Boundary condition
        call VerticalMomentumBoundary
        !----Solve
        call THOMASZ(ilb, iub, jlb, jub, klb, kub, dCoef, eCoef, fCoef, tiCoef,        &
                      Me%Velocity%Vertical%Cartesian, Me%VECG_3D, Me%VECW_3D)
        !----DeAllocate...
        deallocate(fx)
        deallocate(fy)
        deallocate(fz)
        deallocate(dx)
        deallocate(dy)
        deallocate(dz)
    End Subroutine VerticalMomentum
    !End------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                       
    ! Vertical Momentum Boundary Condition                                                                      
    !                                                                           
    ! ----------------------------
    !
    ! author : Hernâni Theias
    ! last modified  : 06/2004 
    ! e-mail : hernanitheias@netcabo.pt                                                      
    !                                                                                      
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine VerticalMomentumBoundary
        !Arguments-------------------------------------------------------------------
        real,    dimension(:,:,:), pointer     :: ti          
        integer                                :: ilb, iub, jlb, jub, k_up !bounds
        integer,    dimension(:,:), pointer    :: k_bottom
        !Local----------------------------------------------------------------------
        integer                                 :: i, j !counters
        !Begin----------------------------------------------------------------------
        ilb = Me%WorkSize%ILB
        iub = Me%WorkSize%IUB
        jlb = Me%WorkSize%JLB
        jub = Me%WorkSize%JUB
        K_UP = Me%WorkSize%KUB + 1
        ti => Me%Coef%D3%TI
        k_bottom => Me%External_Var%KFloor_Z
        do i = ilb, iub
        do j = jlb, jub
        !--------Impose w_bottom = 0.0
            if(k_bottom(i,j)>0) ti(i, j, k_bottom(i,j)) = 0.0
        !--------Impose w_up = d(eta)/dt
            ti(i, j, k_up) =  (Me%WaterLevel%New(i, j) - Me%WaterLevel%Old(i, j)) & 
                             / Me%WaterLevel%DT
        enddo    
        enddo
    EndSubroutine
    !End----------------------------------------------------------------------
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      
    ! Non-HydroStatic Correction
    ! --------------------------                                                        
    !                                                                                      
    ! This routine calculates pressure correction due to non-hydrostatic effects.          
    ! It gives a correction that is then applied to velocity and water level.              
    ! This procedure is based on an article by V. Casulli and P. Zanolli                   
    ! "Semi-Implicit Numerical Modeling of Nonhydrostatic Free-Surface Flows for           
    ! environmental problems" applied to Mohid.
    ! This correction is calculated via a set of equations that yields a 
    ! linear system of equations.
    ! The resulting pentadiagonal system is solved using either:
    ! i)    Pre-Conditionned Conjugate Gradient Method
    ! ii)   Stone's Method (LU decomposition for sparse matrices)
    ! iii)  LiSolve
    ! Values of matrix coefficient for the system are stored in 'p', 'e', 'w', 'n', 's' 
    ! vectors, 'p' being the diagonal. 'q' is the independent term.
    ! The solution of the system is stored in 'pc', which is previsional pressure correction.
    ! There is no correction on w. The continuity equation is used to to determine it, so
    ! model is conservative.
    !
    ! ----------------------------
    !
    ! author : Hernâni Theias
    ! last modified  : 06/2004 
    ! e-mail : hernanitheias@netcabo.pt                                      
    !                                                                                      
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine NonHydroStaticCorrection
        !Local----------------------------------------------------------------------
        real,    dimension (:,:,:), pointer  :: e,w,s,n   ! coefficient matrix (non-diagonals elements)
        real(8), dimension (:,:,:), pointer  :: p         ! coefficient matrix (diagonal elements)
        real,    dimension (:,:,:), pointer  :: q         ! independdent term
        real,    dimension (:,:,:), pointer  :: pc        ! previsional pressure correction
        integer                              :: di, dj    ! index change due to calculation direction
        real                                 :: dt        ! time step
        real                                 :: az        ! cell face area in Z direction
        real(8)                              :: aux       ! auxiliary coefficient 
        real                                 :: tetaW     ! semi-implicit coefficient for Z-dir
        real(8)                              :: fluxZ     ! flux in Z-dir for the upper (free surface) cell
        real                                 :: pcl       ! local value for pressure correction
        integer                              :: i, j, k   ! counters
        integer                              :: ILB, IUB, JLB, JUB, KLB, KUB !bounds
        !Begin----------------------------------------------------------------------
        !----Shorten variables names
        w => Me%NonHydroStatic%CCoef
        s => Me%Coef%D3%D
        p => Me%Coef%D3%E
        n => Me%Coef%D3%F
        e => Me%NonHydroStatic%GCoef
        q => Me%Coef%D3%TI
        pc => Me%NonHydroStatic%PrevisionalQ
        tetaW = Me%NonHydroStatic%ThetaW
        ILB = Me%WorkSize%ILB
        IUB = Me%WorkSize%IUB
        JLB = Me%WorkSize%JLB
        JUB = Me%WorkSize%JUB
        KLB = Me%WorkSize%KLB
        KUB = Me%WorkSize%KUB
        dt = Me%WaterLevel%DT
        !----Initialize coefficient matrices 
        n(:,:,:) = 0.0 
        s(:,:,:) = 0.0 
        w(:,:,:) = 0.0
        e(:,:,:) = 0.0 
        p(:,:,:) = 0.0
        q(:,:,:) = 0.0
        di = Me%Direction%di
        dj = Me%Direction%dj
        !----Calculate matrix coefficient and independent term of the system
        do i = ILB, IUB
        do j = JLB, JUB
        !--------Calculate z-area of cell
            az = Me%External_Var%DUX(i,j) * Me%External_Var%DVY(i,j)
            do k = KLB, KUB
                if(Me%External_Var%OpenPoints3D(i, j, k) /= OpenPoint) then !cell must not be calculated
                    p(i, j, k)  = 1.0
                    q(i, j ,k ) = 0.0 !pc(i, j, k)
                endif
        !-------------Fluxes in the implicit direction
                if(Me%External_Var%ComputeFaces3D_UV(i, j, k) == Compute) then
                    aux = dt * Me%External_Var%Area_UV(i, j, k) ** 2 / Me%External_Var%Volume_UV(i, j, k)
                    p(i     , j     , k) = p(i     , j     , k) + aux
                    s(i     , j     , k) = s(i     , j     , k) - aux
                    q(i     , j     , k) = q(i     , j     , k) + Me%WaterFluxes%XY(i, j, k)
                    p(i - di, j - dj, k) = p(i - di, j - dj, k) + aux
                    n(i - di, j - dj, k) = n(i - di, j - dj, k) - aux
                    q(i - di, j - dj, k) = q(i - di, j - dj, k) - Me%WaterFluxes%XY(i, j, k)
                endif
        !-------------Fluxes in the explicit direction
                if(Me%External_Var%ComputeFaces3D_VU(i, j, k) == Compute) then
                    q(i     , j     , k) = q(i     , j     , k) + Me%WaterFluxes%YX(i, j, k)
                    q(i - dj, j - di, k) = q(i - dj, j - di, k) - Me%WaterFluxes%YX(i, j, k) !note here di and dj are switched
                endif
        !-------------Discharges
                if((Me%ComputeOptions%WaterDischarges).and. &
                   (Me%External_Var%OpenPoints3D(i, j, k) == OpenPoint)) &
                    q(i, j, k) = q(i, j, k) + Me%WaterFluxes%Discharges(i, j, k)
        !------------Fluxes in Z direction
                if(Me%External_Var%ComputeFaces3D_W (i, j, k) == Compute) then
                    aux            = dt * TetaW * az ** 2 / Me%External_Var%Volume_W(i, j, k)
                    fluxZ          = az * Me%Velocity%Vertical%Cartesian(i, j, k)
        !----------------Layers bellow free-surface
                    if      (k <  KUB) then 
                        p(i, j, k) = p(i, j, k    ) + aux
                        w(i, j, k) = w(i, j, k    ) - aux
                        q(i, j, k) = q(i, j, k    ) + fluxZ
        !----------------Free-Surface Layer
                    else if (k == KUB) then
                        p(i, j, k) = p(i, j, k    ) + TetaW * aux   
                        w(i, j, k) = w(i, j, k    ) - TetaW * aux
                        q(i, j, k) = q(i, j, k    ) + TetaW * fluxZ + (1. - TetaW) *  az * &
                                                      Me%Velocity%Vertical%CartesianOld(i, j, k)
                        q(i, j, k) = q(i, j, k    ) + (Me%WaterLevel%Old(i, j) - Me%WaterLevel%New(i, j)) / dt * az
                        if((.not.Me%ComputeOptions%Compute_Tide).or. &
                           (Me%External_Var%BoundaryPoints(i, j)/=Boundary)) &
                        p(i, j, k) = p(i, j, k    ) + az / Gravity / dt
                    endif
                    p(i, j, k - 1) = p(i, j, k - 1) + aux
                    e(i, j, k - 1) = e(i, j, k - 1) - aux
                    q(i, j, k - 1) = q(i, j, k - 1) - fluxZ
                endif
            enddo ! do k
            enddo ! do j
        enddo ! do i
        !
        !----Boundary Condition - Before Solving System
        call NonHydroCorrectionBoundary(.True.)
        !
        !----Solve the syste
        call BICGSTAB2D(pc, p, s, n, w, e, q,               &
                          ilb, iub, jlb, jub, klb, kub,     &
                          dj,                               &
                          Me%NonHydroStatic%MaxIt,          &
                          Me%NonHydroStatic%Residual,       &
                          Me%External_Var%OpenPoints3D,     &
                          Me%NonHydroStatic%AlphaLU,        &
                          Me%NonHydroStatic%NormalizedResidual)
        !
        !----Correction (of velocity and water level accordingly to 'pc')
        !
        !----Boundary Condition - After Solving System
        call NonHydroCorrectionBoundary(.False.)
        !
        do j = JLB, JUB
        do i = ILB, IUB
            az = Me%External_Var%DUX(i,j) * Me%External_Var%DVY(i,j)
        !--------Correct water level
            if((.not.Me%ComputeOptions%Compute_Tide).or. &
              (Me%External_Var%BoundaryPoints(i, j)/=Boundary)) then
                pcl = pc(i, j, KUB) / Gravity
                if(abs(pcl)<AllmostZero) pcl = 0. ! only correct ater level if pc is something
                Me%WaterLevel%New(i,j) = Me%WaterLevel%New(i,j) + pcl
            end if
            do k = KLB,KUB
        !------------Correct NH pressure correction (itself!)
                Me%NonHydroStatic%PressureCorrect(i,j,k) = pc(i, j, k) - pc(i, j, KUB)
        !------------Correct UV - only the direction taken implicit is corrected
                if(Me%External_Var%ComputeFaces3D_UV(i,j,k) == Compute) then 
                    pcl = pc(i - di, j - dj, k) - pc(i, j, k)
                    if(abs(pcl)<AllmostZero) pcl = 0. ! only correct velocity if grdient important                    
                    Me%Velocity%Horizontal%UV%New(i,j,k) =   Me%Velocity%Horizontal%UV%New(i,j,k)       & 
                                                           + dt /Me%External_Var%DZX_ZY(i, j)           &
                                                           * pcl
                endif
            enddo !do k             
        enddo !do i
        enddo !do j
        !----restore values on p (avoid divisions by zero at later stages of calculation)
        p(:,:,:) = 1.0
    End Subroutine NonHydroStaticCorrection
    !End------------------------------------------------------------
     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !
    ! NonHydroCorrectionBoundary (null gradient)     
    ! 
    ! ----------------------------
    !
    ! author : Hernâni Theias
    ! last modified  : 06/2004 
    ! e-mail : hernanitheias@netcabo.pt                                                       !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine NonHydroCorrectionBoundary(PreSolve)
        !Local----------------------------------------------------------------------
        real,    dimension (:,:,:), pointer  :: e,w,s,n   ! coefficient matrix (non-diagonals elements)
        real,    dimension (:,:,:), pointer  :: pc        ! previsional pressure correction
        real(8), dimension (:,:,:), pointer  :: p         ! coefficient matrix (diagonal elements)
        real,    dimension (:,:,:), pointer  :: q         ! independdent term
        integer                              :: i, j, k   ! counters
        integer                              :: ILB, IUB, JLB, JUB, KUB ! bounds
        logical                              :: PreSolve
        !Begin----------------------------------------------------------------------
        !----Shorten variables names
        s => Me%Coef%D3%D
        p => Me%Coef%D3%E
        n => Me%Coef%D3%F
        q => Me%Coef%D3%TI
        w => Me%NonHydroStatic%CCoef
        e => Me%NonHydroStatic%GCoef
        pc => Me%NonHydroStatic%PrevisionalQ
        
        ILB = Me%WorkSize%ILB
        IUB = Me%WorkSize%IUB
        JLB = Me%WorkSize%JLB
        JUB = Me%WorkSize%JUB
        KUB = Me%WorkSize%KUB

        !Null gradient

        do i = ILB, IUB
        do j = JLB, JUB
            !Y boundary faces
Y1:         if (Me%External_Var%BoundaryFacesV(i, j) == Boundary) then

                do k = Me%External_Var%KFloor_V(i, j), KUB

                    if      (Me%External_Var%BoundaryPoints(i-1, j) == Boundary) then
                        
                        if      ((Me%Direction%XY == DirectionY_).and.(PreSolve)) then
                            
                            e(i-1, j, k) =  0.
                            w(i-1, j, k) =  0.
                            p(i-1, j, k) =  1.  
                            s(i-1, j, k) =  0.
                            n(i-1, j, k) = -1.
                            q(i-1, j, k) =  0.
                        
                        else if (Me%Direction%XY == DirectionX_) then
                             
                            if(PreSolve) then ! keep previous value
                              
                                e(i-1, j, k) =  0.
                                w(i-1, j, k) =  0.
                                p(i-1, j, k) =  1.
                                s(i-1, j, k) =  0.
                                n(i-1, j, k) =  0.
                                q(i-1, j, k) =  pc(i - 1, j, k)
                            else ! equal to current neighbour
                                pc(i - 1, j, k) = pc(i, j, k)
                            endif

                        endif

                    else if (Me%External_Var%BoundaryPoints(i, j) == Boundary) then
                  

                        if      ((Me%Direction%XY == DirectionY_).and.(PreSolve))  then
                        
                            e(i, j, k) =  0.
                            w(i, j, k) =  0.
                            p(i, j, k) =  1.
                            s(i, j, k) = -1.
                            n(i, j, k) =  0.
                            q(i, j, k) =  0.

                        else if (Me%Direction%XY == DirectionX_) then
        
                            if(PreSolve) then
                                
                                e(i, j, k) =  0.
                                w(i, j, k) =  0.
                                p(i, j, k) =  1.
                                s(i, j, k) =  0.
                                n(i, j, k) =  0.
                                q(i, j, k) =  pc(i, j, k)
                            else
                                pc(i, j, k) = pc(i - 1, j, k)
                            endif

                        endif
                    
                    endif

                enddo ! do k

            endif Y1

            !X boundary faces
X1:         if (Me%External_Var%BoundaryFacesU(i, j) == Boundary) then
            
                do k = Me%External_Var%KFloor_U(i, j), KUB

                    if      (Me%External_Var%BoundaryPoints(i, j - 1) == Boundary) then

                        if((Me%Direction%XY == DirectionX_).and.PreSolve) then
                            e(i, j-1, k) =  0.
                            w(i, j-1, k) =  0.
                            p(i, j-1, k) =  1.
                            s(i, j-1, k) =  0.
                            n(i, j-1, k) = -1.
                            q(i, j-1, k) =  0.
                        else if (Me%Direction%XY == DirectionY_) then
                            if(PreSolve) then
                                e(i, j-1, k) =  0.
                                w(i, j-1, k) =  0.
                                p(i, j-1, k) =  1.
                                s(i, j-1, k) =  0.
                                n(i, j-1, k) =  0.
                                q(i, j-1, k) =  pc(i, j-1, k)
                            else
                                pc(i, j-1, k) = pc(i, j, k)
                            endif
                        endif
                    else if (Me%External_Var%BoundaryPoints(i, j) == Boundary) then
                        if((Me%Direction%XY == DirectionX_).and.PreSolve) then
                            e(i, j, k) =  0.
                            w(i, j, k) =  0.
                            p(i, j, k) =  1.
                            s(i, j, k) = -1.
                            n(i, j, k) =  0.
                            q(i, j, k) =  0.
                        else if (Me%Direction%XY == DirectionY_) then
                            if(PreSolve) then
                                e(i, j, k) =  0.
                                w(i, j, k) =  0.
                                p(i, j, k) =  1.
                                s(i, j, k) =  0.
                                n(i, j, k) =  0.
                                q(i, j, k) =  pc(i, j, k)
                            else
                                pc(i, j, k) = pc(i, j-1, k)
                            endif
                        endif
                    endif

                enddo ! do k

            endif X1
        enddo ! do j
        enddo ! do i

        nullify(p)
        nullify(pc)
        nullify(q)
        nullify(e)
        nullify(w)
        nullify(s)
        nullify(n)
    End Subroutine
    !End------------------------------------------------------------
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !
    ! ComputeCartesianNH
    ! 
    ! ----------------------------
    !
    ! This routine calculates the vertical velocity based divergence equation :
    ! div(V) = 0
    ! The vertical velocity is given by the flux balance at each cell and assuming
    ! that at bottom w = 0, so we can calculate w from bottom to top.
    ! This routine is only used in non-hydrostatic calculations, to match the numerical
    ! scheme followed.
    !
    ! ----------------------------
    !
    ! author : Hernâni Theias
    ! last modified  : 06/2004 
    ! e-mail : hernanitheias@netcabo.pt                                                     
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine ComputeCartesianNH
        !Local----------------------------------------------------------------------          
        integer                              :: i, j, k   ! counters
        integer                              :: kbottom   ! cell index at bottom
        real                                 :: az        ! cell horizontal area
        real                                 :: df        ! horizontal flux balance
        real                                 :: discharge ! discharge flux
        integer                              :: kub       ! upper cell index
        !Begin----------------------------------------------------------------------
        do i = Me%WorkSize%ILB, Me%WorkSize%IUB
        do j = Me%WorkSize%JLB, Me%WorkSize%JUB
            if(Me%External_Var%OpenPoints3d(i,j, Me%WorkSize%KUB) == OpenPoint) then
                kbottom = Me%External_Var%KFloor_Z(i,j)
                if((Me%ComputeOptions%Compute_Tide).and. &
                   (Me%External_Var%BoundaryPoints(i, j)==Boundary)) then
                    kub = Me%WorkSize%KUB
                else
                    kub = Me%WorkSize%KUB + 1
                endif
                Me%Velocity%Vertical%Cartesian(i,j,kbottom) = 0.
                az = Me%External_Var%DUX(i,j) * Me%External_Var%DVY(i,j)
                do k = kbottom + 1, kub
                    discharge = 0.
                    if(Me%ComputeOptions%WaterDischarges) &
                        discharge = Me%WaterFluxes%Discharges(i, j, k)
                    df =   Me%WaterFluxes%X(i    , j    , k - 1)                        &
                         - Me%WaterFluxes%X(i    , j + 1, k - 1)                        &
                         + Me%WaterFluxes%Y(i    , j    , k - 1)                        &
                         - Me%WaterFluxes%Y(i + 1, j    , k - 1)                        &
                         + discharge                     
                    Me%Velocity%Vertical%Cartesian(i,j,k) = Me%Velocity%Vertical%Cartesian(i,j,k - 1) + df / az                               
                enddo
            endif
        enddo
        enddo
        if (Me%CyclicBoundary%ON) then !in case of cyclic boundary
            call CyclicBoundVertical (Vector = Me%Velocity%Vertical%Cartesian)
        endif
    End Subroutine
    !End------------------------------------------------------------
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Geometry, Mapping                                                            !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine ReadHydrodynamicFile 


        !Arguments-------------------------------------------------------------------
        


        !Local----------------------------------------------------------------------
        real,    dimension(:,:),   pointer :: WaterLevel
        real(8), dimension(:,:,:), pointer :: WaterFluxX, WaterFluxY, Discharges
        integer, dimension(:,:,:), pointer :: ComputeFaces3DU, ComputeFaces3DV

        integer :: STAT_CALL


        !Begin----------------------------------------------------------------------


        !Reads new Instant
        call ModifyHydrodynamicFile(Me%ObjHydrodynamicFileIn, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'ReadHydrodynamicFile - ModuleHydrodynamic - ERR01' 


        !Gets actual WaterLevel
        call GetFileWaterLevel(Me%ObjHydrodynamicFileIn, WaterLevel, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'ReadHydrodynamicFile - ModuleHydrodynamic - ERR02' 


        !Actualizes Hydrodynamic
        Me%WaterLevel%New = WaterLevel


        !With the new WaterLevel, recalculate Geometry
        !Notice: This wont work if the coordinate is of the type Lagrangian
        call New_Geometry


        !Gets Horizontal Fluxes from file
        call GetFileFluxes(Me%ObjHydrodynamicFileIn,                        &
                           WaterFluxX = WaterFluxX,                                      &
                           WaterFluxY = WaterFluxY,                                      &
                           Discharges = Discharges,                                      &
                           STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'ReadHydrodynamicFile - ModuleHydrodynamic - ERR03' 

        Me%WaterFluxes%X = WaterFluxX
        Me%WaterFluxes%Y = WaterFluxY

        Me%WaterFluxes%Discharges = Discharges


        !Calculates horizontal velocities, given the fluxes
        call Compute_VelocityFromFluxes


        !Gets the Mapping from the file
        call GetFileMapping(Me%ObjHydrodynamicFileIn,                       &
                            ComputeFaces3DU,                                             &
                            ComputeFaces3DV,                                             &
                            STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'ReadHydrodynamicFile - ModuleHydrodynamic - ERR04' 


        !Modifies Mapping, acording to the one in the file
        call ReadUnLock_ModuleMap
        call SetComputesFaces3D(Me%ObjMap,                                  &
                                ComputeFaces3DU,                                         &
                                ComputeFaces3DV,                                         &
                                Me%CurrentTime,                             &
                                STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'ReadHydrodynamicFile - ModuleHydrodynamic - ERR05' 
        call ReadLock_ModuleMap


        !Calculates the vertical hydrodynamic
        call New_VerticalHydrodynamic( Grid = Variable)

        !WaterLevel
        call UnGetHydrodynamicFile (Me%ObjHydrodynamicFileIn,               &
                                    WaterLevel, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'ReadHydrodynamicFile - ModuleHydrodynamic - ERR06' 


        !WaterFluxX
        call UnGetHydrodynamicFile (Me%ObjHydrodynamicFileIn,               &
                                    WaterFluxX, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'ReadHydrodynamicFile - ModuleHydrodynamic - ERR07' 

        !WaterFluxY
        call UnGetHydrodynamicFile (Me%ObjHydrodynamicFileIn,               &
                                    WaterFluxY, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'ReadHydrodynamicFile - ModuleHydrodynamic - ERR08' 

        !Discharges
        call UnGetHydrodynamicFile (Me%ObjHydrodynamicFileIn,               &
                                    Discharges, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'ReadHydrodynamicFile - ModuleHydrodynamic - ERR09' 

        !ComputeFaces3DU
        call UnGetHydrodynamicFile (Me%ObjHydrodynamicFileIn,               &
                                    ComputeFaces3DU, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'ReadHydrodynamicFile - ModuleHydrodynamic - ERR10' 

        !ComputeFaces3DV
        call UnGetHydrodynamicFile (Me%ObjHydrodynamicFileIn,               &
                                    ComputeFaces3DU, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'ReadHydrodynamicFile - ModuleHydrodynamic - ERR11' 


    end subroutine ReadHydrodynamicFile
    
    !End----------------------------------------------------------------------


    subroutine New_Geometry

        !Arguments------------------------------------------------------------

        !Local----------------------------------------------------------------
        integer, dimension(:,:,:), pointer  :: WaterPoints3D
        real,    dimension(:,:  ), pointer  :: SurfaceElevation
        real,    dimension(:,:,:), pointer  :: Velocity_Z, DecayTime
        real                                :: DT_WaterLevel
        real                                :: ColdPeriod, ColdOrder, DT_RunPeriod, CoefCold
        integer                             :: i, j, k, kbottom, STAT_CALL

        !Begin----------------------------------------------------------------
        
        WaterPoints3D    => Me%External_Var%WaterPoints3D

        SurfaceElevation => Me%WaterLevel%New

        Velocity_Z       => Me%Velocity%Vertical%Across

        DT_WaterLevel    =  Me%WaterLevel%DT

        if (Me%Relaxation%Geometry) then 

            call GetAssimilationCoef (Me%ObjAssimilation,                               &
                                      ID              = VerticalZ_,                     &
                                      CoefField3D     = DecayTime,                      &
                                      ColdRelaxPeriod = ColdPeriod,                     &
                                      ColdOrder       = ColdOrder,                      &
                                      STAT            = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                  &
                 stop 'Subroutine New_Geometry; Module ModuleHydrodynamic. ERR10' 


            DT_RunPeriod = Me%CurrentTime - Me%BeginTime

            if (ColdPeriod > (Me%EndTime - Me%BeginTime))                               &
                stop 'Subroutine New_Geometry; Module ModuleHydrodynamic. ERR20' 

cd4:        if (ColdPeriod <= DT_RunPeriod) then
                CoefCold = 1
            else  cd4
                CoefCold = (DT_RunPeriod / ColdPeriod) ** ColdOrder
                if (CoefCold < 1.e-32) CoefCold = 1.e-32
            endif cd4

        
            do j = Me%WorkSize%JLB, Me%WorkSize%JUB
            do i = Me%WorkSize%ILB, Me%WorkSize%IUB
            
            kbottom = Me%External_Var%KFloor_Z(i, j)

                if (WaterPoints3D(i, j, Me%WorkSize%KUB) == WaterPoint) then
                    do k = kbottom, Me%WorkSize%KUB
                        Me%Relaxation%DecayTimeGeo(i, j, k) = CoefCold * DecayTime(i, j, k)
                    enddo

                endif

            enddo
            enddo


        endif



        !call ReadUnLock_ModuleHorizontalGrid 


        !call ReadUnLock_ModuleHorizontalMap 


        !call ReadUnLock_ModuleGeometry 

        
        call ReadUnLock_External_Modules 

        !Compute new volume 
        call ComputeVerticalGeometry(Me%ObjGeometry, WaterPoints3D,                     &
                                     SurfaceElevation, Me%CurrentTime,                  &
                                     Velocity_Z, DT_WaterLevel,                         &
                                     DecayTime = DecayTime, STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                                      &
             stop 'Subroutine New_Geometry; Module ModuleHydrodynamic. ERR30' 


        !Nullify auxliar pointers
        nullify(SurfaceElevation, WaterPoints3D, Velocity_Z)


!        call ReadUnLock_ModuleMap 


        !Update the moving boundary  (boundary of the tidal areas covered)
!        call UpdateComputeFaces3D(Me%ObjMap, &
!             Me%CurrentTime, STAT = STAT_CALL)      

!        if (STAT_CALL /= SUCCESS_)                                           &
!            stop 'Subroutine New_Geometry; module ModuleHydrodynamic. ERR02.'


        call ReadLock_External_Modules 

        if (Me%Relaxation%Geometry) then 

            call UnGetAssimilation   (Me%ObjAssimilation,                               &
                                      DecayTime,                                        &
                                      STAT        = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                  &
                stop 'Subroutine New_Geometry; Module ModuleHydrodynamic. ERR40' 


        endif




    end subroutine New_Geometry
    
    !End----------------------------------------------------------------------

    subroutine New_VerticalHydrodynamic( Grid)

        !Arguments------------------------------------------------------------

        integer                          :: Grid

        !Local----------------------------------------------------------------

        !Begin----------------------------------------------------------------
        
        !Grid = Fix = 1
        !First prediction of the vertical fluxes and velocity for a fixed geometry
        !This is only important when one of the domains as vertical "Lagrangian" coordinate

        !Grid = Variable = 2 
        !the vertical water flux is compute with the effect of variable volume
        call Modify_VerticalWaterFlow (Grid)

        call Filter_3D_Fluxes         
    
        call Compute_VerticalVelocity 

        if(Me%NonHydroStatic%ON) then
            call ComputeCartesianNH
        else
            call ComputeCartesianVertVelocity(Grid = Grid)
        endif

        call Boundary_VerticalFlow (Grid)

        if (Me%CyclicBoundary%ON) then

            call CyclicBoundVertical (VectorD = Me%WaterFluxes%Z)

        endif

    
    end subroutine New_VerticalHydrodynamic
    
    !End----------------------------------------------------------------------



    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Geometry, Mapping                                                            !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine Leendertse_Scheme

        !Arguments------------------------------------------------------------
         

        !Local----------------------------------------------------------------

        !Begin----------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Leendertse_Scheme")

        call MaintainDirection   

        call Explicit_Forces  

        call Compute_Velocity 
        ! Water Flux must be consistent with the water level equation 
        Me%WaterFluxes%New_Old = 0.

        call Modify_HorizontalWaterFlow


        !Same direction of the water level direction 

        call ChangeDirection  
        
        call Bottom_Boundary    

        call Explicit_Forces    

        call Compute_WaterLevel 

        call Compute_Velocity   

        ! Water Flux must be consistent with the water level equation 
        Me%WaterFluxes%New_Old = 1.

        call Modify_HorizontalWaterFlow


!        !Modify the Background velocity if the boundary relaxation scheme is ON
!        if (Me%Relaxation%Velocity)                                  &
!            call ModifyBackgroundVelocity 

        if (.not. Me%NonHydrostatic%ON) call NullifyAuxiliarPointers

        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Leendertse_Scheme")

    End Subroutine Leendertse_Scheme

    !End------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Geometry, Mapping                                                            !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine Abbott_Scheme

        !Arguments------------------------------------------------------------
         

        !Local----------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Abbott_Scheme")

        call ChangeDirection
        
        call Bottom_Boundary    

        call Explicit_Forces    

        call Compute_WaterLevel 

        call Compute_Velocity   


        ! Water Flux must be consistent with the water level equation 
        Me%WaterFluxes%New_Old = 0.5

        call Modify_HorizontalWaterFlow


!        !Modify the Background velocity if the boundary relaxation scheme is ON
!        if (Me%Relaxation%Velocity)                                  &
!            call ModifyBackgroundVelocity 
        
        if (.not. Me%NonHydrostatic%ON) call NullifyAuxiliarPointers


        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Abbott_Scheme")

    
    End Subroutine Abbott_Scheme

    !End---------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Geometry, Mapping                                                            !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (2006/1)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine Implicit_1DScheme

        !Arguments------------------------------------------------------------
         

        !Local----------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Implicit_1DScheme")
        
        call Bottom_Boundary    

        call Explicit_Forces    

        call Compute_WaterLevel 

        call Compute_Velocity   


        ! Water Flux must be consistent with the water level equation 
        Me%WaterFluxes%New_Old = 1.

        call Modify_HorizontalWaterFlow

        if (.not. Me%NonHydrostatic%ON) call NullifyAuxiliarPointers


        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Implicit_1DScheme")

    
    End Subroutine Implicit_1DScheme

    !End---------------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Direction                                                                    !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine  ChangeDirection

        !Arguments------------------------------------------------------------


        !Local----------------------------------------------------------------
        integer :: Previous_Direction 

        !Begin----------------------------------------------------------------

        Previous_Direction = Me%Direction%XY

        if (Previous_Direction == DirectionX_) then

             call AssociateDirectionY

        else if (Previous_Direction == DirectionY_) then
             
             call AssociateDirectionX

        endif 

        !NonHydrostatic
        if (Previous_Direction == DirectionX_) then

            Me%NonHydrostatic%ThetaU = 1.
            Me%NonHydrostatic%ThetaV = 0.

            Me%NonHydrostatic%ThetaUV = Me%NonHydrostatic%ThetaU

        else if (Previous_Direction == DirectionY_) then
         
            Me%NonHydrostatic%ThetaU = 0.
            Me%NonHydrostatic%ThetaV = 1.

            Me%NonHydrostatic%ThetaUV = Me%NonHydrostatic%ThetaV

        endif 

      

    End Subroutine  ChangeDirection

    !End------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Direction                                                                    !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine  MaintainDirection

        !Arguments------------------------------------------------------------


        !Local----------------------------------------------------------------
        integer :: Previous_Direction 

        !Begin----------------------------------------------------------------

        Previous_Direction = Me%Direction%XY

        if (Previous_Direction == DirectionX_) then

             call AssociateDirectionX

        else if (Previous_Direction == DirectionY_) then
             
             call AssociateDirectionY

        endif 

        !NonHydrostatic
        if (Previous_Direction == DirectionX_) then

            Me%NonHydrostatic%ThetaU = 0.
            Me%NonHydrostatic%ThetaV = 1.

            Me%NonHydrostatic%ThetaUV = Me%NonHydrostatic%ThetaU

        else if (Previous_Direction == DirectionY_) then
         
            Me%NonHydrostatic%ThetaU = 1.
            Me%NonHydrostatic%ThetaV = 0.

            Me%NonHydrostatic%ThetaUV = Me%NonHydrostatic%ThetaV

        endif 


    End Subroutine  MaintainDirection

    !End------------------------------------------------------------



    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Direction                                                                    !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine  AssociateDirectionY

        !Arguments------------------------------------------------------------



        !Begin----------------------------------------------------------------

         Me%Direction%XY   =  DirectionY_
         Me%Direction%YX   =  DirectionX_
         Me%Direction%di   =  1
         Me%Direction%dj   =  0    

         !Baroclinic 
         Me%Forces%Rox3XY  => Me%Forces%Rox3Y

         !Flow
         Me%Velocity%Horizontal%UV%Old  => &
         Me%Velocity%Horizontal%V%Old

         Me%Velocity%Horizontal%UV%New  => &
         Me%Velocity%Horizontal%V%New


         Me%Velocity%Horizontal%VU%Old  => &
         Me%Velocity%Horizontal%U%Old

         Me%Velocity%Horizontal%VU%New  => &
         Me%Velocity%Horizontal%U%New

         if (.not. Me%ComputeOptions%BaroclinicRadia == NoRadiation_) then
         
             Me%VelBaroclinic%UV%Old  => &
             Me%VelBaroclinic%V%Old

             Me%VelBaroclinic%UV%New  => &
             Me%VelBaroclinic%V%New


             Me%VelBaroclinic%VU%Old  => &
             Me%VelBaroclinic%U%Old

             Me%VelBaroclinic%VU%New  => &
             Me%VelBaroclinic%U%New

             Me%VelBaroclinic%ImposedNormXY  => &
             Me%VelBaroclinic%ImposedNormY

             Me%VelBaroclinic%ImposedTangXY  => &
             Me%VelBaroclinic%ImposedTangY

             Me%VelBaroclinic%UV2D  => &
             Me%VelBaroclinic%V2D
         
         
         endif   


         Me%WaterFluxes%XY              => &
         Me%WaterFluxes%Y

         Me%WaterFluxes%YX              => &
         Me%WaterFluxes%X

         !3D geometry
         Me%External_Var%Volume_UV => &
         Me%External_Var%Volume_V  

         Me%External_Var%Area_UV   => &
         Me%External_Var%Area_V

         Me%External_Var%Area_VU   => &
         Me%External_Var%Area_U

         Me%External_Var%KFloor_UV => &
         Me%External_Var%KFloor_V

         Me%External_Var%KFloor_VU => &
         Me%External_Var%KFloor_U

         Me%External_Var%WaterColumnUV => &
         Me%External_Var%WaterColumnV

         Me%External_Var%WaterColumnVU => &
         Me%External_Var%WaterColumnU

         Me%External_Var%DUZ_VZ        => &
         Me%External_Var%DVZ

         !Horizontal grid
         Me%External_Var%DZX_ZY    => &
         Me%External_Var%DZY

         Me%External_Var%DZY_ZX    => &
         Me%External_Var%DZX

         Me%External_Var%DXX_YY    => &
         Me%External_Var%DYY

         Me%External_Var%DUX_VY    => &
         Me%External_Var%DVY

         Me%External_Var%DVY_UX    => &
         Me%External_Var%DUX

         Me%External_Var%DYY_XX    => &
         Me%External_Var%DXX

         !3D Mapping
         Me%External_Var%ComputeFaces3D_UV   => &
         Me%External_Var%ComputeFaces3D_V

         Me%External_Var%ComputeFaces3D_VU   => &
         Me%External_Var%ComputeFaces3D_U

         Me%External_Var%LandBoundaryFacesUV => &
         Me%External_Var%LandBoundaryFacesV

         Me%External_Var%LandBoundaryFacesVU => &
         Me%External_Var%LandBoundaryFacesU

!         Me%External_Var%UnCoveredFaces3D_UV   => &
!         Me%External_Var%UnCoveredFaces3D_V



         Me%External_Var%BoundaryFacesUV     => &
         Me%External_Var%BoundaryFacesV


         Me%External_Var%BoundaryFacesVU     => &
         Me%External_Var%BoundaryFacesU

         Me%External_Var%ImposedTangentialFacesUV  => &
         Me%External_Var%ImposedTangentialFacesV

         Me%External_Var%ImposedTangentialFacesVU  => &
         Me%External_Var%ImposedTangentialFacesU


         Me%External_Var%ImposedNormalFacesUV  => &
         Me%External_Var%ImposedNormalFacesV


         !Wind
         if (Me%ComputeOptions%Wind /= NoWind_) &
            Me%External_Var%TauWind_UV       => &
            Me%External_Var%TauWindV

         !if (Me%Relaxation%Velocity)         then
            
            !Me%Relaxation%ReferenceVelUV  => &
            !Me%Relaxation%ReferenceVelV
            
            !Me%Relaxation%BackgroundVelUV  => &
            !Me%Relaxation%BackgroundVelV

         !endif
        
        if (Me%SubModel%ON)   then

            Me%SubModel%UV_New   => Me%SubModel%V_New
            Me%SubModel%UV_Old   => Me%SubModel%V_Old
            Me%SubModel%DUVZ_Old => Me%SubModel%DVZ_Old
            Me%SubModel%qXY      => Me%SubModel%qY
            Me%SubModel%qYX      => Me%SubModel%qX
                    
        endif


         !Waves
         if (Me%ComputeOptions%WaveStress) then
            Me%External_Var%TauWaves_UV => Me%External_Var%TauWavesV
         endif


    End Subroutine  AssociateDirectionY

    !End------------------------------------------------------------



    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Direction                                                                    !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine  AssociateDirectionX

        !Arguments------------------------------------------------------------




        !Begin----------------------------------------------------------------

         Me%Direction%XY   =  DirectionX_
         Me%Direction%YX   =  DirectionY_
         Me%Direction%di   =  0
         Me%Direction%dj   =  1   

         !Baroclinic 
         Me%Forces%Rox3XY  => Me%Forces%Rox3X

         !Flow
         Me%Velocity%Horizontal%UV%Old  => &
         Me%Velocity%Horizontal%U%Old

         Me%Velocity%Horizontal%UV%New  => &
         Me%Velocity%Horizontal%U%New


         Me%Velocity%Horizontal%VU%Old  => &
         Me%Velocity%Horizontal%V%Old

         Me%Velocity%Horizontal%VU%New  => &
         Me%Velocity%Horizontal%V%New

         if (.not. Me%ComputeOptions%BaroclinicRadia == NoRadiation_) then
         
             Me%VelBaroclinic%UV%Old  => &
             Me%VelBaroclinic%U%Old

             Me%VelBaroclinic%UV%New  => &
             Me%VelBaroclinic%U%New


             Me%VelBaroclinic%VU%Old  => &
             Me%VelBaroclinic%V%Old

             Me%VelBaroclinic%VU%New  => &
             Me%VelBaroclinic%V%New


             Me%VelBaroclinic%ImposedNormXY  => &
             Me%VelBaroclinic%ImposedNormX

             Me%VelBaroclinic%ImposedTangXY  => &
             Me%VelBaroclinic%ImposedTangX

             Me%VelBaroclinic%UV2D  => &
             Me%VelBaroclinic%U2D
      
         
         endif   

         Me%WaterFluxes%XY              => &
         Me%WaterFluxes%X

         Me%WaterFluxes%YX              => &
         Me%WaterFluxes%Y

         !3D Geometry
         Me%External_Var%Volume_UV => &
         Me%External_Var%Volume_U  

         Me%External_Var%Area_UV   => &
         Me%External_Var%Area_U

         Me%External_Var%Area_VU   => &
         Me%External_Var%Area_V

         Me%External_Var%WaterColumnUV => &
         Me%External_Var%WaterColumnU

         Me%External_Var%WaterColumnVU => &
         Me%External_Var%WaterColumnV

         Me%External_Var%DUZ_VZ        => &
         Me%External_Var%DUZ


         Me%External_Var%KFloor_UV => &
         Me%External_Var%KFloor_U

         Me%External_Var%KFloor_VU => &
         Me%External_Var%KFloor_V

         !Horizontal Grid
         Me%External_Var%DZX_ZY    => &
         Me%External_Var%DZX

         Me%External_Var%DZY_ZX    => &
         Me%External_Var%DZY


         Me%External_Var%DXX_YY    => &
         Me%External_Var%DXX

         Me%External_Var%DUX_VY    => &
         Me%External_Var%DUX

         Me%External_Var%DVY_UX    => &
         Me%External_Var%DVY

         Me%External_Var%DYY_XX    => &
         Me%External_Var%DYY


         !3D Mapping
         Me%External_Var%ComputeFaces3D_UV   => &
         Me%External_Var%ComputeFaces3D_U

         Me%External_Var%ComputeFaces3D_VU   => &
         Me%External_Var%ComputeFaces3D_V

         Me%External_Var%LandBoundaryFacesUV => &
         Me%External_Var%LandBoundaryFacesU

         Me%External_Var%LandBoundaryFacesVU => &
         Me%External_Var%LandBoundaryFacesV

!         Me%External_Var%UnCoveredFaces3D_UV   => &
!         Me%External_Var%UnCoveredFaces3D_U

         !Horizontal Mapping

         Me%External_Var%BoundaryFacesUV     => &
         Me%External_Var%BoundaryFacesU

         Me%External_Var%BoundaryFacesVU     => &
         Me%External_Var%BoundaryFacesV


         Me%External_Var%ImposedTangentialFacesUV  => &
         Me%External_Var%ImposedTangentialFacesU

         Me%External_Var%ImposedTangentialFacesVU  => &
         Me%External_Var%ImposedTangentialFacesV

         Me%External_Var%ImposedNormalFacesUV      => &
         Me%External_Var%ImposedNormalFacesU


         !Wind
         if (Me%ComputeOptions%Wind /= NoWind_) &
            Me%External_Var%TauWind_UV       => &
            Me%External_Var%TauWindU


!         if (Me%Relaxation%Velocity)         then

!            Me%Relaxation%ReferenceVelUV  => &
!            Me%Relaxation%ReferenceVelU

!            Me%Relaxation%BackgroundVelUV  => &
!            Me%Relaxation%BackgroundVelU      

!         endif

        if (Me%SubModel%ON)   then

            Me%SubModel%UV_New   => Me%SubModel%U_New
            Me%SubModel%UV_Old   => Me%SubModel%U_Old
            Me%SubModel%DUVZ_Old => Me%SubModel%DUZ_Old
            Me%SubModel%qXY      => Me%SubModel%qX
            Me%SubModel%qYX      => Me%SubModel%qY
                    
        endif

        
        !Waves
        if (Me%ComputeOptions%WaveStress) then
            Me%External_Var%TauWaves_UV => Me%External_Var%TauWavesU
        endif


    End Subroutine  AssociateDirectionX

    !End------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Direction                                                                    !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine  NullifyAuxiliarPointers

        !Arguments------------------------------------------------------------




        !Begin----------------------------------------------------------------


         nullify(Me%Forces%Rox3XY)

         !Flow
         nullify(Me%Velocity%Horizontal%UV%Old)

         nullify(Me%Velocity%Horizontal%UV%New)

         nullify(Me%Velocity%Horizontal%VU%Old)

         nullify(Me%Velocity%Horizontal%VU%New)

         nullify(Me%WaterFluxes%XY)

         nullify(Me%WaterFluxes%YX)

         !3D Geometry
         nullify(Me%External_Var%Volume_UV)

         nullify(Me%External_Var%Area_UV)

         nullify(Me%External_Var%Area_VU)

         nullify(Me%External_Var%KFloor_UV)

         nullify(Me%External_Var%KFloor_VU)

         nullify(Me%External_Var%WaterColumnUV)

         nullify(Me%External_Var%WaterColumnVU)

         !Horizontal Grid
         nullify(Me%External_Var%DZX_ZY)

         nullify(Me%External_Var%DZY_ZX)

         nullify(Me%External_Var%DXX_YY)

         nullify(Me%External_Var%DUX_VY)

         nullify(Me%External_Var%DVY_UX)

         nullify(Me%External_Var%DYY_XX)


         !3D Mapping
         nullify(Me%External_Var%ComputeFaces3D_UV)

         nullify(Me%External_Var%ComputeFaces3D_VU)

         nullify(Me%External_Var%LandBoundaryFacesUV)

!         nullify(Me%External_Var%UnCoveredFaces3D_UV)

         !Horizontal Mapping

         nullify(Me%External_Var%BoundaryFacesUV)

         nullify(Me%External_Var%BoundaryFacesVU)

         !Wind
         if (Me%ComputeOptions%Wind /= NoWind_) &
            nullify(Me%External_Var%TauWind_UV)

      
         !Reference velocities
!         if (Me%Relaxation%Velocity)         then

!            nullify(Me%Relaxation%ReferenceVelUV)

!            nullify(Me%Relaxation%BackgroundVelUV)      

!         endif


         !Waves
         if (Me%ComputeOptions%WaveStress) then
            nullify(Me%External_Var%TauWaves_UV)
        endif



    End Subroutine  NullifyAuxiliarPointers

    !End------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the effect of all the explicit forces ( Baroclinic and      !
    !  barotropic water pressure, Coriolis, Atmospheric pressure,                          !
    !  Horizontal transport - covection + diffusion)                                       !
    !  in the velocity evolution                                                           !
    !                                                                                      !
    ! Input : Flow, Geometry, Mapping, Forces                                              !
    ! OutPut: TiCoef_3D                                                                      !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Compute_Velocity 

        !Variables Categories  
            !Geometry  : WaterLevel_New, DUX_VY, DZX_ZY 
            !WaterProp : Density
            !Forces    : Inertial_Aceleration, Horizontal_Transport, ROX3, AtmPressure 
            !Time      : DT_Velocity
            !Mapping   : ComputeFaces3D_UV, KFloor_UV, Direction
            !Equations : TiCoef_3D

         
        !Variables Direction Dependent
            !DUX_VY, DZX_ZY, ComputeFaces3D_UV, KFloor_UV, Direction


        !Arguments------------------------------------------------------------


        !Local----------------------------------------------------------------
        real(8), dimension(:,:,:), pointer  :: ECoef_3D
        real,    dimension(:,:,:), pointer  :: DCoef_3D, FCoef_3D, TiCoef_3D, &
                                               Velocity_UV_Old, Velocity_UV_New
        integer, dimension(:,:,:), pointer  :: ComputeFaces3D_UV, LandBoundaryFacesUV, &
                                               WaterPoints3D

        logical                             :: ImplicitAdvection
        integer                             :: IJmin, IJmax, JImin, JImax, di, dj
        
        integer                             :: i, j, k, IUB, ILB, JUB, JLB, KUB, KLB

        integer                             :: FaceAdjacentToWater, Coef

        !Begin----------------------------------------------------------------


        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Compute_Velocity")

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di          =  Me%Direction%di
        dj          =  Me%Direction%dj

        ImplicitAdvection = Me%ComputeOptions%ImplicitAdvection


        DCoef_3D  => Me%Coef%D3%D
        ECoef_3D  => Me%Coef%D3%E
        FCoef_3D  => Me%Coef%D3%F
        TiCoef_3D => Me%Coef%D3%Ti

        ComputeFaces3D_UV   => Me%External_Var%ComputeFaces3D_UV
        LandBoundaryFacesUV => Me%External_Var%LandBoundaryFacesUV

        Velocity_UV_Old => Me%Velocity%Horizontal%UV%Old
        Velocity_UV_New => Me%Velocity%Horizontal%UV%New

        WaterPoints3D   => Me%External_Var%WaterPoints3D


        !End   - Shorten variables name
        
            

do3 :   do K = KLB, KUB
do1 :   do J = JLB, JUB !rcm 11
do2 :   do I = ILB, IUB
            DCoef_3D (I,J,K) = 0.0
            ECoef_3D (I,J,K) = 1.0
            FCoef_3D (I,J,K) = 0.0 
            TICoef_3D(I,J,K) = Velocity_UV_Old(I,J,K)
        end do do2
        end do do1
        end do do3

        if (ImplicitAdvection)                                                          &
            call Modify_Implicit_UX_VY  


        call Velocity_ExplicitForces  


        call VelVerticalDiffusionBoundaries 


cd3D:   if (ImplicitAdvection .and. KUB > 1) then

            IJmin = ILB * dj + JLB * di
            IJmax = IUB * dj + JUB * di

            JImin = ILB * di + JLB * dj
            JImax = IUB * di + JUB * dj

            call THOMAS_3D(IJmin, IJmax, JImin, JImax, KLB, KUB, di, dj,                 &
                           DCoef_3D, ECoef_3D, FCoef_3D, TiCoef_3D, Velocity_UV_New,     &
                           Me%VECG_3D, Me%VECW_3D)

do33 :      do K = KLB, KUB
do13 :      do J = JLB, JUB !rcm 11
do23 :      do I = ILB, IUB
                DCoef_3D (I,J,K) = 0.0
                ECoef_3D (I,J,K) = 1.0
                FCoef_3D (I,J,K) = 0.0 
                TICoef_3D(I,J,K) = Velocity_UV_New(I,J,K)
            end do do23
            end do do13
            end do do33

        endif cd3D


        if (KUB > 1) then

            if (Me%ComputeOptions%VerticalDiffusion)                        &
                call Velocity_VerticalDiffusion  

            if (Me%ComputeOptions%VerticalAdvection)                        &
                call Velocity_VerticalAdvection 

        endif

        if (Me%ComputeOptions%WaveStress) then

            call Velocity_WaveStress

        endif


        do  k = KLB, KUB
        do  j = JLB, JUB
        do  i = ILB, IUB
            ! Large values (FillReal_Value) in non covered faces  
            TiCoef_3D (i, j, k) = TiCoef_3D (i, j, k) * ComputeFaces3D_UV(i, j, k) +     &
                                  (1. - ComputeFaces3D_UV(i, j, k)) * FillValueReal                     

            ! Land boundary condition - velocity zero in faces that 
            ! have water in one side and land in another 
            TiCoef_3D (i, j, k) = TiCoef_3D (i, j, k) * (1. - LandBoundaryFacesUV(i, j, k))

            ! UnCovered faces condition - velocity zero in faces that 
            ! are uncovered
            !The UncoveredFaces disapaered from the module map

!            TiCoef_3D (i, j, k) = TiCoef_3D (i, j, k) * (1. - UnCoveredFacesUV(i, j, k))

            Coef = WaterPoints3D(i, j, k) + WaterPoints3D(i-di, j-dj, k)

            if (Coef > 0) Coef = 1

            FaceAdjacentToWater = (1. - ComputeFaces3D_UV(i, j, k)) * Coef
                            
            TiCoef_3D (i, j, k) = TiCoef_3D (i, j, k) * (1 - FaceAdjacentToWater)

            
        enddo
        enddo
        enddo


cd2D:   if (KUB == 1 .and. ImplicitAdvection) then !If the model is 2D then the implicit direction is in the horizontal

            IJmin = ILB * dj + JLB * di
            IJmax = IUB * dj + JUB * di

            JImin = ILB * di + JLB * dj
            JImax = IUB * di + JUB * dj


            call THOMAS_3D(IJmin, IJmax, JImin, JImax, KLB, KUB, di, dj,                 &
                           DCoef_3D, ECoef_3D, FCoef_3D, TiCoef_3D, Velocity_UV_New,     &
                           Me%VECG_3D, Me%VECW_3D)

        else cd2D ! The implicit direction is in the vertical


            ! Vertical direction implicit
            call THOMASZ(ILB, IUB, JLB, JUB, KLB, KUB, DCoef_3D, ECoef_3D,               &
                         FCoef_3D, TiCoef_3D, Velocity_UV_New,                           &
                         Me%VECG_3D, Me%VECW_3D)

        endif cd2D

        call InstantMixingSmallDepths

        call Velocity_OpenBoundary 

        if (Me%CyclicBoundary%ON)  then

            if (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                Me%CyclicBoundary%Direction == DirectionXY_)  then
                call CyclicBoundVectNormal    ( Vector = Velocity_UV_New)
            endif

            if (Me%CyclicBoundary%Direction == Me%Direction%YX .or. &
                Me%CyclicBoundary%Direction == DirectionXY_)  then
                call CyclicBoundVectTangential( Vector = Velocity_UV_New)
            endif

        endif


        !PCL
        if (Me%Relaxation%Velocity)                                         &
            call VelocityRelaxation 


        !Nullify auxiliar variables
        nullify (DCoef_3D, ECoef_3D, FCoef_3D, TiCoef_3D)

        nullify (WaterPoints3D, LandBoundaryFacesUV)

        nullify (Velocity_UV_Old, Velocity_UV_New)

        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Compute_Velocity")

    end Subroutine Compute_Velocity

    !------------------------------------------------------------------------------
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine mixes instantaniously the watercolumn in small depths               ! 
    !                                                                                      !
    ! Input : Flow, Geometry                                                               !
    ! OutPut: VelocityU, V                                                                 !
    ! Author: Frank (00/10)                                                                !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    subroutine InstantMixingSmallDepths
        
        !Arguments-------------------------------------------------------------


        !Local-----------------------------------------------------------------
        real,    dimension(:, :, :), pointer        :: Area_UV
        real,    dimension(:, :, :), pointer        :: Velocity_UV_New
        real,    dimension(:, :   ), pointer        :: WaterColumnUV
        integer, dimension(:, :, :), pointer        :: ComputeFaces3D_UV
        integer, dimension(:, :   ), pointer        :: KFloor_UV
        real(8)                                     :: TotalArea, TotalFlux
        real                                        :: WaterColumn2D
        integer                                     :: ILB, IUB, i
        integer                                     :: JLB, JUB, j
        integer                                     :: Kbottom, KUB, k

        !Begin-----------------------------------------------------------------
        ILB                  =  Me%WorkSize%ILB
        IUB                  =  Me%WorkSize%IUB
        JLB                  =  Me%WorkSize%JLB
        JUB                  =  Me%WorkSize%JUB
        KUB                  =  Me%WorkSize%KUB
        WaterColumn2D        =  Me%ComputeOptions%WaterColumn2D
        
        Velocity_UV_New      => Me%Velocity%Horizontal%UV%New
        Area_UV              => Me%External_Var%Area_UV
        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        WaterColumnUV        => Me%External_Var%WaterColumnUV
        KFloor_UV            => Me%External_Var%KFloor_UV

doi:    do j=JLB, JUB
doj:    do i=ILB, IUB
            
            
cd1:        if (ComputeFaces3D_UV(i, j, KUB) == Covered  .and.                           &
                WaterColumnUV(i, j) <= WaterColumn2D) then 

                Kbottom = KFloor_UV(i, j)

                TotalArea = 0.
                TotalFlux = 0.

dok1:           do  k = Kbottom, KUB            

                    TotalArea = TotalArea + dble(Area_UV        (i, j, k))
                    TotalFlux = TotalFlux + dble(Area_UV        (i, j, k)) *             &
                                            dble(Velocity_UV_New(i, j, k))

                enddo dok1

                Velocity_UV_New(i, j, Kbottom:KUB) = real(TotalFlux/TotalArea)

            endif cd1

        enddo doj
        enddo doi


        nullify(Velocity_UV_New  )
        nullify(Area_UV          )
        nullify(ComputeFaces3D_UV) 
        nullify(WaterColumnUV    )
        nullify(KFloor_UV        )
        
    end subroutine InstantMixingSmallDepths
         

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the horizontal velocity from the horizontal fluxes.         ! 
    !                                                                                      !
    ! Input : Flow, Geometry                                                               !
    ! OutPut: VelocityU, V                                                                 !
    ! Author: Frank (00/10)                                                                !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    subroutine Compute_VelocityFromFluxes
        
        !Arguments-------------------------------------------------------------


        !Local-----------------------------------------------------------------
        real,    dimension(:, :, :), pointer        :: Area_U, Area_V
        real,    dimension(:, :, :), pointer        :: VelocityU, VelocityV
        real(8), dimension(:, :, :), pointer        :: WaterFluxX, WaterFluxY
        integer                                     :: ILB, IUB, i
        integer                                     :: JLB, JUB, j
        integer                                     :: KLB, KUB, k



!        call ReadLock_ModuleGeometry

        !Shorten Varible Names
        Area_U => Me%External_Var%Area_U
        Area_V => Me%External_Var%Area_V

        VelocityU => Me%Velocity%Horizontal%U%New
        VelocityV => Me%Velocity%Horizontal%V%New

        WaterFluxX => Me%WaterFluxes%X
        WaterFluxY => Me%WaterFluxes%Y

        ILB = Me%WorkSize%ILB
        IUB = Me%WorkSize%IUB
        JLB = Me%WorkSize%JLB
        JUB = Me%WorkSize%JUB
        KLB = Me%WorkSize%KLB
        KUB = Me%WorkSize%KUB


        do k = KLB, KUB
        do j = JLB, JUB + 1
        do i = ILB, IUB
            VelocityU(i, j, k) = WaterFluxX(i, j, k) / Area_U(i, j, k)
        enddo
        enddo
        enddo

        do k = KLB, KUB
        do j = JLB, JUB
        do i = ILB, IUB + 1
            VelocityV(i, j, k) = WaterFluxY(i, j, k) / Area_V(i, j, k)
        enddo
        enddo
        enddo

        !Nullify aux variable
        nullify (Area_U, Area_V)
        nullify (VelocityU, VelocityV)
        nullify (WaterFluxX,WaterFluxY )

!        call ReadUnLock_ModuleGeometry

    end subroutine Compute_VelocityFromFluxes



    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This suborutine compute the water level elevation                                    !
    !                                                                                      !
    ! Input : Geomtry, Flow, Mapping, Time steps                                           !
    ! OutPut: Coefficients of the  linear system equation                                  !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine Compute_WaterLevel 
        
        !Variables Categories  
            !Geometry  : Volume_UV, Area_UV, DUX_VY, DVY_UX, DXX_YY, DYY_XX, DZX_ZY  
            !Flow      : Velocity_UV_Old, Velocity_VU_New, Velocity_VU_Old, Vert_Viscosity
            !WaterProp : Density
            !Boundary  : AtmPressure, Chezy
            !Forces    : Horizontal_Transport, Rox3, 
            !Time      : DT_Elevation, DT_Velocity
            !Mapping   : ComputeFaces3D_UV, KFloor_UV, Direction
            !Equations : DCoef_2D, ECoef_2D, FCoef_2D, TiCoef_2D

        !Variables Direction Dependent
           !Volume_UV, Area_UV, DUX_VY, DVY_UX, DXX_YY, DYY_XX, DZX_ZY
           !Velocity_UV_Old, Velocity_VU_New, Velocity_VU_Old, ComputeFaces3D_UV, KFloor_UV, Direction 

        !Arguments------------------------------------------------------------

         

        !Local---------------------------------------------------------------

        real(8), dimension(:,:),   pointer  :: ECoef_2D
        real,    dimension(:,:),   pointer  :: DCoef_2D, FCoef_2D, TiCoef_2D,  &
                                               WaterLevel_Old, WaterLevel_New, &
                                               RadCoef_2D, TiRadCoef_2D
         
        integer                             :: IUB, ILB, JUB, JLB
        integer                             :: IJmin, IJmax, JImin, JImax 
        integer                             :: I, J, di, dj, DirectionXY


        !Begin----------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Compute_WaterLevel")

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB

        DirectionXY =  Me%Direction%XY
        di          =  Me%Direction%di
        dj          =  Me%Direction%dj

        DCoef_2D  => Me%Coef%D2%D
        ECoef_2D  => Me%Coef%D2%E
        FCoef_2D  => Me%Coef%D2%F
        TiCoef_2D => Me%Coef%D2%Ti



        RadCoef_2D   => Me%Coef%D2%Rad
        TiRadCoef_2D => Me%Coef%D2%TiRad

        WaterLevel_Old => Me%WaterLevel%Old
        WaterLevel_New => Me%WaterLevel%New

        !End   - Shorten variables name

        !Begin - Compute

do1 :   do J = JLB, JUB !rcm 12
do2 :   do I = ILB, IUB
            DCoef_2D (I,J) = 0.0 
            ECoef_2D (I,J) = 1.0
            FCoef_2D (I,J) = 0.0
            TiCoef_2D(I,J) = WaterLevel_Old(I,J)
        end do do2
        end do do1


cd1:    if (Me%ComputeOptions%BarotropicRadia == FlatherWindWave_ .or.      &
            Me%ComputeOptions%BarotropicRadia == FlatherLocalSolution_) then 

do33 :  do J = JLB, JUB !rcm 13
do34 :  do I = ILB, IUB
            RadCoef_2D  (I,J) =  0.0
            TiRadCoef_2D(I,J) =  0.0
        end do do34
        end do do33
        end if cd1


        !Implicit bottom friction
        call WaterLevel_BottomFriction     
        call WaterLevel_BarotropicPressure 
        call WaterLevel_ExplicitForces     
        call WaterLevel_WaterFluxes        

        call WaterLevel_OpenBoundary       

        call WaterLevelDischarges          

        IJmin = ILB * dj + JLB * di
        IJmax = IUB * dj + JUB * di

        JImin = ILB * di + JLB * dj
        JImax = IUB * di + JUB * dj

        if (.not. Me%CyclicBoundary%ON .or.                                              &
                 (Me%CyclicBoundary%ON .and. Me%CyclicBoundary%Direction == Me%Direction%YX))  then

            call THOMAS_2D(IJmin, IJmax, JImin, JImax, di, dj, DCoef_2D, ECoef_2D,       &
                           FCoef_2D, TiCoef_2D, WaterLevel_New,                          &
                           Me%VECG_2D, Me%VECW_2D)

        else
            
            call WaterLevel_CyclicBoundary 

        endif


        if (Me%Relaxation%WaterLevel)                                       &
            call WaterLevelRelaxation        

        ! guillaume nogueira : aqui relaxa-se o nivel com altimetria
        if (Me%ComputeOptions%AltimetryAssimilation%Yes)                    &
            call WaterLevelRelaxationAltimetry

        !In this subroutine model verifies if the level is below a critical level 
        !This is critical level is a warning that says below this level there is a very 
        !by probability of negative volumes
        call WaterLevelCorrection         




        !Nullify auxiliar variables
        nullify (DCoef_2D, ECoef_2D, FCoef_2D, TiCoef_2D)

        nullify (WaterLevel_Old, WaterLevel_New)


        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Compute_WaterLevel")

   end Subroutine Compute_WaterLevel


    !------------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !In this subroutine model verifies if the level is below a critical level              !
    !This is critical level is a warning that says below this level there is a very        !
    !big probability of negative volumes                                                   !
    !To avoid this problem the water level is corrected and put equal to this              !
    !critical                                                                              !
    !                                                                                      !
    ! Input : Mapping                                                                      !
    ! OutPut: Water Level in the open boundary                                             !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine WaterLevelCorrection 

        !Arguments--------------------------------------------------------------
         

        !External---------------------------------------------------------------

!        character(LEN = StringLength) :: string

!        integer :: WARNING_, INTERNAL_

        !Local------------------------------------------------------------------

        integer                             :: i, j, STAT_CALL
!        integer                             :: M
        integer                             :: IUB, ILB, JUB, JLB, KUB
        integer, pointer, dimension (:,:,:) :: WaterPoints3D

        real,    dimension(:,:), pointer    :: WaterLevel_New, Bathymetry, VolumeCreated, &
                                               DUX, DVY 
        real                                :: MinWaterColumn, WaterLevelMin, dh

!        character(LEN = StringLength)       :: auxi,  auxj
!        character(LEN = 5           )       :: auxii, auxjj
        logical                             :: OKWarnning, CorrectWaterLevel 

        !Begin------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB

        WaterLevel_New    => Me%WaterLevel%New
        WaterPoints3D     => Me%External_Var%WaterPoints3D
        VolumeCreated     => Me%WaterLevel%VolumeCreated

        DUX            => Me%External_Var%DUX
        DVY            => Me%External_Var%DVY

        WaterLevelMin     =  Me%ComputeOptions%WaterLevelMin
        CorrectWaterLevel =  Me%ComputeOptions%CorrectWaterLevel
       
        !End   - Shorten variables name

       !Gets Bathymetry
        call GetGridData(Me%ObjGridData, &
                           Bathymetry, STAT = STAT_CALL)
        
        if (STAT_CALL /= SUCCESS_) &
            stop 'WaterLevelCorrection - ModuleHydrodynamic - ERR01'


        call GetGeometryMinWaterColumn(Me%ObjGeometry, &
                                       MinWaterColumn, STAT = STAT_CALL)
        
        if (STAT_CALL /= SUCCESS_) &
            stop 'WaterLevelCorrection - ModuleHydrodynamic - ERR02'

        OKWarnning = .false.
         
do1:    do  j = JLB, JUB
do2:    do  i = ILB, IUB
                        
cd1:        if (WaterPoints3D(i, j, KUB) == OpenPoint) then

                !By defaul this first correction is always made because the water level can not
                !be located below the bottom

cd2:            if (WaterLevel_New(i, j) < (- Bathymetry(i, j) + MinWaterColumn / 2.)) then

                    dh = (- WaterLevel_New(i, j) - Bathymetry(i, j) + MinWaterColumn / 2.)

                    VolumeCreated (i, j) = VolumeCreated(i, j)  + dh * DUX(i, j) * DVY(i, j)

                    WaterLevel_New(i, j) = - Bathymetry(i, j) + MinWaterColumn / 2.

                    OKWarnning = .true.

                endif cd2


                !This second correction is optional and is used when the user wants to 
                !define a reference level below which the water level is corrected.
cd3:            if (CorrectWaterLevel .and. WaterLevel_New(i, j) < (WaterLevelMin + MinWaterColumn / 2.)) then

                    WaterLevel_New(i, j) = WaterLevelMin + MinWaterColumn / 2.

                    OKWarnning = .true.

                endif cd3
        
!cd4:            if (OKWarnning) then

                    !Disables warnings in the corners
!                    if ((i==ILB .and. j == JLB) .or.  &
!                        (i==ILB .and. j == JUB) .or.  &
!                        (i==IUB .and. j == JLB) .or.  &
!                        (i==IUB .and. j == JUB)) Cyclic do2


!do3 :               do M = 1, StringLength
!                        auxi(M:M) = space
!                        auxj(M:M) = space
!                    end do do3

             
!                    write(auxi,*) i
!                    auxi = adjustl(trim(auxi))

             
!                    write(auxj,*) j
!                    auxj = adjustl(trim(auxj))
!

!do4 :               do M = 1, 5
!                        auxii(M:M) = auxi(M:M)
!                        auxjj(M:M) = auxj(M:M)
!                    end do do4


!                    string = adjustl(trim('In point I='//auxii//' and J='//auxjj//' was created water.'))

!                    call SetError (WARNING_, INTERNAL_, String)

!                    OKWarnning = .false.

!                endif cd4
            endif cd1

        enddo do2
        enddo do1

       !UnGets Bathymetry
        call UnGetGridData(Me%ObjGridData,                              &
                           Bathymetry, STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_) &
            stop 'WaterLevelCorrection - ModuleHydrodynamic - ERR03'


        nullify (WaterLevel_New, VolumeCreated, DUX, DVY)
        nullify (WaterPoints3D )

        !----------------------------------------------------------------------

    End Subroutine WaterLevelCorrection

    !--------------------------------------------------------------------------



    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This subroutine compute the water level in the open boundary                         !
    !                                                                                      !
    ! Input : Mapping                                                                      !
    ! OutPut: Water Level in the open boundary                                             !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine WaterLevel_OpenBoundary 

        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------
        integer :: i, j
        integer, pointer, dimension (:,:,:) :: WaterPoints3D

        real,    dimension(:,:), pointer    :: TiCoef_2D
        logical                             :: Imposed_BoundaryWave

        integer                             :: IUB, ILB, JUB, JLB, KUB, BarotropicRadia



        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB

        TiCoef_2D     => Me%Coef%D2%Ti
        WaterPoints3D => Me%External_Var%WaterPoints3D

        Imposed_BoundaryWave =  Me%ComputeOptions%Imposed_BoundaryWave
        BarotropicRadia      =  Me%ComputeOptions%BarotropicRadia

        
        !End   - Shorten variables name

          
        do  j = JLB, JUB
        do  i = ILB, IUB

            !A large negative water level (FillReal_Value) is imposed in non waterpoints
            TiCoef_2D(i, j) = TiCoef_2D(i, j) * WaterPoints3D(i, j, KUB) + &
                               (1. - WaterPoints3D(i, j, KUB)) * FillValueReal

        enddo
        enddo


        if (Imposed_BoundaryWave) then 
           
            call WaterLevel_ImposedWave 

        else if (BarotropicRadia == FlatherWindWave_) then 
 
            !Extrapolate in the implicit direction using a radiation condition the water level 
            !for the boundary points
            call WaterLevel_FlatherWindWave (                                              &
                                       WaterFlux_XY      = Me%WaterFluxes%XY,                 &
                                       WaterFlux_YX      = Me%WaterFluxes%YX,                 &
                                       WaterColumnUV     = Me%External_Var%WaterColumnUV,     &
                                       DUX_VY            = Me%External_Var%DUX_VY,            &
                                       DVY_UX            = Me%External_Var%DVY_UX,            &
                                       DYY_XX            = Me%External_Var%DYY_XX,            &
                                       ComputeFaces3D_UV = Me%External_Var%ComputeFaces3D_UV, &
                                       ComputeFaces3D_VU = Me%External_Var%ComputeFaces3D_VU, &
                                       BoundaryFacesUV   = Me%External_Var%BoundaryFacesUV,   &
                                       Kfloor_UV         = Me%External_Var%Kfloor_UV,         &
                                       Kfloor_VU         = Me%External_Var%Kfloor_VU,         &
                                       di                = Me%Direction%di,                   &
                                       dj                = Me%Direction%dj,                   &
                                       ImplicitFaces     = .true.)

            !Extrapolate in the explicit direction using a radiation condition the water level 
            !for the boundary points
            call WaterLevel_FlatherWindWave (                                              &
                                       WaterFlux_XY      = Me%WaterFluxes%YX,                 &
                                       WaterFlux_YX      = Me%WaterFluxes%XY,                 &
                                       WaterColumnUV     = Me%External_Var%WaterColumnVU,     &
                                       DUX_VY            = Me%External_Var%DVY_UX,            &
                                       DVY_UX            = Me%External_Var%DUX_VY,            &
                                       DYY_XX            = Me%External_Var%DXX_YY,            &
                                       ComputeFaces3D_UV = Me%External_Var%ComputeFaces3D_VU, &
                                       ComputeFaces3D_VU = Me%External_Var%ComputeFaces3D_UV, &
                                       BoundaryFacesUV   = Me%External_Var%BoundaryFacesVU,   &
                                       Kfloor_UV         = Me%External_Var%Kfloor_VU,         &
                                       Kfloor_VU         = Me%External_Var%Kfloor_UV,         &
                                       di                = Me%Direction%dj,                   &
                                       dj                = Me%Direction%di,                   &
                                       ImplicitFaces     = .false.)


        else if  (BarotropicRadia == FlatherLocalSolution_) then 
        
            call WaterLevel_FlatherLocalSolution 
 
        else if (BarotropicRadia  == BlumbergKantha_      ) then !MRV

            call WaterLevel_BlumbergKantha 

        endif                  

        
        
        !Nullify auxiliar variables
        nullify (TiCoef_2D)
        nullify (WaterPoints3D)

        !----------------------------------------------------------------------

    End Subroutine WaterLevel_OpenBoundary

    !--------------------------------------------------------------------------


    !------------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This subroutine imposed a specific wave in the open boundary                         !
    !                                                                                      !
    ! Input : Mapping                                                                      !
    ! OutPut: Water Level in the open boundary                                             !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine WaterLevel_ImposedWave 

        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------
        integer :: i, j, STAT_CALL

        integer, pointer, dimension (:,:)   :: BoundaryPoints

        real(8), dimension(:,:), pointer    :: ECoef_2D
        real,    dimension(:,:), pointer    :: DCoef_2D, FCoef_2D, TiCoef_2D, &
                                               ImposedElevation
        integer                             :: IUB, ILB, JUB, JLB



        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB

        DCoef_2D  => Me%Coef%D2%D
        ECoef_2D  => Me%Coef%D2%E
        FCoef_2D  => Me%Coef%D2%F
        TiCoef_2D => Me%Coef%D2%Ti

        BoundaryPoints   => Me%External_Var%BoundaryPoints

cd1:    if (Me%SubModel%ON) then

            ImposedElevation => Me%SubModel%Z

       
    !End   - Shorten variables name

cd3:        if (.not. Me%SubModel%Set) then 
            
                Stop 'Sub. WaterLevel_ImposedWave - ModuleHydrodynamic - ERR01a.'

            endif cd3
       
        !End   - Shorten variables name

        else cd1 

            call Modify_OpenBoundary(Me%ObjOpenBoundary,                    &
                                     Me%CurrentTime,                        &
                                     STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                   &
                Stop 'Sub. WaterLevel_ImposedWave - ModuleHydrodynamic - ERR01.'
            
cd2:        if (Me%ComputeOptions%Compute_Tide) then
                
                call GetImposedElevation(Me%ObjOpenBoundary,                &
                                      ImposedElevation, STAT = STAT_CALL)


                if (STAT_CALL /= SUCCESS_) &
                    Stop 'Sub. WaterLevel_ImposedWave - ModuleHydrodynamic - ERR03.'

            else cd2

                ImposedElevation => Me%WaterLevel%New

            endif cd2

        endif cd1

       
        do  j = JLB, JUB
        do  i = ILB, IUB

           !The water level values imposed in the open boundary points are maintained
            TiCoef_2D(i, j) = TiCoef_2D(i, j) * (1. - BoundaryPoints(i, j)) +            &
                              ImposedElevation(i, j) * BoundaryPoints(i, j) 

            DCoef_2D(i, j)  = DCoef_2D(i, j)  * (1. - BoundaryPoints(i, j))

            ECoef_2D(i, j)  = ECoef_2D(i, j)  * (1. - BoundaryPoints(i, j)) +            &
                              1. * BoundaryPoints(i, j)

            FCoef_2D(i, j)  = FCoef_2D(i, j)  * (1. - BoundaryPoints(i, j))
               
        enddo
        enddo


cd4:    if (.not. Me%SubModel%ON .and. Me%ComputeOptions%Compute_Tide) then

    
            call UnGetOpenBoundary(Me%ObjOpenBoundary, ImposedElevation, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) &
                Stop 'Sub. WaterLevel_ImposedWave - ModuleHydrodynamic - ERR04.'

        else  cd4

            nullify(ImposedElevation)

        endif cd4


        !Nullify auxiliar variables
        nullify (DCoef_2D, ECoef_2D, FCoef_2D, TiCoef_2D)
        nullify (BoundaryPoints)

        !----------------------------------------------------------------------

    End Subroutine WaterLevel_ImposedWave


    !------------------------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This subroutine imposed a Cyclic boundary condition for the water level               !
    !                                                                                      !
    ! Input : Mapping                                                                      !
    ! OutPut: Water Level in the open boundary                                             !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine WaterLevel_CyclicBoundary 

        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------
        integer :: i, j

        integer, pointer, dimension (:,:)   :: BoundaryPoints

        real(8), dimension(:,:),   pointer  :: ECoef_2D
        real,    dimension(:,:),   pointer  :: DCoef_2D, FCoef_2D, TiCoef_2D, WaterLevel_New
        real(8), dimension(:),     pointer  :: b, bb, gam
        real,    dimension(:),     pointer  :: a, c, r, x, u, z

        real                                :: alpha,beta

        integer                             :: IUB, ILB, JUB, JLB !, status

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB

        BoundaryPoints   => Me%External_Var%BoundaryPoints
        WaterLevel_New   => Me%WaterLevel%New

        DCoef_2D  => Me%Coef%D2%D
        ECoef_2D  => Me%Coef%D2%E
        FCoef_2D  => Me%Coef%D2%F
        TiCoef_2D => Me%Coef%D2%Ti

        a  => Me%Coef%D1%a
        b  => Me%Coef%D1%b
        bb => Me%Coef%D1%bb
        c  => Me%Coef%D1%c
        r  => Me%Coef%D1%r
        u  => Me%Coef%D1%u
        x  => Me%Coef%D1%x
        z  => Me%Coef%D1%z
        gam=> Me%Coef%D1%gam

        a  (:) = 0
        b  (:) = 0
        bb (:) = 0
        c  (:) = 0
        r  (:) = 0
        u  (:) = 0
        x  (:) = 0
        z  (:) = 0
        gam(:) = 0
       
       
        !End   - Shorten variables name

XY:     if (Me%Direction%XY == DirectionY_) then

do1:        do  j = JLB + 1, JUB - 1
                  
cd2:            if   (BoundaryPoints(ILB, j) == Boundary .and. BoundaryPoints(IUB, j) == Boundary) then

                    !beta                  = DCoef_2D (IUB-1, j)
                    !alpha                 = FCoef_2D (ILB+1, j)

                    beta                  = DCoef_2D (ILB+1, j)
                    alpha                 = FCoef_2D (IUB-1, j)


                    DCoef_2D (ILB + 1, j) = 0.
                    FCoef_2D (IUB - 1, j) = 0.

                    a(ILB : IUB)      = DCoef_2D  (ILB:IUB, j)
                    b(ILB : IUB)      = ECoef_2D  (ILB:IUB, j)
                    c(ILB : IUB)      = FCoef_2D  (ILB:IUB, j)
                    r(ILB : IUB)      = TiCoef_2D (ILB:IUB, j)

                    call Tridag_cyclic(a, b, c, alpha, beta, r, x, gam, bb, u, z, ILB + 1, IUB - 1)

                    x(ILB) = x(IUB - 1)
                    x(IUB) = x(ILB + 1)

                
                else if (BoundaryPoints(ILB, j) /= Boundary .or. BoundaryPoints(IUB, j) /= Boundary ) then

                    a(ILB : IUB)      = DCoef_2D  (ILB:IUB, j)
                    b(ILB : IUB)      = ECoef_2D  (ILB:IUB, j)
                    c(ILB : IUB)      = FCoef_2D  (ILB:IUB, j)
                    r(ILB : IUB)      = TiCoef_2D (ILB:IUB, j)

                    call tridag(a,b,c,r,x,gam, ILB + 1, IUB - 1)

                    if (Me%CyclicBoundary%Direction == DirectionY_ .or. &
                        Me%CyclicBoundary%Direction == DirectionXY_) then

                        if (BoundaryPoints(ILB, j) == Boundary) x(ILB) = x(IUB - 1)
                        if (BoundaryPoints(IUB, j) == Boundary) x(IUB) = x(ILB + 1)

                    endif

                endif cd2

                WaterLevel_New(ILB:IUB, j) = x(ILB:IUB)


            enddo do1

            if (Me%CyclicBoundary%Direction == DirectionX_ .or. &
                Me%CyclicBoundary%Direction == DirectionXY_) then

                WaterLevel_New(ILB:IUB, JLB) = WaterLevel_New(ILB:IUB, JUB - 1)
                WaterLevel_New(ILB:IUB, JUB) = WaterLevel_New(ILB:IUB, JLB + 1)

            endif


        else if (Me%Direction%XY == DirectionX_) then XY

do2:        do  i = ILB + 1, IUB - 1
                  
cd3:            if   (BoundaryPoints(i, JLB) == Boundary .and. BoundaryPoints(i, JUB) == Boundary) then

                    !beta                  = DCoef_2D (i, JUB-1)
                    !alpha                 = FCoef_2D (i, JLB+1)

                    beta                  = DCoef_2D (i, JLB+1)
                    alpha                 = FCoef_2D (i, JUB-1)

                    DCoef_2D (i, JLB + 1) = 0.
                    FCoef_2D (i, JUB - 1) = 0.

                    a(JLB : JUB)      = DCoef_2D  (i, JLB:JUB)
                    b(JLB : JUB)      = ECoef_2D  (i, JLB:JUB)
                    c(JLB : JUB)      = FCoef_2D  (i, JLB:JUB)
                    r(JLB : JUB)      = TiCoef_2D (i, JLB:JUB)


                    call Tridag_cyclic(a, b, c, alpha, beta, r, x, gam, bb, u, z, JLB + 1, JUB - 1)

                    x(JLB) = x(JUB - 1)
                    x(JUB) = x(JLB + 1)
                
                else if (BoundaryPoints(i, JLB) /= Boundary .or. BoundaryPoints(i, JUB) /= Boundary ) then cd3

                    a(JLB : JUB)      = DCoef_2D  (i, JLB:JUB)
                    b(JLB : JUB)      = ECoef_2D  (i, JLB:JUB)
                    c(JLB : JUB)      = FCoef_2D  (i, JLB:JUB)
                    r(JLB : JUB)      = TiCoef_2D (i, JLB:JUB)

                    call tridag(a,b,c,r,x,gam, JLB + 1, JUB - 1)

                    if (Me%CyclicBoundary%Direction == DirectionX_ .or. &
                        Me%CyclicBoundary%Direction == DirectionXY_) then

                        if (BoundaryPoints(i, JLB) == Boundary) x(JLB) = x(JUB - 1)
                        if (BoundaryPoints(i, JUB) == Boundary) x(JUB) = x(JLB + 1)

                    endif

                endif cd3

                WaterLevel_New(i, JLB:JUB) = x(JLB:JUB)


            enddo do2

            if (Me%CyclicBoundary%Direction == DirectionY_ .or. &
                Me%CyclicBoundary%Direction == DirectionXY_) then

                WaterLevel_New(ILB, JLB:JUB) = WaterLevel_New(IUB-1, JLB:JUB)
                WaterLevel_New(IUB, JLB:JUB) = WaterLevel_New(ILB+1, JLB:JUB)

            endif

        endif XY


        !Nullify auxiliar variables
        nullify (ECoef_2D, DCoef_2D, FCoef_2D, TiCoef_2D, BoundaryPoints, WaterLevel_New)

        nullify (a, b, bb, c, r, u, x, z, gam)


        !----------------------------------------------------------------------

    End Subroutine WaterLevel_CyclicBoundary


    subroutine CyclicCoef2D ( TiCoef_2D, AuxExplicit, DT_AreaCell1,                      &
                             DT_AreaCell2, I, J, iSouth, jWest,                          &
                             Dcoef_2D, ECoef_2D, FCoef_2D, AuxImplicit, Direction)

        !Arguments------------------------------------------------------------
        real,    dimension(:,:),             pointer  :: TiCoef_2D
        real   , intent (IN)                          :: AuxExplicit,                    &
                                                         DT_AreaCell1, DT_AreaCell2
        integer, intent (IN)                          :: I, J, iSouth, jWest


        real(8), dimension(:,:),   optional, pointer  :: ECoef_2D
        real,    dimension(:,:),   optional, pointer  :: DCoef_2D, FCoef_2D 
        real   , intent (IN),      optional           :: AuxImplicit
        integer, intent (IN),      optional           :: Direction
        !Local---------------------------------------------------------------------


        integer, pointer, dimension (:,:)   :: BoundaryPoints

        integer                             :: IUB, ILB, JUB, JLB, I_Down, J_Down
        integer                             :: Direction_
        logical                             :: ComputeFace

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB

        BoundaryPoints   => Me%External_Var%BoundaryPoints
       
        !End   - Shorten variables name

        ComputeFace = .true.
        I_Down      = iSouth
        J_Down      = jWest

        if (Present(Direction)) then

            Direction_ = Direction

        else

            Direction_ = Me%Direction%XY

        endif
        
        
ixy:    if (Direction_ == DirectionY_ ) then
                 
iby:        if   (BoundaryPoints(ILB, j) == Boundary .and. BoundaryPoints(IUB, j) == Boundary &
                  .and. (I ==ILB + 1 .or. I== IUB)) then

                if (I == ILB + 1) then 

                    I_Down = IUB - 1
                                
                endif

                if (I == IUB) then

                    ComputeFace = .false.

                endif

            endif iby

        else if (Direction_ == DirectionX_) then ixy

                  
ibx:        if   (BoundaryPoints(i, JLB) == Boundary .and. BoundaryPoints(i, JUB) == Boundary &
                  .and. (J ==JLB + 1 .or. J == JUB)) then

                if (J == JLB + 1) then 

                    J_Down = JUB - 1
                                
                endif

                if (J == JUB) then

                    ComputeFace = .false.

                endif

            endif ibx

        endif ixy

        if (ComputeFace) then


            !Compute the coeficients of linear system equations for the I,J Z cell
            ![ ]                   = [ ]         + [m^2/s] * [s/m^2]
            if (present(DCoef_2D))                                                       &
                DCoef_2D(I,J)         = DCoef_2D(I,J)  - AuxImplicit * DT_AreaCell2
        
            ![ ]                   = [ ]         + [m^2/s] * [s/m^2]
            if (present(ECoef_2D))                                                       &
                ECoef_2D (I,J)        = ECoef_2D(I,J)  + AuxImplicit * DT_AreaCell2

            ![m]                   = [m]         + [m^3/s] * [s/m^2] 
            TiCoef_2D(I,J)            = TiCoef_2D(I,J) + AuxExplicit * DT_AreaCell2

            !Compute the coeficients of linear system equations for the iSouth, jWest Z cell

            ![ ]                   = [ ]                     + [m^2/s] * [s/m^2] 
            if (present(FCoef_2D))                                                       &
                FCoef_2D(I_Down, J_Down) = FCoef_2D(I_Down, J_Down)  - AuxImplicit * DT_AreaCell1

            ![ ]                   = [ ]                     + [m^2/s] * [s/m^2] 
            if (present(ECoef_2D))                                                       &   
                ECoef_2D(I_Down, J_Down) = ECoef_2D(I_Down, J_Down)  + AuxImplicit * DT_AreaCell1

            ![m]                   = [m]                     + [m^3/s] * [s/m^2] 
            TiCoef_2D(I_Down, J_Down)    = TiCoef_2D(I_Down, J_Down) - AuxExplicit * DT_AreaCell1

        endif    

        !Nullify auxiliar variables
        nullify (BoundaryPoints)


        !----------------------------------------------------------------------

    End Subroutine CyclicCoef2D



    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This subroutine imposed a Cyclic boundary condition for a vectorial property          !
    !                                                                                      !
    ! Input : Mapping                                                                      !
    ! OutPut: Water Level in the open boundary                                             !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine CyclicBoundVectNormal ( Vector, VectorD)

        !Arguments------------------------------------------------------------
        
        real,    dimension (:,:,:), pointer, optional :: Vector
        real(8), dimension (:,:,:), pointer, optional :: VectorD

        !Local---------------------------------------------------------------------
        integer, dimension (:,:  ), pointer :: BoundaryPoints
        integer                             :: IUB, ILB, JUB, JLB, KLB, KUB
        integer                             :: i, j, k

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB

        BoundaryPoints => Me%External_Var%BoundaryPoints

        !End   - Shorten variables name
        

        !Normal boundary faces --------------------------------------------------------------------------
            
cd1:    if (Me%Direction%XY == DirectionX_) then

do1:        do k = KLB, KUB 
do2:        do i = ILB, IUB

                if (BoundaryPoints(i, JUB) == Boundary .or.                              &
                    BoundaryPoints(i, JLB) == Boundary) then

                    if (present(Vector )) Vector  (i, JUB + 1, k) = Vector (i, JLB + 2, k)
                    if (present(VectorD)) VectorD (i, JUB + 1, k) = VectorD(i, JLB + 2, k)

           
                    if (present(Vector )) Vector  (i, JLB, k) = Vector (i, JUB - 1, k)
                    if (present(VectorD)) VectorD (i, JLB, k) = VectorD(i, JUB - 1, k)


                    if (present(Vector )) Vector  (i, JUB, k) = Vector (i, JLB + 1, k)
                    if (present(VectorD)) VectorD (i, JUB, k) = VectorD(i, JLB + 1, k)

                endif

            enddo do2
            enddo do1



        endif cd1


cd2:    if (Me%Direction%XY == DirectionY_) then
            
do3:        do k = KLB, KUB 
do4:        do j = JLB, JUB

                if (BoundaryPoints(IUB, j) == Boundary .or.                              &
                    BoundaryPoints(ILB, j) == Boundary) then                    
                    if (present(Vector )) Vector  (IUB+1, j, k) = Vector (ILB + 2, j, k)
                    if (present(VectorD)) VectorD (IUB+1, j, k) = VectorD(ILB + 2, j, k)

                
                    if (present(Vector )) Vector  (ILB  , j, k) = Vector (IUB - 1, j, k)
                    if (present(VectorD)) VectorD (ILB  , j, k) = VectorD(IUB - 1, j, k)

                    if (present(Vector )) Vector  (IUB  , j, k) = Vector (ILB + 1, j, k)
                    if (present(VectorD)) VectorD (IUB  , j, k) = VectorD(ILB + 1, j, k)

                endif

            enddo do4
            enddo do3
        
        endif cd2

        nullify(BoundaryPoints)


        !----------------------------------------------------------------------

    End Subroutine CyclicBoundVectNormal

    !--------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This subroutine imposed a Cyclic boundary condition for a vectorial property          !
    !                                                                                      !
    ! Input : Mapping                                                                      !
    ! OutPut: Water Level in the open boundary                                             !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine CyclicBoundVectTangential ( Vector, VectorD)

        !Arguments------------------------------------------------------------
        
        real,    dimension (:,:,:), pointer, optional :: Vector
        real(8), dimension (:,:,:), pointer, optional :: VectorD

        !Local---------------------------------------------------------------------
        integer, dimension (:,:  ), pointer :: BoundaryPoints
        integer                             :: IUB, ILB, JUB, JLB, KLB, KUB
        integer                             :: i, j, k

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB

        BoundaryPoints => Me%External_Var%BoundaryPoints

        !End   - Shorten variables name
        
        !Tangential boundary faces --------------------------------------------------------------------------
                    
cd1:    if (Me%Direction%XY == DirectionY_) then

do1:        do k = KLB, KUB 
do2:        do i = ILB, IUB

                if (BoundaryPoints(i, JUB) == Boundary) then

                    if (present(Vector )) Vector  (i, JUB, k) = Vector (i, JLB + 1, k)
                    if (present(VectorD)) VectorD (i, JUB, k) = VectorD(i, JLB + 1, k)

                endif

                if (BoundaryPoints(i, JLB) == Boundary) then       
                        
                    if (present(Vector )) Vector  (i, JLB, k) = Vector (i, JUB - 1, k)
                    if (present(VectorD)) VectorD (i, JLB, k) = VectorD(i, JUB - 1, k)

                endif

            enddo do2
            enddo do1

        endif cd1


cd2:    if (Me%Direction%XY == DirectionX_) then

do3:        do k = KLB, KUB 
do4:        do j = JLB, JUB

                if (BoundaryPoints(IUB, j) == Boundary) then                   
                    if (present(Vector )) Vector  (IUB, j, k) = Vector (ILB + 1, j, k)
                    if (present(VectorD)) VectorD (IUB, j, k) = VectorD(ILB + 1, j, k)
                endif
               
                if (BoundaryPoints(ILB, j) == Boundary) then
                    if (present(Vector )) Vector  (ILB, j, k) = Vector (IUB - 1, j, k)
                    if (present(VectorD)) VectorD (ILB, j, k) = VectorD(IUB - 1, j, k)
                endif

            enddo do4
            enddo do3


        endif cd2

        nullify(BoundaryPoints)

        !----------------------------------------------------------------------

    End Subroutine CyclicBoundVectTangential

    !--------------------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This subroutine imposed a Cyclic boundary condition for vertical velocity or flux    !
    !                                                                                      !
    ! Input : Mapping                                                                      !
    ! OutPut: Water Level in the open boundary                                             !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine CyclicBoundVertical (Vector, VectorD)

        !Arguments------------------------------------------------------------
        
        real,    dimension (:,:,:), pointer, optional :: Vector
        real(8), dimension (:,:,:), pointer, optional :: VectorD

        !Local---------------------------------------------------------------------
        integer, dimension (:,:  ), pointer :: BoundaryPoints
        integer                             :: IUB, ILB, JUB, JLB, KLB, KUB
        integer                             :: i, j, k

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB

        BoundaryPoints => Me%External_Var%BoundaryPoints

        !End   - Shorten variables name
        
        !Tangential boundary faces --------------------------------------------------------------------------
                    

f1:     if (Me%CyclicBoundary%Direction == DirectionX_ .or. &
            Me%CyclicBoundary%Direction == DirectionXY_)  then



do1:        do i = ILB, IUB

                if (BoundaryPoints(i, JUB) == Boundary) then

do2:               do k = KLB, KUB + 1

                        if (present(Vector )) Vector  (i, JUB, k) = Vector (i, JLB + 1, k)
                        if (present(VectorD)) VectorD (i, JUB, k) = VectorD(i, JLB + 1, k)

                    enddo do2

                endif

                if (BoundaryPoints(i, JLB) == Boundary) then       

do3:                do k = KLB, KUB + 1
                    
                        if (present(Vector )) Vector  (i, JLB, k) = Vector (i, JUB - 1, k)
                        if (present(VectorD)) VectorD (i, JLB, k) = VectorD(i, JUB - 1, k)

                    enddo do3

                endif

            enddo do1

        endif f1


f2:     if (Me%CyclicBoundary%Direction == DirectionY_ .or. &
            Me%CyclicBoundary%Direction == DirectionXY_)  then

            
do4:        do j = JLB, JUB

                if (BoundaryPoints(IUB, j) == Boundary) then                   

do5:                do k = KLB, KUB + 1
                    
                        if (present(Vector )) Vector  (IUB, j, k) = Vector (ILB + 1, j, k)
                        if (present(VectorD)) VectorD (IUB, j, k) = VectorD(ILB + 1, j, k)

                    enddo do5

                endif
           
                if (BoundaryPoints(ILB, j) == Boundary) then

do6:               do k = KLB, KUB + 1
                
                        if (present(Vector )) Vector  (ILB, j, k) = Vector (IUB - 1, j, k)
                        if (present(VectorD)) VectorD (ILB, j, k) = VectorD(IUB - 1, j, k)

                    enddo do6

                endif

            enddo do4

        endif f2


        nullify(BoundaryPoints)

        !----------------------------------------------------------------------

    End Subroutine CyclicBoundVertical

    !--------------------------------------------------------------------------




    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This subroutine compute the Sommerfeld radition condition for the open boundary      !
    !                                                                                      !
    ! Input : Mapping                                                                      !
    ! OutPut: Water Level in the open boundary                                             !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine WaterLevel_FlatherWindWave ( WaterFlux_XY, WaterFlux_YX,  &
                                     WaterColumnUV, DUX_VY, DVY_UX, DYY_XX,              &
                                     ComputeFaces3D_UV, ComputeFaces3D_VU,               &
                                     BoundaryFacesUV, kfloor_UV, kfloor_VU,              &
                                     di, dj, ImplicitFaces)

        !Arguments------------------------------------------------------------
        
        real(8), dimension (:,:,:), pointer :: WaterFlux_XY, WaterFlux_YX
        real,    dimension (:,:  ), pointer :: WaterColumnUV, DUX_VY, DVY_UX, DYY_XX 
        integer, dimension (:,:,:), pointer :: ComputeFaces3D_UV, ComputeFaces3D_VU
        integer, dimension (:,:  ), pointer :: BoundaryFacesUV, kfloor_UV, kfloor_VU
        integer                             :: di, dj
        logical                             :: ImplicitFaces


        !Local---------------------------------------------------------------------
        integer                             :: i, j, k 
        integer, pointer, dimension (:,:)   :: BoundaryPoints


        real(8), dimension(:,:), pointer    :: ECoef_2D
        real,    dimension(:,:), pointer    :: DCoef_2D, FCoef_2D, TiCoef_2D,         &
                                               ImposedElevation, OldImposedElevation, &
                                               ImposedVelocity,                       &
                                               WaterLevel_New, BoundaryReferenceLevel,&
                                               RadCoef_2D, TiRadCoef_2D, WaterLevel_Old


        real,    dimension(:,:,:), pointer  :: SZZ  
                   

        real                                :: D1, D2, E1, E2, E3, E4, F1, F2,  &
                                               T1, T2, T3, T4, A_Aux, B_Aux,    &
                                               HT_boundary, Wave_Celerity,      &
                                               DT_Elevation, WaveEntering,      &
                                               OldWaveEntering, ReferenceLevel

        real(8)                             :: FluxXY_L, FluxYX_L, FluxMod_L,   &  
                                               FluxXY_E, FluxYX_E,              &
                                               FluxXY_T, FluxYX_T,              &
                                               Flux_WestSouth, Flux_EastNorth,  &
                                               Flux_SouthWest, Flux_NorthEast,  &
                                               XY_Component_L, XY_Component_E,  &
                                               XY_Component_Cart_E,             &
                                               YX_Component_Cart_E,             &
                                               WaterFluxBoundary,               &
                                               EnteringWaveDirection,           &
                                               LeavingVelocity !, LeavingVelocityXY
        
        real                                :: MinLeavingComponent,  MinLeavingVelocity 


        integer                             :: IUB, ILB, JUB, JLB, KUB,         &
                                               i1, i2, i3, i4, j1, j2, j3, j4,  &
                                               db, kbottom,                     &
                                               ib, jb, i_int, j_int

                                               
        !In the future this values will be read from the hydrodynamic data file 
        real, parameter                     :: WaveReflection_Coef = 1.

        logical                             :: Compute_Tide

        integer                             :: status

        integer                             :: DirX, DirY, DirBound

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB

        DT_Elevation  =  Me%WaterLevel%DT

        DCoef_2D      => Me%Coef%D2%D
        ECoef_2D      => Me%Coef%D2%E
        FCoef_2D      => Me%Coef%D2%F
        TiCoef_2D     => Me%Coef%D2%Ti

        RadCoef_2D    => Me%Coef%D2%Rad
        TiRadCoef_2D  => Me%Coef%D2%TiRad

        SZZ                  => Me%External_Var%SZZ

        !Geometry
!        WaterColumnUV        => Me%External_Var%WaterColumnUV
!        DUX_VY               => Me%External_Var%DUX_VY
!        DVY_UX               => Me%External_Var%DVY_UX
!        DYY_XX               => Me%External_Var%DYY_XX

!        kfloor_UV            => Me%External_Var%kfloor_UV
!        kfloor_VU            => Me%External_Var%kfloor_VU



        !Flow
!        WaterFlux_XY    => Me%WaterFluxes%XY
!        WaterFlux_YX    => Me%WaterFluxes%YX
        WaterLevel_New  => Me%WaterLevel%New
        WaterLevel_Old  => Me%WaterLevel%Old


!        BoundaryFacesUV   => Me%External_Var%BoundaryFacesUV
        BoundaryPoints    => Me%External_Var%BoundaryPoints

!        ComputeFaces3D_UV =>  Me%External_Var%ComputeFaces3D_UV
!        ComputeFaces3D_VU =>  Me%External_Var%ComputeFaces3D_VU

        EnteringWaveDirection =  Me%ComputeOptions%EnteringWaveDirection
        
        MinLeavingComponent   =  Me%ComputeOptions%MinLeavingComponent
        MinLeavingVelocity    =  Me%ComputeOptions%MinLeavingVelocity


        Compute_Tide          = Me%ComputeOptions%Compute_Tide
        
        !End   - Shorten variables name


        call Modify_OpenBoundary(Me%ObjOpenBoundary,                        &
                                 Me%CurrentTime,                            &
                                 STAT = status)
        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR01")


        call GetImposedElevation(Me%ObjOpenBoundary,                        &
                                  ImposedElevation, STAT = status)


        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR02")


        call GetOldImposedElevation(Me%ObjOpenBoundary, &
                                    OldImposedElevation, STAT = status)


        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR03")


        call GetOpenBoundParameter(Me%ObjOpenBoundary, DirectionX = DirX,   &
                                                                    DirectionY = DirY, STAT= status)

        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR03a")


        if      (Me%Direction%XY == DirectionX_) then

            DirBound = DirX

        else if (Me%Direction%XY == DirectionY_) then

            DirBound = DirY

        endif


        call GetImposedVelocity   (Me%ObjOpenBoundary, ImposedVelocity,     &
                                   DirBound, STAT= status)

        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR03b")

        !PCL

cd23:   if (Me%Relaxation%RefBoundWaterLevel) then
        
            !call GetAssimilationList(WaterLevel = PropertyID)

            call GetAssimilationField(Me%ObjAssimilation,                   &
!                                      ID              = PropertyID,                      &
                                      ID              = WaterLevel_,                     &
                                      Field2D         = BoundaryReferenceLevel,          &
                                      STAT            = status)

            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR04")


        else   cd23

            call GetBoundaryReferenceLevel(Me%ObjOpenBoundary,              &
                                           BoundaryReferenceLevel, STAT = status)

            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR05")


        endif cd23

         
        do  j = JLB, JUB
        do  i = ILB, IUB

            
            !In this way if in a boundary point the elevation is not change 
            !due to the radiation condition then 
            !the old elevation is maintain 
!cd9:        if (BoundaryPoints(i, j) == Boundary) then

                !TiCoef_2D(i, j) = WaterLevel_New(i, j)

                !DCoef_2D (i, j) = 0. 

                !ECoef_2D (i, j) = 1.

                !FCoef_2D (i, j) = 0. 


            !endif cd9
            
cd1:        if  (BoundaryFacesUV  (i, j     )  == Boundary     .and.                     &
                 ComputeFaces3D_UV(i, j, KUB)  == Covered      .and.                     & 
                (BoundaryPoints   (i, j)       == Not_Boundary .or.                      &
                 BoundaryPoints   (i-di, j-dj) == Not_Boundary)) then


                kbottom = kfloor_UV(i, j) 

               ![m] = [m^2]/[m] 
                HT_boundary = WaterColumnUV(i, j)


                !Direction - Leaving wave
                if (BoundaryPoints(i, j) == Boundary) then 

                    !West or South cell is interior and
                    !the East or North cell is boundary
                    db = 1

                    i1 = i - di
                    i2 = i       
                    i3 = i - di
                    i4 = i + dj - di
                    j1 = j - dj
                    j2 = j       
                    j3 = j - dj
                    j4 = j - dj + di


                else 

                    !West or South cell is boundary and
                    !the East or North cell is interior
                    db = 0

                    i1 = i
                    i2 = i + di
                    i3 = i
                    i4 = i + dj 
                    j1 = j
                    j2 = j + dj 
                    j3 = j
                    j4 = j + di


                endif

                !total West or South face water flux
                Flux_WestSouth = 0.    

cd2:            if (ComputeFaces3D_UV(i1, j1, KUB) == Covered) then 

                    kbottom = kfloor_UV(i1, j1) 

                    do  k = kbottom, KUB
                    
                        Flux_WestSouth = Flux_WestSouth + WaterFlux_XY(i1, j1, k)

                    enddo
                
                endif cd2


                !total East or North face water flux
                Flux_EastNorth = 0.    

cd3:            if (ComputeFaces3D_UV(i2, j2, KUB) == Covered) then 

                    kbottom = kfloor_UV(i2, j2) 

                    do  k = kbottom, KUB
                    
                        Flux_EastNorth = Flux_EastNorth + WaterFlux_XY(i2, j2, k)

                    enddo

                endif cd3


                !total South or West face water flux
                Flux_SouthWest = 0.    

cd4:            if (ComputeFaces3D_VU(i3, j3, KUB) == Covered) then 

                    kbottom = kfloor_VU(i3, j3) 

                    do  k = kbottom, KUB
                        
                        Flux_SouthWest = Flux_SouthWest + WaterFlux_YX(i3, j3, k) 

                    enddo

                endif cd4


                !total North or East face water flux

                Flux_NorthEast = 0.    

cd5:            if (ComputeFaces3D_VU(i4, j4, KUB) == Covered) then 

                    kbottom = kfloor_VU(i4, j4) 

                    do  k = kbottom, KUB
                    
                        Flux_NorthEast = Flux_NorthEast + WaterFlux_YX(i4, j4, k)

                    enddo

                endif cd5

                !Boundary cell
                !X direction (di=0,dj=1) - boundary West  cell (db=0) => (ib,jb)=(i, j-1)
                !X direction (di=0,dj=1) - boundary East  cell (db=1) => (ib,jb)=(i, j)
                !Y direction (di=1,dj=0) - boundary South cell (db=0) => (ib,jb)=(i-1, j)
                !Y direction (di=1,dj=0) - boundary North cell (db=1) => (ib,jb)=(i, j)

                ib    = i - di * (1 - db)
                jb    = j - dj * (1 - db)

                ReferenceLevel   = BoundaryReferenceLevel (ib, jb) 
                WaveEntering     = ImposedElevation       (ib, jb) - ReferenceLevel
                OldWaveEntering  = OldImposedElevation    (ib, jb) - ReferenceLevel

                !Interior cell next to a boundary face
                !X direction (di=0,dj=1) - Interior East  cell (db=0) => (ib,jb)=(i, j)
                !X direction (di=0,dj=1) - Interior West  cell (db=1) => (ib,jb)=(i, j-1)
                !Y direction (di=1,dj=0) - Interior North cell (db=0) => (ib,jb)=(i, j)
                !Y direction (di=1,dj=0) - Interior South cell (db=1) => (ib,jb)=(i-1, j)

                i_int = i - di * db
                j_int = j - dj * db

                !The wave Celerity compute in the boundary face 
                ![m/s] = [m/s^2*m]^.5 = [m/s]
                Wave_Celerity = sqrt(Gravity * HT_Boundary) 
                

                !If was defined a entering wave then 
cd15:           if (Me%ComputeOptions%ComputeEnteringWave) then

                    !Direction - Entering wave - Cartesian referencial
                    XY_Component_Cart_E  = dj * cos(EnteringWaveDirection) +  &
                                           di * sin(EnteringWaveDirection)
                    YX_Component_Cart_E  = dj * sin(EnteringWaveDirection) +  &
                                           di * cos(EnteringWaveDirection)

                    if (abs(XY_Component_Cart_E) < MinLeavingComponent) XY_Component_Cart_E = 0.
                    if (abs(YX_Component_Cart_E) < MinLeavingComponent) YX_Component_Cart_E = 0.



                    !If the flow of the entering wave is going from the inside the domain to the 
                    !outside then the entering flow is consider be zero

                    if ((XY_Component_Cart_E <= 0 .and. db == 0) .or.  &  !West or South cell boundary
                        (XY_Component_Cart_E >= 0 .and. db == 1)) then    !East or North cell boundary

                        XY_Component_Cart_E  = 0.

                        WaveEntering         = 0.
                        OldWaveEntering      = 0.

                    endif


                    !Flow - Entering wave - Cartesian referencial. In necessary to compute 
                    !the entering fluxes in cartesian referencial to be consistent witht the 
                    !total fluxes

                    ![m^3/s] = [m] * [m/s] * [ ] * [m]
                    FluxXY_E = WaveEntering * Wave_Celerity *  &
                               XY_Component_Cart_E * DVY_UX(i, j) 

                    ![m^3/s] = [m] * [m/s] * [ ] * [m]
                    FluxYX_E = WaveEntering * Wave_Celerity *  &
                               YX_Component_Cart_E * DUX_VY(i, j)
                                    
                else cd15

                    XY_Component_Cart_E  = 0.

                    WaveEntering         = 0.
                    OldWaveEntering      = 0.

                    FluxXY_E             = 0.
                    FluxYX_E             = 0.

                endif cd15


                !The leaving wave direction is compute in the center of the 
                !first interior cell 
                FluxXY_T = (Flux_WestSouth + Flux_EastNorth) / 2. 


                FluxYX_T = (Flux_SouthWest + Flux_NorthEast) / 2. 


                !Flow - Leaving wave - Cartesian referencial
                FluxXY_L = FluxXY_T - FluxXY_E
                FluxYX_L = FluxYX_T - FluxYX_E

                FluxMod_L = pythag (FluxXY_L, FluxYX_L)

                LeavingVelocity   = FluxMod_L      / DYY_XX(i, j)  / HT_Boundary


                if (LeavingVelocity < MinLeavingVelocity)    then 

                    XY_Component_L = 1.

                else

                    XY_Component_L = abs(FluxXY_L) / FluxMod_L

                endif
                !If the flow of the leaving wave is going from inside the domain to the 
                !outside then the flow must be positive in the oposite condition it must 
                !be negative
                if (db == 0) then  !West or South cell boundary
                    ![ ] = [m^3/s] / [m^3/s]
                    XY_Component_E  =   abs(XY_Component_Cart_E)

                    XY_Component_L  = - abs(XY_Component_L)

                    !The total OLD water flux in the boundary face
                    WaterFluxBoundary = Flux_WestSouth 


                else if (db == 1) then !East or North cell boundary

                    ![ ] = [m^3/s] / [m^3/s]
                    XY_Component_E  = - abs(XY_Component_Cart_E)

                    XY_Component_L  = + abs(XY_Component_L)

                    !The total OLD water flux in the boundary face
                    WaterFluxBoundary = Flux_EastNorth


                endif


                if (abs(XY_Component_L)  > 1. )   Stop 'XY_Component_L = 1'

                if (ImplicitFaces) then


                    ![s^-1] = [m^2/s] / [m] / [m]
                    A_aux = RadCoef_2D(I, J) / DYY_XX(i, j) / HT_Boundary

                    ![m/s]    = [m^3/s] / [m] / [m]
                    T3        = + TiRadCoef_2D(I, J) / DYY_XX(i, j) / HT_Boundary
                

                else

                    ![s^-1]   = [m^2/s] / [m] / [m]
                    A_aux     = 0. 

                    ![m/s]    = [m^3/s] / [m] / [m]
                    T3        = WaterFluxBoundary / DYY_XX(i, j) / HT_Boundary


                endif

               
                T3            = T3 - ImposedVelocity(ib, jb) * XY_Component_Cart_E

                
                ![m^-1*s^-1] = [m/s] * [ ] * [ ] / [m] / [m]
                B_aux =  Wave_Celerity * XY_Component_L * WaveReflection_Coef &
                           / (DUX_VY(i - di, j - dj) + DUX_VY(i, j)) / HT_Boundary


                ![s^-1]   = [ ] * [s^-1] + [m^-1*s^-1] * [m]
                D1        = - db * A_aux
                D2        = + db * B_aux * DUX_VY(i, j)

                E1        = + db * A_Aux 
                E2        = + db * B_aux * DUX_VY(i - di, j - dj)
                E3        = - (1 - db) * A_aux
                E4        = + (1 - db) * B_aux * DUX_VY(i, j) 

                F1        = + (1 - db) * A_aux
                F2        = + (1 - db) * B_aux * DUX_VY(i - di, j - dj)

                ! [s^-1] = ([m/s] / [m] )
                T1        = - Wave_Celerity * XY_Component_E / HT_Boundary

                T2        = + Wave_Celerity * XY_Component_L * WaveReflection_Coef / &
                              HT_Boundary

                    
                T4        = WaveEntering * T1 + T3 + (WaveEntering + ReferenceLevel) * T2 

cd7:            if (ImplicitFaces) then

                    DCoef_2D (ib, jb) = D1 + D2 

                    ECoef_2D (ib, jb) = E1 + E2 + E3 + E4

                    FCoef_2D (ib, jb) = F1 + F2

                    TiCoef_2D(ib, jb) = T4

                else cd7


                    DCoef_2D (ib, jb) = 0. 

                    ECoef_2D (ib, jb) = 1.

                    FCoef_2D (ib, jb) = 0.

                    TiCoef_2D(ib, jb) =   (T4 - (D2     ) * WaterLevel_New(ib - di, jb - dj)   &
                                        - (F2           ) * WaterLevel_New(ib + di, jb + dj))/ &
                                          (E2 + E4)

                endif cd7



            endif cd1

        enddo
        enddo

        
        call UnGetOpenBoundary(Me%ObjOpenBoundary, ImposedElevation, STAT = status)
        if (status /= SUCCESS_) &
            call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR08")


        call UnGetOpenBoundary(Me%ObjOpenBoundary, OldImposedElevation, STAT = status)
        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR09")

        call UnGetOpenBoundary(Me%ObjOpenBoundary, ImposedVelocity, STAT = status)
        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR09a")



cd24:   if (Me%Relaxation%RefBoundWaterLevel) then
        
            call UnGetAssimilation(Me%ObjAssimilation,                      &
                                    BoundaryReferenceLevel, STAT = status)

            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR10")


        else   cd24

            call UnGetOpenBoundary(Me%ObjOpenBoundary, BoundaryReferenceLevel, STAT = status)

            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherWindWave - Hydrodynamic - ERR11")

        
        endif cd24

        !Nullify auxiliar variables
            
        !Linear system equation
        nullify (DCoef_2D, ECoef_2D, FCoef_2D, TiCoef_2D, RadCoef_2D, TiRadCoef_2D)

        !Mapping
        nullify (BoundaryPoints)

        !Geometry
        nullify(SZZ)

        !Hydrodynamic
        nullify(WaterLevel_New)
        nullify(WaterLevel_Old)

        !----------------------------------------------------------------------

    End Subroutine WaterLevel_FlatherWindWave

    !--------------------------------------------------------------------------


      !------------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This subroutine compute the Sommerfeld radition condition for the open boundary      !
    !                                                                                      !
    ! Input : Mapping                                                                      !
    ! OutPut: Water Level in the open boundary                                             !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine WaterLevel_FlatherLocalSolution

        !Arguments------------------------------------------------------------
        

        !Local---------------------------------------------------------------------
        real(8), dimension (:,:,:), pointer :: WaterFlux_XY, WaterFlux_YX,               &
                                               LocalFlux3D_XY, LocalFlux3D_YX
        real,    dimension (:,:  ), pointer :: LocalVel2D_XY, LocalVel2D_YX,             &
                                               LocalVel2D_X , LocalVel2D_Y
        real,    dimension (:,:  ), pointer :: WaterColumnUV, DUX_VY, DYY_XX, DXX_YY 
        integer, dimension (:,:,:), pointer :: ComputeFaces3D_UV, ComputeFaces3D_VU
        integer, dimension (:,:  ), pointer :: BoundaryFacesUV, kfloor_UV, kfloor_VU
        integer                             :: di, dj
        integer                             :: i, j, k 
        integer, pointer, dimension (:,:)   :: BoundaryPoints


        real(8), dimension(:,:), pointer    :: ECoef_2D
        real,    dimension(:,:), pointer    :: DCoef_2D, FCoef_2D, TiCoef_2D,            &
                                               WaterLevel_New,  GaugeWaterLevel,         &
                                               AssimilaWaterLevel, SubModelWaterLevel,   &
                                               RadCoef_2D, TiRadCoef_2D, Bathymetry 
        real,    dimension(:,:,:), pointer  :: SZZ  
                   

        real                                :: D1, D2, E1, E2, E3, E4, F1, F2,           &
                                               T1, T3, T4, A_Aux, B_Aux,                 &
                                               HT_boundary, Wave_Celerity,               &
                                               DT_Elevation, LocalWave, DT_RunPeriod, SlowCoef

        real(8)                             :: FluxXY_L, FluxYX_L, FluxMod_L,            &  
                                               FluxXY_E, FluxYX_E,                       &
                                               FluxXY_T, FluxYX_T,                       &
                                               Flux_WestSouth, Flux_EastNorth,           &
                                               Flux_SouthWest, Flux_NorthEast,           &
                                               LocalFlux_WestSouth, LocalFlux_EastNorth, &
                                               LocalFlux_SouthWest, LocalFlux_NorthEast, &
                                               XY_Component_L,                           &
                                               WaterFluxBoundary, LocalBoundaryFlux,     &
                                               LeavingVelocity, Aux1, Aux2
        
        real                                :: MinLeavingComponent,  MinLeavingVelocity, LocalWLa, LocalWLb

        !This local variable is an auxiliar variable use when 
        !there is a local solution and the cold start option is active
        real                                :: AuxFlatherCold

        integer                             :: IUB, ILB, JUB, JLB, KUB,         &
                                               i1, i2, i3, i4, j1, j2, j3, j4,  &
                                               db, kbottom,                     &
                                               ib, jb, i_int, j_int


        integer                             :: status

        integer                             :: DirX, DirY, DirBoundXY, DirBoundYX
        
        logical                             :: LocalSolution, LocalAssimila, LocalSubModel, LocalGauge

                                               
        !In the future this values will be read from the hydrodynamic data file 
        real,    parameter                  :: WaveReflection_Coef = 1.

        !Begin----------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        
        di  = Me%Direction%di
        dj  = Me%Direction%dj


        DT_Elevation  =  Me%WaterLevel%DT

        DCoef_2D          => Me%Coef%D2%D
        ECoef_2D          => Me%Coef%D2%E
        FCoef_2D          => Me%Coef%D2%F
        TiCoef_2D         => Me%Coef%D2%Ti

        RadCoef_2D        => Me%Coef%D2%Rad
        TiRadCoef_2D      => Me%Coef%D2%TiRad

        SZZ               => Me%External_Var%SZZ

        WaterLevel_New    => Me%WaterLevel%New

        WaterFlux_XY      => Me%WaterFluxes%XY 
        WaterFlux_YX      => Me%WaterFluxes%YX 

        WaterColumnUV     => Me%External_Var%WaterColumnUV
        DUX_VY            => Me%External_Var%DUX_VY
        DYY_XX            => Me%External_Var%DYY_XX
        DXX_YY            => Me%External_Var%DXX_YY
        ComputeFaces3D_UV => Me%External_Var%ComputeFaces3D_UV
        ComputeFaces3D_VU => Me%External_Var%ComputeFaces3D_VU
        BoundaryFacesUV   => Me%External_Var%BoundaryFacesUV
        Kfloor_UV         => Me%External_Var%Kfloor_UV
        Kfloor_VU         => Me%External_Var%Kfloor_VU
                           
        BoundaryPoints    => Me%External_Var%BoundaryPoints

       
        MinLeavingComponent   =  Me%ComputeOptions%MinLeavingComponent
        MinLeavingVelocity    =  Me%ComputeOptions%MinLeavingVelocity

       
        !End   - Shorten variables name

        LocalSolution = .true.

        LocalAssimila = .false.

        LocalGauge    = .false.

        LocalSubModel = .false.


        !Gets Bathymetry
        call GetGridData(Me%ObjGridData,                                &
                           Bathymetry, STAT = status)
        
        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR00")


cd0:    if (Me%ComputeOptions%LocalSolution == Gauge_) then


            call Modify_OpenBoundary(Me%ObjOpenBoundary,                    &
                                     Me%CurrentTime,                        &
                                     STAT = status)
            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR01")


            call GetImposedElevation(Me%ObjOpenBoundary,                    &
                                      GaugeWaterLevel, STAT = status)


            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR02")



            call GetOpenBoundParameter(Me%ObjOpenBoundary, DirectionX = DirX,   &
                                                                        DirectionY = DirY, STAT= status)

            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR03a")


            if      (Me%Direction%XY == DirectionX_) then

                DirBoundXY = DirX
                DirBoundYX = DirY


            else if (Me%Direction%XY == DirectionY_) then

                DirBoundXY = DirY
                DirBoundYX = DirX

            endif


            !call GetImposedVelocity   (Me%ObjOpenBoundary, LocalFlux_XY,   &
            !                           DirBound, STAT= status)

            !if (status /= SUCCESS_)                                                          &
            !    call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR03b")


            !call GetImposedVelocity   (Me%ObjOpenBoundary, LocalFlux_YX,   &
            !                           DirBound, STAT= status)

            !if (status /= SUCCESS_)                                                          &
            !    call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR03b")



            LocalGauge = .true.

        endif cd0 

        !This local variable is an auxiliar variable use when 
        !there is a local solution and the cold start option is active
        AuxFlatherCold = 0.


ifa:    if (Me%ComputeOptions%LocalSolution == AssimilationField_ .or.      & 
            Me%ComputeOptions%LocalSolution == AssimilaPlusSubModel_) then 

            !call GetAssimilationList(WaterLevel = PropertyID)
            call GetAssimilationField(Me%ObjAssimilation,                   &
                                      ID              = WaterLevel_,                     &
                                      Field2D         = AssimilaWaterLevel,              &
                                      STAT            = status)

            if (status /= SUCCESS_) call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR04")

            call GetAssimilationField(Me%ObjAssimilation,                   &
                                      ID              = BarotropicVelocityU_,            &
                                      Field2D         = LocalVel2D_X,                    &
                                      STAT            = status)

            if (status /= SUCCESS_) call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR04a")


            call GetAssimilationField(Me%ObjAssimilation,                   &
                                      ID              = BarotropicVelocityV_,            &
                                      Field2D         = LocalVel2D_Y,                    &
                                      STAT            = status)

            if (status /= SUCCESS_) call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR04b")

            DT_RunPeriod = Me%CurrentTime - Me%BeginTime

            if (Me%ComputeOptions%FlatherColdPeriod <= DT_RunPeriod) then
                SlowCoef = 1.
            else
                SlowCoef = (DT_RunPeriod / Me%ComputeOptions%FlatherColdPeriod) 

                AuxFlatherCold = Me%ComputeOptions%FlatherColdSeaLevel
            endif

            if      (Me%Direction%XY == DirectionX_) then

                LocalVel2D_XY => LocalVel2D_X
                LocalVel2D_YX => LocalVel2D_Y

            else if (Me%Direction%XY == DirectionY_) then

                LocalVel2D_XY => LocalVel2D_Y
                LocalVel2D_YX => LocalVel2D_X

            endif

            LocalAssimila = .true.


        endif ifa

ifb:    if  (Me%ComputeOptions%LocalSolution == SubModel_ .or.              &
             Me%ComputeOptions%LocalSolution == AssimilaPlusSubModel_) then 


            SubModelWaterLevel => Me%SubModel%Z 

            LocalFlux3D_XY     => Me%SubModel%qXY
             
            LocalFlux3D_YX     => Me%SubModel%qYX 


            LocalSubModel = .true.

        endif ifb

ifc:    if  (Me%ComputeOptions%LocalSolution == NoLocalSolution_) then 

            LocalSolution = .false.

        endif ifc

         
        do  j = JLB, JUB
        do  i = ILB, IUB

            
            !In this way if in a boundary point the elevation is not change 
            !due to the radiation condition then 
            !the old elevation is maintain 
cd9:        if (BoundaryPoints(i, j) == Boundary) then

                TiCoef_2D(i, j) = WaterLevel_New(i, j)

                DCoef_2D (i, j) = 0. 

                ECoef_2D (i, j) = 1.

                FCoef_2D (i, j) = 0. 


            endif cd9
            
cd1:        if  (BoundaryFacesUV  (i, j     )  == Boundary     .and.                     &
                 ComputeFaces3D_UV(i, j, KUB)  == Covered      .and.                     & 
                (BoundaryPoints   (i, j)       == Not_Boundary .or.                      &
                 BoundaryPoints   (i-di, j-dj) == Not_Boundary)) then


                kbottom = kfloor_UV(i, j) 

               ![m] = [m^2]/[m] 
                HT_boundary = WaterColumnUV(i, j)


                !Direction - Leaving wave
                if (BoundaryPoints(i, j) == Boundary) then 

                    !West or South cell is interior and
                    !the East or North cell is boundary
                    db = 1

                    i1 = i - di
                    i2 = i       
                    i3 = i - di
                    i4 = i + dj - di
                    j1 = j - dj
                    j2 = j       
                    j3 = j - dj
                    j4 = j - dj + di


                else 

                    !West or South cell is boundary and
                    !the East or North cell is interior
                    db = 0

                    i1 = i
                    i2 = i + di
                    i3 = i
                    i4 = i + dj 
                    j1 = j
                    j2 = j + dj 
                    j3 = j
                    j4 = j + di


                endif


                !Boundary cell
                !X direction (di=0,dj=1) - boundary West  cell (db=0) => (ib,jb)=(i, j-1)
                !X direction (di=0,dj=1) - boundary East  cell (db=1) => (ib,jb)=(i, j)
                !Y direction (di=1,dj=0) - boundary South cell (db=0) => (ib,jb)=(i-1, j)
                !Y direction (di=1,dj=0) - boundary North cell (db=1) => (ib,jb)=(i, j)

                ib    = i - di * (1 - db)
                jb    = j - dj * (1 - db)

                !Interior cell next to a boundary face
                !X direction (di=0,dj=1) - Interior East  cell (db=0) => (ib,jb)=(i, j)
                !X direction (di=0,dj=1) - Interior West  cell (db=1) => (ib,jb)=(i, j-1)
                !Y direction (di=1,dj=0) - Interior North cell (db=0) => (ib,jb)=(i, j)
                !Y direction (di=1,dj=0) - Interior South cell (db=1) => (ib,jb)=(i-1, j)

                i_int = i - di * db
                j_int = j - dj * db


                if (LocalSolution) then

                    if (LocalAssimila) then

                        Aux1 = dble(Bathymetry(i_int, j_int) + AuxFlatherCold +         &
                                    SlowCoef * (AssimilaWaterLevel(i_int, j_int) - AuxFlatherCold))

                    else

                        Aux1 = FillValueReal

                    endif


                else

                    Aux1 = 0.

                endif


                !total West or South face water flux
                Flux_WestSouth      = 0.    
                LocalFlux_WestSouth = 0.

cd2:            if (ComputeFaces3D_UV(i1, j1, KUB) == Covered) then 
                    
                    Aux2 = dble(DYY_XX(i1, j1)) 
                    
                    if (LocalSolution .and. LocalAssimila)                                  &
                        LocalFlux_WestSouth = Aux1 * Aux2 * dble(SlowCoef * LocalVel2D_XY(i1, j1))

                    kbottom = kfloor_UV(i1, j1) 

                    do  k = kbottom, KUB
                    
                        Flux_WestSouth = Flux_WestSouth + WaterFlux_XY(i1, j1, k)

                        if (LocalSolution .and. LocalSubModel)                             &
                            LocalFlux_WestSouth = LocalFlux_WestSouth + LocalFlux3D_XY(i1, j1, k) * Aux2

                    enddo

                
                endif cd2


                !total East or North face water flux
                Flux_EastNorth      = 0.    
                LocalFlux_EastNorth = 0

cd3:            if (ComputeFaces3D_UV(i2, j2, KUB) == Covered) then 

                    Aux2 = dble(DYY_XX(i2, j2))

                    if (LocalSolution .and. LocalAssimila)                                  &
                        LocalFlux_EastNorth = Aux1 * Aux2 * dble(SlowCoef * LocalVel2D_XY(i2, j2))

                    kbottom = kfloor_UV(i2, j2) 

                    do  k = kbottom, KUB
                    
                        Flux_EastNorth = Flux_EastNorth + WaterFlux_XY(i2, j2, k)

                        if (LocalSolution .and. LocalSubModel)                             &
                            LocalFlux_EastNorth = LocalFlux_EastNorth + LocalFlux3D_XY(i2, j2, k) * Aux2

                    enddo

                endif cd3


                !total South or West face water flux
                Flux_SouthWest      = 0.    
                LocalFlux_SouthWest = 0.

cd4:            if (ComputeFaces3D_VU(i3, j3, KUB) == Covered) then 

                    Aux2  = dble(DXX_YY(i3, j3))

                    if (LocalSolution .and. LocalAssimila)                                  &
                        LocalFlux_SouthWest = Aux1 * Aux2 * dble(SlowCoef * LocalVel2D_YX(i3, j3))

                    kbottom = kfloor_VU(i3, j3) 

                    do  k = kbottom, KUB
                        
                        Flux_SouthWest = Flux_SouthWest + WaterFlux_YX(i3, j3, k) 

                        if (LocalSolution .and. LocalSubModel)                             &
                            LocalFlux_SouthWest = LocalFlux_SouthWest + LocalFlux3D_YX(i3, j3, k) * Aux2

                    enddo

                endif cd4


                !total North or East face water flux

                Flux_NorthEast      = 0.    
                LocalFlux_NorthEast = 0.

cd5:            if (ComputeFaces3D_VU(i4, j4, KUB) == Covered) then 

                    Aux2 = dble(DXX_YY(i4, j4))

                    if (LocalSolution .and. LocalAssimila)                                  &
                        LocalFlux_NorthEast = Aux1 * Aux2 * dble(SlowCoef * LocalVel2D_YX(i4, j4))

                    kbottom = kfloor_VU(i4, j4) 

                    do  k = kbottom, KUB
                    
                        Flux_NorthEast = Flux_NorthEast + WaterFlux_YX(i4, j4, k)

                        if (LocalSolution .and. LocalSubModel)                             &
                            LocalFlux_NorthEast = LocalFlux_NorthEast + LocalFlux3D_YX(i4, j4, k) * Aux2

                    enddo

                endif cd5

                !The wave Celerity compute in the boundary face 
                ![m/s] = [m/s^2*m]^.5 = [m/s]
                
                Wave_Celerity = sqrt(Gravity * HT_Boundary) 
                !Wave_Celerity = 2.123163734


                !If was defined a entering wave then 
cd15:           if (LocalSolution) then

                    FluxXY_E = (LocalFlux_WestSouth + LocalFlux_EastNorth) / 2. 
                    FluxYX_E = (LocalFlux_SouthWest + LocalFlux_NorthEast) / 2. 

                    LocalWLa = 0.
                    LocalWLb = 0.

                    if (LocalGauge) then
                        LocalWLa = LocalWLa + GaugeWaterLevel(ib   , jb   )
                        LocalWLb = LocalWLb + GaugeWaterLevel(i_int, j_int)
                    endif

                    if (LocalSubModel) then
                        LocalWLa = LocalWLa + SubModelWaterLevel(ib   , jb   )
                        LocalWLb = LocalWLb + SubModelWaterLevel(i_int, j_int)
                    endif

                    if (LocalAssimila) then
                        LocalWLa = LocalWLa + AuxFlatherCold + SlowCoef * (AssimilaWaterLevel(ib   , jb   ) - AuxFlatherCold)
                        LocalWLb = LocalWLb + AuxFlatherCold + SlowCoef * (AssimilaWaterLevel(i_int, j_int) - AuxFlatherCold)
                    endif


                    LocalWave = (LocalWLa * DUX_VY(i_int, j_int) +  &
                                 LocalWLb * DUX_VY(ib   , jb   ))/  &
                                (DUX_VY(i_int, j_int) + DUX_VY(ib   , jb))

                else cd15

                    LocalWave = 0.

                    FluxXY_E  = 0.
                    FluxYX_E  = 0.

                endif cd15


                !The leaving wave direction is compute in the center of the 
                !first interior cell 
                FluxXY_T = (Flux_WestSouth + Flux_EastNorth) / 2. 
                FluxYX_T = (Flux_SouthWest + Flux_NorthEast) / 2. 


                !Flow - Leaving wave - Cartesian referencial
                FluxXY_L = FluxXY_T - FluxXY_E
                FluxYX_L = FluxYX_T - FluxYX_E

                FluxMod_L = pythag (FluxXY_L, FluxYX_L)

                LeavingVelocity   = FluxMod_L / DYY_XX(i, j) / HT_Boundary

                if (LeavingVelocity < MinLeavingVelocity)    then 

                    XY_Component_L = 1.

                else

                    XY_Component_L = abs(FluxXY_L) / FluxMod_L

                endif
                !If the flow of the leaving wave is going from inside the domain to the 
                !outside then the flow must be positive in the oposite condition it must 
                !be negative
                if (db == 0) then  !West or South cell boundary
                    ![ ] = [m^3/s] / [m^3/s]
                    XY_Component_L  = - abs(XY_Component_L)

                    !The total OLD water flux in the boundary face
                    WaterFluxBoundary = Flux_WestSouth 

                    LocalBoundaryFlux = LocalFlux_WestSouth 


                else if (db == 1) then !East or North cell boundary

                    ![ ] = [m^3/s] / [m^3/s]
                    XY_Component_L  = + abs(XY_Component_L)

                    !The total OLD water flux in the boundary face
                    WaterFluxBoundary = Flux_EastNorth

                    LocalBoundaryFlux = LocalFlux_EastNorth

                endif


                if (abs(XY_Component_L)  > 1. )   Stop 'XY_Component_L = 1'

                ![s^-1] = [m^2/s] / [m] / [m]
                A_aux = RadCoef_2D(I, J) / DYY_XX(i, j) / HT_Boundary

                ![m^3/s]    = [m^3/s] 
                T3        = + TiRadCoef_2D(I, J) 
                
                ![m/s]    = [m^3/s]                
                T3            = (T3 - LocalBoundaryFlux) / DYY_XX(i, j) / HT_Boundary 

              
                
                ![m^-1*s^-1] = [m/s] * [ ] * [ ] / [m] / [m]
                B_aux =  Wave_Celerity * XY_Component_L * WaveReflection_Coef &
                           / (DUX_VY(i - di, j - dj) + DUX_VY(i, j)) / HT_Boundary


                ![s^-1]   = [ ] * [s^-1] + [m^-1*s^-1] * [m]
                D1        = - db * A_aux
                D2        = + db * B_aux * DUX_VY(i, j)

                E1        = + db * A_Aux 
                E2        = + db * B_aux * DUX_VY(i - di, j - dj)
                E3        = - (1 - db) * A_aux
                E4        = + (1 - db) * B_aux * DUX_VY(i, j) 

                F1        = + (1 - db) * A_aux
                F2        = + (1 - db) * B_aux * DUX_VY(i - di, j - dj)

                ! [m/s] = ([m] * [m/s] / [m] )
                T1        = + LocalWave * Wave_Celerity * XY_Component_L / HT_Boundary

                    
                T4        =  T1 + T3  


                DCoef_2D (ib, jb) = D1 + D2 

                ECoef_2D (ib, jb) = E1 + E2 + E3 + E4

                FCoef_2D (ib, jb) = F1 + F2

                TiCoef_2D(ib, jb) = T4 


            endif cd1

        enddo
        enddo


        !Gets Bathymetry
        call UnGetGridData(Me%ObjGridData,                              &
                             Bathymetry, STAT = status)
        
        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR08")

        

cd24:   if (Me%ComputeOptions%LocalSolution == Gauge_) then

            call UnGetOpenBoundary(Me%ObjOpenBoundary, GaugeWaterLevel, STAT = status)
            if (status /= SUCCESS_) &
                call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR09")


            !call UnGetOpenBoundary(Me%ObjOpenBoundary, LocalFlux3D_XY, STAT = status)
            !if (status /= SUCCESS_)                                                          &
            !    call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR10")


            !call UnGetOpenBoundary(Me%ObjOpenBoundary, LocalFlux_YX, STAT = status)
            !if (status /= SUCCESS_)                                                          &
            !    call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR11")

        endif cd24



cd25:   if (Me%ComputeOptions%LocalSolution == AssimilationField_ .or.      &
            Me%ComputeOptions%LocalSolution == AssimilaPlusSubModel_) then 


            call UnGetAssimilation(Me%ObjAssimilation,                      &
                                    AssimilaWaterLevel, STAT = status)

            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR12")


            call UnGetAssimilation(Me%ObjAssimilation,                      &
                                    LocalVel2D_X, STAT = status)

            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR13")



            call UnGetAssimilation(Me%ObjAssimilation,                      &
                                    LocalVel2D_Y, STAT = status)

            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "WaterLevel_FlatherLocalSolution - Hydrodynamic - ERR14")
        
        endif cd25

        !Nullify auxiliar variables
            
        !Linear system equation
        nullify (DCoef_2D, ECoef_2D, FCoef_2D, TiCoef_2D, RadCoef_2D, TiRadCoef_2D)

        !Mapping
        nullify(BoundaryPoints   )
        nullify(ComputeFaces3D_UV)
        nullify(ComputeFaces3D_VU)
        nullify(BoundaryFacesUV  )
        nullify(Kfloor_UV        )
        nullify(Kfloor_VU        )


        !Geometry
        nullify(SZZ              )
        nullify(WaterColumnUV    )
        nullify(DUX_VY           )
        nullify(DXX_YY           )
        nullify(DYY_XX           )
        nullify(Bathymetry       )


        !Hydrodynamic
        nullify(WaterLevel_New   )

        nullify(WaterFlux_XY     )
        nullify(WaterFlux_YX     )

        nullify(LocalFlux3D_XY)
        nullify(LocalFlux3D_YX)

        nullify(SubModelWaterLevel)

        nullify(LocalVel2D_XY)
        nullify(LocalVel2D_YX)


        nullify(LocalVel2D_X )
        nullify(LocalVel2D_Y )


        !----------------------------------------------------------------------

    End Subroutine WaterLevel_FlatherLocalSolution

    !--------------------------------------------------------------------------

    !--------------------------------------------------------------------------


      !------------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                        !
    ! This subroutine computes the implicit Blumberg and Kantha condition for elevation at OB !
    ! This condition is a combination of clamped and radiation conditions                    !
    !                                                                                        !
    ! Input : Mapping                                                                        !
    ! OutPut: Water Level at the open boundary                                               !
    ! Author: Manuel Ruiz Villarreal and Paulo Chambel, 2001                                 !
    !                                                                                        !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine WaterLevel_BlumbergKantha 

        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------
        integer                             :: i, j, STAT_CALL, STAT
        integer, pointer, dimension (:,:)   :: BoundaryPoints, BoundaryFacesV, BoundaryFacesU, BoundaryFacesUV

        real(8), dimension(:,:), pointer    :: ECoef_2D
        real,    dimension(:,:), pointer    :: DCoef_2D, FCoef_2D, TiCoef_2D,         &
                                               ImposedElevation, WaterLevel_Old

        real,    dimension(:,:), pointer    :: DZX, DZY

        real,    dimension(:,:), pointer    :: Tlag

        real                                :: HT_boundary, DT_Elevation,                &
                                               Wave_Celerity, CoefRelax, DZX_ZY, CelAdim          

        integer                             :: IUB, ILB, JUB, JLB, KUB, db
        integer :: di,dj, i_normal, j_normal

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB

        DT_Elevation  =  Me%WaterLevel%DT

        DCoef_2D      => Me%Coef%D2%D
        ECoef_2D      => Me%Coef%D2%E
        FCoef_2D      => Me%Coef%D2%F
        TiCoef_2D     => Me%Coef%D2%Ti

        !Geometry
        DZX               => Me%External_Var%DZX
        DZY               => Me%External_Var%DZY
        
        !Map
        BoundaryFacesU   => Me%External_Var%BoundaryFacesU
        BoundaryFacesV   => Me%External_Var%BoundaryFacesV
        BoundaryFacesUV  => Me%External_Var%BoundaryFacesUV
        BoundaryPoints   => Me%External_Var%BoundaryPoints

        WaterLevel_Old   => Me%WaterLevel%Old
        Tlag             => Me%ComputeOptions%Tlag

        di  = Me%Direction%di
        dj  = Me%Direction%dj
        
        !End   - Shorten variables name


        call Modify_OpenBoundary(Me%ObjOpenBoundary,                        &
                                 Me%CurrentTime,                            &
                                 STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                                       &
            Stop 'Sub. WaterLevel_BlumbergKantha - ModuleHydrodynamic - ERR01.'


        call GetImposedElevation(Me%ObjOpenBoundary, &
                                  ImposedElevation, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) &
            Stop 'Sub. WaterLevel_BlumbergKantha - ModuleHydrodynamic - ERR02.'


          
        do  j = JLB, JUB
        do  i = ILB, IUB
                        
cd1:        if (BoundaryPoints(i, j) == Boundary) then
            
                !Depending on where boundaryfaces are found:
                ! - db= 0, interior point contributes to DCoef; db= 1, interior point contributes to FCoef
                ! - The sign of the normal direction to the boundary
                ! - If the normal direction is X or Y. DZX(i-1,j) == Distance between elevation points i-1,j and i,j
                ! - The depth at the boundary face i,j, needed for computing wave_celerity
                ! In the case of generalised boundaries (i.e. boundary points with several open boundary faces),
                ! the first boundaryface found determines everything. For this purpose we use STAT
                ! Also for avoiding to impose elevation from BK in the explicit direction


                STAT = Unknown_
                
                ! 
                if (BoundaryFacesU(i,j) == Boundary) then

                   db = 0

                   i_normal =  0
                   j_normal = -1

                   DZX_ZY = DZX(i,j-1)

                   !Wave Celerity is computed at the boundary face                 
                   HT_boundary = Me%External_Var%WaterColumnU(i, j)

                   STAT = SUCCESS_

                end if

                if ((BoundaryFacesU(i,j+1) == Boundary).and.(STAT /= SUCCESS_)) then

                   db = 1

                   i_normal = 0
                   j_normal = 1

                   DZX_ZY = DZX(i,j)

                   !Wave Celerity is computed at the boundary face                 
                   HT_boundary = Me%External_Var%WaterColumnU(i, j+1)
                   

                   STAT = SUCCESS_

                end if

                if ((BoundaryFacesV(i,j) == Boundary).and.(STAT /= SUCCESS_)) then

                   db = 0

                   i_normal = -1
                   j_normal = 0

                   DZX_ZY = DZY(i-1,j)

                   !Wave Celerity is computed at the boundary face                 
                   HT_boundary = Me%External_Var%WaterColumnV(i, j)
                   
                   STAT = SUCCESS_

                end if

                if ((BoundaryFacesV(i+1,j) == Boundary).and.(STAT /= SUCCESS_) ) then

                   db = 1

                   i_normal = 1
                   j_normal = 0

                   DZX_ZY = DZY(i,j)

                   !Wave Celerity is computed at the boundary face                 
                   HT_boundary = Me%External_Var%WaterColumnV(i+1, j)


                   STAT = SUCCESS_

                end if    
                    
                if (STAT == SUCCESS_) then

                    ! Wave celerity of a barotropic wave
                    ![m/s] = [m/s^2*m]^.5 = [m/s]
                    Wave_Celerity     = sqrt (Gravity * HT_Boundary) 

                    CoefRelax         = DT_Elevation / Tlag(i, j)

                    CelAdim           = DT_Elevation * Wave_Celerity / DZX_ZY

                    if ((BoundaryFacesUV(i   ,j   ) == Boundary) .or.                    &
                        (BoundaryFacesUV(i+di,j+dj) == Boundary) ) then

                        !Note that the BK condition is discretized implicitly (but only in the implicit direction)!
                        TiCoef_2D(i, j)   = WaterLevel_Old(i,j) + ImposedElevation(i, j) * CoefRelax

                        ECoef_2D (i, j)   = 1. + CoefRelax + CelAdim

                        DCoef_2D (i, j)   = (-1) * (1-db)  * CelAdim

                        FCoef_2D (i, j)   = (-1) *    db   * CelAdim

                    else

                        TiCoef_2D(i, j)   = (1 - CelAdim)  * WaterLevel_Old  (i,         j)             + &
                                               CoefRelax   * ImposedElevation(i         ,j)             + &
                                         (1-db)  * CelAdim * WaterLevel_Old  (i+i_normal,j+j_normal)    + &
                                          db     * CelAdim * WaterLevel_Old  (i+i_normal,j+j_normal)

                        DCoef_2D (i, j)   = 0. 

                        ECoef_2D (i, j)   = 1. + CoefRelax

                        FCoef_2D (i, j)   = 0. 

                    end if

               
                else ! The boundary point has no faces with interior points 
                  
                  TiCoef_2D(i, j) = ImposedElevation(i, j)

                  DCoef_2D (i, j) = 0. 

                  ECoef_2D (i, j) = 1.

                  FCoef_2D (i, j) = 0. 
                                
                end if

            endif cd1

        enddo
        enddo
        
        call UnGetOpenBoundary(Me%ObjOpenBoundary, ImposedElevation, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) &
            Stop 'Sub. WaterLevel_BlumbergKantha - ModuleHydrodynamic - ERR05.'

        !Nullify auxiliar variables

        !Linear system equation
        nullify (DCoef_2D, ECoef_2D, FCoef_2D, TiCoef_2D)
        
        !Mapping
        nullify (BoundaryPoints, BoundaryFacesUV)

        !Geometry
        nullify(DZY, DZX)

        !Flow
        nullify(ImposedElevation, WaterLevel_Old)

        nullify (Tlag)

        !----------------------------------------------------------------------

    End Subroutine WaterLevel_BlumbergKantha

      !------------------------------------------------------------------------------


    FUNCTION spythag(a,b)
        REAL(4) :: a,b,spythag
        REAL(4) :: absa,absb

        absa = abs(a)
        absb = abs(b)
        if(absa.gt.absb)then
            spythag=absa*sqrt(1.+(absb/absa)**2)
        else
            if(absb.eq.0.)then
                spythag=0.
            else
                spythag=absb*sqrt(1.+(absa/absb)**2)
            endif
        endif
    END FUNCTION spythag


    FUNCTION dpythag(a,b)

        REAL(8) :: a,b,dpythag
        REAL(8) :: absa,absb

        absa = abs(a)
        absb = abs(b)
        if(absa.gt.absb)then
            dpythag=absa*sqrt(1.+(absb/absa)**2)
        else
            if(absb.eq.0.)then
                dpythag=0.
            else
                dpythag=absb*sqrt(1.+(absa/absb)**2)
            endif
        endif
    END FUNCTION dpythag




    !--------------------------------------------------------------------------
    ! Impose a horizontal velocity in the exterior faces equal to the closes covered face
    ! This is only needed to compute the velocity modulus in faces adjecent to the       
    ! exterior zone                                                                        
    !                                                                                     
    ! Input : Flow, Mapping                                                                 
    ! OutPut: Velocity                                                                     
    ! Author: Paulo Chambel (99/6) 
    ! Last modification MRV 2001: Possible separation of OB conditions for barotropic and baroclinic
    !                              components of velocity                                                        

    Subroutine Velocity_OpenBoundary 
    

        !Arguments-------------------------------------------------------------
        

        !Local-----------------------------------------------------------------
        real, pointer, dimension(:,:,:) :: Velocity_UV_New


        !Begin - Shorten variables name 


        !Begin-----------------------------------------------------------------

        Velocity_UV_New   => Me%Velocity%Horizontal%UV%New

        if( Me%ComputeOptions%BaroclinicRadia == Horizontal_) then
  
           call Compute_BaroclinicHorVelocity   

        end if

        !PCL - temporary
cdsub: if (Me%SubModel%ON                                           .and.               &
           Me%ComputeOptions%LocalSolution /= AssimilaPlusSubModel_ .and.               &
           Me%ComputeOptions%LocalSolution /= AssimilationField_) then

            call VelSubModelNormalOB       ( Velocity_UV_New)


            call VelSubModelTangentialOB   ( Velocity_UV_New)

        else cdsub     

!PCL
!            if( Me%ComputeOptions%BaroclinicRadia == Horizontal_ ) then                                                

!                call VelNormalRadiaOpenBoundary    ( Velocity_UV_New,    &
!                                                    Me%VelBaroclinic%UV%New,&
!                                                    Me%VelBaroclinic%UV2D)



!                call VelTangentialRadiaOpenBoundary( Velocity_UV_New,    &
!                                                    Me%VelBaroclinic%UV%New,&
!                                                    Me%VelBaroclinic%UV2D)

!            else

                call VelNormalOpenBoundary     ( Velocity_UV_New)


                call VelTangentialOpenBoundary ( Velocity_UV_New)

!PCL
!            endif
            

        endif cdsub


        call MaskNonUsedFaces ( Velocity_UV_New)

        nullify(Velocity_UV_New)

    end Subroutine Velocity_OpenBoundary

    !------------------------------------------------------------------------------

    !--------------------------------------------------------------------------
    ! Impose a horizontal velocity in the exterior faces equal to the sum
    ! of baroclinic component compute using a radiation equation plus 
    ! a barotropic component equal to zero (option : NULL_VALUE ) or equal
    ! to the adjcent compute face barotropic component (option : NULL_GRADIENT)
    !
    !                                                                                     
    ! Input : Flow, Mapping                                                                 
    ! OutPut: Velocity                                                                     
    ! Author: Paulo Chambel (99/6)                                                         

    Subroutine VelTangentialRadiaOpenBoundary ( Velocity_UV_New,         &
                                               BaroclinicUV, BarotropicUV)
    

        !Arguments-------------------------------------------------------------
        
        real,    dimension(:,:,:), pointer :: Velocity_UV_New, BaroclinicUV
        real,    dimension(:,:  ), pointer :: BarotropicUV
                                                
        !Local-----------------------------------------------------------------

        real,    dimension(:,:,:), pointer :: SZZ
        real,    dimension(:,:  ), pointer :: DUX_VY
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedTangentialFacesUV
        integer, dimension(:,:),   pointer :: BoundaryPoints, KFloor_UV

        real                               :: Coef, Aux
        real                               :: DT_Velocity
        integer                            :: VelTangentialBoundary
        integer                            :: I, J, K, di, dj
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB
        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 


        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB


        BoundaryPoints           => Me%External_Var%BoundaryPoints

        ImposedTangentialFacesUV => Me%External_Var%ImposedTangentialFacesUV

        ComputeFaces3D_UV => Me%External_Var%ComputeFaces3D_UV

        KFloor_UV         => Me%External_Var%KFloor_UV

        DUX_VY            => Me%External_Var%DUX_VY
        SZZ               => Me%External_Var%SZZ

        DT_Velocity           = Me%Velocity%DT

        VelTangentialBoundary =  Me%ComputeOptions%VelTangentialBoundary


        di  = Me%Direction%di
        dj  = Me%Direction%dj


        !End   - Shorten variables name
        


cd1:    if (VelTangentialBoundary == NULL_VALUE) then


            dok: do k = KLB, KUB 
            doj: do j = JLB, JUB
            doi: do i = ILB, IUB

                if (ImposedTangentialFacesUV(i, j, k) == Imposed) then

                    Velocity_UV_New(i, j, k)   = BaroclinicUV(i, j, k)

                endif
                                  
            enddo doi
            enddo doj
            enddo dok


        else if (VelTangentialBoundary == NULL_GRADIENT) then cd1

            dok1: do k = KLB, KUB 
            doj1: do j = JLB, JUB
            doi1: do i = ILB, IUB


cd2:            if (ImposedTangentialFacesUV(i, j, k) == Imposed) then 


                    Aux = ComputeFaces3D_UV(i + dj, j + di, k) *  &
                          ComputeFaces3D_UV(i - dj, j - di, k)
        
                    if (Aux == 1) then ! both faces are compute points
                        Coef = 0.5 ! average between the two velocities
                    else
                        Coef = 1.
                    endif

               !In the exterior faces the 
                !velocity is imposed equal to the nearst compute face
                    Velocity_UV_New(i, j, k) = Coef                                * &
                                           (BarotropicUV     (i + dj, j + di   )   * &
                                            ComputeFaces3D_UV(i + dj, j + di, k)   + &
                                            BarotropicUV     (i - dj, j - di   )   * &
                                            ComputeFaces3D_UV(i - dj, j - di, k))  + &
                                            BaroclinicUV(i, j, k)
                                 
                endif cd2

            enddo doi1
            enddo doj1
            enddo dok1


        endif cd1

        !Nullify auxiliar pointers
        nullify(ComputeFaces3D_UV       )
        nullify(ImposedTangentialFacesUV)
        nullify(BoundaryPoints          )
        nullify(KFloor_UV)

        nullify(DUX_VY)
        nullify(SZZ)

        

    end Subroutine VelTangentialRadiaOpenBoundary



    !--------------------------------------------------------------------------
    ! Impose a horizontal velocity in the exterior faces (faces normal to the open boundary)                                
    !                                                                                     
    ! Input : Flow, Mapping                                                                 
    ! OutPut: Velocity                                                                     
    ! Author: Paulo Chambel (99/6)                                                         

    Subroutine VelNormalRadiaOpenBoundary ( Velocity_UV_New,             &
                                           BaroclinicUV, BarotropicUV)
    

        !Arguments-------------------------------------------------------------
        
        real,    dimension(:,:,:), pointer :: Velocity_UV_New, BaroclinicUV
        real,    dimension(:,:  ), pointer :: BarotropicUV
                                                
        !Local-----------------------------------------------------------------
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedNormalFacesUV


        real                               :: Vel_Right, Vel_Left
        
        integer                            :: VelNormalBoundary, imax, jmax, imin, jmin

        integer                            :: I, J, K, di, dj     
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB


        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB


        ImposedNormalFacesUV   => Me%External_Var%ImposedNormalFacesUV

        ComputeFaces3D_UV => Me%External_Var%ComputeFaces3D_UV


        VelNormalBoundary =  Me%ComputeOptions%VelNormalBoundary

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        !End   - Shorten variables name
        

        !--------------------------------------------------------------------------


cd1:    if (VelNormalBoundary == NULL_VALUE) then

            dok: do k = KLB, KUB 
            doj: do j = JLB, JUB + dj
            doi: do i = ILB, IUB + di

                if (ImposedNormalFacesUV(i, j, k) == Imposed) then

                    !In the exterior faces the 
                    !velocity is imposed equal to zero
                    Velocity_UV_New(i, j, k)   = BaroclinicUV(i, j, k) 

                endif
                                     
            enddo doi
            enddo doj
            enddo dok

        else if (VelNormalBoundary == NULL_GRADIENT) then  cd1

            dok1: do k = KLB, KUB 
            doj1: do j = JLB, JUB
            doi1: do i = ILB, IUB

cd2:            if (ImposedNormalFacesUV(i, j, k) == Imposed) then 


                     Vel_Left  = BarotropicUV     (i - di, j - dj)      *  &
                                 ComputeFaces3D_UV(i - di, j - dj, k)

                     Vel_Right = BarotropicUV     (i + di, j + dj   )   *  &
                                 ComputeFaces3D_UV(i + di, j + dj, k)

                    !In the exterior faces the 
                    !the barotropic velocity component is imposed equal to the nearest computed face
                    Velocity_UV_New(i, j, k)   =  Vel_Left + Vel_Right
                    !the baroclinic velocity component compute using a radiation equation is add                     
                    Velocity_UV_New(i, j, k)   =  Velocity_UV_New(i, j, k) + BaroclinicUV(i, j, k)
                                                 
                endif  cd2
                                   
            enddo doi1
            enddo doj1
            enddo dok1  

            !This is to avoid the error : arrays out of bounds

            imin = di * (IUB + di) + dj * ILB
            imax = di * (IUB + di) + dj * IUB
            
            jmin = dj * (JUB + dj) + di * JLB
            jmax = dj * (JUB + dj) + di * JUB

            dok2: do k = KLB, KUB 
            doi2: do i= imin, imax
            doj2: do j= jmin, jmax

cd3:            if (ImposedNormalFacesUV(i, j, k) == Imposed) then 

                         Vel_Left  = Velocity_UV_New  (i - di, j - dj, k) * &
                                     ComputeFaces3D_UV(i - di, j - dj, k)

                        !In the exterior faces the 
                        !velocity is imposed equal to the nearest computed face
                        Velocity_UV_New(i, j, k)   =  Vel_Left
                                                     
                
                endif  cd3

            enddo doj2
            enddo doi2
            enddo dok2

        endif cd1


        !Nullify auxiliar pointers
        nullify(ComputeFaces3D_UV)
        nullify(ImposedNormalFacesUV)

    end Subroutine VelNormalRadiaOpenBoundary

    !------------------------------------------------------------------------------


    !--------------------------------------------------------------------------
    ! Impose a horizontal velocity in the exterior faces (faces normal to the open boundary)                                
    !                                                                                     
    ! Input : Flow, Mapping                                                                 
    ! OutPut: Velocity                                                                     
    ! Author: Paulo Chambel (99/6)                                                         

    Subroutine MaskNonUsedFaces ( Velocity_UV_New)
    

        !Arguments-------------------------------------------------------------
        
        real,    dimension(:,:,:), pointer :: Velocity_UV_New
                                                
        !Local-----------------------------------------------------------------

        integer, dimension(:,:  ), pointer :: BoundaryPoints, BoundaryFacesUV, ExteriorFacesUV


        integer                            :: I, J, K, di, dj     
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        integer                            :: status 



        !Begin----------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB



        BoundaryFacesUV => Me%External_Var%BoundaryFacesUV
        BoundaryPoints  => Me%External_Var%BoundaryPoints

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        !End   - Shorten variables name
        
cd0:    if      (Me%Direction%XY == DirectionX_) then

            call GetExteriorBoundaryFaces(Me%ObjHorizontalMap,              &
                                          BoundaryPointsFaceU = ExteriorFacesUV, STAT = status) 

            if (status /= SUCCESS_)                                                      &
                call SetError(FATAL_, INTERNAL_, "MaskNonUsedFaces; Hydrodynamic. ERR01")     

        else if (Me%Direction%XY == DirectionY_) then cd0

            call GetExteriorBoundaryFaces(Me%ObjHorizontalMap,              &
                                      BoundaryPointsFaceV = ExteriorFacesUV, STAT = status) 

            if (status /= SUCCESS_)                                                      &
                call SetError(FATAL_, INTERNAL_, "MaskNonUsedFaces; Hydrodynamic. ERR02")     

        endif cd0
        !--------------------------------------------------------------------------


doj:    do j = JLB, JUB
doi:    do i = ILB, IUB
                
cd1:        if (BoundaryPoints(i, j) == Boundary) then

                
cd2:            if(BoundaryFacesUV(i     , j     ) == Not_Boundary .and.                 &
                   BoundaryFacesUV(i + di, j + dj) == Not_Boundary) then 
                                                
cd3:                if (ExteriorFacesUV(i, j) == Exterior) then
                              
                   dok: do k = KLB, KUB 

                            Velocity_UV_New(i, j, k) = Velocity_UV_New(i + di, j + dj, k)        

                        enddo dok

                    else if (ExteriorFacesUV(i + di, j + dj) == Exterior) then cd3
                              
                   dol: do k = KLB, KUB 

                            Velocity_UV_New(i + di, j + dj, k) = Velocity_UV_New(i, j, k)

                        enddo dol

 
                    endif cd3

                endif cd2

            endif cd1
                                 
        enddo doi
        enddo doj

        call UnGetHorizontalMap (Me%ObjHorizontalMap,                       &
                                 ExteriorFacesUV, STAT = status) 

        if (status /= SUCCESS_)                                                          &
            call SetError(FATAL_, INTERNAL_, "MaskNonUsedFaces; Hydrodynamic. ERR03")     


        !Nullify auxiliar pointers
        nullify(BoundaryFacesUV)
        nullify(BoundaryPoints )




    end Subroutine MaskNonUsedFaces

    !------------------------------------------------------------------------------


    !--------------------------------------------------------------------------
    ! Impose a horizontal velocity in the exterior faces (faces normal to the open boundary)                                
    !                                                                                     
    ! Input : Flow, Mapping                                                                 
    ! OutPut: Velocity                                                                     
    ! Author: Paulo Chambel (99/6)                                                         

    Subroutine VelNormalOpenBoundary ( Velocity_UV_New)
    

        !Arguments-------------------------------------------------------------
        
        real,    dimension(:,:,:), pointer :: Velocity_UV_New
                                                
        !Local-----------------------------------------------------------------

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedNormalFacesUV


        real                               :: Vel_Right, Vel_Left
        
        integer                            :: VelNormalBoundary, imax, jmax, imin, jmin

        integer                            :: I, J, K, di, dj     
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB


        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB


        ImposedNormalFacesUV   => Me%External_Var%ImposedNormalFacesUV

        ComputeFaces3D_UV => Me%External_Var%ComputeFaces3D_UV


        VelNormalBoundary =  Me%ComputeOptions%VelNormalBoundary

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        !End   - Shorten variables name
        

        !--------------------------------------------------------------------------


cd1:    if (VelNormalBoundary == NULL_VALUE) then

            dok: do k = KLB, KUB 
            doj: do j = JLB, JUB + dj
            doi: do i = ILB, IUB + di


                !In the exterior faces the 
                !velocity is imposed equal to zero
                Velocity_UV_New(i, j, k)   = Velocity_UV_New(i, j, k)         * &
                                             (1. - ImposedNormalFacesUV(i, j, k))  
                                     
            enddo doi
            enddo doj
            enddo dok

        else if (VelNormalBoundary == NULL_GRADIENT) then  cd1

            dok1: do k = KLB, KUB 
            doj1: do j = JLB, JUB
            doi1: do i = ILB, IUB

cd2:            if (ImposedNormalFacesUV(i, j, k) == Imposed) then 


                     Vel_Left  = Velocity_UV_New  (i - di, j - dj, k)   *  &
                                 ComputeFaces3D_UV(i - di, j - dj, k)

                     Vel_Right = Velocity_UV_New  (i + di, j + dj, k)   *  &
                                 ComputeFaces3D_UV(i + di, j + dj, k)

                    !In the exterior faces the 
                    !velocity is imposed equal to the nearest computed face
                    Velocity_UV_New(i, j, k)   =  Vel_Left + Vel_Right
                                                 
                endif  cd2
                                   
            enddo doi1
            enddo doj1
            enddo dok1  

            !This is to avoid the error : arrays out of bounds

            imin = di * (IUB + di) + dj * ILB
            imax = di * (IUB + di) + dj * IUB
            
            jmin = dj * (JUB + dj) + di * JLB
            jmax = dj * (JUB + dj) + di * JUB

            dok2: do k = KLB, KUB 
            doi2: do i= imin, imax
            doj2: do j= jmin, jmax

cd3:            if (ImposedNormalFacesUV(i, j, k) == Imposed) then 

                         Vel_Left  = Velocity_UV_New  (i - di, j - dj, k) * &
                                     ComputeFaces3D_UV(i - di, j - dj, k)

                        !In the exterior faces the 
                        !velocity is imposed equal to the nearest computed face
                        Velocity_UV_New(i, j, k)   =  Vel_Left
                                                     
                
                endif  cd3

            enddo doj2
            enddo doi2
            enddo dok2

        endif cd1


        !Nullify auxiliar pointers
        nullify(ComputeFaces3D_UV)
        nullify(ImposedNormalFacesUV)

    end Subroutine VelNormalOpenBoundary

    !------------------------------------------------------------------------------

    !--------------------------------------------------------------------------
    ! Impose a horizontal velocity in the exterior faces equal to the closes covered face
    ! This is only needed to compute the velocity modulus in faces adjecent to the       
    ! exterior zone                                                                        
    !                                                                                     
    ! Input : Flow, Mapping                                                                 
    ! OutPut: Velocity                                                                     
    ! Author: Paulo Chambel (99/6)                                                         

    Subroutine VelTangentialOpenBoundary ( Velocity_UV_New)
    

        !Arguments-------------------------------------------------------------
        
        real,    dimension(:,:,:), pointer :: Velocity_UV_New
                                                
        !Local-----------------------------------------------------------------

        real,    dimension(:,:,:), pointer :: SZZ
        real,    dimension(:,:  ), pointer :: DUX_VY
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedTangentialFacesUV
        integer, dimension(:,:),   pointer :: BoundaryPoints, KFloor_UV

        real                               :: Coef, Aux
        real                               :: DT_Velocity
        integer                            :: VelTangentialBoundary
        integer                            :: I, J, K, di, dj
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB
        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 


        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB


        BoundaryPoints           => Me%External_Var%BoundaryPoints

        ImposedTangentialFacesUV => Me%External_Var%ImposedTangentialFacesUV

        ComputeFaces3D_UV => Me%External_Var%ComputeFaces3D_UV

        KFloor_UV         => Me%External_Var%KFloor_UV

        DUX_VY            => Me%External_Var%DUX_VY
        SZZ               => Me%External_Var%SZZ

        DT_Velocity           = Me%Velocity%DT

        VelTangentialBoundary =  Me%ComputeOptions%VelTangentialBoundary


        di  = Me%Direction%di
        dj  = Me%Direction%dj


        !End   - Shorten variables name
        


cd1:    if (VelTangentialBoundary == NULL_VALUE) then


            dok: do k = KLB, KUB 
            doj: do j = JLB, JUB
            doi: do i = ILB, IUB

                !iSouth  = i - di
                !jWest   = j - dj


                !In the faces that have boundary points in both sides  
                !velocity is imposed equal to zero
                Velocity_UV_New(i, j, k)   = Velocity_UV_New(i, j, k)         *          &
                                             (1- ImposedTangentialFacesUV(i, j, k)) 
!                                             (1. - BoundaryPoints(i, j)       *          &
!                                             BoundaryPoints(iSouth, jWest))  

                                  
            enddo doi
            enddo doj
            enddo dok


        else if (VelTangentialBoundary == NULL_GRADIENT) then cd1

            dok1: do k = KLB, KUB 
            doj1: do j = JLB, JUB
            doi1: do i = ILB, IUB

!                iSouth  = i - di
!                jWest   = j - dj

!cd2:            if (BoundaryPoints(i      , j     ) == Boundary .and. &
!                    BoundaryPoints(iSouth, jWest) == Boundary) then 

cd2:            if (ImposedTangentialFacesUV(i, j, k) == Imposed) then 


                    Aux = ComputeFaces3D_UV(i + dj, j + di, k) *  &
                          ComputeFaces3D_UV(i - dj, j - di, k)
        
                    if (Aux == 1) then ! both faces are compute points
                        Coef = 0.5 ! average between the two velocities
                    else
                        Coef = 1.
                    endif

               !In the exterior faces the 
                !velocity is imposed equal to the nearst compute face
                    Velocity_UV_New(i, j, k) = Coef                                * &
                                           (Velocity_UV_New  (i + dj, j + di, k)   * &
                                            ComputeFaces3D_UV(i + dj, j + di, k)   + &
                                            Velocity_UV_New  (i - dj, j - di, k)   * &
                                            ComputeFaces3D_UV(i - dj, j - di, k))
                                 
                endif cd2

            enddo doi1
            enddo doj1
            enddo dok1


        endif cd1

        !Nullify auxiliar pointers
        nullify(ComputeFaces3D_UV       )
        nullify(ImposedTangentialFacesUV)
        nullify(BoundaryPoints          )
        nullify(KFloor_UV)

        nullify(DUX_VY)
        nullify(SZZ)

        

    end Subroutine VelTangentialOpenBoundary


    !--------------------------------------------------------------------------
    ! Impose a horizontal velocity in the exterior faces                                 
    !                                                                                     
    ! Input : Flow, Mapping                                                                 
    ! OutPut: Velocity                                                                     
    ! Author: Paulo Chambel (99/6)                                                         

    Subroutine VelSubModelNormalOB ( Velocity_UV_New)
    


        !Arguments-------------------------------------------------------------
        
        real,    dimension(:,:,:), pointer :: Velocity_UV_New
                                                
        !Local-----------------------------------------------------------------

        integer, dimension(:,:,:), pointer :: ImposedNormalFacesUV

        integer                            :: I, J, K, di, dj
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB


        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 


        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB


        ImposedNormalFacesUV   => Me%External_Var%ImposedNormalFacesUV

        di  = Me%Direction%di
        dj  = Me%Direction%dj


        !End   - Shorten variables name
        


        !--------------------------------------------------------------------------

cd5:     if (Me%SubModel%Set) then 

            dok2: do k = KLB, KUB 
            doj2: do j = JLB, JUB + dj
            doi2: do i = ILB, IUB + di

                !The faces that are exterior are put equal to the father model

cd4:            if (Me%External_Var%ImposedNormalFacesUV(i, j, k) == Imposed) then                  
                
                    Velocity_UV_New(i, j, k)   =  Me%SubModel%UV_New(i, j, k) 

                endif cd4

            enddo doi2
            enddo doj2
            enddo dok2

        else cd5

            call SetError (FATAL_, INTERNAL_, "VelSubModelNormalOB - Hydrodynamic - ERR01")        
            

        endif cd5



        !Nullify auxiliar pointers
        nullify(ImposedNormalFacesUV)

    end Subroutine VelSubModelNormalOB

    !------------------------------------------------------------------------------
    !------------------------------------------------------------------------------

    ! Author: Paulo Chambel (99/6)                                                         

    Subroutine VelSubModelTangentialOB ( Velocity_UV_New)
    

        !Arguments-------------------------------------------------------------

        real,    dimension(:,:,:), pointer :: Velocity_UV_New
                                                
        !Local-----------------------------------------------------------------

        integer, dimension(:,:,:), pointer :: ImposedTangentialFacesUV

        integer                            :: I, J, K, di, dj    
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB



        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 


        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB


        ImposedTangentialFacesUV => Me%External_Var%ImposedTangentialFacesUV


        di  = Me%Direction%di
        dj  = Me%Direction%dj


        !End   - Shorten variables name
        


        !--------------------------------------------------------------------------

cd5:     if (Me%SubModel%Set) then 

            dok2: do k = KLB, KUB 
            doj2: do j = JLB, JUB
            doi2: do i = ILB, IUB

                !In the faces that have boundary points in both sides  
                !velocity is imposed equal to the father velocity

cd4:            if (ImposedTangentialFacesUV(i, j, k) == Imposed) then                  
                
                    Velocity_UV_New(i, j, k)   =  Me%SubModel%UV_New(i, j, k) 

                endif cd4

            enddo doi2
            enddo doj2
            enddo dok2

        else cd5

            call SetError (FATAL_, INTERNAL_, "VelSubModelTangentialOB - Hydrodynamic - ERR01")        
            

        endif cd5



        !Nullify auxiliar pointers
        nullify(ImposedTangentialFacesUV)


        

    end Subroutine VelSubModelTangentialOB

    !------------------------------------------------------------------------------

           !------------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! Computes barotropic velocities by vertically integrating velocities                  !
    !                                                                                      !
    ! Input : Geometry, Mapping                                                            !
    ! OutPut: Barotropic velocities                                                        !
    ! Author: Manuel Ruiz Villarreal (01/4)                                                !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    subroutine Compute_BaroclinicHorVelocity  
        
        !Arguments-------------------------------------------------------------
        

                                                
        !Local-----------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_XY       
        real,    dimension(:,:,:), pointer :: Baroclinic_UV_New, Baroclinic_UV_Old,      &
                                              Velocity_UV_New, Area_UV, DWZ, Baroclinic_VU_New
        real,    dimension(:,:  ), pointer :: WaterColumnUV, WaterColumnZ, DYY_XX,       &
                                              DUX_VY, BarotropicUV
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedNormalFacesUV,   &
                                              ImposedTangentialFacesUV

        real                               :: DT_Velocity, WaveCelerityX, InternalCelerity
        real                               :: VelNormal, VelTang, VelMod, NormalDirection, TangDirection, LimitMax
        real(8)                            :: BarotropicVelocity

        integer                            :: I, J, K, kbottom, di, dj, ib , jb
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB,              &
                                              IUBSize, ILBSize, JUBSize, JLBSize

        integer                            :: i0, j0, i1, j1, i2, j2, i3, j3, i4, j4 

        integer                            :: NP, NT

        logical                            :: EastNorthBoundary, ConstantCelerity, ExplDiscrt


        !Begin----------------------------------------------------------------
         
        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KLB = Me%WorkSize%KLB      
        KUB = Me%WorkSize%KUB        

        IUBSize = Me%Size%IUB
        ILBSize = Me%Size%ILB
        JUBSize = Me%Size%JUB
        JLBSize = Me%Size%JLB

        
        DT_Velocity  = Me%Velocity%DT

        NP = 1
        NT = 1

        if (Me%VelBaroclinic%BaroclinicOBCDiscret  == Explicit_) then 

            ExplDiscrt = .true.

        else

            ExplDiscrt = .false.

        endif 
                    
        WaterColumnUV            => Me%External_Var%WaterColumnUV    
        WaterColumnZ             => Me%External_Var%WaterColumn    
        DWZ                      => Me%External_Var%DWZ
        Area_UV                  => Me%External_Var%Area_UV
        DYY_XX                   => Me%External_Var%DYY_XX
        DUX_VY                   => Me%External_Var%DUX_VY

        !Flow
        WaterFlux_XY             => Me%WaterFluxes%XY
        ComputeFaces3D_UV        => Me%External_Var%ComputeFaces3D_UV
        ImposedNormalFacesUV     => Me%External_Var%ImposedNormalFacesUV
        ImposedTangentialFacesUV => Me%External_Var%ImposedTangentialFacesUV
        Baroclinic_UV_New        => Me%VelBaroclinic%UV%New
        Baroclinic_VU_New        => Me%VelBaroclinic%VU%New
        Baroclinic_UV_Old        => Me%VelBaroclinic%UV%Old
        BarotropicUV             => Me%VelBaroclinic%UV2D

        Velocity_UV_New          => Me%Velocity%Horizontal%UV%New


        !End - Shorten


        di                = Me%Direction%di
        dj                = Me%Direction%dj

        !Baroclinic velocities are computed in every point of the domain. 
        !In principle, it only needs to be computed at boundaryfaces if we don't want to do output of barotropic velocities
        doj1: do j = JLB, JUB
        doi1: do i = ILB, IUB 

       
          !Compute internal baroclinic velocity
cd1:      if (ComputeFaces3D_UV(i, j, KUB) == Covered) then 

              kbottom            = Me%External_Var%kfloor_UV(i, j) 
              
              BarotropicVelocity = 0.

              do  k = kbottom, KUB
                  ![m^3/s]           = [m^3/s] + [m/s] * [m^2]
                  BarotropicVelocity = BarotropicVelocity + dble(Velocity_UV_New(i, j, k)) * &
                                                            dble(Area_UV(i, j, k))
        
              enddo
        
              BarotropicVelocity = BarotropicVelocity / dble(WaterColumnUV(i,j)) / dble(DYY_XX (i,j))

              BarotropicUV(i, j) = real(BarotropicVelocity)

              do  k = kbottom, KUB

                  Baroclinic_UV_Old (i, j, k) = Baroclinic_UV_New (i, j, k)
                    
                  Baroclinic_UV_New (i, j, k) = Velocity_UV_New(i, j, k) - BarotropicUV(i, j)

        
              enddo

        
           endif cd1

        end do doi1
        end do doj1



        
doj2:   do j = JLB, JUB + dj
doi2:   do i = ILB, IUB + di 


dok2:       do k = KLB, KUB            
cd2:            if (ImposedNormalFacesUV(i, j, k) == Imposed) then 


                    if (ComputeFaces3D_UV(i - di, j - dj, k) == Covered) then
                
                        ib  = i - di
                        jb  = j - dj

                        EastNorthBoundary = .true.

                        i0  = i -     di
                        j0  = j -     dj

                        i1  = i - 2 * di
                        j1  = j - 2 * dj

                        i2  = i - 2 * di + dj
                        j2  = j - 2 * dj + di

                        i3  = i - 2 * di
                        j3  = j - 2 * dj




                    else if (ComputeFaces3D_UV(i + di, j + dj, k) == Covered) then

                        ib  = i
                        jb  = j
                        EastNorthBoundary = .false.

                        i0  = i + di
                        j0  = j + dj

                        i1  = i + 2 * di
                        j1  = j + 2 * dj

                        i2  = i + di + dj
                        j2  = j + dj + di

                        i3  = i + di
                        j3  = j + dj


                    else

                        call SetError (FATAL_, INTERNAL_, "Compute_BaroclinicHorVelocity - Hydrodynamic - ERR01")

                    endif

                    ConstantCelerity = .false.

                    if (Me%VelBaroclinic%CelerityType /= Orlanski_) then

                        ConstantCelerity = .true.

                        if (Me%VelBaroclinic%CelerityType == Constant_) then

                            InternalCelerity = Me%VelBaroclinic%InternalCelerity &
                                               * DT_Velocity / DUX_VY(ib, jb)                 
                                               
                        else if (Me%VelBaroclinic%CelerityType == OeyAndChen_) then 

                            InternalCelerity = sqrt(1e-3 * Gravity * WaterColumnUV(i0, j0)) &
                                               * DT_Velocity / DUX_VY(ib, jb) 

                        endif


                        VelNormal        = (Baroclinic_UV_New(i0, j0, k) + Baroclinic_UV_New(i1, j1, k)) / 2.
                        VelTang          = (Baroclinic_VU_New(i2, j2, k) + Baroclinic_VU_New(i3, j3, k)) / 2.
                        VelMod           = sqrt(VelNormal ** 2 + VelTang ** 2)

                        if (VelMod < Me%VelBaroclinic%MinLeavingBaroclincVel) then
                        
                            NormalDirection  = 1.
                            TangDirection    = 0.

                        else

                            NormalDirection  = abs (VelNormal) / VelMod
                            TangDirection    = abs (VelTang  ) / VelMod

                            if (EastNorthBoundary) then

                                if ((VelTang * VelNormal) < 0) TangDirection = - TangDirection

                            else

                                if ((VelTang * VelNormal) > 0) TangDirection = - TangDirection

                            endif

                        endif

                    else

                        !Maximum internal velocity allowed (MaxInternalCelerity = 10 m/s)
                        LimitMax = MaxInternalCelerity * DT_Velocity / DUX_VY(ib, jb)

                    endif

                    if (Me%VelBaroclinic%BaroclinicOBCDiscret  == StoreWave_) then 

                        !PCL begin

                        WaveCelerityX = NormalDirection * InternalCelerity

                        call BoundaryInstantList (Me%VelBaroclinic%ImposedNormXY(NP), &
                                                  Me%CurrentTime, Baroclinic_UV_New,  &
                                                  Baroclinic_UV_Old, DT_Velocity,                  &
                                                  Me%VelBaroclinic%DTWave,            &
                                                  WaveCelerityX, i, j, k, i0, j0)

                        NP = NP + 1
                                    
                        !PCL end

                    else

                        call OrlanskiCelerity2D(NewField          = Baroclinic_UV_New,       &
                                                OldField          = Baroclinic_UV_Old,       &
                                                ComputePoints     = ComputeFaces3D_UV,       &
                                                Imin              = ILBSize,                 &
                                                Imax              = IUBSize,                 &
                                                Jmin              = JLBSize,                 &
                                                Jmax              = JUBSize,                 &
                                                di                = di,                      &
                                                dj                = dj,                      &
                                                i                 =  i,                      &
                                                j                 =  j,                      &
                                                k                 =  k,                      &
                                                EastNorthBoundary = EastNorthBoundary,       &
                                                DT                = DT_Velocity,           &
                                                LimitMax          = LimitMax,                &
                                                TrelaxIn          = Me%VelBaroclinic%TRelaxIn,          &
                                                TrelaxOut         = Me%VelBaroclinic%TRelaxOut,        &
                                                InternalCelerity  = InternalCelerity,        &
                                                WaveDirectionX    = NormalDirection,         &
                                                WaveDirectionY    = TangDirection,           & 
                                                ConstantCelerity  = ConstantCelerity,        &
                                                NormalRadiation   = Me%VelBaroclinic%BaroclinicNormalRadiation,   &
                                                Explicit          = ExplDiscrt,              &
                                                WaveCelerityX     = WaveCelerityX)


                    endif



                endif cd2

cd3:            if (ImposedTangentialFacesUV(i, j, k) == Imposed) then 


                    if (ComputeFaces3D_UV(i - dj, j - di, k) == Covered) then

                        EastNorthBoundary = .true.

                        i0  = i -     dj
                        j0  = j -     di

                        i1  = i -     di
                        j1  = j -     dj

                        i2  = i
                        j2  = j

                        i3  = i - di - dj
                        j3  = j - dj - di 

                        i4  = i - dj 
                        j4  = j - di 



                    else if (ComputeFaces3D_UV(i + dj, j + di, k) == Covered) then


                        EastNorthBoundary = .false.

                        i0  = i + dj
                        j0  = j + di

                        i1  = i + dj
                        j1  = j + di

                        i2  = i - di + dj
                        j2  = j - dj + di

                        i3  = i + 2 * dj
                        j3  = j + 2 * di 

                        i4  = i - di + 2 * dj
                        j4  = j - dj + 2 * di 

                    else

!                       call SetError (FATAL_, INTERNAL_, "Compute_BaroclinicHorVelocity - Hydrodynamic - ERR02")
                        Cycle


                    endif

                    ConstantCelerity = .false.

                    if (Me%VelBaroclinic%CelerityType /= Orlanski_) then

                        ConstantCelerity = .true.

                        if (Me%VelBaroclinic%CelerityType == Constant_) then

                            InternalCelerity = Me%VelBaroclinic%InternalCelerity &
                                               * DT_Velocity / (DYY_XX(i, j) + DYY_XX(i0, j0)) * 2.                 
                                               
                        else if (Me%VelBaroclinic%CelerityType == OeyAndChen_) then 

                            InternalCelerity = sqrt(1e-3 * Gravity * WaterColumnUV(i0, j0)) &
                                               * DT_Velocity / (DYY_XX(i, j) + DYY_XX(i0, j0)) * 2.                 

                        endif



                        VelNormal        = (Baroclinic_VU_New(i1, j1, k) + Baroclinic_VU_New(i2, j2, k) + &
                                            Baroclinic_VU_New(i3, j3, k) + Baroclinic_VU_New(i4, j4, k)) / 4.
                        VelTang          =  Baroclinic_UV_New(i0, j0, k)
                        VelMod           = sqrt(VelNormal ** 2 + VelTang ** 2)

                        if (VelMod < Me%VelBaroclinic%MinLeavingBaroclincVel) then
                        
                            NormalDirection  = 1.
                            TangDirection    = 0.

                        else

                            NormalDirection  = abs (VelNormal) / VelMod
                            TangDirection    = abs (VelTang  ) / VelMod

                            if (EastNorthBoundary) then

                                if ((VelTang * VelNormal) < 0) TangDirection = - TangDirection

                            else

                                if ((VelTang * VelNormal) > 0) TangDirection = - TangDirection

                            endif

                        endif

                    else

                        !Maximum internal velocity allowed (MaxInternalCelerity = 10 m/s)
                        LimitMax = MaxInternalCelerity * DT_Velocity / (DYY_XX(i, j) + DYY_XX(i0, j0)) * 2.

                    endif

                    if (Me%VelBaroclinic%BaroclinicOBCDiscret  == StoreWave_) then 

                        !PCL begin
                        WaveCelerityX = NormalDirection * InternalCelerity

                        call BoundaryInstantList (Me%VelBaroclinic%ImposedTangXY(NT), &
                                                  Me%CurrentTime, Baroclinic_UV_New,  &
                                                  Baroclinic_UV_Old, DT_Velocity,                  &
                                                  Me%VelBaroclinic%DTWave,            &
                                                  WaveCelerityX, i, j, k, i0, j0)

                        NT = NT + 1
                                    
                        !PCL end

                    else


                        call OrlanskiCelerity2D(NewField          = Baroclinic_UV_New,       &
                                                OldField          = Baroclinic_UV_Old,       &
                                                ComputePoints     = ComputeFaces3D_UV,       &
                                                Imin              = ILBSize,                 &
                                                Imax              = IUBSize,                 &
                                                Jmin              = JLBSize,                 &
                                                Jmax              = JUBSize,                 &
                                                di                = dj,                      &
                                                dj                = di,                      &
                                                i                 =  i,                      &
                                                j                 =  j,                      &
                                                k                 =  k,                      &
                                                EastNorthBoundary = EastNorthBoundary,       &
                                                DT                = DT_Velocity,             &
                                                LimitMax          = LimitMax,                &
                                                TrelaxIn          = Me%VelBaroclinic%TRelaxIn,          &
                                                TrelaxOut         = Me%VelBaroclinic%TRelaxOut,        &
                                                InternalCelerity  = InternalCelerity,        &
                                                WaveDirectionX    = NormalDirection,         &
                                                WaveDirectionY    = TangDirection,           & 
                                                ConstantCelerity  = ConstantCelerity,        &
                                                NormalRadiation   = Me%VelBaroclinic%BaroclinicNormalRadiation, &
                                                Explicit          = ExplDiscrt,              &
                                                WaveCelerityX     = WaveCelerityX)

                    endif 

                endif cd3


            end do dok2



        end do doi2
        end do doj2



        nullify (WaterFlux_XY            )
        nullify (WaterColumnUV           )
        nullify (Area_UV                 )
        nullify (DYY_XX                  )
        nullify (DUX_VY                  )
        nullify (ComputeFaces3D_UV       )
        nullify (ImposedNormalFacesUV    )
        nullify (ImposedTangentialFacesUV)
        nullify (Baroclinic_UV_New       )
        nullify (Baroclinic_VU_New       )
        nullify (Baroclinic_UV_Old       )
        nullify (Velocity_UV_New         )
        nullify (WaterColumnZ            )
        nullify (DWZ                     )
        nullify (BarotropicUV            )

         
    end subroutine Compute_BaroclinicHorVelocity


    Subroutine BoundaryInstantList (ImposedXY, CurrentTime, Prop_New, Prop_Old, DT_Prop, &
                                    DTWave, WaveCelerityX, i, j, k, ib, jb)


        !Arguments----------------------------------------------------------------------------
        type (T_Imposed)                :: ImposedXY
        type (T_Time)                   :: CurrentTime
        real, dimension(:,:,:), pointer :: Prop_New, Prop_Old
        real                            :: DT_Prop, DTWave, WaveCelerityX
        integer                         :: i, j, k, ib, jb

        !Local--------------------------------------------------------------------------------
        type (T_InstantBound), pointer  :: InstantXY, AuxXY
        type (T_Time)                   :: NextInstant, NewInstant
        real(8)                         :: DT1, DT2
        integer                         :: status
        logical                         :: Found

        !Begin--------------------------------------------------------------------------------


        !Add Instant

cd1:    if (abs(WaveCelerityX) < 1e-4) then
        
            NewInstant  = CurrentTime  + DT_Prop / 1e-4

        else  cd1
            
            NewInstant  = CurrentTime  + DT_Prop / WaveCelerityX 

        endif cd1

cd2:    if (associated(ImposedXY%FirstInstant)) then

            NextInstant = ImposedXY%LastInstant%TimeB + DTWave

        else  cd2

            call null_time(NextInstant)

        endif cd2

        nullify (InstantXY)

        allocate(InstantXY, STAT = status)

        if (status /= SUCCESS_)                                                      &
            call SetError (FATAL_, INTERNAL_, "BoundaryInstantList - Hydrodynamic - ERR01")

        nullify (InstantXY%Next)
        nullify (InstantXY%Prev)

        InstantXY%TimeB    = NewInstant
        InstantXY%BaroclVel= Prop_New(ib, jb, k)

cd3:    if (.not.associated(ImposedXY%FirstInstant)) then
            ImposedXY%Number           =  1
            ImposedXY%FirstInstant     => InstantXY
            ImposedXY%LastInstant      => InstantXY
        else  cd3
                
cd4:        if (.not.associated(ImposedXY%FirstInstant%Next)) then
                
cd5:            if (NewInstant >= NextInstant) then

                    InstantXY%Prev             => ImposedXY%LastInstant
                    ImposedXY%LastInstant%Next => InstantXY
                    ImposedXY%LastInstant      => InstantXY
                    ImposedXY%Number           =  ImposedXY%Number + 1

                endif cd5

            else  cd4
                            
cd6:            if (NewInstant >= NextInstant) then
                    
                    InstantXY%Prev             => ImposedXY%LastInstant
                    ImposedXY%LastInstant%Next => InstantXY
                    ImposedXY%LastInstant      => InstantXY
                    ImposedXY%Number           =  ImposedXY%Number + 1

                else  cd6

                    AuxXY => ImposedXY%FirstInstant

                    Found = .false. 

                    do While(associated(AuxXY) .and. associated(AuxXY%Next)) 
        
                        if (AuxXY%TimeB <= CurrentTime .and. AuxXY%Next%TimeB >= CurrentTime) then
                            if ((CurrentTime      - AuxXY%TimeB) >  DTWave) Found = .true. 
                            if ((AuxXY%Next%TimeB - CurrentTime) >  DTWave) Found = .true. 
                            exit

                        endif

                        AuxXY => AuxXY%Next 

                    enddo 

                    if (Found) then

                        InstantXY%Prev        => AuxXY
                        InstantXY%Next        => AuxXY%Next
                        AuxXY%Next            => InstantXY
                        ImposedXY%Number      =  ImposedXY%Number + 1

                    endif

                endif cd6

            endif  cd4

        endif cd3

        !Delete obsolete instants

        nullify(InstantXY)

        nullify(AuxXY) 

        if (associated(ImposedXY%FirstInstant%Next)) then
            
            do while (ImposedXY%FirstInstant%Next%TimeB < CurrentTime) 

                AuxXY                  => ImposedXY%FirstInstant
                ImposedXY%FirstInstant => ImposedXY%FirstInstant%Next
                ImposedXY%Number       =  ImposedXY%Number - 1

                deallocate (AuxXY, STAT = status)

                if (status /= SUCCESS_)                                                      &
                    call SetError (FATAL_, INTERNAL_, "BoundaryInstantList - Hydrodynamic - ERR02")
            
                nullify(AuxXY) 

            enddo 

        endif

        nullify(AuxXY) 

        AuxXY => ImposedXY%FirstInstant

        Found = .false. 

        do While(associated(AuxXY) .and. associated(AuxXY%Next)) 
        
            if (AuxXY%TimeB <= CurrentTime .and. AuxXY%Next%TimeB >= CurrentTime) then

                Found = .true. 
                exit

            endif


            AuxXY => AuxXY%Next 

        enddo 

        if (Found) then

            DT1 = AuxXY%Next%TimeB - CurrentTime
            DT2 = CurrentTime      - AuxXY%TimeB

            Prop_Old(i, j, k) =  Prop_New(i, j, k)

            Prop_New(i, j, k) = (real(DT1) * AuxXY%BaroclVel + real(DT2) * AuxXY%Next%BaroclVel) /       &
                                 real(DT1 + DT2)

        else

            Prop_New(i, j, k) = 0.

        endif

        nullify(AuxXY) 

    end subroutine BoundaryInstantList



    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! Actualizes variables needed to impose boundary conditions                            !
    ! at the bottom and at the surface                                                     ! 
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping                                                      !
    ! OutPut: Chezy                                                                        !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Bottom_Boundary
    

        !Arguments-----------------------------------------------------------------

         !Categories  
            !Bottom    : Chezy, Rugosity, HMIN_ATR
            !Flow      : WaterFlux_XY, Me%WaterFluxes%New_Old, Velocity_UV_New, Velocity_UV_Old
            !Mapping   : KFloor_Z

                                            
        !Arguments------------------------------------------------------------
         

        !Local-----------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Bottom_Boundary")

       !Bottom boundary
        call Modify_ChezyZ 

        call Modify_ChezyVelUV 


        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Bottom_Boundary")

    !------------------------------------------------------------------------------

    End Subroutine Bottom_Boundary

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! Compute the Chezy bottom friction coeficient                                         !
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping                                                      !
    ! OutPut: Chezy                                                                        !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Modify_ChezyZ 

        !Variables Categories  
            !Geometry  : DWZ
            !Bottom    : Chezy, Rugosity, HMIN_ATR
            !Flow      : WaterFlux_XY, Me%WaterFluxes%New_Old, Velocity_UV_New, Velocity_UV_Old
            !Mapping   : KFloor_Z

        !Arguments------------------------------------------------------------
         

                                            
        !Local---------------------------------------------------------------------
        real,    dimension(:,:,:), pointer :: DWZ
        real,    dimension(:,:),   pointer :: ChezyZ, RugosityMatrix
        integer, dimension(:,:,:), pointer :: WaterPoints3D
        integer, dimension(:,:),   pointer :: KFloor_Z
        real                               :: AuxZ, Hmin_Chezy, EP, WallDistance, Rugosity
        logical                            :: Manning

        integer                            :: IUB, ILB, JUB, JLB, KUB
        integer                            :: I, J, kbottom

        !Begin--------------------------------------------------------------------------

        !Begin - Shorten variables name 
        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB

        Hmin_Chezy     =  Me%External_Var%Hmin_Chezy

        Manning        =  Me%External_Var%Manning

        RugosityMatrix => Me%External_Var%RugosityMatrix

        ChezyZ         => Me%External_Var%ChezyZ

        KFloor_Z       => Me%External_Var%KFloor_Z

        WaterPoints3D  => Me%External_Var%WaterPoints3D
        DWZ            => Me%External_Var%DWZ

        !End - Shorten variables name 


        if (KUB > 1 .and. Manning) then 

            call SetError (FATAL_, INTERNAL_, "Modify_ChezyZ - Hydrodynamic - ERR03")        

        endif

            
doj:    do  j = JLB, JUB
doi:    do  i = ILB, IUB
                    
cd2:        if (WaterPoints3D(i, j, KUB) == WaterPoint) then 
                ! For a non water point Kfloor_Z = -999999
                Kbottom     = KFloor_Z(i, j)

                AUXZ        = MAX(DWZ(I, J, Kbottom), Hmin_Chezy)

                EP          = 1./3.


cd0:            if (Me%External_Var%Chezy) then

                    ChezyZ(i, j) = Me%External_Var%ChezyCoef

                else cd0

                    Rugosity    = RugosityMatrix(i, j)

cd1:                if (Rugosity == 0.) then
                
                        ChezyZ(i, j) = 0.
                
                    else cd1
                 
cd3:                    if (Manning) then
                
                             ![]          =  [m/s2] *   [m-1/3 * s]**2         / [m1/3] 
                             ChezyZ(i, j) = Gravity * Rugosity**2 / AUXZ**EP
                 
                         else cd3
                
                             !To avoid wall distance values lower than rugosity
                             WallDistance = AuxZ/2. + Rugosity
                
                             if (WallDistance <= Rugosity)                                    &
                                 call SetError (FATAL_, INTERNAL_, "Modify_ChezyZ - Hydrodynamic - ERR04")        
                
                
                             ! [] = [] / log ([m]/[m])
                             ChezyZ(i, j) = (Const_VonKarman / LOG(WallDistance / Rugosity))**2.
                
                         endif cd3
                
                    endif cd1
                
                endif cd0

            endif cd2

        enddo doi
        enddo doj

        !Nullify auxiliar variables
        nullify (KFloor_Z)
        nullify (DWZ)
        nullify (ChezyZ)
        nullify (WaterPoints3D)
        nullify (RugosityMatrix)

    end Subroutine Modify_ChezyZ

    !------------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! Compute the Chezy bottom friction coeficient                                         !
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping                                                      !
    ! OutPut: Chezy                                                                        !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Modify_ChezyVelUV 

        !Variables Categories  
            !Bottom    : ChezyVelUV, Rugosity, HMIN_ATR
            !Flow      : WaterFlux_XY, Me%WaterFluxes%New_Old, Velocity_UV_New, Velocity_UV_Old
            !Mapping   : KFloor_Z

        !Arguments------------------------------------------------------------
         

                                            
        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Volume_UV
        real,    dimension(:,:,:), pointer :: DUZ_VZ, Velocity_UV_New, Velocity_VU_New
        real,    dimension(:,:),   pointer :: ChezyVelUV, RugosityMatrix, DUX_VY,        &
                                              DYY_XX, DZX_ZY, DXX_YY
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV
        real                               :: AuxZ, Hmin_Chezy, EP, WallDistance,        &
                                              Rugosity, Vmin_Chezy, Chezy, DT_Z,         &
                                              VelMod_UV, DT_Velocity, ChezyWave
        logical                            :: Manning 

        integer                            :: iSouth, jWest, di, dj, i_North, j_East
        integer                            :: IUB, ILB, JUB, JLB, KUB
        integer                            :: I, J, kbottom

        !Begin--------------------------------------------------------------------------

        !Begin - Shorten variables name 
        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB


        di                = Me%Direction%di
        dj                = Me%Direction%dj

        Hmin_Chezy        =  Me%External_Var%Hmin_Chezy

        Vmin_Chezy        =  Me%External_Var%Vmin_Chezy

        Manning           =  Me%External_Var%Manning

        DT_Velocity       =  Me%Velocity%DT

        RugosityMatrix    => Me%External_Var%RugosityMatrix

        ChezyVelUV        => Me%External_Var%ChezyVelUV

        KFloor_UV         => Me%External_Var%KFloor_UV
        Volume_UV         => Me%External_Var%Volume_UV

        ComputeFaces3D_UV => Me%External_Var%ComputeFaces3D_UV
        DUZ_VZ            => Me%External_Var%DUZ_VZ
        DUX_VY            => Me%External_Var%DUX_VY
        DXX_YY            => Me%External_Var%DXX_YY
        DYY_XX            => Me%External_Var%DYY_XX
        DZX_ZY            => Me%External_Var%DZX_ZY

        Velocity_UV_New   => Me%Velocity%Horizontal%UV%New
        Velocity_VU_New   => Me%Velocity%Horizontal%VU%New

        !End - Shorten variables name 


        if (KUB > 1 .and. Manning) then 
            
            call SetError (FATAL_, INTERNAL_, "Modify_ChezyVelUV - Hydrodynamic - ERR03")        

        endif

            
doj:    do  j = JLB, JUB
doi:    do  i = ILB, IUB
                    
cd2:        if (ComputeFaces3D_UV(i, j, KUB) == Covered) then 
                ! For a non water point Kfloor_UV = -999999
                Kbottom     = KFloor_UV(i, j)

                iSouth     = i - di
                jWest      = j - dj
                ! This values (i_North and j_east) can only be use to compute the velocity modulus in a face
                i_North = i + dj
                j_East  = j + di

cd0:            if (Me%External_Var%Chezy) then

                    Chezy = Me%External_Var%ChezyCoef

                else cd0

cd4:                if (abs(Velocity_UV_New(i, j, Kbottom)) < Vmin_Chezy) then
                    
                        AUXZ        = MAX(DUZ_VZ(i, j, Kbottom), Hmin_Chezy)

                    else  cd4

                        AUXZ        = DUZ_VZ(i, j, Kbottom)

                    endif cd4

                    EP          = 1./3.



                    Rugosity = (RugosityMatrix(i      , j     ) * DUX_VY(iSouth, jWest) +  &
                                RugosityMatrix(iSouth, jWest) * DUX_VY(i      , j     ))/  &
                               (DUX_VY        (iSouth, jWest) + DUX_VY(i      , j     ))

cd1:                if (Rugosity == 0.) then

                        Chezy = 0.

                    else cd1
                
cd3:                   if (Manning) then 

                            ![]         =  [m/s2] * [m-1/3 * s]**2/ [m1/3] 
                            Chezy = Gravity * Rugosity**2 / AUXZ**EP
                
                        else cd3

                            !To avoid wall distance values lower than rugosity
                            WallDistance = AuxZ/2. + Rugosity

                            if (WallDistance <= Rugosity)  then

                                write(*,*) 'AuxZ, IUB ,JUB, X, Y, I, J=', AuxZ, IUB ,JUB, dj, di, I, J

                                call SetError (FATAL_, INTERNAL_, "Modify_ChezyVelUV - Hydrodynamic - ERR04")        

                            endif



                            ! [] = [] / log ([m]/[m])
                            Chezy = (Const_VonKarman / LOG(WallDistance / Rugosity))**2.


                        endif cd3

                    endif cd1

                endif cd0

                ![s/m]                    = [s] / [m^3] * [m] * [m]
                DT_Z                      = DT_Velocity / Volume_UV(i, j, Kbottom)     &
                                            * DZX_ZY(iSouth, jWest) * DYY_XX(I, J)

                VelMod_UV                 = Face_Velocity_Modulus(                     &
                                            Velocity_VU_New(I_North, jWest, kbottom),  &
                                            Velocity_VU_New(I_North, J_East, kbottom), &
                                            Velocity_VU_New(iSouth, jWest, kbottom),   &
                                            Velocity_VU_New(iSouth, J_East, kbottom),  &
                                            DXX_YY(I_North, jWest),                    &
                                            DXX_YY(I_North, J_East),                   &
                                            DXX_YY(iSouth, jWest),                     &
                                            DXX_YY(iSouth, J_East),                    &
                                            Velocity_UV_New(I,J,kbottom))                

                ![]              = []       [s/m] * [m/s]
                ChezyVelUV(i, j) = Chezy  * DT_Z * VelMod_UV


                if (Me%ComputeOptions%WaveStress) then

                    ChezyWave = Face_Interpolation(Me%External_Var%WaveChezyVel(i, j), &
                                                   Me%External_Var%WaveChezyVel(iSouth, jWest), &
                                                   DUX_VY(I, J), DUX_VY(iSouth, jWest))

                    ![]       = [m/s] * [s/m] 
                    ChezyWave = ChezyWave * DT_Z

                    ChezyVelUV(i, j) = ChezyVelUV(i, j) + ChezyWave

                endif

            else  cd2

                ChezyVelUV(i, j) = FillValueReal

            endif cd2

        enddo doi
        enddo doj

        !Nullify auxiliar variables
        nullify (KFloor_UV         )
        nullify (DUZ_VZ            )
        nullify (DUX_VY            ) 
        nullify (DUZ_VZ            )
        nullify (DUX_VY            )
        nullify (DXX_YY            )
        nullify (DYY_XX            )
        nullify (DZX_ZY            )
        nullify (ChezyVelUV        )
        nullify (ComputeFaces3D_UV )
        nullify (RugosityMatrix    )
        nullify (Velocity_UV_New   )
        nullify (Velocity_VU_New   )
        nullify (Volume_UV         )
  
    end Subroutine Modify_ChezyVelUV

    !------------------------------------------------------------------------------


    !Compute all the variables common to the velocities and elevation computing 
    Subroutine Explicit_Forces  

        !Variables Categories
        ! Geometry   : Volume_Z, Area_VU, DWZ, DZX_ZY, DXX_YY, DUX_VY, DYY_XX, Coriolis_Freq
        ! Flow       : Visc_H_Center, Visc_H_Corner, Velocity_UV, Velocity_VU_Old,                          
        !              WaterFlux_XY, WaterFlux_YX
        ! Forces     : Rox3, Horizontal_Transport, Inertial_Aceleration
        ! WaterProp  : Density
        ! Options    : Baroclinic, UpStream_CenterDif, UpStream, Direction
        ! Mapping    : KFloor_UV, ComputeFaces3D_UV
        ! Domain     : ILB, IUB, JLB, JUB, KLB, KUB

        !Variables direction dependent:
        !  Velocity_UV, Velocity_VU_Old, WaterFlux_XY, WaterFlux_YX,
        !  Area_VU, DZX_ZY, DXX_YY, DUX_VY, DYY_XX, KFloor_UV, ComputeFaces3D_UV


        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Explicit_Forces")

        !Baroclinic density gradient integral
        if (Me%ComputeOptions%Baroclinic)                                      &
            call Modify_ROX3  
            
        call Modify_Horizontal_Transport  
        
        !Inertial aceleration 
        if (Me%ComputeOptions%InertiaForces)                                    &
            call Modify_InertiaForces

        !Obstacle drag
        if (Me%ComputeOptions%Obstacle)                                         &
            call Modify_ObstacleDrag


        !Compute the tide potential as a tide elevation
        if (Me%TidePotential%Compute)                                           &
            call ModifyTidePotential 


        !Adds a force that relax the velocity field to a reference field
        if (Me%Relaxation%Force)                                                &
            call ModifyRelaxAceleration 
        
        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Explicit_Forces")

    End Subroutine Explicit_Forces

    !End-----------------------------------------------------------------------



    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the total horizontal inertia =                              !
    !  Hor. Advection + Hor. Diffusion + Coriolis Force                                   !
    !                                                                                      !
    ! Input : Flow, Geometry, Mapping                                                      !
    ! OutPut: Horizontal_Transport                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Modify_Horizontal_Transport 
    

        !Variables Categories-----------------------------------------------------------------

        !Categories  
           !Geometry  : Volume_Z, Area_VU, DYY_XX, DUX_VY
           !Flow      : Velocity_UV_Old, Velocity_VU_Old, WaterFlux_XY, WaterFlux_YX, 
           !            Visc_H_Center, Visc_H_Corner
           !Mapping   : ComputeFaces3D_UV, KFloor_UV, Direction


         
        !Variables Direction Dependent
           !Area_VU, DYY_XX, DUX_VY
           !Velocity_UV_Old, Velocity_VU_Old, WaterFlux_XY, WaterFlux_YX, 
           !Visc_H_Center, Visc_H_Corner
           !ComputeFaces3D_UV, KFloor_UV, Direction

        !Arguments--------------------------------------------------------------------------


        !Local-----------------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport
        real,    dimension(:,:,:), pointer :: Aux_UX_VY, Aux_UY_VX, Velocity_UV_Old
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, LandBoundaryFacesUV

        integer                            :: I, J, K
                          
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !--------------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB
       
        Horizontal_Transport => Me%Forces%Horizontal_Transport

        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        LandBoundaryFacesUV  => Me%External_Var%LandBoundaryFacesUV
        !End - Shorten variables name 



do1:    do k = KLB, KUB
do2:    do j = JLB, JUB
do3:    do i = ILB, IUB
    
            Horizontal_Transport(I, J, K) = 0.
    
        enddo do3
        enddo do2
        enddo do1

cd1:    if (Me%ComputeOptions%HorizontalAdvection) then

            call Modify_Advection_UY_VX 

            call Modify_Advection_UX_VY 

            if (.not. Me%CyclicBoundary%ON .or.                             &
                     (Me%CyclicBoundary%ON .and.                            &
                      Me%CyclicBoundary%Direction == Me%Direction%YX))      &
                call Modify_Advection_Bound  

            call AdvectionInSmallDepths 

            if (Me%Relaxation%HorizAdv)                                     &
                call ModifyRelaxHorizAdv


        endif cd1


cd2:    if (Me%ComputeOptions%HorizontalDiffusion) then
            !Biharmonic filter is able to dissipate the high frequency variabiliy (1dx,4dx and 6dx) 
            !without dissipating energy associated with the big spatial scales
cd3:        if (Me%ComputeOptions%BiHarmonic) then

                !If the BiHarmonic option is true then is compute the laplacian
                !of the velocity in the velocity direction (Aux_UX_VY) and perpendiculary
                !to the velocity (Aux_UX_VY),

                Me%ComputeOptions%BiHarmonicUX_VY(:,:,:) = 0

                Me%ComputeOptions%BiHarmonicUY_VX(:,:,:) = 0

                Aux_UX_VY => Me%ComputeOptions%BiHarmonicUX_VY
                
                Aux_UY_VX => Me%ComputeOptions%BiHarmonicUY_VX

                call LaplacianXY( Velocity_UV_Old, Aux_UX_VY)          
                      
                !For Aux_UX_VY are admitted the same normal open 
                !boundary conditions of the velocities
                if (Me%CyclicBoundary%ON .and. (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                                                Me%CyclicBoundary%Direction == DirectionXY_)) then

                    call CyclicBoundVectNormal  (Aux_UX_VY)                                                

                else

                    call VelNormalOpenBoundary  (Aux_UX_VY)

                endif

                call LaplacianYX( Velocity_UV_Old, Aux_UY_VX)                

                !For Aux_UY_VX are admitted the same tangential open 
                !boundary conditions of the velocities
                if (Me%CyclicBoundary%ON .and. (Me%CyclicBoundary%Direction == Me%Direction%YX .or. &
                                                Me%CyclicBoundary%Direction == DirectionXY_)) then
    
                    call CyclicBoundVectTangential   (Aux_UY_VX)

                else

                    call VelTangentialOpenBoundary   (Aux_UY_VX)

                endif


                call Modify_Diffusion_UY_VX  ( Aux_UY_VX, Biharmonic = .true.)

                call Modify_Diffusion_UX_VY  ( Aux_UX_VY, Biharmonic = .true.)

cd44:           if (Me%SubModel%ON) then

                    call ModifyDiffSub_UY_VX ( Aux_UY_VX, Biharmonic = .true.)                

                    call ModifyDiffSub_UX_VY ( Aux_UX_VY, Biharmonic = .true.)

                endif cd44


                nullify(Aux_UX_VY)
                nullify(Aux_UY_VX)

            endif cd3
            !Turbulent diffusion
            Aux_UY_VX => Me%Velocity%Horizontal%UV%Old    
                        
            Aux_UX_VY => Me%Velocity%Horizontal%UV%Old

            call Modify_Diffusion_UY_VX  ( Aux_UY_VX, Biharmonic = .false.)

            call Modify_Diffusion_UX_VY  ( Aux_UX_VY, Biharmonic = .false.)

cd4:        if (Me%SubModel%ON) then

                call ModifyDiffSub_UY_VX ( Aux_UY_VX, Biharmonic = .false.)                

                call ModifyDiffSub_UX_VY ( Aux_UX_VY, Biharmonic = .false.)

            endif cd4


            nullify(Aux_UX_VY)
            nullify(Aux_UY_VX)

        endif cd2


        if (Me%ComputeOptions%VolumeVariation)                              &
            call ModifyVolumeVariation 

        !Compute the momentum discharge 
        if (Me%ComputeOptions%MomentumDischarge)                            &
            call ModifyMomentumDischarge 


        do  k = KLB, KUB
        do  j = JLB, JUB
        do  i = ILB, IUB

            ! Large values (FillReal_Value) in non covered faces  
            Horizontal_Transport (i, j, k) = Horizontal_Transport (i, j, k)    * &
                                             ComputeFaces3D_UV(i, j, k)        + &
                                             (1. - ComputeFaces3D_UV(i, j, k)) * &
                                             FillValueReal

            ! Land boundary condition - horizontal transport zero in faces that 
            ! have water in one side and land in another 
            Horizontal_Transport (i, j, k) = Horizontal_Transport (i, j, k) * &
                                             (1. - LandBoundaryFacesUV(i, j, k))
            
        enddo
        enddo
        enddo

   

        !Nullify auxiliar pointers
        nullify (Horizontal_Transport)
        nullify (ComputeFaces3D_UV   )
        nullify (LandBoundaryFacesUV )
        nullify (Velocity_UV_Old     )


    end Subroutine Modify_Horizontal_Transport

    !------------------------------------------------------------------------------
    Subroutine Modify_Advection_Bound

        !Arguments--------------------------------------------------------------------------


        !Local-----------------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport
        integer, dimension(:,:),   pointer :: BoundaryFacesUV
        integer                            :: I, J, K
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !--------------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        Horizontal_Transport => Me%Forces%Horizontal_Transport
        BoundaryFacesUV      => Me%External_Var%BoundaryFacesUV


cd1:    if (Me%Submodel%ON) then

            call Modify_UX_VY_SubModel   

            call Modify_UY_VX_SubModel   
        
        else cd1

            call Modify_UX_VY_Boundary   

            call Modify_UY_VX_Boundary   

cd2:        if (Me%ComputeOptions%NullBoundaryHorAdv) then

do4 :           do  k = KLB, KUB
do5 :           do  j = JLB, JUB
do6 :           do  i = ILB, IUB
                    !Horizontal Advection null in the boundary faces  
                    Horizontal_Transport (i, j, k) = Horizontal_Transport (i, j, k) * &
                                                     (1. - BoundaryFacesUV(i, j)) 

                end do do6
                end do do5
                end do do4
                
            endif cd2

            nullify(Horizontal_Transport)
            nullify(BoundaryFacesUV     )


        endif cd1
        
                    

    end Subroutine Modify_Advection_Bound

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the horizontal advection with the same direction of the    !
    !  velocity. For the U velocity compute the advection with the X direction            !       
    !  for the V velocity compute the advection with the Y direction                      !
    !                                                                                      !
    ! Input : Flow, Mapping,                                                               !
    ! OutPut: Horizontal_Transport                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Modify_Advection_UX_VY  
      

        !Variables Categories----------------------------------------------------------------
        ! Flow     : WaterFlux_XY (Horizontal water fluxes), Velocity_UV_Old (U or V velocity)
        ! Mapping  : KFloor_UV (first water layer for a i, j face), ComputeFaces3D_UV  (1 - covered faces, 0 - not covered faces) 
        ! Options  : UpStream_CenterDif (1-Upwind and 0-Centered differences),ImplicitVertAdvection (1 - implict, 0 - explicit)
        ! Direction: Direction (DirectionX=1,DirectionY_=2)
        ! Dimension: ILB (i lower bound), IUB (i upper bound), JLB (j lower bound), JUB (j upper bound), KUB (k upper bound)
        ! OutPut   : Horizontal_Transport 

        !Variables direction dependent: 
        !Velocity_UV_Old, WaterFlux_XY, Horizontal_Transport, ComputeFaces3D_UV, Direction, KFloor_UV


        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_XY, Horizontal_Transport, Volume_UV
        real,    dimension(:,:,:), pointer :: Velocity_UV_Old
        real,    dimension(:,:),   pointer :: DZX_ZY

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedNormalFacesUV
        integer, dimension(:,:),   pointer :: KFloor_UV

        real(8), dimension(2)              :: V2
        real,    dimension(4)              :: CFace, Vel4, du4
         
!        real                               :: UpStream_CenterDif, Aux

!        real                               :: Coef1_Up, Coef2_Up, Coef3_Up, Coef_Centered

        real(8)                            :: FaceFlux_WestSouth, MomentumFlux

!        real                               :: Coef1_WestSouth, Coef2_WestSouth, Coef3_WestSouth, Coef4_WestSouth
 
 !       real                               :: Cell1_FaceWestSouth, Cell2_FaceWestSouth, Cell3_FaceWestSouth, Cell4_FaceWestSouth

 !       real                               :: Cell_1, Cell_2, Cell_3, Cell_4

        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest, i_North, j_East, iSouth2, &
                                              jWest2, iSouth3, jWest3

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        logical                            :: ComputeFlux, NearBoundary

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

!        UpStream_CenterDif   =  Me%ComputeOptions%UpStream_CenterDif

!        Coef1_Up             =  Me%HorAdvection%Coef1_Up
!        Coef2_Up             =  Me%HorAdvection%Coef2_Up
!        Coef3_Up             =  Me%HorAdvection%Coef3_Up

        WaterFlux_XY         => Me%WaterFluxes%XY
        Horizontal_Transport => Me%Forces%Horizontal_Transport
        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old

        DZX_ZY               => Me%External_Var%DZX_ZY
        Volume_UV            => Me%External_Var%Volume_UV

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        ImposedNormalFacesUV => Me%External_Var%ImposedNormalFacesUV
        KFloor_UV            => Me%External_Var%KFloor_UV

        !End - Shorten variables name 

        !Centered difference coefficient equal for both faces (West/South = East/North)
!        Coef_Centered = 0.5

    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

            iSouth  = i -   di
            jWest   = j -   dj
            i_North = i +   di
            j_East  = j +   dj
            iSouth2 = i - 2*di
            jWest2  = j - 2*dj
            iSouth3 = i - 3*di
            jWest3  = j - 3*dj


            ComputeFlux = .false.

            !This condition impose in the open boundary gradient null for the horizontal advection 
            if (ComputeFaces3D_UV(i, j, KUB)            == Covered .and. &
                ComputeFaces3D_UV(iSouth, jWest, KUB) == Covered ) ComputeFlux = .true.
            
            if (Me%CyclicBoundary%ON .and. (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                                            Me%CyclicBoundary%Direction == DirectionXY_)) then
            
                if ((ComputeFaces3D_UV   (i     , j    , KUB) == Covered .and.           &
                     ImposedNormalFacesUV(iSouth, jWest, KUB) == Imposed).or.            &
                    (ComputeFaces3D_UV   (iSouth, jWest, KUB) == Covered .and.           &
                     ImposedNormalFacesUV(i     , j    , KUB) == Imposed)) ComputeFlux = .true.

            endif
 
cd0:        if (ComputeFlux) then


                Kbottom = max(KFloor_UV(i, j), KFloor_UV(iSouth, jWest))

                    ! West or South Face
        dok1:   do k = Kbottom, KUB
                

                    !UpStream Coefficients :
                    !if (FaceFlux_WestSouth>0) then
                    !   !When the velocity compute point j - 2 or i - 2 is not covered then 
                       !(Aux = 0) the advection term is always compute using a upwind scheme
                   !    Aux             = ComputeFaces3D_UV(iSouth2, jWest2, k)
                   !    Coef1_WestSouth = Coef1_Up * Aux
                   !    Coef2_WestSouth = Coef2_Up * Aux + (1. - Aux)
                   !    Coef3_WestSouth = Coef3_Up * Aux
                   !    Coef4_WestSouth = 0.
                   ! else 
                   !    Coef1_WestSouth = 0.
                   !    Coef2_WestSouth = Coef3_Up
                   !    Coef3_WestSouth = Coef2_Up
                   !    Coef4_WestSouth = Coef1_Up 
                   ! endif 

                    !Total Coefficient (Upstream + Centered difference)
                   ! Cell1_FaceWestSouth = Coef1_WestSouth * UpStream_CenterDif

                    !Cell2_FaceWestSouth = Coef2_WestSouth * UpStream_CenterDif + &
                    !                      Coef_Centered   * (1. - UpStream_CenterDif)

                    !Cell3_FaceWestSouth = Coef3_WestSouth * UpStream_CenterDif + &
                    !                      Coef_Centered   * (1. - UpStream_CenterDif)

                    !Cell4_FaceWestSouth = Coef4_WestSouth * UpStream_CenterDif

                    ![m^3/s*m/s]  = [m/s*m^3/s]

                    ! j-2 or i-2
                    !Cell_1 = Velocity_UV_Old(iSouth2, jWest2, k) * Cell1_FaceWestSouth

                    ! j-1 or i-1
                    !Cell_2 = Velocity_UV_Old(iSouth,  jWest,  k) * Cell2_FaceWestSouth 
                                                                      
                    ! j or i
                    !Cell_3 = Velocity_UV_Old(i,        j,       k) * Cell3_FaceWestSouth 

                    ! j+1 or i+1
                    !Cell_4 = Velocity_UV_Old(i_North,  j_East,  k) * Cell4_FaceWestSouth 



                    FaceFlux_WestSouth = (WaterFlux_XY(iSouth, jWest, k) + &
                                         WaterFlux_XY(i, j, k))/2.            ![m^3/s]

                    NearBoundary = .false.


                    Vel4(1) = Velocity_UV_Old(iSouth2, jWest2, k);
                    Vel4(2) = Velocity_UV_Old(iSouth,  jWest,  k);
                    Vel4(3) = Velocity_UV_Old(i,       j,      k);
                    Vel4(4) = Velocity_UV_Old(i_North, j_East, k);


                    if (FaceFlux_WestSouth > 0) then
                        if (ComputeFaces3D_UV(iSouth2, jWest2, k) /= Compute) then
                            NearBoundary = .true.
                            du4(1) = FillValueReal;
                        else
                            du4(1) = DZX_ZY(iSouth3, jWest3);
                        endif
                    else
                        if (ComputeFaces3D_UV(i_North,  j_East,  k) /= Compute) NearBoundary = .true.
                    endif

                    du4(2) = DZX_ZY(iSouth2, jWest2);
                    du4(3) = DZX_ZY(iSouth,  jWest );
                    du4(4) = DZX_ZY(i,       j     );


                    !du4  (1) = DZX_ZY  (i-2);du4  (2) = du  (i-1);du4  (3) = du  (i);du4  (4) = du  (i+1);
                    V2   (1) = Volume_UV  (iSouth,  jWest,  k);
                    V2   (2) = Volume_UV  (i     ,  j    ,  k);

                    call ComputeAdvectionFace(Vel4, V2, du4, Me%Velocity%DT,            &
                                              FaceFlux_WestSouth,                       &
                                              Me%ComputeOptions%VolumeRelMax,           &
                                              Me%ComputeOptions%AdvectionMethodH,       &
                                              Me%ComputeOptions%TVD_LimH,               &
                                              NearBoundary,                             &
                                              Me%ComputeOptions%Upwind2H, CFace)



                    MomentumFlux = dble(Vel4(1) * CFace(1)  + Vel4(2) * CFace(2)  +     &
                                        Vel4(3) * CFace(3)  + Vel4(4) * CFace(4)) *     &
                                        FaceFlux_WestSouth ![m/s*m^3/s]

                    Horizontal_Transport(i, j, k)            = Horizontal_Transport(i, j, k) + &
                                                               MomentumFlux                       

                    Horizontal_Transport(iSouth, jWest, k) = Horizontal_Transport(iSouth, jWest, k)  - &
                                                               MomentumFlux
           
                enddo dok1
            endif cd0

        enddo doj
        enddo doi

        !Nullify auxiliar pointers
        nullify (WaterFlux_XY        )
        nullify (Horizontal_Transport)
        nullify (Velocity_UV_Old     )
        nullify (ComputeFaces3D_UV   )
        nullify (KFloor_UV           )
        nullify (ImposedNormalFacesUV)

        nullify (DZX_ZY              )
        nullify (Volume_UV           )


    End Subroutine Modify_Advection_UX_VY

    
    !End ----------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the horizontal advection with the perpendicular direction  !
    !  in the horizontal plane of the velocity. For the U velocity compute the             !
    !  advection with the Y direction for the V velocity compute the advection with the  !
    !  X direction                                                                         !
    !                                                                                      !
    ! Input : Flow, Mapping, Geometry, Time steps                                          !
    ! OutPut: Horizontal_Transport                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Modify_Advection_UY_VX 

      

        !Variables categories
        ! Geometry : DYY_XX  (U or V Control Volume width) 
        ! Flow     : WaterFlux_YX (Water flux perpendicular to the velocity direction), Velocity_UV_Old (U or V velocity)
        ! Mapping  : KFloor_UV (first water layer for a i, j face), ComputeFaces3D_UV  (1 - covered faces, 0 - not covered faces) 
        ! Options  : UpStream_CenterDif (1-Upwind and 0-Centered differences), ImplicitVertAdvection (1-implict, 0- explicit)
        ! Direction: Direction (DirectionX=1,DirectionY_=2)
        ! Dimension: ILB (i lower bound), IUB (i upper bound), JLB (j lower bound), JUB (j upper bound), KUB (k upper bound)
        ! OutPut   : Horizontal_Transport

        !Arguments dependent from the direction: 
        ! DYY_XX, Velocity_UV_Old, Horizontal_Transport, WaterFlux_YX, ComputeFaces3D_UV, 
        ! Direction, Kfloor_UV, WaterFlux_YX


        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_YX, Horizontal_Transport, Volume_UV
        real,    dimension(:,:,:), pointer :: Velocity_UV_Old 
        real,    dimension(:,:),   pointer :: DYY_XX

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedTangentialFacesUV
        integer, dimension(:,:),   pointer :: KFloor_UV, BoundaryFacesUV

        !real                               :: UpStream_CenterDif, Aux

!        real                               :: Coef1_Up, Coef2_Up, Coef3_Up, Coef2_Centered_SW, &
!                                              Coef3_Centered_SW

        real(8)                            :: FaceFlux_SouthWest, MomentumFlux

!        real                               :: Coef1_SouthWest, Coef2_SouthWest, Coef3_SouthWest, Coef4_SouthWest

!        real                               :: Cell1_FaceSouthWest, Cell2_FaceSouthWest, Cell3_FaceSouthWest, Cell4_FaceSouthWest

!        real                               :: Cell_1, Cell_2, Cell_3, Cell_4
    
        integer                            :: di, dj, i, j, k, Kbottom
        integer                            :: iSouth, jWest, i_West, j_South, i_East, j_North, &
                                              i_West2, j_South2

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        logical                            :: NotBoundary, FaceLeftOK, FaceRightOK, NearBoundary

        real(8), dimension(2)              :: V2
        real,    dimension(4)              :: CFace, Vel4, du4


        !Begin---------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

!        UpStream_CenterDif   =  Me%ComputeOptions%UpStream_CenterDif

!        Coef1_Up             =  Me%HorAdvection%Coef1_Up
!        Coef2_Up             =  Me%HorAdvection%Coef2_Up
!        Coef3_Up             =  Me%HorAdvection%Coef3_Up

        WaterFlux_YX         => Me%WaterFluxes%YX
        Horizontal_Transport => Me%Forces%Horizontal_Transport
        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old

        Volume_UV            => Me%External_Var%Volume_UV

        ComputeFaces3D_UV        => Me%External_Var%ComputeFaces3D_UV
        ImposedTangentialFacesUV => Me%External_Var%ImposedTangentialFacesUV
        BoundaryFacesUV          => Me%External_Var%BoundaryFacesUV
        KFloor_UV                => Me%External_Var%KFloor_UV
        DYY_XX                   => Me%External_Var%DYY_XX


        !End - Shorten variables name 

doj:    do j=JLB, JUB
doi:    do i=ILB, IUB
            
            iSouth  = i -   di
            jWest   = j -   dj

            i_West   = i -   dj
            j_South  = j -   di

            i_East   = i +   dj
            j_North  = j +   di

            i_West2  = i - 2*dj
            j_South2 = j - 2*di

cd1:        if (BoundaryFacesUV  (i     , j      ) == Not_Boundary .and.                 &
                BoundaryFacesUV  (i_West, j_South) == Not_Boundary) then
                
                NotBoundary = .true.

            else  cd1

                NotBoundary = .false.

            endif cd1

            !When the boundary is Cyclic the momentum advection flux is also compute for the boundary faces
            if (Me%CyclicBoundary%ON .and. (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                                            Me%CyclicBoundary%Direction == DirectionXY_)) NotBoundary = .true.

cd2:        if (ComputeFaces3D_UV       (i, j, KUB) == Covered .or.                      &
                ImposedTangentialFacesUV(i, j, KUB) == Imposed) then

                FaceRightOK = .true.

            else  cd2

                FaceRightOK = .false.

            endif cd2

cd3:        if (ComputeFaces3D_UV       (i_West, j_South, KUB) == Covered .or.           &
                ImposedTangentialFacesUV(i_West, j_South, KUB) == Imposed) then

                FaceLeftOK = .true.

            else  cd3

                FaceLeftOK = .false.

            endif cd3

cd4:       if (NotBoundary .and. FaceRightOK .and. FaceLeftOK) then

                Kbottom = max(KFloor_UV(i, j), KFloor_UV(i_West, j_South))

dok1:           do k = Kbottom, KUB


                   !The water flux Y in the South face of a U cell
                   !is equal (WaterFlux_Y(i, j, k) + WaterFlux_Y(i, j-1, k))/2
                   !It's not needed to do a complex interpolation because 
                   !the Area of this face is equal to (Area_V(i,j,k)+AreaV(i,j-1,k))/2.

                   !South or West Face
!                   FaceFlux_SouthWest = (WaterFlux_YX(iSouth  , jWest, k) + &
!                                         WaterFlux_YX(i, j, k))/2.            

                   !Centered difference coefficient 
                   !Coef2_Centered_SW = DYY_XX(i, j) / (DYY_XX(i_West, j_South) + DYY_XX(i, j))
                   !Coef3_Centered_SW = DYY_XX(i_West, j_South) / (DYY_XX(i_West, j_South) + DYY_XX(i, j))

                   !UpStream Coefficients :
!cd5:               if (FaceFlux_SouthWest>0) then

                       !When the velocity compute point i - 2 or j - 2 is not covered then 
                       !(Aux = 0) the advection term is always compute using a upwind scheme
!                      Aux             = ComputeFaces3D_UV(i_West2, j_South2, k)
!                      Coef1_SouthWest = Coef1_Up * Aux
!                      Coef2_SouthWest = Coef2_Up * Aux + (1. - Aux)
!                      Coef3_SouthWest = Coef3_Up * Aux
!                      Coef4_SouthWest = 0.

!                  else  cd5

                       !When the velocity compute point i + 1 or j + 1 is not covered then 
                       !(Aux = 0) the advection term is always compute using a upwind scheme
!                      Aux             = ComputeFaces3D_UV(i_East, j_North, k)
!                      Coef1_SouthWest = 0.
!                      Coef2_SouthWest = Coef3_Up * Aux
!                      Coef3_SouthWest = Coef2_Up * Aux + (1. - Aux)
!                      Coef4_SouthWest = Coef1_Up * Aux

!                  endif cd5

                   !Total Coefficient (Upstream + Centered difference)
!                  Cell1_FaceSouthWest = Coef1_SouthWest   * UpStream_CenterDif

!                  Cell2_FaceSouthWest = Coef2_SouthWest   * UpStream_CenterDif + &
!                                        Coef2_Centered_SW * (1. - UpStream_CenterDif)

!                  Cell3_FaceSouthWest = Coef3_SouthWest   * UpStream_CenterDif + &
!                                        Coef3_Centered_SW * (1. - UpStream_CenterDif)

!                  Cell4_FaceSouthWest = Coef4_SouthWest   * UpStream_CenterDif

                   ! i-2 or j-2
!                  Cell_1 = Velocity_UV_Old(i_West2, j_South2, k) * Cell1_FaceSouthWest
                   ! i-1 or j-1
!                  Cell_2 = Velocity_UV_Old(i_West, j_South,   k) * Cell2_FaceSouthWest 
                   ! i or j
!                  Cell_3 = Velocity_UV_Old(i,            j,   k) * Cell3_FaceSouthWest
                   ! i+1 or j+1
!                  Cell_4 = Velocity_UV_Old(i_East, j_North,   k) * Cell4_FaceSouthWest

                   !The water flux Y in the South face of a U cell
                   !is equal (WaterFlux_Y(i, j, k) + WaterFlux_Y(i, j-1, k))/2
                   !It's not needed to do a complex interpolation because 
                   !the Area of this face is equal to (Area_V(i,j,k)+AreaV(i,j-1,k))/2.

                    !South or West Face
                    FaceFlux_SouthWest = (WaterFlux_YX(iSouth  , jWest, k) + &
                                          WaterFlux_YX(i, j, k))/2.  
                    
                    NearBoundary = .false.


                    if (FaceFlux_SouthWest > 0) then
                        if (ComputeFaces3D_UV(i_West2, j_South2, k) /= Compute) NearBoundary = .true.
                    else
                        if (ComputeFaces3D_UV(i_East,  j_North,  k) /= Compute) NearBoundary = .true.
                    endif

                    Vel4(1) = Velocity_UV_Old(i_West2, j_South2, k);
                    Vel4(2) = Velocity_UV_Old(i_West, j_South,   k);
                    Vel4(3) = Velocity_UV_Old(i     , j,         k);
                    Vel4(4) = Velocity_UV_Old(i_East, j_North,   k);

                    du4(1) = DYY_XX(i_West2, j_South2)
                    du4(2) = DYY_XX(i_West, j_South  )
                    du4(3) = DYY_XX(i     , j        )
                    du4(4) = DYY_XX(i_East, j_North  )

                    !du4  (1) = DZX_ZY  (i-2);du4  (2) = du  (i-1);du4  (3) = du  (i);du4  (4) = du  (i+1);
                    V2   (1) = Volume_UV  (i_West, j_South,   k);
                    V2   (2) = Volume_UV  (i     ,  j     ,   k);

                    call ComputeAdvectionFace(Vel4, V2, du4, Me%Velocity%DT,            &
                                              FaceFlux_SouthWest,                       &
                                              Me%ComputeOptions%VolumeRelMax,           &
                                              Me%ComputeOptions%AdvectionMethodH,       &
                                              Me%ComputeOptions%TVD_LimH,               &
                                              NearBoundary,                             &
                                              Me%ComputeOptions%Upwind2H, CFace)



                    MomentumFlux = dble(Vel4(1) * CFace(1)  + Vel4(2) * CFace(2)  +     &
                                        Vel4(3) * CFace(3)  + Vel4(4) * CFace(4)) *     &
                                        FaceFlux_SouthWest ![m/s*m^3/s]
                    
                           
                    Horizontal_Transport(i, j, k)           = Horizontal_Transport(i, j, k) + &
                                                              MomentumFlux

                    Horizontal_Transport(i_West, j_South, k)= Horizontal_Transport(i_West, j_South, k) - &
                                                              MomentumFlux


                enddo dok1

            endif cd4

        enddo doi
        enddo doj

        !Nullify auxiliar pointers
        nullify (WaterFlux_YX            )
        nullify (Horizontal_Transport    )
        nullify (Velocity_UV_Old         )
        nullify (ComputeFaces3D_UV       )
        nullify (ImposedTangentialFacesUV)
        nullify (KFloor_UV               )
        nullify (DYY_XX                  )
        nullify (BoundaryFacesUV         )
        nullify (Volume_UV           )



    End Subroutine Modify_Advection_UY_VX
    
        !End ----------------------------------------------------------------------


    !------------------------------------------------------------------------------

    Subroutine Modify_UX_VY_Boundary  
      


        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_XY, Horizontal_Transport
        real,    dimension(:,:,:), pointer :: Velocity_UV_Old 
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedNormalFacesUV
        integer, dimension(:,:),   pointer :: KFloor_UV, BoundaryFacesUV

        real                               :: VelAux
         
        real(8)                            :: MomentumFlux

        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest, i_North, j_East

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        WaterFlux_XY         => Me%WaterFluxes%XY
        Horizontal_Transport => Me%Forces%Horizontal_Transport
        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        ImposedNormalFacesUV => Me%External_Var%ImposedNormalFacesUV
        KFloor_UV            => Me%External_Var%KFloor_UV
        BoundaryFacesUV      => Me%External_Var%BoundaryFacesUV

        !End - Shorten variables name 

 
    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

            iSouth  = i -   di
            jWest   = j -   dj
            i_North  = i +   di
            j_East   = j +   dj

 
cd0:        if (BoundaryFacesUV  (i, j     ) == Boundary .and.                                  &
                ComputeFaces3D_UV(i, j, KUB) == Covered) then

                Kbottom = KFloor_UV(i, j)


                    ! West or South Face
                               
!cd1:            if (BoundaryFacesUV   (i_North, j_East)      == Not_Boundary .and.       &
!                    ComputeFaces3D_UV (i_North, j_East, KUB) == Not_Covered) then

cd1:            if (ImposedNormalFacesUV (i_North, j_East, KUB)  == Imposed) then
 
            dok1:   do k = Kbottom, KUB

                        if (WaterFlux_XY(i, j, k) > 0.) then

                            VelAux = Velocity_UV_Old(i, j, k)

                        else

                            VelAux = Velocity_UV_Old(i_North, j_East, k)

                        endif
                        
                        ![m^3/s*m/s]  = [m/s*m^3/s]
                        MomentumFlux = dble(VelAux) * WaterFlux_XY(i, j, k) ![m/s*m^3/s]


                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k) - &
                                                         MomentumFlux

                    enddo dok1
                                                        
!                else if (BoundaryFacesUV   (iSouth, jWest)      == Not_Boundary .and.  &
!                         ComputeFaces3D_UV (iSouth, jWest, KUB) == Not_Covered ) then cd1
                
                else if (ImposedNormalFacesUV (iSouth, jWest, KUB)  == Imposed) then cd1

            dok2:   do k = Kbottom, KUB

                        if (WaterFlux_XY(i, j, k) > 0.) then

                            VelAux = Velocity_UV_Old(iSouth, jWest, k)

                        else

                            VelAux = Velocity_UV_Old(i, j, k)

                        endif


                        ![m^3/s*m/s]  = [m/s*m^3/s]
                        MomentumFlux = dble(VelAux) * WaterFlux_XY(i, j, k) ![m/s*m^3/s]


                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k) + &
                                                         MomentumFlux                       


                    enddo dok2

                endif cd1
         

            endif cd0

        enddo doj
        enddo doi
 
        !Nullify auxiliar pointers
        nullify (WaterFlux_XY        )
        nullify (Horizontal_Transport)
        nullify (Velocity_UV_Old     )
        nullify (KFloor_UV           )
        nullify (BoundaryFacesUV     )
        nullify (ComputeFaces3D_UV   )
        nullify (ImposedNormalFacesUV)

    End Subroutine Modify_UX_VY_Boundary

    
    !End ----------------------------------------------------------------------


    !------------------------------------------------------------------------------

    Subroutine Modify_UX_VY_SubModel 
      


        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_XY, Horizontal_Transport, Sub_qXY
        real,    dimension(:,:,:), pointer :: Velocity_UV_Old !,Sub_UV
        real,    dimension(:,:  ), pointer :: DYY_XX

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedNormalFacesUV
        integer, dimension(:,:),   pointer :: KFloor_UV, BoundaryFacesUV
         
        real(8)                            :: MomentumFlux, FatherFlux, SonFlux, AverageFlux

        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest, i_North, j_East

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        WaterFlux_XY         => Me%WaterFluxes%XY
        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old
        Horizontal_Transport => Me%Forces%Horizontal_Transport
        !Sub_UV               => Me%SubModel%UV
        Sub_qXY              => Me%SubModel%qXY

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        ImposedNormalFacesUV => Me%External_Var%ImposedNormalFacesUV
        BoundaryFacesUV      => Me%External_Var%BoundaryFacesUV
        KFloor_UV            => Me%External_Var%KFloor_UV
        DYY_XX               => Me%External_Var%DYY_XX

        !End - Shorten variables name 


    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

            iSouth  = i -   di
            jWest   = j -   dj
            i_North  = i +   di
            j_East   = j +   dj

 
cd0:        if (BoundaryFacesUV  (i, j)      == Boundary .and.                           &
                ComputeFaces3D_UV(i, j, KUB) == Covered) then
                
                Kbottom = KFloor_UV(i, j)

                ! East or North Face          

!cd1:            if (BoundaryFacesUV   (i_North, j_East)      == Not_Boundary .and.       &
!                    ComputeFaces3D_UV (i_North, j_East, KUB) == Not_Covered) then

cd1:            if (ImposedNormalFacesUV (i_North, j_East, KUB) == Imposed) then

            dok1:   do k = Kbottom, KUB

            
                       ![m^3/s]  = [m^3/s]
                        SonFlux    =  WaterFlux_XY(i, j, k) ![m/s*m^3/s]


                        ![m^3/s]   = [m^2/s]*[m]

                        FatherFlux =      Sub_qXY (i_North, j_East, k)  *                &
                                     dble(DYY_XX  (i_North, j_East)   )
                    
                        AverageFlux  = (FatherFlux + SonFlux) / 2.

                        if (AverageFlux > 0 ) then

                            ![m^3/s*m/s] = [m/s*m^3/s]
                            MomentumFlux = dble(Velocity_UV_Old(i,  j,  k))          * AverageFlux

                        else

                            ![m^3/s*m/s] = [m/s*m^3/s]
                            MomentumFlux = dble(Velocity_UV_Old(i_North, j_East, k)) * AverageFlux

                        endif


                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k) - &
                                                         MomentumFlux

                    enddo dok1

                ! West or South Face

!                else if (BoundaryFacesUV   (iSouth, jWest)      == Not_Boundary .and.  &
!                         ComputeFaces3D_UV (iSouth, jWest, KUB) == Not_Covered ) then cd1

                else if (ImposedNormalFacesUV (iSouth, jWest, KUB) == Imposed) then cd1

            dok2:   do k = Kbottom, KUB



                       ![m^3/s]  = [m^3/s]
                        SonFlux    =  WaterFlux_XY(i, j, k) ![m/s*m^3/s]


                        ![m^3/s]  = [m^2/s]*[m]
                        FatherFlux =      Sub_qXY (iSouth, jWest, k)  *                &
                                     dble(DYY_XX  (iSouth, jWest)   )

                        AverageFlux  = (FatherFlux + SonFlux) / 2.

                        if (AverageFlux > 0 ) then

                            ![m^3/s*m/s] = [m/s*m^3/s]
                            MomentumFlux = dble(Velocity_UV_Old(iSouth, jWest, k)) * AverageFlux

                        else

                            ![m^3/s*m/s] = [m/s*m^3/s]
                            MomentumFlux = dble(Velocity_UV_Old(i,  j,  k))          * AverageFlux

                        endif


                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k) + &
                                                         MomentumFlux                       

                    enddo dok2

                endif cd1
         
            endif cd0

        enddo doj
        enddo doi

        !Nullify auxiliar pointers
        nullify (WaterFlux_XY        )
        nullify (Horizontal_Transport)
        !nullify (Sub_UV             )
        nullify (Sub_qXY             )
        nullify (DYY_XX              )
        nullify (KFloor_UV           )
        nullify (BoundaryFacesUV     )
        nullify (Velocity_UV_Old     )
        nullify (ComputeFaces3D_UV   )
        nullify (ImposedNormalFacesUV)

    End Subroutine Modify_UX_VY_SubModel

    
    !End ----------------------------------------------------------------------


    !------------------------------------------------------------------------------

    Subroutine Modify_UY_VX_Boundary  
      


        !Arguments------------------------------------------------------------
        


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport, WaterFlux_YX

        real,    dimension(:,:,:), pointer :: Velocity_UV_Old

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ComputeFaces3D_VU
        integer, dimension(:,:),   pointer :: KFloor_UV, BoundaryFacesUV,                &
                                              BoundaryFacesVU

        real(8)                            :: MomentumFluxUp, MomentumFluxDown,          &
                                              WaterFluxUp   , WaterFluxDown

        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest , i_East,                  &
                                              j_North, i_West, j_South

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB


        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        WaterFlux_YX         => Me%WaterFluxes%YX
        Horizontal_Transport => Me%Forces%Horizontal_Transport
        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        ComputeFaces3D_VU    => Me%External_Var%ComputeFaces3D_VU
        KFloor_UV            => Me%External_Var%KFloor_UV

        BoundaryFacesUV      => Me%External_Var%BoundaryFacesUV
        BoundaryFacesVU      => Me%External_Var%BoundaryFacesVU

        !End - Shorten variables name 


    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

            iSouth  = i -   di
            jWest   = j -   dj

            i_East   = i +   dj
            j_North  = j +   di

            i_West   = i -   dj
            j_South  = j -   di


             
            Kbottom = KFloor_UV(i, j)

            !Momentum changes perpendicular to the velocity
            ! in boundary faces perpendicular also to the velocity
            !If the velocity is in the X direction the boundaries 
            ! compute are the West and the East ones
            !If the velocity is in the Y direction the boundaries 
            ! compute are the South and the North ones


cd0:        if (BoundaryFacesUV  (i, j     ) == Boundary .and.                           &
                ComputeFaces3D_UV(i, j, KUB) == Covered) then

        dok1:   do k = Kbottom, KUB

                    ![m^3/s*m/s]  = [m^3/s*m/s]
                    WaterFluxUp       = (dble(ComputeFaces3D_VU(i - di + dj, j - dj + di, k)) * &
                                         WaterFlux_YX          (i - di + dj, j - dj + di, k)  + &
                                         dble(ComputeFaces3D_VU(i_East     , j_North    , k)) * &
                                         WaterFlux_YX          (i_East     , j_North    , k)) 

                    if (WaterFluxUp > 0) then
                        
                        MomentumFluxUp = dble(Velocity_UV_Old  (i     , j      , k)) * WaterFluxUp

                    else

                        MomentumFluxUp = dble(Velocity_UV_Old  (i_East, j_North, k)) * WaterFluxUp

                    endif


                    WaterFluxDown     = (dble(ComputeFaces3D_VU(iSouth    , jWest     , k)) * &
                                         WaterFlux_YX          (iSouth    , jWest     , k)  + &
                                         dble(ComputeFaces3D_VU(i          , j          , k)) * &
                                         WaterFlux_YX          (i          , j          , k)) 


                    if (WaterFluxDown > 0) then
                        
                        MomentumFluxDown = dble(Velocity_UV_Old  (i_West, j_South, k)) * WaterFluxDown

                    else

                        MomentumFluxDown = dble(Velocity_UV_Old  (i     , j      , k)) * WaterFluxDown

                    endif

                    !The same tangential boundary condition assumed 
                    !for the velocity is assumed for the water flow 
                    if (Me%ComputeOptions%VelTangentialBoundary == NULL_VALUE) then 

                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k) - &
                                                         MomentumFluxUp    / 2.        + &
                                                         MomentumFluxDown  / 2.

                    else if (Me%ComputeOptions%VelTangentialBoundary == NULL_GRADIENT) then 
                        

                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k) - &
                                                         MomentumFluxUp        +         &
                                                         MomentumFluxDown 

                    endif


                enddo dok1

            endif cd0




        enddo doj
        enddo doi

        !Nullify auxiliar pointers
        nullify(WaterFlux_YX         )
        nullify(Horizontal_Transport )
        nullify(Velocity_UV_Old      )

        nullify(ComputeFaces3D_UV    )
        nullify(ComputeFaces3D_VU    )
        nullify(KFloor_UV            )

        nullify(BoundaryFacesUV      )
        nullify(BoundaryFacesVU      )

    End Subroutine Modify_UY_VX_Boundary

    
    !End ----------------------------------------------------------------------


    !------------------------------------------------------------------------------

    !------------------------------------------------------------------------------

    Subroutine Modify_UY_VX_SubModel  
      


        !Arguments------------------------------------------------------------
        


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport, WaterFlux_YX, Sub_qYX
        real,    dimension(:,:,:), pointer :: Velocity_UV_Old !,Sub_UV, Sub_VU
        real,    dimension(:,:  ), pointer :: DXX_YY

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV       , ComputeFaces3D_VU
        integer, dimension(:,:,:), pointer :: ImposedTangentialFacesUV, ImposedTangentialFacesVU 
        integer, dimension(:,:),   pointer :: BoundaryFacesUV, KFloor_UV

        real(8)                            :: MomentumFluxUp, MomentumFluxDown
        real(8)                            :: WaterFluxUp, WaterFluxDown
        real(8)                            :: WaterFluxImposed, WaterFluxComputed

        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest , i_East,                  &
                                              j_North

        integer                            :: j_South, i_West 


        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        WaterFlux_YX         => Me%WaterFluxes%YX
        Horizontal_Transport => Me%Forces%Horizontal_Transport
        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old

        Sub_qYX              => Me%SubModel%qYX

        ComputeFaces3D_UV        => Me%External_Var%ComputeFaces3D_UV
        ComputeFaces3D_VU        => Me%External_Var%ComputeFaces3D_VU

        ImposedTangentialFacesVU => Me%External_Var%ImposedTangentialFacesVU
        ImposedTangentialFacesUV => Me%External_Var%ImposedTangentialFacesUV
        KFloor_UV                => Me%External_Var%KFloor_UV

        DXX_YY                   => Me%External_Var%DXX_YY

        BoundaryFacesUV      => Me%External_Var%BoundaryFacesUV


        !End - Shorten variables name 


    doj: do j=JLB, JUB
    doi: do i=ILB, IUB

            iSouth  = i -   di
            jWest   = j -   dj

            i_East   = i +   dj
            j_North  = j +   di

            i_West   = i -   dj
            j_South  = j -   di
                

            !Momentum changes perpendicular to the velocity
            ! in boundary faces perpendicular also to the velocity
            !If the velocity is in the X direction the boundaries 
            ! compute are the West and the East ones
            !If the velocity is in the Y direction the boundaries 
            ! compute are the South and the North ones


cd0:        if (BoundaryFacesUV  (i, j     ) == Boundary .and.                           &
                ComputeFaces3D_UV(i, j, KUB) == Covered) then
                
                !East or North face
cd1:            if (ComputeFaces3D_UV       (i_East, j_North, KUB) == Covered   .or.     &         
                    ImposedTangentialFacesUV(i_East, j_North, KUB) == Imposed) then

                    Kbottom = max(KFloor_UV(i, j), KFloor_UV(i_East, j_North))

dok1:               do k = Kbottom, KUB

                        ![m^3/s]          = [m^2/s]*[m]
                        WaterFluxImposed  =  dble(ImposedTangentialFacesVU(i - di + dj, j - dj + di, k)) * &
                                                  Sub_qYX                 (i - di + dj, j - dj + di, k)  * &
                                             dble(DXX_YY                  (i - di + dj, j - dj + di   )) + &
                                             dble(ImposedTangentialFacesVU(i_East     , j_North    , k)) * &
                                                  Sub_qYX                 (i_East     , j_North    , k)  * &
                                             dble(DXX_YY                  (i_East     , j_North       ))
                        ![m^3/s]          = [m^3/s]
                        WaterFluxComputed =  dble(ComputeFaces3D_VU(i - di + dj, j - dj + di, k)) * &
                                                  WaterFlux_YX     (i - di + dj, j - dj + di, k)  + &
                                             dble(ComputeFaces3D_VU(i_East     , j_North    , k)) * &
                                                  WaterFlux_YX     (i_East     , j_North    , k) 




                        WaterFluxUp       =  (WaterFluxImposed + WaterFluxComputed) / 2.


cd2:                    if (WaterFluxUp > 0) then

                            MomentumFluxUp = WaterFluxUp * dble(Velocity_UV_Old  (i , j , k))

                        else  cd2
                        
                            MomentumFluxUp = WaterFluxUp * dble(Velocity_UV_Old  (i_East, j_North, k))

                        endif cd2

                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k) - &
                                                         MomentumFluxUp 

                    enddo dok1

                endif cd1


                !West or South face
cd3:            if (ComputeFaces3D_UV       (i_West, j_South, KUB) == Covered   .or.     &         
                    ImposedTangentialFacesUV(i_West, j_South, KUB) == Imposed) then

                    Kbottom = max(KFloor_UV(i, j), KFloor_UV(i_West, j_South))

dok2:               do k = Kbottom, KUB

                        ![m^3/s]         = [m^2/s]*[m]
                        WaterFluxImposed =  dble(ImposedTangentialFacesVU(iSouth    , jWest     , k)) * &
                                                 Sub_qYX                 (iSouth    , jWest     , k)  * &
                                            dble(DXX_YY                  (iSouth    , jWest        )) + &                                             
                                            dble(ImposedTangentialFacesVU(i          , j          , k)) * &
                                                 Sub_qYX                 (i          , j          , k)  * &                                             
                                            dble(DXX_YY                  (i          , j             ))


                        ![m^3/s]         = [m^2/s]*[m]
                        WaterFluxComputed=  dble(ComputeFaces3D_VU(iSouth    , jWest     , k)) * &
                                                 WaterFlux_YX     (iSouth    , jWest     , k)  + &
                                            dble(ComputeFaces3D_VU(i          , j          , k)) * &
                                                 WaterFlux_YX     (i          , j          , k)


                        WaterFluxDown    =  (WaterFluxImposed + WaterFluxComputed) / 2.


cd4:                    if (WaterFluxDown > 0) then

                            MomentumFluxDown = WaterFluxDown * dble(Velocity_UV_Old  (i_West, j_South, k))

                        else  cd4
                        
                            MomentumFluxDown = WaterFluxDown * dble(Velocity_UV_Old  (i , j , k))

                        endif cd4

                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k) + &
                                                         MomentumFluxDown 

                    enddo dok2

                endif cd3

            endif cd0

        enddo doi
        enddo doj

        !Nullify auxiliar pointers
        nullify(WaterFlux_YX         )
        nullify(Horizontal_Transport )
        nullify(Velocity_UV_Old      )

        nullify(Sub_qYX              )

        nullify(ComputeFaces3D_UV    )
        nullify(ComputeFaces3D_VU    )

        nullify(ImposedTangentialFacesUV)
        nullify(ImposedTangentialFacesVU)
        
        nullify(KFloor_UV            )

        nullify(BoundaryFacesUV      )

        nullify(DXX_YY               )

    End Subroutine Modify_UY_VX_SubModel

    
    !End ----------------------------------------------------------------------


    !------------------------------------------------------------------------------

    Subroutine AdvectionInSmallDepths  
      

        !Arguments------------------------------------------------------------

                                                

        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport
        real,    dimension(:,:  ), pointer :: WaterColumn, WaterColumnUV, DUX_VY

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV
         
        real                               :: FaceWaterColumn, Hmin_Advection
    
        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest

        integer                            :: IUB, ILB, JUB, JLB, KUB

        !Begin----------------------------------------------------------------


        !Shorten variables name 
        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV            => Me%External_Var%KFloor_UV

        !WaterColumn          => Me%External_Var%WaterColumn
        WaterColumnUV        => Me%External_Var%WaterColumnUV
        DUX_VY               => Me%External_Var%DUX_VY

        Horizontal_Transport => Me%Forces%Horizontal_Transport

        Hmin_Advection      =  Me%ComputeOptions%Hmin_Advection

        !End - Shorten variables name 


    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

            iSouth  = i -   di
            jWest   = j -   dj

            !FaceWaterColumn = (WaterColumn(i      , j     ) * DUX_VY(iSouth, jWest) +  &
            !                   WaterColumn(iSouth, jWest) * DUX_VY(i      , j     ))/  &
            !                  (DUX_VY     (iSouth, jWest) + DUX_VY(i      , j     ))  

            FaceWaterColumn = WaterColumnUV(i, j)

 !If the depth in a face is smaller than Hmin_Advection then advection is cancelled
cd0:        if (ComputeFaces3D_UV(i, j, KUB) == Covered .and.                            &
                FaceWaterColumn < Hmin_Advection) then


                Kbottom = KFloor_UV(i, j)

                !West or South Face
        dok1:   do k = Kbottom, KUB
                  
                    Horizontal_Transport(i, j, k) = 0.                    

                enddo dok1
                
            endif cd0

        enddo doj
        enddo doi

        nullify (WaterColumn         )
        nullify (DUX_VY              )

        !End ----------------------------------------------------------------------

    end Subroutine AdvectionInSmallDepths


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the horizontal diffusion with the same direction of the     !
    !  velocity. For the U velocity compute the diffusion with the X direction             !       
    !  for the V velocity compute the diffusion with the Y direction                       !
    !                                                                                      !
    ! Input : Flow, Geometry, Mapping                                                      !
    ! OutPut: Horizontal_Transport                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Modify_Diffusion_UX_VY ( Velocity_UV_Old, Biharmonic)           
     

        !Variables category 
        ! Geometry : Volume_Z, DUX_VY (Volume and length of the elevation control volume)
        ! Flow     : Visc_H_Center (Turbulent viscosity in the center of the elevation control volume), 
        !            Velocity_UV_Old (U or V velocity)
        ! Mapping  : KFloor_UV (first water layer for a i, j face), ComputeFaces3D_UV  (1 - covered faces, 0 - not covered faces) 
        ! Direction: Direction (DirectionX=1,DirectionY_=2)
        ! Dimension: ILB (i lower bound), IUB (i upper bound), JLB (j lower bound), JUB (j upper bound), KUB (k upper bound)

        !Variables direction dependent: 
        ! Horizontal_Transport, DUX_VY, Velocity_UV_Old, ComputeFaces3D_UV, Direction, Kfloor_UV


        !Arguments------------------------------------------------------------

        real,    dimension(:,:,:), pointer :: Velocity_UV_Old
        logical, intent (IN)               :: Biharmonic
                                            
        !Local-----------------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport, Volume_Z_New, Volume_UV
        real,    dimension(:,:,:), pointer :: Visc_H_Center
        real,    dimension(:,:),   pointer :: DUX_VY, DZX_ZY

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedNormalFacesUV
        integer, dimension(:,:),   pointer :: KFloor_UV

        logical                            :: ConservativeHorDif, ComputeFlux

        real                               :: FaceFlux_WestSouth1, FaceFlux_WestSouth2, Aux, ViscAux
    
        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest, i_North, j_East

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB
        !Begin-----------------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        ConservativeHorDif   =  Me%ComputeOptions%ConservativeHorDif

        Visc_H_Center        => Me%External_Var%Visc_H_Center
        
        Horizontal_Transport => Me%Forces%Horizontal_Transport

        ImposedNormalFacesUV => Me%External_Var%ImposedNormalFacesUV

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV            => Me%External_Var%KFloor_UV

        Volume_Z_New         => Me%External_Var%Volume_Z_New
        DUX_VY               => Me%External_Var%DUX_VY

        DZX_ZY               => Me%External_Var%DZX_ZY
        Volume_UV            => Me%External_Var%Volume_UV

        !End - Shorten variables name 

    doi: do j=JLB, JUB
    doj: do i=ILB, IUB


            iSouth  = i -   di
            jWest   = j -   dj
            i_North  = i +   di
            j_East   = j +   dj

            ComputeFlux = .false.

            if (Me%ComputeOptions%SlippingCondition) then

                if (ComputeFaces3D_UV(i      , j     , KUB) == Covered  .and.            &
                    ComputeFaces3D_UV(iSouth, jWest, KUB) == Covered )   ComputeFlux = .true. 

            else

                if (ComputeFaces3D_UV   (i      , j     , KUB) == Covered  .or.          &
                    ComputeFaces3D_UV   (iSouth, jWest, KUB) == Covered) ComputeFlux = .true. 

            endif

            !When the boundary is Cyclic the momentum diffusion flux is also compute for the boundary faces
            if (Me%CyclicBoundary%ON .and. (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                                            Me%CyclicBoundary%Direction == DirectionXY_))  then

                if ((ComputeFaces3D_UV   (i     , j     , KUB) == Covered .and.          &
                     ImposedNormalFacesUV(iSouth, jWest , KUB) == Imposed) .or.          &
                    (ComputeFaces3D_UV   (iSouth, jWest , KUB) == Covered .and.          &
                     ImposedNormalFacesUV(i     , j     , KUB) == Imposed))              &
                                                                           ComputeFlux = .true.

            endif


cd0:        if (ComputeFlux) then  

                Kbottom = max(KFloor_UV(i, j), KFloor_UV(iSouth, jWest)) 

dok1:           do k = Kbottom, KUB

                    if (BiHarmonic) then
            
                        ViscAux = Me%ComputeOptions%BiHarmonicCoef

                    else
                        
                        ViscAux = Visc_H_Center( iSouth, jWest, k)

                    endif
             
                    
cd1:                if (ConservativeHorDif) then 

                        ! West or South Face

                        ![m^3/s*m/s]       = [m^2/s] * [m/s] / [m] * [m^3] / [m]
                        FaceFlux_WestSouth1 = ViscAux                            *       & ! Turbulent viscosity
                                             (Velocity_UV_Old( i, j, k) -                &
                                             Velocity_UV_Old( iSouth, jWest, k)) /     &
                                             DUX_VY( iSouth, jWest) *                  & ! Velocity gradient
                                             Volume_Z_New( iSouth, jWest, k) /         &
                                             DUX_VY( iSouth, jWest)                    ! Face Area
                    
                        FaceFlux_WestSouth2 = FaceFlux_WestSouth1

                    else cd1
                        
                        ![m^2/s^2] = [m^2/s] * [m/s] / [m]
                        Aux                 = ViscAux                           *        & ! Turbulent viscosity
                                            (Velocity_UV_Old( i, j, k) -                 &
                                            Velocity_UV_Old( iSouth, jWest, k)) /      &
                                            DUX_VY( iSouth, jWest)                       ! Velocity gradient

                        !The velocity gradient plus the volume divided by the distance between 
                        !volume faces is equal to compute in a non-conservative way the lapalcian of the 
                        !velocity plus viscosity. The effect of the variable horizontal_transport in the velocity 
                        !is compute dividing the variable horizontal_Transport/VolumeU*DT = Visc * Laplacian(Velocity)
                        !

                        ![m^3/s*m/s]         = [m^2/s^2] * [m^3]/[m]
                        FaceFlux_WestSouth1 = Aux * Volume_UV(i      , j     , k) /      &
                                                    DZX_ZY   (i - di , j - dj)

                        ![m^3/s*m/s]         = [m^2/s^2] * [m^3]/[m]
                        FaceFlux_WestSouth2 = Aux * Volume_UV(iSouth, jWest, k) /      &
                                                    DZX_ZY   (iSouth - di , jWest - dj)

                    endif cd1

                    
                    Horizontal_Transport(i, j, k)            = Horizontal_Transport(i, j, k) &
                                                              - FaceFlux_WestSouth1  

                    Horizontal_Transport(iSouth, jWest, k) = Horizontal_Transport(iSouth, jWest, k) & 
                                                              + FaceFlux_WestSouth2  

                                                     
                 

                 enddo dok1
             endif cd0

        enddo doj
        enddo doi

        !Nullify auxiliar pointers
        nullify (Horizontal_Transport)
        nullify (Volume_Z_New        )
        nullify (Visc_H_Center       )
        nullify (DUX_VY              )
        nullify (DZX_ZY              )
        nullify (ComputeFaces3D_UV   )
        nullify (ImposedNormalFacesUV)
        nullify (KFloor_UV           )
        nullify (Volume_UV           )


    End Subroutine Modify_Diffusion_UX_VY

    
        !End ----------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the horizontal diffusion perpendicular to the               !
    !  velocity. For the U velocity compute the diffusion with the Y direction             !       
    !  for the V velocity compute the diffusion with the X direction                       !
    !                                                                                      !
    ! Input : Flow, Geometry, Mapping                                                      !
    ! OutPut: Horizontal_Transport                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Modify_Diffusion_UY_VX ( Velocity_UV_Old, Biharmonic)           


        !Variables categories 
        ! Geometry : Area_VU (area of the compute V or U compute points), DYY_XX (centered 
        !   width of the V or U control volume)
        !
        ! Flow     : Visc_H_Corner (Turbulent viscosity in the SW corner of the elevation 
        !   control volume), Velocity_UV_Old (U or V velocity)
        !
        ! Mapping  : KFloor_UV (first water layer for a i, j face), ComputeFaces3D_UV  
        !   (1 - covered faces, 0 - not covered faces) 
        !
        ! Direction: Direction (DirectionX=1,DirectionY_=2)
        !
        ! Dimension: ILB (i lower bound), IUB (i upper bound), JLB (j lower bound), JUB (j upper bound), 
        !            KUB (k upper bound)
        !
        !Variables direction dependent: 
        !DUX_DVY, Velocity_UV_Old, ComputeFaces3D_UV, Direction, Kfloor_UV

        !Arguments--------------------------------------------------------------------------

        real,    dimension(:,:,:), pointer :: Velocity_UV_Old 
        logical, intent (IN)               :: Biharmonic
        !Local-----------------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport, Volume_UV
        real,    dimension(:,:,:), pointer :: Area_VU
        real,    dimension(:,:),   pointer :: DYY_XX

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:,:), pointer :: ImposedTangentialFacesUV
        integer, dimension(:,:),   pointer :: KFloor_UV

        real                               :: FaceFlux_SouthWest1, FaceFlux_SouthWest2

        real                               :: Aux, ViscAux

        logical                            :: ConservativeHorDif, NoSlipFace,            &
                                              ComputeFlux, ComputeFlux1, ComputeFlux2
    
        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest, i_West, j_South

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !Begin-------------------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        ConservativeHorDif   =  Me%ComputeOptions%ConservativeHorDif
       
        Horizontal_Transport => Me%Forces%Horizontal_Transport

        ImposedTangentialFacesUV => Me%External_Var%ImposedTangentialFacesUV
        
        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV

        KFloor_UV            => Me%External_Var%KFloor_UV

        Volume_UV            => Me%External_Var%Volume_UV
        Area_VU              => Me%External_Var%Area_VU
        DYY_XX               => Me%External_Var%DYY_XX

        !End - Shorten variables name 


    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

            iSouth  = i - di
            jWest   = j - dj

            i_West   = i - dj
            j_South  = j - di

            ComputeFlux  = .false.
            ComputeFlux1 = .false.
            ComputeFlux2 = .false.

            if (Me%ComputeOptions%SlippingCondition) then

                if (ComputeFaces3D_UV(i     , j      , KUB) == Covered .and.             &
                    ComputeFaces3D_UV(i_West, j_South, KUB) == Covered) ComputeFlux = .true. 

            else

                if (ComputeFaces3D_UV        (i     , j      , KUB) == Covered .or.      &
                    ComputeFaces3D_UV        (i_West, j_South, KUB) == Covered) then
                    
                    ComputeFlux = .true. 
                    if (ComputeFaces3D_UV    (i     , j      , KUB) == Covered) ComputeFlux1 = .true.
                    if (ComputeFaces3D_UV    (i_West, j_South, KUB) == Covered) ComputeFlux2 = .true.

                endif

            endif

            !When the boundary is Cyclic the momentum diffusion flux is also compute for the boundary faces
            if (Me%CyclicBoundary%ON .and. (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                                            Me%CyclicBoundary%Direction == DirectionXY_))  then


                if ((ComputeFaces3D_UV       (i     , j       , KUB) == Covered .and.    &
                     ImposedTangentialFacesUV(i_West, j_South , KUB) == Imposed) .or.    &
                    (ComputeFaces3D_UV       (i_West, j_South , KUB) == Covered .and.    &
                     ImposedTangentialFacesUV(i     , j       , KUB) == Imposed)) then
                                         
                    ComputeFlux = .true.

                    ComputeFlux1 = .true.

                    ComputeFlux2 = .true.

                  endif

            endif
            
cd0:        if (ComputeFlux) then  


                Kbottom = max(KFloor_UV(i, j), KFloor_UV(i_West, j_South))

       dok1:    do k = Kbottom, KUB
                    

                   ! West or South Face

!cd1:                if (ComputeFaces3D_U(i-1,  j,  k) == Covered .and. &
!                        ComputeFaces3D_U(i,  j,  k) == Covered .and. &
!                        ComputeFaces3D_V(i,  j-1,k) == Covered .and. &
!                        ComputeFaces3D_V(i,  j,  k) == Covered) then

           
                        if (Biharmonic) then
                
                            ViscAux = Me%ComputeOptions%BiHarmonicCoef

                        else
                            
                            ViscAux = Me%External_Var%Visc_H_Corner(i, j, k)

                        endif

!                    else cd1

!                        ViscAux = 0.

!                    endif cd1

                    NoSlipFace = .false.

                    !Test if one of the faces is not covered
                    if (.not. Me%ComputeOptions%SlippingCondition)  then
                        
                        call DiffusionAlongNotCoveredFaces(Velocity_UV_Old,              &
                                                      ComputeFlux1,                      &
                                                      ComputeFlux2,                      &
                                                      DYY_XX, Volume_UV,                 &
                                                      FaceFlux_SouthWest1,               &
                                                      FaceFlux_SouthWest2,               &
                                                      NoSlipFace,                        &
                                                      ViscAux,                           &
                                                      i_West, j_South, i, j, k)

                    endif

cd3:                if (.not. NoSlipFace) then

cd2:                    if (ConservativeHorDif) then 

                            ![m^3/s*m/s]       = [m^2/s] * [m/s] / [m]  * [m^2] 
                            FaceFlux_SouthWest1 = ViscAux               *           & ! Turbulent viscosity
                                            (Velocity_UV_Old(i, j, k) -             &
                                             Velocity_UV_Old(i_West, j_South, k)) / &
                                            (DYY_XX(i_West, j_South) +              &
                                             DYY_XX( i, j)) *                       & ! half of the Velocity gradient
                                            (Area_VU(iSouth, jWest, k) +            &
                                             Area_VU(i     , j    , k))               ! double of the Face Area

                            FaceFlux_SouthWest2 = FaceFlux_SouthWest1

                        else cd2
                        
                   
                            ![m^2/s^2] = [m^2/s] * [m/s] / [m]
                            Aux = ViscAux                *                                   &  ! Turbulent viscosity
                                 (Velocity_UV_Old(i, j, k) -                                 &
                                  Velocity_UV_Old(i_West, j_South, k)) /                     &
                                 (DYY_XX(i_West, j_South) +                                  &
                                  DYY_XX( i, j)) * 2                        ! Velocity gradient

                            ![m^3/s*m/s]         = [m^2/s^2] * [m^3]/[m]
                            FaceFlux_SouthWest1 = Aux  *                                     &
                                                  Volume_UV   (i     , j, k) /               &  ! Area
                                                  DYY_XX      (i     , j   )
                        
                            ![m^3/s*m/s]         = [m^2/s^2] * [m^3]/[m]
                            FaceFlux_SouthWest2 = Aux  *                                     &
                                                  Volume_UV   (i_West, j_South, k) /         &
                                                  DYY_XX      (i_West, j_South)
                                                            
                        endif cd2

                    endif cd3


                    Horizontal_Transport(i, j, k)            = Horizontal_Transport(i, j, k) - &
                                                               FaceFlux_SouthWest1           * &
                                                               ComputeFaces3D_UV   (i, j, k)

                    Horizontal_Transport(i_West, j_South, k) = Horizontal_Transport(i_West, j_South, k) + &
                                                               FaceFlux_SouthWest2                      * &
                                                               ComputeFaces3D_UV   (i_West, j_South, k)


                enddo dok1

            endif cd0 

        enddo doj
        enddo doi


        !Nullify auxiliar pointers
        nullify (Horizontal_Transport)
        nullify (Area_VU)
        nullify (DYY_XX)
        nullify (ComputeFaces3D_UV)
        nullify (ImposedTangentialFacesUV)
        nullify (KFloor_UV)
        nullify (Volume_UV)


    End Subroutine Modify_Diffusion_UY_VX


    Subroutine DiffusionAlongNotCoveredFaces(Velocity_UV_Old, ComputeFlux1, ComputeFlux2,&
                                             DYY_XX, Volume_UV,                          &
                                             FaceFlux_SouthWest1,                        &
                                             FaceFlux_SouthWest2,                        &
                                             NoSlipFace,                                 &
                                             ViscAux,                                    &
                                             i_West, j_South, i, j, k)
            !Arguments--------------------------------------------------------------------------
        real,    dimension(:,:,:), pointer :: Velocity_UV_Old 
        real(8), dimension(:,:,:), pointer :: Volume_UV
        real,    dimension(:,:),   pointer :: DYY_XX
        logical, intent(IN )               :: ComputeFlux1, ComputeFlux2
        real,    intent(OUT)               :: FaceFlux_SouthWest1, FaceFlux_SouthWest2
        logical, intent(OUT)               :: NoSlipFace

        real                               :: ViscAux

        integer                            :: i, j, k

        integer                            :: i_West, j_South

        !Begin-------------------------------------------------------------------------------


        ! i,j,k not covered face
        if (.not. ComputeFlux1) then

            FaceFlux_SouthWest1 = 0.
            ![m^3/s*m/s]         = [m2/s] * [m/s] / [m] * [m^3]/[m]
            FaceFlux_SouthWest2 = - ViscAux * Velocity_UV_Old(i_West, j_South, k) /      &
                                    DYY_XX      (i_West, j_South)    / 2.         *      &
                                    Volume_UV   (i_West, j_South, k) /                   &
                                    DYY_XX      (i_West, j_South)

            NoSlipFace = .true.
 
        endif  

        ! i_West, j_South, k not covered face
        if (.not. ComputeFlux2) then

            ![m^3/s*m/s]         = [m2/s] * [m/s] / [m] * [m^3]/[m]
            FaceFlux_SouthWest1 =   ViscAux * Velocity_UV_Old(i, j, k)  /                &
                                    DYY_XX      (i, j) / 2. *                            &
                                    Volume_UV   (i, j, k)   /                            &
                                    DYY_XX      (i, j)
            FaceFlux_SouthWest2 = 0.

            NoSlipFace = .true.

        endif  

    end Subroutine DiffusionAlongNotCoveredFaces


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the horizontal diffusion with the same direction of the     !
    !  velocity. For the U velocity compute the diffusion with the X direction             !       
    !  for the V velocity compute the diffusion with the Y direction                       !
    !                                                                                      !
    ! Input : Flow, Geometry, Mapping                                                      !
    ! OutPut: Horizontal_Transport                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine ModifyDiffSub_UX_VY ( Velocity_UV_Old, Biharmonic)           
     

        !Variables category 
        ! Geometry : Volume_Z, DUX_VY (Volume and length of the elevation control volume)
        ! Flow     : Visc_H_Center (Turbulent viscosity in the center of the elevation control volume), 
        !            Velocity_UV_Old (U or V velocity)
        ! Mapping  : KFloor_UV (first water layer for a i, j face), ComputeFaces3D_UV  (1 - covered faces, 0 - not covered faces) 
        ! Direction: Direction (DirectionX=1,DirectionY_=2)
        ! Dimension: ILB (i lower bound), IUB (i upper bound), JLB (j lower bound), JUB (j upper bound), KUB (k upper bound)

        !Variables direction dependent: 
        ! Horizontal_Transport, DUX_VY, Velocity_UV_Old, ComputeFaces3D_UV, Direction, Kfloor_UV


        !Arguments------------------------------------------------------------

        real,    dimension(:,:,:), pointer :: Velocity_UV_Old
        logical, intent (IN)               :: Biharmonic
                                           
        !Local-----------------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport, Volume_Z_New, Volume_UV
        real,    dimension(:,:,:), pointer :: Visc_H_Center
        real,    dimension(:,:),   pointer :: DUX_VY, DZX_ZY

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedNormalFacesUV
        integer, dimension(:,:),   pointer :: KFloor_UV

        logical                            :: ConservativeHorDif

        real                               :: FaceFlux_WestSouth, FaceFlux_EastNorth, Aux, ViscAux
    
        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest, i_North, j_East

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB
        !Begin-----------------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        ConservativeHorDif   =  Me%ComputeOptions%ConservativeHorDif

        Visc_H_Center        => Me%External_Var%Visc_H_Center
        
        Horizontal_Transport => Me%Forces%Horizontal_Transport

        ComputeFaces3D_UV      => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV              => Me%External_Var%KFloor_UV
        ImposedNormalFacesUV   => Me%External_Var%ImposedNormalFacesUV

        Volume_Z_New         => Me%External_Var%Volume_Z_New
        DUX_VY               => Me%External_Var%DUX_VY

        DZX_ZY               => Me%External_Var%DZX_ZY
        Volume_UV            => Me%External_Var%Volume_UV

        !End - Shorten variables name 

    doi: do j=JLB, JUB
    doj: do i=ILB, IUB


            iSouth  = i -   di
            jWest   = j -   dj
            i_North  = i +   di
            j_East   = j +   dj


cd0:        if (ComputeFaces3D_UV(i, j, KUB)  == Covered) then 

                   
cd1:            if (ImposedNormalFacesUV(iSouth, jWest, KUB) == Imposed) then

                    Kbottom = KFloor_UV(i, j)
                    
dok1:               do k = Kbottom, KUB

cd2:                    if (BiHarmonic) then
            
                            ViscAux = Me%ComputeOptions%BiHarmonicCoef

                        else  cd2
                        
                            ViscAux = Visc_H_Center( iSouth, jWest, k)

                        endif cd2
             
                    
cd3:                    if (ConservativeHorDif) then 

                            ! West or South Face

                            ![m^3/s*m/s]       = [m^2/s] * [m/s] / [m] * [m^3] / [m]
                            FaceFlux_WestSouth  = ViscAux                            *   & ! Turbulent viscosity
                                                 (Velocity_UV_Old( i, j, k) -            &
                                                 Velocity_UV_Old( iSouth, jWest, k)) / &
                                                 DUX_VY( iSouth, jWest) *              & ! Velocity gradient
                                                 Volume_Z_New( iSouth, jWest, k) /     &
                                                 DUX_VY( iSouth, jWest)                    ! Face Area
                    

                        else cd3
                        
                            ![m^2/s^2] = [m^2/s] * [m/s] / [m]
                            Aux                 = ViscAux                           *    & ! Turbulent viscosity
                                                (Velocity_UV_Old( i, j, k) -             &
                                                Velocity_UV_Old( iSouth, jWest, k)) /  &
                                                DUX_VY( iSouth, jWest)                       ! Velocity gradient

                            !The velocity gradient plus the volume divided by the distance between 
                            !volume faces is equal to compute in a non-conservative way the lapalcian of the 
                            !velocity plus viscosity. The effect of the variable horizontal_transport in the velocity 
                            !is compute dividing the variable horizontal_Transport/VolumeU*DT = Visc * Laplacian(Velocity)
                            !

                            ![m^3/s*m/s]         = [m^2/s^2] * [m^3]/[m]
                            FaceFlux_WestSouth  = Aux * Volume_UV(i      , j     , k) /  &
                                                        DZX_ZY   (iSouth, jWest)

                        endif cd3

                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k)   &
                                                       - FaceFlux_WestSouth  
                    enddo dok1

                endif cd1



cd4:            if (ImposedNormalFacesUV(i_North, j_East, KUB) == Imposed) then

                    Kbottom = KFloor_UV(i, j)
                    
dok2:               do k = Kbottom, KUB


cd5:                    if (BiHarmonic) then
            
                            ViscAux = Me%ComputeOptions%BiHarmonicCoef

                        else cd5
                        
                            ViscAux = Visc_H_Center(i, j, k)

                        endif cd5
             
                    
cd6:                    if (ConservativeHorDif) then 

                            ! West or South Face

                            ![m^3/s*m/s]       = [m^2/s] * [m/s] / [m] * [m^3] / [m]
                            FaceFlux_EastNorth  = ViscAux                             *  & ! Turbulent viscosity
                                                 (Velocity_UV_Old(i_North, j_East, k) -  &
                                                 Velocity_UV_Old( i      , j     , k))/  &
                                                 DUX_VY( i, j)                        *  & ! Velocity gradient
                                                 Volume_Z_New( i, j, k) /  DUX_VY( i, j)   ! Face Area
                    

                        else cd6
                        
                            ![m^2/s^2] = [m^2/s] * [m/s] / [m]
                            Aux                 = ViscAux                            *   & ! Turbulent viscosity
                                                 (Velocity_UV_Old(i_North, j_East, k)-   &
                                                  Velocity_UV_Old( i, j, k))         /   & ! Velocity gradient
                                                  DUX_VY(  i, j)                             

                            !The velocity gradient plus the volume divided by the distance between 
                            !volume faces is equal to compute in a non-conservative way the lapalcian of the 
                            !velocity plus viscosity. The effect of the variable horizontal_transport in the velocity 
                            !is compute dividing the variable horizontal_Transport/VolumeU*DT = Visc * Laplacian(Velocity)
                            !

                            ![m^3/s*m/s]        = [m^2/s^2] * [m^3]/[m]
                            FaceFlux_EastNorth  = Aux * Volume_UV(i      , j     , k) /  &
                                                        DZX_ZY   (iSouth, jWest)

                        endif cd6


                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k)   &
                                                       + FaceFlux_EastNorth  
                 
                    enddo dok2

                 endif cd4
               

             endif cd0

        enddo doj
        enddo doi

        !Nullify auxiliar pointers
        nullify (Horizontal_Transport)
        nullify (Volume_Z_New        )
        nullify (Visc_H_Center       )
        nullify (DUX_VY              )
        nullify (DZX_ZY              )
        nullify (ComputeFaces3D_UV   )
        nullify (ImposedNormalFacesUV)
        nullify (KFloor_UV           )
        nullify (Volume_UV           )


    End Subroutine ModifyDiffSub_UX_VY

    
        !End ----------------------------------------------------------------------

    Subroutine ModifyDiffSub_UY_VX ( Velocity_UV_Old, Biharmonic)           


        !Arguments--------------------------------------------------------------------------

        real,    dimension(:,:,:), pointer :: Velocity_UV_Old 
        logical, intent (IN)               :: Biharmonic


        !Local-----------------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport, Volume_UV
        real,    dimension(:,:,:), pointer :: Area_VU
        real,    dimension(:,:),   pointer :: DYY_XX

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ComputeFaces3D_U, ComputeFaces3D_V
        integer, dimension(:,:,:), pointer :: ImposedTangentialFacesUV
        integer, dimension(:,:),   pointer :: KFloor_UV

        real                               :: FaceFlux_SouthWest, FaceFlux_NorthEast

        real                               :: Aux, ViscAux

        logical                            :: ConservativeHorDif
    
        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest, i_West, j_South

        integer                            :: i_North, j_East, i_East, j_North

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !Begin-------------------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        ConservativeHorDif   =  Me%ComputeOptions%ConservativeHorDif
       
        Horizontal_Transport => Me%Forces%Horizontal_Transport
        
        ComputeFaces3D_U         => Me%External_Var%ComputeFaces3D_U
        ComputeFaces3D_V         => Me%External_Var%ComputeFaces3D_V
        ComputeFaces3D_UV        => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV                => Me%External_Var%KFloor_UV
        ImposedTangentialFacesUV => Me%External_Var%ImposedTangentialFacesUV

        Volume_UV            => Me%External_Var%Volume_UV
        Area_VU              => Me%External_Var%Area_VU
        DYY_XX               => Me%External_Var%DYY_XX

        !End - Shorten variables name 


    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

            iSouth  = i - di
            jWest   = j - dj

            i_West   = i - dj
            j_South  = j - di

            i_North  = i + di
            j_East   = j + dj

            i_East   = i + dj
            j_North  = j + di


cd0:        if (ComputeFaces3D_UV(i, j, KUB) == Covered) then 

cd1:            if (ImposedTangentialFacesUV(i_West, j_South, KUB) == Imposed) then

                    Kbottom = max(KFloor_UV(i, j), KFloor_UV(i_West, j_South))

           dok1:    do k = Kbottom, KUB
                    

                       ! West or South Face


cd2:                    if (BiHarmonic) then
                    
                            ViscAux = Me%ComputeOptions%BiHarmonicCoef

                        else cd2
                    
                            ViscAux = Me%External_Var%Visc_H_Corner(i, j, k)

                        endif cd2
                        
                                        
cd3:                    if (ConservativeHorDif) then 

                            ![m^3/s*m/s]       = [m^2/s] * [m/s] / [m]  * [m^2] 
                            FaceFlux_SouthWest = ViscAux               *                 & ! Turbulent viscosity
                                            (Velocity_UV_Old(i, j, k) -                  &
                                             Velocity_UV_Old(i_West, j_South, k)) /      &
                                            (DYY_XX(i_West, j_South) +                   &
                                             DYY_XX( i, j)) *                            & ! half of the Velocity gradient
                                            (Area_VU(iSouth, jWest, k) +               &
                                             Area_VU(i      , j     , k))             ! double of the Face Area


                        else cd3
                    
               
                            ![m^2/s^2] = [m^2/s] * [m/s] / [m]
                            Aux = ViscAux                *                               &  ! Turbulent viscosity
                                 (Velocity_UV_Old(i, j, k) -                             &
                                  Velocity_UV_Old(i_West, j_South, k)) /                 &
                                 (DYY_XX(i_West, j_South) +                              &
                                  DYY_XX( i, j)) * 2                        ! Velocity gradient

                            ![m^3/s*m/s]         = [m^2/s^2] * [m^3]/[m]
                            FaceFlux_SouthWest  = Aux  *                                 &
                                                  Volume_UV   (i     , j, k) /           &  ! Area
                                                  DYY_XX      (i     , j   )
                              
                        endif cd3


                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k)   &
                                                       - FaceFlux_SouthWest

                    enddo dok1

                endif cd1


cd4:            if (ImposedTangentialFacesUV(i_East, j_North, KUB) == Imposed) then

                    Kbottom = max(KFloor_UV(i, j), KFloor_UV(i_East, j_North))

           dok2:    do k = Kbottom, KUB
                    

                       ! East or North Face


cd5:                    if (BiHarmonic) then
                    
                            ViscAux = Me%ComputeOptions%BiHarmonicCoef

                        else cd5
                    
                            ViscAux = Me%External_Var%Visc_H_Corner(i_East, j_North, k)

                        endif cd5
                        
                                        
cd6:                    if (ConservativeHorDif) then 

                            ![m^3/s*m/s]       = [m^2/s] * [m/s] / [m]  * [m^2] 
                            FaceFlux_NorthEast = ViscAux               *            & ! Turbulent viscosity
                                            (Velocity_UV_Old(i_East, j_North, k) -             &
                                             Velocity_UV_Old(i, j, k)) / &
                                            (DYY_XX(i_East, j_North) +              &
                                             DYY_XX( i, j)) *                       & ! half of the Velocity gradient
                                            (Area_VU(i_East     , j_North    , k) + &
                                             Area_VU(i - di + dj, j - dj + di, k))                        ! double of the Face Area


                        else cd6
                    
               
                            ![m^2/s^2] = [m^2/s] * [m/s] / [m]
                            Aux = ViscAux                *                                   &  ! Turbulent viscosity
                                 (Velocity_UV_Old(i_East, j_North, k) -                                 &
                                  Velocity_UV_Old(i     , j      , k)) /                     &
                                 (DYY_XX(i_East, j_North) +                                  &
                                  DYY_XX( i, j)) * 2                        ! Velocity gradient

                            ![m^3/s*m/s]         = [m^2/s^2] * [m^3]/[m]
                            FaceFlux_NorthEast  = Aux  *                                     &
                                                  Volume_UV   (i     , j, k) /               &  ! Area
                                                  DYY_XX      (i     , j   )
                    
                        endif cd6


                        Horizontal_Transport(i, j, k)  = Horizontal_Transport(i, j, k)       &
                                                       + FaceFlux_NorthEast

                    enddo dok2

                endif cd4


            endif cd0 

        enddo doj
        enddo doi


        !Nullify auxiliar pointers
        nullify (Horizontal_Transport)
        nullify (Area_VU)
        nullify (DYY_XX)
        nullify (ComputeFaces3D_UV)
        nullify (ComputeFaces3D_U)
        nullify (ComputeFaces3D_V)
        nullify (KFloor_UV)
        nullify (ImposedTangentialFacesUV)
        nullify (Volume_UV)


    End Subroutine ModifyDiffSub_UY_VX

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the Laplacian                                               !
    !                                                                                      !
    ! Input : Flow, Geometry, Mapping                                                      !
    ! OutPut: Horizontal_Transport                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine LaplacianXY( Velocity_UV_Old, Aux_UX_VY) 
     

        !Arguments------------------------------------------------------------

        real,    dimension(:,:,:), pointer :: Velocity_UV_Old, Aux_UX_VY
                                            
        !Local-----------------------------------------------------------------------------
        real,    dimension(:,:),   pointer :: DUX_VY, DZX_ZY

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV

        real                               :: Aux1, Aux2
    
        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest, i_North, j_East

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB
        !Begin-----------------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV             => Me%External_Var%KFloor_UV

        DUX_VY               => Me%External_Var%DUX_VY

        DZX_ZY               => Me%External_Var%DZX_ZY

        !End - Shorten variables name 

    doi: do j=JLB, JUB
    doj: do i=ILB, IUB


            iSouth  = i -   di
            jWest   = j -   dj
            i_North  = i +   di
            j_East   = j +   dj


cd0:        if (ComputeFaces3D_UV(i, j, KUB)            == Covered ) then 

                Kbottom = KFloor_UV(i, j)

dok1:           do k = Kbottom, KUB
             
                    
                    ! West or South Face
                    if (ComputeFaces3D_UV(iSouth, jWest, k) == Covered ) then
                        ![s^-1] = [m/s] / [m]
                        Aux1 =(Velocity_UV_Old( i      , j     , k) -                        &
                               Velocity_UV_Old( iSouth, jWest, k)) /                       &
                               DUX_VY( iSouth, jWest)                   
                    else

                        Aux1 = 0

                    endif 
                

                    ! East or North Face
                    if (ComputeFaces3D_UV(i_North, j_East, k) == Covered ) then

                        Aux2 =(Velocity_UV_Old( i_North, j_East, k) -                    &
                               Velocity_UV_Old( i      , j     , k)) /                   &
                               DUX_VY( i, j)                   

                    else

                        Aux2 = 0.

                    endif

                    Aux_UX_VY(i, j, k) = - (Aux2 - Aux1) / DZX_ZY( iSouth, jWest)

                 enddo dok1

             endif cd0

        enddo doj
        enddo doi

        !Nullify auxiliar pointers
        nullify (DUX_VY              )
        nullify (DZX_ZY              )
        nullify (ComputeFaces3D_UV   )
        nullify (KFloor_UV           )


    End Subroutine LaplacianXY

    
        !End ----------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the horizontal diffusion perpendicular to the               !
    !  velocity. For the U velocity compute the diffusion with the Y direction             !       
    !  for the V velocity compute the diffusion with the X direction                       !
    !                                                                                      !
    ! Input : Flow, Geometry, Mapping                                                      !
    ! OutPut: Horizontal_Transport                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine LaplacianYX ( Velocity_UV_Old, Aux_UY_VX) 
     

        !Arguments------------------------------------------------------------

        real,    dimension(:,:,:), pointer :: Velocity_UV_Old, Aux_UY_VX
                                            

        !Local-----------------------------------------------------------------------------
        real,    dimension(:,:),   pointer :: DYY_XX

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV

        real                               :: Aux1, Aux2

        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: i_West, j_South, i_East, j_North

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !Begin-------------------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj


        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV            => Me%External_Var%KFloor_UV

        DYY_XX               => Me%External_Var%DYY_XX

        !End - Shorten variables name 


    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

            i_West   = i - dj
            i_East   = i + dj

            j_South  = j - di
            j_North  = j + di

cd0:        if (ComputeFaces3D_UV(i, j, KUB) == Covered) then

                Kbottom = KFloor_UV(i, j)
                    

       dok1:        do k = Kbottom, KUB
                    
                        
                        ! West or South Face
                        if (ComputeFaces3D_UV(i_West, j_South, k) == Covered) then 

                            ![s^-1] = [m/s] / [m]
                            Aux1 =(Velocity_UV_Old( i      , j     , k) -                &
                                   Velocity_UV_Old( i_West , j_South, k))* 2 /           &
                                   (DYY_XX(i_West, j_South) +  DYY_XX( i, j))     

                        else

                            Aux1 = 0.

                        endif

                        ! East or North Face
                        if (ComputeFaces3D_UV(i_East, j_North, k) == Covered) then 
                
                            Aux2 =(Velocity_UV_Old( i_East, j_North, k) -                &
                                   Velocity_UV_Old( i      , j     , k)) * 2 /           &
                                   (DYY_XX(i_East, j_North) +  DYY_XX( i, j))

                        else

                            Aux2 = 0

                        endif

                        Aux_UY_VX(i, j, k) = - (Aux2 - Aux1) / DYY_XX( i, j)

                            
                    enddo dok1
                    

            endif cd0 

        enddo doj
        enddo doi


        !Nullify auxiliar pointers
        nullify (DYY_XX)
        nullify (ComputeFaces3D_UV)
        nullify (KFloor_UV)


    End Subroutine LaplacianYX


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the effect of volume variation in the velocity time         !
    !  variation.                                                                          !
    !                                                                                      !
    ! Input : Flow, Mapping,                                                               !
    ! OutPut: Horizontal_Transport                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine ModifyVolumeVariation  
      

        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport, Volume_Z_Old, Volume_UV
        real,    dimension(:,:,:), pointer :: Velocity_UV_Old 

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV

        real(8)                            :: VolumeVariation, VolumeUVOld

        real                               :: DT_Velocity

        integer                            :: i, j, k, Kbottom, di, dj, iSouth, jWest

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        DT_Velocity = Me%Velocity%DT

        Horizontal_Transport => Me%Forces%Horizontal_Transport
        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old

        Volume_Z_Old         => Me%External_Var%Volume_Z_Old
        Volume_UV            => Me%External_Var%Volume_UV

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV            => Me%External_Var%KFloor_UV


        !End - Shorten variables name 


    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

    cd1:    if (ComputeFaces3D_UV(i, j, KUB) == Covered) then 

                iSouth  = i - di
                jWest   = j - dj

                Kbottom = KFloor_UV(i, j)

        dok1:   do k = Kbottom, KUB

                    VolumeUVOld                   = (Volume_Z_Old(iSouth, jWest, k)  + &
                                                     Volume_Z_Old(i, j, k) ) / 2. 

                    ![m/s*m^3/s]                  = [m^3] * [m/s] / [s] 
                    VolumeVariation               = (VolumeUVOld - Volume_UV(i, j, k)) * & 
                                                    dble(Velocity_UV_Old(i, j, k))     / &
                                                    dble(DT_Velocity)

                    Horizontal_Transport(i, j, k) = Horizontal_Transport(i, j, k)      + &
                                                    VolumeVariation                       

                enddo dok1

            endif cd1

        enddo doj
        enddo doi

        !Nullify auxiliar pointers
        nullify (Horizontal_Transport)
        nullify (Volume_UV)
        nullify (Volume_Z_Old)
        nullify (Velocity_UV_Old)
        nullify (ComputeFaces3D_UV)
        nullify (KFloor_UV)

    End Subroutine ModifyVolumeVariation

    
    !End ----------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the effect of momentum discharges in the velocity time      !
    !  variation.                                                                          !
    !                                                                                      !
    ! Input : Flow, Mapping,                                                               !
    ! OutPut: Horizontal_Transport                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine ModifyMomentumDischarge 
      

        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport
        real,    dimension(:,:,:), pointer :: Velocity_UV_Old, DUZ_VZ
        real,    dimension(:,:  ), pointer :: Bathymetry, WaterColumnUV
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:  ), pointer :: KFloor_UV

        real(8)                            :: MomentumDischarge
        real                               :: DischargeFlow, DischargeVelocity, AuxFlow

        integer                            :: DirectionXY, DischargesNumber, DischargeID
        integer                            :: i, j, k, kd, kmin, kmax, di, dj, STAT_CALL, iNorth, jEast, KUB

        logical                            :: DischargeUniform
        
        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        DirectionXY = Me%Direction%XY
        KUB         = Me%WorkSize%KUB

        Horizontal_Transport => Me%Forces%Horizontal_Transport
        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old
        KFloor_UV            => Me%External_Var%KFloor_UV
        WaterColumnUV        => Me%External_Var%WaterColumnUV 
        DUZ_VZ               => Me%External_Var%DUZ_VZ



        !End - Shorten variables name 
        call GetDischargesNumber(Me%ObjDischarges, DischargesNumber, STAT = STAT_CALL)
        if (STAT_CALL/=SUCCESS_)stop 'Sub. ModifyMomentumDischarge - ModuleHydrodynamic - ERR01'
             

        !Gets a pointer to Bathymetry
        call GetGridData(Me%ObjGridData, Bathymetry, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ModifyMomentumDischarge - ModuleHydrodynamic - ERR02'

do1:    do DischargeID = 1, DischargesNumber

            call GetDischargesGridLocalization(Me%ObjDischarges,                        &
                 DischargeID, Igrid=I, JGrid=J, KGrid=kd,                               &
                 DischargeUniform = DischargeUniform,                                   &
                 WaterColumnZ = Me%External_Var%Watercolumn,                            &
                 Batimetry    = Bathymetry,                                             &
                 OpenPoints3D   = Me%External_Var%OpenPoints3D,                         &
                 STAT = STAT_CALL)   

            if (STAT_CALL/=SUCCESS_)                                                    &
                 stop 'Sub. ModifyMomentumDischarge - ModuleHydrodynamic - ERR03'

            call GetDischargeWaterFlow(Me%ObjDischarges,                    &
                                       Me%CurrentTime, DischargeID,         &
                                       Me%WaterLevel%Old(I, J),             &
                                       DischargeFlow, STAT = STAT_CALL)             

            if (STAT_CALL/=SUCCESS_)                                                    &
                 stop 'Sub. ModifyMomentumDischarge - ModuleHydrodynamic - ERR04'

            if (DirectionXY == DirectionX_) then
                
                call GetDischargeFlowVelocity(Me%ObjDischarges,                 &
                                           Me%CurrentTime, DischargeID,         &
                                           VelocityU = DischargeVelocity, STAT = STAT_CALL)             

                if (STAT_CALL/=SUCCESS_)                                                &
                    stop 'Sub. ModifyMomentumDischarge - ModuleHydrodynamic - ERR05'

            else if (DirectionXY == DirectionY_) then


                call GetDischargeFlowVelocity(Me%ObjDischarges,                 &
                                           Me%CurrentTime, DischargeID,         &
                                           VelocityV = DischargeVelocity, STAT = STAT_CALL)             

                if (STAT_CALL/=SUCCESS_)                                                     &
                    stop 'Sub. ModifyMomentumDischarge - ModuleHydrodynamic - ERR06'

            endif

            di  = Me%Direction%di
            dj  = Me%Direction%dj

            iNorth = i+di
            jEast =  j+dj

            if (DischargeUniform) then

                if      (ComputeFaces3D_UV(i     , j    , KUB) == Covered) then
                    kmin = KFloor_UV(i     , j    )
                else if (ComputeFaces3D_UV(iNorth, jEast, KUB) == Covered) then
                    kmin = KFloor_UV(iNorth, jEast)
                endif

                kmax = KUB

            else
            
                kmin = kd; kmax = kd

            endif

            MomentumDischarge = 0.


dk:         do k = kmin,kmax

                AuxFlow = DischargeFlow

                if (ComputeFaces3D_UV(i, j, k) == Covered) then

                    if (DischargeUniform) AuxFlow = DUZ_VZ(i,j,k) / WaterColumnUV(i,j) * DischargeFlow

                    ![m/s*m^3/s]                  = [m^3] * [m/s] / [s] 
                    if (DischargeFlow > 0.) then
            
                        MomentumDischarge  = AuxFlow * DischargeVelocity

                    else

                        MomentumDischarge  = AuxFlow * Velocity_UV_Old(i, j, k)
            
                    endif 


                    Horizontal_Transport(i     , j    , k) =                                 &
                        Horizontal_Transport(i     , j    , k)   +   MomentumDischarge                       

                else if (ComputeFaces3D_UV(iNorth, jEast, k) == Covered) then

                    if (DischargeUniform) AuxFlow = DUZ_VZ(iNorth, jEast,k) / WaterColumnUV(iNorth, jEast) * DischargeFlow

                    ![m/s*m^3/s]                  = [m^3] * [m/s] / [s] 
                    if (DischargeFlow > 0.) then
            
                        MomentumDischarge  = AuxFlow * DischargeVelocity

                    else

                        MomentumDischarge  = AuxFlow * Velocity_UV_Old(iNorth, jEast, k)
            
                    endif 

                    Horizontal_Transport(iNorth, jEast, k) =                                 &
                        Horizontal_Transport(iNorth, jEast, k)   +   MomentumDischarge                       

                else if (abs(MomentumDischarge) > AllmostZero) then

                    write(*,*) 'WARNING_ - The Model is trying to discharge Momentum in a No Compute Face'
                    write(*,*) 'WARNING_ - ModifyMomentumDischarge - ModuleHydrodynamic - WARN01'
                endif 

            enddo dk

        enddo do1

        !Nullify auxiliar pointers
        nullify (Horizontal_Transport)
        nullify (ComputeFaces3D_UV   )
        nullify (Velocity_UV_Old     )
        nullify (KFloor_UV           )
        nullify (WaterColumnUV       )
        nullify (DUZ_VZ              )


        !Disposes pointer to the Bathymetry
        call UngetGridData(Me%ObjGridData, Bathymetry, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'ModifyMomentumDischarge - ModuleHydrodynamic - ERR07'


    End Subroutine ModifyMomentumDischarge

    
    !End ----------------------------------------------------------------------


  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the horizontal advection implicit with the same            !
    !  direction of the velocity. For the U velocity compute the advection with           !       
    !  the X direction for the V velocity compute the advection with the Y direction      !
    !                                                                                      !
    ! Input : Flow, Mapping,                                                               !
    ! OutPut: Horizontal_Transport                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Modify_Implicit_UX_VY  
      

        !Variables Categories----------------------------------------------------------------
        ! Flow     : WaterFlux_XY (Horizontal water fluxes), Velocity_UV_Old (U or V velocity)
        ! Mapping  : KFloor_UV (first water layer for a i, j face), ComputeFaces3D_UV  (1 - covered faces, 0 - not covered faces) 
        ! Options  : UpStream_CenterDif (1-Upwind and 0-Centered differences),ImplicitVertAdvection (1 - implict, 0 - explicit)
        ! Direction: Direction (DirectionX_=1,DirectionY_=2)
        ! Dimension: ILB (i lower bound), IUB (i upper bound), JLB (j lower bound), JUB (j upper bound), KUB (k upper bound)
        ! OutPut   : Horizontal_Transport 

        !Variables direction dependent: 
        !Velocity_UV_Old, WaterFlux_XY, Horizontal_Transport, ComputeFaces3D_UV, Direction, KFloor_UV


        !Arguments------------------------------------------------------------
         


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: ECoef_3D
        real,    dimension(:,:,:), pointer :: DCoef_3D, FCoef_3D

        real,    dimension(:,:,:), pointer :: Velocity_UV_Old 
        real(8), dimension(:,:,:), pointer :: WaterFlux_XY, Volume_UV, Horizontal_Transport

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV
         
        real                               :: UpStream_CenterDif, Aux, DT_Velocity

        real                               :: Coef1_Up, Coef2_Up, Coef3_Up, Coef_Centered

        real                               :: Cell_1, Cell_2, Cell_3, Cell_4

        real(8)                            :: FaceFlux_WestSouth, DTAux1, DTAux2, MomentumFlux

        real                               :: Coef1_WestSouth, Coef2_WestSouth, Coef3_WestSouth, Coef4_WestSouth
 
        real                               :: Cell1_FaceWestSouth, Cell2_FaceWestSouth, Cell3_FaceWestSouth, Cell4_FaceWestSouth
   
        integer                            :: di, dj, i, j, k, Kbottom

        integer                            :: iSouth, jWest, i_North, j_East, iSouth2, &
                                              jWest2

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !Begin----------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        UpStream_CenterDif   =  Me%ComputeOptions%UpStream_CenterDif

        DT_Velocity = Me%Velocity%DT

        Coef1_Up             =  Me%HorAdvection%Coef1_Up
        Coef2_Up             =  Me%HorAdvection%Coef2_Up
        Coef3_Up             =  Me%HorAdvection%Coef3_Up

        WaterFlux_XY         => Me%WaterFluxes%XY

        Horizontal_Transport => Me%Forces%Horizontal_Transport

        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV            => Me%External_Var%KFloor_UV

        DCoef_3D             => Me%Coef%D3%D
        ECoef_3D             => Me%Coef%D3%E
        FCoef_3D             => Me%Coef%D3%F

        Volume_UV            => Me%External_Var%Volume_UV


        !End - Shorten variables name 

        !Centered difference coefficient equal for both faces (West/South = East/North)
        Coef_Centered = 0.5

    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

            iSouth  = i -   di
            jWest   = j -   dj
            i_North  = i +   di
            j_East   = j +   dj
            iSouth2 = i - 2*di
            jWest2  = j - 2*dj

 !This condition impose in the open boundary gradient null for the horizontal advection 
cd0:        if (ComputeFaces3D_UV(i, j, KUB)            == Covered .and. &
                ComputeFaces3D_UV(iSouth, jWest, KUB) == Covered) then


                Kbottom = max(KFloor_UV(i, j), KFloor_UV(iSouth, jWest))

                    ! West or South Face
        dok1:   do k = Kbottom, KUB
                


                    FaceFlux_WestSouth = (WaterFlux_XY(iSouth, jWest, k) + &
                                         WaterFlux_XY(i, j, k))/2.            ![m^3/s]

                    !UpStream Coefficients :
                    if (FaceFlux_WestSouth>0) then
                       !When the velocity compute point j - 2 or i - 2 is not covered then 
                       !(Aux = 0) the advection term is always compute using a upwind scheme
                       Aux             = ComputeFaces3D_UV(iSouth2, jWest2, k)
                       Coef1_WestSouth = Coef1_Up * Aux
                       Coef2_WestSouth = Coef2_Up * Aux + (1. - Aux)
                       Coef3_WestSouth = Coef3_Up * Aux
                       Coef4_WestSouth = 0.
                    else 
                       Coef1_WestSouth = 0.
                       Coef2_WestSouth = Coef3_Up
                       Coef3_WestSouth = Coef2_Up
                       Coef4_WestSouth = Coef1_Up 
                    endif 

                    !Total Coefficient (Upstream + Centered difference)
                    Cell1_FaceWestSouth = Coef1_WestSouth * UpStream_CenterDif

                    Cell2_FaceWestSouth = Coef2_WestSouth * UpStream_CenterDif +         &
                                          Coef_Centered   * (1. - UpStream_CenterDif)

                    Cell3_FaceWestSouth = Coef3_WestSouth * UpStream_CenterDif +         &
                                          Coef_Centered   * (1. - UpStream_CenterDif)

                    Cell4_FaceWestSouth = Coef4_WestSouth * UpStream_CenterDif


                    ! j-2 or i-2
                    Cell_1 = Velocity_UV_Old(iSouth2, jWest2, k) * Cell1_FaceWestSouth

                    ! j-1 or i-1
                    Cell_2 = Velocity_UV_Old(iSouth,  jWest,  k) * Cell2_FaceWestSouth
                                                                      
                    ! j or i
                    Cell_3 = Velocity_UV_Old(i,        j,       k) * Cell3_FaceWestSouth

                    ! j+1 or i+1
                    Cell_4 = Velocity_UV_Old(i_North,  j_East,  k) * Cell4_FaceWestSouth

                    
                    
                    MomentumFlux = dble(Cell_1  +  Cell_2  +  Cell_3  + Cell_4) * &
                                   FaceFlux_WestSouth ![m/s*m^3/s]

                    !Take from the Horizontal_Transport variable the part that will be 
                    !compute implicitly
                    Horizontal_Transport(i, j, k)            = Horizontal_Transport(i, j, k) - &
                                                               MomentumFlux                       

                    Horizontal_Transport(iSouth, jWest, k) = Horizontal_Transport(iSouth, jWest, k)  + &
                                                               MomentumFlux



                    ![ ] = [s] * [m^3/s] */ [m^3]
                    DTAux1 = DT_Velocity * FaceFlux_WestSouth  / Volume_UV(i, j, k)


                    ![ ] = [s] * [m^3/s] */ [m^3]
                    DTAux2 = DT_Velocity * FaceFlux_WestSouth  / Volume_UV(iSouth, jWest, k)


                    ![ ]  = [ ] + [ ] * [ ]

                    ! j-2 or i-2
                    !Ccoef_3D(i, j, k)            = Ccoef_3D(i, j, k)             - Cell1_FaceWestSouth * DTAux1

                    ! j-1 or i-1
                    Dcoef_3D(i, j, k)             = Dcoef_3D(i, j, k)             - Cell2_FaceWestSouth * DTAux1
                                                                      
                    ! j or i
                    Ecoef_3D(i, j, k)             = Ecoef_3D(i, j, k)             - Cell3_FaceWestSouth * DTAux1

                    ! j+1 or i+1
                    !Fcoef_3D(i, j, k)            = Fcoef_3D(i, j, k)             - Cell4_FaceWestSouth * DTAux1


                    ! j-2 or i-2
                    !Dcoef_3D(iSouth, jWest, k) = Dcoef_3D(iSouth, jWest, k)  + Cell1_FaceWestSouth * DTAux2

                     ! j-1 or i-1
                    Ecoef_3D(iSouth, jWest, k)  = Ecoef_3D(iSouth, jWest, k)  + Cell2_FaceWestSouth * DTAux2 
                                                                      
                    ! j or i
                    Fcoef_3D(iSouth, jWest, k)  = Fcoef_3D(iSouth, jWest, k)  + Cell3_FaceWestSouth * DTAux2  

                    ! j+1 or i+1
                    !Gcoef_3D(iSouth, jWest, k) = Gcoef_3D(iSouth, jWest, k)  + Cell4_FaceWestSouth * DTAux2 


                enddo dok1
            endif cd0

        enddo doj
        enddo doi

        !Nullify auxiliar pointers
        nullify (WaterFlux_XY)
        nullify (ECoef_3D, DCoef_3D, FCoef_3D)
        nullify (Horizontal_Transport)
        nullify (Velocity_UV_Old)
        nullify (Volume_UV)
        nullify (ComputeFaces3D_UV)
        nullify (KFloor_UV)

    End Subroutine Modify_Implicit_UX_VY

    
    !End ----------------------------------------------------------------------


    subroutine Modify_ObstacleDrag
        
        !Local---------------------------------------------------------------------
        integer                             :: STAT_CALL
        integer                             :: IUB, ILB, JUB, JLB, KUB, KLB, kbottom
        integer                             :: di, dj, i, j, k
        real                                :: FaceDragCoef, VelMod_UV
        integer                             :: iSouth, I_North, J_East, jWest

        !Begin---------------------------------------------------------------------

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        if (Me%Drag%ID%SolutionFromFile) then

            call ModifyFillMatrix(FillMatrixID      = Me%Drag%ID%ObjFillMatrix,             &
                                  Matrix3D          = Me%Drag%Coef,                         &
                                  PointsToFill3D    = Me%External_Var%WaterPoints3D,        &
                                  STAT              = STAT_CALL)
            if(STAT_CALL .ne. SUCCESS_) stop 'Modify_ObstacleForces - ModuleHydrodynamic - ERR01'

        endif

do1:    do j = JLB, JUB
do2:    do i = ILB, IUB

            if (Me%External_Var%ComputeFaces3D_UV(I, J, KUB) == Covered) then 


                kbottom = Me%External_Var%KFloor_UV(I, J)

                iSouth     = I - di
                jWest      = J - dj 

                ! This values (i_North and j_east) can only be used to compute the velocity modulus in a face
                I_North     = I + dj
                J_East      = J + di


do3:            do k = kbottom, KUB
                

                    VelMod_UV       = Face_Velocity_Modulus(                                &
                                      Me%Velocity%Horizontal%VU%New(I_North, jWest, K),     &
                                      Me%Velocity%Horizontal%VU%New(I_North, J_East, K),    &
                                      Me%Velocity%Horizontal%VU%New(iSouth, jWest, K),      &
                                      Me%Velocity%Horizontal%VU%New(iSouth, J_East, K),     &
                                      Me%External_Var%DXX_YY(I_North, jWest),               &
                                      Me%External_Var%DXX_YY(I_North, J_East),              &
                                      Me%External_Var%DXX_YY(iSouth, jWest),                &
                                      Me%External_Var%DXX_YY(iSouth, J_East),               &
                                      Me%Velocity%Horizontal%UV%New(I,J,K))                               
                                                
                    FaceDragCoef    = Face_Interpolation(Me%Drag%Coef(i, j, k),             &
                                                         Me%Drag%Coef(iSouth, jWest, K),    &
                                                         Me%External_Var%DUX_VY(I, J),      &
                                                         Me%External_Var%DUX_VY(iSouth, jWest))

                    ![]              = []       [s/m] * [m/s]
                    Me%Forces%ObstacleDrag_Aceleration(i, j, k) = -1. * FaceDragCoef * VelMod_UV * &
                                                                  Me%Velocity%Horizontal%UV%New(I,J,K)


                enddo do3

            endif

        enddo do2
        enddo do1


    end subroutine Modify_ObstacleDrag


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the coriolis force devided by the density                   !
    !  for both horizontal directions : X and Y                                            ! 
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping, Time steps                                          !
    ! OutPut: Coriolis force                                                               !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine Modify_InertiaForces 

        ! X direction (Coriolis_Force(Vvar, Volume_U, Coriolis_Freq, DXX, DUX, KFloorU, CoveredFacesX, &
        !              ILB, IUB, JLB, JUB, KUB, Direction=1, Inertial_Aceleration)
        ! Y direction (Coriolis_Force(Uvar, Volume_V, Coriolis_Freq, DYY, DVY, KFloorV, CoveredFacesY, &
        !              ILB, IUB, JLB, JUB, KUB, Direction=0, Inertial_Aceleration)

        !Arguments------------------------------------------------------------



        !Local---------------------------------------------------------------------
        real,    dimension(:,:,:), pointer :: Velocity_UV_New, Velocity_VU_New, Inertial_Aceleration
        real,    dimension(:,:),   pointer :: DXX_YY, DYY_XX, DUX_VY, DVY_UX, DZX_ZY, Coriolis_Freq

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, LandBoundaryFacesVU
        integer, dimension(:,:),   pointer :: KFloor_UV
        
        real,    dimension(:  ),   pointer :: XX 

        real                               :: VUvar1, VUvar2, VUAverage, F_UV
        integer                            :: di, dj, k, kbottom, NoLand1, NoLand2
        integer                            :: I, I1, I2, I3
        integer                            :: J, J1, J2, J3

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        real                               :: Radius, Xorig, Yorig, Coriolis_Aceleration, &
                                              Centrifugal_Aceleration
        real                               :: dx1, dx2, Area, dxdy, dydx, f_Curvature

        integer                            :: FATAL_, INTERNAL_, ICOORD_TIP, CIRCULAR,   &
                                              status, Iaux

        !------------initialization----

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        Inertial_Aceleration => Me%Forces%Inertial_Aceleration
        Velocity_UV_New      => Me%Velocity%Horizontal%UV%New
        Velocity_VU_New      => Me%Velocity%Horizontal%VU%New

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV

        KFloor_UV            => Me%External_Var%KFloor_UV


        DXX_YY               => Me%External_Var%DXX_YY
        DYY_XX               => Me%External_Var%DYY_XX

        DUX_VY               => Me%External_Var%DUX_VY
        DVY_UX               => Me%External_Var%DVY_UX

        DZX_ZY               => Me%External_Var%DZX_ZY

        Coriolis_Freq        => Me%External_Var%Coriolis_Freq

        LandBoundaryFacesVU  => Me%External_Var%LandBoundaryFacesVU

        !End - Shorten variables name 
        !Gets the type of Coordinates
        call GetCoordTypeList(CIRCULAR  = CIRCULAR)

        call GetGridCoordType(Me%ObjHorizontalGrid, ICOORD_TIP, STAT = status)
        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "Modify_InertiaForces - Hydrodynamic - ERR01")
                            
        if (ICOORD_TIP == CIRCULAR .and. Me%ComputeOptions%CentrifugalForce) then
            
            !Gets XX (radius when the grid coordinates are circular
            call GetHorizontalGrid(Me%ObjHorizontalGrid, XX = XX, STAT = status)
            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "Modify_InertiaForces - Hydrodynamic - ERR02")

            !Gets Origin of the Bathymetry
            call GetGridOrigin(Me%ObjHorizontalGrid, Xorig, Yorig, STAT = status)
            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "Modify_InertiaForces - Hydrodynamic - ERR03")


        endif


        !------------Main cicle--------

do1:    do  J = JLB, JUB
do2:    do  I = ILB, IUB
                                
cd1:        if (ComputeFaces3D_UV(I, J, KUB) == Covered) then 

                kbottom = KFloor_UV(I, J)


                I1    = I+dj-di
                J1    = J-dj+di
                I2    = I+dj
                J2    = J+di
                I3    = I-di
                J3    = J-dj


                
    do3:        do K=kbottom, KUB


                    !Null gradient is admitted in the land boundary.
                    if ((LandBoundaryFacesVU(I1, J1, K) + LandBoundaryFacesVU(I2, J2, K)) == 0) then

                        VUvar1 = (Velocity_VU_New(I1, J1, K) * DXX_YY(I2, J2) + &
                                  Velocity_VU_New(I2, J2, K) * DXX_YY(I1, J1))/ &
                                 (DXX_YY(I1, J1) +  DXX_YY(I2, J2))

                        NoLand1  = 1

                    else

                        VUvar1 = (1 - LandBoundaryFacesVU(I1, J1, K)) * Velocity_VU_New(I1, J1, K) + &
                                 (1 - LandBoundaryFacesVU(I2, J2, K)) * Velocity_VU_New(I2, J2, K)

                        NoLand1  = 2 - LandBoundaryFacesVU(I1, J1, K) - LandBoundaryFacesVU(I2, J2, K)

                    endif

                    if ((LandBoundaryFacesVU(I3, J3, K) + LandBoundaryFacesVU(I, J, K)) == 0) then
                        
                        VUvar2 = (Velocity_VU_New(I3, J3, K) * DXX_YY(I, J)   + &
                                  Velocity_VU_New(I,   J, K) * DXX_YY(I3, J3))/ &
                                 (DXX_YY(I3, J3) +  DXX_YY(I, J))

                       NoLand2  = 1

                    else

                       VUvar2 = (1 - LandBoundaryFacesVU(I3, J3, K)) * Velocity_VU_New(I3, J3, K) + &
                                (1 - LandBoundaryFacesVU(I,   J, K)) * Velocity_VU_New(I,   J, K)

                       NoLand2  = 2 - LandBoundaryFacesVU(I3, J3, K) - LandBoundaryFacesVU(I,   J, K)

                    endif

                    Iaux = NoLand1 + NoLand2
               
                    if (Iaux > 0) then
                        VUAverage  = (VUvar1 * NoLand1 + VUvar2 * NoLand2) / real(Iaux)
                    else
                        VUAverage  = 0.
                    endif   
                    

                    !VUvar1 = (Velocity_VU_New(I1, J1, K) * DXX_YY(I2, J2) + &
                    !          Velocity_VU_New(I2, J2, K) * DXX_YY(I1, J1))/ &
                    !         (DXX_YY(I1, J1) +  DXX_YY(I2, J2))

                    !VUvar2 = (Velocity_VU_New(I3, J3, K) * DXX_YY(I, J)   + &
                    !          Velocity_VU_New(I,   J, K) * DXX_YY(I3, J3))/ &
                    !         (DXX_YY(I3, J3) +  DXX_YY(I, J))

                    !VUAverage  = (VUvar1  + VUvar2) / 2.

                    Inertial_Aceleration(I, J, K) = 0.


                    if (Me%ComputeOptions%Coriolis) then

                        ! Interpolates Coriolis_Freq for the face 
                        F_UV = (DUX_VY(I3, J3) * Coriolis_Freq(I, J) + DUX_VY(I, J) * Coriolis_Freq(I3, J3)) / &
                               (DUX_VY(I3, J3) + DUX_VY(I, J))


                        ! Compute aceleration force

                        ![m/s^2]                 =            [s^-1] * [m/s]
                        Coriolis_Aceleration     = (dj - di) * F_UV * VUAverage 
                        Inertial_Aceleration(I, J, K) = Inertial_Aceleration(I, J, K) +  Coriolis_Aceleration

                    endif

                    if (Me%ComputeOptions%CentrifugalForce) then

                                       
                        if (ICOORD_TIP == CIRCULAR) then

                            Radius      = Xorig + XX(J)
                       
                            ![m/s^2]                =           [m/s] * [m/s] / [m]
                            Centrifugal_Aceleration =  dj * VUAverage * VUAverage / Radius

                            ![m/s^2]                 =            [m/s^2]  + [m/s^2] 
                            Inertial_Aceleration(I, J, K) = Inertial_Aceleration(I, J, K) + Centrifugal_Aceleration

                        else 

                            Area      = DZX_ZY(i3, j3) * DYY_XX(i, j)

                            !If 
                            dydx      = DVY_UX(i, j) - DVY_UX(i3, j3)

                            dx2       = (DXX_YY(i1, j1) + DXX_YY(i2, j2)) / 2.
                            dx1       = (DXX_YY(i , j ) + DXX_YY(i3, j3)) / 2.

                            dxdy      = dx2 - dx1

                            ! [s-1]     =   [m/s * m / m^2]
                            f_Curvature =   (VUAverage * dydx - Velocity_UV_New(i, j, k) * dxdy) / Area
                       
                            ![m/s^2]                =           [m/s] * [s-1]
                            Centrifugal_Aceleration =  VUAverage * f_Curvature

                            ![m/s^2]                 =            [m/s^2]  + [m/s^2] 
                            Inertial_Aceleration(I, J, K) = Inertial_Aceleration(I, J, K) + Centrifugal_Aceleration


                        endif

                    endif
                    
                    
                enddo do3
                
            end if cd1
                    
        enddo do2
        enddo do1

        if (ICOORD_TIP == CIRCULAR) then
            
            !Gets XX and YY
            call UngetHorizontalGrid(Me%ObjHorizontalGrid, XX, STAT = status)
            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "Modify_InertiaForces - Hydrodynamic - ERR02")


        endif
              
        nullify (Inertial_Aceleration)
        nullify (Velocity_UV_New)
        nullify (Velocity_VU_New)

        nullify (DXX_YY)
        nullify (DYY_XX)
        nullify (DUX_VY)
        nullify (DVY_UX)
        nullify (DZX_ZY)

        nullify (Coriolis_Freq)

        nullify (ComputeFaces3D_UV, LandBoundaryFacesVU)
        nullify (KFloor_UV)

    End Subroutine Modify_InertiaForces

    !End------------------------------------------------------------------------------

    Subroutine ModifyRelaxAceleration 


        !Arguments------------------------------------------------------------


        !Local---------------------------------------------------------------------
        real,    dimension(:,:,:), pointer :: Velocity_UV_New, SubModel_UV_New,          &
                                              Relax_Aceleration, DecayTime,              &
                                              VelAssimilation, DUZ_VZ

        real,    dimension(:,:  ), pointer :: WaterColumnUV
        
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV

        integer, dimension(:,:),   pointer :: KFloor_UV 

        type (T_Time)                      :: CurrentTime, BeginTime, EndTime

        real                               :: ColdPeriod, ColdOrder, DT_RunPeriod, CoefCold, VelModel, VelReference  

        integer                            :: Vel_ID, status
        integer                            :: ILB, IUB, JLB, JUB, KUB, kbottom, i, j, k


    !------------initialization----

        !Begin - Shorten variables name         
        Relax_Aceleration    => Me%Forces%Relax_Aceleration

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV

        KFloor_UV            => Me%External_Var%KFloor_UV
        
        WaterColumnUV        => Me%External_Var%WaterColumnUV 

        DUZ_VZ               => Me%External_Var%DUZ_VZ


cd1:    if (Me%Relaxation%ReferenceVelocity == TotalVel_   .or.             &
            Me%Relaxation%ReferenceVelocity == BarotrVel_)  then

            Velocity_UV_New      => Me%Velocity%Horizontal%UV%New

        else if (Me%Relaxation%ReferenceVelocity == BaroclVel_) then cd1

            Velocity_UV_New      => Me%VelBaroclinic%UV%New

        endif cd1

        
        IUB = Me%WorkSize%IUB
        JUB = Me%WorkSize%JUB
        KUB = Me%WorkSize%KUB

        ILB = Me%WorkSize%ILB
        JLB = Me%WorkSize%JLB

        EndTime     = Me%EndTime 

        BeginTime   = Me%BeginTime 

        CurrentTime = Me%CurrentTime

        !End - Shorten variables name         


        nullify (SubModel_UV_New)
      
cd2:    if      (Me%Direction%XY == DirectionX_) then

            Vel_ID = VelocityU_
            if (Me%SubModel%ON)                                             &
                SubModel_UV_New => Me%SubModel%U_New

        else if (Me%Direction%XY == DirectionY_) then cd2

            Vel_ID = VelocityV_
            if (Me%SubModel%ON)                                             &
                SubModel_UV_New => Me%SubModel%V_New

        endif cd2


        call GetAssimilationField(Me%ObjAssimilation,                   &
                                  ID              = Vel_ID,                          &
                                  Field3D         = VelAssimilation,                 &
                                  STAT            = status)

        if (status /= SUCCESS_)                                                      &
            call SetError (FATAL_, INTERNAL_, "ModifyRelaxAceleration - Hydrodynamic - ERR10")


        call GetAssimilationCoef (Me%ObjAssimilation,                                &
                                  ID          = Vel_ID,                              &
                                  CoefField3D = DecayTime,                           &
                                  ColdRelaxPeriod = ColdPeriod,                      &
                                  ColdOrder       = ColdOrder,                       &
                                  STAT        = status)

        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "ModifyRelaxAceleration - Hydrodynamic - ERR20")


        DT_RunPeriod = CurrentTime - BeginTime

        if (ColdPeriod > (EndTime - BeginTime))                                          &
            call SetError (FATAL_, INTERNAL_, "ModifyRelaxAceleration - Hydrodynamic - ERR30")

cd4:    if (ColdPeriod <= DT_RunPeriod) then
            CoefCold = 1
        else  cd4
            CoefCold = (DT_RunPeriod / ColdPeriod) ** ColdOrder
            if (CoefCold < 1.e-32) CoefCold = 1.e-32
        endif cd4


        
do1:    do  J = JLB, JUB
do2:    do  I = ILB, IUB
            
cd5:        if (ComputeFaces3D_UV(I, J, KUB) == Covered ) then 

                kbottom = KFloor_UV(I, J)                            
                       
cd6:            if (Me%Relaxation%ReferenceVelocity == BarotrVel_) then

                    VelModel  = 0.

do4:                do K=kbottom, KUB

                        VelModel  =  VelModel + Velocity_UV_New(i, j, k) *               &
                                     DUZ_VZ(i, j, k) / WaterColumnUV(i, j)

                    enddo do4

                endif cd6

do3:            do K=kbottom, KUB
                    
                    if (Me%Relaxation%ReferenceVelocity /= BarotrVel_)      &
                        VelModel  = Velocity_UV_New(i, j, k)

                    if     (Me%ComputeOptions%LocalSolution == AssimilaPlusSubModel_) then

                         VelReference = VelAssimilation(i, j, k)  + SubModel_UV_New(i, j, k)
                    
                    elseif (Me%ComputeOptions%LocalSolution == Submodel_)             then

                        VelReference = SubModel_UV_New(i, j, k)

                    elseif (Me%ComputeOptions%LocalSolution == NoLocalSolution_ .or.    &
                            Me%ComputeOptions%LocalSolution == AssimilationField_) then

                        VelReference = VelAssimilation(i, j, k)

                    elseif (Me%ComputeOptions%LocalSolution == Gauge_) then

                        stop 'ModifyRelaxAceleration - ModuleHydrodynamic - ERR40'

                    endif


                    ![m/s^2]                   = []*([m/s] - [m/s]) / [s]
                    Relax_Aceleration(i, j, k) = CoefCold  * (VelReference - VelModel)/ DecayTime(i, j, k)
                    

                enddo do3
                            
            endif cd5
                 
        enddo do2
        enddo do1

        call UnGetAssimilation(Me%ObjAssimilation, DecayTime, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "ModifyRelaxAceleration - Hydrodynamic - ERR50")

        call UnGetAssimilation(Me%ObjAssimilation, VelAssimilation,         &
                               STAT        = status)

        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "ModifyRelaxAceleration - Hydrodynamic - ERR60")

        nullify(Relax_Aceleration)
        nullify(ComputeFaces3D_UV)
        nullify(KFloor_UV        )
        nullify(Velocity_UV_New  )    
        nullify(WaterColumnUV    )
        nullify(DUZ_VZ           )
        
        if (Me%SubModel%ON)                                                 &
            nullify(SubModel_UV_New)
 

    End Subroutine ModifyRelaxAceleration

    !End------------------------------------------------------------------------------

    Subroutine ModifyRelaxHorizAdv 


        !Arguments------------------------------------------------------------


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport
        real,    dimension(:,:,:), pointer :: DecayTime
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV 

        real                               :: DecayTimeMin

        integer                            :: HT_ID, status
        integer                            :: ILB, IUB, JLB, JUB, KUB, kbottom, i, j, k


    !------------initialization----

        !Begin - Shorten variables name         

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV

        KFloor_UV            => Me%External_Var%KFloor_UV

        Horizontal_Transport => Me%Forces%Horizontal_Transport

        
        IUB = Me%WorkSize%IUB
        JUB = Me%WorkSize%JUB
        KUB = Me%WorkSize%KUB

        ILB = Me%WorkSize%ILB
        JLB = Me%WorkSize%JLB

      
cd2:    if      (Me%Direction%XY == DirectionX_) then

            HT_ID = HorizontalTransportX_


        else if (Me%Direction%XY == DirectionY_) then cd2

            HT_ID = HorizontalTransportY_

        endif cd2

        call GetAssimilationCoef (Me%ObjAssimilation,                       &
                                  ID          = HT_ID,                                   &
                                  Minimum     = DecayTimeMin,                            &
                                  CoefField3D = DecayTime,                               &
                                  STAT        = status)

        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "ModifyRelaxHorizAdv - Hydrodynamic - ERR01")

        
do1:    do  J = JLB, JUB
do2:    do  I = ILB, IUB
            
cd5:        if (ComputeFaces3D_UV(I, J, KUB) == Covered ) then 

                kbottom = KFloor_UV(I, J)                            
                       
do3:            do K=kbottom, KUB
                    
                    ![m3/s*m/s]                   = [m3/s*m/s] * [s/s]
                    Horizontal_Transport(i, j, k) = Horizontal_Transport(i, j, k)*(1. - DecayTimeMin / DecayTime(i, j, k))
                    

                enddo do3
                            
            endif cd5
                 
        enddo do2
        enddo do1

        call UnGetAssimilation(Me%ObjAssimilation, DecayTime, STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "ModifyRelaxHorizAdv - Hydrodynamic - ERR02")


        nullify(ComputeFaces3D_UV   )
        nullify(KFloor_UV           )
        nullify(Horizontal_Transport)

    End Subroutine ModifyRelaxHorizAdv

    !End------------------------------------------------------------------------------

    !-----------------------------------------------------------------

    Subroutine ModifyTidePotential

        !Arguments-------------------------------------------------------------

        


        !Local-----------------------------------------------------------------

        real,    pointer, dimension (:,:)   :: GridLatitude, GridLongitude, &
                                               TidePotentialLevel
        real,    pointer, dimension (:  )   :: Beta, EqAmp, Freq, AstroArg, L
        integer, pointer, dimension (:  )   :: m
        integer, pointer, dimension (:,:,:) :: WaterPoints3D
        type (T_Time)                       :: CurrentTime, TimeRef
        real(8)                             :: UTSeconds, tc, h0, s0, p0, Tau, TimeSeconds !ps, ns,
        real                                :: LatRad, LongRad, Run_Period, Aux, LongDegree
        real                                :: Year, Month, Day, Hour, Minute, Seconds
        integer                             :: STATUS, JulDay, D
        integer                             :: IUB, ILB, JUB, JLB, KUB, i, j, Ncomp, n


        !Begin-----------------------------------------------------------------


        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB


        TidePotentialLevel => Me%Forces%TidePotentialLevel
        
        Beta           => Me%TidePotential%Beta
        EqAmp          => Me%TidePotential%Amplitude
        Freq           => Me%TidePotential%Frequency
        AstroArg       => Me%TidePotential%Arguments
        m              => Me%TidePotential%m
        L              => Me%TidePotential%L

        Ncomp          =  Me%TidePotential%ComponentsNumber

        WaterPoints3D  => Me%External_Var%WaterPoints3D

        TimeRef        =  Me%TidePotential%TimeRef

        CurrentTime    = Me%CurrentTime


        Run_Period     = Me%CurrentTime - Me%BeginTime

        call GetGridLatitudeLongitude(Me%ObjHorizontalGrid,                 &
                                      GridLatitude  = GridLatitude,                      &
                                      GridLongitude = GridLongitude,                     &
                                      STAT = STATUS)

        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "ModifyTidePotential - Hydrodynamic - ERR01")        


        call ExtractDate(CurrentTime, Year, Month, Day, Hour, Minute, Seconds)
        
        if (year < 1975) call SetError (FATAL_, INTERNAL_, "ModifyTidePotential - Hydrodynamic - ERR02")        

        call JulianDay(CurrentTime, JulDay)

        D = JulDay + 365*(int(year)-1975)+int((year-1973)/4)

      
        !time in Junlian centuries (36525 days)
        !tc = TimeSeconds / 86400. / 36525.
        tc = (27392.500528+1.0000000356*real(D))/36525 


        !Lunar and solar ephemerides in degrees - Kantha e Clayson, 2000 (pág. 435)

        h0 = 279.69668    + 36000.768925485*tc + 3.03e-4 *tc*tc
        s0 = 270.434358   + 481267.88314137*tc - 0.001133*tc*tc   + 1.9e-6*tc*tc*tc
        p0 = 334.329653   + 4069.0340329575*tc - 0.10325 *tc*tc   - 1.2e-5*tc*tc*tc
        !ns = 259.16000    - 1934.14        *tc + 0.0021  *tc*tc
        !ps = 281.22083    + 1.71902        *tc + 0.00045 *tc*tc   + 3.0e-6*tc*tc*tc


        !Astronomical Arguments (Table 6.2.1 Kantha and Clayson, 2000)
        AstroArg(Ssa) =  2*h0
        AstroArg(Mm ) =  s0 - p0
        AstroArg(Mf ) =  2*s0

        AstroArg(K1 ) =          h0      +90.
        AstroArg(O1 ) = -2*s0 +  h0      -90.
        AstroArg(P1 ) =       -  h0      -90.
        AstroArg(Q1 ) = -3*s0 +  h0 + p0 -90. 

        AstroArg(M2 ) = -2*s0 + 2*h0
        AstroArg(S2 ) = 0.
        AstroArg(N2 ) = -3*s0 + 2*h0 + p0
        AstroArg(K2 ) = 2*h0

        !Conversion of Degrees in Radians
        do n = 1, Ncomp
            AstroArg(n) = AstroArg(n) * Pi / 180.
        enddo


        !Universal Time in seconds (by default is consider that the model time is the UT)
        UTSeconds = Hour * 3600. + Minute * 60. + Seconds


        do  i = ILB, IUB
        do  j = JLB, JUB
            
iw1:        if (WaterPoints3D(i, j, KUB) == WaterPoint)  then

                LatRad     = GridLatitude (i, j) * Pi / 180.

                LongDegree = GridLongitude(i, j)

                do while (LongDegree>=360.) 
                    LongDegree = LongDegree - 360.
                enddo
                do while (LongDegree<   0.) 
                    LongDegree = LongDegree + 360.
                enddo


                LongRad = LongDegree * Pi / 180.


it1:            if (Me%TidePotential%Algorithm == Kantha) then 

                    !L 
                    L(0) = 1.5*cos(LatRad)*cos(LatRad) - 1.
                    L(1) = sin(2*LatRad)
                    L(2) = cos(LatRad)*cos(LatRad)

                    TidePotentialLevel(i,j) = 0.
                    do n=1, Ncomp
                        TidePotentialLevel(i,j) = TidePotentialLevel(i,j) +  Beta (n) * EqAmp(n) * L(m(n)) *     &
                                                  cos (Freq(n)*UTSeconds/3600 + real(m(n))*LongRad + AstroArg(n))
                    enddo

                    if (Me%ComputeOptions%TideSlowStartCoef > 0.)  then

                        Aux = Run_Period / Me%ComputeOptions%TideSlowStartCoef
 
                        if (Aux < 1) TidePotentialLevel(i,j)= TidePotentialLevel(i,j) * Aux 


                    endif

                else if (Me%TidePotential%Algorithm == Lefevre) then it1

                    !time in Junlian centuries (36525 days)
                    !Seconds TimeRef = 1900/1/1 : 0h0m 

                    TimeSeconds = CurrentTime - TimeRef

                    tc = TimeSeconds / 86400. / 36525.

                    !Universal Time in seconds (by default is consider that the model time is the UT)
                    UTSeconds = Hour * 3600. + Minute * 60. + Seconds + 86400. 

                    !Lefévre, 2001 (4.19) chapter 4 page 55 (phD Thesis).
                    h0 = 280.18950    +  36000.76892*tc + 3.00e-4 *tc*tc
                    s0 = 277.02480    + 481267.89060*tc + 2.00e-3 *tc*tc 
                    p0 = 334.38530    +   4069.03400*tc + 1.03e-2 *tc*tc
                    !ns = 100.84320    +   1934.14200*tc + 2.10e-3 *tc*tc
                    !ps = 281.22086    +      1.71920*tc + 5.00e-4 *tc*tc   

       
                    Tau = UTseconds / 86400.*360. + LongDegree - s0 + h0

                    !Astronomical Arguments (Table 5 Lefèvre, 2001)
                    AstroArg(Ssa) =  2*h0
                    AstroArg(Mm ) =  s0 - p0
                    AstroArg(Mf ) =  2*s0

                    !Lefèvre, 2001 do not make reference to the phase corrections (+- 90º)
                    !However this corrections are made in the ModuleToga (Foreman Tidal Analysis package)
                    !and are also maed by Kantha e Clayson, 2000.
                    AstroArg(K1 ) =  Tau + s0         + 90. 
                    AstroArg(O1 ) =  Tau - s0         - 90. 
                    AstroArg(P1 ) =  Tau + s0 - 2*h0  - 90. 
                    AstroArg(Q1 ) =  Tau - 2*s0 + p0  - 90.

                    AstroArg(M2 ) = 2*Tau
                    AstroArg(S2 ) = 2*Tau + 2*s0 - 2*h0
                    AstroArg(N2 ) = 2*Tau -   s0 +   p0
                    AstroArg(K2 ) = 2*Tau + 2*s0

                    !Conversion of Degrees in Radians
                    do n = 1, Ncomp
                        AstroArg(n) = AstroArg(n) * Pi / 180.
                    enddo
                    !L 
                    L(0) = 1.5*cos(LatRad)*cos(LatRad) - 1.
                    L(1) = sin(2*LatRad)
                    L(2) = cos(LatRad)*cos(LatRad)

                    TidePotentialLevel(i,j) = 0.

                    do n=1, Ncomp
                        TidePotentialLevel(i,j) = TidePotentialLevel(i,j) +  Beta (n) * EqAmp(n) * L(m(n)) *     &
                                                  cos (AstroArg(n))
                    enddo

                    if (Me%ComputeOptions%TideSlowStartCoef > 0.)  then

                        Aux = Run_Period / Me%ComputeOptions%TideSlowStartCoef
 
                        if (Aux < 1) TidePotentialLevel(i,j)= TidePotentialLevel(i,j) * Aux 


                    endif
            
                endif it1

            else  iw1

                TidePotentialLevel(i, j) = FillValueReal
        
            endif iw1

        enddo
        enddo


        do  i = ILB, IUB
        do  j = JLB, JUB

            if (WaterPoints3D(i, j, KUB) == WaterPoint)  then

            else

                TidePotentialLevel(i, j) = FillValueReal
        
            endif

        enddo
        enddo

        call UngetHorizontalGrid(Me%ObjHorizontalGrid,  &
                                 Array = GridLatitude, STAT = STATUS)

        if (STATUS /= SUCCESS_)                                          &
            call SetError (FATAL_, INTERNAL_, "ModifyTidePotential - Hydrodynamic - ERR03")        


        call UngetHorizontalGrid(Me%ObjHorizontalGrid,  &
                                 Array = GridLongitude, STAT = STATUS)

        if (STATUS /= SUCCESS_)                                          &
            call SetError (FATAL_, INTERNAL_, "ModifyTidePotential - Hydrodynamic - ERR04")        


        !nullify auxiliar pointers
        nullify(TidePotentialLevel)
        nullify(Beta          )
        nullify(EqAmp         )
        nullify(Freq          )
        nullify(AstroArg      )
        nullify(m             )
        nullify(L             )

        nullify(WaterPoints3D)

!
    end Subroutine ModifyTidePotential


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! Compute the horizontal water flow                                                    !
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping                                                      !
    ! OutPut: Water Flow                                                                   !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Modify_HorizontalWaterFlow 

         !Variables Categories  
            !Geometry  : Area_UV
            !Flow      : WaterFlux_XY, Me%WaterFluxes%New_Old, Velocity_UV_New, Velocity_UV_Old
            !Mapping   : ComputeFaces3D_UV, KFloor_UV, Direction

         
         !Variables Direction Dependent
           !Area_UV, WaterFlux_XY, Me%WaterFluxes%New_Old, Velocity_UV_New, Velocity_UV_Old
           !ComputeFaces3D_UV, KFloor_UV, Direction
        !Arguments------------------------------------------------------------


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_XY
        real,    dimension(:,:,:), pointer :: Velocity_UV_Old, Velocity_UV_New, Area_UV, DWZ
        real,    dimension(:,:,:), pointer :: Baroclinic_UV_New, Baroclinic_UV_Old,      &
                                              DUZ_VZ, SZZ
        real,    dimension(:,:  ), pointer :: WaterColumnUV, DYY_XX

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ImposedNormalFacesUV,   &
                                              ImposedTangentialFacesUV
        integer, dimension(:,:),   pointer :: KFloor_Z, KFloor_UV, BoundaryPoints

        real(8)                            :: TotalFlux, dz

        integer                            :: I, J, K, Kbottom, di, dj

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB, ic, jc

        !--------------------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Modify_HorizontalWaterFlow")

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        WaterFlux_XY      => Me%WaterFluxes%XY
        Velocity_UV_Old   => Me%Velocity%Horizontal%UV%Old
        Velocity_UV_New   => Me%Velocity%Horizontal%UV%New

        Baroclinic_UV_New => Me%VelBaroclinic%UV%New
        Baroclinic_UV_Old => Me%VelBaroclinic%UV%Old

        ComputeFaces3D_UV        => Me%External_Var%ComputeFaces3D_UV
        KFloor_Z                 => Me%External_Var%KFloor_Z
        KFloor_UV                => Me%External_Var%KFloor_UV
        Area_UV                  => Me%External_Var%Area_UV
        ImposedNormalFacesUV     => Me%External_Var%ImposedNormalFacesUV
        ImposedTangentialFacesUV => Me%External_Var%ImposedTangentialFacesUV

        BoundaryPoints           => Me%External_Var%BoundaryPoints

        DYY_XX                   => Me%External_Var%DYY_XX
        DWZ                      => Me%External_Var%DWZ

        SZZ                      => Me%External_Var%SZZ
        WaterColumnUV            => Me%External_Var%WaterColumnUV
        DUZ_VZ                   => Me%External_Var%DUZ_VZ

        !End - Shorten variables name 


do3 :   do k = KLB, KUB  !rcm 6
do1 :   do j = JLB, JUB
do2 :   do i = ILB, IUB
            WaterFlux_XY(I,J,K) = 0.0 
        end do do2
        end do do1
        end do do3


doj:     do j = JLB, JUB
doi:     do i = ILB, IUB

Cov1:       if (ComputeFaces3D_UV(I, J, KUB) == Covered) then

                Kbottom = KFloor_UV(i, j)

dok:            do  k = Kbottom, KUB
 
                    ![m^3/s]              = [ ] * [m/s] * [m^2]
                    WaterFlux_XY(i, j, k) = (dble(Me%WaterFluxes%New_Old) *                  &
                                            dble(Velocity_UV_New(i, j, k))  + &
                                            dble((1. - Me%WaterFluxes%New_Old)) *            &
                                            dble(Velocity_UV_Old(i, j, k))) * &
                                            dble(Area_UV(i, j, k))
                enddo dok

            endif Cov1

        enddo doi
        enddo doj
        
cd3:    if (Me%SubModel%ON) then 
            
cd5:        if (Me%SubModel%Set) then 

                dok2: do k = KLB, KUB 
                doj2: do j = JLB, JUB + dj
                doi2: do i = ILB, IUB + di

                    !The faces that are exterior are put equal to the father model

cd4:                if (ImposedNormalFacesUV    (i, j, k) == Imposed   .or.              &
                        ImposedTangentialFacesUV(i, j, k) == Imposed) then                  
                
                        !Specific flow 
                        ![m^2/s]            = [m/s] * [m]
                        Me%SubModel%qXY(i, j, k)   =  (dble(Me%WaterFluxes%New_Old) *      &
                                            dble(Velocity_UV_New(i, j, k))        +      &
                                            dble((1. - Me%WaterFluxes%New_Old))                  *      &
                                            dble(Velocity_UV_Old(i, j, k)))       *      &
                                            dble(Me%SubModel%DUVZ_Old(i, j, k))
                        

                    endif cd4


cd11:               if (ComputeFaces3D_UV(i, j, k) == Covered) then                  
                
                        !Specific flow 
                        ![m^2/s]            = [m/s] * [m]
                        Me%SubModel%qXY(i, j, k)   =  (dble(Me%WaterFluxes%New_Old)           * &
                                            dble(Me%SubModel%UV_New(i, j, k))  + &
                                            dble((1. - Me%WaterFluxes%New_Old))                            * &
                                            dble(Me%SubModel%UV_Old(i, j, k))) * &
                                            dble(Me%SubModel%DUVZ_Old(i, j, k))
                        

                    endif cd11


                enddo doi2
                enddo doj2
                enddo dok2

            else cd5

                call SetError (FATAL_, INTERNAL_, "Modify_HorizontalWaterFlow - Hydrodynamic - ERR01")        
            

            endif cd5

        endif cd3

cd6:    if (Me%ComputeOptions%BaroclinicRadia == Horizontal_) then 


    doj3:   do j = JLB, JUB + dj
    doi3:   do i = ILB, IUB + di
                
cd9:            if (ImposedNormalFacesUV(i, j, KUB) == Imposed) then



                    if      (BoundaryPoints(i - di, j - dj) == Boundary) then



                        ic = i - di
                        jc = j - dj 
                
                    else if (BoundaryPoints(i     , j     ) == Boundary) then

                        ic = i 
                        jc = j 

                    endif

                    Kbottom = KFloor_Z(ic, jc)

                    TotalFlux = 0.

            dok3:   do k = Kbottom, KUB 


                        ![m^3/s]              = [ ] * [m/s] * [m] * [m]
                        WaterFlux_XY(i, j, k) = (dble(Me%WaterFluxes%New_Old)                     *         &
                                                dble(Baroclinic_UV_New (i, j, k))  +         &
                                                dble((1. - Me%WaterFluxes%New_Old))               *         &
                                                dble(Baroclinic_UV_Old(i, j, k)))  *         &
                                                dble(DWZ(ic, jc, k)) * dble(DYY_XX(i, j))

!                        WaterFlux_XY(i, j, k) = dble(Baroclinic_UV_New (i, j, k))  *         &
!                                                dble(DWZ(ic, jc, k)) * dble(DYY_XX(i, j))


                        TotalFlux = TotalFlux + WaterFlux_XY(i, j, k)

                    enddo dok3


            dok5:   do k = Kbottom, KUB 

                        dz = dble(SZZ(ic, jc, k       - 1) - SZZ(ic, jc, k  )) /         &
                             dble(SZZ(ic, jc, kbottom - 1) - SZZ(ic, jc, KUB))

                        ![m^3/s]              = [ ] * [m/s] * [m^2]
                        WaterFlux_XY(i, j, k) = WaterFlux_XY(i, j, k) -                  &
                                                TotalFlux * dz
                    enddo dok5

                    
                                            
                endif cd9

                
cd10:           if (ImposedTangentialFacesUV(i, j, KUB) == Imposed) then

                    Kbottom = KFloor_UV(i, j)

                    TotalFlux = 0.

            dok4:   do k = Kbottom, KUB 

                        ![m^3/s]              = [ ] * [m/s] * [m^2]
                        WaterFlux_XY(i, j, k) = (dble(Me%WaterFluxes%New_Old)                     *         &
                                                dble(Baroclinic_UV_New (i, j, k))  +         &
                                                dble((1. - Me%WaterFluxes%New_Old))               *         &
                                                dble(Baroclinic_UV_Old(i, j, k)))  *         &
                                                Area_UV(i, j, k)

!                        ![m^3/s]              = [ ] * [m/s] * [m^2]
!                        WaterFlux_XY(i, j, k) = dble(Baroclinic_UV_New (i, j, k))  *         &
!                                                Area_UV(i, j, k)


                        TotalFlux = TotalFlux + WaterFlux_XY(i, j, k)

                    enddo dok4

   
            dok6:   do k = Kbottom, KUB 

                        dz = dble(DUZ_VZ(i, j, k)) / dble(WaterColumnUV(i, j))

                        ![m^3/s]              = [ ] * [m/s] * [m^2]
                        WaterFlux_XY(i, j, k) = WaterFlux_XY(i, j, k) -                  &
                                                TotalFlux * dz

                    enddo dok6

                                            
                endif cd10


            enddo doi3
            enddo doj3


        
        endif cd6

        if (Me%CyclicBoundary%ON) then
        
        
            if (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                Me%CyclicBoundary%Direction == DirectionXY_)  then
                call CyclicBoundVectNormal    ( VectorD = WaterFlux_XY)
            endif

            if (Me%CyclicBoundary%Direction == Me%Direction%YX .or. &
                Me%CyclicBoundary%Direction == DirectionXY_)  then
                call CyclicBoundVectTangential( VectorD = WaterFlux_XY)
            endif

        endif


        nullify (WaterFlux_XY)
        nullify (Velocity_UV_Old)

        nullify (ComputeFaces3D_UV       )
        nullify (KFloor_UV               )
        nullify (KFloor_Z                )
        nullify (Area_UV                 ) 
        nullify (ImposedNormalFacesUV    )
        nullify (ImposedTangentialFacesUV)
        nullify (DYY_XX                  )
        nullify (DWZ                     )
        nullify (Baroclinic_UV_New       )
        nullify (Baroclinic_UV_Old       )
        nullify (SZZ                     )
        nullify (WaterColumnUV           )
        nullify (DUZ_VZ                  )
        
        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Modify_HorizontalWaterFlow")

    end Subroutine Modify_HorizontalWaterFlow

    !------------------------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the density gradient integral                               !
    !  for both horizontal directions : X and Y                                            ! 
    !                                                                                      !
    ! Input : Geometry, Mapping, density                                                   !
    ! OutPut: Rox3 - density gradient integral                                             !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine Modify_ROX3

        !Arguments------------------------------------------------------------


        !Local---------------------------------------------------------------------
        real,    dimension(:,:,:), pointer :: Rox3XY, DWZ, SigmaDens, DUZ_VZ, SZZ

        real,    dimension(:,:  ), pointer :: DZX_ZY, Coriolis_Freq, DUX_VY

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:  ), pointer :: BoundaryFacesUV
        integer, dimension(:,:),   pointer :: KFloor_UV 
        Integer                            :: i, j, di, dj, k, kbottom, ileft, jleft

        Integer, dimension( : ), pointer   :: Kleft,Kright

        Real(8), dimension( : ), pointer   :: Depth_integ, Hcenter, Hleft,&
                                              Hright, HroLeft, HroRight,  &
                                              DensRight, DensLeft

        Real(8)                            :: DAux,DAuxRight,DAuxLeft, AuxRight, AuxLeft, &
                                              ZRight, ZLeft, DRight, DLeft, DensZRight, DensZLeft

        type (T_Time)                      :: CurrentTime

        Real                               :: TimeCoef, F_UV, DT_RunPeriod, InertialPeriods

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB
        integer                            :: NRight, NLeft, kbright, kbleft, PoliDegree

        logical                            :: FoundBottomRight, FoundBottomLeft, FoundSurfaceRight, FoundSurfaceLeft
        logical                            :: BaroclinicRAMP, BoundaryBaroclinic, PoliIsEven


    !------------initialization----


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        Rox3XY            => Me%Forces%Rox3XY
        SigmaDens         => Me%External_Var%SigmaDens

        ComputeFaces3D_UV => Me%External_Var%ComputeFaces3D_UV
        BoundaryFacesUV   => Me%External_Var%BoundaryFacesUV
        KFloor_UV         => Me%External_Var%KFloor_UV

        DWZ               => Me%External_Var%DWZ
        SZZ               => Me%External_Var%SZZ
        DUZ_VZ            => Me%External_Var%DUZ_VZ
        DZX_ZY            => Me%External_Var%DZX_ZY  
        DUX_VY            => Me%External_Var%DUX_VY  

        Kleft             => Me%Coef%Baroc%Kleft
        Kright            => Me%Coef%Baroc%Kright
        Depth_integ       => Me%Coef%Baroc%Depth_integ
        Hcenter           => Me%Coef%Baroc%Hcenter
        Hleft             => Me%Coef%Baroc%Hleft
        Hright            => Me%Coef%Baroc%Hright
        HroLeft           => Me%Coef%Baroc%HroLeft
        HroRight          => Me%Coef%Baroc%HroRight
        DensRight         => Me%Coef%Baroc%DensRight
        DensLeft          => Me%Coef%Baroc%DensLeft
        

        !End - Shorten variables name 

do1:    do  k = KLB, KUB
do2:    do  j = JLB, JUB
do3:    do  i = ILB, IUB

            Rox3XY (i, j, k) = FillValueReal

        enddo do3
        enddo do2
        enddo do1




!        Kleft             = FillValueInt   !rcm 7
!        Kright            = FillValueInt
!
!        Depth_integ       = FillValueReal
!        Hcenter           = FillValueReal
!        Hleft             = FillValueReal
!        Hright            = FillValueReal
!        HroLeft           = FillValueReal
!        HroRight          = FillValueReal


        

    !------------Main cicle--------

do4:     do J = JLB, JUB
do5:     do I = ILB, IUB
                    
cd1:        if (ComputeFaces3D_UV(i, j, KUB)== Covered) then 

do7:            do K = KLB, KUB
                    Kleft      (K)       = FillValueInt    !rcm 8
                    Kright     (K)       = FillValueInt

                    Depth_integ(K)       = FillValueReal
                    Hcenter    (K)       = FillValueReal
                    Hleft      (K)       = FillValueReal
                    Hright     (K)       = FillValueReal
                    HroLeft    (K)       = FillValueReal
                    HroRight   (K)       = FillValueReal

                    DensRight  (K)       = FillValueReal
                    DensLeft   (K)       = FillValueReal 
                end do do7


                kbottom = KFloor_UV(i, j)

                ileft = i - di
                jleft = j - dj

                call calc_depth_and_Hro (Hcenter, Hleft, Hright, HroLeft, HroRight,     &
                                         DensRight, DensLeft, DWZ, SZZ, DUZ_VZ, SigmaDens,&
                                         i, j, ileft, jleft, KUB, kbottom)

                if      (Me%ComputeOptions%BaroclinicMethod == DensityUniform  .or.     &
                         Me%ComputeOptions%BaroclinicMethod == DensityLinear) then

                    call Calc_Depth_integration(Hcenter, Hleft, Hright,                 &
                                                Kleft, Kright, Depth_integ, KUB, kbottom) 



do6:                do  k=KUB, kbottom,-1

                        Zright   = Depth_integ    (k)  - Hright (kright(k) + 1)    
                        Dright   = Hright (kright (k)) - Hright (kright(k) + 1)

                        Zleft    = Depth_integ    (k)  - Hleft  (kleft (k) + 1)    
                        Dleft    = Hleft  (kleft  (k)) - Hleft  (kleft (k) + 1)

                              

                        if      (Me%ComputeOptions%BaroclinicMethod == DensityUniform) then

                            !Constant SigmaDens in each layer

                            AuxRight = Zright / Dright

                            AuxLeft  = Zleft  / Dleft


                            ![M/m^3 * m]  = [M/m^3 * m]               
                            DAuxRight=     HroRight(kright(k) + 1)                        + &
                                          (HroRight(kright(k)) - HroRight(kright(k) + 1)) * &
                                           AuxRight

                            DAuxLeft =     Hroleft (kleft (k) + 1)                        + &
                                          (Hroleft(kleft  (k)) - Hroleft(kleft(k)  + 1))  * &
                                           AuxLeft

                        else if (Me%ComputeOptions%BaroclinicMethod == DensityLinear) then

                            !Linear SigmaDens evolution in each layer
                            DensZRight = (DensRight(kright(k)    ) *  Zright/2.          +  &
                                          DensRight(kright(k) + 1) * (Dright-Zright/2.)) /  &
                                          Dright

                            DensZLeft  = (DensLeft(kLeft  (k)    ) *  ZLeft/2.           +  &
                                          DensLeft(kLeft  (k) + 1) * (DLeft-ZLeft/2.))   /  &
                                          DLeft
                        

                            ![M/m^3 * m]  = [M/m^3 * m]               
                            DAuxRight  =  HroRight (kright(k) + 1) + DensZRight * Zright

                            DAuxLeft   =  Hroleft  (kleft (k) + 1) + DensZLeft  * ZLeft

                        endif

                        ! DAuxLeft (i or i -1, j-1 or j) - DAuxRight (i,j)
                        DAux     =     DAuxLeft - DAuxRight

                        ![M/m^3] =     [M/m^3 * m] / [m]              
                        DAux     =     DAux/dble(DZX_ZY(ileft, jleft))

                        !if Rox3 is positive then the baroclinic force is positive 
                        !in the pass was the opposite but to maintain coherence with the 
                        !other pressure forces now (Rox3 = (DAuxLeft - DAuxRight)/dxy) 
                        !in the pass (Rox3 = (- DAuxLeft + DAuxRight)/dxy)
                        Rox3XY(i,j,k) = real(DAux)

                enddo do6                    

            endif
                    
                    
            if (Me%ComputeOptions%BaroclinicMethod == Leibniz .or.                     &
                Me%ComputeOptions%BaroclinicMethod == Leibniz2) then

                Rox3XY(i,j,KUB +1) = 0.

                kbright = Me%External_Var%KFloor_Z(i, j)

                NRight = KUB - kbright + 1

                kbleft = Me%External_Var%KFloor_Z(ileft, jleft)


                Hright  (KUB+1) = null_real
                Hleft   (KUB+1) = null_real

                DensRight(KUB+1)   = null_real
                DensLeft (KUB+1)   = null_real                
                
                do k = KUB , kbright, -1
                   Hright  (k) = (dble(SZZ (  i,       j, k)) + dble(SZZ (    i,     j, k-1))) / 2.
                   DensRight(k) = dble(SigmaDens(i    ,j    ,k  ))
                enddo

                do k = KUB , kbleft , -1
                   Hleft   (k) = (dble(SZZ (ileft, jleft, k)) + dble(SZZ (ileft, jleft, k-1))) / 2.
                   DensLeft (k) = dble(SigmaDens(ileft,jleft,k  ))
                enddo   

                NLeft  = KUB - kbLeft + 1

do27:           do  k=KUB, kbottom,-1

                    if      (Me%ComputeOptions%BaroclinicMethod == Leibniz) then

                        !Linear interpolation
                        DensZRight = InterpolateProfileR8 (Hcenter(k), NRight, Hright(kbright:KUB),  &
                                                           DensRight(kbright:KUB), FoundBottomRight, &
                                                           FoundSurfaceRight)
                    
                        DensZLeft  = InterpolateProfileR8 (Hcenter(k), NLeft , HLeft (kbleft :KUB),  &
                                                           DensLeft (kbleft :KUB), FoundBottomLeft , &
                                                           FoundSurfaceLeft )

                        if (.not. FoundBottomRight .and. .not. FoundBottomLeft                       &
                            .and. .not.FoundSurfaceRight .and. .not. FoundSurfaceLeft) then

                            DAux       =  (DensZLeft - DensZRight) * DUZ_VZ(i, j, k)  / dble(DZX_ZY(ileft, jleft))

                        else
                            DAux = 0.
                        endif

                    else if (Me%ComputeOptions%BaroclinicMethod == Leibniz2) then

                        if ( (KUB - kbright) == 0) then
                            !Uniform profile is assumed when there only one layer
                            DensZRight = DensRight(KUB)
                        else
                            !Interpolation n degree
                            PoliDegree = min (Me%ComputeOptions%BaroclinicPoliDegree, KUB - kbright)

                            if(IsOdd(PoliDegree))then
                                PoliIsEven = .false.
                            else
                                PoliIsEven = .true.
                            endif

                            DensZRight = PolIntProfile  (Hcenter(k), NRight, Hright(kbright:KUB), &
                                                         DensRight(kbright:KUB), PoliDegree,      &
                                                         PoliIsEven)
                        endif

                        if ( (KUB - kbleft ) == 0) then
                            !Uniform profile is assumed when there only one layer
                            DensZLeft  = DensLeft (KUB)
                        else
                            !Interpolation n degree
                            PoliDegree = min (Me%ComputeOptions%BaroclinicPoliDegree, KUB - kbleft )

                            if(IsOdd(PoliDegree))then
                                PoliIsEven = .false.
                            else
                                PoliIsEven = .true.
                            endif

                            DensZLeft  = PolIntProfile  (Hcenter(k), NLeft , HLeft (kbleft :KUB), &
                                                         DensLeft (kbleft :KUB), PoliDegree,      &
                                                         PoliIsEven)
                        endif

                        DAux       =  (DensZLeft - DensZRight) * DUZ_VZ(i, j, k)  / dble(DZX_ZY(ileft, jleft))
                   
                    endif


                    Rox3XY(i,j,k) = Rox3XY(i,j,k+1) + DAux

                enddo do27

            endif


            end if cd1

        enddo do5
        enddo do4


        


        !If the baroclinic force is not to be consider in the boundary then
        BoundaryBaroclinic = Me%ComputeOptions%BoundaryBaroclinic
        
cd10:   if ( .not. BoundaryBaroclinic ) then 

do41:       do J = JLB, JUB
do51:       do I = ILB, IUB
                    
cd11:           if (BoundaryFacesUV(i, j) == Boundary) then 

                    kbottom = KFloor_UV(i, j)

do61:               do  K = kbottom, KUB

                        Rox3XY (i, j, k) = 0.
                    
                    enddo do61

                endif cd11

            enddo do51
            enddo do41       

        endif cd10

        !If the RAMP option is on then the baroclinic force is gradually imposed
        BaroclinicRAMP = Me%ComputeOptions%BaroclinicRAMP
        
cd12:   if ( BaroclinicRAMP ) then 

            CurrentTime  = Me%CurrentTime

            DT_RunPeriod = CurrentTime - Me%ComputeOptions%RAMP_BeginTime

            InertialPeriods = Me%ComputeOptions%InertialPeriods

            Coriolis_Freq => Me%External_Var%Coriolis_Freq


do42:       do J = JLB, JUB
do52:       do I = ILB, IUB
                        
cd13:           if (ComputeFaces3D_UV(i, j, KUB)== Covered) then

                    ileft = i - di
                    jleft = j - dj

                    ! Interpolates Coriolis_Freq for the face 
                    F_UV = (DUX_VY(ileft, jleft) * Coriolis_Freq(I, J) + DUX_VY(I, J) * Coriolis_Freq(ileft, jleft)) / &
                           (DUX_VY(ileft, jleft) + DUX_VY(I, J))

                    
!                    InertialPeriods = Me%ComputeOptions%InertialPeriods


                    TimeCoef = abs (DT_RunPeriod * F_UV / (2 * Pi) / InertialPeriods)

cd14:               if (TimeCoef < 1) then
                    
                        kbottom = KFloor_UV(i, j)

do62:                   do  K = kbottom, KUB

                            Rox3XY (i, j, k) = TimeCoef * Rox3XY (i, j, k)
                    
                        enddo do62

                    endif cd14

                endif cd13

            enddo do52
            enddo do42     
            
            nullify (Coriolis_Freq)

        endif cd12

        
        !Nullify auxiliar pointers
        nullify (Kleft)
        nullify (Kright)
        nullify (Depth_integ)
        nullify (Hcenter)
        nullify (Hleft)
        nullify (Hright)
        nullify (HroLeft)
        nullify (HroRight)
        nullify (DensRight)
        nullify (DensLeft )


        nullify (Rox3XY)             
        nullify (SigmaDens)          

        nullify (ComputeFaces3D_UV)
        nullify (BoundaryFacesUV)
        nullify (KFloor_UV)

        nullify (DWZ, SZZ)
        nullify (DZX_ZY)
        nullify (DUX_VY)  
        nullify (DUZ_VZ)


    End Subroutine Modify_ROX3



    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This subroutine relaxes 3D hydrodynamic properties of single precision for a         !
    ! specific value                                                                       !
    !                                                                                      !
    ! Input : Hydrodynamic Property compute by the model                                   !
    ! OutPut: Hydrodynamic Property after assimilation                                     !
    ! Author: Paulo Chambel & Manuel Ruiz Villarreal  (2000/12)                                                              !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine HydroPropAssimilation3D( PropertyID, PropModel,           &
                                       PropSubModel, Map3D, KFloor, DT)

        !Arguments------------------------------------------------------------


        real,    dimension(:,:,:), pointer :: PropModel, PropSubModel

        integer, dimension(:,:,:), pointer :: Map3D

        integer, dimension(:,:),   pointer :: KFloor

        real                               :: DT

        integer                            :: PropertyID

        !Local---------------------------------------------------------------------
        real,    dimension(:,:,:), pointer :: DecayTime
        
        real,    dimension(:,:,:), pointer :: PropAssimilation

        type(T_Time)                       :: CurrentTime, EndTime, BeginTime

        real                               :: ColdPeriod, ColdOrder, CoefCold, DT_RunPeriod, AuxDecay
    
        integer                            :: I, J, K, Kbottom

        integer                            :: IUB, JUB, KUB, ILB, JLB, KLB, status

       

    !------------initialization----


        !Begin - Shorten variables name         
        
        IUB = Me%WorkSize%IUB
        JUB = Me%WorkSize%JUB
        KUB = Me%WorkSize%KUB

        ILB = Me%WorkSize%ILB
        JLB = Me%WorkSize%JLB
        KLB = Me%WorkSize%KLB

        EndTime     = Me%EndTime 

        BeginTime   = Me%BeginTime 

        CurrentTime = Me%CurrentTime

        !End - Shorten variables name         


        if (associated(PropSubModel)) then

            PropAssimilation => PropSubModel
            ColdPeriod       =  0.

        else

            call GetAssimilationField(Me%ObjAssimilation,                               &
                                      ID              = PropertyID,                     &
                                      Field3D         = PropAssimilation,               &
                                      STAT            = status)

            if (status /= SUCCESS_)                                                     &

                call SetError (FATAL_, INTERNAL_, "HydroPropAssimilation3D - Hydrodynamic - ERR01")

        endif

        call GetAssimilationCoef (Me%ObjAssimilation,                                   &
                                  ID          = PropertyID,                             &
                                  CoefField3D = DecayTime,                              &
                                  ColdRelaxPeriod = ColdPeriod,                         &
                                  ColdOrder       = ColdOrder,                          &
                                  STAT        = status)

        if (status /= SUCCESS_)                                                         &
            call SetError (FATAL_, INTERNAL_, "HydroPropAssimilation3D - Hydrodynamic - ERR02")


        DT_RunPeriod = CurrentTime - BeginTime

        if (ColdPeriod > (EndTime - BeginTime))                                         &
            call SetError (FATAL_, INTERNAL_, "HydroPropAssimilation3D - Hydrodynamic - ERR03")

        if (ColdPeriod <= DT_RunPeriod) then
            CoefCold = 1
        else
            CoefCold = (DT_RunPeriod / ColdPeriod) ** ColdOrder
            if (CoefCold < 1.e-32) CoefCold = 1.e-32
        endif


        
do1:    do  J = JLB, JUB
do2:    do  I = ILB, IUB
            
cd2:        if (Map3D(I, J, KUB) == Covered ) then 

                kbottom = KFloor(I, J)                            
                       

do3:            do K=kbottom, KUB

                    AuxDecay = CoefCold  * DT / DecayTime(i, j, k)                   

                    PropModel(i, j, k) = (PropModel (i, j, k)                  +         &
                                        AuxDecay * PropAssimilation(i, j, k))  /         &
                                        (1 + AuxDecay)

                enddo do3
                            
            endif cd2
                 
        enddo do2
        enddo do1

        call UnGetAssimilation(Me%ObjAssimilation, DecayTime,        &
                               STAT        = status)

        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "HydroPropAssimilation3D - Hydrodynamic - ERR04")

        if (.not. associated(PropSubModel)) then

            call UnGetAssimilation(Me%ObjAssimilation, PropAssimilation,    &
                                   STAT        = status)

            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "HydroPropAssimilation3D - Hydrodynamic - ERR05")

        else

            nullify(PropAssimilation)

        endif
 

    End Subroutine HydroPropAssimilation3D


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This subroutine relaxes 2D hydrodynamic properties of single precision for a         !
    ! specific value                                                                       !
    !                                                                                      !
    ! Input : Hydrodynamic Property computed by the model                                   !
    ! OutPut: Hydrodynamic Property after assimilation                                     !
    ! Author: Manuel & Paulo(2000/12)                                                              !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine HydroPropAssimilation2D( PropertyID, PropModel, PropSubModel, Map3D, DT)

        !Arguments------------------------------------------------------------


        real,    dimension(:,:  ), pointer :: PropModel, PropSubModel

        integer, dimension(:,:,:), pointer :: Map3D

        real                               :: DT

        integer                            :: PropertyID

        !Local---------------------------------------------------------------------
        real,    dimension(:,:  ), pointer :: DecayTime
        
        real,    dimension(:,:  ), pointer :: PropAssimilation
        
        type(T_Time)                       :: CurrentTime, EndTime, BeginTime

        real                               :: ColdPeriod, ColdOrder, CoefCold, DT_RunPeriod, AuxDecay
    
        integer                            :: I, J

        integer                            :: IUB, JUB, KUB, ILB, JLB, status
        
    !------------initialization----


        !Begin - Shorten variables name         
        
        IUB = Me%WorkSize%IUB
        JUB = Me%WorkSize%JUB
        KUB = Me%WorkSize%KUB

        ILB = Me%WorkSize%ILB
        JLB = Me%WorkSize%JLB


        EndTime     = Me%EndTime 

        BeginTime   = Me%BeginTime 

        CurrentTime = Me%CurrentTime

        !End - Shorten variables name         

        if (associated(PropSubModel)) then

            PropAssimilation => PropSubModel

        else

            call GetAssimilationField(Me%ObjAssimilation,                               &
                                      ID              = PropertyID,                     &
                                      Field2D         = PropAssimilation,               &
                                      STAT            = status)

            if (status /= SUCCESS_)                                                     &
                call SetError (FATAL_, INTERNAL_, "HydroPropAssimilation2D - Hydrodynamic - ERR01")

        endif

        call GetAssimilationCoef (Me%ObjAssimilation,                                   &
                                  ID          = PropertyID,                             &
                                  CoefField2D = DecayTime,                              &
                                  ColdRelaxPeriod = ColdPeriod,                         &
                                  ColdOrder       = ColdOrder,                          &
                                  STAT        = status)

        if (status /= SUCCESS_)                                                         &
            call SetError (FATAL_, INTERNAL_, "HydroPropAssimilation2D - Hydrodynamic - ERR02")


        DT_RunPeriod = CurrentTime - BeginTime

        if (ColdPeriod > (EndTime - BeginTime))                                         &
            call SetError (FATAL_, INTERNAL_, "HydroPropAssimilation3D - Hydrodynamic - ERR03")

        if (ColdPeriod <= DT_RunPeriod) then
            CoefCold = 1
        else
            CoefCold = (DT_RunPeriod / ColdPeriod) ** ColdOrder
            if (CoefCold < 1.e-32) CoefCold = 1.e-32
        endif

        
do1:    do  J = JLB, JUB
do2:    do  I = ILB, IUB

cd2:        if (Map3D(I, J, KUB) == Covered ) then 

                AuxDecay = CoefCold  * DT / DecayTime(i, j)                   

                PropModel(i, j) = (PropModel (i, j)                  +         &
                                  AuxDecay * PropAssimilation(i, j))  /         &
                                  (1 + AuxDecay)

                       
            endif cd2
                 
        enddo do2
        enddo do1

        call UnGetAssimilation(Me%ObjAssimilation, DecayTime,        &
                               STAT = status)

        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "HydroPropAssimilation2D - Hydrodynamic - ERR04")

        if (.not. associated(PropSubModel)) then

            call UnGetAssimilation(Me%ObjAssimilation, PropAssimilation,    &
                                   STAT        = status)

            if (status /= SUCCESS_)                                                      &
                call SetError (FATAL_, INTERNAL_, "HydroPropAssimilation2D - Hydrodynamic - ERR05")
 
         else


            nullify(PropAssimilation)

        endif

 

    End Subroutine HydroPropAssimilation2D


    Subroutine VelocityRelaxation

        !Arguments------------------------------------------------------------


        !Local---------------------------------------------------------------------
        real,    dimension(:,:,:), pointer :: Velocity_UV_New, SubModel_UV_New
        
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV

        integer, dimension(:,:),   pointer :: KFloor_UV 

        integer                            :: Vel_ID

    !------------initialization----

        !Begin - Shorten variables name         
        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV

        KFloor_UV            => Me%External_Var%KFloor_UV

        Velocity_UV_New      => Me%Velocity%Horizontal%UV%New

       !End - Shorten variables name   


        nullify (SubModel_UV_New)
      
        if      (Me%Direction%XY == DirectionX_) then

            !call GetAssimilationList(VelocityU = Vel_ID)
            Vel_ID = VelocityU_
            if (Me%SubModel%ON)                                             &
                SubModel_UV_New => Me%SubModel%U_New

        else if (Me%Direction%XY == DirectionY_) then

            !call GetAssimilationList(VelocityV = Vel_ID)
            Vel_ID = VelocityV_
            if (Me%SubModel%ON)                                             &
                SubModel_UV_New => Me%SubModel%V_New

        endif


        call HydroPropAssimilation ( Vel_ID, Velocity_UV_New,            &
                                    SubModel_UV_New, ComputeFaces3D_UV, KFloor_UV,       &
                                    Me%Velocity%DT)


        nullify(Velocity_UV_New  )
        nullify(KFloor_UV        )
        nullify(ComputeFaces3D_UV)


    End Subroutine VelocityRelaxation        
    !----------------------------------------------------------------

    Subroutine WaterLevelRelaxation

        !Arguments------------------------------------------------------------


        !Local---------------------------------------------------------------------
        real,    dimension(:,:  ), pointer :: WaterLevel_New, SubModel_Z
        
        integer, dimension(:,:,:), pointer :: OpenPoints3D

        integer, dimension(:,:),   pointer :: KFloor_Z 

        integer                            :: Vel_ID

    !------------initialization----

        !Begin - Shorten variables name         
        OpenPoints3D        => Me%External_Var%OpenPoints3D

        KFloor_Z            => Me%External_Var%KFloor_Z

        WaterLevel_New      => Me%WaterLevel%New

       !End - Shorten variables name   
      
        !call GetAssimilationList(WaterLevel = Vel_ID)
        Vel_ID = WaterLevel_
        nullify (SubModel_Z)
        
        if (Me%SubModel%ON)                                                 &
            SubModel_Z => Me%SubModel%Z


        call HydroPropAssimilation ( Vel_ID, WaterLevel_New, SubModel_Z, &
                                    OpenPoints3D, Me%WaterLevel%DT)


        nullify(WaterLevel_New   )
        nullify(KFloor_Z         )
        nullify(OpenPoints3D     )
        nullify(SubModel_Z       )


    End Subroutine WaterLevelRelaxation        
    !----------------------------------------------------------------

    !----------------------------------------------------------------
    ! guillaume nogueira

    Subroutine  WaterLevelRelaxationAltimetry

        !Local -----------------------------------------------------------------
        real,    pointer, dimension(:,:)          :: LevelAnalyzed
        real                                        :: AltimDecayTime
        integer                                     :: ILB, IUB 
        integer                                     :: JLB, JUB 
        integer                                     :: KLB, KUB
        integer                                     :: I, J, STAT_CALL
        real                                        :: AuxDecay

        !Begin--------------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "WaterLevelRelaxationAltimetry")

        ILB = Me%WorkSize%ILB 
        IUB = Me%WorkSize%IUB 
        JLB = Me%WorkSize%JLB 
        JUB = Me%WorkSize%JUB 
        KLB = Me%WorkSize%KLB 
        KUB = Me%WorkSize%KUB 

cd2:    if( Me%ComputeOptions%AltimetryAssimilation%flag)  then

            !Testar o tempo a ver se e agora que se assimila
            !Se for entao assimilar (nudge)
            if (Me%CurrentTime .ge. Me%ComputeOptions%AltimetryAssimilation%NextCompute) then

                !Fetch the analyzed temperature and salinity fields
                call GetAssimilationField(Me%ObjAssimilation,        &
                                          ID              = AltimLevelAnalyzed_,              &
                                          Field2D         = LevelAnalyzed,        &
                                          STAT            = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'AltimAssimilationProcess - ModuleWaterProperties - ERR03'

                !Fetch the DecayTime
                call GetAltimetryDecayTime(Me%ObjAssimilation,                          &               
                                           AltimDecayTime,             &
                                           STAT            = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'AltimAssimilationProcess - ModuleWaterProperties - ERR05'

                ! C(t+dt) = (C(t) + Cref*dt/Tref) / (1 + dt / Tref) -> Implicit
                 
                !nudging temperature     
                do j = JLB, JUB
                do i = ILB, IUB
                    
                    if (Me%External_Var%OpenPoints3D(i, j, KUB) == OpenPoint) then

                        AuxDecay = Me%ComputeOptions%AltimetryAssimilation%DT_Compute       &
                                     / AltimDecayTime

                        Me%WaterLevel%New(i, j) = (Me%WaterLevel%New(i, j) + &
                                                                   LevelAnalyzed(i, j)       * &
                                                                   AuxDecay) / (1. + AuxDecay)
                    endif
                                  

                enddo
                enddo 
                       
                Me%ComputeOptions%AltimetryAssimilation%NextCompute =                        &
                        Me%ComputeOptions%AltimetryAssimilation%NextCompute  +                   &
                        Me%ComputeOptions%AltimetryAssimilation%DT_Compute

                !Unfetch the analyzed temperature and salinity fields
                call UnGetAssimilation(Me%ObjAssimilation, LevelAnalyzed, STAT = STAT_CALL) 
                if (STAT_CALL /= SUCCESS_)                                                  &
                    stop 'AltimAssimilationProcess - ModuleWaterProperties - ERR10' 

            endif

        else cd2

           !Here we fetch the altimetry DT and initialize the nextcompute time            
           call GetAssimilationAltimetryDT(Me%ObjAssimilation, Me%ComputeOptions%AltimetryAssimilation%DT_Compute, STAT_CALL)
           if (STAT_CALL == SUCCESS_) then

                Me%ComputeOptions%AltimetryAssimilation%NextCompute  =                              &
                            Me%CurrentTime                & 
                            + Me%ComputeOptions%AltimetryAssimilation%DT_Compute

                Me%ComputeOptions%AltimetryAssimilation%flag = .true.

            end if
        
        end if cd2

        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "WaterLevelRelaxationAltimetry")

    End Subroutine WaterLevelRelaxationAltimetry        
    !----------------------------------------------------------------

    !----------------------------------------------------------------
    Subroutine calc_depth_and_Hro (Hcenter, Hleft, Hright, HroLeft, HroRight,           &
                                   DensRight, DensLeft, DWZ, SZZ, DUZ_VZ, SigmaDens,           &
                                   i, j, ileft, jleft, KUB, kbottom)

        

        !Arguments
        Integer,  intent(in )              :: i, j, ileft, jleft, KUB, kbottom
        
        Real(8), pointer,  dimension ( : ) :: Hleft, Hright, Hcenter, HroLeft, HroRight, DensRight, DensLeft
        Real, pointer, dimension(:, :, :)  :: DWZ, DUZ_VZ, SigmaDens, SZZ

        !Local variable
        Integer     :: k


        !Begin---------------------------------------------------------------------



        if (Me%ComputeOptions%BaroclinicMethod == Leibniz .or. Me%ComputeOptions%BaroclinicMethod == Leibniz2) then

            Hcenter (KUB+1) = null_real           
            Hcenter (KUB  ) = (dble(SZZ (i, j, KUB)) + dble(SZZ (ileft, jleft, KUB))) / 2. + dble(DUZ_VZ( i, j, KUB) / 2.) 

            do k = KUB-1 , kbottom, -1
                Hcenter(k)  = Hcenter(k+1) + dble(DUZ_VZ( i, j, k+1) / 2.) + dble(DUZ_VZ( i, j, k) / 2.) 
            enddo
 
        else

            Hcenter (KUB+1) = 0           
            Hcenter (KUB  ) = dble(DUZ_VZ( i, j, KUB) / 2.) 

            do k = KUB-1 , kbottom, -1
                Hcenter(k)  = Hcenter(k+1) + dble(DUZ_VZ( i, j, k+1) / 2.) + dble(DUZ_VZ( i, j, k) / 2.) 
            enddo

            Hright  (KUB+1) = 0.0 !rcm 9
            Hleft   (KUB+1) = 0.0

            do k = KUB , kbottom, -1
               Hright  (k) = Hright  (k + 1) + dble(DWZ ( i, j, k))
               Hleft   (k) = Hleft   (k + 1) + dble(DWZ (ileft, jleft, k))
            enddo


            HroRight(KUB+1) = 0.0
            Hroleft (KUB+1) = 0.0


            if      (Me%ComputeOptions%BaroclinicMethod == DensityUniform) then

               
                do k = KUB , kbottom, -1
                   HroRight(k) = HroRight(k + 1) + dble(SigmaDens(i    ,j    ,k)) * dble(DWZ (    i,    j,  k))
                   Hroleft (k) = Hroleft (k + 1) + dble(SigmaDens(ileft,jleft,k)) * dble(DWZ (ileft, jleft, k))
                enddo                       

        
            else if (Me%ComputeOptions%BaroclinicMethod == DensityLinear) then

                DensRight(KUB+1)   = dble(SigmaDens(i    ,j    ,KUB    ))
                DensLeft (KUB+1)   = dble(SigmaDens(ileft,jleft,KUB    ))

                DensRight(kbottom) = dble(SigmaDens(i    ,j    ,kbottom))
                DensLeft (kbottom) = dble(SigmaDens(ileft,jleft,kbottom))

                do k = kbottom+1, KUB
                   DensRight(k) = (dble(SigmaDens(i    ,j    ,k  )) * dble(DWZ (    i,    j,  k-1)) +  &
                                   dble(SigmaDens(i    ,j    ,k-1)) * dble(DWZ (    i,    j,  k  ))) / &
                                  (dble(DWZ    (i    ,j    ,k-1)) + dble(DWZ (    i,    j,  k  )))
               
                   DensLeft (k) = (dble(SigmaDens(ileft,jleft,k  )) * dble(DWZ (ileft,jleft,  k-1)) +  &
                                   dble(SigmaDens(ileft,jleft,k-1)) * dble(DWZ (ileft,jleft,  k  ))) / &
                                  (dble(DWZ    (ileft,jleft,k-1)) + dble(DWZ (ileft,jleft,  k  )))
                enddo      

                 DensRight(kbottom : KUB+1) =  DensRight(kbottom : KUB+1)
                 DensLeft (kbottom : KUB+1) =  DensLeft (kbottom : KUB+1)

                do k = KUB , kbottom, -1
                   HroRight(k) = HroRight(k + 1) + (DensRight(k+1) + DensRight(k)) / 2. * dble(DWZ (    i,    j,  k))
                   Hroleft (k) = Hroleft (k + 1) + (DensLeft (k+1) + DensLeft (k)) / 2. * dble(DWZ (ileft, jleft, k))
                enddo   
            
            endif

        endif




    End subroutine calc_depth_and_Hro

    !-------------------------------------------------

    subroutine Calc_Depth_integration(Hcenter, Hleft, Hright,  &
                                      Kleft, Kright, Depth_integ, KUB, kbottom)

        

        ! External variables

        Integer, intent(in )             :: KUB, kbottom
        Real(8), pointer, dimension( : ) :: Hleft, Hright, Hcenter
        Integer, pointer, dimension( : ) :: kleft, kright

        Real(8), pointer, dimension( : ) :: Depth_integ
        ! Internal

        Integer  :: k    

        !------------------------------------------------------------------------

!        Depth_integ = 0 !rcm 10
!        kleft       = 0
!        kright      = 0

dok:     do k=KUB,kbottom,-1

          kleft (k) = Locate_Layer(KUB, kbottom, Hcenter(k), Hleft )
          kright(k) = Locate_Layer(KUB, kbottom, Hcenter(k), Hright)

          Depth_integ(k)= min(Hcenter(k), Hleft(kleft (k)), Hright(kright(k)) )

          kleft (k) = Locate_Layer (KUB, kbottom, Depth_integ(k), Hleft )
          kright(k) = Locate_Layer (KUB, kbottom, Depth_integ(k), Hright)

        enddo dok

    end subroutine Calc_Depth_integration

    !--------------------------------------------------------------------

    function Locate_Layer (KUB, kbottom, Zpoint, Zside)
    Integer  :: Locate_Layer

        ! External variables

        Integer,   intent(in )                       :: KUB, kbottom
        Real(8),   pointer, dimension(:)             :: Zside
        Real(8), intent(in)                          :: Zpoint
        ! Internal 
        Integer                   :: k_Locate_Layer

        k_Locate_Layer = KUB

        Do While ( (Zside(k_Locate_Layer) < Zpoint) .and. (k_Locate_Layer > kbottom) )
            k_Locate_Layer = k_Locate_Layer -1
        Enddo 

        Locate_Layer=k_Locate_Layer

    end function Locate_Layer

    !--------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! Compute the vertical water flow                                                      !
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping                                                      !
    ! OutPut: Water Flow                                                                   !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Modify_VerticalWaterFlow( Grid)

        !Variables Categories  
            !Geometry  : Volume_Z_New, Volume_Z_Old
            !Flow      : WaterFlux_X, WaterFlux_Y, WaterFlux_Z
            !Mapping   : ComputeFaces3D_U, ComputeFaces3D_V
 
        !Arguments------------------------------------------------------------

        integer                            :: Grid

        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Volume_Z_New, Volume_Z_Old, WaterFlux_X,   &
                                              WaterFlux_Y, WaterFlux_Z, DischargeFlow,   &
                                              qX, qY

        real,    dimension(:,:)  , pointer :: DXX, DYY

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_U, ComputeFaces3D_V,        &
                                              WaterPoints3D,                             &
                                              ImposedNormalFacesU, ImposedNormalFacesV,  &
                                              ImposedTangentialFacesU,                   &
                                              ImposedTangentialFacesV

        integer, dimension(:,:  ), pointer :: BoundaryPoints

!        real                               :: DT_Elevation, Evolution
        real                               :: Evolution, DT
        real(8)                            :: dVdt, Discharge,                           &
                                              WestFlux, EastFlux, SouthFlux, NorthFlux

        logical                            :: DischargesON
    
        integer                            :: I, J, K, IUB, ILB, JUB, JLB, KUB, KLB
        integer                            :: STAT_CALL

                                    

        !Begin--------------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

!        DT_Elevation = Me%WaterLevel%DT
        call GetComputeTimeStep(Me%ObjTime, DT, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Modify_VerticalWaterFlow - ModuleHydrodynamic - ERR00.'


        Volume_Z_New      => Me%External_Var%Volume_Z_New
        Volume_Z_Old      => Me%External_Var%Volume_Z_Old

        ComputeFaces3D_U  => Me%External_Var%ComputeFaces3D_U
        ComputeFaces3D_V  => Me%External_Var%ComputeFaces3D_V
        WaterPoints3D     => Me%External_Var%WaterPoints3D

        WaterFlux_X       => Me%WaterFluxes%X
        WaterFlux_Y       => Me%WaterFluxes%Y
        WaterFlux_Z       => Me%WaterFluxes%Z
        DischargeFlow     => Me%WaterFluxes%Discharges

        ImposedNormalFacesU      => Me%External_Var%ImposedNormalFacesU
        ImposedTangentialFacesU  => Me%External_Var%ImposedTangentialFacesU
        ImposedNormalFacesV      => Me%External_Var%ImposedNormalFacesV
        ImposedTangentialFacesV  => Me%External_Var%ImposedTangentialFacesV
        BoundaryPoints           => Me%External_Var%BoundaryPoints 
        DYY                      => Me%External_Var%DYY
        DXX                      => Me%External_Var%DXX
        qX                       => Me%SubModel%qX
        qY                       => Me%SubModel%qY


        !End - Shorten variables name 



        !Compute volume variation if the grid is not fixed
        if (Grid == Variable) then 

            Evolution = 1.

        else if (Grid == Fix) then 

            Evolution = 0.

        else 

            stop 'Subroutine Modify_VerticalWaterFlow; Module ModuleHydrodynamic. ERR01'

        endif

        DischargesON = .false.

        Discharge    = 0.

        if (associated(DischargeFlow)) then

            DischargesON = .true.

        endif


        !Fluxes divergence
        dok3: do k = KLB, KUB
        doj3: do j = JLB, JUB
        doi3: do i = ILB, IUB
!            dVdt =  dble(Evolution) * (Volume_Z_New(i, j, k) - Volume_Z_Old(i, j, k)) / &
!                    dble(DT_Elevation )
            dVdt =  dble(Evolution) * (Volume_Z_New(i, j, k) - Volume_Z_Old(i, j, k)) / &
                    dble(DT)
                    !E preciso alterar esta parte para que se possa calcular fluxos verticais independentemente
                    !de como sao calculados os fluxos horizontais

            if (DischargesON) Discharge = DischargeFlow (i    , j    , k)


            WaterFlux_Z(i, j, k + 1) = WaterFlux_Z          (i    , j    , k)     +      &  !Bottom Face
                                       WaterFlux_X          (i    , j    , k)     *      &
                                       dble(ComputeFaces3D_U(i    , j    , k))    -      &  !West Face
                                       WaterFlux_X          (i    , j + 1, k)     *      &
                                       dble(ComputeFaces3D_U(i    , j + 1, k))    +      &  !East Face   
                                       WaterFlux_Y          (i    , j    , k)     *      &
                                       dble(ComputeFaces3D_V(i    , j    , k))    -      &  !South Face
                                       WaterFlux_Y          (i + 1, j    , k)     *      &
                                       dble(ComputeFaces3D_V(i + 1, j    , k))    +      &  !North Face
                                       Discharge                                  *      &  
                                       dble(WaterPoints3D   (i    , j    , k))    -      &  !Discharges contribution
                                       dVdt

        enddo doi3
        enddo doj3
        enddo dok3

cd5:    if (Me%SubModel%ON) then

            !Fluxes divergence
            doj4: do j = JLB, JUB
            doi4: do i = ILB, IUB
                                
                                                
cd4:            if (BoundaryPoints(i, j) == Boundary) then

                    dok4: do k = KLB, KUB
                                
                            dVdt =  dble(Evolution) * (Volume_Z_New(i, j, k) - Volume_Z_Old(i, j, k)) / &
                                dble(DT)

                            if (DischargesON) Discharge = DischargeFlow (i    , j    , k)


                            !West Face
                            WestFlux = WaterFlux_X(i, j, k) * dble(ComputeFaces3D_U(i, j, k)) + &
                                       qX         (i, j, k) * dble(DYY             (i, j   )) * &
                                       (dble(ImposedNormalFacesU    (i,   j, k))              + &
                                        dble(ImposedTangentialFacesU(i,   j, k)))

                            !East Face
                            EastFlux = WaterFlux_X(i, j+1, k) * dble(ComputeFaces3D_U(i, j+1, k)) + &
                                       qX         (i, j+1, k) * dble(DYY             (i, j+1))    * &
                                       (dble(ImposedNormalFacesU    (i, j+1, k))                  + &
                                        dble(ImposedTangentialFacesU(i, j+1, k)))



                            !South Face
                            SouthFlux = WaterFlux_Y(i, j, k) * dble(ComputeFaces3D_V (i, j, k)) + &
                                        qY         (i, j, k) * dble(DXX              (i, j))    * &
                                       (dble(ImposedNormalFacesV    (i  , j, k))                + &
                                        dble(ImposedTangentialFacesV(i  , j, k)))


                            !North Face
                            NorthFlux = WaterFlux_Y(i+1, j, k) * dble(ComputeFaces3D_V (i+1, j, k)) + &
                                        qY         (i+1, j, k) * dble(DXX              (i+1, j))    * &
                                       (dble(ImposedNormalFacesV    (i+1, j, k))                    + &
                                        dble(ImposedTangentialFacesV(i+1, j, k)))



                            WaterFlux_Z(i, j, k + 1) = WaterFlux_Z          (i    , j    , k)      + &  !Bottom Face
                                                       WestFlux - EastFlux + SouthFlux - NorthFlux + &  
                                                       Discharge                                   * &  
                                                       dble(WaterPoints3D   (i    , j    , k))     - &  !Discharges contribution
                                                       dVdt

                        enddo dok4
                    endif cd4
        
            enddo doi4
            enddo doj4
        

        endif cd5




        !Nullify auxiliar pointers 
        nullify(Volume_Z_New)
        nullify(Volume_Z_Old)

        nullify(ComputeFaces3D_U)
        nullify(ComputeFaces3D_V)
        nullify(WaterPoints3D   )

        nullify(WaterFlux_X)
        nullify(WaterFlux_Y)
        nullify(WaterFlux_Z)
        nullify(DischargeFlow)

        nullify(ImposedNormalFacesU    )
        nullify(ImposedTangentialFacesU)
        nullify(ImposedNormalFacesV    )
        nullify(ImposedTangentialFacesV)
        nullify(BoundaryPoints         )
        nullify(DYY                    )
        nullify(DXX                    )
        nullify(qX                     )
        nullify(qY                     )



    end Subroutine Modify_VerticalWaterFlow

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! Filter the vertical and horizontal Fluxes                                            !
    !                                                                                      !
    ! Input : Flow, Mapping                                                                !
    ! OutPut: Water Flow                                                                   !
    ! Author: Paulo Chambel (99/6)                                                         !
    ! Main Objective: To imposed vertical flux null at the Z boundary points               !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Filter_3D_Fluxes 
    

        !Variables Categories  
            !Flow      : WaterFlux_Z
            !Mapping   : BoundaryPoints
         
        !Arguments------------------------------------------------------------


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_Z
        integer, dimension(:,:),   pointer :: BoundaryPoints
                                                
        integer                            :: I, J, K, IUB, ILB, JUB, JLB, KUB, KLB

        !Begin--------------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        BoundaryPoints  => Me%External_Var%BoundaryPoints
        WaterFlux_Z     => Me%WaterFluxes%Z

        !End - Shorten variables name 
 
        dok: do k = KLB, KUB 
        doj: do j = JLB, JUB
        doi: do i = ILB, IUB
            !Vertical flux null at the open boundary points
            WaterFlux_Z(i, j, k + 1) = WaterFlux_Z(i, j, k + 1) *    &
                                       (1. - BoundaryPoints(i, j))
        enddo doi
        enddo doj
        enddo dok


        !Nullify auxiliar pointers 
        nullify(WaterFlux_Z)
        nullify(BoundaryPoints)

 
    end Subroutine Filter_3D_Fluxes

    !------------------------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! Defines a boundary condition for the vertical water fluxes in the boundary
    !                                                                                      !
    ! Input : Flow, Mapping                                                                !
    ! OutPut: Water Flow                                                                   !
    ! Author: Paulo Chambel (2001/6)                                                       !
    ! Main Objective: To imposed radiation boundary condition in the baroclinic            !
    !                 component of the vertical flux at the Z boundary points              !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Boundary_VerticalFlow ( Grid)

        !Arguments------------------------------------------------------------

        integer                            :: Grid

        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_X, WaterFlux_Y
        real   , dimension(:,:  ), pointer :: DZX, DZY

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_U, ComputeFaces3D_V
        integer, dimension(:,:  ), pointer :: BoundaryFacesU, BoundaryFacesV, BoundaryPoints
   
        integer                            :: I, J, IUB, ILB, JUB, JLB, KUB

        !Begin--------------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB

        DZX               => Me%External_Var%DZX
        DZY               => Me%External_Var%DZY

        BoundaryFacesU    => Me%External_Var%BoundaryFacesU
        BoundaryFacesV    => Me%External_Var%BoundaryFacesV
        BoundaryPoints    => Me%External_Var%BoundaryPoints 

        ComputeFaces3D_U  => Me%External_Var%ComputeFaces3D_U
        ComputeFaces3D_V  => Me%External_Var%ComputeFaces3D_V

        WaterFlux_X       => Me%WaterFluxes%X
        WaterFlux_Y       => Me%WaterFluxes%Y

        !End - Shorten variables name 


        if (.not. Me%ComputeOptions%BaroclinicRadia == NoRadiation_)        &
            call ComputeBaroclinicVertVelocity( Grid)

         
   do1: do j = JLB, JUB
   do2: do i = ILB, IUB

            if (BoundaryFacesU(i, j) == Boundary .and. ComputeFaces3D_U(i, j, KUB) == Covered) then


                if (BoundaryPoints(i, j) == Boundary) then

                    call Compute_BoundaryVertFlux( WaterFlux_XY = WaterFlux_X,  &
                                                  WaterFlux_YX = WaterFlux_Y,                   &
                                                  i = i, j = j, di = 0, dj = 1, db = 1) 


                else

                    call Compute_BoundaryVertFlux( WaterFlux_XY = WaterFlux_X,  &
                                                  WaterFlux_YX = WaterFlux_Y,                   &
                                                  i = i, j = j, di = 0, dj = 1, db = 0) 
                endif



            endif

        enddo do2
        enddo do1


do3:    do j = JLB, JUB
do4:    do i = ILB, IUB

            if (BoundaryFacesV(i, j) == Boundary .and. ComputeFaces3D_V(i, j, KUB) == Covered) then

                if (BoundaryPoints(i, j) == Boundary) then

                    call Compute_BoundaryVertFlux( WaterFlux_XY = WaterFlux_Y, &
                                                  WaterFlux_YX = WaterFlux_X,                  &
                                                  i = i, j = j, di = 1, dj = 0, db = 1)               
                else

                    call Compute_BoundaryVertFlux( WaterFlux_XY = WaterFlux_Y, &
                                                  WaterFlux_YX = WaterFlux_X,                  &
                                                  i = i, j = j, di = 1, dj = 0, db = 0) 

                endif
                

            endif

        enddo do4
        enddo do3



        !Nullify auxiliar pointers 
        nullify(DZX , DZY       )
        nullify(ComputeFaces3D_U)
        nullify(ComputeFaces3D_V)
        nullify(BoundaryFacesU  )
        nullify(BoundaryFacesV  )
        nullify(BoundaryPoints  )

        nullify(WaterFlux_X     )
        nullify(WaterFlux_Y     )

    end Subroutine Boundary_VerticalFlow

    !------------------------------------------------------------------------------

    !------------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! Defines a boundary condition for the vertical water fluxes in the boundary
    !                                                                                      !
    ! Input : Flow, Mapping                                                                !
    ! OutPut: Water Flow                                                                   !
    ! Author: Paulo Chambel (2001/6)                                                       !
    ! Main Objective: To imposed radiation boundary condition in the baroclinic            !
    !                 component of the vertical flux at the Z boundary points              !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Compute_BoundaryVertFlux ( WaterFlux_XY, WaterFlux_YX,    &
                                         i, j, di, dj, db) 

        !Arguments------------------------------------------------------------

        real(8), dimension(:,:,:), pointer :: WaterFlux_XY, WaterFlux_YX
        integer                            :: i, j, di, dj, db

        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_Z
        real   , dimension(:,:,:), pointer :: Velocity_Z, Vel_Z_Cartesian,               &
                                              Vel_Z_Baroclinic, SZZ, Density,            &
                                              Vel_Z_BaroclinicOld
        real   , dimension(:,:  ), pointer :: WaterLevel_New, WaterLevel_Old, DUX, DVY
        integer, dimension(:,:,:), pointer :: ComputeFaces3D_W
        integer, dimension(:,:  ), pointer :: KFloor_Z

        real                               :: Vel_Z_BoundBarot,                          &
                                              Vel_Z_B_BarocUp,  Vel_Z_B_BarocLow
        real                               :: DT_Elevation
        real(8)                            :: BarotBoundFlux, BarocBoundFlux,            &
                                              DivBarocFlux, dz
   
        integer                            :: ib, jb, i_int, j_int, K, KUB, i_int2, j_int2, i_ext, j_ext
        integer                            :: i_Tang1, j_Tang1, i_Tang2, j_Tang2
        integer                            :: kbottom

        !Begin--------------------------------------------------------------------------


        !Begin - Shorten variables name 
        KUB = Me%WorkSize%KUB


        DT_Elevation        =  Me%WaterLevel%DT

        DUX                 => Me%External_Var%DUX
        DVY                 => Me%External_Var%DVY

        KFloor_Z            => Me%External_Var%KFloor_Z
        SZZ                 => Me%External_Var%SZZ

        Density             => Me%External_Var%Density
        ComputeFaces3D_W    => Me%External_Var%ComputeFaces3D_W

        Velocity_Z          => Me%Velocity%Vertical%Across
        Vel_Z_Cartesian     => Me%Velocity%Vertical%Cartesian
        Vel_Z_Baroclinic    => Me%VelBaroclinic%W_New
        Vel_Z_BaroclinicOld => Me%VelBaroclinic%W_Old

        WaterFlux_Z         => Me%WaterFluxes%Z
        WaterLevel_New      => Me%WaterLevel%New
        WaterLevel_Old      => Me%WaterLevel%Old


        !End - Shorten variables name 


        ib    = i - di * (1- db)
        jb    = j - dj * (1- db)

        i_int = i - di * db
        j_int = j - dj * db

        i_int2 = i - di * (3 * db - 1)
        j_int2 = j - dj * (3 * db - 1)

        i_ext  = i + di * (2 * db - 1)
        j_ext  = j + dj * (2 * db - 1)

        i_tang1  = i_ext * (1 - db) + i     * db  
        j_tang1  = j_ext * (1 - db) + j     * db  

        i_tang2  = i + di * (db - 1) + dj
        j_tang2  = j + dj * (db - 1) + di

        kbottom = KFloor_Z(ib, jb)

        BarotBoundFlux = 0.

dok1:   do k = kbottom, KUB


            !Compute the vertical velocity induced by the 
            !water level variation barotropic. 
            !To this vertical velocity is called 
            !vertical barotropic velocity
            BarotBoundFlux = BarotBoundFlux + WaterFlux_XY(i, j, k) 

        enddo dok1

        Vel_Z_B_BarocLow = 0.


dok2:   do k = kbottom + 1, KUB + 1

            ![m/s]           = ([m] - [m]) / [s] * [m] / [m]
            Vel_Z_BoundBarot =  (WaterLevel_New(ib, jb) -  WaterLevel_Old(ib, jb)) / &
                                 DT_Elevation                                      * &
                                (SZZ(ib, jb, kbottom - 1) - SZZ(ib, jb, k - 1))   /  &
                                (SZZ(ib, jb, kbottom - 1) - SZZ(ib, jb, KUB)) 

cd1:        if (Me%ComputeOptions%BaroclinicRadia == Horizontal_) then 

                ![]= [m] / [m]
                dz = dble(SZZ(ib, jb, k - 2) - SZZ(ib, jb, k - 1))    /              &
                     dble(SZZ(ib, jb, kbottom - 1) - SZZ(ib, jb, KUB)) 

            

                ![m^3/s]       = [m^3/s] - [m^3/s] * []
                BarocBoundFlux = WaterFlux_XY(i, j, k - 1) - BarotBoundFlux * dz

                DivBarocFlux   = (2*db - 1) * (BarocBoundFlux - WaterFlux_XY(i_ext, j_ext, k - 1))

                !PCL
                DivBarocFlux   = DivBarocFlux + WaterFlux_YX(i_Tang1, j_Tang1, k - 1) - WaterFlux_YX(i_Tang2, j_Tang2, k - 1)

                Vel_Z_B_BarocUp  = DivBarocFlux / DUX(ib, jb) / DVY(ib, jb) + Vel_Z_B_BarocLow

                Vel_Z_B_BarocLow = Vel_Z_B_BarocUp

            else

                Vel_Z_B_BarocUp = 0.

            endif cd1 


            !Compute the vertical velocity relatively to the grid
            !When the cartesian velocity is compute in the routine "ComputeCartesianVelocity"
            !the across grid velocity in the boundary points is consider zero so the 
            !Vel_Z_Cartesian(ib, jb, k) only consider the mesh velocity in the boundary points

            !Vel_Z_Cartesian(ib, jb, k) - is temporarlly the grid velocity in the boundary points


            !Across Velocity           = (cartesian = barotropic + baroclinic) - Grid velocity
            Velocity_Z(ib, jb, k)      = Vel_Z_BoundBarot + Vel_Z_B_BarocUp - Vel_Z_Cartesian(ib, jb, k)

            !In this way the cartesian velocity is computed in a realistic way in the boundary points
            Vel_Z_Cartesian(ib, jb, k) = Vel_Z_BoundBarot + Vel_Z_B_BarocUp

            !The water flux across grid is also compute for the boundary points
            WaterFlux_Z(ib, jb, k)     = Velocity_Z(ib, jb, k) * DUX(ib, jb) * DVY(ib, jb)



        enddo dok2


        !Nullify auxiliar pointers 
        nullify(DUX, DVY           )
        nullify(KFloor_Z           )
        nullify(ComputeFaces3D_W   )
        nullify(SZZ                )
        nullify(Density            )
        nullify(Velocity_Z         )
        nullify(Vel_Z_Cartesian    )
        nullify(Vel_Z_Baroclinic   )
        nullify(Vel_Z_BaroclinicOld)

        nullify(WaterFlux_Z        )
        nullify(WaterLevel_New     )
        nullify(WaterLevel_Old     )
 
    end Subroutine Compute_BoundaryVertFlux

    !------------------------------------------------------------------------------

    !--------------------------------------------------------------------------

    Subroutine ComputeCartesianVertVelocity(Grid, MeshSlope)

        !Arguments-------------------------------------------------------------
        integer, optional                   :: Grid                             
        logical, optional                   :: MeshSlope

        !Local-----------------------------------------------------------------
        real(8), dimension(:,:,:), pointer  :: Volz_old, Volum_z
        real,    dimension(:,:,:), pointer  :: Velocity_W_Cartesian, Velocity_W_Across,  &
                                               uavar, vavar           
        real   , dimension(:,:  ), pointer  :: WaterLevel_New, WaterLevel_Old
        integer, dimension(:,:,:), pointer  :: ComputeFaces3D_U, ComputeFaces3D_V,       &
                                               ComputeFaces3D_W, WaterPoints3D

        integer, dimension(:,:  ), pointer  :: BoundaryPoints

        real                                :: velusup, veluinf, velu, velvsup, velvinf, velv, &
                                               dt, dszdt, szzxp1, dzxp1, szzxm1, dzxm1, dszdx, &
                                               szzyp1, dzyp1, szzym1, dzym1, dszdy

        integer                             :: IUB,ILB,JUB,JLB,KUB,KLB, i, j, k

        real,    dimension(:,:  ), pointer  :: dzx, dzy, dux, dvy
        real,    dimension(:,:,:), pointer  :: dwz, szz

        logical                             :: MeshVelocity_, MeshSlope_

        !Begin-----------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        Velocity_W_Cartesian    => Me%Velocity%Vertical%Cartesian
        Velocity_W_Across       => Me%Velocity%Vertical%Across
        uavar                   => Me%Velocity%Horizontal%U%New
        vavar                   => Me%Velocity%Horizontal%V%New
        dt                      =  Me%Waterlevel%DT
        ComputeFaces3D_U        => Me%External_Var%ComputeFaces3D_U
        ComputeFaces3D_V        => Me%External_Var%ComputeFaces3D_V
        ComputeFaces3D_W        => Me%External_Var%ComputeFaces3D_W
        WaterPoints3D           => Me%External_Var%WaterPoints3D
        BoundaryPoints          => Me%External_Var%BoundaryPoints
        Volz_old                => Me%External_Var%Volume_Z_Old
        Volum_z                 => Me%External_Var%Volume_Z_New
        dzx                     => Me%External_Var%DZX
        dzy                     => Me%External_Var%DZY
        dux                     => Me%External_Var%DUX
        dvy                     => Me%External_Var%DVY
        dwz                     => Me%External_Var%DWZ
        szz                     => Me%External_Var%SZZ

                               
        WaterLevel_New          => Me%WaterLevel%New
        WaterLevel_Old          => Me%WaterLevel%Old        

        ! ciclo a todos os pontos interiores

        dszdt = 0.
        velu  = 0.
        dszdx = 0.
        velv  = 0.
        dszdy = 0.


        if (Present(Grid)) then

            if      (Grid == Variable) then 

                MeshVelocity_ = .true.

            else if (Grid == Fix     ) then

                MeshVelocity_ = .false.

            endif

        else

            MeshVelocity_ = .true.

        endif

        if (Present(MeshSlope)) then

            MeshSlope_ = MeshSlope

        else

            MeshSlope_ = .true.

        endif


do1:    do i = ILB, IUB
do2:    do j = JLB, JUB
            dszdt=0.0

            if (WaterPoints3D(i, j, KUB) == WaterPoint) then

                Velocity_W_Cartesian(i,j,KUB+1)= (WaterLevel_New(i,j)-WaterLevel_Old(i,j)) / dt

            endif

do3:        do k = KLB, KUB
                            
cd1:            if (ComputeFaces3D_W(i,j,k) == Covered ) then

                    ! mesh velocity
                    if (MeshVelocity_)                                                   &
                        dszdt  = dszdt-(volum_z(i,j,k-1)-volz_old(i,j,k-1))/dux(i,j)/dvy(i,j)/dt


cd2:                if (MeshSlope_ .and. BoundaryPoints(i, j) /= Boundary) then
                        ! mesh slope in X direction: central, progressive or regressive differences are used as a function of the
                        ! land boundary. The boundary is automatically detected in the equation through "ComputeFaces3D_W" matrix
                        szzxp1 = ComputeFaces3D_W(i,j+1,k)*szz(i,j+1,k-1)+(1-ComputeFaces3D_W(i,j+1,k))*szz(i,j,k-1)
                        dzxp1  = ComputeFaces3D_W(i,j+1,k)*dzx(i,j)
                        szzxm1 = ComputeFaces3D_W(i,j-1,k)*szz(i,j-1,k-1)+(1-ComputeFaces3D_W(i,j-1,k))*szz(i,j,k-1)
                        dzxm1  = ComputeFaces3D_W(i,j-1,k)*dzx(i,j-1)
                        if ((dzxp1+dzxm1) /= 0) then
                          dszdx=(szzxp1-szzxm1)/(dzxp1+dzxm1)
                        else
                          dszdx=0.0
                        endif

                        ! mesh slope in Y direction: central, progressive or regressive differences are used as a function of the
                        ! land boundary. The boundary is automatically detected in the equation through "ComputeFaces3D_W" matrix
                        szzyp1 = ComputeFaces3D_W(i+1,j,k)*szz(i+1,j,k-1)+(1-ComputeFaces3D_W(i+1,j,k))*szz(i,j,k-1)
                        dzyp1  = ComputeFaces3D_W(i+1,j,k)*dzy(i,j)
                        szzym1 = ComputeFaces3D_W(i-1,j,k)*szz(i-1,j,k-1)+(1-ComputeFaces3D_W(i-1,j,k))*szz(i,j,k-1)
                        dzym1  = ComputeFaces3D_W(i-1,j,k)*dzy(i-1,j)
                        if ((dzyp1+dzym1) /= 0) then
                          dszdy=(szzyp1-szzym1)/(dzyp1+dzym1)
                        else
                          dszdy=0.0
                        endif

                        ! Velocity components at cell center
                        if ((ComputeFaces3D_U(i,j,k)+ComputeFaces3D_U(i,j+1,k)) /=0) then
                            velusup=(ComputeFaces3D_U(i,j,k)*uavar(i,j,k)+ComputeFaces3D_U(i,j+1,k)*uavar(i,j+1,k))/ &
                                    (ComputeFaces3D_U(i,j,k)+ComputeFaces3D_U(i,j+1,k))
                        else
                            velusup=0.0
                        endif
                        if ((ComputeFaces3D_U(i,j,k-1)+ComputeFaces3D_U(i,j+1,k-1)) /=0) then
                            veluinf=(ComputeFaces3D_U(i,j,k-1)*uavar(i,j,k-1)+ComputeFaces3D_U(i,j+1,k-1)*uavar(i,j+1,k-1))/ &
                                    (ComputeFaces3D_U(i,j,k-1)+ComputeFaces3D_U(i,j+1,k-1))
                        else
                            veluinf=0.0
                        endif
                        velu=(velusup*dwz(i,j,k-1)+veluinf*dwz(i,j,k))/(dwz(i,j,k-1)+dwz(i,j,k))

                        if ((ComputeFaces3D_V(i,j,k)+ComputeFaces3D_V(i+1,j,k)) /=0) then
                            velvsup=(ComputeFaces3D_V(i,j,k)*vavar(i,j,k)+ComputeFaces3D_V(i+1,j,k)*vavar(i+1,j,k))/ &
                                    (ComputeFaces3D_V(i,j,k)+ComputeFaces3D_V(i+1,j,k))
                        else
                            velvsup=0.0
                        endif
                        if ((ComputeFaces3D_V(i,j,k-1)+ComputeFaces3D_V(i+1,j,k-1)) /=0) then
                            velvinf=(ComputeFaces3D_V(i,j,k-1)*vavar(i,j,k-1)+ComputeFaces3D_V(i+1,j,k-1)*vavar(i+1,j,k-1))/ &
                                    (ComputeFaces3D_V(i,j,k-1)+ComputeFaces3D_V(i+1,j,k-1))
                        else
                            velvinf=0.0
                        endif
                    
                        velv=(velvsup*dwz(i,j,k-1)+velvinf*dwz(i,j,k))/(dwz(i,j,k-1)+dwz(i,j,k))

                    else  cd2

                          dszdx=0.0
                          dszdy=0.0

                    endif cd2

                    !Cartesian vertical velocity
                    Velocity_W_Cartesian(i,j,k)=Velocity_W_Across(i,j,k) - dszdt - velu * dszdx - velv * dszdy

                endif cd1
            enddo do3
            
        enddo do2
        enddo do1


        if (Me%CyclicBoundary%ON) then
        
            call CyclicBoundVertical (Vector = Velocity_W_Cartesian)

        endif
  

        !nulify auxiliar variables
        nullify(Velocity_W_Cartesian, Velocity_W_Across, uavar, vavar, ComputeFaces3D_U, ComputeFaces3D_V, &
                ComputeFaces3D_W, Volz_old, Volum_z, dzx, dzy, dux, dvy, dwz, szz, WaterPoints3D)

        nullify(WaterLevel_New, WaterLevel_Old)

        nullify(BoundaryPoints)

    !----------------------------------------------------------------------

    End Subroutine ComputeCartesianVertVelocity



    !--------------------------------------------------------------------------

    Subroutine ComputeBaroclinicVertVelocity( Grid)

        !Arguments------------------------------------------------------------

        integer                            :: Grid

        !Local---------------------------------------------------------------------
        real   , dimension(:,:,:), pointer :: Vel_Z_Cartesian, Vel_Z_Baroclinic, SZZ,    &
                                              Vel_Z_BaroclinicOld
        real   , dimension(:,:  ), pointer :: WaterLevel_New, WaterLevel_Old
        integer, dimension(:,:  ), pointer :: KFloor_Z

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_W
   
        real                               :: DT_Elevation, Vel_Z_Barotropic
        integer                            :: I, J, K, IUB, ILB, JUB, JLB, KUB, kbottom

        !Begin--------------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB

        DT_Elevation         =  Me%WaterLevel%DT

        Vel_Z_Cartesian      => Me%Velocity%Vertical%Cartesian
        Vel_Z_Baroclinic     => Me%VelBaroclinic%W_New
        Vel_Z_BaroclinicOld  => Me%VelBaroclinic%W_Old

        WaterLevel_New       => Me%WaterLevel%New
        WaterLevel_Old       => Me%WaterLevel%Old

        SZZ                  => Me%External_Var%SZZ
        KFloor_Z             => Me%External_Var%KFloor_Z

        ComputeFaces3D_W     => Me%External_Var%ComputeFaces3D_W

        !End - Shorten variables name 

        if (Grid == Fix) then 
            
            Vel_Z_BaroclinicOld(:, :, :)  = Vel_Z_Baroclinic(:, :, :)

        endif


doj:    do j=JLB, JUB
doi:    do i=ILB, IUB        
            
cd1:        if (ComputeFaces3D_W(i, j, KUB) == Covered) then
            
                kbottom = KFloor_Z(i, j)

dok:            do k = kbottom + 1, KUB

                    !Compute the vertical velocity induced by the 
                    !water level variation. 
                    !To this vertical velocity is called 
                    !vertical barotropic velocity
                    Vel_Z_Barotropic =  (WaterLevel_New(i, j) - WaterLevel_Old(i, j)) /  &
                                         DT_Elevation                                 *  &
                                        (SZZ(i, j, kbottom - 1) - SZZ(i, j, k - 1))   /  &
                                        (SZZ(i, j, kbottom - 1) - SZZ(i, j, KUB)) 

       
                    !Compute in all the vertical faces the baroclinic velocity
                    Vel_Z_Baroclinic(i, j, k)  = Vel_Z_Cartesian(i, j, k) - Vel_Z_Barotropic

                enddo dok

            endif cd1

        enddo doi
        enddo doj

        !Nullify auxiliar pointers 
        nullify(KFloor_Z, SZZ      )
        nullify(Vel_Z_Cartesian    )
        nullify(Vel_Z_Baroclinic   )
        nullify(Vel_Z_BaroclinicOld)

        nullify(ComputeFaces3D_W   )
        nullify(WaterLevel_New     )
        nullify(WaterLevel_Old     )


    end Subroutine ComputeBaroclinicVertVelocity

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! Compute the vertical water flow                                                      !
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping                                                      !
    ! OutPut: Water Flow                                                                   !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Compute_VerticalVelocity 
    

        !Variables Categories  
            !Flow      : WaterFlux_Z, Velocity_Z
            !HorizontalGrid : DUX, DVY
         
        !Arguments------------------------------------------------------------


        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: WaterFlux_Z
        real,    dimension(:,:,:), pointer :: Velocity_Z
        real,    dimension(:,:  ), pointer :: DUX, DVY
        integer, dimension(:,:,:), pointer :: WaterPoints3D

        integer                            :: I, J, K, IUB, ILB, JUB, JLB, KUB, KLB


        !Begin--------------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        Velocity_Z    => Me%Velocity%Vertical%Across
        WaterFlux_Z   => Me%WaterFluxes%Z
        DUX           => Me%External_Var%DUX
        DVY           => Me%External_Var%DVY
        WaterPoints3D => Me%External_Var%WaterPoints3D


        dok: do k = KLB, KUB+1
        doj: do j = JLB, JUB
        doi: do i = ILB, IUB

            if (WaterPoints3D(i, j, k - 1) == 1) then

                Velocity_Z(i, j, k)  = WaterFlux_Z(i, j, k)/ DUX(i, j) / DVY(i, j)

            endif

        enddo doi
        enddo doj
        enddo dok

        !Nullify auxiliar pointers 
        nullify(Velocity_Z)
        nullify(WaterFlux_Z)

        nullify(DUX)
        nullify(DVY)
        nullify(WaterPoints3D)

    end Subroutine Compute_VerticalVelocity

    !--------------------------------------------------------------------

    
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the effect of all the explicit forces ( Baroclinic and      !
    !  barotropic water pressure, Coriolis, Atmospheric pressure,                          !
    !  Horizontal transport - covection + diffusion)                                       !
    !  in the velocity evolution                                                           !
    !                                                                                      !
    ! Input : Flow, Geometry, Mapping, Forces                                              !
    ! OutPut: TiCoef_3D                                                                      !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Velocity_ExplicitForces 

    

        !Variables Categories  
            !Geometry  : WaterLevel_New, DUX_VY, DZX_ZY 
            !WaterProp : Density
            !Forces    : Inertial_Aceleration, Horizontal_Transport, ROX3, AtmPressure 
            !Time      : DT_Velocity
            !Mapping   : ComputeFaces3D_UV, KFloor_UV, Direction
            !Equations : TiCoef_3D

         
         !Variables Direction Dependent
            !DUX_VY, DZX_ZY, ComputeFaces3D_UV, KFloor_UV, Direction
        
        !Arguments------------------------------------------------------------



        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Volume_UV, Horizontal_Transport,           &
                                              ECoef_3D

        real,    dimension(:,:,:), pointer :: Density, Inertial_Aceleration,             &
                                              Rox3XY, DCoef_3D, FCoef_3D, TiCoef_3D,     &
                                              Relax_Aceleration, PressureCorrect

        real,    dimension(:,:),   pointer :: DZX_ZY, DUX_VY,                            &
                                              WaterLevel_New, WaterLevel_Old,            &
                                              AtmPressure, TidePotentialLevel

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV, BoundaryFacesUV

        real                               :: DT_Velocity, Alpha

        real                               :: FaceDensity, WaterPressure_Aceleration,          &
                                              AtmosphericPressure_Aceleration,                 &
                                              Barotropic_Aceleration, Baroclinic_Aceleration,  &
                                              Transport_Aceleration, TidePotentialAceleration

        integer                            :: I, J, K, kbottom, di, dj, iSouth, jWest
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !Begin---------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        DT_Velocity = Me%Velocity%DT

        DCoef_3D             => Me%Coef%D3%D
        ECoef_3D             => Me%Coef%D3%E
        FCoef_3D             => Me%Coef%D3%F
        TiCoef_3D            => Me%Coef%D3%Ti

        Rox3XY               => Me%Forces%Rox3XY
        Horizontal_Transport => Me%Forces%Horizontal_Transport
        Inertial_Aceleration => Me%Forces%Inertial_Aceleration
        TidePotentialLevel   => Me%Forces%TidePotentialLevel
        Relax_Aceleration    => Me%Forces%Relax_Aceleration

        WaterLevel_New       => Me%WaterLevel%New
        WaterLevel_Old       => Me%WaterLevel%Old

        PressureCorrect      => Me%NonHydrostatic%PressureCorrect

        Density              => Me%External_Var%Density
        AtmPressure          => Me%External_Var%AtmosphericPressure

        Volume_UV            => Me%External_Var%Volume_UV

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV            => Me%External_Var%KFloor_UV

        BoundaryFacesUV      => Me%External_Var%BoundaryFacesUV

        DZX_ZY               => Me%External_Var%DZX_ZY
        DUX_VY               => Me%External_Var%DUX_VY

        !End - Shorten variables name 


        if (Me%TidePotential%Compute) then
            
            Alpha = Me%TidePotential%Alpha

        else

            Alpha = 1.

        endif


doj:     do j = JLB, JUB
doi:     do i = ILB, IUB

Cov1:       if (ComputeFaces3D_UV(I, J, KUB) == Covered) then

                iSouth     = I - di
                jWest      = J - dj 

                kbottom = KFloor_UV(I, J)

dok:            do  K = kbottom, KUB

                    if (Me%ComputeOptions%LocalDensity) then

                        FaceDensity    = Face_Interpolation(Density(I, J, K),            &
                                                            Density(iSouth, jWest, K), &
                                                            DUX_VY(I, J),                &
                                                            DUX_VY(iSouth, jWest))
                    else

                        FaceDensity    = SigmaDensityReference

                    endif

                    !Aceleration due to barotropic water Pressure 

                    ![m/s^2]                   = [m/s^2] * [m] / [m] 
                    WaterPressure_Aceleration  = Gravity * (WaterLevel_New(iSouth, jWest) - &
                                                 WaterLevel_New(I, J)) /                    &
                                                 DZX_ZY(iSouth, jWest) *                    &
                                                 Me%NonHydrostatic%ThetaUV                                                  

                    WaterPressure_Aceleration  = WaterPressure_Aceleration                + &
                                                 Gravity * (WaterLevel_Old(iSouth, jWest) - &
                                                 WaterLevel_Old(I, J)) /                    &
                                                 DZX_ZY(iSouth, jWest) *                    &
                                                 (1. - Me%NonHydrostatic%ThetaUV)


                    !Deformation "crosta terrestre" - Tide Potential
                    WaterPressure_Aceleration  = Alpha * WaterPressure_Aceleration


                    if (Me%NonHydrostatic%ON) then
                        ![m/s^2]           = [m/s^2]  +     [m^2/s^2] / [m] 
                        WaterPressure_Aceleration = WaterPressure_Aceleration +            &
                                             (1. - Me%NonHydrostatic%ThetaUV) *            &
                                             (PressureCorrect(iSouth, jWest, K) -          &
                                              PressureCorrect(I     , J    , K))/          &
                                              DZX_ZY(iSouth, jWest)  

                    endif


                    !Aceleration due the tide potential 
                    ![m/s^2]                   = [m/s^2] * [m] / [m]
                    TidePotentialAceleration   = - Gravity * (TidePotentialLevel(iSouth, jWest) - &
                                                 TidePotentialLevel(I, J)) /                      &
                                                 DZX_ZY(iSouth, jWest)
                
                
                    if (Me%ComputeOptions%AtmPressure) then
                    !Aceleration due to Atmospheric Pressure
                        ![m/s^2]                        = [M*m/s^2/m^2] / [M/m^3] / [m]
                        AtmosphericPressure_Aceleration = (AtmPressure(iSouth, jWest) - AtmPressure(I, J)) / &
                                                           FaceDensity / DZX_ZY(iSouth, jWest)           
                    else 
                        
                        AtmosphericPressure_Aceleration = 0.

                    endif


                    !Aceleration due to Barotropic Pressure

                    Barotropic_Aceleration = WaterPressure_Aceleration + AtmosphericPressure_Aceleration + &
                                             TidePotentialAceleration

                    ![m/s]           = [m/s]            +     [s]     *     [m/s^2] 
                    TiCoef_3D(I, J, K) = TiCoef_3D(I, J, K) + DT_Velocity * Barotropic_Aceleration  

                    !Aceleration due to Baroclinic Pressure

                    ![m/s^2]               = [m/s^2] * [M/m^3] / [M/m^3]
                    Baroclinic_Aceleration = Gravity * Rox3XY(I, J, K) / FaceDensity

                    ![m/s]           = [m/s]            +     [s]     *     [m/s^2] 
                    TiCoef_3D(I, J, K) = TiCoef_3D(I, J, K) + DT_Velocity * Baroclinic_Aceleration  



                    !Aceleration due to Horizontal transport = advection + diffusion
                    ![m/s^2]              = [m^4/s^2] / [m^3]                
                    Transport_Aceleration = Horizontal_Transport (I, J, K) / Volume_UV(I, J, K)


                    !Aceleration due to Horizontal transport = advection + diffusion

                    ![m/s]           = [m/s]            +     [s]     *     [m/s^2] 
                    TiCoef_3D(I, J, K) = TiCoef_3D(I, J, K) + DT_Velocity * Transport_Aceleration  

                    !Aceleration due the coriolis and centrifugal force 

                    ![m/s]           = [m/s]            +     [s]     *     [m/s^2] 
                    TiCoef_3D(I, J, K) = TiCoef_3D(I, J, K) + DT_Velocity * Inertial_Aceleration(I, J, K)  


                    ![m/s]           = [m/s]            +     [s]     *     [m/s^2] 
                    if (Me%Relaxation%Force)                                &
                        TiCoef_3D(I, J, K) = TiCoef_3D(I, J, K) + DT_Velocity *          &
                                                                  Relax_aceleration(I, J, K)  

                    ![m/s]           = [m/s]            +     [s]     *     [m/s^2] 
                    if (Me%ComputeOptions%Obstacle)                                &
                        TiCoef_3D(I, J, K) = TiCoef_3D(I, J, K) + DT_Velocity *          &
                                                                  Me%Forces%ObstacleDrag_Aceleration(I, J, K)  



                enddo dok      

            endif Cov1

        enddo doi
        enddo doj

        !Nullify auxiliar pointers 
        nullify(DCoef_3D)
        nullify(ECoef_3D)
        nullify(FCoef_3D)
        nullify(TiCoef_3D)

        nullify(Rox3XY)
        nullify(Horizontal_Transport)
        nullify(Inertial_Aceleration)
        nullify(TidePotentialLevel)
        nullify(Relax_Aceleration)

        nullify(WaterLevel_New, WaterLevel_Old)

        nullify(Density)
        nullify(AtmPressure)

        nullify(Volume_UV)

        nullify(ComputeFaces3D_UV)
        nullify(KFloor_UV)

        nullify(DZX_ZY)
        nullify(DUX_VY)

    end Subroutine Velocity_ExplicitForces

    !------------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the vertical advection and is able to do the               !
    !  calculation explicit or implicit                                                    !
    ! Input : Flow, Geometry, Mapping                                                      !
    ! OutPut: DCoef_3D, ECoef_3D, FCoef_3D, TiCoef_3D                                              !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Velocity_VerticalAdvection 

        !Variables Categories
        ! Geometry : Volume_UV, Area_UV (Control Volume and Area for the U faces or V faces)
        ! Flow     : WaterFlux_Z (Vertical water fluxes), Velocity_UV (U or V velocity)
        ! Time     : DT_Velocity (velocity time step) 
        ! Mapping  : KFloor_UV (first water layer for a i, j face), ComputeFaces3D_UV  (1 - covered faces, 0 - not covered faces) 
        ! Options  : UpStream_CenterDif (1- Upwind and 0- Centered differences), ImplicitVertAdvection (1- implict, 0- explicit)
        ! Direction: Direction (DirectionX_=1,DirectionY_=2)
        ! Dimension: ILB (i lower bound), IUB (i upper bound), JLB (j lower bound), JUB (j upper bound), KUB (k upper bound)

        !Variables dependent from the direction: 
        !Volume_UV, Area_UV, Velocity_UV, ComputeFaces3D_UV, Direction, KFloor_UV

        !Variables independent from the direction. In the future this arguments 
        !will enter the subroutine associated with modules: 
        !WaterFlux_Z, DCoef_3D, ECoef_3D, FCoef_3D, TiCoef_3D,            
        !DT_Velocity, UpStream_CenterDif, ImplicitVertAdvection,  
        !ILB, IUB, JLB, JUB, KUB

        !X direction 
        !call VerticalAdvection(Volume_U, Area_U, Velocity_U,             &
        !                        ComputeFaces3D_U, KFloorU, DirectionX_,      &
        !                        WaterFlux_Z,                              &
        !                        DCoef_3D, ECoef_3D, FCoef_3D, TiCoef_3D,          &
        !                        DT_Velocity,                              &
        !                        UpStream_CenterDif, ImplicitVertAdvection,   &
        !                        ILB, IUB, JLB, JUB, KUB)             

        !Y direction 
        !call VerticalAdvection(Volume_V, Area_V, Velocity_V,             &
        !                        ComputeFaces3D_V, KFloorV, DirectionY_,      &
        !                        WaterFlux_Z,                              &
        !                        DCoef_3D, ECoef_3D, FCoef_3D, TiCoef_3D,          &   
        !                        DT_Velocity,                              &
        !                        UpStream_CenterDif, ImplicitVertAdvection,   &
        !                        ILB, IUB, JLB, JUB, KUB)             
                  


        !Arguments------------------------------------------------------------



        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Volume_UV, WaterFlux_Z, ECoef_3D

        real,    dimension(:,:,:), pointer :: DCoef_3D, FCoef_3D, TiCoef_3D, &
                                              Area_UV, Velocity_UV_Old

        real,    dimension(:,:  ), pointer :: DZX_ZY, WaterColumnUV, DYY_XX

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV, BoundaryFacesUV

        real(8), dimension(2)              :: V2
        real,    dimension(4)              :: CFace, Vel4, du4

        real                               :: UpStream_CenterDif, ImplicitVertAdvection, WaterColumn2D

        real(8)                            :: CorrectionOld, CorrectionNew, Face_Flux, MomentumFlux
    
        integer                            :: di, dj, i, j, k, Kbottom, iSouth, jWest

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        logical                            :: NearBoundary


        !Begin---------------------------------------------------------------------


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

!        DT_Velocity          =  Me%Velocity%DT

        UpStream_CenterDif   =  Me%ComputeOptions%UpStream_CenterDif
        WaterColumn2D        =  Me%ComputeOptions%WaterColumn2D

        ImplicitVertAdvection   =  Me%ComputeOptions%ImplicitVertAdvection

        DCoef_3D             => Me%Coef%D3%D
        ECoef_3D             => Me%Coef%D3%E
        FCoef_3D             => Me%Coef%D3%F
        TiCoef_3D            => Me%Coef%D3%Ti
        
        WaterFlux_Z          => Me%WaterFluxes%Z

        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old

        Volume_UV            => Me%External_Var%Volume_UV
        Area_UV              => Me%External_Var%Area_UV

        DZX_ZY               => Me%External_Var%DZX_ZY
        DYY_XX               => Me%External_Var%DYY_XX
        WaterColumnUV        => Me%External_Var%WaterColumnUV

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        BoundaryFacesUV      => Me%External_Var%BoundaryFacesUV
        KFloor_UV            => Me%External_Var%KFloor_UV

        !End - Shorten variables name 

!        allocate(BottomCell_BottomFace(KUB), CenterCell_BottomFace(KUB), &
!                 CenterCell_TopFace(KUB), TopCell_TopFace(KUB))

doi:     do j=JLB, JUB
doj:     do i=ILB, IUB

            !This if impose in the open boundary gradient null for the vertical advection 
cd1:        if (ComputeFaces3D_UV(i, j, KUB) == Covered  .and.                           &
                WaterColumnUV(i, j) > WaterColumn2D) then 

                if (BoundaryFacesUV  (i, j) == Boundary .and.                            &
                    .not. Me%SubModel%ON .and. (.not. Me%CyclicBoundary%ON .or.          &
                   (Me%CyclicBoundary%ON .and. Me%CyclicBoundary%Direction == Me%Direction%YX)))  then

                    Cycle

                endif

                iSouth = i - di
                jWest  = j - dj

                Kbottom = KFloor_UV(i, j)

!                TopFace_Flux  = 0.

                CorrectionOld = 0.

dok1:           do  k = Kbottom + 1, KUB                              

                    !This formulation assumes that AreaUV / VolumeUV = DZX_ZY, because
                    !is the only way of cancel the vertical diffusion and advection terms 
                    !when the water flow is considered implicit in the water level calculation. 
                    !However, this relation is not true when AreaUV is computed using the 
                    !minimum thickness metodology.    
                    !See ModuleGeometry 
                    ![s/m]                   =   [s] /  [m]
!                    DT_V                     =   DT_Velocity / (Area_UV(i, j, k) * DZX_ZY(iSouth, jWest))

                    !When the faces area is compute using the average thickness metodology
                    !(See ModuleGeometry) then this relation and the above one are equal.  

                    ![s/m^3]        = [s] / [m^3]
!                    DT_V            = DT_Velocity / Volume_UV(i, j, k)


                    !BottomFace_Flux = (WaterFlux_Z(iSouth, jWest, k) + WaterFlux_Z(i, j, k))/2. 
                    
!                    BottomFace_Flux = TopFace_Flux

!                    TopFace_Flux    = (WaterFlux_Z(iSouth, jWest, k+1) + WaterFlux_Z(i, j, k+1))/2.

!                    if (Me%SubModel%ON .and. BoundaryFacesUV  (i, j) == Boundary ) then
!                    
!                        call VertAdvectionSubModel ( CorrectionOld, CorrectionNew, i, j, k)

!                        TopFace_Flux   = TopFace_Flux + CorrectionNew / 2.

!                        CorrectionOld  = CorrectionNew

!                    endif


                    !Upwind Coefficients :
                    ! bottom face - UpWind_Velocity = Coef_Up_1*Velocity(k-1) +  Coef_Up_2*Velocity(k)
                    !if (BottomFace_Flux>0) then
                    !   Coef_Up_1 = 1.
                    !   Coef_Up_2 = 0.
                    !else 
                    !   Coef_Up_1 = 0.
                    !   Coef_Up_2 = 1.
                    !endif 

                    !Coef_Centered_1          = Area_UV(i, j, k)   / (Area_UV(i, j, k) + Area_UV(i, j, k-1))

                    !Coef_Centered_2          = Area_UV(i, j, k-1) / (Area_UV(i, j, k) + Area_UV(i, j, k-1))

                    ![ ]                     = [s/m^3] * [m^3/s]
                    !BottomCell_BottomFace(k) = DT_V * BottomFace_Flux * (UpStream_CenterDif * Coef_Up_1 +  &
                    !                           (1. - UpStream_CenterDif) * Coef_Centered_1)

                    ![ ]                     = [s/m^3] * [m^3/s]
                    !CenterCell_BottomFace(k) = DT_V * BottomFace_Flux * (UpStream_CenterDif * Coef_Up_2 +  &
                    !                           (1. - UpStream_CenterDif) * Coef_Centered_2)


                    !Upwind Coefficients :
                    ! top face  - UpWind_Velocity = Coef_Up_1*Velocity(k)   +  Coef_Up_2*Velocity(k+1)
                    !if (TopFace_Flux>0) then
                    !!   Coef_Up_1 = 1.
                    !   Coef_Up_2 = 0.
                    !else 
                    !   Coef_Up_1 = 0.
                    !   Coef_Up_2 = 1.
                    !endif 

                    !Coef_Centered_1          = Area_UV(i, j, k+1) / (Area_UV(i, j, k) + Area_UV(i, j, k+1))

                    !Coef_Centered_2          = Area_UV(i, j, k)   / (Area_UV(i, j, k) + Area_UV(i, j, k+1))


                    ![ ]                     = [s/m^3] * [m^3/s]
                    !CenterCell_TopFace(k)    = DT_V * TopFace_Flux * (UpStream_CenterDif * Coef_Up_1      + &
                    !                          (1 - UpStream_CenterDif) * Coef_Centered_1)

                    ![ ]                     = [s/m^3] * [m^3/s]
                    !TopCell_TopFace(k)       = DT_V * TopFace_Flux * (UpStream_CenterDif * Coef_Up_2 +         &
                    !                          (1 - UpStream_CenterDif) * Coef_Centered_2)


                    Face_Flux    = (WaterFlux_Z(iSouth, jWest, k) + WaterFlux_Z(i, j, k))/2.

                    if (Me%SubModel%ON .and. BoundaryFacesUV  (i, j) == Boundary ) then
                    
                        call VertAdvectionSubModel ( CorrectionOld, CorrectionNew, i, j, k)

                        Face_Flux   = Face_Flux + CorrectionNew / 2.

                        CorrectionOld  = CorrectionNew

                    endif

                    if (Face_Flux > 0) then
                        if (k == Kbottom + 1) NearBoundary = .true.
                    else
                        if (k == KUB        ) NearBoundary = .true.
                    endif

                    Vel4(1) = Velocity_UV_Old(i, j, k - 2);
                    Vel4(2) = Velocity_UV_Old(i, j, k - 1);
                    Vel4(3) = Velocity_UV_Old(i, j, k    );
                    Vel4(4) = Velocity_UV_Old(i, j, k + 1);

                    du4(1) = Area_UV(i, j, k - 2) / DYY_XX(i, j);
                    du4(2) = Area_UV(i, j, k - 1) / DYY_XX(i, j);
                    du4(3) = Area_UV(i, j, k    ) / DYY_XX(i, j);
                    du4(4) = Area_UV(i, j, k + 1) / DYY_XX(i, j);

                    !This formulation assumes that AreaUV / VolumeUV = DZX_ZY, because
                    !is the only way of cancel the vertical diffusion and advection terms 
                    !when the water flow is considered implicit in the water level calculation. 
                    !However, this relation is not true when AreaUV is computed using the 
                    !minimum thickness metodology.    
                    !See ModuleGeometry 
                    ![s/m]                   =   [s] /  [m]
!                    DT_V                     =   DT_Velocity / (Area_UV(i, j, k) * DZX_ZY(iSouth, jWest))

                    V2   (1) = Area_UV(i, j, k-1) * DZX_ZY(iSouth, jWest);
                    V2   (2) = Area_UV(i, j, k  ) * DZX_ZY(iSouth, jWest);

                    call ComputeAdvectionFace(Vel4, V2, du4, Me%Velocity%DT,            &
                                              Face_Flux,                                &
                                              Me%ComputeOptions%VolumeRelMax,           &
                                              Me%ComputeOptions%AdvectionMethodV,       &
                                              Me%ComputeOptions%TVD_LimV,               &
                                              NearBoundary,                             &
                                              Me%ComputeOptions%Upwind2V, CFace)



                    MomentumFlux = dble(Vel4(1) * CFace(1)  + Vel4(2) * CFace(2)  +     &
                                        Vel4(3) * CFace(3)  + Vel4(4) * CFace(4)) *     &
                                        Face_Flux ![m/s*m^3/s]


                    TiCoef_3D(i, j, k  )  = TiCoef_3D(i, j, k  ) + (1. - ImplicitVertAdvection) * &
                                            MomentumFlux * Me%Velocity%DT / V2(2)

                    TiCoef_3D(i, j, k-1)  = TiCoef_3D(i, j, k-1) - (1. - ImplicitVertAdvection) * &
                                            MomentumFlux * Me%Velocity%DT / V2(1)

                    DCoef_3D (i, j, k  )  = DCoef_3D (i, j, k  ) - ImplicitVertAdvection *  &
                                            CFace(2) * Face_Flux *  Me%Velocity%DT / V2(2)

                    ECoef_3D (i, j, k  )  = ECoef_3D (i, j, k  ) - ImplicitVertAdvection *  &
                                            CFace(3) * Face_Flux *  Me%Velocity%DT / V2(2)

                    ECoef_3D (i, j, k-1)  = ECoef_3D (i, j, k-1) + ImplicitVertAdvection *  &
                                            CFace(2) * Face_Flux *  Me%Velocity%DT / V2(1)

                    FCoef_3D (i, j, k-1)  = FCoef_3D (i, j, k-1) + ImplicitVertAdvection *  &
                                            CFace(3) * Face_Flux *  Me%Velocity%DT / V2(1)

                enddo dok1

                !Boundary conditions - bottom 
                !BottomCell_BottomFace(kbottom) = 0.

                !CenterCell_BottomFace(kbottom) = 0.

                !Boundary conditions - surface
                !CenterCell_TopFace(KUB)        = 0.
      
                !TopCell_TopFace(KUB)           = 0.
   
!dok2:           do k=kbottom, KUB

!                DCoef_3D (i, j, k)  = DCoef_3D (i, j, k) + ImplicitVertAdvection * (- BottomCell_BottomFace(k))

!                ECoef_3D (i, j, k)  = ECoef_3D (i, j, k) + ImplicitVertAdvection * (- CenterCell_BottomFace(k)  &
!                                                            + CenterCell_TopFace(k))

!                FCoef_3D (i, j, k)  = FCoef_3D (i, j, k) + ImplicitVertAdvection * (+ TopCell_TopFace(k))



                    ![ ]                      =               [ ]           *    [m/s]               
!                    TotalExplicitVerticalAdv = BottomCell_BottomFace(k)  * Velocity_UV_Old(i,j,k-1) &
!                                              +(CenterCell_BottomFace(k) - CenterCell_TopFace(k))    &
!                                                                   * Velocity_UV_Old(i,j,k  )        &
!                                              - TopCell_TopFace(k) * Velocity_UV_Old(i,j,k+1)                              



                   !ImplicitVertAdvection (1 - Implicit, 0 - Explicit)
!                   TiCoef_3D(i, j, k)  = TiCoef_3D(i, j, k) + (1. - ImplicitVertAdvection) * &
!                                       TotalExplicitVerticalAdv
!                enddo dok2

            endif cd1

        enddo doj
        enddo doi

        !Nullify auxiliar pointers 
        nullify(DCoef_3D)
        nullify(ECoef_3D)   
        nullify(FCoef_3D)   
        nullify(TiCoef_3D)  
        
        nullify(WaterFlux_Z)

        nullify(Velocity_UV_Old)

        nullify(Volume_UV)
        nullify(Area_UV  )
        nullify(DZX_ZY, DYY_XX)
        nullify(WaterColumnUV)
        
        nullify(ComputeFaces3D_UV)
        nullify(KFloor_UV)
        nullify(BoundaryFacesUV)


!        Deallocate(BottomCell_BottomFace, CenterCell_BottomFace, &
!                   CenterCell_TopFace,    TopCell_TopFace)

    End Subroutine Velocity_VerticalAdvection


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! Corrects the vertical flux in the boundary faces                                     !
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping                                                      !
    ! OutPut: Water Flow                                                                   !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine VertAdvectionSubModel ( BottomFlux, TopFlux, i, j, k)

        !Arguments------------------------------------------------------------


        real(8), intent (IN)               :: BottomFlux
        integer, intent (IN)               :: i, j, k
        real(8), intent (OUT)              :: TopFlux

        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: qXY, qYX, WaterFlux_XY, WaterFlux_YX,      &
                                              Volume_Z_New, Volume_Z_Old
        real   , dimension(:,:  ), pointer :: DYY_XX, DXX_YY
        integer, dimension(:,:,:), pointer :: ImposedNormalFacesUV,                      &
                                              ImposedTangentialFacesVU,                  &
                                              ComputeFaces3D_UV, ComputeFaces3D_VU

        integer, dimension(:,:  ), pointer :: BoundaryPoints

        real                               :: DT
        integer                            :: di, dj, status

        !--------------------------------------------------------------------------

        !Begin - Shorten variables name 

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        ImposedNormalFacesUV     => Me%External_Var%ImposedNormalFacesUV
        ImposedTangentialFacesVU => Me%External_Var%ImposedTangentialFacesVU
        DYY_XX                   => Me%External_Var%DYY_XX
        DXX_YY                   => Me%External_Var%DXX_YY
        BoundaryPoints           => Me%External_Var%BoundaryPoints 
        qXY                      => Me%SubModel%qXY
        qYX                      => Me%SubModel%qYX

        Volume_Z_New             => Me%External_Var%Volume_Z_New
        Volume_Z_Old             => Me%External_Var%Volume_Z_Old

        ComputeFaces3D_UV        => Me%External_Var%ComputeFaces3D_UV
        ComputeFaces3D_VU        => Me%External_Var%ComputeFaces3D_VU

        WaterFlux_XY             => Me%WaterFluxes%XY
        WaterFlux_YX             => Me%WaterFluxes%YX


        !End - Shorten variables name 


        call GetComputeTimeStep(Me%ObjTime, DT, STAT = status)
        if (status /= SUCCESS_)                                                          &
            call SetError (FATAL_, INTERNAL_, "VertAdvectionSubModel - Hydrodynamic - ERR01")


        !Bottom flux  - positive
        TopFlux = BottomFlux



cd1:    if (BoundaryPoints(i, j) == 1) then

            !Volume Variation - negative
            TopFlux = TopFlux - (Volume_Z_New(i, j, k) - Volume_Z_Old(i, j, k)) /        &
                      dble(DT)


            !Face West (Face Boundary) - positive
            TopFlux = TopFlux + dble(ComputeFaces3D_UV (i, j, k)) * WaterFlux_XY(i, j, k)


            !Face East - negative
            TopFlux = TopFlux - dble(ImposedNormalFacesUV (i + di , j + dj, k))     *    & 
                        qXY(i + di , j + dj, k) * dble(DYY_XX(i + di , j + dj))

            !Face South - positive
            if (ImposedTangentialFacesVU (i , j , k) == 1 .and.                          &
                ComputeFaces3D_VU        (i , j , k) == 1)                               &
                call SetError (FATAL_, INTERNAL_, "VertAdvectionSubModel - Hydrodynamic - ERR02")

            TopFlux = TopFlux + dble(ImposedTangentialFacesVU (i , j , k))          *    & 
                        qYX(i, j, k) * dble(DXX_YY(i , j))                               &
                      + dble(ComputeFaces3D_VU (i, j, k))                           *    &
                        WaterFlux_YX(i, j, k)


            !Face North  - negative
            if (ImposedTangentialFacesVU (i + dj , j + di, k) == 1 .and.                 &
                ComputeFaces3D_VU        (i + dj , j + di, k) == 1)                      &
                call SetError (FATAL_, INTERNAL_, "VertAdvectionSubModel - Hydrodynamic - ERR03")

            TopFlux = TopFlux - dble(ImposedTangentialFacesVU (i + dj , j + di, k)) *    & 
                        qYX(i + dj , j + di, k) * dble(DXX_YY(i + dj , j + di))          &
                      - dble(ComputeFaces3D_VU (i + dj , j + di, k))                *    &
                        WaterFlux_YX(i + dj , j + di, k)


        else if (BoundaryPoints(i - di , j - dj) == 1) then cd1

            !Volume Variation - negative
            TopFlux = TopFlux - (Volume_Z_New(i - di , j - dj, k) - Volume_Z_Old(i - di , j - dj, k)) / &
                      dble(DT)


            !Face West - positive
            TopFlux = TopFlux + dble(ImposedNormalFacesUV (i - di , j - dj, k))     *    & 
                        qXY(i - di , j - dj, k) * dble(DYY_XX(i - di , j - dj))


            !Face East (Face Boundary) - negative
            TopFlux = TopFlux - dble(ComputeFaces3D_UV (i, j, k)) * WaterFlux_XY(i, j, k)



            !Face South - positive
            if (ImposedTangentialFacesVU (i - di, j - dj, k) == 1 .and.                  &
                ComputeFaces3D_VU        (i - di, j - dj, k) == 1)                       &
                call SetError (FATAL_, INTERNAL_, "VertAdvectionSubModel - Hydrodynamic - ERR04")

            TopFlux = TopFlux + dble(ImposedTangentialFacesVU (i - di, j - dj, k))  *    & 
                        qYX(i - di, j - dj, k) * dble(DXX_YY(i - di, j - dj))            &
                      + dble(ComputeFaces3D_VU (i - di, j - dj, k))                 *    &
                        WaterFlux_YX(i - di, j - dj, k)


            !Face North  - negative
            if (ImposedTangentialFacesVU (i - di + dj, j - dj + di, k) == 1 .and.        &
                ComputeFaces3D_VU        (i - di + dj, j - dj + di, k) == 1)             &
                call SetError (FATAL_, INTERNAL_, "VertAdvectionSubModel - Hydrodynamic - ERR05")

            TopFlux = TopFlux - dble(ImposedTangentialFacesVU (i - di + dj, j - dj + di, k)) *  & 
                        qYX(i - di + dj, j - dj + di, k) * dble(DXX_YY(i - di + dj, j - dj + di)) &
                      - dble(ComputeFaces3D_VU (i - di + dj, j - dj + di, k))         *  &
                        WaterFlux_YX(i - di + dj, j - dj + di, k)


        else  cd1 

            
            call SetError (FATAL_, INTERNAL_, "VertAdvectionSubModel - Hydrodynamic - ERR06")


        endif cd1


        !Nullify auxiliar pointers 
        nullify (ImposedNormalFacesUV    )
        nullify (ImposedTangentialFacesVU)

        nullify (ComputeFaces3D_UV       )
        nullify (ComputeFaces3D_VU       )

        nullify (DYY_XX                  )
        nullify (DXX_YY                  )

        nullify (qXY                     )
        nullify (qYX                     )
        nullify (WaterFlux_XY            )
        nullify (WaterFlux_YX            )

        nullify (Volume_Z_New)
        nullify (Volume_Z_Old)





    end Subroutine VertAdvectionSubModel

   !End ----------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the vertical diffusion and is able to do the                !
    !  calculation explicit or implicit                                                    !
    ! Input : Flow, Geometry, Mapping                                                      !
    ! OutPut: DCoef_3D, ECoef_3D, FCoef_3D, TiCoef_3D                                      !
    ! Author: Paulo Chambel (99/6)                                                         !
    ! Modifications: 2001 Manuel Ruiz Villarreal, 
    !                limitation to maximum bottom viscosity   !                                                  !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Velocity_VerticalDiffusion 
        

        !Variables Categories 
        ! 3DGeometry : Volume_UV, Area_UV (Control Volume and Area for the U faces or V faces)
        ! GridGeomtry: DZX_ZY (U or V Control volume length), DUX_VY (distance between faces), DYY_XX (U or V Control Volume width) 
        ! Flow       : Velocity_UV_Old (U or V velocity), VerticalViscosity (Vertical turbulent Viscosity)
        ! Time       : DT_Velocity (velocity time step) 
        ! Mapping    : KFloor_UV (first water layer for a i, j face), ComputeFaces3D_UV  (1 - covered faces, 0 - not covered faces) 
        !
        ! Options    : UpStream_CenterDif (1 - UpStream and 0 - Centered differences), 
        !   ImplicitVertAdvection (1 - implict, 0 - explicit)
        !
        ! Direction  : Direction (DirectionX_=1,DirectionY_=2)
        ! Dimension  : ILB (i lower bound), IUB (i upper bound), JLB (j lower bound), JUB (j upper bound), KUB (k upper bound)

        !Variables dependent from the direction: 
         !Volume_UV, Area_UV, Velocity_UV_Old, DZX_ZY, DUX_VY, DYY_DXX,    
         !VerticalViscosity, ComputeFaces3D_UV, Direction, KFloor_UV

        !Variables independent from the direction. In the future this arguments 
        !will enter the subroutine associated with modules: 
         !WaterFlux_Z, DCoef_3D, ECoef_3D, FCoef_3D, TiCoef_3D,            
         !DT_Velocity, ImplicitVertDiffusion,  
         !ILB, IUB, JLB, JUB, KUB


        !X direction 
        ! call VerticalDiffusion(Volume_U, Area_U, DZX, DUX, DYY,      &
        !                        VerticalViscosity, Velocity_U,        &
        !                        CoveredFacesX, DirectionX_, KFloorU,   & 
        !                        DCoef_3D, ECoef_3D, FCoef_3D, TiCoef_3D,      &
        !                        DT_Velocity, ImplicitVertDiffusion,       &
        !                        ILB, IUB, JLB, JUB, KUB)

        !Y direction 
        ! call VerticalDiffusion(Volume_V, Area_V, DZY, DVY, DXX,      &
        !                        VerticalViscosity, Velocity_V,        &
        !                        CoveredFacesY, DirectionY_, KFloorV,   & 
        !                        DCoef_3D, ECoef_3D, FCoef_3D, TiCoef_3D,      &
        !                        DT_Velocity, ImplicitVertDiffusion,       &
        !                        ILB, IUB, JLB, JUB, KUB)

        !Arguments------------------------------------------------------------



        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Volume_UV, ECoef_3D

        real,    dimension(:,:,:), pointer :: DCoef_3D, FCoef_3D, TiCoef_3D,             &
                                              Velocity_UV_Old,                           & !DUZ_VZ                 &
                                              Vertical_Viscosity, DUZ_VZ

        real,    dimension(:,:  ), pointer :: DUX_VY, DYY_XX, DZX_ZY, WaterColumnUV

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV

        real                               :: DT_Velocity, ImplicitVertDiffusion

        real                               :: BottomFaceViscosity,TopFaceViscosity, DT_Z, &
                                              ExplicitVerticalDiffusion, WaterColumn2D
    
        integer                            :: di, dj, i, j, k, Kbottom, iSouth, jWest

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        real(8), allocatable, dimension(:) :: BottomCell_BottomFace, CenterCell_BottomFace, &
                                              CenterCell_TopFace, TopCell_TopFace

        real                               :: DUZ_Top, DUZ_Bottom, Visc_bottom_max,      &
                                              BottomViscCoef

        !Begin---------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        DT_Velocity          =  Me%Velocity%DT
        ImplicitVertDiffusion=  Me%ComputeOptions%ImplicitVertDiffusion
        BottomViscCoef       =  Me%ComputeOptions%BottomViscCoef
        WaterColumn2D        =  Me%ComputeOptions%WaterColumn2D

        DCoef_3D             => Me%Coef%D3%D
        ECoef_3D             => Me%Coef%D3%E
        FCoef_3D             => Me%Coef%D3%F
        TiCoef_3D            => Me%Coef%D3%Ti
        
        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old

        Volume_UV            => Me%External_Var%Volume_UV
        DUZ_VZ               => Me%External_Var%DUZ_VZ

        DUX_VY               => Me%External_Var%DUX_VY
        DYY_XX               => Me%External_Var%DYY_XX
        DZX_ZY               => Me%External_Var%DZX_ZY

        WaterColumnUV        => Me%External_Var%WaterColumnUV

        Vertical_Viscosity   => Me%External_Var%Vertical_Viscosity

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV            => Me%External_Var%KFloor_UV

        !End - Shorten variables name 


        allocate(BottomCell_BottomFace(KUB), CenterCell_BottomFace(KUB), &
                 CenterCell_TopFace(KUB), TopCell_TopFace(KUB))
  
    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

            iSouth = i-di
            jWest  = j-dj

    cd1:    if (ComputeFaces3D_UV(i, j, KUB)==Covered .and.                              &
                WaterColumnUV(i,j) > WaterColumn2D) then 
        
                Kbottom          = KFloor_UV(i, j)

                TopFaceViscosity = FillValueReal
                DUZ_Top          = FillValueReal

                
    dok1:       do k = Kbottom, KUB
                    


                    !This formulation assumes that AreaUV / VolumeUV = DZX_ZY, because
                    !is the only way of cancel the vertical diffusion and advection terms 
                    !when the water flow is considered implicit in the water level calculation. 
                    !However, this relation is not true when AreaUV is computed using the 
                    !minimum thickness metodology.    
                    !See ModuleGeometry 
                    ![s/m]                   =   [s] /  [m]
                    DT_Z                     =   DT_Velocity / DUZ_VZ(i, j, k)

                    !When the faces area is compute using the average thickness metodology
                    !(See ModuleGeometry) then this relation and the above one are equal.  

                    ![s/m]                   =   [s] / [m^3] * [m] * [m]
!                    DT_Z                     =   DT_Velocity / Volume_UV(i, j, k) *      &
!                                                 DZX_ZY(iSouth, jWest) * DYY_XX(i, j)




! Manuel RV 2001 Changed!!! Vertical viscosities are calculated at faces with the notation that viscosity at bottom face 
!                           corresponds to viscosity (k)

                    BottomFaceViscosity      =   TopFaceViscosity

                    !Horizontal viscosity faces interpolation
                    TopFaceViscosity         =   (Vertical_Viscosity(i, j, k+1) * DUX_VY(iSouth, jWest)  + &
                                                 Vertical_Viscosity(iSouth, jWest, k+1) * DUX_VY(i, j)) /  &
                                                (DUX_VY(iSouth, jWest) + DUX_VY(i, j))

                    !Distance in vertical between adjacent velocity compute points.
                    DUZ_Bottom               =   DUZ_Top
                    DUZ_Top                  =  (DUZ_VZ(i, j, k) + DUZ_VZ(i, j, k + 1)) / 2.

                    !Limitation of bottom viscosity due to the semi-implicit discretization of bottom friction. MRV
                    if (Me%ComputeOptions%BottomVisc_LIM .and. k == kbottom) then

                        ![m^2/s]             =  [] * [m] * [m] / [s]
                        visc_bottom_max      =  BottomViscCoef * DUZ_VZ(i, j, k) * DUZ_Top / 2./ DT_Velocity
                        TopFaceViscosity     =  min (TopFaceViscosity , visc_bottom_max)                                            

                    end if     

!MRV New     
      
                   ![ ]                      =   [s/m]* [m^2/s] / [m]
                    BottomCell_BottomFace(k) = - DT_Z * BottomFaceViscosity / DUZ_Bottom

                   ![ ]                     =    [s/m]* [m^2/s] / [m]
                    TopCell_TopFace(k)       = - DT_Z * TopFaceViscosity    / DUZ_Top

      
                    CenterCell_BottomFace(k) = - BottomCell_BottomFace(k)

                    CenterCell_TopFace(k)    = - TopCell_TopFace(k) 
     
                enddo dok1


                !The bottom boundary conditions are imposed in another subroutine
                !see VelVerticalDiffusionBoundaries
                BottomCell_BottomFace(kbottom) = 0.

                CenterCell_BottomFace(kbottom) = 0.

                !The surface boundary conditions are imposed in another subroutine
                !see VelVerticalDiffusionBoundaries
                CenterCell_TopFace(KUB)        = 0.
      
                TopCell_TopFace(KUB)           = 0.

    dok2:       do k = kbottom, KUB

                   DCoef_3D (i, j, k)  = DCoef_3D (i, j, k) + ImplicitVertDiffusion * BottomCell_BottomFace(k)
       
                   ECoef_3D (i, j, k)  = ECoef_3D (i, j, k) + ImplicitVertDiffusion *  &
                                        (CenterCell_BottomFace(k) + CenterCell_TopFace(k))

                   FCoef_3D (i, j, k)  = FCoef_3D (i, j, k) + ImplicitVertDiffusion * TopCell_TopFace(k)

                   ExplicitVerticalDiffusion = (BottomCell_BottomFace(k) * Velocity_UV_Old(i, j, k-1)   +  &
                                               (CenterCell_BottomFace(k) +                             & 
                                                CenterCell_TopFace(k))   * Velocity_UV_Old(i, j, k)     +  &
                                                TopCell_TopFace(k)       * Velocity_UV_Old(i, j, k+1))

                   TiCoef_3D(i,j,k)  = TiCoef_3D(i,j,k) + (ImplicitVertDiffusion - 1) * ExplicitVerticalDiffusion
                         
                enddo dok2

            endif cd1

        enddo doj
        enddo doi

        !Nullify auxiliar pointers 
        nullify(DCoef_3D)
        nullify(ECoef_3D)   
        nullify(FCoef_3D)   
        nullify(TiCoef_3D)  
        
        nullify(Velocity_UV_Old)

        nullify(Vertical_Viscosity)

        nullify(DYY_XX)
        nullify(DUX_VY)
        nullify(DZX_ZY)

        nullify(WaterColumnUV)

        nullify(Volume_UV)
        nullify(DUZ_VZ   )


        nullify(ComputeFaces3D_UV)
        nullify(KFloor_UV)


        Deallocate(BottomCell_BottomFace, CenterCell_BottomFace, &
                   CenterCell_TopFace,    TopCell_TopFace)

    End Subroutine Velocity_VerticalDiffusion

        !End-----------------------------------------------------------------------

    Subroutine Velocity_WaveStress
        

        !Arguments------------------------------------------------------------



        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Volume_UV
        real,    dimension(:,:,:), pointer :: TiCoef_3D, Density, DUZ_VZ

        real,    dimension(:,:  ), pointer :: DUX_VY, DYY_XX, DZX_ZY, TauWaves_UV,       &
                                              WaterColumnUV

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV

        real                               :: DT_Velocity

        real                               :: Aux_2D, TauFace, FaceDensity
    
        integer                            :: di, dj, i, j, k, Kbottom, iSouth, jWest

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !Begin---------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        DT_Velocity          =  Me%Velocity%DT

        TiCoef_3D            => Me%Coef%D3%Ti
        
        Volume_UV            => Me%External_Var%Volume_UV

        DUX_VY               => Me%External_Var%DUX_VY
        DYY_XX               => Me%External_Var%DYY_XX
        DZX_ZY               => Me%External_Var%DZX_ZY

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV            => Me%External_Var%KFloor_UV

        Density              => Me%External_Var%Density

        TauWaves_UV          => Me%External_Var%TauWaves_UV
        DUZ_VZ               => Me%External_Var%DUZ_VZ
        WaterColumnUV        => Me%External_Var%WaterColumnUV

        !End - Shorten variables name 


  
    doi: do j=JLB, JUB
    doj: do i=ILB, IUB

            iSouth = i-di
            jWest  = j-dj

    cd1:    if (ComputeFaces3D_UV(i, j, KUB)==Covered) then 
        
                Kbottom          = KFloor_UV(i, j)

                TauFace  = Face_Interpolation(TauWaves_UV(I,J), TauWaves_UV(iSouth, jWest), &
                                              DUX_VY(I, J), DUX_VY(iSouth, jWest))                
                ![M*m/s]   [s] * [m] * [m] * [M*m/s^2/m^2] 
                Aux_2D   = DT_Velocity * DZX_ZY(iSouth, jWest) * DYY_XX(I, J) * TauFace 

    dok1:       do k = Kbottom, KUB

                    if (Me%ComputeOptions%LocalDensity) then

                        FaceDensity  = Face_Interpolation(Density(I, J, k),                  &
                                                          Density(iSouth, jWest, k),       &
                                                          DUX_VY(I, J), DUX_VY(iSouth, jWest))
                    else

                        FaceDensity  = SigmaDensityReference

                    endif

                    ![m/s]                                 [M*m/s] / [m^3] / [M/m^3]  
                    TiCoef_3D(i,j,k)  = TiCoef_3D(i,j,k) + Aux_2D / Volume_UV(i, j, k) / FaceDensity &
                                                         * DUZ_VZ(i, j, k) / WaterColumnUV(i, j)
                         
                enddo dok1

            endif cd1

        enddo doj
        enddo doi

        !Nullify auxiliar pointers 
        nullify(TiCoef_3D)  
        

        nullify(DYY_XX)
        nullify(DUX_VY)
        nullify(DZX_ZY)

        nullify(Volume_UV)

        nullify(ComputeFaces3D_UV)
        nullify(KFloor_UV)

        nullify(TauWaves_UV, Density)
        nullify(DUZ_VZ, WaterColumnUV)


    End Subroutine Velocity_WaveStress

        !End-----------------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !  This subroutine compute the vertical diffusion surface and bottom boundaries.       !
    !  Compute always the wind effect explicit                                             !
    !  the bottom friction effect implicit can be explicit or implicit (advised)           !
    ! Input : Flow, Geometry, Mapping                                                      !
    ! OutPut: ECoef_3D,  TiCoef_3D                                                             !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine VelVerticalDiffusionBoundaries            
        

        !Variables Categories 
        ! 3DGeometry : Volume_UV, Area_UV (Control Volume and Area for the U faces or V faces)
        ! GridGeomtry: DZX_ZY (U or V Control volume length), DUX_VY (distance between faces), DYY_XX (U or V Control Volume width) 
        ! Flow       : Velocity_UV_Old (U or V velocity), VerticalViscosity (Vertical turbulent Viscosity)
        ! Time       : DT_Velocity (velocity time step) 
        !
        ! Mapping    : KFloor_UV (first water layer for a i, j face), ComputeFaces3D_UV  
        !   (1 - covered faces, 0 - not covered faces) 
        !
        ! Options    : UpStream_CenterDif (1 - UpStream and 0 - Centered differences),  
        !              ImplicitVertAdvection(1 - implict, 0 - explicit)
        !
        ! Direction  : Direction (DirectionX_=1,DirectionY_=2)
        !
        ! Dimension  : ILB (i lower bound), IUB (i upper bound), JLB (j lower bound), 
        !              JUB (j upper bound), KUB (k upper bound)

        !Variables dependent from the direction: 
         !Volume_UV, Area_UV, Velocity_UV_Old, DZX_ZY, DUX_VY, DYY_DXX,    
         !ComputeFaces3D_UV, Direction, KFloor_UV


        !Arguments------------------------------------------------------------



        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Volume_UV, ECoef_3D

        real,    dimension(:,:,:), pointer :: DCoef_3D, FCoef_3D, TiCoef_3D,             &
                                              Velocity_UV_Old, Velocity_VU_New, Density, &
                                              DUZ_VZ

        real,    dimension(:,:  ), pointer :: DUX_VY, DYY_XX, DXX_YY, DZX_ZY, ChezyVelUV,&
                                              TauWind_UV, WaterColumnUV

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV

        real                               :: DT_Velocity, ImplicitVertDiffusion

        real                               :: CellFace_BottomFace, CellFace_TopFace, SmoothCoef, RunPeriod

        real                               :: DT_Z, TauFace, FaceDensity, Coef, WaterColumn2D
        real(8)                            :: TotalVolume
    
        integer                            :: di, dj, i, j, Kbottom, iSouth, jWest, i_North, j_East, k

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB

        !Begin---------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        DT_Velocity          =  Me%Velocity%DT

        ImplicitVertDiffusion=  Me%ComputeOptions%ImplicitVertDiffusion 

        WaterColumn2D        =  Me%ComputeOptions%WaterColumn2D

        DCoef_3D             => Me%Coef%D3%D
        ECoef_3D             => Me%Coef%D3%E
        FCoef_3D             => Me%Coef%D3%F
        TiCoef_3D            => Me%Coef%D3%Ti
        
        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old
        Velocity_VU_New      => Me%Velocity%Horizontal%VU%New

        Volume_UV            => Me%External_Var%Volume_UV
        DUZ_VZ               => Me%External_Var%DUZ_VZ
        WaterColumnUV        => Me%External_Var%WaterColumnUV

        DUX_VY               => Me%External_Var%DUX_VY
        DYY_XX               => Me%External_Var%DYY_XX
        DXX_YY               => Me%External_Var%DXX_YY
        DZX_ZY               => Me%External_Var%DZX_ZY

        ChezyVelUV           => Me%External_Var%ChezyVelUV
        TauWind_UV           => Me%External_Var%TauWind_UV

        Density              => Me%External_Var%Density

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV            => Me%External_Var%KFloor_UV

        !End - Shorten variables name 
  

  

doi:     do j=JLB, JUB
doj:     do i=ILB, IUB

            iSouth = i - di
            jWest  = j - dj
            ! This values (i_North and j_east) can only be use to compute the velocity modulus in a face
            i_North = i + dj
            j_East  = j + di


cd1:        if (ComputeFaces3D_UV(i, j, KUB)==Covered) then 
        

                !Bottom boundary condition (bottom friction)
                        
                Kbottom = KFloor_UV(i, j)

                ![s/m^3]                  = [s] / [m^3] * [m] * [m]
!                DT_Z                      = DT_Velocity / Volume_UV(i, j, Kbottom)       &
!                                            * DZX_ZY(iSouth, jWest) * DYY_XX(I, J)

!                VelMod_UV                 = Face_Velocity_Modulus(                     &
!                                            Velocity_VU_New(I_North, jWest, kbottom), &
!                                            Velocity_VU_New(I_North, J_East, kbottom), &
!                                            Velocity_VU_New(iSouth, jWest, kbottom), &
!                                            Velocity_VU_New(iSouth, J_East, kbottom), &
!                                            DXX_YY(I_North, jWest),               &
!                                            DXX_YY(I_North, J_East),               &
!                                            DXX_YY(iSouth, jWest),               &
!                                            DXX_YY(iSouth, J_East),               &
!                                            Velocity_UV_Old(I,J,kbottom))

!                Face_Chezy                = (Chezy(iSouth, jWest) * DUX_VY(I, J)   +  &
!                                             Chezy (I, J) * DUX_VY(iSouth, jWest)) /  &
!                                            (DUX_VY(iSouth, jWest) + DUX_VY(I, J))

!                Face_Chezy              = ChezyVelUV (I, J)


                ![ ]                      = [s/m] * [ ] * [m/s]
!                CellFace_BottomFace     = DT_Z  * Face_Chezy * VelMod_UV

                CellFace_BottomFace     = ChezyVelUV (I, J)

                ![m/s ]                   =          [ ]          *     [m/s]
                !ExplicitVerticalDiffusion = CellFace_BottomFace * Velocity_UV_Old(i, j, Kbottom) 

                !TiCoef_3D(i, j, Kbottom)    = TiCoef_3D(i, j, Kbottom) + (ImplicitVertDiffusion - 1) * &
                !                            ExplicitVerticalDiffusion

                !Surface boundary condition (Wind)

                if (Me%ComputeOptions%Wind /= NoWind_) then

                    if (Me%ComputeOptions%LocalDensity) then

                        FaceDensity  = Face_Interpolation(Density(I, J, KUB),                &
                                                          Density(iSouth, jWest, KUB),     &
                                                          DUX_VY(I, J), DUX_VY(iSouth, jWest))
                    else

                        FaceDensity  = SigmaDensityReference

                    endif


                    SmoothCoef = 1.
                    
                    if (Me%ComputeOptions%Wind == InitialSmoothWind_) then

                        RunPeriod = Me%CurrentTime - Me%BeginTime

                        if (RunPeriod < Me%ComputeOptions%SmoothInitialPeriod) then

                            SmoothCoef = RunPeriod / Me%ComputeOptions%SmoothInitialPeriod

                        endif

                    endif


                    TauFace  = Face_Interpolation(TauWind_UV(I,J), TauWind_UV(iSouth, jWest), &
                                                  DUX_VY(I, J), DUX_VY(iSouth, jWest))

                    TauFace  = SmoothCoef * TauFace

                    DT_Z                      = DT_Velocity / Volume_UV(i, j, KUB)       &
                                                * DZX_ZY(iSouth, jWest) * DYY_XX(I, J)

                    ![m/s]                    = [s/m] * [M*m/s^2/m^2] / [M/m^3]
                    CellFace_TopFace        = DT_Z * TauFace / FaceDensity
                else

                    CellFace_TopFace        = 0.

                endif


                !In case of 3D models where the depth is very low a linear profile 
                !is assumed to the shear stress (pressure = shear stress) and the momentum 
                !is decrease in uniform way along the entire water column
                !
                if (KUB > 1 .and. WaterColumnUV(i,j) <= WaterColumn2D) then

                    TotalVolume = 0.

                    do k = Kbottom, KUB

                        TotalVolume = TotalVolume + Volume_UV(i, j, k)

                    enddo

                    do k = Kbottom, KUB

                        Coef = real (Volume_UV(i, j, k) / TotalVolume)

                        ECoef_3D (i, j, k)  = ECoef_3D (i, j, k) + CellFace_BottomFace * Coef

                        !Wind must be always explicit
                        TiCoef_3D(i, j, k)  = TiCoef_3D(i, j, k) + CellFace_TopFace * Coef

                    enddo

                else

                    !the bottom friction is consider always implicit like is done in the water level compute.

                    ECoef_3D (i, j, Kbottom)    = ECoef_3D (i, j, Kbottom) + CellFace_BottomFace 

                    !Wind must be always explicit
                    TiCoef_3D(i, j, KUB)        = TiCoef_3D(i, j, KUB)     + CellFace_TopFace

                endif
             

            endif cd1

        enddo doj
        enddo doi

        !Nullify auxiliar pointers 
        nullify(DCoef_3D)
        nullify(ECoef_3D)   
        nullify(FCoef_3D)   
        nullify(TiCoef_3D)  
        
        nullify(Velocity_UV_Old)
        nullify(Velocity_VU_New)

        nullify(ChezyVelUV) 
        nullify(TauWind_UV)

        nullify(Density)

        nullify(DYY_XX)
        nullify(DUX_VY)
        nullify(DZX_ZY)
        nullify(DXX_YY)
        nullify(WaterColumnUV)

        nullify(Volume_UV)
        nullify(DUZ_VZ   )

        nullify(ComputeFaces3D_UV)
        nullify(KFloor_UV)


    End Subroutine VelVerticalDiffusionBoundaries

        !End-----------------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This subroutine compute the barotropic pressure effect in the water level            !
    ! calculation. The barotropic pressure is the water barotropic pressure plus           !
    ! the atmospheric pressure                                                             !
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping, Time steps                                          !
    ! OutPut: Coefficients of the  linear system equation                                  !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine WaterLevel_BarotropicPressure    
        
        !Variables Categories  
            !Geometry  : WaterColumn, DUX_VY, DVY_UX, DYY_XX, DZX_ZY 
            !WaterProp : Density, AtmPressure
            !Time      : DT_Elevation, DT_Velocity, Num_Discretization
            !Mapping   : ComputeFaces3D_UV, Direction
            !Equations : DCoef_2D, ECoef_2D, FCoef_2D, TiCoef_2D

         
        !Variables Direction Dependent
            !DUX_VY, DVY_UX, DYY_XX, DZX_ZY, ComputeFaces3D_UV, Direction


        !Arguments------------------------------------------------------------



        !Local---------------------------------------------------------------------
        real,    dimension(:,:,:), pointer :: Density, Area_UV, SZZ

        real(8), dimension(:,:),   pointer :: ECoef_2D

        real,    dimension(:,:),   pointer :: DCoef_2D, FCoef_2D, TiCoef_2D, &
                                              WaterColumnUV, AtmPressure,    &
                                              RadCoef_2D, TiRadCoef_2D,      &
                                              TidePotentialLevel

        real,    dimension(:,:  ), pointer :: DUX_VY, DVY_UX, DYY_XX, DZX_ZY

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV, BoundaryFacesUV

        real                               :: DT_Elevation, DT_Velocity, Num_Discretization, &
                                              Alpha

        integer                            :: I, J, di, dj, iSouth, jWest, kbottom

        real                               :: AuxPressure, AuxImplicit, AuxExplicit,  &
                                              WaterColumn_High, DT_AUX, DT_AreaCell1, & 
                                              DT_AreaCell2, AreaCell1, AreaCell2,     &
                                              SurfaceFaceDensity,                     &
                                              AtmosphericExplicit,                    &
                                              TidePotentialExplicit
        
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB, BarotropicRadia

        !Begin---------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        DT_Velocity          =  Me%Velocity%DT
        DT_Elevation         =  Me%WaterLevel%DT

        Num_Discretization   =  Me%ComputeOptions%Num_Discretization

        BarotropicRadia      =  Me%ComputeOptions%BarotropicRadia

        DCoef_2D             => Me%Coef%D2%D
        ECoef_2D             => Me%Coef%D2%E
        FCoef_2D             => Me%Coef%D2%F
        TiCoef_2D            => Me%Coef%D2%Ti

        RadCoef_2D           => Me%Coef%D2%Rad
        TiRadCoef_2D         => Me%Coef%D2%TiRad

        !WaterColumn          => Me%External_Var%WaterColumn
        WaterColumnUV        => Me%External_Var%WaterColumnUV
        AtmPressure          => Me%External_Var%AtmosphericPressure
        TidePotentialLevel   => Me%Forces%TidePotentialLevel


        DUX_VY               => Me%External_Var%DUX_VY
        DVY_UX               => Me%External_Var%DVY_UX
        DYY_XX               => Me%External_Var%DYY_XX
        DZX_ZY               => Me%External_Var%DZX_ZY

        Density              => Me%External_Var%Density

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        BoundaryFacesUV      => Me%External_Var%BoundaryFacesUV
        KFloor_UV            => Me%External_Var%KFloor_UV

        Area_UV              => Me%External_Var%Area_UV
        SZZ                  => Me%External_Var%SZZ

        !End - Shorten variables name 

        if (Me%TidePotential%Compute) then
            
            Alpha = Me%TidePotential%Alpha

        else

            Alpha = 1.

        endif



        

    doj: do j = JLB, JUB
    doi: do i = ILB, IUB

    Cov1:   if (ComputeFaces3D_UV(i, j, KUB) == Covered) then

                iSouth     = I - di
                jWest      = J - dj 

                kbottom = KFloor_UV(i, j)

                !WaterColumn_Left  = SZZ(iSouth, jWest, kbottom - 1) - SZZ(iSouth, jWest, KUB)

                !WaterColumn_Right = SZZ(I      , J     , kbottom - 1) - SZZ(I      , J     , KUB)


                !WaterColumn_High  = Face_Interpolation(WaterColumn_Right, WaterColumn_Left, &
                !                                       DUX_VY(I, J), DUX_VY(iSouth, jWest))
                WaterColumn_High   = WaterColumnUV(i, j)

                ![m*s]            = [m] * [m] * [s] / [m] 
                AuxPressure       = WaterColumn_High * DYY_XX(I, J) * &
                                    DT_Velocity / DZX_ZY(iSouth, jWest)

                !Alpha - Deformation "crosta terreste" Tide potential effect
                AuxPressure       = AuxPressure * Alpha


                !The barotropic water pressure effect is consider implicit while the
                !the atmospheric pressure must be explicit 

                !Water Pressure 
                ![m^2/s]     = [m*s] * [m/s^2]
                AuxImplicit  = AuxPressure * Gravity 

                ![s]         = [s] * []
                DT_AUX       = DT_Elevation * Num_Discretization / 2.
            
                !Area of a South or West Z cell 
                ![m^2]       = [m] * [m]
                AreaCell1    = DUX_VY(iSouth, jWest) * DVY_UX(iSouth, jWest)

                !Area of a North or East Z cell 
                ![m^2]       = [m] * [m]
                AreaCell2    = DUX_VY(I,J) * DVY_UX(I,J)

            
                ![s/m^2]     = [s] / [m^2]
                DT_AreaCell1 = DT_AUX / AreaCell1
                
                ![s/m^2]     = [s] / [m^2]
                DT_AreaCell2 = DT_AUX / AreaCell2


                !Atmospheric pressure
                
                if (Me%ComputeOptions%AtmPressure) then

                    !It should be use the average density of the water column to compute 
                    !atmospheric pressure effect but for speed up the program and to simplify the
                    !code was used the surface density. This aproximation dosen't introduce 
                    !a large error (<0.3 %).

                    if (Me%ComputeOptions%LocalDensity) then

                        ![M/m^3]
                        SurfaceFaceDensity = Face_Interpolation(Density(I,       J,      KUB), &
                                                                Density(iSouth, jWest, KUB), &
                                                                DUX_VY (I,       J),           &
                                                                DUX_VY (iSouth, jWest))
                    else

                        SurfaceFaceDensity = SigmaDensityReference

                    endif


                    ![m^3/s]                  = [m*s]       *  [M*m/s^2/m^2] / [M/m^3] 
                    AtmosphericExplicit       = AuxPressure * (AtmPressure(iSouth, jWest) -     &
                                                               AtmPressure(I, J)) / SurfaceFaceDensity
                else

                    AtmosphericExplicit       = 0.

                endif

                !Tide potential pressure
                ![m^3/s]                  = [m*s]       * [m/s^2] * [m] 
                TidePotentialExplicit     = - AuxPressure * Gravity * (TidePotentialLevel(iSouth, jWest) - &
                                              TidePotentialLevel(I, J)) 


                AuxExplicit               = AtmosphericExplicit + TidePotentialExplicit 

ic1:            if (Me%CyclicBoundary%ON .and. (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                                                Me%CyclicBoundary%Direction == DirectionXY_))  then


                    call CyclicCoef2D ( TiCoef_2D,                                       &
                                       AuxExplicit, DT_AreaCell1,                        &
                                       DT_AreaCell2, I, J, iSouth, jWest,                &
                                       Dcoef_2D, ECoef_2D, FCoef_2D, AuxImplicit)

                else ic1

                    ![ ]                      = [ ]                        +  [m^2/s]    * [s/m^2]
                    DCoef_2D(I, J)            = DCoef_2D(I, J)             - AuxImplicit * DT_AreaCell2 
                
                    ![ ]                      = [ ]                        +  [m^2/s]    * [s/m^2]
                    ECoef_2D(I, J)            = ECoef_2D(I, J)             + AuxImplicit * DT_AreaCell2 

                    ![ ]                      = [ ]                        +  [m^2/s]    * [s/m^2]
                    FCoef_2D(iSouth, jWest) = FCoef_2D(iSouth, jWest)  - AuxImplicit * DT_AreaCell1 

                    ![ ]                      = [ ]                        +  [m^2/s]    * [s/m^2]
                    ECoef_2D(iSouth, jWest) = ECoef_2D(iSouth, jWest)  + AuxImplicit * DT_AreaCell1 
           
           
                    ![m]                      = [m]                        + [m^3/s] * [s/m^2]
                    TiCoef_2D (I, J)          = TiCoef_2D(I, J)            + AuxExplicit * DT_AreaCell2 

                    ![m]                      = [m]                        + [m^3/s] * [s/m^2]
                    TiCoef_2D(iSouth, jWest)= TiCoef_2D(iSouth, jWest) - AuxExplicit * DT_AreaCell1 

                endif ic1


                if ((BarotropicRadia == FlatherWindWave_       .or.                      &
                     BarotropicRadia == FlatherLocalSolution_) .and.                     &
                     BoundaryFacesUV(I, J) == Boundary) then
                    ![m^3/s]
                    TiRadCoef_2D (I, J)   = TiRadCoef_2D(I, J   )      + AuxExplicit * Num_Discretization / 2.

                   ![m^2/s] 
                    RadCoef_2D   (I, J)   = RadCoef_2D(I, J)           + AuxImplicit * Num_Discretization / 2.

                endif 

            endif Cov1

        enddo doi
        enddo doj

        !Nullify auxiliar pointers 
        nullify(DCoef_2D)
        nullify(ECoef_2D)   
        nullify(FCoef_2D)   
        nullify(TiCoef_2D)  
        
        nullify(RadCoef_2D)   
        nullify(TiRadCoef_2D)  

        nullify(WaterColumnUV)
        nullify(AtmPressure)

        nullify(TidePotentialLevel)

        nullify(Density) 

        nullify(DYY_XX)
        nullify(DUX_VY)
        nullify(DVY_UX)
        nullify(DZX_ZY)

        nullify(ComputeFaces3D_UV)
        nullify(KFloor_UV)
        nullify(BoundaryFacesUV)

        nullify(Area_UV)

        nullify(SZZ)



    end Subroutine WaterLevel_BarotropicPressure

    !------------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! This suborutine computes the bottom friction effect in the water level calculation   !
    !                                                                                      !
    ! Input : Geomtry, Flow, Mapping, Time steps                                           !
    ! OutPut: Coefficients of the  linear system equation                                  !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine WaterLevel_BottomFriction 
        
        !Variables Categories  
            !Geometry  : Volume_UV, Area_UV, DUX_VY, DVY_UX, DXX_YY, DYY_XX, DZX_ZY  
            !Flow      : Velocity_UV_Old, Velocity_VU_Old, Vert_Viscosity
            !WaterProp : Density
            !Boundary  : AtmPressure, Chezy
            !Forces    : Horizontal_Transport, Rox3, 
            !Time      : DT_Elevation, DT_Velocity
            !Mapping   : ComputeFaces3D_UV, KFloor_UV, Direction
            !Equations : DCoef_2D, ECoef_2D, FCoef_2D, TiCoef_2D
            
         
        !Variables Direction Dependent
            !Volume_UV, Area_UV, DUX_VY, DVY_UX, DXX_YY, DYY_XX, DZX_ZY
            !Velocity_UV_Old, Velocity_VU_Old, ComputeFaces3D_UV, KFloor_UV, Direction 
        

        !Arguments------------------------------------------------------------



        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Volume_UV, Horizontal_Transport
        real(8), dimension(:,:  ), pointer :: ECoef_2D

        real,    dimension(:,:,:), pointer :: Area_UV, Velocity_UV_Old, Velocity_VU_New, &
                                              Density, Inertial_Aceleration, Rox3XY,     &
                                              Vertical_Viscosity, DUZ_VZ,                &
                                              Relax_Aceleration, PressureCorrect

        real,    dimension(:,:  ), pointer :: DCoef_2D, FCoef_2D, TiCoef_2D,             &
                                              DUX_VY, DVY_UX, DYY_XX, DZX_ZY, DXX_YY,    & 
                                              ChezyVelUV, AtmPressure, RadCoef_2D,       &
                                              TiRadCoef_2D, TidePotentialLevel,          &
                                              WaterColumnUV  

        !Manuel
        real                               :: visc_bottom_max


        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV, BoundaryFacesUV

        real                               :: DT_Velocity, DT_Elevation, Num_Discretization, &
                                              Alpha, Transport_Aceleration

        integer                            :: I, J, kbottom, di, dj, iSouth, I_North, J_East, jWest

        real                               :: FC, FC_Area, VelModXY, FaceDensity,        &
                                              DUZ, ViscAux, AuxImplicit, AuxExplicit,    &
                                              DT_AUX, DT_AreaCell1, DT_AreaCell2,        &
                                              AreaCell1, AreaCell2, BottomViscCoef      !, CoefRelax

        real                               :: WaterColumn2D


        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB, BarotropicRadia
    
        !Begin---------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        DT_Velocity          =  Me%Velocity%DT
        DT_Elevation         =  Me%WaterLevel%DT

        Num_Discretization   =  Me%ComputeOptions%Num_Discretization

        BarotropicRadia      =  Me%ComputeOptions%BarotropicRadia
        BottomViscCoef       =  Me%ComputeOptions%BottomViscCoef
        WaterColumn2D        =  Me%ComputeOptions%WaterColumn2D

        DCoef_2D             => Me%Coef%D2%D
        ECoef_2D             => Me%Coef%D2%E
        FCoef_2D             => Me%Coef%D2%F
        TiCoef_2D            => Me%Coef%D2%Ti

        RadCoef_2D           => Me%Coef%D2%Rad
        TiRadCoef_2D         => Me%Coef%D2%TiRad

        Horizontal_Transport => Me%Forces%Horizontal_Transport
        Inertial_Aceleration => Me%Forces%Inertial_Aceleration
        Rox3XY               => Me%Forces%Rox3XY
        TidePotentialLevel   => Me%Forces%TidePotentialLevel
        Relax_Aceleration    => Me%Forces%Relax_Aceleration

        AtmPressure          => Me%External_Var%AtmosphericPressure
        ChezyVelUV           => Me%External_Var%ChezyVelUV

        DUX_VY               => Me%External_Var%DUX_VY
        DVY_UX               => Me%External_Var%DVY_UX
        DYY_XX               => Me%External_Var%DYY_XX
        DXX_YY               => Me%External_Var%DXX_YY
        DZX_ZY               => Me%External_Var%DZX_ZY

        Density              => Me%External_Var%Density

        Volume_UV            => Me%External_Var%Volume_UV
        Area_UV              => Me%External_Var%Area_UV
        DUZ_VZ               => Me%External_Var%DUZ_VZ
        WaterColumnUV        => Me%External_Var%WaterColumnUV

        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old
        Velocity_VU_New      => Me%Velocity%Horizontal%VU%New

        Vertical_Viscosity   => Me%External_Var%Vertical_Viscosity

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        BoundaryFacesUV      => Me%External_Var%BoundaryFacesUV
        KFloor_UV            => Me%External_Var%KFloor_UV

        PressureCorrect      => Me%NonHydrostatic%PressureCorrect


        !End - Shorten variables name 


        if (Me%TidePotential%Compute) then
            
            Alpha = Me%TidePotential%Alpha

        else

            Alpha = 1.

        endif

        

    doj: do j = JLB, JUB
    doi: do i = ILB, IUB

    Cov1:   if (ComputeFaces3D_UV(i, j, KUB) == Covered) then

                iSouth     = I - di
                jWest      = J - dj 

                ! This values (i_North and j_east) can only be used to compute the velocity modulus in a face
                I_North     = I + dj
                J_East      = J + di

                kbottom     = KFloor_UV(I, J)

                VelModXY    = Face_Velocity_Modulus(Velocity_VU_New(I_North, jWest, kbottom), &
                                                    Velocity_VU_New(I_North, J_East, kbottom), &
                                                    Velocity_VU_New(iSouth, jWest, kbottom), &
                                                    Velocity_VU_New(iSouth, J_East, kbottom), &
                                                    DXX_YY(I_North, jWest),               &
                                                    DXX_YY(I_North, J_East),               &
                                                    DXX_YY(iSouth, jWest),               &
                                                    DXX_YY(iSouth, J_East),               &
                                                    Velocity_UV_Old(I,J,kbottom))
            
                !FC (FrictionCoefficient) is a non-dimensional coefficient
!                FC          = FrictionCoefficient(Chezy(iSouth, jWest) , Chezy (I, J), &
!                                                 DUX_VY(iSouth, jWest), DUX_VY(I, J), &
!                                                 VelModXY, DT_Velocity,                 &     
!                                                 DZX_ZY(iSouth, jWest), DYY_XX(I, J), &
!                                                 Volume_UV(I, J, kbottom))

                !FC (FrictionCoefficient) is a non-dimensional coefficient
                !FC = FB - 1 (FB - Backhaus friction coefficient )

                ![]         = [s] * [m] * [m] * [] * [m/s] / [m^3]
                !FC          = 1. / (1. + DT_Velocity * DZX_ZY(iSouth, jWest) *         &
                !              DYY_XX(I, J) * ChezyVelUV(I, J) * VelModXY /                  &
                !              Volume_UV(I, J, kbottom)) - 1.      

                ![]         =  []
                FC          = 1. / (1. + ChezyVelUV(I, J)) - 1.      


    
                FC_Area     = FC * Area_UV(I, J, kbottom) ! [m^2]

                ! Corrections to all terms of the bottom layer due to bottom friction (See Mesh3D technical manual)

                !Implicit effects : barotropic water pressure
                !Alpha - Deformation "crosta terreste" Tide potential effect

                ![m^2/s]    = [m^2] * [s] * [m/s^2] / [m] 
                AuxImplicit = FC_Area * DT_Velocity * Gravity / DZX_ZY(iSouth, jWest) * Alpha


                !Explicit effects
                ![m^3/s]
                AuxExplicit  = 0.   

                !WaterFlow in the bottom layer
                ![m^3/s]     = [m^3/s]      + [m^2]*[m/s] 
                AuxExplicit  = AuxExplicit  + FC_Area * Velocity_UV_Old(I, J, kbottom) 


                if (Me%ComputeOptions%LocalDensity) then

                    ![M/m^3]
                    FaceDensity = Face_Interpolation(Density(I,J,kbottom), Density(iSouth, jWest,kbottom), &
                                                     DUX_VY(I, J), DUX_VY(iSouth, jWest))

                else
                    ![M/m^3]
                    FaceDensity = SigmaDensityReference

                endif


                !Atmospheric pressure 

                if (Me%ComputeOptions%AtmPressure) then

                    ![m^3/s]     = [m^2] * [s] * [M*m/s^2/m^2] / [M/m^3] / [m]  
                    AuxExplicit  = AuxExplicit  + FC_Area * DT_Velocity *              &
                                                  (AtmPressure(iSouth, jWest) -      &
                                                  AtmPressure(I,J))/                   &
                                                  FaceDensity / DZX_ZY(iSouth, jWest)
                endif


                !Tide potential pressure
                ![m^3/s]                  =   [m^2] * [s] * [m/s^2] * [m] / [m]
                AuxExplicit  = AuxExplicit  - FC_Area * DT_Velocity * Gravity *              &
                                              (TidePotentialLevel(iSouth, jWest) -         &
                                              TidePotentialLevel(I, J)) / DZX_ZY(iSouth, jWest)


                !Aceleration due to Horizontal transport = advection + diffusion
                ![m/s^2]              = [m^4/s^2] / [m^3]                
                Transport_Aceleration = Horizontal_Transport (I, J, kbottom) /               &
                                        Volume_UV(I, J, kbottom)


                !Horizontal Transport in the bottom layer = Advection, diffusion 
                ![m^3/s]     = [m^3/s]      +  [m^2]  * [s]  * [m/s^2]
                AuxExplicit  = AuxExplicit  + FC_Area * DT_Velocity *                             &
                                              Transport_Aceleration
!                                              Horizontal_Transport(I, J, kbottom) / &
!                                              DZX_ZY(iSouth, jWest)

                !Coriolis and centrifugal force in the bottom layer
                ![m^3/s]     = [m^3/s]      + [m^2]   * [s]         * [m/s^2]

                AuxExplicit  = AuxExplicit  + FC_Area * DT_Velocity *                    &
                                              Inertial_Aceleration(I, J, kbottom)
                                             
                if (Me%Relaxation%Force)                                    &
                    ![m^3/s]     = [m^3/s]      + [m^2]   * [s]         * [m/s^2]
                    AuxExplicit  = AuxExplicit  + FC_Area * DT_Velocity *                &
                                                  Relax_Aceleration(I, J, kbottom)

                if(Me%ComputeOptions%Obstacle)                                           &
                    ![m^3/s]     = [m^3/s]      + [m^2]   * [s]         * [m/s^2]
                    AuxExplicit  = AuxExplicit  + FC_Area * DT_Velocity *                &
                                                  Me%Forces%ObstacleDrag_Aceleration(I, J, kbottom)

                !baroclinic pressure in the bottom layer
                ![m^3/s]     = [m^3/s]      + [m^2] * [s] * [M/m^3] * [m/s^2] / [M/m^3]  
                AuxExplicit  = AuxExplicit  + FC_Area * DT_Velocity *                    &
                                              Rox3XY(I, J, kbottom)   * Gravity / FaceDensity

                if (Me%NonHydrostatic%ON) then

                    ![m^3/s]           = [m^3/s] +  [m^2] * [m^2/s^2] / [m] * [s] * []
                    AuxExplicit = AuxExplicit +  FC_Area *                              &
                                         (PressureCorrect(iSouth, jWest, kbottom)   -   &
                                          PressureCorrect(I      , J     , kbottom))/   &
                                          DZX_ZY(iSouth, jWest) * DT_Velocity       *   &
                                          (1. - Me%NonHydrostatic%ThetaUV)

                endif


                ! Shear stress between the first and the second layer
    kmax1:      if (KUB > kbottom) then
                    ![m^2/s]

                     ! Manuel Remember that viscosities are defined at faces.
                     VISCAUX = Face_Interpolation(Vertical_Viscosity(I, J, kbottom+1),            &
                                                 Vertical_Viscosity(iSouth, jWest, kbottom+1), &
                                                 DUX_VY(I, J), DUX_VY(iSouth, jWest))

                     ! Vertical distance between the velocities "Velocity_X kbottom +1" and "Velocity_X kbottom"
                     DUZ = (DUZ_VZ(I, J, kbottom + 1) + DUZ_VZ(I, J, kbottom)) / 2.0

                     !Limitation of bottom viscosity due to the semi-implicit discretization of bottom friction. MRV
                     if (Me%ComputeOptions%BottomVisc_LIM ) then

                         visc_bottom_max  = BottomViscCoef * DUZ_VZ(I, J, kbottom) * DUZ / 2. / DT_Velocity
                         

                         VISCAUX          = min(VISCAUX,visc_bottom_max)
                    
                    end if


                    !This formulation assumes that AreaUV / VolumeUV = DZX_ZY, because
                    !is the only way of cancel the vertical diffusion and advection terms. 
                    !However, this relation is not true when AreaUV is computed using the 
                    !minimum thickness metodology.    

                    
                    ![m^3/s]    = [m^3/s]     + [ ]* [s] * [m] * [m^2/s] * [m/s] / [m]  
                    AuxExplicit = AuxExplicit + FC * DT_Velocity * DYY_XX(i, j) * VISCAUX * &
                                                (Velocity_UV_Old(I, J, kbottom+1) -         &
                                                 Velocity_UV_Old(I, J, kbottom)) / DUZ 
                endif kmax1

                DT_Aux = DT_Elevation * Num_Discretization / 2.  

                !Area of a South or West Z cell
                ![m^2]
                AreaCell1 = DUX_VY(iSouth, jWest) * DVY_UX(iSouth, jWest)

                !Area of a North or East Z cell
                ![m^2]
                AreaCell2 = DUX_VY(I,J) * DVY_UX(I,J)

                ![s/m^2]
                DT_AreaCell1 = DT_Aux / AreaCell1  

                ![s/m^2]
                DT_AreaCell2 = DT_Aux / AreaCell2  


ic1:            if (Me%CyclicBoundary%ON .and. (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                                                Me%CyclicBoundary%Direction == DirectionXY_)) then

                    call CyclicCoef2D ( TiCoef_2D,                                       &
                                       AuxExplicit, DT_AreaCell1,                        &
                                       DT_AreaCell2, I, J, iSouth, jWest,                &
                                       Dcoef_2D, ECoef_2D, FCoef_2D, AuxImplicit)

                else ic1

                    !Compute the coeficients of linear system equations for the I,J Z cell
                    ![ ]                   = [ ]         + [m^2/s] * [s/m^2]
                    DCoef_2D(I,J)             = DCoef_2D(I,J)  - AuxImplicit * DT_AreaCell2
                
                    ![ ]                   = [ ]         + [m^2/s] * [s/m^2]
                    ECoef_2D (I,J)            = ECoef_2D(I,J)  + AuxImplicit * DT_AreaCell2

                    ![m]                   = [m]         + [m^3/s] * [s/m^2] 
                    TiCoef_2D(I,J)            = TiCoef_2D(I,J) + AuxExplicit * DT_AreaCell2

                    !Compute the coeficients of linear system equations for the iSouth, jWest Z cell

                    ![ ]                   = [ ]                     + [m^2/s] * [s/m^2] 
                    FCoef_2D(iSouth, jWest) = FCoef_2D(iSouth, jWest)  - AuxImplicit * DT_AreaCell1

                    ![ ]                   = [ ]                     + [m^2/s] * [s/m^2] 
                    ECoef_2D(iSouth, jWest) = ECoef_2D(iSouth, jWest)  + AuxImplicit * DT_AreaCell1

                    ![m]                   = [m]                     + [m^3/s] * [s/m^2] 
                    TiCoef_2D(iSouth, jWest)= TiCoef_2D(iSouth, jWest) - AuxExplicit * DT_AreaCell1

                endif ic1


                !PCL - New changes
                if ((BarotropicRadia == FlatherWindWave_       .or.                    &
                     BarotropicRadia == FlatherLocalSolution_) .and.                   &
                     BoundaryFacesUV(I, J) == Boundary) then

                    ![m^3/s]
                    TiRadCoef_2D (I, J) = TiRadCoef_2D(I, J) + AuxExplicit * Num_Discretization / 2.

                   ![m^2/s] 
                    RadCoef_2D   (I, J) = RadCoef_2D  (I, J) + AuxImplicit * Num_Discretization / 2.

                endif 


            endif Cov1
   

        enddo doi
        enddo doj

        !Nullify auxiliar pointers 
        nullify(DCoef_2D)
        nullify(ECoef_2D)   
        nullify(FCoef_2D)   
        nullify(TiCoef_2D)  

        nullify(RadCoef_2D)   
        nullify(TiRadCoef_2D)  
        
        nullify(AtmPressure)

        nullify(Density) 

        nullify(DYY_XX)
        nullify(DUX_VY)
        nullify(DVY_UX)
        nullify(DZX_ZY)
        nullify(DXX_YY)

        nullify(ComputeFaces3D_UV)
        nullify(KFloor_UV)
        nullify(BoundaryFacesUV)

        nullify(Horizontal_Transport)
        nullify(Inertial_Aceleration)
        nullify(Relax_Aceleration   )
        nullify(Rox3XY)
        nullify(TidePotentialLevel)

        nullify(ChezyVelUV)

        nullify(Volume_UV)
        nullify(Area_UV  )
        nullify(DUZ_VZ   )

        nullify(Velocity_UV_Old)
        nullify(Velocity_VU_New)

        nullify(Vertical_Viscosity)


    end Subroutine WaterLevel_BottomFriction

    !------------------------------------------------------------------------------

    function Face_Interpolation(X,Y,DX,DY)

        !Arguments
        real ::  Face_Interpolation, X,Y,DX,DY
    
        !Begin---------------------------------------------------------------------

        Face_Interpolation = (X*DY+Y*DX)/(DX+DY)

    end function Face_Interpolation

    !------------------------------------------------------------------------------

    function Face_Velocity_Modulus(VelVU1, VelVU2, VelVU3, VelVU4, &
                                         DXY1, DXY2, DXY3, DXY4, VelUV)

        !Arguments      
        real :: Face_Velocity_Modulus, VelVU1, VelVU2, VelVU3, VelVU4, &
                DXY1, DXY2, DXY3, DXY4, VelUV

        !Local     
        real :: VU1, VU2, VU12

        !Begin---------------------------------------------------------------------
             
        !X - Direction i,j,kbottom face
        !
        !V1 = (Velocity_Y(I+1,J-1,kbottom)*DXX(I+1,J)+Velocity_Y(I+1,J,kbottom)* &
        !      DXX(I+1,J-1))/(DXX(I+1,J)+DXX(I+1,J-1))


        VU1 = Face_Interpolation(VelVU1, VelVU2, DXY1, DXY2)

        !X - Direction i,j,kbottom face
        !
        !V2 = (Velocity_Y(I,J-1,kbottom)*DXX(I,J)+Velocity_Y(I,J,kbottom)*       &
        !      DXX(I,J-1))/(DXX(I,J)+DXX(I,J-1))

        VU2 = Face_Interpolation(VelVU3, VelVU4, DXY3, DXY4)
           
        VU12= (VU1 + VU2)/2.

        Face_Velocity_Modulus = abs(cmplx(VelUV, VU12))
!        Face_Velocity_Modulus = SQRT(VelUV*VelUV + VU12*VU12)


    end function Face_Velocity_Modulus


    !------------------------------------------------------------------------------

    function FrictionCoefficient(Chezy1, Chezy2, DUV1, DUV2, VelMod, DT, &
                                       DZXY, DYX, Volume_UV)

        !Arguments
          real    :: FrictionCoefficient, Chezy1, Chezy2, DUV1, DUV2, VelMod, &
                     DT, DZXY, DYX
          real(8) :: Volume_UV

        ! Local
          real :: D

        !Begin---------------------------------------------------------------------


        !X - Direction i,j face
        !
        !D  = (CHEZY(I,J)*DUX(I,J-1)+CHEZY(I,J-1)*DUX(I,J))/         &
        !                 (DUX(I,J-1)+DUX(I,J))

        D = Face_Interpolation(Chezy1,Chezy2,DUV1,DUV2)

        !X - Direction i,j,kbottom face

        !FrictionCoefficient = 1./(1. + DT*DZX(I,J-1)*DYY(I,J)/Volume_U(I,J,kbottom)*D*VelMod)-1.      


        FrictionCoefficient = 1./(1. + DT*DZXY*DYX*D*VelMod/Volume_UV)-1.      


    End function FrictionCoefficient


    !------------------------------------------------------------------------------
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !The effect of all explicit forces in the elevation calculation is compute             !
    !in this subroutine except the atmospheric pressure that is compute in the             !
    ! WaterLevel_BarotropicPressure subroutine                                             !             !
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping, Time steps                                          !
    ! OutPut: Coefficients of the  linear system equation                                  !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine WaterLevel_ExplicitForces    
        
        !Variables Categories  
            !Geometry  : Area_UV, DUX_VY, DVY_UX, DYY_XX, DZX_ZY
            !WaterProp : Density
            !Forces    : Horizontal_Transport, Rox3, TauWind_UV, Inertial_Aceleration 
            !Time      : DT_Elevation, DT_Velocity
            !Mapping   : ComputeFaces3D_UV, KFloor_UV, Direction
            !Equations : TiCoef_2D

         
        !Variables Direction Dependent
            !TauWind_UV, Area_UV, DUX_VY, DVY_UX, DYY_XX, DZX_ZY
            !ComputeFaces3D_UV, KFloor_UV, Direction
        

        !Arguments------------------------------------------------------------



        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: Horizontal_Transport, Volume_UV

        real,    dimension(:,:,:), pointer :: Area_UV, Density, Inertial_Aceleration,    &
                                              Rox3XY, Relax_Aceleration, PressureCorrect,&
                                              DUZ_VZ

        real,    dimension(:,:  ), pointer :: TiCoef_2D, TiRadCoef_2D, DUX_VY, DVY_UX,   &
                                              DYY_XX, DZX_ZY, TauWind_UV, TauWaves_UV,   &
                                              WaterColumnUV

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV
        integer, dimension(:,:),   pointer :: KFloor_UV, BoundaryFacesUV

        real                               :: DT_Velocity, DT_Elevation, Num_Discretization     

        integer                            :: I, J, K, kbottom, di, dj, iSouth, jWest

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB, BarotropicRadia


        real                               :: FaceDensity, SurfaceFaceDensity, AuxExplicit, &
                                              DT_AUX, DT_AreaCell1, DT_AreaCell2,           &
                                              AreaCell1, AreaCell2, TauFace,                &
                                              Transport_Aceleration, SmoothCoef, RunPeriod, &
                                              Aux_2D

        !Begin---------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        DT_Velocity          =  Me%Velocity%DT
        DT_Elevation         =  Me%WaterLevel%DT

        Num_Discretization   =  Me%ComputeOptions%Num_Discretization


        BarotropicRadia      =  Me%ComputeOptions%BarotropicRadia


        TiCoef_2D            => Me%Coef%D2%Ti

        TiRadCoef_2D         => Me%Coef%D2%TiRad

        Horizontal_Transport => Me%Forces%Horizontal_Transport
        Inertial_Aceleration => Me%Forces%Inertial_Aceleration
        Relax_Aceleration    => Me%Forces%Relax_Aceleration
        Rox3XY               => Me%Forces%Rox3XY

        DUX_VY               => Me%External_Var%DUX_VY
        DVY_UX               => Me%External_Var%DVY_UX
        DYY_XX               => Me%External_Var%DYY_XX
        DZX_ZY               => Me%External_Var%DZX_ZY

        Density              => Me%External_Var%Density

        TauWind_UV           => Me%External_Var%TauWind_UV

        Area_UV              => Me%External_Var%Area_UV
        Volume_UV            => Me%External_Var%Volume_UV

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        KFloor_UV            => Me%External_Var%KFloor_UV
        BoundaryFacesUV      => Me%External_Var%BoundaryFacesUV

        PressureCorrect      => Me%NonHydrostatic%PressureCorrect

        TauWaves_UV          => Me%External_Var%TauWaves_UV
        DUZ_VZ               => Me%External_Var%DUZ_VZ
        WaterColumnUV        => Me%External_Var%WaterColumnUV

        !End - Shorten variables name 
        


    doj: do j = JLB, JUB
    doi: do i = ILB, IUB

    Cov1:   if (ComputeFaces3D_UV(i, j, KUB) == Covered) then

                iSouth     = I - di
                jWest      = J - dj 


                kbottom     = KFloor_UV(I, J)
       
                AuxExplicit  = 0.

                if (Me%ComputeOptions%WaveStress) then 

                    TauFace  = Face_Interpolation(TauWaves_UV(I,J), TauWaves_UV(iSouth, jWest), &
                                          DUX_VY(I, J), DUX_VY(iSouth, jWest))


                    ![M * m/s] = [M*m/s^2/m^2] * [m] * [m] * [s] 
                    Aux_2D =   TauFace * DZX_ZY(iSouth, jWest) * DYY_XX(I, J)* DT_Velocity 

                endif


dok:            do  k = kbottom, KUB

                    if (Me%ComputeOptions%LocalDensity) then

                        ![M/m^3]                
                        FaceDensity  = Face_Interpolation(Density(I,J,K), Density(iSouth, jWest,K), &
                                                          DUX_VY(I, J), DUX_VY(iSouth, jWest))

                    else
                        ![M/m^3]
                        FaceDensity = SigmaDensityReference

                    endif

                    !Horizontal Transport - Advection, diffusion

                    !Aceleration due to Horizontal transport = advection + diffusion
                    ![m/s^2]              = [m^4/s^2] / [m^3]                
                    Transport_Aceleration = Horizontal_Transport (I, J, K) /             &
                                            Volume_UV(I, J, K)



                    ![m^3/s]     = [m^3/s]      + [s] * [m/s^2] * [m^2]
                    AuxExplicit  = AuxExplicit  + DT_Velocity * Transport_Aceleration *  &   
                                                  Area_UV(I, J, K)
                                                  ![m^3/s*m/s] / [m]
                                                  !Horizontal_Transport(I, J, K) / &
                                                  !DZX_ZY(iSouth, jWest)


                    !Coriolis and centrifugal force 

                    ![m^3/s]     = [m^3/s]      +     [s]     * [m/s^2] * [m^2]
                    AuxExplicit  = AuxExplicit  + DT_Velocity * Inertial_Aceleration(I, J, K) * &
                                                  Area_UV(I, J, K)

                    !Relaxation Force

                    if (Me%Relaxation%Force)                                &
                        ![m^3/s]     = [m^3/s]      +     [s]     * [m/s^2] * [m^2]
                        AuxExplicit  = AuxExplicit  + DT_Velocity * Relax_Aceleration(I, J, K) * &
                                                      Area_UV(I, J, K)

                    if(Me%ComputeOptions%Obstacle)                                           &
                        ![m^3/s]     = [m^3/s]      +     [s]     * [m^2]  * [m/s^2]
                        AuxExplicit  = AuxExplicit  + DT_Velocity * Area_UV(I, J, K)   *     &
                                                      Me%Forces%ObstacleDrag_Aceleration(I, J, K) 

                    !Baroclinic pressure

                    ![m^3/s]     = [m^3/s]      + [m^2] * [s] * [M/m^3] * [m/s^2] / [M/m^3]
                    AuxExplicit  = AuxExplicit  + Area_UV(I, J, K) * DT_Velocity *      &
                                                  Rox3XY (I, J, K) *                    &
                                                  Gravity / FaceDensity

                    if (Me%NonHydrostatic%ON) then

                        ![m^3/s]           = [m^3/s] +  [m^2] * [m^2/s^2] / [m] * [s] * []
                        AuxExplicit = AuxExplicit +  Area_UV(I, J, K) *                 &
                                             (PressureCorrect(iSouth, jWest, K) -       &
                                              PressureCorrect(I      , J     , K))/     &
                                              DZX_ZY(iSouth, jWest) * DT_Velocity *     &
                                             (1. - Me%NonHydrostatic%ThetaUV)

                    endif


                    if (Me%ComputeOptions%WaveStress) then 

                        ![m^3/s]           = [m^3/s] +  [m^2]        * [M * m/s] / [M/m^3] / [m^3] * [m] / [m]
                        AuxExplicit = AuxExplicit +  Area_UV  (I, J, K) * Aux_2D / FaceDensity  / &
                                                     Volume_UV(i, j, k) * DUZ_VZ(i, j, k) / WaterColumnUV(i, j)

                    endif


                
                enddo dok


                !Wind Shear Stress
                if (Me%ComputeOptions%Wind /= NoWind_) then

                    !The last k of the dok Cyclic is KUB - surface layer
                    SurfaceFaceDensity = FaceDensity


                    SmoothCoef = 1.
                    
                    if (Me%ComputeOptions%Wind == InitialSmoothWind_) then

                        RunPeriod = Me%CurrentTime - Me%BeginTime

                        if (RunPeriod < Me%ComputeOptions%SmoothInitialPeriod) then

                            SmoothCoef = RunPeriod / Me%ComputeOptions%SmoothInitialPeriod


                        endif

                    endif


                    TauFace  = Face_Interpolation(TauWind_UV(I,J), TauWind_UV(iSouth, jWest), &
                                                  DUX_VY(I, J), DUX_VY(iSouth, jWest))

                    TauFace  = TauFace * SmoothCoef

                    ![m^3/s]     = [m^3/s]     + [M*m/s^2/m^2] * [m] * [s] / [M/m^3]
                    AuxExplicit  = AuxExplicit + TauFace * DYY_XX(I, J) *                       &
                                                 DT_Velocity / SurfaceFaceDensity        
                endif


                DT_Aux = DT_Elevation * Num_Discretization / 2.

                !Area of a South or West Z cell
                AreaCell1 = DUX_VY(iSouth, jWest) * DVY_UX(iSouth, jWest)

                !Area of a North or East Z cell
                AreaCell2 = DUX_VY(I,J) * DVY_UX(I,J)

                DT_AreaCell1 = DT_Aux / AreaCell1   ![s/m^2]

                DT_AreaCell2 = DT_Aux / AreaCell2   ![s/m^2]



                !Compute the coeficients of linear system equations for the I,J Z cell

ic1:            if (Me%CyclicBoundary%ON .and. (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                                                Me%CyclicBoundary%Direction == DirectionXY_)) then


                    call CyclicCoef2D ( TiCoef_2D,                                       &
                                       AuxExplicit, DT_AreaCell1,                        &
                                       DT_AreaCell2, I, J, iSouth, jWest)
                else ic1


                    ![m]                   = [m]         + [m^3/s]     * [s/m^2]
                    TiCoef_2D(I,J)            = TiCoef_2D(I,J) + AuxExplicit * DT_AreaCell2

                    !Compute the coeficients of linear system equations for the iSouth, jWest Z cell

                    ![m]                   = [m]                     + [m^3/s]     * [s/m^2]
                    TiCoef_2D(iSouth, jWest)= TiCoef_2D(iSouth, jWest) - AuxExplicit * DT_AreaCell1

                endif ic1

                !PCL - New changes
                if ((BarotropicRadia == FlatherWindWave_       .or.                    &
                     BarotropicRadia == FlatherLocalSolution_) .and.                   &
                     BoundaryFacesUV(I, J) == Boundary) then

                    ![m^3/s]
                    TiRadCoef_2D (I, J) = TiRadCoef_2D(I, J   ) + AuxExplicit * Num_Discretization / 2.

                endif 



            endif Cov1

        enddo doi
        enddo doj

        !Nullify auxiliar pointers 
        nullify(TiCoef_2D)  

        nullify(TiRadCoef_2D)  


        nullify(Density) 

        nullify(TauWind_UV)

        nullify(TauWaves_UV)

        nullify(DYY_XX)
        nullify(DUX_VY)
        nullify(DVY_UX)
        nullify(DZX_ZY)

        nullify(ComputeFaces3D_UV)
        nullify(KFloor_UV)
        nullify(BoundaryFacesUV)

        nullify(Horizontal_Transport)
        nullify(Inertial_Aceleration)
        nullify(Relax_Aceleration   )
        nullify(Rox3XY)

        nullify(Area_UV  )
        nullify(Volume_UV)
        nullify(DUZ_VZ, WaterColumnUV)



    end Subroutine WaterLevel_ExplicitForces

    !------------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! The effect of all explicit water fluxes in the elevation calculation is compute      !
    ! in this subroutine                                                                   ! 
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping, Time steps                                          !
    ! OutPut: Coefficients of the  linear system equation                                  !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine WaterLevel_WaterFluxes 
    
        
        !Variables Categories  
            !Geometry  : Area_UV, Area_VU, DUX_VY, DVY_UX
            !Flow      : Velocity_UV_Old, Velocity_VU_Old, Velocity_VU_New
            !Time      : DT_Elevation
            !Mapping   : ComputeFaces3D_UV, KFloor_UV, Direction
            !Equations : TiCoef_2D
            !Domain    : KUB, ILB, IUB, JLB, JUB,              
            !Numeric   : Num_Discretization

         
        !Variables Direction Dependent
            !Area_UV, Area_VU, DUX_VY, DVY_UX, Velocity_UV_Old, Velocity_VU_Old, 
            !Velocity_VU_New, ComputeFaces3D_UV, KFloor_UV, Direction
        
        !Arguments------------------------------------------------------------



        !Local---------------------------------------------------------------------

        real,    dimension(:,:,:), pointer :: Velocity_UV_Old, Velocity_UV_New, Area_UV, &
                                              Velocity_VU_Old, Velocity_VU_New, Area_VU

        real,    dimension(:,:  ), pointer :: TiCoef_2D, TiRadCoef_2D, DUX_VY, DVY_UX

        integer, dimension(:,:,:), pointer :: ComputeFaces3D_UV, ComputeFaces3D_VU
        integer, dimension(:,:),   pointer :: KFloor_UV, KFloor_VU, BoundaryFacesUV

        real                               :: DT_Elevation, Num_Discretization

        integer                            :: I, J, K, kbottom, di, dj, iSouth, jWest

        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB, BarotropicRadia


        real                               :: AuxExplicit, DT_AUX, DT_AreaCell1, &
                                              DT_AreaCell2, AreaCell1, AreaCell2

        real                               :: Aux !,CoefRelax

        !Begin---------------------------------------------------------------------

        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        di  = Me%Direction%di
        dj  = Me%Direction%dj

        DT_Elevation         =  Me%WaterLevel%DT

        Num_Discretization   =  Me%ComputeOptions%Num_Discretization

        BarotropicRadia      =  Me%ComputeOptions%BarotropicRadia

        TiCoef_2D            => Me%Coef%D2%Ti

        TiRadCoef_2D         => Me%Coef%D2%TiRad

        DUX_VY               => Me%External_Var%DUX_VY
        DVY_UX               => Me%External_Var%DVY_UX

        Area_VU              => Me%External_Var%Area_VU
        Area_UV              => Me%External_Var%Area_UV

        Velocity_UV_Old      => Me%Velocity%Horizontal%UV%Old
        Velocity_UV_New      => Me%Velocity%Horizontal%UV%New

        Velocity_VU_Old      => Me%Velocity%Horizontal%VU%Old
        Velocity_VU_New      => Me%Velocity%Horizontal%VU%New

        ComputeFaces3D_UV    => Me%External_Var%ComputeFaces3D_UV
        ComputeFaces3D_VU    => Me%External_Var%ComputeFaces3D_VU
        KFloor_UV            => Me%External_Var%KFloor_UV
        KFloor_VU            => Me%External_Var%KFloor_VU
        BoundaryFacesUV      => Me%External_Var%BoundaryFacesUV


        !End - Shorten variables name 

    do1: do j = JLB, JUB
    do2: do i = ILB, IUB

            iSouth = I - di
            jWest  = J - dj


    cd1:    if (ComputeFaces3D_UV(i, j, KUB) == Covered) then
        
                kbottom = KFloor_UV(I, J)

                AuxExplicit  = 0.

    do3:        do  k = kbottom, KUB
                
                    !old U or V water flux
                    Aux = Velocity_UV_Old(I, J, K) * Area_UV (I, J, K) 


                    ![m^3/s]     = [m^3/s]      + [m/s] * [m^2]
                    AuxExplicit  = AuxExplicit  + Aux

                enddo do3

                !Area of a South or West Z cell
                AreaCell1 = DUX_VY(iSouth, jWest) * DVY_UX(iSouth, jWest)

                !Area of a North or East Z cell
                AreaCell2 = DUX_VY(I, J) * DVY_UX(I, J)

                DT_AreaCell1 = DT_Elevation / AreaCell1   ![s/m^2]

                DT_AreaCell2 = DT_Elevation / AreaCell2   ![s/m^2]



                !Compute the coeficients of linear system equations for the I,J Z cell

ic1:            if (Me%CyclicBoundary%ON .and. (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                                                Me%CyclicBoundary%Direction == DirectionXY_)) then


                    call CyclicCoef2D (TiCoef_2D,                                        &
                                       AuxExplicit, DT_AreaCell1,                        &
                                       DT_AreaCell2, I, J, iSouth, jWest)
                else ic1


                    ![m]                   = [m]         + [m^3/s]     * [s/m^2]
                    TiCoef_2D(I, J)           = TiCoef_2D(I      , J     ) + AuxExplicit * DT_AreaCell2

                    !Compute the coeficients of linear system equations for the iSouth, jWest Z cell

                    ![m]                   = [m]                     + [m^3/s]     * [s/m^2]
                    TiCoef_2D(iSouth, jWest)= TiCoef_2D(iSouth, jWest) - AuxExplicit * DT_AreaCell1

                endif ic1


                if ((BarotropicRadia == FlatherWindWave_       .or.                    &
                     BarotropicRadia == FlatherLocalSolution_) .and.                   &
                     BoundaryFacesUV(I, J) == Boundary) then

                    ![m^3/s]
                    TiRadCoef_2D (I, J)   = TiRadCoef_2D(I, J   )  + AuxExplicit

                endif 


            endif cd1

        enddo do2
        enddo do1

    ! Explicit direction 
    do4: do j = JLB, JUB
    do5: do i = ILB, IUB

            iSouth = I - dj
            jWest  = J - di


    cd2:    if (ComputeFaces3D_VU(i, j, KUB) == Covered) then
        
                kbottom = KFloor_VU(I, J)

                AuxExplicit  = 0.

    do6:        do  k = kbottom, KUB
                

                    !Old V or U water flux

                    ![m^3/s]     = [m^3/s]      + [m/s] * [m^2]
                    AuxExplicit  = AuxExplicit  + Velocity_VU_Old(I, J, K) * Area_VU (I, J, K) 
                

                    !New V or U water flux

                    ![m^3/s]     = [m^3/s]      + [m/s] * [m^2]
                    AuxExplicit  = AuxExplicit  + (2. - Num_Discretization) * &
                                                  Velocity_VU_New(I, J, K) * Area_VU (I, J, K) 

                enddo do6


                DT_Aux = DT_Elevation * Num_Discretization / 2.  

                !Area of a South or West Z cell
                AreaCell1 = DUX_VY(iSouth, jWest) * DVY_UX(iSouth, jWest)

                !Area of a North or East Z cell
                AreaCell2 = DUX_VY(I,J) * DVY_UX(I,J)

                DT_AreaCell1 = DT_Aux / AreaCell1   ![s/m^2]

                DT_AreaCell2 = DT_Aux / AreaCell2   ![s/m^2]

                !Compute the coeficients of linear system equations for the I,J Z cell

ic2:            if (Me%CyclicBoundary%ON .and. (Me%CyclicBoundary%Direction == Me%Direction%XY .or. &
                                                Me%CyclicBoundary%Direction == DirectionXY_)) then


                    call CyclicCoef2D (TiCoef_2D,                                        &
                                       AuxExplicit, DT_AreaCell1,                        &
                                       DT_AreaCell2, I, J, iSouth, jWest, Direction = Me%Direction%YX)
                else ic2


                    ![m]                   = [m]         + [m^3/s]     * [s/m^2]
                    TiCoef_2D(I,J)         = TiCoef_2D(I,       J     ) + AuxExplicit * DT_AreaCell2

                    !Compute the coeficients of linear system equations for the iSouth, jWest Z cell

                    ![m]                   = [m]                     + [m^3/s]     * [s/m^2]
                    TiCoef_2D(iSouth, jWest)= TiCoef_2D(iSouth, jWest) - AuxExplicit * DT_AreaCell1
                endif ic2

            endif cd2

        enddo do5
        enddo do4

        !Nullify auxiliar pointers 
        nullify(TiCoef_2D)  

        nullify(TiRadCoef_2D)  

        nullify(DUX_VY)
        nullify(DVY_UX)

        nullify(ComputeFaces3D_UV)
        nullify(ComputeFaces3D_VU)
        nullify(KFloor_UV)
        nullify(KFloor_VU)
        nullify(BoundaryFacesUV)

        nullify(Area_UV)
        nullify(Area_VU)

        nullify(Velocity_UV_Old)
        nullify(Velocity_UV_New)
        nullify(Velocity_VU_Old)
        nullify(Velocity_VU_New)


    end Subroutine WaterLevel_WaterFluxes

    !End------------------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! The effect of all explicit water discharges in the elevation calculation is compute  !
    ! in this subroutine                                                                   ! 
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping, Time steps                                          !
    ! OutPut: Coefficients of the  linear system equation                                  !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine WaterLevelDischarges 
    
        
        !Variables Categories  
            !Geometry  : Area_UV, Area_VU, DUX_VY, DVY_UX
            !Flow      : Velocity_UV_Old, Velocity_VU_Old, Velocity_VU_New
            !Time      : DT_Elevation
            !Mapping   : ComputeFaces3D_UV, KFloor_UV, Direction
            !Equations : TiCoef_2D
            !Domain    : KUB, ILB, IUB, JLB, JUB,              
            !Numeric   : Num_Discretization

         
        !Variables Direction Dependent
            !Area_UV, Area_VU, DUX_VY, DVY_UX, Velocity_UV_Old, Velocity_VU_Old, 
            !Velocity_VU_New, ComputeFaces3D_UV, KFloor_UV, Direction
        
        !Arguments------------------------------------------------------------



        !Local---------------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: DischargeFlow
        real,    dimension(:,:  ), pointer :: TiCoef_2D, DUX, DVY

        integer, dimension(:,:,:), pointer :: WaterPoints3D
        integer, dimension(:,:),   pointer :: KFloor_Z

        real                               :: DT_Elevation

        integer                            :: I, J, K, kbottom

        integer                            :: IUB, ILB, JUB, JLB, KUB


        real                               :: AuxExplicit, DT_AreaCell, AreaCell

        !Begin---------------------------------------------------------------------

cd0:    if (Me%ComputeOptions%SurfaceWaterFlux .or.                         &
            Me%ComputeOptions%WaterDischarges  .or.                         &
            Me%ComputeOptions%BottomWaterFlux) then


            !Begin - Shorten variables name 

            IUB = Me%WorkSize%IUB
            ILB = Me%WorkSize%ILB
            JUB = Me%WorkSize%JUB
            JLB = Me%WorkSize%JLB
            KUB = Me%WorkSize%KUB

            DT_Elevation         =  Me%WaterLevel%DT

            TiCoef_2D            => Me%Coef%D2%Ti
            DischargeFlow        => Me%WaterFluxes%Discharges

            DUX                  => Me%External_Var%DUX
            DVY                  => Me%External_Var%DVY

            WaterPoints3D        => Me%External_Var%WaterPoints3D
            KFloor_Z             => Me%External_Var%KFloor_Z
            !End - Shorten variables name 

do1:        do j = JLB, JUB
do2:        do i = ILB, IUB


cd1:            if (WaterPoints3D(i, j, KUB) == WaterPoint) then
        
                    kbottom = KFloor_Z(I, J)

                    AuxExplicit  = 0.
                    
do3:                do  k = kbottom, KUB
                
                        ![m^3/s]     = [m^3/s]      + [m^3/s]
                        AuxExplicit  = AuxExplicit  + DischargeFlow(i, j, k)

                    enddo do3

                    !Area of a North or East Z cell
                    AreaCell = DUX(I, J) * DVY(I, J)

                    DT_AreaCell = DT_Elevation / AreaCell   ![s/m^2]

                    !Compute the coeficients of linear system equations for the I,J Z cell

                    ![m]             = [m]             + [m^3/s]     * [s/m^2]
                    TiCoef_2D(I, J)  = TiCoef_2D(I, J) + AuxExplicit * DT_AreaCell


                endif cd1

            enddo do2
            enddo do1

            !Nullify auxiliar pointers 

            nullify(TiCoef_2D)  

            nullify(DUX)
            nullify(DVY)

            nullify(WaterPoints3D)
            nullify(KFloor_Z)

            nullify(DischargeFlow)

        endif cd0




    end Subroutine WaterLevelDischarges

    !End------------------------------------------------------------------------------

    !End------------------------------------------------------------------------------
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    ! The effect of all explicit water discharges in the elevation calculation is compute  !
    ! in this subroutine                                                                   ! 
    !                                                                                      !
    ! Input : Geometry, Flow, Mapping, Time steps                                          !
    ! OutPut: Coefficients of the  linear system equation                                  !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine ModifyWaterDischarges

        !Arguments-------------------------------------------------------------


        !Local----------------------------------------------------------------- 
        real,    dimension(:,:  ), pointer :: AddSurfaceWater
        type (T_Time)                      :: CurrentTime

        real                               :: DischargeFlow, AuxFlow
        integer                            :: DischargesNumber, DischargeID, i, j, kd, k, kmin, kmax
        integer                            :: IUB, ILB, JUB, JLB, KUB, KLB
        integer                            :: STAT_CALL, kbottom

        integer, dimension(:,:,:), pointer :: OpenPoints3D, WaterPoints3D
        real(8), dimension(:,:  ), pointer :: BottomWaterFlux
        real,    dimension(:,:  ), pointer :: Bathymetry

        real,    dimension(:,:,:), pointer :: DWZ
        real,    dimension(:,:  ), pointer :: WaterColumnZ
        integer, dimension(:,:  ), pointer :: KFloor_Z

        logical                            :: DischargeUniform

 
        !Begin----------------------------------------------------------------------

        !Begin - Shorten variables name 

        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB
        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB

        OpenPoints3D  => Me%External_Var%OpenPoints3D
        WaterPoints3D => Me%External_Var%WaterPoints3D
        KFloor_Z      => Me%External_Var%KFloor_Z
        DWZ           => Me%External_Var%DWZ
        WaterColumnZ  => Me%External_Var%WaterColumn


       
        do k = KLB, KUB
        do j = JLB, JUB
        do i = ILB, IUB
                        
            Me%WaterFluxes%Discharges(i, j, k) = 0.

        enddo
        enddo
        enddo

        !Water discharge - input of mass in the domain 
cd1:    if (Me%ComputeOptions%WaterDischarges) then

            ! Sinks and Sources
            call GetDischargesNumber(Me%ObjDischarges,&
                                      DischargesNumber, STAT = STAT_CALL)

            if (STAT_CALL/=SUCCESS_)                                                    &
                 stop 'Sub. ModifyWaterDischarges - ModuleHydrodynamic - ERR01'
            
            !Gets a pointer to Bathymetry
            call GetGridData(Me%ObjGridData, Bathymetry, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'ModifyMomentumDischarge - ModuleHydrodynamic - ERR02'

do1:            do DischargeID = 1, DischargesNumber

                call GetDischargesGridLocalization(Me%ObjDischarges,                    &
                     DischargeID, Igrid=I, JGrid=J, KGrid=Kd,                           &
                     DischargeUniform = DischargeUniform,                               &
                     WaterColumnZ = WaterColumnZ,                                       &
                     Batimetry    = Bathymetry,                                         &
                     OpenPoints3D   = Me%External_Var%OpenPoints3D,                     &
                     STAT = STAT_CALL)   

                if (STAT_CALL/=SUCCESS_)                                                &
                     stop 'Sub. ModifyWaterDischarges - ModuleHydrodynamic - ERR03'

                call GetDischargeWaterFlow(Me%ObjDischarges,                &
                                           Me%CurrentTime, DischargeID,     &
                                           Me%WaterLevel%Old(I, J),         &
                                           DischargeFlow, STAT = STAT_CALL)             

                if (STAT_CALL/=SUCCESS_)                                                &
                     stop 'Sub. ModifyWaterDischarges - ModuleHydrodynamic - ERR04'

                if (DischargeUniform) then

                    kmin = KFloor_Z(i, j)
                    kmax = KUB

                else
            
                    kmin = kd; kmax = kd

                endif

                do k=kmin, kmax

                    if (OpenPoints3D(i, j, k) /= OpenPoint .and. DischargeFlow < 0)  Cycle

                    if (DischargeUniform) then
                        
                        AuxFlow = DWZ(i, j, k) / WaterColumnZ(i,j) * DischargeFlow

                    else

                        AuxFlow = DischargeFlow

                    endif

                    Me%WaterFluxes%Discharges(i, j, k) =                                &
                        Me%WaterFluxes%Discharges(i, j, k) + AuxFlow

                enddo

            enddo do1

            !Disposes pointer to the Bathymetry
            call UngetGridData(Me%ObjGridData, Bathymetry, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'ModifyMomentumDischarge - ModuleHydrodynamic - ERR05'


        endif cd1


cd2:    if (Me%ComputeOptions%SurfaceWaterFlux .and. .not. Me%State%Initial) then

            AddSurfaceWater => Me%External_Var%SurfaceWaterFlux 

            CurrentTime   = Me%CurrentTime
 
do2:            do j = JLB, JUB
do3:            do i = ILB, IUB

                    !Precipitation Condition : AddSurfaceWater(i, j) > 0
                    !Evaporation   Condition : AddSurfaceWater(i, j) < 0
                    if ((OpenPoints3D (i, j, KUB) == OpenPoint .and. AddSurfaceWater(i, j) < 0) .or. &
                        (WaterPoints3D(i, j, KUB) == WaterPoint.and. AddSurfaceWater(i, j) > 0)) then
                
                        Me%WaterFluxes%Discharges(i, j, KUB)     =                      &
                            Me%WaterFluxes%Discharges(i, j, KUB) +                      &
                            AddSurfaceWater(i, j)

                    endif

            enddo do3
            enddo do2

        endif cd2

!Put BottomWaterFlux in data input
cd3:    if (Me%ComputeOptions%BottomWaterFlux .and. .not. Me%State%Initial) then

                BottomWaterFlux => Me%External_Var%BottomWaterFlux

do4:            do j = JLB, JUB
do5:            do i = ILB, IUB

                    kbottom  = Me%External_Var%KFloor_Z (i,j)

                    !Water out of sediment : BottomWaterFluxes(i, j) > 0
                    !Water infiltrating    : BottomWaterFluxes(i, j) < 0
                    if ((OpenPoints3D (i, j, KLB) == OpenPoint .and. BottomWaterFlux (i, j) < 0) .or. &
                        (WaterPoints3D(i, j, KLB) == WaterPoint.and. BottomWaterFlux (i, j) > 0)) then
                
                        Me%WaterFluxes%Discharges(i, j, kbottom)     =                  &
                            Me%WaterFluxes%Discharges(i, j, kbottom) +                  &
                            BottomWaterFlux(i, j)

                    endif

            enddo do5
            enddo do4

        endif cd3
        

        !Nullify auxilary pointers
        nullify (OpenPoints3D )
        nullify (WaterPoints3D)
        nullify (KFloor_Z     ) 
        nullify (DWZ          ) 
        nullify (WaterColumnZ )


    end subroutine ModifyWaterDischarges

    !End------------------------------------------------------------------------------

  
    subroutine Hydrodynamic_OutPut

        !Arguments-------------------------------------------------------------
            

        !Local-----------------------------------------------------------------
        logical :: OutPutFiledOK
        integer :: NextOutPut, STAT_CALL
        real    :: DT_Model


        !Begin---------------------------------------------------------------------


        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Hydrodynamic_OutPut")

        Me%OutPut%Run_End       = .false.
        
        OutPutFiledOK = .false.

        if (Me%OutPut%TimeSerieON .or. Me%OutPut%hdf5ON .or. Me%OutPut%ProfileON)&
            call ModifyMatrixesOutput
        
        if (Me%OutPut%hdf5ON) then 

            NextOutPut = Me%OutPut%NextOutPut

            if (NextOutPut <= Me%OutPut%Number) then
                if (Me%CurrentTime >= Me%OutPut%OutTime(NextOutPut)) then

                    OutPutFiledOK = .true.

                endif
            endif

            !Computes cartesian vertical velocity
            !if (OutPutFiledOK .or. Me%OutPut%TimeSerieON) then

            !  call ComputeCartesianVertVelocity

            !endif

             !Next line changed to avoid rounding errors - Frank Aug - 2001
            if (OutPutFiledOK) then

!            if ((Me%CurrentTime + DT_Model/10.) >= Me%OutPut%OutTime(NextOutPut)) then

                call GetComputeTimeStep(Me%ObjTime, DT_Model, STAT = STAT_CALL)

                !Next line changed to avoid rounding errors - Frank Aug - 2001
                if (Me%EndTime == Me%OutPut%OutTime(NextOutPut)) then
!                if (abs(Me%EndTime - Me%OutPut%OutTime(NextOutPut)) < DT_Model/10. ) then

                    Me%OutPut%Run_End = .true.

                endif


                !Output in HDF
                call Write_HDF5_Format

                !
                ! This passed to the module ModuleModel
                !
                !Message to the user
                !call PrintProgress(Me%ObjTime)     !Frank

                Me%OutPut%NextOutPut = NextOutPut + 1

            endif

        endif

        if (Me%OutPut%TimeSerieON)  &
            call OutPut_TimeSeries

        if (Me%OutPut%ProfileON)    &
            call Output_Profile
        
        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Hydrodynamic_OutPut")


    end subroutine Hydrodynamic_OutPut

    !End------------------------------------------------------------------------------


    !--------------------------------------------------------------------------
    ! This subroutine is responsable for computing fluxes between boxes      

    subroutine ComputeBoxesWaterFluxes

        !Arguments-------------------------------------------------------------

         

        !External--------------------------------------------------------------
        
        integer :: STAT_CALL    

        !Local-----------------------------------------------------------------


        !----------------------------------------------------------------------
       
        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "ComputeBoxesWaterFluxes")

cd1:    if (Me%State%BOXFLUXES) then

            call BoxDif(Me%ObjBoxDif,                                                    &
                        Me%WaterFluxes%X,                                                &
                        Me%WaterFluxes%Y,                                                &
                        Me%WaterFluxes%Z,                                                & 
                        Char_Water,                                                      &
                        Me%External_Var%WaterPoints3D,                                   &
                        STAT = STAT_CALL)

            if (STAT_CALL .NE. SUCCESS_)                                                 &
               stop 'Subroutine ComputeBoxesWaterFluxes; Module ModuleHydrodynamic. ERR01'

            call BoxDif(Me%ObjBoxDif,                                                    &
                        Me%External_Var%Volume_Z_New,                                    &
                        Char_Water,                                                      &
                        Me%External_Var%WaterPoints3D,                                   &
                        STAT = STAT_CALL)

            if (STAT_CALL .NE. SUCCESS_)                                                 &
               stop 'Subroutine ComputeBoxesWaterFluxes; Module ModuleHydrodynamic. ERR02'

        endif cd1

        !----------------------------------------------------------------------
        
        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "ComputeBoxesWaterFluxes")

    end subroutine ComputeBoxesWaterFluxes

    !--------------------------------------------------------------------------


    !This subroutine computes 
    Subroutine ComputeResidualFlowProperties

        !Arguments-------------------------------------------------------------

        
   

        !Local-----------------------------------------------------------------
        real(8), dimension(:,:,:), pointer :: ResidualFluxX, ResidualFluxY,              &
                                              WaterFluxX, WaterFluxY

        real,    dimension(:,:,:), pointer :: ResidualU, ResidualV,                      &
                                              ResidualW,                                 &
                                              VelocityU, VelocityV,                      &
                                              VelocityW,                                 &
                                              Area_U, Area_V, ResidualDWZ, DWZ

        real,    dimension(:,:  ), pointer :: WaterLevel, ResidualLevel, DXX, DYY       

        integer, dimension(:,:,:), pointer :: WaterPoints3D
        integer, dimension(:,:  ), pointer :: KFloor_Z

        real                               :: ResidualTime, DT_Elevation

        integer                            :: i, j, k, kbottom,             &
                                              ILB, JLB, KLB, IUB, JUB, KUB

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "ComputeResidualFlowProperties")


        !Begin - Shorten variables name 

        IUB = Me%WorkSize%IUB
        ILB = Me%WorkSize%ILB
        JUB = Me%WorkSize%JUB
        JLB = Me%WorkSize%JLB
        KUB = Me%WorkSize%KUB
        KLB = Me%WorkSize%KLB

        ResidualTime  = Me%Residual%ResidualTime

        DT_Elevation  = Me%WaterLevel%DT


        !Mapping points and geometry
        DYY           => Me%External_Var%DYY
        DXX           => Me%External_Var%DXX
        DWZ           => Me%External_Var%DWZ

        Area_U        => Me%External_Var%Area_U
        Area_V        => Me%External_Var%Area_V


        WaterPoints3D => Me%External_Var%WaterPoints3D

        KFloor_Z      => Me%External_Var%KFloor_Z

        !Instant flow values 

        !Water Level
        WaterLevel => Me%WaterLevel%New

        !horizontal velocity
        VelocityU  => Me%Velocity%Horizontal%U%New
        VelocityV  => Me%Velocity%Horizontal%V%New

        !vertical velocity
        VelocityW  => Me%Velocity%Vertical%Across

        !Water fluxes
        WaterFluxX => Me%WaterFluxes%X
        WaterFluxY => Me%WaterFluxes%Y

        !Residual flow values

        ResidualLevel => Me%Residual%WaterLevel 

        !Residual horizontal velocity
        ResidualU     => Me%Residual%Velocity_U
        ResidualV     => Me%Residual%Velocity_V

        !Residual vertical velocity
        ResidualW     => Me%Residual%Vertical_Velocity

        !Residual Water specific fluxes
        ResidualFluxX => Me%Residual%WaterFlux_X
        ResidualFluxY => Me%Residual%WaterFlux_Y

        !Residual layer thickness
        ResidualDWZ   => Me%Residual%DWZ

        !End - Shorten variables name 
                        
do1:    do  j = JLB, JUB 
do2:    do  i = ILB, IUB
            
cd2:        if (WaterPoints3D(i, j, KUB) == WaterPoint) then 

                !Residual Water elevation
                ResidualLevel(i, j) = (ResidualLevel(i, j) * ResidualTime + &
                                       WaterLevel(i, j) * DT_Elevation)   / &
                                      (ResidualTime + DT_Elevation)

                kbottom = KFloor_Z(i, j)

do3:            do  k = kbottom, KUB
                    
                    !Residual horizontal velocity
                    ResidualU(i, j, k) = (ResidualU(i, j, k) * ResidualTime  + &
                                          VelocityU(i, j, k) * DT_Elevation) / &
                                         (ResidualTime + DT_Elevation)

                    ResidualV(i, j, k) = (ResidualV(i, j, k) * ResidualTime  + &
                                          VelocityV(i, j, k) * DT_Elevation) / &
                                         (ResidualTime + DT_Elevation)

                    !Residual vertical velocity
                    ResidualW(i, j, k) = (ResidualW(i, j, k) * ResidualTime  + &
                                          VelocityW(i, j, k) * DT_Elevation) / &
                                         (ResidualTime + DT_Elevation)


                    !Residual Water fluxes by width (residual specifc flow)
                    ResidualFluxX(i, j, k) = (ResidualFluxX(i, j, k) * ResidualTime + &
                                              WaterFluxX(i, j, k) / DYY(i, j) * DT_Elevation)   / &
                                             (ResidualTime + DT_Elevation)  

                    ResidualFluxY(i, j, k) = (ResidualFluxY(i, j, k) * ResidualTime + &
                                              WaterFluxY(i, j, k) / DXX(i, j) * DT_Elevation)   / &
                                             (ResidualTime + DT_Elevation)  

                    !Residual layer thickness
                    ResidualDWZ(i, j, k) = (ResidualDWZ(i, j, k) * ResidualTime  + &
                                            DWZ(i, j, k)         * DT_Elevation) / &
                                            (ResidualTime + DT_Elevation) 



                enddo do3

            endif cd2

        enddo do2
        enddo do1

        ResidualTime  = ResidualTime + DT_Elevation
        Me%Residual%ResidualTime  = ResidualTime

        !Nullify auxiliar pointers
        nullify (ResidualU, ResidualV, ResidualW)
        nullify (ResidualFluxX   , ResidualFluxY)
        nullify (ResidualDWZ)
        nullify (VelocityU, VelocityV, VelocityW)
        nullify (WaterFluxX, WaterFluxY)
        nullify (WaterLevel, ResidualLevel)       
        nullify (WaterPoints3D, KFloor_Z)
        nullify (DXX, DYY, Area_U, Area_V, DWZ)
        
        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "ComputeResidualFlowProperties")

        !----------------------------------------------------------------------

    end subroutine ComputeResidualFlowProperties
    
 

    subroutine ComputeSystemEnergy !Frank Out99

        !Arguments-------------------------------------------------------------
        


        !Local-----------------------------------------------------------------
        real(8)                                    :: KineticEnergy,   TotalKineticEnergy        !*, ecin
        real(8)                                    :: BarotropicKineticEnergy,   TotalBarotropicKineticEnergy      
        real(8)                                    :: BaroclinicKineticEnergy,   TotalBaroclinicKineticEnergy      
        real(8)                                    :: PotentialEnergy, TotalPotentialEnergy      !potmat, epot
!        real(8)                                    :: APE, TotalAPE
!        real(8)                                    :: GPE, TotalGPE
        real(8)                                    :: Vorticity, TotalEnstrophy
        real(8)                                    :: Mass,            TotalMass                 !rmassa, rmtot
        real(8)                                    :: Volume,          TotalVolume, OpenVolume
        real(8)                                    :: TotalLevelArea, TotalArea, Area
        real(8)                                    :: Velocity2, AuxVel
        real                                       :: Year, Month, Day, Hour, Minute, Second
        real(8)                                    :: VelMaxBaroclinic, VelMax, BaroclinicU, BaroclinicV
        integer                                 :: ILB, IUB, JLB, JUB, KLB, KUB
        integer                                 :: WorkILB, WorkIUB, WorkJLB, WorkJUB
        integer                                 :: WorkKLB, WorkKUB
        integer                                 :: i, j, k, STAT_CALL, iBuffer
        integer, dimension(:, :, :), pointer    :: WaterPoints3D
        integer, dimension(:, :, :), pointer    :: OpenPoints3D
        integer, dimension(:, :   ), pointer    :: BoundaryPoints
        real, dimension(:, :, :),    pointer    :: Density, SZZ, DWZ
        real(8), dimension(:, :, :), pointer    :: VolumeZ
        real, dimension(:,:),        pointer    :: Bathymetry, DUX, DVY
        real, dimension(:,:),        pointer    :: DZX, DZY
        real, dimension(:, :, :),    pointer    :: CenterU, CenterV
        real, dimension(:, :, :),    pointer    :: CenterW
        real, dimension(:, :   ),    pointer    :: BarotropicU, BarotropicV, WaterColumnZ
!        real, dimension(:, :, :),    pointer    :: S,T
!        real(8)                                 :: MinusOnePercentS, A, TotalA,Smin,Smax
!        real(8)                                 :: rho_p, rho

        !Begin --------------------------------------------------------------------------

        if (Me%CurrentTime >= Me%Energy%NextOutPut) then

            Me%Energy%NextOutPut = Me%Energy%NextOutPut +      &
                                                Me%Energy%DtOut

            !Size
            IUB = Me%Size%IUB
            ILB = Me%Size%ILB

            JUB = Me%Size%JUB
            JLB = Me%Size%JLB

            KUB = Me%Size%KUB
            KLB = Me%Size%KLB

            !WorkSize
            WorkILB = Me%Energy%Window%ILB 
            WorkIUB = Me%Energy%Window%IUB 

            WorkJLB = Me%Energy%Window%JLB 
            WorkJUB = Me%Energy%Window%JUB 

            WorkKLB = Me%Energy%Window%KLB 
            WorkKUB = Me%Energy%Window%KUB 

            !Gets a pointer to the bathymetry
            call GetGridData(Me%ObjGridData, Bathymetry, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'ComputeSystemEnergy - ModuleHydrodynamic - ERR00'

            !Shorten variable names
            WaterPoints3D => Me%External_Var%WaterPoints3D
            OpenPoints3D  => Me%External_Var%OpenPoints3D
            BoundaryPoints=> Me%External_Var%BoundaryPoints
            Density       => Me%External_Var%Density
            VolumeZ       => Me%External_Var%Volume_Z_New
            SZZ           => Me%External_Var%SZZ
            DWZ           => Me%External_Var%DWZ
            DUX           => Me%External_Var%DUX
            DVY           => Me%External_Var%DVY
            DZX           => Me%External_Var%DZX
            DZY           => Me%External_Var%DZY
            WaterColumnZ  => Me%External_Var%WaterColumn

            !Centers horizontal velocity
            allocate(CenterU    (ILB:IUB, JLB:JUB, KLB:KUB),                            &
                     CenterV    (ILB:IUB, JLB:JUB, KLB:KUB),                            &
                     BarotropicU(ILB:IUB, JLB:JUB         ),                            &
                     BarotropicV(ILB:IUB, JLB:JUB         ),                            &
                     STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'ComputeSystemEnergy - ModuleHydrodynamic - ERR01'

            call CenterVelocity( CenterU, CenterV,                           &
                                VectorType = CurrentVelocity)


            !Centers vertical velocity
            allocate(CenterW(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'ComputeSystemEnergy - ModuleHydrodynamic - ERR02'
            CenterW = 0.
            do k = WorkKLB, WorkKUB
            do j = WorkJLB, WorkJUB
            do i = WorkILB, WorkIUB
                if (k == WorkKLB) then
                    CenterW(i, j, k) = Me%Velocity%Vertical%Cartesian(i, j, k+1) / 2.
                elseif (k == WorkKUB) then
                    CenterW(i, j, k) = Me%Velocity%Vertical%Cartesian(i, j, k) / 2.
                else
                    CenterW(i, j, k) = (Me%Velocity%Vertical%Cartesian(i, j, k+1) +  &
                                                Me%Velocity%Vertical%Cartesian(i, j, k)) / 2.
                endif
            enddo
            enddo
            enddo


            !Inits variables
            TotalKineticEnergy   = 0.d0
            TotalPotentialEnergy = 0.d0
            TotalBarotropicKineticEnergy = 0.d0
            TotalBaroclinicKineticEnergy = 0.d0
            TotalEnstrophy = 0.d0
            TotalMass            = 0.d0
            TotalVolume          = 0.d0
!            TotalAPE             = 0.d0    

            OpenVolume           = 0.d0
            TotalLevelArea       = 0.d0
            TotalArea            = 0.d0
!            TotalA               = 0.d0    

            VelMax               = -99
            VelMaxBaroclinic     = -99

            !Calculates de barotropic velocity 
            do j = WorkJLB, WorkJUB
            do i = WorkILB, WorkIUB

                BarotropicU(i, j) = 0. 
                BarotropicV(i, j) = 0.
                Mass              = 0.

                if (WaterPoints3D(i, j, WorkKUB) == WaterPoint .and. BoundaryPoints(i,j) /= Boundary) then 

                    do k = WorkKLB, WorkKUB

                        if (WaterPoints3D(i, j, k) == WaterPoint) then

                            Volume    = VolumeZ(i, j, k) 
                            Mass      = Mass + Density(i, j, k) * Volume

                            BarotropicU(i, j) = BarotropicU(i, j) + CenterU(i, j, k) * DWZ(i, j, k) / WaterColumnZ(i, j)
                            BarotropicV(i, j) = BarotropicV(i, j) + CenterV(i, j, k) * DWZ(i, j, k) / WaterColumnZ(i, j) 

                        endif
                    enddo

                    BarotropicKineticEnergy      = Mass * (BarotropicU(i, j)**2 + BarotropicV(i, j)**2)
                    TotalBarotropicKineticEnergy = TotalBarotropicKineticEnergy + BarotropicKineticEnergy

                endif
            enddo
            enddo            

            TotalBarotropicKineticEnergy = 0.5 * TotalBarotropicKineticEnergy

            !Calculates Kinetic Energy and Potential Energy of all the sistem
            do i = WorkILB, WorkIUB
            do j = WorkJLB, WorkJUB
            do k = WorkKLB, WorkKUB

                if (WaterPoints3D(i, j, k) == WaterPoint .and. BoundaryPoints(i,j) /= Boundary) then 

                    Volume    = VolumeZ(i, j, k) 
                    Mass      = Density(i, j, k) * Volume

                    TotalVolume = TotalVolume + Volume
                    TotalMass   = TotalMass   + Mass
            
                    if (OpenPoints3D(i, j, k) == OpenPoint) then
                        Velocity2 = CenterU(i, j, k)**2. + CenterV(i, j, k)**2. + &
                                    CenterW(i, j, k)**2.
                        AuxVel = sqrt(Velocity2)

                        if (AuxVel > VelMax) VelMax = AuxVel


                        KineticEnergy        = Mass * Velocity2
                        TotalKineticEnergy   = TotalKineticEnergy + KineticEnergy


                        BaroclinicU = CenterU(i, j, k)-BarotropicU(i, j)
                        BaroclinicV = CenterV(i, j, k)-BarotropicV(i, j)

                        Velocity2 = BaroclinicU**2. + BaroclinicV**2. + &
                                    CenterW(i, j, k)**2.
                        AuxVel = sqrt(Velocity2)

                        if (AuxVel > VelMaxBaroclinic) VelMaxBaroclinic = AuxVel

                        BaroclinicKineticEnergy        = Mass * Velocity2
                        TotalBaroclinicKineticEnergy   = TotalBaroclinicKineticEnergy + BaroclinicKineticEnergy

                    endif                    

                    !PotentialEnergy      = Mass * Gravity * (Bathymetry(i, j) - (SZZ(i, j, k) + DWZ(i, j, k)/2.))
                    !Potential energy compute relatively to hydrographic zero
                    PotentialEnergy      = Mass * (- SZZ(i, j, k) - DWZ(i, j, k)/2.) 
                    TotalPotentialEnergy = TotalPotentialEnergy + PotentialEnergy

                    !Calculates the available potential energy
!                    rho_p = SigmaUNESCO(S(i,j,k),T(i,j,k))
!                    rho   = SigmaUNESCO(S(i,j,k+1),T(i,j,k+1))
!                    APE = (rho_p - rho) * DWZ(i,j,k) * volume
!                    TotalAPE = TotalAPE + APE
                    
                    !GravitationalPotentialEnergy
!                    GPE = Mass / (MeanRadius_ - SZZ(i,j,k) - 0.5 * DWZ(i,j,k))
!                    TotalGPE = TotalGPE + GPE

                    !To calculate the graph Level/Volume
                    if (OpenPoints3D(i, j, k) == OpenPoint) then
                        OpenVolume  = OpenVolume  + Volume
                        if (k == WorkKUB) then
                            Area            = DUX(i, j) * DVY(i, j)
                            TotalLevelArea  = TotalLevelArea  + Me%WaterLevel%New(i, j) * Area
                            TotalArea       = TotalArea + Area
                        endif
                    endif

                endif

            enddo
            enddo
            enddo            

            TotalKineticEnergy   = 0.5 * TotalKineticEnergy
            TotalBaroclinicKineticEnergy   = 0.5 * TotalBaroclinicKineticEnergy
            TotalPotentialEnergy = Gravity * TotalPotentialEnergy
!            TotalAPE = 0.5 * Gravity * TotalAPE
!            TotalGPE = mu_ * TotalGPE

!            Smin = 39.
!            Smax = 0.
!            do i = WorkILB, WorkIUB
!            do j = WorkJLB, WorkJUB
!            do k = WorkKLB, WorkKUB
                    
!                if (WaterPoints3D(i, j, k) == WaterPoint .and. BoundaryPoints(i,j) /= Boundary) then 
                
!                    if ( Smax .lt. S(i,j,k)) then
!                        Smax = S(i,j,k)
!                    endif

!                    if ( Smin .gt. S(i,j,k)) then
!                        Smin = S(i,j,k)
!                    endif

!                endif

!            enddo
!            enddo
!            enddo            

!            MinusOnePercentS = 0.d0
!            do i = WorkILB, WorkIUB
!            do j = WorkJLB, WorkJUB
                    
!                if (WaterPoints3D(i, j, WorkKUB) == WaterPoint .and. BoundaryPoints(i,j) /= Boundary) then 
                
!                    A = DUX(i, j) * DVY(i, j)
!                    MinusOnePercentS = MinusOnePercentS + S(i,j,WorkKUB) * A
!                    TotalA = TotalA + A

!                endif

!            enddo
!            enddo            
!            MinusOnePercentS = MinusOnePercentS * .99d0 / TotalA

!            TotalA = 0.d0
!            do i = WorkILB, WorkIUB
!            do j = WorkJLB, WorkJUB
                    
!                if (WaterPoints3D(i, j, WorkKUB) == WaterPoint .and. BoundaryPoints(i,j) /= Boundary) then 
                
!                    if ( S(i,j,WorkKUB) .lt. MinusOnePercentS ) then
!                        A = DUX(i, j) * DVY(i, j)
!                       TotalA = TotalA + A
!                    endif

!                endif

!            enddo
!            enddo            

            !Computes the Enstrophy
        
dok:        do k = WorkKLB, WorkKUB
doj:        do j = WorkJLB, WorkJUB
doi:        do i = WorkILB, WorkIUB
    
                Vorticity = 0
                Volume    = VolumeZ(i, j, k) 
                
cd1:            if (WaterPoints3D(i-1, j  ,k)== WaterPoint .and.                &
                    WaterPoints3D(i  , j  ,k)== WaterPoint) then 

                    Vorticity = - (CenterU(i, j, k) - CenterU(i-1, j, k)) / DZY(i-1,j)

                endif cd1

cd2:            if (WaterPoints3D(i  , j  ,k)== WaterPoint .and.                &
                    WaterPoints3D(i  , j-1,k)== WaterPoint) then 

                    Vorticity =  Vorticity + (CenterV(i, j, k) - CenterV(i , j-1, k)) / DZX(i,j-1)

                endif cd2

                TotalEnstrophy = TotalEnstrophy + Volume * Vorticity**2.

            enddo doi
            enddo doj
            enddo dok

            ! TotalEnstrophy = 0.5 * TotalEnstrophy

            !Gets the current simulation time
            call ExtractDate(Me%CurrentTime,     &
                             Year   = Year,   Month = Month,  &
                             Day    = Day,    Hour  = Hour,   &
                             Minute = Minute, Second= Second)

            if (Me%Energy%FirstTime) then
                Me%Energy%FirstTime = .false.
            
                !Stores the energy of the first iteration as reference
                Me%Energy%PotentialEnergyReference = TotalPotentialEnergy

            endif


            !Stores Data in a Buffer
            Me%Energy%BufferCount = Me%Energy%BufferCount + 1
            iBuffer = Me%Energy%BufferCount

            Me%Energy%YearBuffer(iBuffer)      = Year
            Me%Energy%MonthBuffer(iBuffer)     = Month
            Me%Energy%DayBuffer(iBuffer)       = Day
            Me%Energy%HourBuffer(iBuffer)      = Hour
            Me%Energy%MinuteBuffer(iBuffer)    = Minute
            Me%Energy%SecondBuffer(iBuffer)    = Second
            Me%Energy%RelativeKEBuffer(iBuffer)= TotalKineticEnergy / TotalMass
            Me%Energy%RelativePEBuffer(iBuffer)= (TotalPotentialEnergy -        &
                                                               Me%Energy%PotentialEnergyReference) / &
                                                               TotalMass
            !Me%Energy%RelativeKEBuffer(iBuffer)= TotalGPE
            !Me%Energy%RelativePEBuffer(iBuffer)= TotalAPE

            Me%Energy%KineticBuffer(iBuffer)   =   TotalKineticEnergy

            Me%Energy%PotentialBuffer(iBuffer) =   TotalPotentialEnergy - Me%Energy%PotentialEnergyReference

            Me%Energy%VorticityBuffer(iBuffer) =   TotalEnstrophy

            Me%Energy%MassBuffer(iBuffer)      =   TotalMass

            Me%Energy%VolumeBuffer(iBuffer)    =   TotalVolume

            if (TotalArea > 0) then
                Me%Energy%WaterLevelBuffer(iBuffer)=   TotalLevelArea / TotalArea
            else
                Me%Energy%WaterLevelBuffer(iBuffer)=   -99.
            endif
            Me%Energy%OpenVolumeBuffer(iBuffer)    =   OpenVolume


            Me%Energy%BarotropicKEBuffer    (iBuffer)  =  TotalBarotropicKineticEnergy / TotalMass
            Me%Energy%BaroclinicKEBuffer    (iBuffer)  =  TotalBaroclinicKineticEnergy / TotalMass
!            Me%Energy%BarotropicKEBuffer    (iBuffer)  =  Smin
!            Me%Energy%BaroclinicKEBuffer    (iBuffer)  =  Smax

           Me%Energy%VelMaxBuffer          (iBuffer)  =  VelMax
!            Me%Energy%VelMaxBuffer          (iBuffer)  =  TotalA
            Me%Energy%VelMaxBaroclinicBuffer(iBuffer)  =  VelMaxBaroclinic

            !If the buffer is full, writes the data file
            if (iBuffer == EnergyBufferSize) &
                call WriteEnergyDataFile

            !Disposes pointer to the Bathymetry
            call UngetGridData(Me%ObjGridData, Bathymetry, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'ComputeSystemEnergy - ModuleHydrodynamic - ERR03'

            !Nullifies pointers
            nullify(WaterPoints3D, Density, VolumeZ, SZZ, DWZ)
            nullify(OpenPoints3D, BoundaryPoints)

            !Deallocates CenterVelocities
            deallocate(CenterU, CenterV, CenterW, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'ComputeSystemEnergy - ModuleHydrodynamic - ERR04'

            deallocate(BarotropicU, BarotropicV, STAT = STAT_CALL)


            nullify(CenterU, CenterV, CenterW)
            nullify(DUX, DVY)

            nullify(BarotropicU, BarotropicV) 

        endif

    end subroutine ComputeSystemEnergy

    !--------------------------------------------------------------------------

    subroutine WriteEnergyDataFile !Frank Out99

        !Arguments-------------------------------------------------------------
        

        !Local
        integer                             :: iBuffer


        do iBuffer = 1, Me%Energy%BufferCount
            write(Me%Energy%FileID, fmt=100) Me%Energy%YearBuffer            (iBuffer), &
                                             Me%Energy%MonthBuffer           (iBuffer), &
                                             Me%Energy%DayBuffer             (iBuffer), &
                                             Me%Energy%HourBuffer            (iBuffer), &
                                             Me%Energy%MinuteBuffer          (iBuffer), &
                                             Me%Energy%SecondBuffer          (iBuffer), &
                                             Me%Energy%KineticBuffer         (iBuffer), &
                                             Me%Energy%PotentialBuffer       (iBuffer), &
                                             Me%Energy%RelativeKEBuffer      (iBuffer), &
                                             Me%Energy%RelativePEBuffer      (iBuffer), &
                                             Me%Energy%MassBuffer            (iBuffer), &
                                             Me%Energy%VolumeBuffer          (iBuffer), &
                                             Me%Energy%OpenVolumeBuffer      (iBuffer), &
                                             Me%Energy%WaterLevelBuffer      (iBuffer), &
                                             Me%Energy%BarotropicKEBuffer    (iBuffer), &
                                             Me%Energy%BaroclinicKEBuffer    (iBuffer), &                                                   
                                             Me%Energy%VelMaxBuffer          (iBuffer), &
                                             Me%Energy%VelMaxBaroclinicBuffer(iBuffer), &
                                             Me%Energy%VorticityBuffer       (iBuffer)
                                                         
            100 format(1x, f5.0, 1x, f4.0, 1x, f4.0, 1x, f4.0, 1x, f4.0, f4.0, 1x, e14.8, 1x, e14.8, 1x, e14.8, 1x, e14.8, 1x,  &
                       e14.8, 1x, e14.8, 1x, e14.8, 1x, f12.6, 1x, e14.8, 1x, e14.8, 1x, e14.8, 1x, e14.8, 1x, e14.8)
        enddo
        Me%Energy%BufferCount = 0

    end subroutine WriteEnergyDataFile

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------

    subroutine Write_HDF5_Format

        !Arguments-------------------------------------------------------------
        

        !Local-----------------------------------------------------------------
        real, dimension(:, :, :), pointer   :: CenterU, CenterV 
        integer                             :: STAT_CALL

        real, dimension(6), target          :: AuxTime
        real, dimension(:), pointer         :: TimePtr
        integer                             :: ILB, IUB, JLB, JUB, KLB, KUB
        integer                             :: WorkILB, WorkIUB, WorkJLB, WorkJUB
        integer                             :: WorkKLB, WorkKUB, Index
        integer                             :: i, j, k, kbottom
        real                                :: TotalSeconds
        real, dimension(:, :, :), pointer   :: SZZ, DWZ, CenterW   !flavio
        real, dimension(:, :), pointer      :: VerticalVelocityError

        integer, dimension(:,:,:), pointer  :: WaterPoints3D, ComputeFaces3D_W ! flavio
        integer, dimension(:,:,:), pointer  :: OpenPoints3D
        integer, dimension(:,:),   pointer  :: KFloorZ

        !----------------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "Write_HDF5_Format")

        !Bounds
        ILB = Me%Size%ILB 
        IUB = Me%Size%IUB 

        JLB = Me%Size%JLB 
        JUB = Me%Size%JUB 

        KLB = Me%Size%KLB 
        KUB = Me%Size%KUB 

        WorkILB = Me%WorkSize%ILB 
        WorkIUB = Me%WorkSize%IUB 

        WorkJLB = Me%WorkSize%JLB 
        WorkJUB = Me%WorkSize%JUB 

        WorkKLB = Me%WorkSize%KLB 
        WorkKUB = Me%WorkSize%KUB 


        WaterPoints3D    => Me%External_Var%WaterPoints3D
        ComputeFaces3D_W => Me%External_Var%ComputeFaces3D_W
        KFloorZ          => Me%External_Var%KFloor_Z
        OpenPoints3D     => Me%External_Var%OpenPoints3D

        SZZ => Me%External_Var%SZZ
        DWZ => Me%External_Var%DWZ

        !Current output index
        Index        = Me%OutPut%NextOutPut
        TotalSeconds = Me%CurrentTime - Me%OutPut%OutTime(1)

        !Sets the attributes of the instant after HW
!        HouresAfterHW  = Me%OutPut%TimeAfterHW(Index)/3600.
!        MinutesAfterHW = (Me%OutPut%TimeAfterHW(Index) - (HouresAfterHW * 3600.0)) / 60.0

        !Writes current time
        call ExtractDate   (Me%CurrentTime, AuxTime(1), AuxTime(2), AuxTime(3), &
                            AuxTime(4), AuxTime(5), AuxTime(6))
        TimePtr => AuxTime
        call HDF5SetLimits  (Me%ObjHDF5, 1, 6, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR01'

        call HDF5WriteData  (Me%ObjHDF5, "/Time", "Time", "YYYY/MM/DD HH:MM:SS",      &
                             Array1D = TimePtr, OutputNumber = Index, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR02'



        !Writes SZZ
        call HDF5SetLimits  (Me%ObjHDF5, WorkILB, WorkIUB, WorkJLB,                     &
                             WorkJUB, WorkKLB-1, WorkKUB, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR03'

        call HDF5WriteData  (Me%ObjHDF5, "/Grid/VerticalZ", "Vertical",                 &
                             "m", Array3D = SZZ, OutputNumber = Index, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR04'


        !Writes OpenPoints
        call HDF5SetLimits  (Me%ObjHDF5, WorkILB, WorkIUB,                              &
                             WorkJLB, WorkJUB, WorkKLB, WorkKUB,                        &
                             STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR05'

        call HDF5WriteData  (Me%ObjHDF5, "/Grid/OpenPoints", "OpenPoints",              &
                             "-", Array3D = OpenPoints3D, OutputNumber = Index,         &
                             STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR06'

        !Writes Waterlevel
        call HDF5WriteData  (Me%ObjHDF5, "/Results/"//trim(GetPropertyName (WaterLevel_)),         &
                             trim(GetPropertyName (WaterLevel_)), "m", Array2D = Me%WaterLevel%New,&
                             OutputNumber = Index, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR07'


        !call CenterVelocity( CenterU, CenterV,                           &
        !                    VectorType = CurrentVelocity)

        !Writes Velocity
        call HDF5WriteData  (Me%ObjHDF5, "/Results/"//trim(GetPropertyName (VelocityU_)),&
                             trim(GetPropertyName (VelocityU_)),                        &
                             "m/s", Array3D = Me%OutPut%CenterU,                        &
                             OutputNumber = Index, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR09'
        
        call HDF5WriteData  (Me%ObjHDF5, "/Results/"//trim(GetPropertyName (VelocityV_)),&
                             trim(GetPropertyName (VelocityV_)),                        &
                             "m/s", Array3D =  Me%OutPut%CenterV,                       &
                             OutputNumber = Index, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR10'


        !Writes Velocity modulus
        call HDF5WriteData  (Me%ObjHDF5, "/Results/"//trim(GetPropertyName (VelocityModulus_)), &
                            trim(GetPropertyName (VelocityModulus_)),                   &
                              "m/s", Array3D =  Me%OutPut%ModulusH,                     &
                             OutputNumber = Index, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR11'


        !Vertical Velocity
        nullify  (CenterW)
        allocate (CenterW(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR12'

        !CenterW(:,:,:) = FillValueReal

        !Writes Velocity W
        call HDF5WriteData  (Me%ObjHDF5, "/Results/"//trim(GetPropertyName (VelocityW_)),&
                             trim(GetPropertyName (VelocityW_)), "m/s",Array3D = Me%OutPut%CenterW,&
                             OutputNumber = Index, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR13'

        call Statistics_OutPut   ( Me%OutPut%CenterU, Me%OutPut%CenterV, Me%OutPut%CenterW)



        if (.not. Me%ComputeOptions%BaroclinicRadia == NoRadiation_) then

            !Horizontal Velocity
            allocate(CenterU(ILB:IUB, JLB:JUB, KLB:KUB),                                     &
                     CenterV(ILB:IUB, JLB:JUB, KLB:KUB),                                     &
                     STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR08'


            CenterW(:,:,:) = FillValueReal

            do j = WorkJLB, WorkJUB
            do i = WorkILB, WorkIUB

                if (WaterPoints3D (i  ,j  ,WorkKUB) == WaterPoint) then

                    kbottom = KFloorZ(i, j)

                    !By default the vertical velocity in the faces that are not compute is zero
                    Me%VelBaroclinic%W_New(i, j, kbottom : WorkKUB + 1) = &
                    Me%VelBaroclinic%W_New(i, j, kbottom : WorkKUB + 1) * &
                    ComputeFaces3D_W                   (i, j, kbottom : WorkKUB + 1)

        
                    do k = kbottom, WorkKUB

                        CenterW(i, j, k) = (Me%VelBaroclinic%W_New(i, j, k+1) +  &
                                            Me%VelBaroclinic%W_New(i, j, k)) / 2.
                    enddo

                endif

            enddo
            enddo


            !Baroclinic Vertical Velocity
            call HDF5WriteData  (Me%ObjHDF5, "/Results/Baroclinic/Z",           &
                                 "Vel. Z", "m/s", Array3D = CenterW,                         &
                                 OutputNumber = Index, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR14'


            !Baroclinc Horizontal Velocity
            call CenterVelocity( CenterU, CenterV,                           &
                                VectorType = BaroclinicVelocity)

            call HDF5WriteData  (Me%ObjHDF5, "/Results/Baroclinic/X",           &
                                 "Vel. X", "m/s", Array3D = CenterU,                         &
                                 OutputNumber = Index, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR15'


            call HDF5WriteData  (Me%ObjHDF5, "/Results/Baroclinic/Y",           &
                                 "Vel. Y", "m/s", Array3D = CenterV,                         &
                                 OutputNumber = Index, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR16'


            deallocate(CenterU, CenterV, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR17'
            nullify(CenterU, CenterV)

            deallocate(CenterW, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR18'
            nullify(CenterW)

        endif


        !Writes the "Error"
        allocate(VerticalVelocityError(ILB:IUB, JLB:JUB), STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR19'
        do j = JLB, JUB
        do i = ILB, IUB
            VerticalVelocityError(i, j) = Me%Velocity%Vertical%Across(i, j, WorkKUB + 1)
        enddo
        enddo

        call HDF5WriteData  (Me%ObjHDF5, "/Results/Error",                  &
                             "Error", "m/s", Array2D = VerticalVelocityError,            &
                             OutputNumber = Index, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR20'


        deallocate(VerticalVelocityError, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR21'


        if (Me%TidePotential%Compute) then
            call HDF5WriteData  (Me%ObjHDF5, "/Results/TidePotential",          &
                                 "TidePotential", "m",                                       &
                                 Array2D = Me%Forces%TidePotentialLevel,        &
                                 OutputNumber = Index, STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR22'

        endif

         if (Me%NonHydroStatic%ON) then
            call HDF5WriteData  (Me%ObjHDF5, "/Results/NonHydroStaticCorrection",          &
                                 "NonHydroStaticCorrection", "m^2/s^2",                    &
                                 Array3D = Me%NonHydroStatic%PressureCorrect,        &
                                 OutputNumber = Index, STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR22'

        endif


        if (Me%ComputeOptions%Baroclinic) then

            call HDF5WriteData  (Me%ObjHDF5, "/Results/"//trim(GetPropertyName(BaroclinicForceX_)), &
                                 trim(GetPropertyName(BaroclinicForceX_)), "kg/m3",                 &
                                 Array3D = Me%Forces%Rox3X,                                         &
                                 OutputNumber = Index, STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR22a'

            call HDF5WriteData  (Me%ObjHDF5, "/Results/"//trim(GetPropertyName(BaroclinicForceY_)), &
                                 trim(GetPropertyName(BaroclinicForceY_)), "kg/m3",                 &
                                 Array3D = Me%Forces%Rox3Y,                                         &
                                 OutputNumber = Index, STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR22a'

        endif

           
cd2:    if (Me%OutPut%Run_End) then

            call HDF5WriteData  (Me%ObjHDF5, "/Results/VolumeCreated",      &
                                 "Volume Created", "m3",                                 &
                                 Array2D = Me%WaterLevel%VolumeCreated, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR23'

                !Residual Velocity
cd3:        if (Me%ComputeOptions%Residual) then

                !Horizontal Residual Velocity
                allocate(CenterU(ILB:IUB, JLB:JUB, KLB:KUB),                                     &
                         CenterV(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR24'

                call CenterVelocity( CenterU, CenterV, VectorType = ResidualVelocity)

                call HDF5WriteData  (Me%ObjHDF5, "/Residual/Velocity/X",     &
                                     "Vel. X", "m/s", Array3D = CenterU, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR25'

                call HDF5WriteData  (Me%ObjHDF5, "/Residual/Velocity/Y",     &
                                     "Vel. Y", "m/s", Array3D = CenterV, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR26'


                !Horizontal Residual Flux
                call CenterVelocity( CenterU, CenterV, VectorType = ResidualFlux)

                call HDF5WriteData  (Me%ObjHDF5, "/Residual/Flux/X", &
                                     "Flux X", "m2/s", Array3D = CenterU, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR27'

                call HDF5WriteData  (Me%ObjHDF5, "/Residual/Flux/Y", &
                                     "Flux Y", "m2/s", Array3D = CenterV, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR28'


                !Calculates residual flux by area.  This a kind of conservative average velocity.
                do k = KLB, KUB
                do j = JLB, JUB
                do i = ILB, IUB

                    if (WaterPoints3D(i, j, k) == WaterPoint) then

                        !Divide the specific residual flow interpolate for the cell center by the residual thickness
                        CenterU(i, j, k) =  CenterU(i, j, k) / Me%Residual%DWZ(i, j, k)
                        CenterV(i, j, k) =  CenterV(i, j, k) / Me%Residual%DWZ(i, j, k)

                    endif 

                enddo
                enddo
                enddo



                !Horizontal Residual Flux
                call CenterVelocity( CenterU, CenterV, VectorType = ResidualFlux)

                call HDF5WriteData  (Me%ObjHDF5, "/Residual/FluxVel/X", &
                                     "Flux X", "m/s", Array3D = CenterU, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR29'

                call HDF5WriteData  (Me%ObjHDF5, "/Residual/FluxVel/Y", &
                                     "Flux Y", "m/s", Array3D = CenterV, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR30'


                deallocate(CenterU, CenterV, STAT = STAT_CALL)

                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR31'

                nullify(CenterU, CenterV)


                nullify(CenterW)
                allocate(CenterW(ILB:IUB, JLB:JUB, KLB:KUB), STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR32'
                CenterW = 0.
                do k = WorkKLB, WorkKUB
                do j = WorkJLB, WorkJUB
                do i = WorkILB, WorkIUB
                    if (k == WorkKLB) then
                        CenterW(i, j, k) = Me%Residual%Vertical_Velocity(i, j, k+1) / 2.
                    elseif (k == WorkKUB) then
                        CenterW(i, j, k) = Me%Residual%Vertical_Velocity(i, j, k) / 2.
                    else
                        CenterW(i, j, k) = (Me%Residual%Vertical_Velocity(i, j, k+1) +  &
                                                    Me%Residual%Vertical_Velocity(i, j, k)) / 2.
                    endif
                enddo
                enddo
                enddo

                call HDF5WriteData  (Me%ObjHDF5, "/Residual/Velocity/Z", &
                                     "Vel. Z", "m/s", Array3D = CenterW, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR33'

                deallocate(CenterW, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR34'
                nullify(CenterW)

                !Residual Water Level
                call HDF5WriteData  (Me%ObjHDF5, "/Residual/Waterlevel", &
                                     "Vel. Z", "m", Array2D = Me%Residual%WaterLevel,                       &
                                     STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR35'

            endif cd3

            call KillHydroStatistics


            call KillHDF5 (Me%ObjHDF5, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Write_HDF5_Format - ModuleHydrodynamic - ERR36'

        else  cd2

            !Writes everything to disk
            call HDF5FlushMemory (Me%ObjHDF5, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'Open_HDF5_OutPut_File - ModuleHydrodynamic - ERR37'

        endif cd2


        !Nullify auxiliar variables
        nullify(SZZ             ) 
        nullify(DWZ             )
        nullify(WaterPoints3D   )
        nullify(KFloorZ         )
        nullify(ComputeFaces3D_W)
        nullify(OpenPoints3D    )

        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "Write_HDF5_Format")

    end subroutine Write_HDF5_Format

    !End------------------------------------------------------------------------------



    subroutine ModifyMatrixesOutput


        !Arguments-------------------------------------------------------------
        

        !Local-----------------------------------------------------------------
        integer                             :: ILB, IUB, JLB, JUB, KLB, KUB
        integer                             :: i, j, k, kbottom

        !----------------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "ModifyMatrixesOutput")


        !Bounds
        ILB = Me%WorkSize%ILB 
        IUB = Me%WorkSize%IUB 

        JLB = Me%WorkSize%JLB 
        JUB = Me%WorkSize%JUB 

        KLB = Me%WorkSize%KLB 
        KUB = Me%WorkSize%KUB 

            !Horizontal Velocity
        call CenterVelocity( Me%OutPut%CenterU, Me%OutPut%CenterV,    &
                            VectorType = CurrentVelocity)



        !if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "ModifyMatrixesOutput-abs-cmplx")

        !Calculates the velocity modulus
        do k = KLB, KUB
        do j = JLB, JUB
        do i = ILB, IUB

            if (Me%External_Var%WaterPoints3D (i,j ,k) == WaterPoint) then

                Me%OutPut%ModulusH  (i, j, k) = abs(cmplx(Me%OutPut%CenterU(i, j, k), Me%OutPut%CenterV(i, j, k)))
                Me%OutPut%DirectionH(i, j, k) = atan2(Me%OutPut%CenterV(i, j, k), Me%OutPut%CenterU(i, j, k))
                Me%OutPut%DirectionH(i, j, k) = Me%OutPut%DirectionH(i, j, k) * 180. / Pi
                !Instituto Hidrografico convention
                Me%OutPut%DirectionH(i, j, k) = - Me%OutPut%DirectionH(i, j, k) + 90.
                if (Me%OutPut%DirectionH(i, j, k) < 0.) then
                    Me%OutPut%DirectionH(i, j, k) = Me%OutPut%DirectionH(i, j, k) + 360.
                endif

            end if

        enddo
        enddo
        enddo

        !if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "ModifyMatrixesOutput-abs-cmplx")

        !if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "ModifyMatrixesOutput-VelW")


        do j = JLB, JUB        
        do i = ILB, IUB
            if (Me%External_Var%WaterPoints3D (i  ,j  ,KUB) == WaterPoint) then

                kbottom = Me%External_Var%KFloor_Z(i, j)

                !By default the vertical velocity in the faces that are not compute is zero
                !Do not apply it to surface points (correction by Hernâni Theias)
                Me%Velocity%Vertical%Cartesian (i, j, kbottom : KUB) = &
                Me%Velocity%Vertical%Cartesian (i, j, kbottom : KUB) * &
                Me%External_Var%ComputeFaces3D_W(i, j, kbottom : KUB)

        
                do k = kbottom, KUB

                    Me%OutPut%CenterW(i, j, k) = (Me%Velocity%Vertical%Cartesian(i, j, k+1) +  &
                                                  Me%Velocity%Vertical%Cartesian(i, j, k)) / 2.
                enddo

            endif

        enddo
        enddo

        !if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "ModifyMatrixesOutput-VelW")


        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "ModifyMatrixesOutput")

    
    end subroutine ModifyMatrixesOutput

    !--------------------------------------------------------------------------


    subroutine CenterVelocity( CenterU, CenterV, VectorType)

        !Arguments-------------------------------------------------------------
         
        real,    dimension(:, :, :), pointer    :: CenterU, CenterV
        integer                                 :: VectorType

        !Local-----------------------------------------------------------------
        real,    dimension(:, :, :), pointer    :: FaceVelocityU, FaceVelocityV
        real(8), dimension(:, :, :), pointer    :: FaceUDouble, FaceVDouble
        real                                    :: VelU, VelV, AngleX, AngleY
        integer                                 :: ILB, IUB, JLB, JUB, KLB, KUB
        integer                                 :: i, j, k
        logical                                 :: Simple, Double
        
        
        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "CenterVelocity")

        
        !Bounds
        ILB = Me%Size%ILB 
        IUB = Me%Size%IUB 

        JLB = Me%Size%JLB 
        JUB = Me%Size%JUB 

        KLB = Me%Size%KLB 
        KUB = Me%Size%KUB 
        
        AngleX = 0.
        AngleY = 0.

        Simple = .false.
        Double = .true.
        
        !Checks for the type of velocity to interpolate
        if (VectorType == CurrentVelocity) then

            FaceVelocityU => Me%Velocity%Horizontal%U%New
            FaceVelocityV => Me%Velocity%Horizontal%V%New

            Simple = .true.

        elseif (VectorType == BaroclinicVelocity) then

            FaceVelocityU => Me%VelBaroclinic%U%New
            FaceVelocityV => Me%VelBaroclinic%V%New

            Simple = .true.

        elseif (VectorType == ResidualVelocity) then

            FaceVelocityU => Me%Residual%Velocity_U
            FaceVelocityV => Me%Residual%Velocity_V

            Simple = .true.

        elseif (VectorType == ResidualFlux) then

            FaceUDouble => Me%Residual%WaterFlux_X
            FaceVDouble => Me%Residual%WaterFlux_Y


            Double = .true.

        else
        
            stop 'CenterVelocity - ModuleHydrodynamic - ERR00'

        endif
            

        !Interpolates CenterVelocities
        
        !if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "DoLoop-CenterVelocity")

        if (Me%External_Var%Distortion .and. Simple)then

            do k = KLB, KUB
            do j = JLB, JUB
            do i = ILB, IUB
            
                if (Me%External_Var%WaterPoints3D(i, j, k) == 1) then

                    AngleX = Me%External_Var%RotationX(i, j) 
                    AngleY = Me%External_Var%RotationY(i, j) 

                    VelU = (FaceVelocityU(i, j, k)  +   FaceVelocityU(i, j+1, k)) / 2.

                    VelV = (FaceVelocityV(i, j, k)  +   FaceVelocityV(i+1, j, k)) / 2.
                else

                    VelU = 0.
                    VelV = 0.

                endif

                CenterU(i, j, k) = VelU * cos(AngleX) + VelV * cos(AngleY)
                CenterV(i, j, k) = VelU * sin(AngleX) + VelV * sin(AngleY)

            enddo
            enddo
            enddo

        elseif(Me%External_Var%Distortion .and. Double)then

            do k = KLB, KUB
            do j = JLB, JUB
            do i = ILB, IUB


                if (Me%External_Var%WaterPoints3D(i, j, k) == 1) then

                    AngleX = Me%External_Var%RotationX(i, j) 
                    AngleY = Me%External_Var%RotationY(i, j) 

                    VelU = (FaceUDouble(i, j, k)  +  FaceUDouble(i, j+1, k)) / 2.

                    VelV = (FaceVDouble(i, j, k)  +  FaceVDouble(i+1, j, k)) / 2.
                              
                else

                    VelU = 0.
                    VelV = 0.

                endif

                CenterU(i, j, k) = VelU * cos(AngleX) + VelV * cos(AngleY)
                CenterV(i, j, k) = VelU * sin(AngleX) + VelV * sin(AngleY)

            enddo
            enddo
            enddo


        elseif((.not. Me%External_Var%Distortion) .and. Simple)then
            
            do k = KLB, KUB
            do j = JLB, JUB
            do i = ILB, IUB
            
                if (Me%External_Var%WaterPoints3D(i, j, k) == 1) then

                    AngleX = 0.
                    AngleY = Pi/2.

                    AngleX = AngleX + Me%External_Var%GridRotation
                    AngleY = AngleY + Me%External_Var%GridRotation
                    
                    VelU = (FaceVelocityU(i, j, k)  +   FaceVelocityU(i, j+1, k)) / 2.

                    VelV = (FaceVelocityV(i, j, k)  +   FaceVelocityV(i+1, j, k)) / 2.
                
                else

                    VelU = 0.
                    VelV = 0.

                endif
                
                CenterU(i, j, k) = VelU * cos(AngleX) + VelV * cos(AngleY)
                CenterV(i, j, k) = VelU * sin(AngleX) + VelV * sin(AngleY)

            enddo
            enddo
            enddo

        elseif((.not. Me%External_Var%Distortion) .and. Double)then

            do k = KLB, KUB
            do j = JLB, JUB
            do i = ILB, IUB
            
                if (Me%External_Var%WaterPoints3D(i, j, k) == 1) then

                    AngleX = 0.
                    AngleY = Pi/2.


                    AngleX = AngleX + Me%External_Var%GridRotation
                    AngleY = AngleY + Me%External_Var%GridRotation

                    VelU = (FaceUDouble(i, j, k)  +  FaceUDouble(i, j+1, k)) / 2.

                    VelV = (FaceVDouble(i, j, k)  +  FaceVDouble(i+1, j, k)) / 2.
                              
                else

                    VelU = 0.
                    VelV = 0.

                endif

                CenterU(i, j, k) = VelU * cos(AngleX) + VelV * cos(AngleY)
                CenterV(i, j, k) = VelU * sin(AngleX) + VelV * sin(AngleY)

            enddo
            enddo
            enddo

        endif


        !if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "DoLoop-CenterVelocity")

        !Nullifies FaceVelocityU, FaceVelocityV
        nullify(FaceVelocityU, FaceVelocityV)
        nullify(FaceUDouble,   FaceVDouble)

        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "CenterVelocity")


    end subroutine CenterVelocity



    subroutine OutPut_TimeSeries

        !Arguments-------------------------------------------------------------
        

        !External--------------------------------------------------------------

        !Local-----------------------------------------------------------------
        integer                                 :: STAT_CALL


        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "OutPut_TimeSeries")


        !West-East Velocity
        call WriteTimeSerie(Me%ObjTimeSerie,                                &
                            Data3D = Me%OutPut%CenterU,                     &
                            STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_TimeSeries - ModuleHydrodynamic - ERR01'

        !South-North Velocity
        call WriteTimeSerie(Me%ObjTimeSerie,                                &
                            Data3D = Me%OutPut%CenterV,                     &
                            STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_TimeSeries - ModuleHydrodynamic - ERR02'


        !Vertical Velocity
        call WriteTimeSerie(Me%ObjTimeSerie,                                &
                            Data3D = Me%OutPut%CenterW,                     &
                            STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_TimeSeries - ModuleHydrodynamic - ERR03'

        !Horizontal Velocity intensity
        call WriteTimeSerie(Me%ObjTimeSerie,                                &
                            Data3D = Me%OutPut%ModulusH,                    &
                            STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_TimeSeries - ModuleHydrodynamic - ERR04'


        !Horizontal Velocity Direction
        call WriteTimeSerie(Me%ObjTimeSerie,                                &
                            Data3D = Me%OutPut%DirectionH,                  &
                            STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_TimeSeries - ModuleHydrodynamic - ERR05'


        !Elevation
        call WriteTimeSerie(Me%ObjTimeSerie,                                &
                            Data2D = Me%WaterLevel%New,                     &
                            STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_TimeSeries - ModuleHydrodynamic - ERR07'


       !Open Points
        call WriteTimeSerie(Me%ObjTimeSerie,                                &
                            Data3D_Int = Me%External_Var%OpenPoints3D,      &
                            STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_TimeSeries - ModuleHydrodynamic - ERR08'

        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "OutPut_TimeSeries")

   
    end subroutine OutPut_TimeSeries

    !--------------------------------------------------------------------------

    subroutine OutPut_Profile

        !Local-----------------------------------------------------------------
        integer                                 :: STAT_CALL
        
        !Begin-----------------------------------------------------------------

        if (MonitorPerformance) call StartWatch ("ModuleHydrodynamic", "OutPut_Profile")

        call WriteProfile(Me%ObjProfile,                                        &
                          Me%OutPut%CenterU,                                    &
                          SZZ    = Me%External_Var%SZZ,                         &
                          STAT   = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_Profile - ModuleHydrodynamic - ERR01'
            
        call WriteProfile(Me%ObjProfile,                                        &
                          Me%OutPut%CenterV,                                    &
                          SZZ    = Me%External_Var%SZZ,                         &
                          STAT   = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_Profile - ModuleHydrodynamic - ERR02'

        call WriteProfile(Me%ObjProfile,                                        &
                          Me%OutPut%CenterW,                                    &
                          SZZ    = Me%External_Var%SZZ,                         &
                          STAT   = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_Profile - ModuleHydrodynamic - ERR03'


        call WriteProfile(Me%ObjProfile,                                        &
                          Me%OutPut%ModulusH,                                   &
                          SZZ    = Me%External_Var%SZZ,                         &
                          STAT   = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_Profile - ModuleHydrodynamic - ERR04'


        call WriteProfile(Me%ObjProfile,                                        &
                          Me%OutPut%DirectionH,                                 &
                          SZZ    = Me%External_Var%SZZ,                         &
                          STAT   = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'OutPut_Profile - ModuleHydrodynamic - ERR05'

        if (MonitorPerformance) call StopWatch ("ModuleHydrodynamic", "OutPut_Profile")

    
    end subroutine OutPut_Profile

    !--------------------------------------------------------------------------------------


    Real Function TangentialVelInterpolation(Velocity_VU_New, ComputeFaces3D_VU, &
                                             DXX_YY, di, dj, I, J, K)

        !Parameters variables
        real,    dimension(:,:,:), pointer  :: Velocity_VU_New
        real,    dimension(:,:  ), pointer  :: DXX_YY
        integer, dimension(:,:,:), pointer  :: ComputeFaces3D_VU
        integer                             :: di, dj, I, J, K

        !Local Variables
        real         :: Face1, Face2, Face3, Face4, Face12,  &
                        Face34, VUvar1, VUvar2, VUAverage
        integer      :: I1, I2, I3, J1, J2, J3


            I1    = I+dj-di
            J1    = J-dj+di
            I2    = I+dj
            J2    = J+di
            I3    = I-di
            J3    = J-dj



            !This aux variables are needed to the velocity_UV_New interpolation 
            !be valid near the open boundary faces and near land faces 

            Face1      = ComputeFaces3D_VU(I1, J1, K)

            Face2      = ComputeFaces3D_VU(I2, J2, K)

            Face3      = ComputeFaces3D_VU(I3, J3, K)

            Face4      = ComputeFaces3D_VU(I , J , K)

            ! Average velocity in the North or East face 
            ! if Face1 = 0 => VUvar1 = Velocity_VU_New(I2, J2, K)
            ! Face1 = 0 (cell face where de Velocity_VU is not compute)

            Face12 = Covered

            if (Face1 == Covered .and. Face2 == Covered) then 

                VUvar1 = (Velocity_VU_New(I1, J1, K) * DXX_YY(I2, J2) + &
                          Velocity_VU_New(I2, J2, K) * DXX_YY(I1, J1))/ &
                         (DXX_YY(I1, J1) +  DXX_YY(I2, J2))

            else if (Face1 == Covered) then

                VUvar1 = Velocity_VU_New(I1, J1, K)

            else if (Face2 == Covered) then

                VUvar1 = Velocity_VU_New(I2, J2, K)

            else 
            
                VUvar1 = 0.
            
                Face12 = Not_Covered

            endif

            ! Average velocity in the South or West face 
            ! if Face3 = 0 => VUvar2 = Velocity_VU_New(I4, J4, K)
            ! Face3 = 0 (cell face where de Velocity_VU is not compute)

            Face34 = Covered

            if (Face3 == Covered .and. Face4 == Covered) then 


                VUvar2 = (Velocity_VU_New(I3, J3, K) * DXX_YY(I, J)   + &
                          Velocity_VU_New(I,   J, K) * DXX_YY(I3, J3))/ &
                         (DXX_YY(I3, J3) +  DXX_YY(I, J))

            else if (Face3 == Covered) then

                VUvar2 = Velocity_VU_New(I3, J3, K)

            else if (Face4 == Covered) then

                VUvar2 = Velocity_VU_New(I , J , K)

            else 
            
                VUvar2 = 0. 

                Face34 = Not_Covered

            endif


            ! Velocity V in the U point or Velocity U in the V point
            if (Face12 == Covered .and. Face34 == Covered) then

                VUAverage  = (VUvar1 + VUvar2)/2.

            else if (Face12 == Covered) then

                VUAverage  = VUvar1

            else if (Face34 == Covered) then

                VUAverage  = VUvar2

            else 

                VUAverage  = 0.
                
            endif                        

            TangentialVelInterpolation = VUAverage

    End Function TangentialVelInterpolation




    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    !DESTRUCTOR DESTRUCTOR DESTRUCTOR DESTRUCTOR DESTRUCTOR DESTRUCTOR DESTRUCT 

    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



    subroutine KillHydrodynamic(HydrodynamicID, STAT)

        !Arguments-------------------------------------------------------------
        integer,           intent(INOUT) :: HydrodynamicID
        integer, optional, intent(OUT)   :: STAT    


        !Local-----------------------------------------------------------------

        integer :: STAT_, nUsers
        integer :: STAT_CALL
        integer :: ready_    

        !----------------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_)
        
cd1 :   if (ready_ /= OFF_ERR_) then

            nUsers = DeassociateInstance(mHYDRODYNAMIC_,  Me%InstanceID)

cd2:        if (nUsers == 0) then

                !Time Properties - Actualises CurrentTime
                call GetComputeCurrentTime(Me%ObjTime, Me%CurrentTime, STAT = STAT_CALL)

                if (STAT_CALL /= SUCCESS_) &
                    stop 'KillHydrodynamic; ModuleHydrodynamic. ERR01.'

                !Write final HDF output if necessary
cd3:            if (Me%OutPut%hdf5ON) then

                    call ReadLock_External_Modules

                    if (.not. Me%OutPut%Run_End) then 
                        !Output in HDF
                        Me%OutPut%Run_End = .true.
                        call Write_HDF5_Format
                    endif

                    call ReadUnLock_External_Modules

                endif cd3


                if (Me%OutPut%ProfileON) then

                    call ReadLock_External_Modules

                    call OutPut_Profile

                    call ReadUnLock_External_Modules

                endif

                call Write_Final_Hydrodynamic_File 

                call Deassociate_External_Modules 

                call Kill_Sub_Modules 

                if (Me%ComputeOptions%Evolution == ImposedSolution_) then

                    if(Me%WaterLevel%ID%SolutionFromFile)then
                        call KillFillMatrix(Me%WaterLevel%ID%ObjFillMatrix, STAT = STAT_CALL)
                        if (STAT_CALL /= SUCCESS_) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR10'
                    end if
    
                    if(Me%Velocity%Horizontal%U%ID%SolutionFromFile)then
                        call KillFillMatrix(Me%Velocity%Horizontal%U%ID%ObjFillMatrix, STAT = STAT_CALL)
                        if (STAT_CALL /= SUCCESS_) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR10'
                    end if

                    if(Me%Velocity%Horizontal%V%ID%SolutionFromFile)then
                        call KillFillMatrix(Me%Velocity%Horizontal%V%ID%ObjFillMatrix, STAT = STAT_CALL)
                        if (STAT_CALL /= SUCCESS_) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR20'
                    end if


                endif

                
                call DeallocateVariables                 
               
                call DeallocateInstance()

                HydrodynamicID = 0
                STAT_          = SUCCESS_

            end if cd2

        else 
            
            STAT_ = UNKNOWN_

        end if cd1


        if (present(STAT))                                                    &
            STAT = STAT_

        !----------------------------------------------------------------------

    end subroutine KillHydrodynamic


    !--------------------------------------------------------------------------
    ! The model writes the final hydrodynamic properties in a binary file

    subroutine Write_Final_Hydrodynamic_File

        !Arguments-------------------------------------------------------------

         

        !External--------------------------------------------------------------

        integer :: STAT_CALL

        !Local-----------------------------------------------------------------


        real               :: Year_File, Month_File, Day_File, &
                              Hour_File, Minute_File, Second_File

        integer            :: IUB, JUB, KUB, ILB, JLB, KLB
        integer            :: FinalFile, i, j, k

        !----------------------------------------------------------------------

        ILB = Me%Size%ILB 
        IUB = Me%Size%IUB

        JLB = Me%Size%JLB 
        JUB = Me%Size%JUB 

        KLB = Me%Size%KLB 
        KUB = Me%Size%KUB 


        call UnitsManager(FinalFile, FileOpen, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError (FATAL_, INTERNAL_,'Write_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR01.')

        open(Unit = FinalFile, File = Me%Files%FinalHydrodynamic,           &
             Form = 'UNFORMATTED', status = 'UNKNOWN', IOSTAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError (FATAL_, INTERNAL_,'Write_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR02.')

        !Time Properties - Actualizes CurrentTime
        call GetComputeCurrentTime(Me%ObjTime, Me%CurrentTime, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError (FATAL_, INTERNAL_,'Write_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR03.')



        !Start writting the final hydrodynamic conditions file

        call ExtractDate(Me%CurrentTime, Year_File, Month_File, Day_File, Hour_File, Minute_File, Second_File)

        write(FinalFile) Year_File, Month_File, Day_File, Hour_File, Minute_File, Second_File

        !Write the discretization Method used
        write(FinalFile) Me%ComputeOptions%Num_Discretization


        write(FinalFile) Me%ComputeOptions%Residual

        !Write the last direction computed implicit by the model
        write(FinalFile) Me%Direction%XY 


        !Water level
        write(FinalFile) ((Me%WaterLevel%New(i, j),                         &
                           i = ILB, IUB), j = JLB, JUB)


        !Horizontal velocity Old
        write(FinalFile) (((Me%Velocity%Horizontal%U%Old(i, j, k),          &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )


        write(FinalFile) (((Me%Velocity%Horizontal%V%Old(i, j, k),          &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )


        !Horizontal velocity New
        write(FinalFile) (((Me%Velocity%Horizontal%U%New(i, j, k),          &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

        write(FinalFile) (((Me%Velocity%Horizontal%V%New(i, j, k),          &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

        !Water fluxes
        write(FinalFile) (((Me%WaterFluxes%X(i, j, k),                      &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

        write(FinalFile) (((Me%WaterFluxes%Y(i, j, k) ,                     &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )
                            
        write(FinalFile) (((Me%WaterFluxes%Z(i, j, k),                      &
                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )
       
cd1:    if (Me%ComputeOptions%Residual) then

                   
            write(FinalFile) Me%Residual%ResidualTime

            !Average water level 
            write(FinalFile) ((Me%Residual%WaterLevel(i, j),                &
                               i = ILB, IUB), j = JLB, JUB)

            !Residual horizontal velocities
            write(FinalFile) (((Me%Residual%Velocity_U(i, j, k),            &
                               i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )
            write(FinalFile) (((Me%Residual%Velocity_V(i, j, k),            &
                               i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            !Residual vertical velocity  
            write(FinalFile) (((Me%Residual%Vertical_Velocity(i, j, k),     &
                               i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            !Residual Water specific fluxes 
            write(FinalFile) (((Me%Residual%WaterFlux_X(i, j, k),           &
                               i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            write(FinalFile) (((Me%Residual%WaterFlux_Y(i, j, k) ,          &
                               i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )
  
                              
        endif cd1

        call WriteGeometry(Me%ObjGeometry, FinalFile, STAT = STAT_CALL) 

        if (STAT_CALL /= SUCCESS_)                                                       &
            call SetError (FATAL_, INTERNAL_,'Write_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR04.')

cd2:    if (Me%ComputeOptions%Residual) then 

            !Residual layer thickness 
            write(FinalFile) (((Me%Residual%DWZ(i, j, k),                   &
                               i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

        endif cd2

        write(FinalFile) Me%ComputeOptions%BaroclinicRadia

cd4:    if (.not. Me%ComputeOptions%BaroclinicRadia == NoRadiation_) then


            !Horizontal baroclinic velocity Old
            write(FinalFile) (((Me%VelBaroclinic%U%Old(i, j, k),            &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )


            write(FinalFile) (((Me%VelBaroclinic%V%Old(i, j, k),            &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            !Horizontal baroclinic velocity New
            write(FinalFile) (((Me%VelBaroclinic%U%New(i, j, k),            &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            write(FinalFile) (((Me%VelBaroclinic%V%New(i, j, k),            &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            !vertical baroclinic velocity 
            write(FinalFile) (((Me%VelBaroclinic%W_New(i, j, k),            &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

            write(FinalFile) (((Me%VelBaroclinic%W_Old(i, j, k),            &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )

        endif cd4


        if (Me%NonHydrostatic%ON) then

            write(FinalFile) (((Me%Velocity%Vertical%CartesianOld(i, j, k), &
                                           i = ILB, IUB), j = JLB, JUB), k = KLB, KUB )
        endif



        call UnitsManager(FinalFile, FileClose, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                        &
            call SetError (FATAL_, INTERNAL_,'Write_Final_Hydrodynamic_File; ModuleHydrodynamic. ERR06.')


    end subroutine Write_Final_Hydrodynamic_File

    !End--------------------------------------------------------------------------
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input :                                                             !
    ! OutPut:                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine Deassociate_External_Modules

        !Arguments-------------------------------------------------------------

        !Local---------------------------------------------------------
        integer                       :: nUsers

        nUsers = DeassociateInstance (mTIME_,           Me%ObjTime)
        if (nUsers == 0) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR01'

        nUsers = DeassociateInstance (mGRIDDATA_,       Me%ObjGridData)
        if (nUsers == 0) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR02'

        nUsers = DeassociateInstance (mHORIZONTALGRID_,  Me%ObjHorizontalGrid)
        if (nUsers == 0) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR03'
        
        nUsers = DeassociateInstance (mHORIZONTALMAP_,  Me%ObjHorizontalMap)
        if (nUsers == 0) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR04'
        
        nUsers = DeassociateInstance (mGEOMETRY_,       Me%ObjGeometry)
        if (nUsers == 0) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR05'

        nUsers = DeassociateInstance (mMAP_,            Me%ObjMap)
        if (nUsers == 0) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR06'

        nUsers = DeassociateInstance (mTURBULENCE_,     Me%ObjTurbulence)
        if (nUsers == 0) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR07'
#ifndef _WAVES_
        if(Me%ObjWaves /= 0)then
            nUsers = DeassociateInstance (mWAVES_,  Me%ObjWaves)
            if (nUsers == 0) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR08'
        end if
#endif

        
!        nUsers = DeassociateInstance (mBOTTOM_,         Me%ObjBottom)
!        if (nUsers == 0) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR08'
        
!        nUsers = DeassociateInstance (mSURFACE_,        Me%ObjSurface)
!        if (nUsers == 0) stop 'KillHydrodynamic - ModuleHydrodynamic - ERR09'

    End Subroutine Deassociate_External_Modules

    !End---------------------------------------------------------


    !If needed the sub-modules responsible for the:
    !   - Turbulence
    !   - OpenBoundary
    !   - Discharges
    !   - Surface conditions
    !   - Bottom Conditions
    !will be construct in this subroutine

    subroutine Kill_Sub_Modules 


        !Arguments------------------------------------------------------------

        !Local----------------------------------------------------------------
        integer :: STAT_CALL, nUsers

        !Begin----------------------------------------------------------------

        
        if (Me%ComputeOptions%WaterDischarges) then

            nUsers = GetUsersNumber(mDISCHARGES_, Me%ObjDischarges)
            if (nUsers == 1) then
            
                call Kill_Discharges(Me%ObjDischarges, STAT = STAT_CALL)

                if (STAT_CALL /= SUCCESS_)                                               &
                    stop 'Subroutine Kill_Sub_Modules; Module ModuleHydrodynamic. ERR01.'  

            else if (nUsers > 1) then

                nUsers = DeassociateInstance (mDISCHARGES_, Me%ObjDischarges)
                if (nUsers == 0) stop 'Kill_Sub_Modules - ModuleHydrodynamic - ERR02'
               
            else
            
                stop 'Subroutine Kill_Sub_Modules; Module ModuleHydrodynamic. ERR03.'  

            endif

        endif


        !Kill the assimilation object
        if (Me%ComputeOptions%Relaxation .or. Me%ComputeOptions%AltimetryAssimilation%Yes)  then

            nUsers = GetUsersNumber(mASSIMILATION_, Me%ObjAssimilation)
            if (nUsers == 1) then
            
                call KillAssimilation(Me%ObjAssimilation, STAT = STAT_CALL)

                if (STAT_CALL /= SUCCESS_)                                               &
                    stop 'Subroutine Kill_Sub_Modules; Module ModuleHydrodynamic. ERR04.'  

            else if (nUsers > 1) then

                nUsers = DeassociateInstance (mASSIMILATION_, Me%ObjAssimilation)
                if (nUsers == 0) stop 'Kill_Sub_Modules - ModuleHydrodynamic - ERR05'
               
            else
            
                stop 'Subroutine Kill_Sub_Modules; Module ModuleHydrodynamic. ERR06.'  

            endif


        endif

        call KillOpenBoundary(Me%ObjOpenBoundary, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine Kill_Sub_Modules; Module ModuleHydrodynamic. ERR07.'  


        if (Me%ComputeOptions%Evolution == Read_File_) then
            call KillHydrodynamicFile(Me%ObjHydrodynamicFileIn, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine Kill_Sub_Modules; Module ModuleHydrodynamic. ERR08.'  
        endif

        if (Me%ComputeOptions%Recording) then
            call KillHydrodynamicFile(Me%ObjHydrodynamicFileOut, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                            &
                stop 'Subroutine Kill_Sub_Modules; Module ModuleHydrodynamic. ERR09.'  
        endif

        !Kill boxes
cd1:    if (Me%State%BOXFLUXES) then

            call KillBoxDif(Me%ObjBoxDif, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine Kill_Sub_Modules; Module ModuleHydrodynamic. ERR10.'  

        endif cd1


        !Disposes the rest of the energy buffer
        if (Me%ComputeOptions%Energy) call KillEnergy

        !Deallocates the variables necessary to compute 
        !the tide potential
        if (Me%TidePotential%Compute) call KillTidePotential 

        if (Me%SubModel%ON) call KillSubModel 


    end subroutine Kill_Sub_Modules   

    !End----------------------------------------------------------------------

    subroutine KillEnergy

        !Arguments------------------------------------------------------------
         

        !Local----------------------------------------------------------------
        integer                         :: STAT_CALL

        !Disposes the rest of the buffer
        call WriteEnergyDataFile

        call UnitsManager(Me%Energy%FileID, FileClose, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR01' 

        !Deallocates buffer
        deallocate(Me%Energy%YearBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR02' 

        deallocate(Me%Energy%MonthBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR03' 

        deallocate(Me%Energy%DayBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR04' 

        deallocate(Me%Energy%HourBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR05' 

        deallocate(Me%Energy%MinuteBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR06' 

        deallocate(Me%Energy%SecondBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR07' 

        deallocate(Me%Energy%KineticBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR08' 

        deallocate(Me%Energy%PotentialBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR09' 

        deallocate(Me%Energy%MassBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR10' 

        deallocate(Me%Energy%VolumeBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR11' 

        deallocate(Me%Energy%OpenVolumeBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR11a' 

        deallocate(Me%Energy%WaterLevelBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR12' 

        deallocate(Me%Energy%BarotropicKEBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR13' 

        deallocate(Me%Energy%RelativeKEBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR14' 

        deallocate(Me%Energy%RelativePEBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR15' 

        deallocate(Me%Energy%BaroclinicKEBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR16' 

        deallocate(Me%Energy%VelMaxBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR17' 

        deallocate(Me%Energy%VelMaxBaroclinicBuffer, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                        &
            stop 'KillEnergy - ModuleHydrodynamic - ERR18' 


    end subroutine KillEnergy

    !--------------------------------------------------------------------------

    Subroutine KillTidePotential

        !Arguments-------------------------------------------------------------

        

        !Local-----------------------------------------------------------------
        integer   :: STATUS
        


        deallocate (Me%TidePotential%Frequency, STAT = STATUS)
        if (STATUS /= SUCCESS_)                                              &
            call SetError (FATAL_, OUT_OF_MEM_, "KillTidePotential - Hydrodynamic - ERR01")

        deallocate (Me%TidePotential%Amplitude, STAT = STATUS)
        if (STATUS /= SUCCESS_)                                              &
            call SetError (FATAL_, OUT_OF_MEM_, "KillTidePotential - Hydrodynamic - ERR02")

        deallocate (Me%TidePotential%Arguments        , STAT = STATUS)
        if (STATUS /= SUCCESS_)                                              &
            call SetError (FATAL_, OUT_OF_MEM_, "KillTidePotential - Hydrodynamic - ERR03")

        deallocate (Me%TidePotential%Beta            , STAT = STATUS)
        if (STATUS /= SUCCESS_)                                              &
            call SetError (FATAL_, OUT_OF_MEM_, "KillTidePotential - Hydrodynamic - ERR04")

        deallocate (Me%TidePotential%m               , STAT = STATUS)
        if (STATUS /= SUCCESS_)                                              &
            call SetError (FATAL_, OUT_OF_MEM_, "KillTidePotential - Hydrodynamic - ERR05")

        deallocate (Me%TidePotential%L               , STAT = STATUS)
        if (STATUS /= SUCCESS_)                                              &
            call SetError (FATAL_, OUT_OF_MEM_, "KillTidePotential - Hydrodynamic - ERR06")


    end subroutine KillTidePotential


    !-----------------------------------------------------------------

    !--------------------------------------------------------------------------

    Subroutine KillHydroStatistics

        !Arguments-------------------------------------------------------------

        

        !Local-----------------------------------------------------------------
        integer   :: STATUS, i


        if (Me%Statistics%ON) then


            do i = 1, Me%Statistics%Nprop
            
                call KillStatistic (Me%Statistics%ID(i), STAT = STATUS)
                if (STATUS /= SUCCESS_)                                                  &
                    call SetError (FATAL_, OUT_OF_MEM_, "KillHydroStatistics - Hydrodynamic - ERR01")

            enddo
        

        endif

    end subroutine KillHydroStatistics


    !-----------------------------------------------------------------

    !--------------------------------------------------------------------------

    Subroutine KillSubModel

        !Arguments-------------------------------------------------------------

        

        !Local-----------------------------------------------------------------
        integer   :: STATUS

        

        deallocate (Me%SubModel%Z, STAT = STATUS)
        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR01")

        nullify(Me%SubModel%Z)

        deallocate (Me%SubModel%U_New, STAT = STATUS)
        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR02")

        nullify(Me%SubModel%U_New)

        deallocate (Me%SubModel%V_New, STAT = STATUS)
        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR03")

        nullify(Me%SubModel%V_New)

        nullify(Me%SubModel%UV_New)


        deallocate (Me%SubModel%DUZ_New, STAT = STATUS)
        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR04")

        nullify(Me%SubModel%DUZ_New)

        deallocate (Me%SubModel%DVZ_New, STAT = STATUS)
        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR05")

        nullify(Me%SubModel%DVZ_New)



        deallocate (Me%SubModel%qX, STAT = STATUS)

        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR06")

        nullify(Me%SubModel%qX)

        deallocate (Me%SubModel%qY, STAT = STATUS)

        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR07")

        nullify(Me%SubModel%qY )

        nullify(Me%SubModel%qXY)

        nullify(Me%SubModel%qYX)


        deallocate (Me%SubModel%DUZ_Old, STAT = STATUS)
        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR08")

        nullify(Me%SubModel%DUZ_Old)

        deallocate (Me%SubModel%DVZ_Old, STAT = STATUS)
        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR09")

        nullify(Me%SubModel%DVZ_Old)

        nullify(Me%SubModel%DUVZ_Old)

        deallocate (Me%SubModel%U_Old, STAT = STATUS)
        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR09a")

        nullify(Me%SubModel%U_Old)

        deallocate (Me%SubModel%V_Old, STAT = STATUS)
        if (STATUS /= SUCCESS_)                                                          &
            call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR09b")

        nullify(Me%SubModel%V_Old)

        nullify(Me%SubModel%UV_Old)

cd1:    if (Me%SubModel%InterpolTime) then

            deallocate (Me%SubModel%Z_Previous, STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                          &
                call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR10")

            nullify(Me%SubModel%Z_Previous)

            deallocate (Me%SubModel%Z_Next, STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                          &
                call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR11")

            nullify(Me%SubModel%Z_Next)

            deallocate (Me%SubModel%U_Previous, STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                          &
                call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR12")

            nullify(Me%SubModel%U_Previous)

            deallocate (Me%SubModel%U_Next, STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                          &
                call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR13")

            nullify(Me%SubModel%U_Next)


            deallocate (Me%SubModel%V_Previous, STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                          &
                call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR14")

            nullify(Me%SubModel%V_Previous)

            deallocate (Me%SubModel%V_Next, STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                          &
                call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR15")

            nullify(Me%SubModel%V_Next)


            deallocate (Me%SubModel%DUZ_Previous, STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                          &
                call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR16")

            nullify(Me%SubModel%DUZ_Previous)

            deallocate (Me%SubModel%DUZ_Next, STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                          &
                call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR17")

            nullify(Me%SubModel%DUZ_Next)


            deallocate (Me%SubModel%DVZ_Previous, STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                          &
                call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR18")

            nullify(Me%SubModel%DVZ_Previous)

            deallocate (Me%SubModel%DVZ_Next, STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                          &
                call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR19")

            nullify(Me%SubModel%DVZ_Next)

        endif cd1


cd2:    if (Me%SubModel%DeadZone) then

            deallocate (Me%SubModel%DeadZonePoint, STAT = STATUS)
            if (STATUS /= SUCCESS_)                                                      &
                call SetError (FATAL_, OUT_OF_MEM_, "KillSubModel - Hydrodynamic - ERR20")

        endif cd2



    End Subroutine KillSubModel

    !--------------------------------------------------------------------------

    Subroutine DeallocateVariables

        !Arguments-------------------------------------------------------------

        

        !Local-----------------------------------------------------------------

        integer :: STAT_CALL

        !Begin------------------------------------------------------------------

        !Water level variables allocation
        deallocate (Me%WaterLevel%New, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR01.' 

        nullify (Me%WaterLevel%New) 



        deallocate (Me%WaterLevel%Old, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR02.' 

        nullify (Me%WaterLevel%Old) 
             
        deallocate (Me%WaterLevel%VolumeCreated, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR02a.' 

        nullify (Me%WaterLevel%VolumeCreated) 


        !Horizontal velocity
        deallocate (Me%Velocity%Horizontal%U%New, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR04.' 

        nullify (Me%Velocity%Horizontal%U%New) 



        deallocate (Me%Velocity%Horizontal%U%Old, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR05.' 

        nullify (Me%Velocity%Horizontal%U%Old)            



        deallocate (Me%Velocity%Horizontal%V%New, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR07.' 

        nullify (Me%Velocity%Horizontal%V%New) 


             
        deallocate (Me%Velocity%Horizontal%V%Old, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR08.' 

        nullify (Me%Velocity%Horizontal%V%Old) 

             
        !Auxiliar horizontal velocity pointers
        nullify (Me%Velocity%Horizontal%UV%New) 
        nullify (Me%Velocity%Horizontal%UV%Old) 

        nullify (Me%Velocity%Horizontal%VU%New) 
        nullify (Me%Velocity%Horizontal%VU%Old) 



        !Vertical Velocity
        deallocate (Me%Velocity%Vertical%Across, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR10.' 
        
        nullify (Me%Velocity%Vertical%Across)         

         
        deallocate (Me%Velocity%Vertical%Cartesian, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11.' 

        nullify (Me%Velocity%Vertical%Cartesian) 
        
        
        if (Me%NonHydrostatic%ON) then

            deallocate (Me%Velocity%Vertical%CartesianOld, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11a.' 

            nullify (Me%Velocity%Vertical%CartesianOld) 

            deallocate (Me%NonHydrostatic%PressureCorrect, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11b.' 

            nullify (Me%NonHydrostatic%PressureCorrect) 

            deallocate (Me%NonHydrostatic%PrevisionalQ, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11b.' 

            nullify (Me%NonHydrostatic%PrevisionalQ) 

            deallocate (Me%NonHydrostatic%CCoef, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11b.' 

            nullify (Me%NonHydrostatic%CCoef) 

            deallocate (Me%NonHydrostatic%GCoef, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11b.' 

            nullify (Me%NonHydrostatic%GCoef) 

        endif

        if (.not. Me%ComputeOptions%BaroclinicRadia == NoRadiation_) then

            deallocate (Me%VelBaroclinic%W_New, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                       &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11a.' 

            nullify (Me%VelBaroclinic%W_New) 

            deallocate (Me%VelBaroclinic%W_Old, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                       &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11b.' 

            nullify (Me%VelBaroclinic%W_Old) 

            deallocate (Me%VelBaroclinic%U%New, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                       &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11c.' 

            nullify(Me%VelBaroclinic%U%New)

            deallocate (Me%VelBaroclinic%U%Old, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                       &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11d.' 

            nullify(Me%VelBaroclinic%U%Old)



            deallocate (Me%VelBaroclinic%V%New, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                       &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11e.' 

            nullify(Me%VelBaroclinic%V%New)

            deallocate (Me%VelBaroclinic%V%Old, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                       &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11f.' 

            nullify(Me%VelBaroclinic%V%Old)

            deallocate (Me%VelBaroclinic%U2D, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                       &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11g.' 
      
            nullify(Me%VelBaroclinic%U2D)


            deallocate (Me%VelBaroclinic%V2D, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                       &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR11h.' 
      
            nullify(Me%VelBaroclinic%V2D)


            !Auxiliar horizontal baroclinic velocity pointers
            nullify (Me%VelBaroclinic%UV%New) 
            nullify (Me%VelBaroclinic%UV%Old) 

            nullify (Me%VelBaroclinic%VU%New) 
            nullify (Me%VelBaroclinic%VU%Old) 

            nullify (Me%VelBaroclinic%UV2D) 

        endif
                      


        !Water fluxes        
        deallocate (Me%WaterFluxes%X, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DellocateVariables; Module ModuleHydrodynamic. ERR13.' 

        nullify (Me%WaterFluxes%X) 
             
        deallocate (Me%WaterFluxes%Y, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR14.' 
             
        nullify (Me%WaterFluxes%Y) 


        deallocate (Me%WaterFluxes%Z, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR15.' 

        nullify (Me%WaterFluxes%Z) 

        deallocate (Me%WaterFluxes%Discharges, STAT = STAT_CALL) 

        if (STAT_CALL /= SUCCESS_)                                                   &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR15a.' 

        nullify (Me%WaterFluxes%Discharges) 


        !Auxiliar Water Fluxes
        nullify (Me%WaterFluxes%XY) 
        nullify (Me%WaterFluxes%YX) 


        !If compute Residual properties then must allocate residual variables

cd1:    if (Me%ComputeOptions%Residual) then 


            Me%Residual%ResidualTime = FillValueReal

            
            !Can be interesting to compute the average water level
            deallocate (Me%Residual%WaterLevel, STAT = STAT_CALL)        
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR03.'  

            nullify (Me%Residual%WaterLevel) 


            deallocate (Me%Residual%Velocity_U, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR06.'  

            nullify (Me%Residual%Velocity_U)



            deallocate (Me%Residual%Velocity_V, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR09.'  

            nullify (Me%Residual%Velocity_V) 


            deallocate (Me%Residual%Vertical_Velocity, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR12.'  

            nullify (Me%Residual%Vertical_Velocity)


            deallocate (Me%Residual%WaterFlux_X, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR13a.' 

            nullify (Me%Residual%WaterFlux_X) 


             
            deallocate (Me%Residual%WaterFlux_Y, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR14a.' 
          
            nullify (Me%Residual%WaterFlux_Y) 

            deallocate (Me%Residual%DWZ, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR13b.' 

            nullify (Me%Residual%DWZ) 

            
        endif cd1


        !Forces 
        deallocate (Me%Forces%Rox3X, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR16.' 
        
        nullify (Me%Forces%Rox3X) 

        deallocate (Me%Forces%Rox3Y, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR16a.' 

        nullify (Me%Forces%Rox3Y) 
                
             
        deallocate (Me%Forces%Horizontal_Transport, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR17.' 

        nullify (Me%Forces%Horizontal_Transport) 
             
        deallocate (Me%Forces%Inertial_Aceleration, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR18.' 

        nullify (Me%Forces%Inertial_Aceleration) 


        deallocate (Me%Forces%TidePotentialLevel,   STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR18a.' 

        nullify (Me%Forces%TidePotentialLevel) 


        if (Me%Relaxation%Force) then
            deallocate (Me%Forces%Relax_Aceleration, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR18c.' 

            nullify (Me%Forces%Relax_Aceleration) 

        endif


        if (Me%Relaxation%Geometry) then
            deallocate (Me%Relaxation%DecayTimeGeo, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR18d.' 

            nullify (Me%Relaxation%DecayTimeGeo) 

        endif


             
        !Coefficients
        deallocate (Me%Coef%D2%D, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR20.' 

        nullify (Me%Coef%D2%D) 
                    


        deallocate (Me%Coef%D2%E, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR21.' 

        nullify (Me%Coef%D2%E) 
                     


        deallocate (Me%Coef%D2%F, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR22.' 

        nullify (Me%Coef%D2%F) 


             
        deallocate (Me%Coef%D2%Ti, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR23.'  

        nullify (Me%Coef%D2%Ti) 




cd2:    if (Me%ComputeOptions%BarotropicRadia == FlatherWindWave_ .or.      &
            Me%ComputeOptions%BarotropicRadia == FlatherLocalSolution_) then

            deallocate (Me%Coef%D2%Rad, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR23a.'  

            nullify(Me%Coef%D2%Rad)


            deallocate (Me%Coef%D2%TiRad, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_)                                                   &
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR23b.'  

            nullify(Me%Coef%D2%TiRad)

        endif cd2

        deallocate (Me%Coef%D3%D, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR24.'  

        nullify (Me%Coef%D3%D) 



        deallocate (Me%Coef%D3%E, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR25.' 
 
         nullify (Me%Coef%D3%E) 


        
             
        deallocate (Me%Coef%D3%F, STAT = STAT_CALL) 

        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR26.' 
        
        nullify (Me%Coef%D3%F) 


             
        deallocate (Me%Coef%D3%Ti, STAT = STAT_CALL) 

        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR27.'  

        nullify (Me%Coef%D3%Ti)

        
        !External Variables

        !Bottom boundary: this variable in the future must migrate to the module ModuleBottom
        deallocate (Me%External_Var%ChezyZ, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR28.'  

        nullify (Me%External_Var%ChezyZ)

        deallocate (Me%External_Var%ChezyVelUV, STAT = STAT_CALL) 
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR28.'  

        nullify (Me%External_Var%ChezyVelUV)



        !OutPut Time variables

cd3:    if (Me%OutPut%hdf5ON) then
        

            Deallocate (Me%OutPut%OutTime, STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_) stop 'Sub. DeallocateVariables - ModuleHydrodynamic - ERR33'

            nullify (Me%OutPut%OutTime)
            

        endif cd3


        if(Me%OutPut%ProfileON)then

            call KillProfile(Me%ObjProfile, STAT = STAT_CALL)
            if (STAT_CALL .NE. SUCCESS_)                                                 &
                stop 'DeallocateVariables - ModuleHydrodynamic - ERR340'

        end if

        !Kills the TimeSerie
        if (Me%ObjTimeSerie /= 0) then
            call KillTimeSerie(Me%ObjTimeSerie, STAT = STAT_CALL)
            if (STAT_CALL .NE. SUCCESS_)                                                 &
                stop 'DeallocateVariables - ModuleHydrodynamic - ERR34'
        endif

                
cd4:    if (Me%ComputeOptions%Baroclinic) then 

            deallocate (Me%Coef%Baroc%Kleft,       STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                   &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR35.'  

            nullify (Me%Coef%Baroc%Kleft)


        
            deallocate (Me%Coef%Baroc%Kright,      STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                   &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR36'

            nullify (Me%Coef%Baroc%Kright)

        
        
            deallocate (Me%Coef%Baroc%Depth_integ, STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                   &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR37'

            nullify (Me%Coef%Baroc%Depth_integ)


            deallocate (Me%Coef%Baroc%Hcenter,     STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                   &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR38'

            nullify (Me%Coef%Baroc%Hcenter)
        
        
        
            deallocate (Me%Coef%Baroc%Hleft,       STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                   &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR39'

            nullify (Me%Coef%Baroc%Hleft)

        
                 
            deallocate (Me%Coef%Baroc%Hright,      STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                   &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR40'
        
            nullify (Me%Coef%Baroc%Hright)

            
              
            deallocate (Me%Coef%Baroc%HroLeft,     STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                   &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR41'

            nullify (Me%Coef%Baroc%HroLeft)
        
        
            deallocate (Me%Coef%Baroc%HroRight,    STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                   &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR42'
            nullify (Me%Coef%Baroc%HroRight)

            deallocate (Me%Coef%Baroc%DensRight,    STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                   &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR420'
            nullify (Me%Coef%Baroc%DensRight)

            deallocate (Me%Coef%Baroc%DensLeft,    STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                   &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR430'
            nullify (Me%Coef%Baroc%DensLeft)

        endif cd4


        
        deallocate (Me%VECG_3D,    STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &            
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR43'
        nullify (Me%VECG_3D)

        
        deallocate (Me%VECW_3D,    STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &            
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR44'
        nullify (Me%VECW_3D)

        
        deallocate (Me%VECG_2D,    STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &            
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR45'
        nullify (Me%VECG_2D)

        
        deallocate (Me%VECW_2D,    STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &            
            stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR46'
        nullify (Me%VECW_2D)

        if (Me%ComputeOptions%BarotropicRadia == BlumbergKantha_)  then

            deallocate (Me%ComputeOptions%Tlag, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                                   &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR47'
            nullify (Me%ComputeOptions%Tlag)

        endif

        if (Me%ComputeOptions%BiHarmonic) then

            deallocate (Me%ComputeOptions%BiHarmonicUX_VY,    STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR48'
            
            deallocate (Me%ComputeOptions%BiHarmonicUY_VX,    STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) &            
                stop 'Subroutine DeallocateVariables; Module ModuleHydrodynamic. ERR49'

        endif

ic1:    if (Me%CyclicBoundary%ON) then

            deallocate (Me%Coef%D1%a,   STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR52.' 

            deallocate (Me%Coef%D1%b,   STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR53.' 

            deallocate (Me%Coef%D1%bb,  STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR54.' 

            deallocate (Me%Coef%D1%c,   STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR55.' 

            deallocate (Me%Coef%D1%r,   STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR56.' 

            deallocate (Me%Coef%D1%u,   STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR57.' 

            deallocate (Me%Coef%D1%x,   STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR58.' 

            deallocate (Me%Coef%D1%z,   STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR59.' 

            deallocate (Me%Coef%D1%gam, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR60.' 

        endif ic1

        if(Me%ComputeOptions%Obstacle)then
            
            deallocate (Me%Drag%Coef, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR70.' 

            if(Me%Drag%ID%SolutionFromFile)then
                call KillFillMatrix(Me%Drag%ID%ObjFillMatrix, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR71.' 
            endif

            deallocate (Me%Forces%ObstacleDrag_Aceleration, STAT = STAT_CALL) 
            if (STAT_CALL /= SUCCESS_) stop 'DeallocateVariables; ModuleHydrodynamic. ERR72.' 


        end if

        if (Me%OutPut%TimeSerieON .or. Me%OutPut%hdf5ON .or. Me%OutPut%ProfileON) &
            call KillMatrixesOutput

       !----------------------------------------------------------------------

    end subroutine DeallocateVariables   

    !--------------------------------------------------------------------------

    subroutine KillMatrixesOutput

        !Arguments-------------------------------------------------------------
        

        !Local-----------------------------------------------------------------
        integer                             :: STAT_CALL

        !----------------------------------------------------------------------


        !Horizontal Velocity
        deallocate(Me%OutPut%CenterU   ,                       &
                   Me%OutPut%CenterV   ,                       &
                   Me%OutPut%ModulusH  ,                       &
                   Me%OutPut%DirectionH,                       &
                   STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'KillMatrixesOutput - ModuleHydrodynamic - ERR10'

        nullify  (Me%OutPut%CenterU   )
        nullify  (Me%OutPut%CenterV   )
        nullify  (Me%OutPut%ModulusH  )
        nullify  (Me%OutPut%DirectionH)


        !Vertical Velocity
        deallocate (Me%OutPut%CenterW, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_) stop 'KillMatrixesOutput - ModuleHydrodynamic - ERR20'

        nullify  (Me%OutPut%CenterW)


    
    end subroutine KillMatrixesOutput

    !--------------------------------------------------------------------------


    subroutine DeallocateInstance ()

        !Arguments-------------------------------------------------------------

        !Local-----------------------------------------------------------------
        type (T_Hydrodynamic), pointer           :: AuxHydrodynamic
        type (T_Hydrodynamic), pointer           :: PreviousHydrodynamic

        !Updates pointers
        if (Me%InstanceID == FirstHydrodynamic%InstanceID) then
            FirstHydrodynamic => FirstHydrodynamic%Next
        else
            PreviousHydrodynamic => FirstHydrodynamic
            AuxHydrodynamic      => FirstHydrodynamic%Next
            do while (AuxHydrodynamic%InstanceID /= Me%InstanceID)
                PreviousHydrodynamic => AuxHydrodynamic
                AuxHydrodynamic      => AuxHydrodynamic%Next
            enddo

            !Now update linked list
            PreviousHydrodynamic%Next => AuxHydrodynamic%Next


        endif

        !Deallocates instance
        deallocate (Me)
        nullify    (Me) 

            
    end subroutine DeallocateInstance





    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    !MANAGEMENT MANAGEMENT MANAGEMENT MANAGEMENT MANAGEMENT MANAGEMENT MANAGEME

    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    subroutine Ready (HydrodynamicID, ready_) 

        !Arguments-------------------------------------------------------------
        integer                                     :: HydrodynamicID
        integer                                     :: ready_

        !----------------------------------------------------------------------

        nullify (Me)

cd1:    if (HydrodynamicID > 0) then
            Me => FirstHydrodynamic
            do while (associated (Me))
                if (Me%InstanceID == HydrodynamicID) exit
                Me => Me%Next
            enddo

            if (.not. associated(Me))                                                    &
                stop 'ModuleHydrodynamic - Ready - ERR01'

            ready_ = VerifyReadLock (mHYDRODYNAMIC_, Me%InstanceID)
        else
            ready_ = OFF_ERR_
        end if cd1


        !----------------------------------------------------------------------

    end subroutine Ready

    !--------------------------------------------------------------------------


    subroutine ReadyFather (HydrodynamicID, HydroFather, ready_) 

        !Arguments-------------------------------------------------------------
        integer                                     :: HydrodynamicID
        type (T_Hydrodynamic), pointer              :: HydroFather
        integer                                     :: ready_

        !----------------------------------------------------------------------

        nullify (HydroFather)

cd1:    if (HydrodynamicID > 0) then
            HydroFather => FirstHydrodynamic
            do while (associated (HydroFather))
                if (HydroFather%InstanceID == HydrodynamicID) exit
                HydroFather => HydroFather%Next
            enddo

            if (.not. associated(HydroFather))                                                    &
                stop 'ModuleHydrodynamic - Ready - ERR01'

            ready_ = VerifyReadLock (mHYDRODYNAMIC_, HydroFather%InstanceID)

        else
            ready_ = OFF_ERR_
        end if cd1


        !----------------------------------------------------------------------

    end subroutine ReadyFather




    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Geometry, Mapping                                                            !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !         Manuel Ruiz Villarreal 2000: Vertical viscosities are located at faces of control volume  !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine ReadLock_ModuleTurbulence 


        !Arguments-------------------------------------------------------------------
        


        !Local----------------------------------------------------------------------
        integer                          :: STAT_CALL 

        !Module - ModuleTurbulence
        !Turbulence Properties
        call GetHorizontalViscosity(Me%ObjTurbulence,                       &
                                    Me%External_Var%Visc_H_Center,          &
                                    Me%External_Var%Visc_H_Corner,          &
                                    STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine ReadLock_ModuleTurbulence; module ModuleHydrodynamic. ERR01.'



!Manuel
        call GetVerticalViscosity(Me%ObjTurbulence,                         &
                                  VerticalViscosityCenter =                              &
                                  Me%External_Var%Vertical_Viscosity,       &
                                  STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine ReadLock_ModuleTurbulence; module ModuleHydrodynamic. ERR02.'



    End Subroutine ReadLock_ModuleTurbulence

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------

    Subroutine ReadUnLock_ModuleTurbulence


        !Arguments-------------------------------------------------------------

        


        !Local-----------------------------------------------------------------

        integer        :: STAT_CALL 

        !----------------------------------------------------------------------

        !Module - ModuleTurbulence
        !Turbulence Properties
        !Horizontal Turbulent Viscosity in the cell Center
        call UnGetTurbulence(Me%ObjTurbulence,                   &
                             Me%External_Var%Visc_H_Center, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleTurbulence; module ModuleHydrodynamic. ERR01.'



        !Horizontal Turbulent Viscosity in the cell corner
        call UnGetTurbulence(Me%ObjTurbulence,                   &
                             Me%External_Var%Visc_H_Corner, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleTurbulence; module ModuleHydrodynamic. ERR02.'



        !Vertical Turbulent Viscosity
        call UnGetTurbulence(Me%ObjTurbulence,                   &
                             Me%External_Var%Vertical_Viscosity, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleTurbulence; module ModuleHydrodynamic. ERR03.'

        !----------------------------------------------------------------------

    End Subroutine ReadUnLock_ModuleTurbulence

    !--------------------------------------------------------------------------

#ifndef _WAVES_
    Subroutine ReadLock_ModuleWaves 

        !Local------------------------------------------------------------------
        integer                          :: STAT_CALL 

        !Begin------------------------------------------------------------------

        call GetWavesStress    (Me%ObjWaves,                                             &
                                Me%External_Var%TauWavesU,                               &
                                Me%External_Var%TauWavesV,                               &
                                STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                          &
            stop 'Subroutine ReadLock_ModuleWaves; module ModuleHydrodynamic. ERR01.'


    End Subroutine ReadLock_ModuleWaves


    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------

    Subroutine ReadUnLock_ModuleWaves

        !Local-----------------------------------------------------------------

        integer        :: STAT_CALL 

        !----------------------------------------------------------------------

        call UnGetWaves(Me%ObjWaves,                                                     &
                             Me%External_Var%TauWavesU, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine ReadUnLock_ModuleWaves; module ModuleHydrodynamic. ERR01.'

        call UnGetWaves(Me%ObjWaves,                                                     &
                             Me%External_Var%TauWavesV, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine ReadUnLock_ModuleWaves; module ModuleHydrodynamic. ERR02.'

        !----------------------------------------------------------------------

    End Subroutine ReadUnLock_ModuleWaves

    !--------------------------------------------------------------------------

#endif

    !--------------------------------------------------------------------------

    Subroutine ReadLock_ModuleHorizontalGrid


        !Arguments-------------------------------------------------------------

        


        !Local----------------------------------------------------------------------
        integer                          :: STAT_CALL 

       
        !Module - ModuleHorizontalGrid
        !Horizontal Grid properties
         call GetHorizontalGrid(Me%ObjHorizontalGrid,                                   &
                                DXX  = Me%External_Var%DXX,                             &
                                DYY  = Me%External_Var%DYY,                             &
                                DZX  = Me%External_Var%DZX,                             &
                                DZY  = Me%External_Var%DZY,                             &
                                DUX  = Me%External_Var%DUX,                             &
                                DVY  = Me%External_Var%DVY,                             &
                                STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                                      &
            stop 'Subroutine ReadLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR01.'



        call GetCoriolisFrequency(Me%ObjHorizontalGrid,                                 &
                                  Me%External_Var%Coriolis_Freq,                        &
                                  STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                                      &
            stop 'Subroutine ReadLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR02.'

        call GetCheckDistortion (Me%ObjHorizontalGrid,                                  &
                                 Me%External_Var%Distortion,                            &
                                 STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                                      &
            stop 'Subroutine ReadLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR03.'

        if (Me%External_Var%Distortion) then

            call GetGridRotation(Me%ObjHorizontalGrid,                                  &
                                 Me%External_Var%RotationX,                             &
                                 Me%External_Var%RotationY,                             &
                                 STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                  &
                stop 'Subroutine ReadLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR04.'

        else

            call GetGridAngle(Me%ObjHorizontalGrid,                                     &
                              Me%External_Var%GridRotation,                             &
                              STAT = STAT_CALL)

            if (STAT_CALL /= SUCCESS_)                                                  &
                stop 'Subroutine ReadLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR40.'

            !Convert from degrees in to radians 
            Me%External_Var%GridRotation = Me%External_Var%GridRotation * Pi / 180.
            

        endif


    End Subroutine ReadLock_ModuleHorizontalGrid

    !End----------------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input :                                                                              !
    ! OutPut:                                                                              !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine ReadUnLock_ModuleHorizontalGrid 


        !Arguments-------------------------------------------------------------

        


        !Local-----------------------------------------------------------------
        integer        :: STAT_CALL 
        
        !Module - ModuleHorizontalGrid
        !Horizontal Grid properties

        !DXX
        call UnGetHorizontalGrid(Me%ObjHorizontalGrid,           &
                                 Me%External_Var%DXX, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR01.'

        
        !DYY
        call UnGetHorizontalGrid(Me%ObjHorizontalGrid,           &
                                 Me%External_Var%DYY, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR02.'


        !DZX
        call UnGetHorizontalGrid(Me%ObjHorizontalGrid,           &
                                 Me%External_Var%DZX, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR03.'


        !DZY
        call UnGetHorizontalGrid(Me%ObjHorizontalGrid,           &
                                 Me%External_Var%DZY, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR04.'


        !DUX
        call UnGetHorizontalGrid(Me%ObjHorizontalGrid,           &
                                 Me%External_Var%DUX, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR05.'


        !DVY
        call UnGetHorizontalGrid(Me%ObjHorizontalGrid,           &
                                 Me%External_Var%DVY, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR06.'

         
        !Coriolis frequency
        call UnGetHorizontalGrid(Me%ObjHorizontalGrid,           &
                                 Me%External_Var%Coriolis_Freq, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR07.'

        if (Me%External_Var%Distortion) then

            call UnGetHorizontalGrid(Me%ObjHorizontalGrid,           &
                                     Me%External_Var%RotationX, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                            &
                stop 'Subroutine ReadUnLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR08.'

         
            call UnGetHorizontalGrid(Me%ObjHorizontalGrid,           &
                                     Me%External_Var%RotationY, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_)                                            &
                stop 'Subroutine ReadUnLock_ModuleHorizontalGrid; module ModuleHydrodynamic. ERR09.'

        endif


        !---------------------------------------------------------------------

    End Subroutine ReadUnLock_ModuleHorizontalGrid

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------

    Subroutine ReadLock_ModuleHorizontalMap 


        !Arguments-------------------------------------------------------------------
        


        !Local----------------------------------------------------------------------
        integer                          :: STAT_CALL 



        !Module - ModuleHorizontalMap
        !Horizontal Mapping Properties
        call GetBoundaryFaces(Me%ObjHorizontalMap,                          &
                              Me%External_Var%BoundaryFacesU,               &
                              Me%External_Var%BoundaryFacesV,               &
                              STAT = STAT_CALL)      

        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine ReadLock_ModuleHorizontalMap; module ModuleHydrodynamic. ERR**.'


        call GetBoundaries(Me%ObjHorizontalMap,                             &
                           Me%External_Var%BoundaryPoints,                  &
                              STAT = STAT_CALL)      

        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine ReadLock_ModuleHorizontalMap; module ModuleHydrodynamic. ERR**.'

        !Gets WaterPoints2D
        call GetWaterPoints2D(Me%ObjHorizontalMap, &
                              Me%External_Var%WaterPoints2D, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine ReadLock_ModuleHorizontalMap; module ModuleHydrodynamic. ERR**.'


    End Subroutine ReadLock_ModuleHorizontalMap

    !End----------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input :                                                                              !
    ! OutPut:                                                                              !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine ReadUnLock_ModuleHorizontalMap 


        !Arguments-------------------------------------------------------------------
        


        !Local----------------------------------------------------------------------
        integer        :: STAT_CALL 

  
        !Module - ModuleHorizontalMap
        !Horizontal Mapping Properties

        !Boundary faces along the X direction
        call UnGetHorizontalMap(Me%ObjHorizontalMap, Me%External_Var%BoundaryFacesU,  &
                                STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                           &
            stop 'Subroutine ReadUnLock_ModuleHorizontalMap; module ModuleHydrodynamic. ERR**.'


        !Boundary faces along the Y direction
        call UnGetHorizontalMap(Me%ObjHorizontalMap, Me%External_Var%BoundaryFacesV,  &
                                STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                           &
            stop 'Subroutine ReadUnLock_ModuleHorizontalMap; module ModuleHydrodynamic. ERR**.'

       !Boundary points
        call UnGetHorizontalMap(Me%ObjHorizontalMap, Me%External_Var%BoundaryPoints,  &
                                STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                           &
            stop 'Subroutine ReadUnLock_ModuleHorizontalMap; module ModuleHydrodynamic. ERR**.'

        !UnGets WaterPoints2D
        call UnGetHorizontalMap(Me%ObjHorizontalMap, &
                                Me%External_Var%WaterPoints2D, STAT = STAT_CALL)
        
        if (STAT_CALL /= SUCCESS_)                                           &
            stop 'Subroutine ReadUnLock_ModuleHorizontalMap; module ModuleHydrodynamic. ERR**.'



    End Subroutine ReadUnLock_ModuleHorizontalMap

    !End----------------------------------------------------------------------



    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Geometry, Mapping                                                            !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine ReadLock_ModuleGeometry 


        !Arguments-------------------------------------------------------------------
        


        !Local----------------------------------------------------------------------
        integer                          :: STAT_CALL 

        !Module - ModuleGeometry
        !3D Geometry properties

        call GetGeometryKFloor(Me%ObjGeometry,               &
                               Z = Me%External_Var%KFloor_Z, &
                               U = Me%External_Var%KFloor_U, &
                               V = Me%External_Var%KFloor_V, &
                               STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                          &
            stop 'Subroutine ReadLock_ModuleGeometry; module ModuleHydrodynamic. ERR**.'



        call GetGeometryVolumes(Me%ObjGeometry,                            &
                                VolumeZ = Me%External_Var%Volume_Z_New,    &
                                VolumeU = Me%External_Var%Volume_U,        &
                                VolumeV = Me%External_Var%Volume_V,        &
                                VolumeW = Me%External_Var%Volume_W,        &
                                VolumeZOld = Me%External_Var%Volume_Z_Old, &
                                STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                          &
            stop 'Subroutine ReadLock_ModuleGeometry; module ModuleHydrodynamic. ERR**.'



        call GetGeometryAreas(Me%ObjGeometry,                 &
                              AreaU = Me%External_Var%Area_U, &
                              AreaV = Me%External_Var%Area_V, &
                              STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                          &
            stop 'Subroutine ReadLock_ModuleGeometry; module ModuleHydrodynamic. ERR**.'



        call GetGeometryDistances(Me%ObjGeometry,             &
                                  DWZ = Me%External_Var%DWZ,  &
                                  SZZ = Me%External_Var%SZZ,  &
                                  DUZ = Me%External_Var%DUZ,  &
                                  DVZ = Me%External_Var%DVZ,  &
                                  DZZ = Me%External_Var%DZZ,  &
                                  STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                          &
            stop 'Subroutine ReadLock_ModuleGeometry; module ModuleHydrodynamic. ERR**.'



        call GetGeometryWaterColumn(Me%ObjGeometry,                             &
                                    WaterColumn = Me%External_Var%WaterColumn,  &
                                    WaterColumnU= Me%External_Var%WaterColumnU, &
                                    WaterColumnV= Me%External_Var%WaterColumnV, &
                                    STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                          &
            stop 'Subroutine ReadLock_ModuleGeometry; module ModuleHydrodynamic. ERR**.'



    End Subroutine ReadLock_ModuleGeometry

    !End----------------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input :                                                                              !
    ! OutPut:                                                                              !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Subroutine ReadUnLock_ModuleGeometry 


        !Arguments-------------------------------------------------------------
        


        !Local-----------------------------------------------------------------
        integer        :: STAT_CALL 

        !Module - ModuleGeometry
        !3D Geometry properties


        !First non land layer of the Z cell (water level compute point)
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%KFloor_Z, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR01.'


        !First non land layer of the U cell (velocity U compute point)
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%KFloor_U, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR02.'


        !First non land layer of the V cell (velocity V compute point)
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%KFloor_V, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR03.'



        !New volume of the Z cell (water level compute point)
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%Volume_Z_New, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR04.'



        !Old volume of the Z cell (water level compute point)
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%Volume_Z_Old, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR05.'


        !New volume of the U cell (Velocity U compute point)
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%Volume_U, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR06.'


        !New volume of the V cell (Velocity V compute point)
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%Volume_V, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR07.'

        !New volume of the V cell (Velocity W compute point)
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%Volume_W, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR07a.'

        !New Area of the U cell (Velocity U compute point)
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%Area_U, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR08.'


        !New Area of the V cell (Velocity V compute point)
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%Area_V, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR09.'


        !Tickness of the Z cell 
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%DWZ, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR10.'

        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%DZZ, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR10a.'


        !Top face position
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%SZZ, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR11.'


        !Tickness of the total water column in the Z cell center
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%WaterColumn, STAT = STAT_CALL)
       if (STAT_CALL /= SUCCESS_)                                             &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR12.'

        !Tickness of the total water column in the U cell center
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%WaterColumnU, STAT = STAT_CALL)
       if (STAT_CALL /= SUCCESS_)                                             &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR13.'


        !Tickness of the total water column in the V cell center
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%WaterColumnV, STAT = STAT_CALL)
       if (STAT_CALL /= SUCCESS_)                                             &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR14.'

        !Tickness of the U cell center
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%DUZ, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR15.'


        !Tickness of the V cell center
        call UnGetGeometry(Me%ObjGeometry,                       &
                           Me%External_Var%DVZ, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleGeometry; module ModuleHydrodynamic. ERR16.'


    End Subroutine ReadUnLock_ModuleGeometry 

    !End----------------------------------------------------------------------


    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input : Geometry, Mapping                                                            !
    ! OutPut: Flow                                                                         !
    ! Author: Paulo Chambel (99/6)                                                         !
    !                                                                                      !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Subroutine ReadLock_ModuleMap 


        !Arguments-------------------------------------------------------------------
        


        !Local----------------------------------------------------------------------
        integer                          :: STAT_CALL 



        !Module - ModuleMap
        !3D Mapping Properties

        call GetComputeFaces3D(Me%ObjMap,                        &
                               ComputeFacesU3D =                              &
                               Me%External_Var%ComputeFaces3D_U, &
                               ComputeFacesV3D =                              &
                               Me%External_Var%ComputeFaces3D_V, &
                               ComputeFacesW3D =                              &
                               Me%External_Var%ComputeFaces3D_W, &
                               STAT= STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadLock_ModuleMap; module ModuleHydrodynamic. ERR**.'


!        call GetUnCoveredFaces3D(Me%ObjMap,                        &
!                               UnCoveredFacesU3D =                              &
!                               Me%External_Var%UnCoveredFaces3D_U, &
!                               UnCoveredFacesV3D =                              &
!                               Me%External_Var%UnCoveredFaces3D_V, &
!                               STAT= STAT_CALL)

!        if (STAT_CALL /= SUCCESS_)                                          &
!            stop 'Subroutine ReadLock_ModuleMap; module ModuleHydrodynamic. ERR**.'


        call GetLandBoundaryFaces3D(Me%ObjMap,                     &
                               LandBoundaryFaces3DU =                           &
                               Me%External_Var%LandBoundaryFacesU, &
                               LandBoundaryFaces3DV =                           &
                               Me%External_Var%LandBoundaryFacesV, &
                               STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                          &
            stop 'Subroutine ReadLock_ModuleMap; module ModuleHydrodynamic. ERR**.'


        call GetWaterPoints3D(Me%ObjMap,                     &
                              Me%External_Var%WaterPoints3D, &
                              STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_) &
            Stop 'Sub. ReadLock_ModuleMap - ModuleHydrodynamic - ERR**.'

        call GetOpenPoints3D(Me%ObjMap,                      &
                             Me%External_Var%OpenPoints3D,   &
                             STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_) &
            Stop 'Sub. ReadLock_ModuleMap - ModuleHydrodynamic - ERR**.'


        call GetImposedTangentialFaces(Me%ObjMap,                           &
                              Me%External_Var%ImposedTangentialFacesU,      &
                              Me%External_Var%ImposedTangentialFacesV,      &
                              STAT = STAT_CALL)      

        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine ReadLock_ModuleMap; module ModuleHydrodynamic. ERR**.'


        call GetImposedNormalFaces(Me%ObjMap,                               &
                              Me%External_Var%ImposedNormalFacesU,          &
                              Me%External_Var%ImposedNormalFacesV,          &
                              STAT = STAT_CALL)      

        if (STAT_CALL /= SUCCESS_)                                                       &
            stop 'Subroutine ReadLock_ModuleMap; module ModuleHydrodynamic. ERR**.'




    End Subroutine ReadLock_ModuleMap

    !End----------------------------------------------------------------------

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !                                                                                      !
    !                                                                                      !
    ! Input :                                                                              !
    ! OutPut:                                                                              !
    ! Author: Paulo Chambel (99/6)                                                         !

    Subroutine ReadUnLock_ModuleMap 


        !Arguments-------------------------------------------------------------
        


        !Local-----------------------------------------------------------------
        integer        :: STAT_CALL 

  

        !Module - ModuleMap
        !3D Mapping Properties

        !3D Boundary land faces along the X direction
        call UnGetMap(Me%ObjMap,                                 &
                      Me%External_Var%LandBoundaryFacesU, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR01.'


        !3D Boundary land faces along the Y direction
        call UnGetMap(Me%ObjMap,                                 &
                      Me%External_Var%LandBoundaryFacesV, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR02.'


        !3D water points
        call UnGetMap(Me%ObjMap,                                 &
                      Me%External_Var%WaterPoints3D, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR03.'


        !3D Compute faces along the X direction
        call UnGetMap(Me%ObjMap,                                 &
                      Me%External_Var%ComputeFaces3D_U, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR04.'


        !3D Compute faces along the Y direction
        call UnGetMap(Me%ObjMap,                                 &
                      Me%External_Var%ComputeFaces3D_V, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR05.'

        !3D Compute faces along the Z direction  !flavio
        call UnGetMap(Me%ObjMap,                                 &
                      Me%External_Var%ComputeFaces3D_W, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR05a.'
        
        !3D UnCovered faces along the X direction
!        call UnGetMap(Me%ObjMap,                                 &
!                      Me%External_Var%UnCoveredFaces3D_U, STAT = STAT_CALL)
!        if (STAT_CALL /= SUCCESS_)                                            &
!            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR06.'


        !3D UnCovered faces along the Y direction
!        call UnGetMap(Me%ObjMap,                                 &
!                      Me%External_Var%UnCoveredFaces3D_V, STAT = STAT_CALL)
!        if (STAT_CALL /= SUCCESS_)                                            &
!            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR07.'

        !3D OpenPoints
        call UnGetMap(Me%ObjMap,                                 &
                      Me%External_Var%OpenPoints3D, STAT = STAT_CALL)
        if (STAT_CALL /= SUCCESS_)                                            &
            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR07.'



        !Imposed Tangential faces along the X direction
        call UnGetMap(Me%ObjMap, Me%External_Var%ImposedTangentialFacesU,  &
                                STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                           &
            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR**.'


        !Imposed Tangential  faces along the Y direction
        call UnGetMap(Me%ObjMap, Me%External_Var%ImposedTangentialFacesV,  &
                                STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                           &
            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR**.'


        !Imposed Normal faces along the X direction
        call UnGetMap(Me%ObjMap, Me%External_Var%ImposedNormalFacesU,  &
                                STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                           &
            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR**.'


        !Imposed Normal  faces along the Y direction
        call UnGetMap(Me%ObjMap, Me%External_Var%ImposedNormalFacesV,  &
                                STAT = STAT_CALL)

        if (STAT_CALL /= SUCCESS_)                                           &
            stop 'Subroutine ReadUnLock_ModuleMap; module ModuleHydrodynamic. ERR**.'

 
        !----------------------------------------------------------------------

    End Subroutine ReadUnLock_ModuleMap

    !--------------------------------------------------------------------------


    !--------------------------------------------------------------------------

    Subroutine ReadLock_External_Modules

        !Arguments-------------------------------------------------------------

         

        !----------------------------------------------------------------------

            call ReadLock_ModuleHorizontalGrid 

            call ReadLock_ModuleHorizontalMap  

            call ReadLock_ModuleGeometry       

            call ReadLock_ModuleMap            

        !----------------------------------------------------------------------

    End Subroutine ReadLock_External_Modules

    !--------------------------------------------------------------------------

    !--------------------------------------------------------------------------

    Subroutine ReadUnLock_External_Modules

        !Arguments-------------------------------------------------------------

         

        !----------------------------------------------------------------------

            call ReadUnLock_ModuleHorizontalGrid 

            call ReadUnLock_ModuleHorizontalMap 

            call ReadUnLock_ModuleGeometry 

            call ReadUnLock_ModuleMap 

        !----------------------------------------------------------------------

    End Subroutine ReadUnLock_External_Modules

    !--------------------------------------------------------------------------
#ifdef _USE_MPI

    subroutine SendHydrodynamicMPI (HydrodynamicID, Destination, Window, InitialField, STAT)

        !Arguments-------------------------------------------------------------
        integer                                     :: HydrodynamicID
        integer                                     :: Destination
        type (T_Size2D)                             :: Window
        logical                                     :: InitialField
        integer, optional, intent (OUT)             :: STAT

        !Local-----------------------------------------------------------------
        integer                                     :: ready_ 
        integer                                     :: STAT_, STAT_CALL
        real                                        :: DT
        integer                                     :: ILB, IUB, JLB, JUB, KLB, KUB
        real, dimension(6)                          :: AuxTime
        real,    dimension(:,:,:), pointer          :: DUZFather, DVZFather
        integer, dimension(:,:,:), pointer          :: Open3DFather     
        integer, dimension(:,:,:), pointer          :: Faces3D_UFather    
        integer, dimension(:,:,:), pointer          :: Faces3D_VFather
        integer                                     :: iSize
        integer, save                               :: Precision

        !Begin-----------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_)

cd1 :   if (ready_ .EQ. IDLE_ERR_) then


            !Window to send
            ILB = Window%ILB
            IUB = Window%IUB
            JLB = Window%JLB
            JUB = Window%JUB
            KLB = Me%WorkSize%KLB
            KUB = Me%WorkSize%KUB

            if (InitialField) then

           
                !Gets Compute time step
                call GetComputeTimeStep(Me%ObjTime, DT, STAT = STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR01'

                !Sends Continous Compute
                call MPI_Send (Me%ComputeOptions%Continuous, 1, MPI_LOGICAL, Destination,    &
                               1000, MPI_COMM_WORLD, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR02'
            
                !Sends KLB
                call MPI_Send (Me%WorkSize%KLB, 1, MPI_INTEGER, Destination, 1001,            &
                               MPI_COMM_WORLD, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR03'

                !Sends KUB
                call MPI_Send (Me%WorkSize%KUB, 1, MPI_INTEGER, Destination, 1002,            &
                               MPI_COMM_WORLD, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR04'

                Precision = MPIKind(DT)

                !Sends DT
                call MPI_Send (DT, 1, Precision, Destination, 1003, MPI_COMM_WORLD, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR05'

                !Assuming that all other variables have the same kind
                Precision = MPIKind(Me%Velocity%Horizontal%U%New)

            endif

            !Sends last iteration
            call ExtractDate (Me%LastIteration, AuxTime(1), AuxTime(2), AuxTime(3),      &
                              AuxTime(4), AuxTime(5), AuxTime(6))
            
            
            call MPI_Send (AuxTime, 6, Precision, Destination, 1004, MPI_COMM_WORLD, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR06'

            !Gets OpenPoints
            call GetOpenPoints3D      (Me%ObjMap, Open3DFather, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR07'

            !Gets ComputeFaces
            call GetComputeFaces3D    (Me%ObjMap, ComputeFacesU3D = Faces3D_UFather,     &
                                       ComputeFacesV3D = Faces3D_VFather,                &
                                       STAT= STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR08'

            !Gets DUZ, DVZ
            call GetGeometryDistances (Me%ObjGeometry, DUZ =  DUZFather,                 &
                                       DVZ =  DVZFather, STAT = STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR09'


            !UFather
            iSize = (IUB-ILB+1) * (JUB+1-JLB+1) * (KUB-KLB+1)
            call MPI_Send (Me%Velocity%Horizontal%U%New(ILB:IUB, JLB:JUB+1, KLB:KUB),    &
                           iSize, Precision, Destination, 1005, MPI_COMM_WORLD, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR10'
                           

            !VFather
            iSize = (IUB+1-ILB+1) * (JUB-JLB+1) * (KUB-KLB+1)
            call MPI_Send (Me%Velocity%Horizontal%V%New(ILB:IUB+1, JLB:JUB, KLB:KUB),    &
                           iSize, Precision, Destination, 1006, MPI_COMM_WORLD, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR11'
                          
            
            !FluxXFather
            iSize = (IUB-ILB+1) * (JUB+1-JLB+1) * (KUB-KLB+1)
            call MPI_Send (Me%WaterFluxes%X(ILB:IUB, JLB:JUB+1, KLB:KUB),                &
                           iSize, MPI_DOUBLE_PRECISION, Destination, 1007, MPI_COMM_WORLD, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR12'


            !FluxYFather
            iSize = (IUB+1-ILB+1) * (JUB-JLB+1) * (KUB-KLB+1)
            call MPI_Send (Me%WaterFluxes%Y(ILB:IUB+1, JLB:JUB, KLB:KUB),                &
                           iSize, MPI_DOUBLE_PRECISION, Destination, 1008, MPI_COMM_WORLD, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR13'


            !ZFather
            iSize = (IUB-ILB+1) * (JUB-JLB+1)
            call MPI_Send (Me%WaterLevel%New(ILB:IUB, JLB:JUB),                          &
                           iSize, Precision, Destination, 1009, MPI_COMM_WORLD, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR14'



            !Open3DFather
            iSize = (IUB-ILB+1) * (JUB-JLB+1) * (KUB-KLB+1)
            call MPI_Send (Open3DFather(ILB:IUB, JLB:JUB, KLB:KUB),                      &
                           iSize, MPI_INTEGER, Destination, 1010, MPI_COMM_WORLD, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR15'


            !Faces3D_UFather
            iSize = (IUB-ILB+1) * (JUB+1-JLB+1) * (KUB-KLB+1)
            call MPI_Send (Faces3D_UFather(ILB:IUB, JLB:JUB+1, KLB:KUB),                 &
                           iSize, MPI_INTEGER, Destination, 1011, MPI_COMM_WORLD, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR16'


            !Faces3D_VFather
            iSize = (IUB+1-ILB+1) * (JUB-JLB+1) * (KUB-KLB+1)
            call MPI_Send (Faces3D_VFather(ILB:IUB+1, JLB:JUB, KLB:KUB),                 &
                           iSize, MPI_INTEGER, Destination, 1012, MPI_COMM_WORLD, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR17'


            !DUZFather
            iSize = (IUB-ILB+1) * (JUB+1-JLB+1) * (KUB-KLB+1)
            call MPI_Send (DUZFather(ILB:IUB, JLB:JUB+1, KLB:KUB),                         &
                           iSize, Precision , Destination, 1013, MPI_COMM_WORLD, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR18'

            !DVZFather
            iSize = (IUB+1-ILB+1) * (JUB-JLB+1) * (KUB-KLB+1)
            call MPI_Send (DVZFather(ILB:IUB+1, JLB:JUB, KLB:KUB),                         &
                           iSize, Precision, Destination, 1014, MPI_COMM_WORLD, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'SendHydrodynamicMPI - MohidWater - ERR19'



            !Ungets information
            call UnGetMap       (Me%ObjMap,      Open3DFather,    STAT = STAT_CALL)
            call UnGetMap       (Me%ObjMap,      Faces3D_UFather, STAT = STAT_CALL)
            call UnGetMap       (Me%ObjMap,      Faces3D_VFather, STAT = STAT_CALL)

            !Ungets information
            call UnGetGeometry  (Me%ObjGeometry, DUZFather,  STAT = STAT_CALL)
            call UnGetGeometry  (Me%ObjGeometry, DVZFather,  STAT = STAT_CALL)


            STAT_ = SUCCESS_

        else              
         
            STAT_ = ready_

        end if cd1


        if (present(STAT)) STAT = STAT_

    end subroutine SendHydrodynamicMPI

    !--------------------------------------------------------------------------

    subroutine RecvHydrodynamicMPI (HydrodynamicID, Source, Window, InitialField,        &
                                    FatherGridID, STAT)

        !Arguments-------------------------------------------------------------
        integer                                     :: HydrodynamicID
        integer                                     :: Source
        type (T_Size2D)                             :: Window
        logical                                     :: InitialField
        integer                                     :: FatherGridID
        integer, optional, intent (OUT)             :: STAT

        !Local-----------------------------------------------------------------
        integer                                     :: ready_ 
        integer                                     :: STAT_, STAT_CALL
        logical                                     :: FatherContinous
        real                                        :: DT
        integer, save                               :: KLB, KUB
        integer                                     :: ILB, IUB, JLB, JUB
        type (T_Size2D), save                       :: WorkSize, Size
        integer                                     :: status(MPI_STATUS_SIZE)
        real, dimension(6)                          :: AuxTime
        type (T_Time)                               :: LastIteration
        real,    dimension(:,:,:), pointer, save    :: UFather, VFather, DUZFather, DVZFather
        real(8), dimension(:,:,:), pointer, save    :: FluxXFather, FluxYFather
        real,    dimension(:,:  ), pointer, save    :: ZFather
        integer, dimension(:,:,:), pointer, save    :: Open3DFather     
        integer, dimension(:,:,:), pointer, save    :: Faces3D_UFather    
        integer, dimension(:,:,:), pointer, save    :: Faces3D_VFather
        integer                                     :: iSize
        integer, save                               :: Precision

        !Begin-----------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_)

cd1 :   if (ready_ .EQ. IDLE_ERR_) then


            call GetHorizontalGridSize (FatherGridID, Size = Size,          &
                                        WorkSize = WorkSize, STAT = STAT_CALL)


            !Window Size
            ILB = Window%ILB
            IUB = Window%IUB
            JLB = Window%JLB
            JUB = Window%JUB

            if (InitialField) then

                !Recieves Continous Compute
                call MPI_Recv (FatherContinous, 1, MPI_LOGICAL, Source, 1000, MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR01'

                !Recieves KLB
                call MPI_Recv (KLB, 1, MPI_INTEGER, Source, 1001,  MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR02'

                !Recieves KUB
                call MPI_Recv (KUB, 1, MPI_INTEGER, Source, 1002,  MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - DW23
                MohidWater - ERR03'


                Precision = MPIKind(DT)

                !Recieves DT
                call MPI_Recv (DT, 1, Precision, Source, 1003,  MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR04'

                call TestSubModelOptionsConsistence (FatherContinous)
                call ConstructTimeInterpolation     (KLB, KUB, DT)

                !Allocates receiving buffer
                allocate (UFather        (Size%ILB:Size%IUB, Size%JLB:Size%JUB, KLB-1:KUB+1))
                allocate (VFather        (Size%ILB:Size%IUB, Size%JLB:Size%JUB, KLB-1:KUB+1))
                allocate (DUZFather      (Size%ILB:Size%IUB, Size%JLB:Size%JUB, KLB-1:KUB+1))
                allocate (DVZFather      (Size%ILB:Size%IUB, Size%JLB:Size%JUB, KLB-1:KUB+1))
                allocate (FluxXFather    (Size%ILB:Size%IUB, Size%JLB:Size%JUB, KLB-1:KUB+1))
                allocate (FluxYFather    (Size%ILB:Size%IUB, Size%JLB:Size%JUB, KLB-1:KUB+1))
                allocate (ZFather        (Size%ILB:Size%IUB, Size%JLB:Size%JUB             ))
                allocate (Open3DFather   (Size%ILB:Size%IUB, Size%JLB:Size%JUB, KLB-1:KUB+1))
                allocate (Faces3D_UFather(Size%ILB:Size%IUB, Size%JLB:Size%JUB, KLB-1:KUB+1))
                allocate (Faces3D_VFather(Size%ILB:Size%IUB, Size%JLB:Size%JUB, KLB-1:KUB+1))


                UFather             = 0.0
                VFather             = 0.0
                DUZFather           = null_real
                DVZFather           = null_real
                FluxXFather         = 0.0
                FluxYFather         = 0.0
                ZFather             = null_real
                Open3DFather        = 0
                Faces3D_UFather     = 0
                Faces3D_VFather     = 0

            endif

            Me%SubModel%DUZ_Old(:,:,:) = Me%SubModel%DUZ_New(:,:,:)
            Me%SubModel%DVZ_Old(:,:,:) = Me%SubModel%DVZ_New(:,:,:)

            !Receives LastIteration
            call MPI_Recv (AuxTime, 6, Precision, Source, 1004, MPI_COMM_WORLD, status, STAT_CALL)
            if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR05'

            call SetDate  (LastIteration, AuxTime(1), AuxTime(2), AuxTime(3), AuxTime(4), AuxTime(5), AuxTime(6))

            if (LastIteration > Me%SubModel%NextTime .or. InitialField) then

                !UFather
                iSize = (IUB-ILB+1) * (JUB+1-JLB+1) * (KUB-KLB+1)
                call MPI_Recv (UFather(ILB:IUB, JLB:JUB+1, KLB:KUB), iSize, Precision,    &
                               Source, 1005, MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR06'

                !VFather
                iSize = (IUB+1-ILB+1) * (JUB-JLB+1) * (KUB-KLB+1)
                call MPI_Recv (VFather(ILB:IUB+1, JLB:JUB, KLB:KUB), iSize, Precision,    &
                               Source, 1006, MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR07'
            

                !FluxXFather
                iSize = (IUB-ILB+1) * (JUB+1-JLB+1) * (KUB-KLB+1)
                call MPI_Recv (FluxXFather(ILB:IUB, JLB:JUB+1, KLB:KUB), iSize, MPI_DOUBLE_PRECISION,&
                               Source, 1007, MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR08'


                !FluxYFather
                iSize = (IUB+1-ILB+1) * (JUB-JLB+1) * (KUB-KLB+1)
                call MPI_Recv (FluxYFather(ILB:IUB+1, JLB:JUB, KLB:KUB), iSize, MPI_DOUBLE_PRECISION,&
                               Source, 1008, MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR09'


                !ZFather
                iSize = (IUB-ILB+1) * (JUB-JLB+1)
                call MPI_Recv (ZFather(ILB:IUB, JLB:JUB), iSize, Precision,               &
                               Source, 1009, MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR10'


                !Open3DFather
                iSize = (IUB-ILB+1) * (JUB-JLB+1) * (KUB-KLB+1)
                call MPI_Recv (Open3DFather(ILB:IUB, JLB:JUB, KLB:KUB), iSize, MPI_INTEGER, &
                               Source, 1010, MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR11'


                !Faces3D_UFather
                iSize = (IUB-ILB+1) * (JUB+1-JLB+1) * (KUB-KLB+1)
                call MPI_Recv (Faces3D_UFather(ILB:IUB, JLB:JUB+1, KLB:KUB), iSize, MPI_INTEGER,&
                               Source, 1011, MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR12'


                !Faces3D_VFather
                iSize = (IUB+1-ILB+1) * (JUB-JLB+1) * (KUB-KLB+1)
                call MPI_Recv (Faces3D_VFather(ILB:IUB+1, JLB:JUB, KLB:KUB), iSize, MPI_INTEGER,&
                               Source, 1012, MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR13'


                !DUZFather
                iSize = (IUB-ILB+1) * (JUB+1-JLB+1) * (KUB-KLB+1)
                call MPI_Recv (DUZFather(ILB:IUB, JLB:JUB+1, KLB:KUB), iSize, Precision,    &
                               Source, 1013, MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR14'

                !DVZFather
                iSize = (IUB+1-ILB+1) * (JUB-JLB+1) * (KUB-KLB+1)
                call MPI_Recv (DVZFather(ILB:IUB+1, JLB:JUB, KLB:KUB), iSize, Precision,    &
                               Source, 1014, MPI_COMM_WORLD, status, STAT_CALL)
                if (STAT_CALL /= SUCCESS_) stop 'RecvInitialHydrodynamicMPI - MohidWater - ERR15'


                call ReadNextOrInitialField (UFather, VFather, DUZFather, DVZFather,     &
                                       FluxXFather, FluxYFather, ZFather, Open3DFather,  &
                                       Faces3D_UFather, Faces3D_VFather, InitialField,   &
                                       KLB, KUB, FatherGridID)

                if (.not. InitialField) then
                    Me%SubModel%PreviousTime = Me%SubModel%NextTime
                    Me%SubModel%NextTime     = LastIteration 
                endif

            endif

            if      (Me%SubModel%VertComunic == FatherSonEqualDim) then
                
                call ActualizeSubModelValues    (InitialField)

            else if (Me%SubModel%VertComunic == Father2DSon3D) then

                call ActualizeSon3DWithFather2D (InitialField)

            endif

!            if (Me%SubModel%DeadZone .and. InitialField  .and. .not. Me%ComputeOptions%Continuous)  then
            if (InitialField  .and. .not. Me%ComputeOptions%Continuous)  then
                call Initial_Geometry(Me%WaterLevel%New)
            endif

            STAT_ = SUCCESS_

        else              
         
            STAT_ = ready_

        end if cd1


        if (present(STAT)) STAT = STAT_

    end subroutine RecvHydrodynamicMPI

    !--------------------------------------------------------------------------

    subroutine UpdateHydroMPI (HydrodynamicID, InitialField, STAT)

        !Arguments-------------------------------------------------------------
        integer                                     :: HydrodynamicID
        logical                                     :: InitialField
        integer, optional, intent (OUT)             :: STAT

        !Local-----------------------------------------------------------------
        integer                                     :: ready_ 
        integer                                     :: STAT_

        !Begin-----------------------------------------------------------------

        STAT_ = UNKNOWN_

        call Ready(HydrodynamicID, ready_)

cd1 :   if (ready_ .EQ. IDLE_ERR_) then

            Me%SubModel%DUZ_Old(:,:,:) = Me%SubModel%DUZ_New(:,:,:)
            Me%SubModel%DVZ_Old(:,:,:) = Me%SubModel%DVZ_New(:,:,:)

            if      (Me%SubModel%VertComunic == FatherSonEqualDim) then
                
                call ActualizeSubModelValues    (InitialField)

            else if (Me%SubModel%VertComunic == Father2DSon3D) then

                call ActualizeSon3DWithFather2D (InitialField)

            endif

            STAT_ = SUCCESS_

        else              
         
            STAT_ = ready_

        end if cd1


        if (present(STAT)) STAT = STAT_


    end subroutine UpdateHydroMPI


#endif

End Module ModuleHydrodynamic    

