GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 85.9% 128 / 0 / 149
Functions: 64.7% 11 / 0 / 17
Branches: 52.5% 96 / 0 / 183

tensorprod/m_tensorprod_indices.f90
Line Branch Exec Source
1 !> @brief Module for handling tensor product indices and lists of indices
2 module m_tensorprod_indices
3 use m_common, only: wp
4 implicit none
5
6 private
7 public :: TensorProdIndices, TensorProdIndexList
8 public :: Box
9 public :: size, intersect, size_2d
10
11 !> @brief Type to hold tensor product indices
12 !>
13 !> This type holds the indices for a tensor product space, where the indices themselves are also a tensor product of 1D indices
14 type :: TensorProdIndices
15 !> Start index in x-direction
16 integer :: i0
17 !> End index in x-direction
18 integer :: i1
19 !> Start index in y-direction
20 integer :: j0
21 !> End index in y-direction
22 integer :: j1
23 !> Start index in z-direction
24 integer :: k0
25 !> End index in z-direction
26 integer :: k1
27 !> Total number in x-direction
28 integer :: total_nr_x
29 !> Total number in y-direction
30 integer :: total_nr_y
31 !> Total number in z-direction
32 integer :: total_nr_z
33 !> If true, then the indices represent a complement of the specified indices
34 !> (e.g. {0, ..., i0-1} U {i1+1, ..., total_nr_x-1} for x-direction)
35 logical :: complement
36 contains
37 procedure :: init => init_indices
38 procedure :: empty => empty_indices
39 end type
40
41 !> @brief Type to hold lists of tensor product indices
42 !>
43 !> This type holds a list of indices for a tensor product space, where the indices themselves are not necessarily a tensor product
44 !> of 1D indices
45 type TensorProdIndexList
46
47 !> Linear index
48 integer, allocatable :: lin(:)
49
50 !> Cartesian index i
51 integer, allocatable :: i(:)
52 !> Cartesian index j
53 integer, allocatable :: j(:)
54 !> Cartesian index k
55 integer, allocatable :: k(:)
56
57 !> The corresponding TensorProdIndices
58 type(TensorProdIndices) :: tp_inds
59 contains
60 procedure :: init => init_lists
61 procedure :: destroy => destroy_indices
62 procedure, private :: get_local_index_2d
63 procedure, private :: get_local_index_3d
64 generic :: get_local_index => get_local_index_2d, get_local_index_3d
65 procedure :: get_bounds => get_bounds_list
66 end type
67
68 !> @brief Type to represent a 3D box
69 type Box
70 !> Left most x-coordinate
71 real(wp) :: x0 = 0._wp
72 !> Right most x-coordinate
73 real(wp) :: x1 = -1._wp
74 !> Left most y-coordinate
75 real(wp) :: y0 = 0._wp
76 !> Right most y-coordinate
77 real(wp) :: y1 = -1._wp
78 !> Left most z-coordinate
79 real(wp) :: z0 = 0._wp
80 !> Right most z-coordinate
81 real(wp) :: z1 = -1._wp
82 contains
83 procedure :: is_inside
84 end type Box
85
86 !> @brief Get the size of the tensor product indices
87 interface size
88 module procedure size_tpinds, size_index_list
89 end interface
90
91 interface size_2d
92 module procedure size_tp_inds_2d, size_index_list_2d
93 end interface
94
95 contains
96 !> @brief Initialize the TensorProdIndices
97 !>
98 !> @param this[inout] The TensorProdIndices to initialize
99 !> @param i0[in] Start index in x-direction
100 !> @param i1[in] End index in x-direction
101 !> @param j0[in] Start index in y-direction
102 !> @param j1[in] End index in y-direction
103 !> @param k0[in] Start index in z-direction
104 !> @param k1[in] End index in z-direction
105 !> @param bsplines[in] The B-spline spaces for each direction
106 !> @param complement[in] _(optional)_ If true, the indices represent a complement of the specified indices (default is false)
107 !> @param intervals[in] _(optional)_ If true, the indices represent intervals instead of B-splines (default is false)
108 323570 pure subroutine init_indices(this, i0, i1, j0, j1, k0, k1, bsplines, complement, intervals)
109 use m_bspline_basis, only: BSplineSpace
110 implicit none
111
112 class(TensorProdIndices), intent(inout) :: this
113 integer, intent(in) :: i0, i1, j0, j1, k0, k1
114 type(BSplineSpace), intent(in) :: bsplines(3)
115 logical, intent(in), optional :: complement
116 logical, intent(in), optional :: intervals
117
118 logical :: intervals_
119
120 323570 this%complement = .false.
121
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 323570 times.
323570 if (present(complement)) this%complement = complement
122
2/2
✓ Branch 4 → 5 taken 323335 times.
✓ Branch 4 → 6 taken 235 times.
323570 if (i0 <= i1) then
123 323335 this%i0 = i0
124 323335 this%i1 = i1
125 else
126 235 this%i0 = 0
127 235 this%i1 = -1
128 end if
129
2/2
✓ Branch 7 → 8 taken 321589 times.
✓ Branch 7 → 9 taken 1981 times.
323570 if (j0 <= j1) then
130 321589 this%j0 = j0
131 321589 this%j1 = j1
132 else
133 1981 this%j0 = 0
134 1981 this%j1 = -1
135 end if
136
2/2
✓ Branch 10 → 11 taken 306743 times.
✓ Branch 10 → 12 taken 16827 times.
323570 if (k0 <= k1) then
137 306743 this%k0 = k0
138 306743 this%k1 = k1
139 else
140 16827 this%k0 = 0
141 16827 this%k1 = -1
142 end if
143
144 intervals_ = .false.
145
2/2
✓ Branch 13 → 14 taken 126620 times.
✓ Branch 13 → 16 taken 196950 times.
323570 if (present(intervals)) intervals_ = intervals
146
1/2
✓ Branch 14 → 15 taken 126620 times.
✗ Branch 14 → 16 not taken.
126620 if (intervals_) then
147 126620 this%total_nr_x = bsplines(1)%nr_intervals
148 126620 this%total_nr_y = bsplines(2)%nr_intervals
149 126620 this%total_nr_z = bsplines(3)%nr_intervals
150 else
151 196950 this%total_nr_x = bsplines(1)%nr_bsplines
152 196950 this%total_nr_y = bsplines(2)%nr_bsplines
153 196950 this%total_nr_z = bsplines(3)%nr_bsplines
154 end if
155
156 323570 end subroutine init_indices
157
158 !> @brief Initialize the TensorProdIndices to empty
159 !>
160 !> @param this[inout] The constructed TensorProdIndices
161 10681636 subroutine empty_indices(this)
162 class(TensorProdIndices), intent(inout) :: this
163
164 10681636 this%i0 = 0
165 10681636 this%i1 = -1
166 10681636 this%j0 = 0
167 10681636 this%j1 = -1
168 10681636 this%k0 = 0
169 10681636 this%k1 = -1
170 10681636 this%total_nr_x = 0
171 10681636 this%total_nr_y = 0
172 10681636 this%total_nr_z = 0
173 10681636 this%complement = .false.
174
175 10681636 end subroutine empty_indices
176
177 !> @brief Initialize the TensorProdIndexList from the given TensorProdIndices
178 !>
179 !> @param this[inout] The TensorProdIndexList to initialize
180 !> @param inds[in] The TensorProdIndices to use for initialization
181 !> @param my_inds[in] The TensorProdIndices of the current rank (used for determining the global linear index, as well as the
182 !> complement when applicable)
183 !> @param l0[in] The starting linear index for the current rank (used for determining the global linear index)
184 !>
185 !> @note If inds%complement is true, the indices will be initialized as the complement of the specified indices within my_inds
186 3023 subroutine init_lists(this, inds, my_inds, l0)
187 implicit none
188
189 class(TensorProdIndexList), intent(inout) :: this
190 type(TensorProdIndices), intent(in) :: inds, my_inds
191 integer, intent(in) :: l0
192
193 integer :: sze, i, j, k, row_global, row_local, my_sze_x, my_sze_y, my_sze_z
194
195 ! NOTE: complement is understood as the complement of the indices within the responsible B-spline indices of this rank
196 3023 my_sze_x = my_inds%i1 - my_inds%i0 + 1
197 3023 my_sze_y = my_inds%j1 - my_inds%j0 + 1
198 3023 my_sze_z = my_inds%k1 - my_inds%k0 + 1
199
200 3023 sze = (inds%i1 - inds%i0 + 1) * (inds%j1 - inds%j0 + 1) * (inds%k1 - inds%k0 + 1)
201
2/2
✓ Branch 2 → 3 taken 405 times.
✓ Branch 2 → 4 taken 2618 times.
3023 if (inds%complement) then
202 405 sze = my_sze_x * my_sze_y * my_sze_z - sze
203 end if
204
205
8/14
✓ Branch 4 → 5 taken 2214 times.
✓ Branch 4 → 12 taken 809 times.
✓ Branch 5 → 6 taken 2214 times.
✗ Branch 5 → 11 not taken.
✓ Branch 6 → 7 taken 2214 times.
✗ Branch 6 → 11 not taken.
✓ Branch 7 → 8 taken 2214 times.
✗ Branch 7 → 11 not taken.
✓ Branch 8 → 9 taken 2214 times.
✗ Branch 8 → 11 not taken.
✓ Branch 9 → 10 taken 2214 times.
✗ Branch 9 → 11 not taken.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 2214 times.
3023 if (sze > 0 .and. (inds%i0 < my_inds%i0 .or. &
206 inds%i1 > my_inds%i1 .or. &
207 inds%j0 < my_inds%j0 .or. &
208 inds%j1 > my_inds%j1 .or. &
209 inds%k0 < my_inds%k0 .or. &
210 inds%k1 > my_inds%k1)) then
211 error stop "TensorProdIndexList::init_lists provided indices must be a subset of responsible B-spline indices of this rank."
212 end if
213
214
1/2
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 3023 times.
3023 if (allocated(this%lin)) deallocate (this%lin)
215
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 3023 times.
3023 if (allocated(this%i)) deallocate (this%i)
216
1/2
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 3023 times.
3023 if (allocated(this%j)) deallocate (this%j)
217
1/2
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 3023 times.
3023 if (allocated(this%k)) deallocate (this%k)
218
219
9/14
✓ Branch 20 → 21 taken 809 times.
✓ Branch 20 → 22 taken 2214 times.
✓ Branch 22 → 21 taken 2214 times.
✗ Branch 22 → 23 not taken.
✓ Branch 23 → 24 taken 3023 times.
✗ Branch 23 → 25 not taken.
✓ Branch 25 → 26 taken 2214 times.
✓ Branch 25 → 27 taken 809 times.
✗ Branch 27 → 28 not taken.
✓ Branch 27 → 29 taken 3023 times.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 31 taken 3023 times.
✗ Branch 31 → 32 not taken.
✓ Branch 31 → 33 taken 3023 times.
9069 allocate (this%lin(0:sze - 1))
220
6/10
✓ Branch 33 → 34 taken 809 times.
✓ Branch 33 → 35 taken 2214 times.
✓ Branch 35 → 34 taken 2214 times.
✗ Branch 35 → 36 not taken.
✗ Branch 36 → 37 not taken.
✓ Branch 36 → 38 taken 3023 times.
✗ Branch 38 → 39 not taken.
✓ Branch 38 → 40 taken 3023 times.
✗ Branch 40 → 41 not taken.
✓ Branch 40 → 42 taken 3023 times.
6046 allocate (this%i(0:sze - 1))
221
6/10
✓ Branch 42 → 43 taken 809 times.
✓ Branch 42 → 44 taken 2214 times.
✓ Branch 44 → 43 taken 2214 times.
✗ Branch 44 → 45 not taken.
✗ Branch 45 → 46 not taken.
✓ Branch 45 → 47 taken 3023 times.
✗ Branch 47 → 48 not taken.
✓ Branch 47 → 49 taken 3023 times.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 51 taken 3023 times.
6046 allocate (this%j(0:sze - 1))
222
6/10
✓ Branch 51 → 52 taken 809 times.
✓ Branch 51 → 53 taken 2214 times.
✓ Branch 53 → 52 taken 2214 times.
✗ Branch 53 → 54 not taken.
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 56 taken 3023 times.
✗ Branch 56 → 57 not taken.
✓ Branch 56 → 58 taken 3023 times.
✗ Branch 58 → 59 not taken.
✓ Branch 58 → 60 taken 3023 times.
6046 allocate (this%k(0:sze - 1))
223
224 row_local = 0
225
2/2
✓ Branch 60 → 61 taken 405 times.
✓ Branch 60 → 62 taken 2618 times.
3023 if (.not. inds%complement) then
226
2/2
✓ Branch 63 → 64 taken 6911 times.
✓ Branch 63 → 92 taken 2618 times.
9529 do k = inds%k0, inds%k1
227
2/2
✓ Branch 65 → 66 taken 178794 times.
✓ Branch 65 → 71 taken 6911 times.
188323 do j = inds%j0, inds%j1
228
2/2
✓ Branch 67 → 68 taken 513212 times.
✓ Branch 67 → 69 taken 178794 times.
698917 do i = inds%i0, inds%i1
229 513212 row_global = l0 + (i - my_inds%i0) + (j - my_inds%j0) * my_sze_x + (k - my_inds%k0) * my_sze_x * my_sze_y
230
231 513212 this%lin(row_local) = row_global
232 513212 this%i(row_local) = i
233 513212 this%j(row_local) = j
234 513212 this%k(row_local) = k
235
236 692006 row_local = row_local + 1
237 end do
238 end do
239 end do
240 else
241
2/2
✓ Branch 73 → 74 taken 405 times.
✓ Branch 73 → 75 taken 2125 times.
2530 do k = my_inds%k0, my_inds%k1
242
2/2
✓ Branch 76 → 77 taken 35374 times.
✓ Branch 76 → 90 taken 2125 times.
37904 do j = my_inds%j0, my_inds%j1
243
2/2
✓ Branch 78 → 79 taken 587962 times.
✓ Branch 78 → 88 taken 35374 times.
625461 do i = my_inds%i0, my_inds%i1
244
12/12
✓ Branch 79 → 80 taken 577347 times.
✓ Branch 79 → 86 taken 10615 times.
✓ Branch 80 → 81 taken 566732 times.
✓ Branch 80 → 86 taken 10615 times.
✓ Branch 81 → 82 taken 550770 times.
✓ Branch 81 → 86 taken 15962 times.
✓ Branch 82 → 83 taken 534808 times.
✓ Branch 82 → 86 taken 15962 times.
✓ Branch 83 → 84 taken 530622 times.
✓ Branch 83 → 86 taken 4186 times.
✓ Branch 84 → 85 taken 507112 times.
✓ Branch 84 → 86 taken 23510 times.
587962 if (k >= inds%k0 .and. k <= inds%k1 .and. j >= inds%j0 .and. j <= inds%j1 .and. i >= inds%i0 .and. i <= inds%i1) cycle
245 80850 row_global = l0 + (i - my_inds%i0) + (j - my_inds%j0) * my_sze_x + (k - my_inds%k0) * my_sze_x * my_sze_y
246
247 80850 this%lin(row_local) = row_global
248 80850 this%i(row_local) = i
249 80850 this%j(row_local) = j
250 80850 this%k(row_local) = k
251
252 623336 row_local = row_local + 1
253 end do
254 end do
255 end do
256 end if
257
258 ! Set the corresponding TensorProdIndices
259 3023 this%tp_inds = inds
260 3023 end subroutine init_lists
261
262 !> @brief Destroy the TensorProdIndexList
263 !>
264 !> @param this[inout] The TensorProdIndexList to destroy
265 1885 subroutine destroy_indices(this)
266 implicit none
267
268 class(TensorProdIndexList), intent(inout) :: this
269
270
1/2
✓ Branch 2 → 3 taken 1885 times.
✗ Branch 2 → 4 not taken.
1885 if (allocated(this%lin)) deallocate (this%lin)
271
1/2
✓ Branch 4 → 5 taken 1885 times.
✗ Branch 4 → 6 not taken.
1885 if (allocated(this%i)) deallocate (this%i)
272
1/2
✓ Branch 6 → 7 taken 1885 times.
✗ Branch 6 → 8 not taken.
1885 if (allocated(this%j)) deallocate (this%j)
273
1/2
✓ Branch 8 → 9 taken 1885 times.
✗ Branch 8 → 10 not taken.
1885 if (allocated(this%k)) deallocate (this%k)
274
275 1885 end subroutine destroy_indices
276
277 !> @brief Get the size of the TensorProdIndices
278 !>
279 !> @param a The TensorProdIndices for which to get the size
280 !> @param dir _(optional)_ The direction for which to get the size (1 for x, 2 for y, 3 for z). If not provided, the total size is
281 !> returned.
282 727655 pure integer function size_tpinds(a, dir)
283 implicit none
284
285 type(TensorProdIndices), intent(in) :: a
286 integer, intent(in), optional :: dir
287
288
2/2
✓ Branch 2 → 3 taken 723252 times.
✓ Branch 2 → 4 taken 4403 times.
727655 if (.not. present(dir)) then
289 723252 size_tpinds = (a%i1 - a%i0 + 1) * (a%j1 - a%j0 + 1) * (a%k1 - a%k0 + 1)
290 else
291 5083 select case (dir)
292 case (1) ! x-direction
293 680 size_tpinds = a%i1 - a%i0 + 1
294 case (2) ! y-direction
295 680 size_tpinds = a%j1 - a%j0 + 1
296 case (3) ! z-direction
297 3043 size_tpinds = a%k1 - a%k0 + 1
298 case default
299
3/4
✓ Branch 4 → 5 taken 680 times.
✓ Branch 4 → 6 taken 680 times.
✓ Branch 4 → 7 taken 3043 times.
✗ Branch 4 → 8 not taken.
4403 error stop "Invalid direction for TensorProdIndices::size_tpinds"
300 end select
301 end if
302
303
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 727655 times.
727655 if (a%complement) then
304 size_tpinds = a%total_nr_x * a%total_nr_y * a%total_nr_z - size_tpinds
305 end if
306 727655 end function size_tpinds
307
308 !> @brief Get the size of the TensorProdIndices in 2D
309 !>
310 !> @param a The TensorProdIndices for which to get the size
311 !> @param dir _(optional)_ The direction for which to get the size (1 for x, 2 for y). If not provided, the total size is returned.
312 1860 pure integer function size_tp_inds_2d(a, dir)
313 implicit none
314
315 type(TensorProdIndices), intent(in) :: a
316 integer, intent(in), optional :: dir
317
318
1/2
✓ Branch 2 → 3 taken 1860 times.
✗ Branch 2 → 4 not taken.
1860 if (.not. present(dir)) then
319 1860 size_tp_inds_2d = (a%i1 - a%i0 + 1) * (a%j1 - a%j0 + 1)
320 else
321 select case (dir)
322 case (1) ! x-direction
323 size_tp_inds_2d = a%i1 - a%i0 + 1
324 case (2) ! y-direction
325 size_tp_inds_2d = a%j1 - a%j0 + 1
326 case default
327 error stop "Invalid direction for TensorProdIndices::size_tp_inds_2d"
328 end select
329 end if
330
331 1860 end function size_tp_inds_2d
332
333 !> @brief Get the size of the TensorProdIndexList
334 !>
335 !> @param a The TensorProdIndexList for which to get the size
336 !> @param dir _(optional)_ The direction for which to get the size (1 for x, 2 for y, 3 for z). If not provided, the total size is
337 !> returned.
338 8962 pure integer function size_index_list(a, dir)
339 implicit none
340 type(TensorProdIndexList), intent(in) :: a
341 integer, intent(in), optional :: dir
342 8962 size_index_list = size(a%tp_inds, dir)
343 8962 end function size_index_list
344
345 !> @brief Get the size of the TensorProdIndexList in 2D
346 !>
347 !> @param a The TensorProdIndexList for which to get the size
348 !> @param dir _(optional)_ The direction for which to get the size (1 for x, 2 for y). If not provided, the total size is returned.
349 1860 pure integer function size_index_list_2d(a, dir)
350 implicit none
351 type(TensorProdIndexList), intent(in) :: a
352 integer, intent(in), optional :: dir
353
354
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1860 times.
1860 if (a%tp_inds%complement) then
355 error stop "TensorProdIndexList::size_index_list_2d not implemented for complement indices"
356 end if
357
358 1860 size_index_list_2d = size_tp_inds_2d(a%tp_inds, dir)
359 1860 end function size_index_list_2d
360
361 !> @brief Compute the intersection of two TensorProdIndices
362 !>
363 !> @param a The first TensorProdIndices
364 !> @param b The second TensorProdIndices
365 !>
366 !> @return The intersection of the two TensorProdIndices
367 405 pure type(TensorProdIndices) function intersect(a, b)
368 implicit none
369
370 type(TensorProdIndices), intent(in) :: a, b
371
372 ! Compute the intersection of two TensorProdIndices
373
374
2/4
✓ Branch 2 → 3 taken 405 times.
✗ Branch 2 → 5 not taken.
✓ Branch 3 → 4 taken 405 times.
✗ Branch 3 → 5 not taken.
405 if (.not. a%complement .and. .not. b%complement) then
375 405 intersect%i0 = max(a%i0, b%i0)
376 405 intersect%i1 = min(a%i1, b%i1)
377 405 intersect%j0 = max(a%j0, b%j0)
378 405 intersect%j1 = min(a%j1, b%j1)
379 405 intersect%k0 = max(a%k0, b%k0)
380 405 intersect%k1 = min(a%k1, b%k1)
381
382 intersect%complement = .false.
383
384 405 intersect%total_nr_x = a%total_nr_x
385 405 intersect%total_nr_y = a%total_nr_y
386 405 intersect%total_nr_z = a%total_nr_z
387 else
388 error stop "Intersecting TensorProdIndices with complement is not implemented"
389 end if
390
391 405 end function intersect
392
393 !> @brief Check if a point is inside the box
394 !>
395 !> @param this The box
396 !> @param x The x-coordinate of the point
397 !> @param y The y-coordinate of the point
398 !> @param z The z-coordinate of the point
399 !>
400 !> @return True if the point is inside the box, false otherwise
401 pure logical function is_inside(this, x, y, z)
402 implicit none
403
404 class(Box), intent(in) :: this
405 real(wp), intent(in) :: x, y, z
406
407 ! TODO: check what happens on the boundary, and periodicity?
408 is_inside = (x >= this%x0 .and. x <= this%x1 .and. &
409 y >= this%y0 .and. y <= this%y1 .and. &
410 z >= this%z0 .and. z <= this%z1)
411
412 end function is_inside
413
414 !> @brief Get the local index in the TensorProdIndexList for a given global Cartesian index
415 !>
416 !> @param this The TensorProdIndexList
417 !> @param i The global x-index
418 !> @param j The global y-index
419 !> @param k The global z-index
420 !>
421 !> @return The local index in the TensorProdIndexList
422 458512 pure integer function get_local_index_3d(this, i, j, k)
423 implicit none
424
425 class(TensorProdIndexList), intent(in) :: this
426 integer, intent(in) :: i, j, k
427
428
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 458512 times.
458512 if (this%tp_inds%complement) then
429 error stop "TensorProdIndexList::get_local_index_3d not implemented for complement indices"
430 end if
431
432 get_local_index_3d = (i - this%tp_inds%i0) + (j - this%tp_inds%j0) * (1 + this%tp_inds%i1 - this%tp_inds%i0) + &
433 458512 (k - this%tp_inds%k0) * (1 + this%tp_inds%i1 - this%tp_inds%i0) * (1 + this%tp_inds%j1 - this%tp_inds%j0)
434
435 458512 end function get_local_index_3d
436
437 !> @brief Get the local index in the TensorProdIndexList for a given global Cartesian index (2D version)
438 !>
439 !> @param this The TensorProdIndexList
440 !> @param i The global x-index
441 !> @param j The global y-index
442 !>
443 !> @return The local index in the TensorProdIndexList
444 pure integer function get_local_index_2d(this, i, j)
445 implicit none
446 class(TensorProdIndexList), intent(in) :: this
447 integer, intent(in) :: i, j
448 if (this%tp_inds%complement) then
449 error stop "TensorProdIndexList::get_local_index_2d not implemented for complement indices"
450 end if
451 get_local_index_2d = (i - this%tp_inds%i0) + (j - this%tp_inds%j0) * (1 + this%tp_inds%i1 - this%tp_inds%i0)
452 end function get_local_index_2d
453
454 !> @brief Get the index bounds from a single TensorProdIndexList
455 !>
456 !> @param[in] index_list The TensorProdIndexList
457 !> @param[out] i_min The minimum i-index
458 !> @param[out] i_max The maximum i-index
459 !> @param[out] j_min The minimum j-index
460 !> @param[out] j_max The maximum j-index
461 !> @param[out] _(optional)_ k_min The minimum k-index
462 !> @param[out] _(optional)_ k_max The maximum k-index
463 3010 pure subroutine get_bounds_list(this, i_min, i_max, j_min, j_max, k_min, k_max)
464 implicit none
465
466 class(TensorProdIndexList), intent(in) :: this
467 integer, intent(out) :: i_min, i_max, j_min, j_max
468 integer, optional, intent(out) :: k_min, k_max
469
470 3010 i_min = this%tp_inds%i0
471 3010 i_max = this%tp_inds%i1
472 3010 j_min = this%tp_inds%j0
473 3010 j_max = this%tp_inds%j1
474
2/2
✓ Branch 2 → 3 taken 2517 times.
✓ Branch 2 → 4 taken 493 times.
3010 if (present(k_min)) k_min = this%tp_inds%k0
475
2/2
✓ Branch 4 → 5 taken 2517 times.
✓ Branch 4 → 6 taken 493 times.
3010 if (present(k_max)) k_max = this%tp_inds%k1
476 3010 end subroutine get_bounds_list
477 end module m_tensorprod_indices
478