MODFLOW 6  version 6.7.0.dev3
USGS Modular Hydrologic Model
CachedGradient.f90
Go to the documentation of this file.
2  use kindmodule, only: dp, i4b
3  use constantsmodule, only: done
4 
5  Use igradient
6  use basedismodule, only: disbasetype
7 
8  implicit none
9  private
10 
11  public :: cachedgradienttype
12 
13  !> @brief Decorator that adds caching to any gradient computation implementation
14  !!
15  !! This class wraps any IGradientType implementation and provides caching functionality
16  !! using the Decorator pattern. When set_field is called, it pre-computes gradients
17  !! for all nodes and stores them in memory for fast O(1) retrieval. This trades memory
18  !! for speed when gradients are accessed multiple times for the same scalar field.
19  !!
20  !! The class takes ownership of the wrapped gradient object via move semantics and
21  !! provides the same interface as any other gradient implementation. This allows it
22  !! to be used transparently in place of the original gradient object.
23  !!
24  !! Usage pattern:
25  !! 1. Create a base gradient implementation (e.g., LeastSquaresGradientType)
26  !! 2. Wrap it with CachedGradientType using the constructor
27  !! 3. Call set_field() once to pre-compute all gradients
28  !! 4. Call get() multiple times for fast cached lookups
29  !!
30  !! @note The wrapped gradient object is moved (not copied) during construction
31  !! for efficient memory management.
32  !<
34  private
35  class(disbasetype), pointer :: dis
36  class(igradienttype), allocatable :: gradient
37  real(dp), dimension(:, :), allocatable :: cached_gradients ! gradients at nodes
38  contains
39  procedure :: get
40  procedure :: set_field
41  final :: destructor
42  end type cachedgradienttype
43 
44  interface cachedgradienttype
45  module procedure constructor
46  end interface cachedgradienttype
47 
48 contains
49 
50  function constructor(gradient, dis) result(cached_gradient)
51  ! --dummy
52  class(igradienttype), allocatable, intent(inout) :: gradient
53  class(disbasetype), pointer, intent(in) :: dis
54  !-- return
55  type(cachedgradienttype) :: cached_gradient
56 
57  cached_gradient%dis => dis
58 
59  call move_alloc(gradient, cached_gradient%gradient) ! Take ownership
60  allocate (cached_gradient%cached_gradients(dis%nodes, 3))
61 
62  end function constructor
63 
64  subroutine destructor(this)
65  ! -- dummy
66  type(cachedgradienttype), intent(inout) :: this
67 
68  deallocate (this%cached_gradients)
69  end subroutine destructor
70 
71  function get(this, n) result(grad_c)
72  ! -- dummy
73  class(cachedgradienttype), target :: this
74  integer(I4B), intent(in) :: n
75  !-- return
76  real(dp), dimension(3) :: grad_c
77 
78  grad_c = this%cached_gradients(n, :)
79  end function get
80 
81  subroutine set_field(this, phi)
82  ! -- dummy
83  class(cachedgradienttype), target :: this
84  real(DP), dimension(:), pointer, intent(in) :: phi
85  ! -- local
86  integer(I4B) :: n
87 
88  call this%gradient%set_field(phi)
89  do n = 1, this%dis%nodes
90  this%cached_gradients(n, :) = this%gradient%get(n)
91  end do
92 
93  end subroutine set_field
94 
95 end module cachedgradientmodule
subroutine set_field(this, phi)
type(cachedgradienttype) function constructor(gradient, dis)
subroutine destructor(this)
real(dp) function, dimension(3) get(this, n)
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
This module defines variable data types.
Definition: kind.f90:8
Decorator that adds caching to any gradient computation implementation.
Abstract interface for cell-based gradient computation.
Definition: IGradient.f90:15