Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_sparse_matrix_pastix.F90
Go to the documentation of this file.
1 !**************************************************************
2 ! Copyright INRIA
3 ! Authors :
4 ! CALVI project team
5 !
6 ! This code SeLaLib (for Semi-Lagrangian-Library)
7 ! is a parallel library for simulating the plasma turbulence
8 ! in a tokamak.
9 !
10 ! This software is governed by the CeCILL-B license
11 ! under French law and abiding by the rules of distribution
12 ! of free software. You can use, modify and redistribute
13 ! the software under the terms of the CeCILL-B license as
14 ! circulated by CEA, CNRS and INRIA at the following URL
15 ! "http://www.cecill.info".
16 !**************************************************************
17 
19 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20 #include "sll_working_precision.h"
21 #include "sll_memory.h"
22 #include "sll_assert.h"
23 
24  use sll_m_pastix
26 
27  implicit none
28 
29  public :: &
43 
44  private
45 
46 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47 
49  type sll_t_csr_matrix
50  sll_int32 :: num_rows
51  sll_int32 :: num_cols
52  sll_int32 :: num_nz
53  sll_int32, dimension(:), pointer :: row_ptr
54  sll_int32, dimension(:), pointer :: col_ind
55  sll_real64, dimension(:), pointer :: val
56  type(pastix_solver), pointer :: linear_solver
57  end type sll_t_csr_matrix
58 
59  interface sll_o_delete
60  module procedure sll_s_delete_csr_matrix
61  end interface sll_o_delete
62 
63 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
64 
65 contains
66 
67 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
68 
69  subroutine sll_s_delete_csr_matrix(csr_mat)
70 
71  type(sll_t_csr_matrix), pointer :: csr_mat
72 
73  nullify (csr_mat)
74 
75  end subroutine sll_s_delete_csr_matrix
76 
90 
91  function sll_f_new_csr_matrix(num_rows, &
92  num_cols, &
93  num_elts, &
94  local_to_global_row, &
95  num_local_dof_row, &
96  local_to_global_col, &
97  num_local_dof_col) result(mat)
98 
99  type(sll_t_csr_matrix), pointer :: mat
100  sll_int32, intent(in) :: num_rows
101  sll_int32, intent(in) :: num_cols
102  sll_int32, intent(in) :: num_elts
103  sll_int32, dimension(:, :), intent(in) :: local_to_global_row
104  sll_int32, intent(in) :: num_local_dof_row
105  sll_int32, dimension(:, :), intent(in) :: local_to_global_col
106  sll_int32, intent(in) :: num_local_dof_col
107 
108  sll_int32 :: ierr
109 
110  sll_allocate(mat, ierr)
111 
112  call sll_s_csr_matrix_init(mat, &
113  num_rows, &
114  num_cols, &
115  num_elts, &
116  local_to_global_row, &
117  num_local_dof_row, &
118  local_to_global_col, &
119  num_local_dof_col)
120 
121  end function sll_f_new_csr_matrix
122 
135  subroutine sll_s_csr_matrix_init(mat, &
136  num_rows, &
137  num_cols, &
138  num_elts, &
139  local_to_global_row, &
140  num_local_dof_row, &
141  local_to_global_col, &
142  num_local_dof_col)
143 
144  type(sll_t_csr_matrix), intent(inout) :: mat
145  sll_int32, intent(in) :: num_rows
146  sll_int32, intent(in) :: num_cols
147  sll_int32, intent(in) :: num_elts
148  sll_int32, dimension(:, :), intent(in) :: local_to_global_row
149  sll_int32, intent(in) :: num_local_dof_row
150  sll_int32, dimension(:, :), intent(in) :: local_to_global_col
151  sll_int32, intent(in) :: num_local_dof_col
152 
153  sll_int32 :: num_nz
154  sll_int32, pointer :: lpi_columns(:, :)
155  sll_int32, pointer :: lpi_occ(:)
156  sll_int32 :: coef
157  sll_int32 :: ierr
158 
159  coef = 10
160  sll_allocate(lpi_columns(num_rows, 0:coef*num_local_dof_col), ierr)
161  sll_allocate(lpi_occ(num_rows + 1), ierr)
162 
163  lpi_columns(:, :) = 0
164  lpi_occ(:) = 0
165  ! COUNTING NON ZERO ELEMENTS
166 
167  num_nz = sll_count_non_zero_elts(num_rows, &
168  num_cols, &
169  num_elts, &
170  local_to_global_row, &
171  num_local_dof_row, &
172  local_to_global_col, &
173  num_local_dof_col, &
174  lpi_columns, &
175  lpi_occ)
176  mat%num_rows = num_rows
177  mat%num_cols = num_cols
178  mat%num_nz = num_nz
179 
180  call init_sparsematrix(num_elts, &
181  local_to_global_row, &
182  num_local_dof_row, &
183  local_to_global_col, &
184  num_local_dof_col, &
185  lpi_columns, &
186  lpi_occ, &
187  colptr, &
188  row, &
189  num_rows)
190  stop
191 
192  mat%linear_solver%iparm(iparm_transpose_solve) = api_yes
193  sll_allocate(mat%linear_solver, ierr)
194  call initialize(mat%linear_solver, num_rows, num_nz)
195 
196  mat%linear_solver%avals = 0._f64
197 
198  sll_deallocate_array(lpi_columns, ierr)
199  sll_deallocate_array(lpi_occ, ierr)
200 
201  end subroutine sll_s_csr_matrix_init
202 
204 
205  type(sll_t_csr_matrix), intent(inout) :: mat
206  type(sll_t_csr_matrix), intent(in) :: mat_a
207 
208  !print*,' COUNTING NON ZERO ELEMENTS'
209  mat%num_nz = mat_a%num_nz + 2*mat_a%num_rows
210  print *, 'num_nz mat, num_nz mat_tot', mat_a%num_nz, mat%num_nz
211  mat%num_rows = mat_a%num_rows + 1
212  print *, 'num_rows mat, num_rows mat_tot', mat_a%num_rows, mat%num_rows
213  mat%num_cols = mat_a%num_cols + 1
214  print *, 'num_cols mat, num_cols mat_tot', mat_a%num_cols, mat%num_cols
215 
216  mat%linear_solver%avals = 0._f64
217 
219 
220  function sll_f_new_csr_matrix_with_constraint(mat_a) result(mat)
221 
222  type(sll_t_csr_matrix), pointer :: mat
223  type(sll_t_csr_matrix) :: mat_a
224 
225  sll_int32 :: ierr
226 
227  sll_allocate(mat, ierr)
228 
230 
232 
233  subroutine sll_s_csr_add_one_constraint(ia_in, &
234  ja_in, &
235  a_in, &
236  num_rows_in, &
237  num_nz_in, &
238  constraint_vec, &
239  ia_out, &
240  ja_out, &
241  a_out)
242 
243  sll_int32, dimension(:), intent(in) :: ia_in
244  sll_int32, dimension(:), intent(in) :: ja_in
245  real(8), dimension(:), intent(in) :: a_in
246  sll_int32, intent(in) :: num_rows_in
247  sll_int32, intent(in) :: num_nz_in
248  real(8), dimension(:), intent(in) :: constraint_vec
249  sll_int32, dimension(:), intent(out) :: ia_out
250  sll_int32, dimension(:), intent(out) :: ja_out
251  real(8), dimension(:), intent(out) :: a_out
252 
253  sll_int32 :: num_rows_out
254  sll_int32 :: num_nz_out
255  sll_int32 :: i
256  sll_int32 :: s
257  sll_int32 :: k
258 
259  num_rows_out = num_rows_in + 1
260  num_nz_out = num_nz_in + 2*num_rows_in
261 
262  if (size(ia_in) < num_rows_in + 1) then
263  print *, '#problem of size of ia_in', size(ia_in), num_rows_in + 1
264  stop
265  end if
266  if (size(ja_in) < num_nz_in) then
267  print *, '#problem of size of ja_in', size(ja_in), num_nz_in
268  stop
269  end if
270  if (size(a_in) < num_nz_in) then
271  print *, '#problem of size of a_in', size(a_in), num_nz_in
272  stop
273  end if
274  if (size(ia_out) < num_rows_out + 1) then
275  print *, '#problem of size of ia_out', size(ia_out), num_rows_out + 1
276  stop
277  end if
278  if (size(ja_out) < num_nz_out) then
279  print *, '#problem of size of ja_out', size(ja_out), num_nz_out
280  stop
281  end if
282  if (size(a_out) < num_nz_out) then
283  print *, '#problem of size of a_out', size(a_out), num_nz_out
284  stop
285  end if
286  if (ia_in(num_rows_in + 1) .ne. num_nz_in + 1) then
287  print *, '#bad value of ia_in(num_rows_in+1)', ia_in(num_rows_in + 1), num_nz_in + 1
288  stop
289  end if
290 
291  s = 1
292  do i = 1, num_rows_in
293  ia_out(i) = s
294  do k = ia_in(i), ia_in(i + 1) - 1
295  a_out(s) = a_in(k)
296  ja_out(s) = ja_in(k)
297  s = s + 1
298  end do
299  a_out(s) = constraint_vec(i)
300  ja_out(s) = num_rows_out
301  s = s + 1
302  end do
303  ia_out(num_rows_in + 1) = s
304  do i = 1, num_rows_in
305  a_out(s) = constraint_vec(i)
306  ja_out(s) = i
307  s = s + 1
308  end do
309  ia_out(num_rows_in + 2) = s
310 
311  if (ia_out(num_rows_out + 1) .ne. num_nz_out + 1) then
312  print *, '#bad value of ia_out(num_rows_out+1)', ia_out(num_rows_out + 1), num_nz_out + 1
313  stop
314  end if
315 
316  end subroutine sll_s_csr_add_one_constraint
317 
318  subroutine sll_s_factorize_csr_matrix(mat)
319  type(sll_t_csr_matrix), intent(inout) :: mat
320 
321  call factorize(mat%linear_solver)
322 
323  end subroutine sll_s_factorize_csr_matrix
324 
325  subroutine sll_s_mult_csr_matrix_vector(mat, input, output)
326 
327  type(sll_t_csr_matrix) :: mat
328  sll_real64, dimension(:), intent(in) :: input
329  sll_real64, dimension(:), intent(out) :: output
330  !local var
331  sll_int32 :: i
332  sll_int32 :: k_1
333  sll_int32 :: k_2
334 
335  do i = 1, mat%num_rows
336 
337  k_1 = mat%linear_solver%colptr(i)
338  k_2 = mat%linear_solver%colptr(i + 1) - 1
339  output(i) = &
340  dot_product(mat%linear_solver%avals(k_1:k_2), &
341  input(mat%linear_solver%row(k_1:k_2)))
342 
343  end do
344 
345  end subroutine sll_s_mult_csr_matrix_vector
346 
347  subroutine sll_s_add_to_csr_matrix(mat, val, a, a_prime)
348 
349  type(sll_t_csr_matrix), intent(inout) :: mat
350  sll_real64, intent(in) :: val
351  sll_int32, intent(in) :: a
352  sll_int32, intent(in) :: a_prime
353  !local var
354  sll_int32 :: j
355  sll_int32 :: k
356 
357  ! THE CURRENT LINE IS self%row_ptr(a)
358  do k = mat%linear_solver%colptr(a), mat%linear_solver%colptr(a + 1) - 1
359  j = mat%linear_solver%row(k)
360  if (j == a_prime) then
361  mat%linear_solver%avals(k) = mat%linear_solver%avals(k) + val
362  exit
363  end if
364  end do
365 
366  end subroutine sll_s_add_to_csr_matrix
367 
368  subroutine set_values_csr_matrix(mat, val)
369  implicit none
370  type(sll_t_csr_matrix) :: mat
371  sll_real64, dimension(:), intent(in) :: val
372  !local variables
373 
374  if (size(val) < mat%num_nz) then
375  print *, '#Problem of size of val', size(val), mat%num_nz
376  print *, '#at line', __line__
377  print *, '#in file', __file__
378  print *, '#in subroutine set_values_csr_matrix'
379  stop
380  end if
381 
382  mat%linear_solver%avals(1:mat%num_nz) = val(1:mat%num_nz)
383 
384  end subroutine set_values_csr_matrix
385 
386  subroutine sll_s_solve_csr_matrix(mat, apr_B, apr_U)
387  implicit none
388  type(sll_t_csr_matrix) :: mat
389  sll_real64, dimension(:) :: apr_u
390  sll_real64, dimension(:) :: apr_b
391  !local var
392  sll_int32 :: sys
393  sys = 0
394  apr_u = apr_b
395  call solve(mat%linear_solver, apr_u)
396 
397  end subroutine sll_s_solve_csr_matrix
398 
399  sll_int32 function sll_count_non_zero_elts( &
400  ai_nR, ai_nC, ai_nel, api_LM_1, ai_nen_1, api_LM_2, ai_nen_2, api_columns, api_occ)
401  ! _1 FOR ROWS
402  ! _2 FOR COLUMNS
403  implicit none
404  sll_int32 :: ai_nr, ai_nc
405  sll_int32, dimension(:, :), intent(in) :: api_lm_1, api_lm_2
406  sll_int32 :: ai_nel, ai_nen_1, ai_nen_2
407  sll_int32, dimension(:, :), pointer :: api_columns
408  sll_int32, dimension(:), pointer :: api_occ
409  !local var
410  sll_int32 :: e, b_1, a_1, b_2, a_2, i
411  sll_int32 :: result
412  sll_int32, dimension(2) :: lpi_size
413  logical :: ll_done
414  sll_int32, dimension(:, :), pointer :: lpi_columns
415 
416  ! WE FIRST COMPUTE, FOR EACH ROW, THE NUMBER OF COLUMNS THAT WILL BE USED
417  do e = 1, ai_nel
418 
419  do b_1 = 1, ai_nen_1
420 
421  a_1 = api_lm_1(b_1, e)
422  if (a_1 == 0) then
423  cycle
424  end if
425 
426  do b_2 = 1, ai_nen_2
427 
428  a_2 = api_lm_2(b_2, e)
429  if (a_2 == 0) then
430  cycle
431  end if
432 
433  ll_done = .false.
434  ! WE CHECK IF IT IS THE FIRST OCCURANCE OF THE COUPLE (A_1, A_2)
435  do i = 1, api_columns(a_1, 0)
436 
437  if (api_columns(a_1, i) /= a_2) then
438  cycle
439  end if
440 
441  ll_done = .true.
442  exit
443 
444  end do
445 
446  if (.not. ll_done) then
447 
448  api_occ(a_1) = api_occ(a_1) + 1
449 
450  ! A_1 IS THE ROW NUM, A_2 THE COLUMN NUM
451  ! INITIALIZATION OF THE SPARSE MATRIX
452  api_columns(a_1, 0) = api_columns(a_1, 0) + 1
453  api_columns(a_1, api_columns(a_1, 0)) = a_2
454 
455  ! resizing the array
456  lpi_size(1) = SIZE(api_columns, 1)
457  lpi_size(2) = SIZE(api_columns, 2)
458  if (lpi_size(2) < api_columns(a_1, 0)) then
459  ALLOCATE (lpi_columns(lpi_size(1), lpi_size(2)))
460  lpi_columns = api_columns
461 
462  DEALLOCATE (api_columns)
463 
464  ALLOCATE (api_columns(lpi_size(1), 2*lpi_size(2)))
465  api_columns(1:lpi_size(1), 1:lpi_size(2)) = lpi_columns(1:lpi_size(1), 1:lpi_size(2))
466 
467  DEALLOCATE (lpi_columns)
468  end if
469 
470  end if
471 
472  end do
473 
474  end do
475 
476  end do
477 
478  ! COUNT NON ZERO ELEMENTS
479  result = sum(api_occ(1:ai_nr))
480 
481  sll_count_non_zero_elts = result
482  end function sll_count_non_zero_elts
483 
484  subroutine init_sparsematrix(ai_nel, &
485  api_LM_1, &
486  ai_nen_1, &
487  api_LM_2, &
488  ai_nen_2, &
489  api_columns, &
490  api_occ, &
491  row_ptr, &
492  col_ind, &
493  num_rows)
494 
495 ! _1 FOR ROWS
496 ! _2 FOR COLUMNS
497  sll_int32, dimension(:, :), intent(in) :: api_lm_1
498  sll_int32, dimension(:, :), intent(in) :: api_lm_2
499  sll_int32 :: ai_nel
500  sll_int32 :: ai_nen_1
501  sll_int32 :: ai_nen_2
502  sll_int32, dimension(:, :), pointer :: api_columns
503  sll_int32, dimension(:), pointer :: api_occ
504  sll_int32, dimension(:), intent(out) :: row_ptr
505  sll_int32, dimension(:), intent(out) :: col_ind
506  sll_int32, intent(in) :: num_rows
507 
508  sll_int32 :: e, b_1, a_1, i, size
509  sll_int32 :: err, flag
510  sll_int32, dimension(:), pointer :: lpr_tmp
511 
512 ! INITIALIZING ia
513  row_ptr(1) = 1
514  do i = 1, num_rows
515  row_ptr(i + 1) = row_ptr(1) + sum(api_occ(1:i))
516  end do
517 
518 ! INITIALIZING ja
519  do e = 1, ai_nel
520  do b_1 = 1, ai_nen_1
521 
522  a_1 = api_lm_1(b_1, e)
523  if (a_1 == 0) cycle
524  if (api_columns(a_1, 0) == 0) cycle
525  size = api_columns(a_1, 0)
526  allocate (lpr_tmp(size), stat=err)
527  if (err .ne. 0) flag = 10
528  lpr_tmp(1:size) = api_columns(a_1, 1:size)
529  call sll_s_qsortc(lpr_tmp)
530  do i = 1, size
531  col_ind(row_ptr(a_1) + i - 1) = int(lpr_tmp(i))
532  end do
533  api_columns(a_1, 0) = 0
534  deallocate (lpr_tmp)
535 
536  end do
537  end do
538 
539  end subroutine init_sparsematrix
540 
541  subroutine sll_s_solve_csr_matrix_perper(mat, apr_B, apr_U, Masse_tot)
542 
543  type(sll_t_csr_matrix) :: mat
544  sll_real64, dimension(:) :: apr_u
545  sll_real64, dimension(:) :: apr_b
546  sll_real64, dimension(:), pointer :: masse_tot
547 
548  sll_int32 :: sys
549  sys = 0
550 
551  end subroutine sll_s_solve_csr_matrix_perper
552 
553 end module sll_m_sparse_matrix
recursive subroutine, public sll_s_qsortc(A)
Sparse matrix linear solver utilities.
subroutine, public sll_s_csr_add_one_constraint(ia_in, ja_in, a_in, num_rows_in, num_nz_in, constraint_vec, ia_out, ja_out, a_out)
subroutine, public sll_s_add_to_csr_matrix(mat, val, row, col)
type(sll_t_csr_matrix) function, pointer, public sll_f_new_csr_matrix_with_constraint(mat_a)
subroutine, public sll_s_delete_csr_matrix(csr_mat)
subroutine sll_s_csr_matrix_init(mat, num_rows, num_cols, num_elts, local_to_global_row, num_local_dof_row, local_to_global_col, num_local_dof_col)
initialization of CSR matrix type thanks to the global index of each local dof of each element
subroutine, public sll_s_mult_csr_matrix_vector(mat, input, output)
subroutine, public sll_s_solve_csr_matrix(mat, b, u)
subroutine, public sll_s_csr_matrix_init_with_constraint(mat, mat_a)
integer(kind=i32) function sll_count_non_zero_elts(ai_nR, ai_nC, ai_nel, api_LM_1, ai_nen_1, api_LM_2, ai_nen_2, api_columns, api_occ)
subroutine init_sparsematrix(ai_nel, api_LM_1, ai_nen_1, api_LM_2, ai_nen_2, api_columns, api_occ, row_ptr, col_ind, num_rows)
subroutine, public sll_s_factorize_csr_matrix(mat)
subroutine, public sll_s_solve_csr_matrix_perper(mat, b, u, masse_tot)
subroutine set_values_csr_matrix(mat, val)
    Report Typos and Errors