Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_sparse_matrix.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 
26 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27 #include "sll_working_precision.h"
28 #include "sll_memory.h"
29 #include "sll_assert.h"
30 
32 
33 #ifdef UMFPACK
34  use sll_m_umfpack
35  use iso_fortran_env, only: output_unit
36 #endif /* UMFPACK */
37 
38 #ifdef PASTIX
39  use sll_m_pastix
40 #endif /* PASTIX */
41 
42 #ifdef MUMPS
43  use sll_m_mumps
44 #endif /* MUMPS */
45 
46  implicit none
47 
48  public :: &
61  sll_p_umfpack, &
62  sll_p_pastix, &
64 
65  private
66 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
69  sll_int32 :: num_rows
70  sll_int32 :: num_cols
71  sll_int32 :: num_nz
72  sll_int32, pointer :: row_ptr(:)
73  sll_int32, pointer :: col_ind(:)
74  sll_real64, pointer :: val(:)
75  sll_int32 :: solver = 0
76 
77 #ifdef UMFPACK
78  integer(umf_void) :: umf_symbolic
79  integer(umf_void) :: umf_numeric
80  sll_real64, dimension(:), pointer :: umf_control
81 #endif /* UMFPACK */
82 
83 #ifdef PASTIX
84  type(pastix_solver) :: pstx
85 #endif
86 #ifdef MUMPS
87  type(mumps_solver) :: mmps
88 #endif
89 
90  end type sll_t_csr_matrix
91 
92  sll_int32, parameter :: sll_p_umfpack = 1
93  sll_int32, parameter :: sll_p_pastix = 2
94  sll_int32, parameter :: sll_p_mumps = 3
95 
97  module procedure new_csr_matrix_with_dof
98  end interface sll_f_new_csr_matrix
99 
100 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
101 contains
102 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
103 
104  subroutine sll_s_free_csr_matrix(mat)
105  type(sll_t_csr_matrix), pointer :: mat
106  if (associated(mat)) nullify (mat)
107  end subroutine sll_s_free_csr_matrix
108 
124  num_rows, &
125  num_cols, &
126  num_elts, &
127  local_to_global_row, &
128  num_local_dof_row, &
129  local_to_global_col, &
130  num_local_dof_col, &
131  solver) result(mat)
132 
133  type(sll_t_csr_matrix), pointer :: mat
134  sll_int32, intent(in) :: num_rows
135  sll_int32, intent(in) :: num_cols
136  sll_int32, intent(in) :: num_elts
137  sll_int32, dimension(:, :), intent(in) :: local_to_global_row
138  sll_int32, dimension(:, :), intent(in) :: local_to_global_col
139  sll_int32, intent(in) :: num_local_dof_row
140  sll_int32, intent(in) :: num_local_dof_col
141  sll_int32, optional :: solver
142 
143  sll_int32 :: ierr
144 
145  sll_allocate(mat, ierr)
146 
147  mat%solver = 0
148  if (present(solver)) then
149 #ifdef UMFPACK
150  if (solver == sll_p_umfpack) mat%solver = solver
151 #endif /* UMFPACK */
152 #ifdef PASTIX
153  if (solver == sll_p_pastix) mat%solver = solver
154 #endif /* PASTIX */
155 #ifdef MUMPS
156  if (solver == sll_p_mumps) mat%solver = solver
157 #endif /* MUMPS */
158  end if
159 
160  call sll_s_csr_matrix_init( &
161  mat, &
162  num_rows, &
163  num_cols, &
164  num_elts, &
165  local_to_global_row, &
166  num_local_dof_row, &
167  local_to_global_col, &
168  num_local_dof_col)
169 
170  end function new_csr_matrix_with_dof
171 
184 
185  subroutine sll_s_csr_matrix_init(mat, &
186  num_rows, &
187  num_cols, &
188  num_elts, &
189  local_to_global_row, &
190  num_local_dof_row, &
191  local_to_global_col, &
192  num_local_dof_col)
193 
194  type(sll_t_csr_matrix), intent(inout) :: mat
195  sll_int32, intent(in) :: num_rows
196  sll_int32, intent(in) :: num_cols
197  sll_int32, intent(in) :: num_elts
198  sll_int32, dimension(:, :), intent(in) :: local_to_global_row
199  sll_int32, intent(in) :: num_local_dof_row
200  sll_int32, dimension(:, :), intent(in) :: local_to_global_col
201  sll_int32, intent(in) :: num_local_dof_col
202 
203  sll_int32 :: num_nz
204  sll_int32 :: ierr
205  sll_int32, dimension(:, :), allocatable :: lpi_col
206  sll_int32, dimension(:), allocatable :: lpi_occ
207  sll_int32 :: coef
208  sll_int32 :: elt
209  sll_int32 :: ii
210  sll_int32 :: jj
211  sll_int32 :: row
212  sll_int32 :: col
213  sll_int32 :: i
214  sll_int32 :: sz
215  logical :: ll_done
216 
217 #ifdef DEBUG
218  print *, '#sll_s_csr_matrix_init'
219 #endif
220 
221  coef = 6
222 
223  sll_allocate(lpi_col(num_rows, 0:coef*num_local_dof_col), ierr)
224  sll_allocate(lpi_occ(num_rows + 1), ierr)
225 
226  lpi_col(:, :) = 0
227  lpi_occ(:) = 0
228 
229  do elt = 1, num_elts !Loop over cells
230  do ii = 1, num_local_dof_row
231  row = local_to_global_row(ii, elt) !Row number in matrix
232  if (row /= 0) then
233  do jj = 1, num_local_dof_col
234  col = local_to_global_col(jj, elt) !Column number in matrix
235  if (col /= 0) then
236  ll_done = .false.
237  ! WE CHECK IF IT IS THE FIRST OCCURANCE OF THE COUPLE (row, col)
238  do i = 1, lpi_col(row, 0)
239  if (lpi_col(row, i) == col) then
240  ll_done = .true.
241  exit
242  end if
243  end do
244  if (.not. ll_done) then
245  lpi_occ(row) = lpi_occ(row) + 1
246  lpi_col(row, 0) = lpi_col(row, 0) + 1
247  lpi_col(row, lpi_col(row, 0)) = col
248  end if
249  end if
250  end do
251  end if
252  end do
253  end do
254 
255 ! COUNT NON ZERO ELEMENTS
256  num_nz = sum(lpi_occ(1:num_rows))
257 
258  mat%num_rows = num_rows
259  mat%num_cols = num_cols
260  mat%num_nz = num_nz
261 
262 #ifdef DEBUG
263  print *, '#solver =', mat%solver
264  print *, '#num_rows=', num_rows
265  print *, '#num_cols=', num_cols
266  print *, '#num_nz =', num_nz
267 #endif
268 
269  sll_allocate(mat%row_ptr(num_rows + 1), ierr)
270  sll_allocate(mat%col_ind(num_nz), ierr)
271  sll_allocate(mat%val(num_nz), ierr)
272 
273  mat%row_ptr(1) = 1
274 
275  do i = 1, mat%num_rows
276  mat%row_ptr(i + 1) = mat%row_ptr(1) + sum(lpi_occ(1:i))
277  end do
278 
279  do elt = 1, num_elts
280  do ii = 1, num_local_dof_row
281  row = local_to_global_row(ii, elt)
282  if (row /= 0) then
283  if (lpi_col(row, 0) /= 0) then
284  sz = lpi_col(row, 0)
285  call sll_s_qsortc(lpi_col(row, 1:sz))
286  do i = 1, sz
287  mat%col_ind(mat%row_ptr(row) + i - 1) = lpi_col(row, i)
288  end do
289  lpi_col(row, 0) = 0
290  end if
291  end if
292  end do
293  end do
294 
295  mat%val(:) = 0.0_f64
296  sll_deallocate_array(lpi_col, ierr)
297  sll_deallocate_array(lpi_occ, ierr)
298 
299  select case (mat%solver)
300 
301  case (sll_p_umfpack)
302 
303 #ifdef UMFPACK
304  sll_allocate(mat%umf_control(umfpack_control), ierr)
305  mat%row_ptr = mat%row_ptr - 1
306  mat%col_ind = mat%col_ind - 1
307  call umf4def(mat%umf_control) ! get the default configuration
308 #endif /* UMFPACK */
309 
310  case (sll_p_pastix)
311 
312 #ifdef PASTIX
313  call initialize(mat%pstx, num_rows, num_nz, mat%row_ptr, mat%col_ind, mat%val)
314 #endif /* PASTIX */
315 
316  case (sll_p_mumps)
317 
318 #ifdef MUMPS
319  call initialize(mat%mmps, num_rows, num_nz, mat%row_ptr, mat%col_ind, mat%val)
320 #endif /* MUMPS */
321 
322  end select
323 
324  end subroutine sll_s_csr_matrix_init
325 
327 
328  type(sll_t_csr_matrix), intent(inout) :: mat
329  type(sll_t_csr_matrix), intent(in) :: mat_a
330  sll_int32 :: ierr
331 
332  mat%num_nz = mat_a%num_nz + 2*mat_a%num_rows
333  mat%num_rows = mat_a%num_rows + 1
334  mat%num_cols = mat_a%num_cols + 1
335 #ifdef DEBUG
336  print *, '# sll_s_csr_matrix_with_constraint_init'
337  print *, '# num_nz mat, num_nz mat_tot', mat_a%num_nz, mat%num_nz
338  print *, '# num_rows mat, num_rows mat_tot', mat_a%num_rows, mat%num_rows
339  print *, '# num_cols mat, num_cols mat_tot', mat_a%num_cols, mat%num_cols
340 #endif /* DEBUG */
341 
342  sll_allocate(mat%row_ptr(mat%num_rows + 1), ierr)
343  sll_allocate(mat%col_ind(mat%num_nz), ierr)
344  sll_clear_allocate(mat%val(1:mat%num_nz), ierr)
345 
346  mat%solver = mat_a%solver
347 
348  select case (mat%solver)
349 #ifdef UMFPACK
350  case (sll_p_umfpack)
351  sll_allocate(mat%umf_control(umfpack_control), ierr)
352  call umf4def(mat%umf_control)
353 #endif /* UMFPACK */
354  case (sll_p_pastix)
355 #ifdef PASTIX
356  call initialize(mat%pstx, mat%num_rows, mat%num_nz, mat%row_ptr, &
357  mat%col_ind, mat%val)
358 #endif /* PASTIX */
359  case (sll_p_mumps)
360 #ifdef MUMPS
361  call initialize(mat%mmps, mat%num_rows, mat%num_nz, mat%row_ptr, mat%col_ind, mat%val)
362 #endif /* MUMPS */
363  end select
364 
366 
367  function sll_f_new_csr_matrix_with_constraint(mat_a) result(mat)
368 
369  type(sll_t_csr_matrix), pointer :: mat
370  type(sll_t_csr_matrix) :: mat_a
371 
372  sll_int32 :: ierr
373  sll_allocate(mat, ierr)
375 
377 
378  subroutine sll_s_csr_add_one_constraint(ia_in, &
379  ja_in, &
380  a_in, &
381  num_rows_in, &
382  num_nz_in, &
383  constraint_vec, &
384  ia_out, &
385  ja_out, &
386  a_out)
387 
388  integer, dimension(:), intent(in) :: ia_in
389  integer, dimension(:), intent(in) :: ja_in
390  real(8), dimension(:), intent(in) :: a_in
391  integer, intent(in) :: num_rows_in
392  integer, intent(in) :: num_nz_in
393  real(8), dimension(:), intent(in) :: constraint_vec
394  integer, dimension(:), intent(out) :: ia_out
395  integer, dimension(:), intent(out) :: ja_out
396  real(8), dimension(:), intent(out) :: a_out
397 
398  integer :: num_rows_out
399  integer :: num_nz_out
400  integer :: i
401  integer :: s
402  integer :: k
403 
404  num_rows_out = num_rows_in + 1
405  num_nz_out = num_nz_in + 2*num_rows_in
406 
407  sll_assert(size(ia_in) >= num_rows_in + 1)
408  sll_assert(size(ja_in) >= num_nz_in)
409  sll_assert(size(a_in) >= num_nz_in)
410  sll_assert(size(ia_out) >= num_rows_out + 1)
411  sll_assert(size(ja_out) == num_nz_out)
412  sll_assert(size(a_out) >= num_nz_out)
413 
414  if (ia_in(num_rows_in + 1) == num_nz_in) then ! UMFPACK
415 
416  s = 1
417  do i = 1, num_rows_in
418  ia_out(i) = s - 1
419  do k = ia_in(i) + 1, ia_in(i + 1)
420  a_out(s) = a_in(k)
421  ja_out(s) = ja_in(k)
422  s = s + 1
423  end do
424  a_out(s) = constraint_vec(i)
425  ja_out(s) = num_rows_out - 1
426  s = s + 1
427  end do
428  ia_out(num_rows_in + 1) = s - 1
429  do i = 1, num_rows_in
430  a_out(s) = constraint_vec(i)
431  ja_out(s) = i - 1
432  s = s + 1
433  end do
434  ia_out(num_rows_in + 2) = s - 1
435 
436  sll_assert(ia_out(num_rows_out + 1) == num_nz_out)
437 
438  else ! Default CG
439 
440  sll_assert(ia_in(num_rows_in + 1) == num_nz_in + 1)
441 
442  s = 1
443  do i = 1, num_rows_in
444  ia_out(i) = s
445  do k = ia_in(i), ia_in(i + 1) - 1
446  a_out(s) = a_in(k)
447  ja_out(s) = ja_in(k)
448  s = s + 1
449  end do
450  a_out(s) = constraint_vec(i)
451  ja_out(s) = num_rows_out
452  s = s + 1
453  end do
454  ia_out(num_rows_in + 1) = s
455  do i = 1, num_rows_in
456  a_out(s) = constraint_vec(i)
457  ja_out(s) = i
458  s = s + 1
459  end do
460  ia_out(num_rows_in + 2) = s
461 
462  sll_assert(ia_in(num_rows_in + 1) == num_nz_in + 1)
463 
464  end if
465 
466  end subroutine sll_s_csr_add_one_constraint
467 
469 
470  type(sll_t_csr_matrix), intent(inout) :: mat
471 
472 #ifdef UMFPACK
473  sll_real64, dimension(umfpack_info) :: info
474 #endif /* UMFPACK */
475 #ifdef MUMPS
476  sll_int32 :: i, k, l
477 #endif /* MUMPS */
478 
479 #ifdef DEBUG
480  call print_solver_type(mat)
481  print *, '# begin factorize_csr_matrix '
482 #endif /* DEBUG */
483 
484  select case (mat%solver)
485 
486  case (sll_p_umfpack)
487 
488 #ifdef UMFPACK
489  ! pre-order and symbolic analysis
490  call umf4sym(mat%num_rows, &
491  mat%num_cols, &
492  mat%row_ptr, &
493  mat%col_ind, &
494  mat%val, &
495  mat%umf_symbolic, &
496  mat%umf_control, &
497  info)
498 
499  if (info(1) .lt. 0) then
500  print *, '#Error occurred in umf4sym: ', info(1)
501  stop
502  end if
503 
504  ! numeric factorization
505  call umf4num(mat%row_ptr, &
506  mat%col_ind, &
507  mat%val, &
508  mat%umf_symbolic, &
509  mat%umf_numeric, &
510  mat%umf_control, &
511  info)
512 
513  if (info(1) .lt. 0) then
514  print *, '#Error occurred in umf4num: ', info(1)
515  stop
516  end if
517 #endif /* UMFPACK */
518 
519  case (sll_p_pastix)
520 
521 #ifdef PASTIX
522  call factorize(mat%pstx)
523 #endif /* PASTIX */
524 
525  case (sll_p_mumps)
526 
527 #ifdef MUMPS
528  l = 0
529  do i = 1, mat%num_rows
530  do k = mat%row_ptr(i), mat%row_ptr(i + 1) - 1
531  l = l + 1
532  mat%mmps%mumps_par%irn(l) = i
533  mat%mmps%mumps_par%jcn(l) = mat%col_ind(l)
534  mat%mmps%mumps_par%a(l) = mat%val(l)
535  end do
536  end do
537  call factorize(mat%mmps)
538 #endif /* MUMPS */
539 
540  case default
541 
542  sll_assert(associated(mat%val)) ! Just to avoid warning in debug mode
543 
544  end select
545 
546 #ifdef DEBUG
547  print *, '# end factorize_csr_matrix '
548 #endif /* DEBUG */
549 
550  end subroutine sll_s_factorize_csr_matrix
551 
552  subroutine sll_s_mult_csr_matrix_vector(mat, input, output)
553 
554  type(sll_t_csr_matrix), intent(in) :: mat
555  sll_real64, dimension(:), intent(in) :: input
556  sll_real64, dimension(:), intent(out) :: output
557 
558  sll_int32 :: i
559  sll_int32 :: k_1
560  sll_int32 :: k_2
561 
562  do i = 1, mat%num_rows
563 
564  k_1 = mat%row_ptr(i)
565  k_2 = mat%row_ptr(i + 1) - 1
566 
567  output(i) = dot_product(mat%val(k_1:k_2), input(mat%col_ind(k_1:k_2)))
568 
569  end do
570 
571  end subroutine sll_s_mult_csr_matrix_vector
572 
573  subroutine sll_s_add_to_csr_matrix(mat, val, row, col)
574 
575  type(sll_t_csr_matrix), intent(inout) :: mat
576  sll_real64, intent(in) :: val
577  sll_int32, intent(in) :: row
578  sll_int32, intent(in) :: col
579 
580  sll_int32 :: k
581 
582  if (mat%solver == sll_p_umfpack) then
583  do k = mat%row_ptr(row) + 1, mat%row_ptr(row + 1)
584  if (mat%col_ind(k) + 1 == col) then
585  mat%val(k) = mat%val(k) + val
586  exit
587  end if
588  end do
589  else
590  do k = mat%row_ptr(row), mat%row_ptr(row + 1) - 1
591  if (mat%col_ind(k) == col) then
592  mat%val(k) = mat%val(k) + val
593  exit
594  end if
595  end do
596  end if
597 
598  end subroutine sll_s_add_to_csr_matrix
599 
600  subroutine sll_s_solve_csr_matrix(mat, b, u)
601 
602  type(sll_t_csr_matrix), intent(in) :: mat
603  sll_real64, dimension(:), intent(inout) :: b
604  sll_real64, dimension(:), intent(out) :: u
605 
606 #ifdef UMFPACK
607 
608  sll_int32 :: sys
609  sll_real64, dimension(umfpack_info) :: info
610 
611 #endif
612 
613 #ifdef DEBUG
614  print *, '# begin solve_csr_matrix '
615 #endif /* DEBUG */
616 
617  select case (mat%solver)
618 
619  case (sll_p_umfpack)
620 
621 #ifdef UMFPACK
622  sys = 0
623  call umf4sol(sys, u, b, mat%umf_numeric, mat%umf_control, info)
624 #endif /* UMFPACK */
625 
626  case (sll_p_pastix)
627 
628 #ifdef PASTIX
629  u = b
630  call solve(mat%pstx, u)
631 #endif /* PASTIX */
632 
633  case (sll_p_mumps)
634 
635 #ifdef MUMPS
636  u = b
637  call solve(mat%mmps, u)
638 #endif /* MUMPS */
639 
640  case default
641 
642  call solve_with_cg(mat, b, u)
643 
644  end select
645 
646 #ifdef DEBUG
647  print *, '# end solve_csr_matrix '
648 #endif /* DEBUG */
649 
650  end subroutine sll_s_solve_csr_matrix
651 
652  subroutine sll_s_solve_csr_matrix_perper(mat, b, u, masse_tot)
653 
654  type(sll_t_csr_matrix) :: mat
655  sll_real64, dimension(:) :: u
656  sll_real64, dimension(:) :: b
657  sll_real64, dimension(:), pointer :: masse_tot
658 
659 #ifdef UMFPACK
660 
661  sll_real64, dimension(umfpack_info) :: info
662  sll_int32 :: sys
663 
664 #endif /* UMFPACK */
665 
666  select case (mat%solver)
667 
668  case (sll_p_umfpack)
669 
670 #ifdef UMFPACK
671  sys = 0
672  call umf4sol(sys, u, b, mat%umf_numeric, mat%umf_control, info)
673 #endif /* UMFPACK */
674 
675  case (sll_p_pastix)
676 
677 #ifdef PASTIX
678  u = b
679  call solve(mat%pstx, u)
680 #endif /* PASTIX */
681 
682  case (sll_p_mumps)
683 
684 #ifdef MUMPS
685  u = b
686  call solve(mat%mmps, u)
687 #endif /* MUMPS */
688 
689  case default
690 
691  call solve_with_cg(mat, b, u)
692 
693  end select
694 
695  end subroutine sll_s_solve_csr_matrix_perper
696 
697  subroutine sll_s_csr_todense(mat, dense_matrix)
698 
699  type(sll_t_csr_matrix) :: mat
700  sll_real64, dimension(:, :) :: dense_matrix
701  sll_int32 :: i, j, k, l
702 
703  if (mat%solver == sll_p_umfpack) then
704  l = 0
705  do i = 1, mat%num_rows
706  do k = mat%row_ptr(i) + 1, mat%row_ptr(i + 1)
707  l = l + 1
708  j = mat%col_ind(l) + 1
709  dense_matrix(i, j) = mat%val(l)
710  end do
711  end do
712  else
713  l = 0
714  do i = 1, mat%num_rows
715  do k = mat%row_ptr(i), mat%row_ptr(i + 1) - 1
716  l = l + 1
717  j = mat%col_ind(l)
718  dense_matrix(i, j) = mat%val(l)
719  end do
720  end do
721  end if
722 
723  end subroutine sll_s_csr_todense
724 
725  subroutine solve_with_cg(mat, b, u)
726 
727  type(sll_t_csr_matrix) :: mat
728  sll_real64, dimension(:) :: u
729  sll_real64, dimension(:) :: b
730 
731  sll_int32 :: maxiter
732  sll_real64 :: eps
733 
734  sll_real64, dimension(:), allocatable :: ad
735  sll_real64, dimension(:), allocatable :: d
736 
737  sll_real64 :: norm2r1
738  sll_real64 :: norm2r0
739  sll_real64 :: norminfb
740  sll_real64 :: norminfr
741  sll_real64 :: ps
742  sll_real64 :: beta
743  sll_real64 :: alpha
744  sll_int32 :: iter
745  sll_int32 :: err
746 
747  eps = 1.d-13
748  maxiter = 10000
749 
750  if (mat%num_rows /= mat%num_cols) then
751  print *, '#ERROR Gradient_conj: The matrix must be square'
752  stop
753  end if
754 
755  if ((abs(maxval(b)) < eps) .AND. (abs(minval(b)) < eps)) then
756  u = 0.0_f64
757  return
758  end if
759 
760  sll_allocate(ad(mat%num_rows), err)
761  sll_allocate(d(mat%num_rows), err)
762 
763  u = 0.0_f64
764  iter = 0
765 
766  norminfb = maxval(abs(b))
767  norm2r0 = dot_product(b, b)
768 
769  d = b
770 
771  do iter = 1, maxiter
772  !--------------------------------------!
773  ! calcul du ak parametre optimal local !
774  !--------------------------------------!
775 
776  call sll_s_mult_csr_matrix_vector(mat, d, ad)
777 
778  ps = dot_product(ad, d)
779  alpha = norm2r0/ps
780 
781  !==================================================!
782  ! calcul de l'approximation Xk+1 et du residu Rk+1 !
783  !==================================================!
784  ! calcul des composantes residuelles
785  !-----------------------------------
786  b = b - alpha*ad
787 
788  !----------------------------------------!
789  ! approximations ponctuelles au rang k+1 !
790  !----------------------------------------!
791  u = u + alpha*d
792 
793  !-------------------------------------------------------!
794  ! (a) extraction de la norme infinie du residu !
795  ! pour le test d'arret !
796  ! (b) extraction de la norme euclidienne du residu rk+1 !
797  !-------------------------------------------------------!
798  norminfr = maxval(abs(b))
799  norm2r1 = dot_product(b, b)
800 
801  !==================================================!
802  ! calcul de la nouvelle direction de descente dk+1 !
803  !==================================================!
804  beta = norm2r1/norm2r0
805  norm2r0 = norm2r1
806  d = b + beta*d
807 
808  !-------------------!
809  ! boucle suivante ? !
810  !-------------------!
811  if (norminfr/norminfb < eps) exit
812 
813  end do
814 
815  if (iter == maxiter) then
816  print *, 'Warning Gradient_conj : iter == maxIter'
817  print *, 'Error after CG =', (norminfr/norminfb)
818  end if
819 
820  deallocate (ad)
821  deallocate (d)
822 
823  end subroutine solve_with_cg
824 
825  subroutine print_solver_type(mat)
826 
827  type(sll_t_csr_matrix) :: mat
828 
829  print *, 'print_solver =', mat%solver
830  select case (mat%solver)
831  case (sll_p_umfpack)
832  print *, "# We use UMFPACK to solve the system "
833  case (sll_p_pastix)
834  print *, "# We use PASTIX to solve the system "
835  case (sll_p_mumps)
836  print *, "# We use MUMPS to solve the system "
837  case default
838  print *, "# We use CG to solve the system "
839  end select
840 
841  end subroutine print_solver_type
842 
843 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_csr_todense(mat, dense_matrix)
subroutine solve_with_cg(mat, b, u)
type(sll_t_csr_matrix) function, pointer new_csr_matrix_with_dof(num_rows, num_cols, num_elts, local_to_global_row, num_local_dof_row, local_to_global_col, num_local_dof_col, solver)
allocates the memory space for a new CSR matrix,
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)
integer(kind=i32), parameter, public sll_p_pastix
subroutine, public sll_s_solve_csr_matrix(mat, b, u)
subroutine print_solver_type(mat)
integer(kind=i32), parameter, public sll_p_mumps
integer(kind=i32), parameter, public sll_p_umfpack
subroutine, public sll_s_factorize_csr_matrix(mat)
subroutine, public sll_s_free_csr_matrix(mat)
subroutine, public sll_s_solve_csr_matrix_perper(mat, b, u, masse_tot)
subroutine, public sll_s_csr_matrix_with_constraint_init(mat, mat_a)
    Report Typos and Errors