MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
PetscVector.F90
Go to the documentation of this file.
2 #include <petsc/finclude/petscksp.h>
3  use petscksp
5  use kindmodule, only: i4b, dp
6  use constantsmodule, only: dzero
9  implicit none
10  private
11 
12  type, public, extends(vectorbasetype) :: petscvectortype
13  real(dp), dimension(:), pointer, contiguous :: array => null()
14  vec :: vec_impl
15  contains
16  ! override
17  procedure :: create_mm => petsc_vec_create_mm
18  procedure :: create => petsc_vec_create
19  procedure :: destroy => petsc_vec_destroy
20  procedure :: get_array => petsc_vec_get_array
21  procedure :: get_ownership_range => petsc_vec_get_ownership_range
22  procedure :: get_size => petsc_vec_get_size
23  procedure :: get_value_local => petsc_vec_get_value_local
24  procedure :: zero_entries => petsc_vec_zero_entries
25  procedure :: set_value_local => petsc_vec_set_value_local
26  procedure :: axpy => petsc_vec_axpy
27  procedure :: norm2 => petsc_vec_norm2
28  procedure :: print => petsc_vec_print
29  end type petscvectortype
30 
31 contains
32 
33  !> @brief Create a PETSc vector, with memory
34  !< in the memory manager
35  subroutine petsc_vec_create_mm(this, n, name, mem_path)
36  class(petscvectortype) :: this !< this vector
37  integer(I4B) :: n !< the nr. of elements in the vector
38  character(len=*) :: name !< the variable name (for access through memory manager)
39  character(len=*) :: mem_path !< memory path for storing the underlying memory items
40  ! local
41  petscerrorcode :: ierr
42 
43  this%is_mem_managed = .true.
44 
45  call mem_allocate(this%array, n, name, mem_path)
46  if (simulation_mode == 'PARALLEL' .and. nr_procs > 1) then
47  call veccreatempiwitharray(petsc_comm_world, 1, n, petsc_decide, &
48  this%array, this%vec_impl, ierr)
49  else
50  call veccreateseqwitharray(petsc_comm_world, 1, n, this%array, &
51  this%vec_impl, ierr)
52  end if
53  chkerrq(ierr)
54 
55  call this%zero_entries()
56 
57  end subroutine petsc_vec_create_mm
58 
59  !> @brief Create a PETSc vector, with memory
60  !< in the memory manager
61  subroutine petsc_vec_create(this, n)
62  class(petscvectortype) :: this !< this vector
63  integer(I4B) :: n !< the nr. of elements in the vector
64  ! local
65  petscerrorcode :: ierr
66 
67  this%is_mem_managed = .false.
68 
69  allocate (this%array(n))
70  if (simulation_mode == 'PARALLEL' .and. nr_procs > 1) then
71  call veccreatempiwitharray(petsc_comm_world, 1, n, petsc_decide, &
72  this%array, this%vec_impl, ierr)
73  else
74  call veccreateseqwitharray(petsc_comm_world, 1, n, this%array, &
75  this%vec_impl, ierr)
76  end if
77  chkerrq(ierr)
78 
79  call this%zero_entries()
80 
81  end subroutine petsc_vec_create
82 
83  !> @brief Clean up
84  !<
85  subroutine petsc_vec_destroy(this)
86  class(petscvectortype) :: this !< this vector
87  ! local
88  petscerrorcode :: ierr
89 
90  call vecdestroy(this%vec_impl, ierr)
91  chkerrq(ierr)
92  if (this%is_mem_managed) then
93  call mem_deallocate(this%array)
94  else
95  deallocate (this%array)
96  end if
97 
98  end subroutine petsc_vec_destroy
99 
100  !> @brief Get a pointer to the underlying data array
101  !< for this vector
102  function petsc_vec_get_array(this) result(array)
103  class(petscvectortype) :: this !< this vector
104  real(dp), dimension(:), pointer, contiguous :: array !< the underlying data array for this vector
105 
106  array => this%array
107 
108  end function petsc_vec_get_array
109 
110  subroutine petsc_vec_get_ownership_range(this, start, end)
111  class(petscvectortype) :: this !< this vector
112  integer(I4B) :: start !< the index of the first element (owned by this process) in the global vector
113  integer(I4B) :: end !< the index of the last element (owned by this process) in the global vector
114  ! local
115  petscerrorcode :: ierr
116 
117  ! gets the range as [start, end) but 0-based
118  call vecgetownershiprange(this%vec_impl, start, end, ierr)
119 
120  ! now we make it [start, end] and 1-based
121  start = start + 1
122 
123  chkerrq(ierr)
124 
125  end subroutine petsc_vec_get_ownership_range
126 
127  function petsc_vec_get_size(this) result(size)
128  class(petscvectortype) :: this !< this vector
129  integer(I4B) :: size !< the (global) vector size
130  ! local
131  petscerrorcode :: ierr
132 
133  call vecgetsize(this%vec_impl, size, ierr)
134  chkerrq(ierr)
135 
136  end function petsc_vec_get_size
137 
138  !> @brief Gets a value from the vector at the local index
139  !<
140  function petsc_vec_get_value_local(this, idx) result(val)
141  class(petscvectortype) :: this !< this vector
142  integer(I4B) :: idx !< the index in local numbering
143  real(dp) :: val !< the value
144 
145  val = this%array(idx)
146 
147  end function petsc_vec_get_value_local
148 
149  !> @brief set all elements to zero
150  !<
151  subroutine petsc_vec_zero_entries(this)
152  class(petscvectortype) :: this !< this vector
153  ! local
154  petscerrorcode :: ierr
155 
156  call veczeroentries(this%vec_impl, ierr)
157  chkerrq(ierr)
158  call vecassemblybegin(this%vec_impl, ierr)
159  chkerrq(ierr)
160  call vecassemblyend(this%vec_impl, ierr)
161  chkerrq(ierr)
162 
163  end subroutine petsc_vec_zero_entries
164 
165  !> @brief Set vector value at local index
166  !<
167  subroutine petsc_vec_set_value_local(this, idx, val)
168  class(petscvectortype) :: this !< this vector
169  integer(I4B) :: idx !< the index in local numbering
170  real(DP) :: val !< the value to set
171 
172  this%array(idx) = val
173 
174  end subroutine petsc_vec_set_value_local
175 
176  !> @brief Calculate AXPY: y = a*x + y
177  !<
178  subroutine petsc_vec_axpy(this, alpha, vec_x)
179  class(petscvectortype) :: this !< this vector
180  real(DP) :: alpha !< the factor
181  class(vectorbasetype), pointer :: vec_x !< the vector to add
182  ! local
183  petscerrorcode :: ierr
184  class(petscvectortype), pointer :: x
185 
186  x => null()
187  select type (vec_x)
188  class is (petscvectortype)
189  x => vec_x
190  end select
191  call vecaxpy(this%vec_impl, alpha, x%vec_impl, ierr)
192  chkerrq(ierr)
193 
194  end subroutine petsc_vec_axpy
195 
196  !> @brief Calculate this vector's (global) 2-norm
197  !<
198  function petsc_vec_norm2(this) result(n2)
199  class(petscvectortype) :: this !< this vector
200  real(dp) :: n2 !< the calculated 2-norm
201  ! local
202  petscerrorcode :: ierr
203 
204  call vecnorm(this%vec_impl, norm_2, n2, ierr)
205  chkerrq(ierr)
206 
207  end function petsc_vec_norm2
208 
209  subroutine petsc_vec_print(this)
210  class(petscvectortype) :: this !< this vector
211  ! local
212  petscerrorcode :: ierr
213 
214  call vecview(this%vec_impl, petsc_viewer_stdout_world, ierr)
215  chkerrq(ierr)
216 
217  end subroutine petsc_vec_print
218 
219 end module petscvectormodule
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:64
This module defines variable data types.
Definition: kind.f90:8
subroutine petsc_vec_print(this)
real(dp) function petsc_vec_norm2(this)
Calculate this vector's (global) 2-norm.
real(dp) function petsc_vec_get_value_local(this, idx)
Gets a value from the vector at the local index.
subroutine petsc_vec_get_ownership_range(this, start, end)
subroutine petsc_vec_destroy(this)
Clean up.
Definition: PetscVector.F90:86
subroutine petsc_vec_create(this, n)
Create a PETSc vector, with memory.
Definition: PetscVector.F90:62
subroutine petsc_vec_create_mm(this, n, name, mem_path)
Create a PETSc vector, with memory.
Definition: PetscVector.F90:36
subroutine petsc_vec_axpy(this, alpha, vec_x)
Calculate AXPY: y = a*x + y.
integer(i4b) function petsc_vec_get_size(this)
real(dp) function, dimension(:), pointer, contiguous petsc_vec_get_array(this)
Get a pointer to the underlying data array.
subroutine petsc_vec_zero_entries(this)
set all elements to zero
subroutine petsc_vec_set_value_local(this, idx, val)
Set vector value at local index.
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=linelength) simulation_mode
integer(i4b) nr_procs