31 use const_gbl,
only: stdout
43 integer,
pointer :: ij(:,:)
44 real(wp),
pointer :: coefficient(:)
46 logical :: constructed = .false.
63 logical :: constructed = .false.
64 integer :: matrix_index
65 integer :: num_matrix_chunks = 1
66 integer :: max_capacity = 0
98 if (.not. this % constructed)
then
99 write (stdout,
"('Vector::constructed - Vector is not constructed')")
100 stop
"Vector::constructed - Vector is not constructed"
108 integer,
intent(in) :: idx
109 integer :: mat_idx, local_idx
111 call this % get_local_mat(idx, mat_idx, local_idx)
121 integer,
optional,
intent(in) :: expand_size_
123 if (
present(expand_size_))
then
124 this % expand_size = expand_size_
129 this % max_capacity = this % expand_size
131 this % matrix_index = 1
134 allocate(this%matrix_arrays(this%matrix_index),stat=err)
135 call master_memory%track_memory(36,
size(this%matrix_arrays),err,
'MATRIXCACHE::MATRIXARRAY')
141 call this % matrix_arrays(this % matrix_index) % construct(this % expand_size)
144 this % num_matrix_chunks = 1
149 write (stdout,
"('Matrix Cache::construct- arrays not allocated')")
150 stop
"Matrix Cache:: arrays not allocated"
154 this % constructed = .true.
161 integer,
intent(in) :: i, j
162 real(wp),
intent(in) :: coefficient
163 integer :: mat_id, local_index
166 this % n = this % n + 1
168 if (this % n > this % max_capacity)
then
169 call this % expand_array()
172 call this % get_local_mat(this % n, mat_id, local_index)
174 this % num_matrix_chunks = mat_id
175 this % matrix_arrays(mat_id) % ij(1, local_index) = i
176 this % matrix_arrays(mat_id) % ij(2, local_index) = j
177 this % matrix_arrays(mat_id) % coefficient(local_index) = coefficient
179 this % matrix_arrays(mat_id) % num_elems = this % matrix_arrays(mat_id) % num_elems + 1
186 integer,
intent(in) :: idx
187 integer,
intent(out) :: mat_id
188 integer,
intent(out) :: local_index
190 if (this % check_bounds(idx))
then
191 mat_id = (idx - 1) / this % expand_size + 1
196 local_index = idx - (mat_id - 1) * this % expand_size
204 integer,
intent(in) :: idx
205 integer,
intent(out) :: i, j
206 real(wp),
intent(out) :: coeff
208 integer :: mat_id, local_index
210 if (this % check_bounds(idx))
then
211 call this % get_local_mat(idx, mat_id, local_index)
213 i = this % matrix_arrays(mat_id) % ij(1, local_index)
214 j = this % matrix_arrays(mat_id) % ij(2, local_index)
216 coeff = this % matrix_arrays(mat_id) % coefficient(local_index)
224 type(
matrixarray) :: temp_matrix(this % num_matrix_chunks + 1)
225 integer :: new_num_mats, err
227 call this % check_constructed
230 temp_matrix(1:this % num_matrix_chunks) = this % matrix_arrays(1:this % num_matrix_chunks)
231 call master_memory % free_memory(36,
size(this % matrix_arrays))
232 deallocate(this % matrix_arrays)
234 this % max_capacity = this % max_capacity + this % expand_size
236 new_num_mats = this % max_capacity / this % expand_size
237 this % matrix_index = new_num_mats
238 this % num_matrix_chunks = this % num_matrix_chunks + 1
239 allocate(this % matrix_arrays(this % num_matrix_chunks), stat = err)
240 call master_memory % track_memory(36,
size(this % matrix_arrays), err,
'MATRIXCACHE::MATRIXARRAY')
242 this % matrix_arrays(:) = temp_matrix(:)
243 this % matrix_arrays(this % num_matrix_chunks) % num_elems = 0
244 call this % matrix_arrays(this % num_matrix_chunks) % construct(this % expand_size)
253 if (.not. this % constructed)
return
254 if (
associated(this % ij))
then
255 call master_memory % free_memory(kind(this % ij),
size(this % ij))
256 deallocate(this % ij)
259 if (
associated(this % coefficient))
then
260 call master_memory % free_memory(kind(this % coefficient),
size(this % coefficient))
261 deallocate(this % coefficient)
262 this % coefficient => null()
264 this % constructed = .false.
272 integer,
intent(in) :: capacity
275 if (.not. this % constructed)
then
276 call master_memory % track_memory(kind(this % ij), capacity * 2, 0,
'MATRIXCACHE::MATRIXARRAY::IJ')
277 call master_memory % track_memory(kind(this % coefficient), capacity, 0,
'MATRIXCACHE::MATRIXARRAY::COEFF')
278 allocate(this % ij(2, capacity), this % coefficient(capacity), stat = err)
279 this % constructed = .true.
295 integer,
intent(in) :: i, j
296 real(wp),
intent(in) :: coeff
298 this % num_elems = this % num_elems + 1
299 this % ij(this % num_elems, 1) = i
300 this % ij(this % num_elems, 2) = j
301 this % coefficient(this % num_elems) = coeff
308 integer,
intent(in) :: idx
309 integer,
intent(out) :: i, j
310 real(wp),
intent(out) :: coeff
312 if (idx > this % num_elems) stop
"Matrix Array access segfault!"
314 i = this % ij(1, idx)
315 j = this % ij(2, idx)
316 coeff = this % coefficient(idx)
323 integer,
intent(in) :: capacity
325 do while (this % max_capacity < capacity)
326 call this % expand_array
334 integer,
intent(in) :: i
336 if (i <= 0 .or. i > this % n)
then
337 write (stdout,
"('MatrixCache::check_bounds - Out of Bounds access', 2i4)") i, this % n
338 stop
"MatrixCache::check_bounds - Out of Bounds access"
360 if (
allocated(this % matrix_arrays)) this % matrix_arrays(:) % num_elems = 0
376 integer :: ido, total_size, shrink_size
380 if (
allocated(this % matrix_arrays))
then
381 total_size =
size(this % matrix_arrays)
382 shrink_size = min(this % n / this % expand_size + 1, this % num_matrix_chunks)
384 if (shrink_size == this % num_matrix_chunks)
return
386 do ido = shrink_size + 1, total_size
387 call this % matrix_arrays(ido) % destroy
390 allocate(temp_matrix(shrink_size))
391 call master_memory % track_memory(36,
size(temp_matrix), 0,
'MATRIXCACHE::SHRINK::TEMP')
392 temp_matrix(1:shrink_size) = this % matrix_arrays(1:shrink_size)
393 call master_memory % free_memory(36,
size(this % matrix_arrays))
394 deallocate(this % matrix_arrays)
396 allocate(this % matrix_arrays(shrink_size))
397 call master_memory % track_memory(36,
size(this % matrix_arrays), 0,
'MATRIXCACHE::SHRINK::MATRIXARRAYS')
398 this % matrix_arrays(1:shrink_size) = temp_matrix(1:shrink_size)
399 this % max_capacity = shrink_size * this % expand_size
400 this % num_matrix_chunks = shrink_size
402 deallocate(temp_matrix)
412 call this % shrink_capacity
419 integer :: num_arrays, ido
421 if (
allocated(this % matrix_arrays))
then
422 num_arrays =
size(this % matrix_arrays)
424 do ido = 1, num_arrays
425 call this % matrix_arrays(ido) % destroy
428 call master_memory % free_memory(36,
size(this % matrix_arrays))
429 deallocate(this % matrix_arrays)
432 this % constructed = .false.
439 integer :: labels(8), ido, arrs, jdo, elm
442 write (stdout,
"('Outputting Matrix elements....')")
444 this % matrix_index = this % n / this % expand_size + 1
447 do ido = 1, this % num_matrix_chunks
448 write (stdout, *) this % matrix_arrays(ido) % num_elems
449 do jdo = 1, this % matrix_arrays(ido) % num_elems
450 write (stdout,
"(2i8,' -- ',D16.8)") this % matrix_arrays(ido) % ij(1:2,jdo), &
451 this % matrix_arrays(ido) % coefficient(jdo)
461 call this % check_constructed
462 if (this % n <= 1)
return
463 call this % quick_sort_function(1, this % n)
471 integer,
intent(in) :: start_idx, end_idx
472 integer :: mat_size, iq
474 mat_size = end_idx - start_idx + 1
476 if (mat_size > 1)
then
477 call this % partition_function(iq, start_idx, end_idx)
478 call this % quick_sort_function(start_idx, iq - 1)
479 call this % quick_sort_function(iq, end_idx)
487 integer,
intent(in) :: start_idx, end_idx
488 integer,
intent(out) :: marker
489 integer :: i, j, temp_ij(2), x_ij(2), A_ij(2), mat_id_i, mat_id_j, local_index_i, local_index_j
490 real(wp) :: temp_coeff, x_coeff, A_coeff
492 call this % get_from_cache(start_idx, x_ij(1), x_ij(2), x_coeff)
500 call this % get_from_cache(j, a_ij(1), a_ij(2), a_coeff)
501 if (a_ij(1) <= x_ij(1))
exit
506 call this % get_from_cache(i, a_ij(1), a_ij(2), a_coeff)
507 if (a_ij(1) >= x_ij(1))
exit
512 call this % get_local_mat(i, mat_id_i, local_index_i)
513 call this % get_local_mat(j, mat_id_j, local_index_j)
515 temp_ij(:) = this % matrix_arrays(mat_id_i) % ij(:,local_index_i)
516 temp_coeff = this % matrix_arrays(mat_id_i) % coefficient(local_index_i)
518 this % matrix_arrays(mat_id_i) % ij(:,local_index_i) &
519 = this % matrix_arrays(mat_id_j) % ij(:,local_index_j)
520 this % matrix_arrays(mat_id_i) % coefficient(local_index_i) &
521 = this % matrix_arrays(mat_id_j) % coefficient(local_index_j)
523 this % matrix_arrays(mat_id_j) % ij(:,local_index_j) = temp_ij(:)
524 this % matrix_arrays(mat_id_j) % coefficient(local_index_j) = temp_coeff
525 else if (i == j)
then