Merge remote-tracking branch 'origin/release-v4.5'
[WRF.git] / hydro / Routing / Reservoirs / module_reservoir.F
blobd48d3347c13cc5bd54c2423d239fafb17293e0d2
1 ! This module is the base module for reservoirs that defines
2 ! abstract types for a reservoir base, reservoir state, and
3 ! reservoir properties. It also defines types for the inputs
4 ! and outputs common to all sub-types of reservoirs. Finally,
5 ! it defines a pointer to a reservoir object and an interface
6 ! for running a reservoir.
7 module module_reservoir
9     ! Defines the reservoir base state type that sub-types of
10     ! reservoirs will derive from. Since this is abstract, an instance
11     ! of reservoir state cannot be created but only derived to sub-types
12     ! of reservoirs. State holds and tracks dynamic/changing variables
13     ! that are only relevant to the given reservoir object and not other
14     ! modules or areas of the system.
15     type, abstract :: reservoir_state
17     end type
19     ! Defines the reservoir base properties/parameters type that
20     ! sub-types of reservoirs will derive from. Since this is abstract,
21     ! an instance of reservoir properties cannot be created but only
22     ! derived to sub-types of reservoirs. Properties holds
23     ! static/unchanging variables that are set when the given reservoir
24     ! object is initialized/instantiated.
25     type, abstract :: reservoir_properties
27     end type
29     ! Defines the input base type which holds the same inputs that all
30     ! sub-types of reservoirs will derive from. Therefore, all types of
31     ! reservoirs will hold the inputs defined below. These are
32     ! dynamic/changing variables that will receive values passed into the
33     ! object's methods/subroutines at runtime.
34     type :: reservoir_input
36         real :: inflow                      ! cubic meters per second (cms)
37         real :: lateral_inflow              ! cubic meters per second (cms)
38         real :: previous_timestep_inflow    ! cubic meters per second (cms)
40     contains
42         procedure :: init => reservoir_input_init
43         procedure :: destroy => reservoir_input_destroy
45     end type
47     ! Defines the output base type which holds the same output(s) that all
48     ! sub-types of reservoirs will derive from. Therefore, all types of
49     ! reservoirs will hold the output(s) defined below. These are
50     ! dynamic/changing variables that will receive values returned from the
51     ! object's methods/subroutines at runtime.
52     type :: reservoir_output
54         real :: outflow                     ! cubic meters per second (cms)
56     contains
58         procedure :: init => reservoir_output_init
59         procedure :: destroy => reservoir_output_destroy
61     end type
63     ! Defines the reservoir base type that sub-types of reservoirs
64     ! will derive from. Since this is abstract, an instance of reservoir
65     ! cannot be created but only derived to sub-types of reservoirs.
66     ! Derived sub-types of reservoirs of this base type will create a
67     ! reservoir object that will hold state, properties/parameters,
68     ! inputs, and outputs as sub-objects.
69     type, abstract :: reservoir
71         type(reservoir_input), pointer :: input
72         type(reservoir_output), pointer :: output
74     contains
76         ! Defines procedure to call run reservoir for a type of reservoir,
77         ! which will then call methods/subroutines for processing the
78         ! inputs and returning the outputs. Since this is deferred,
79         ! it cannot be implemented for a base reservoir but only for
80         ! a sub-type of reservoir.
81         procedure (run_reservoir_interface), deferred :: run
83     end type
85     ! Defines a pointer to a reservoir base type
86     type :: reservoir_container
87         class (reservoir), pointer :: ptr
88     end type
90     ! Defines the abstract implementation of run_reservoir that all
91     ! reservoir sub-types will derive from with the same given
92     ! inputs and outputs.
93     abstract interface
94         subroutine run_reservoir_interface(this, previous_timestep_inflow, inflow, &
95             lateral_inflow, water_elevation, outflow, routing_period, dynamic_reservoir_type, &
96             assimilated_value, assimilated_source_file)
97             import reservoir
98             class(reservoir), intent(inout) :: this
99             real, intent(in)    :: previous_timestep_inflow ! cubic meters per second (cms)
100             real, intent(in)    :: inflow                   ! cubic meters per second (cms)
101             real, intent(in)    :: lateral_inflow           ! cubic meters per second (cms)
102             real, intent(inout) :: water_elevation          ! meters AMSL
103             real, intent(out)   :: outflow                  ! cubic meters per second (cms)
104             real, intent(in)    :: routing_period           ! seconds
105             integer, intent(out):: dynamic_reservoir_type   ! dynamic reservoir type sent to lake out files
106             real, intent(out)   :: assimilated_value        ! value assimilated from observation or forecast
107             character(len=256), intent(out) :: assimilated_source_file ! source file of assimilated value
109         end subroutine run_reservoir_interface
111     end interface
113 contains
115     ! Constructor the reservoir input type
116     subroutine reservoir_input_init(this)
117         implicit none
118         class (reservoir_input), intent(inout) :: this ! object being initialized
119         this%inflow = 0.0
120         this%lateral_inflow = 0.0
121         this%previous_timestep_inflow = 0.0
123     end subroutine reservoir_input_init
126     ! Destructor for the reservoir input type
127     subroutine reservoir_input_destroy(this)
128         implicit none
129         class (reservoir_input), intent(inout) :: this ! object being destroyed
131     end subroutine reservoir_input_destroy
134     ! Constructor for the reservoir output type
135     subroutine reservoir_output_init(this)
136         implicit none
137         class (reservoir_output), intent(inout) :: this ! object being initialized
138         this%outflow = 0.0
140     end subroutine reservoir_output_init
143     ! Destructor for the reservoir output type
144     subroutine reservoir_output_destroy(this)
145         implicit none
146         class (reservoir_output), intent(inout) :: this ! object being destroyed
148     end subroutine reservoir_output_destroy
150 end module module_reservoir