SpM Handbook 1.2.4
Loading...
Searching...
No Matches
spmf_user.F90
Go to the documentation of this file.
1!>
2!> @file spmf_user.F90
3!>
4!> @brief Fortran 90 example where the user provides its own matrix in IJV format
5!>
6!> Fortran 90 example using a laplacian matrix.
7!>
8!> @copyright 2015-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
9!> Univ. Bordeaux. All rights reserved.
10!>
11!> @version 1.2.4
12!> @author Mathieu Faverge
13!> @author Alycia Lisito
14!> @date 2024-05-29
15!>
16!> @ingroup examples_fortran
17!>
18#ifndef DOXYGEN_SHOULD_SKIP_THIS
19program spmf_user
20 use iso_c_binding
21 use spmf
22#if defined(SPM_WITH_MPI)
23 use mpi_f08
24#endif
25 implicit none
26
27 integer(kind=spm_int_t), dimension(:), pointer :: rowptr
28 integer(kind=spm_int_t), dimension(:), pointer :: colptr
29 real(kind=c_double), dimension(:), pointer :: values
30 real(kind=c_double), dimension(:,:), allocatable, target :: x0, x, b
31 real(kind=c_double) :: eps = 1.e-15
32 type(spmatrix_t), target :: spm
33 integer(kind=spm_int_t) :: dim1, dim2, dim3, n, nnz
34 integer(kind=spm_int_t) :: i, j, k, l, nrhs
35 integer(c_int) :: info
36
37#if defined(SPM_WITH_MPI)
38 ! SPM is compiled with MPI, thus MPI must be initialized
39 ! before any spm call
40 call mpi_init( info )
41#endif
42
43 !
44 ! Generate a 10x10x10 complex Laplacian in IJV format
45 !
46 dim1 = 10
47 dim2 = 10
48 dim3 = 10
49 n = dim1 * dim2 * dim3
50 nnz = (2*(dim1)-1) * dim2 * dim3 + (dim2-1)*dim1*dim3 + dim2*dim1*(dim3-1)
51
52 !
53 ! Create the spm out of the internal data
54 !
55 call spminit( spm )
56 spm%baseval = 1
57 spm%mtxtype = spmsymmetric
58 spm%flttype = spmdouble
59 spm%fmttype = spmijv
60 spm%n = n
61 spm%nnz = nnz
62 spm%dof = 1
63
64 call spmupdatecomputedfields( spm )
65 call spmalloc( spm )
66
67 call spmgetarray( spm, colptr=colptr, rowptr=rowptr, dvalues=values )
68
69 l = 1
70 do i=1,dim1
71 do j=1,dim2
72 do k=1,dim3
73 rowptr(l) = (i-1) + dim1 * (j-1) + dim1 * dim2 * (k-1) + 1
74 colptr(l) = (i-1) + dim1 * (j-1) + dim1 * dim2 * (k-1) + 1
75 values(l) = 6.
76
77 if (i == 1) then
78 values(l) = values(l) - 1.
79 end if
80 if (i == dim1) then
81 values(l) = values(l) - 1.
82 end if
83 if (j == 1) then
84 values(l) = values(l) - 1.
85 end if
86 if (j == dim2) then
87 values(l) = values(l) - 1.
88 end if
89 if (k == 1) then
90 values(l) = values(l) - 1.
91 end if
92 if (k == dim3) then
93 values(l) = values(l) - 1.
94 end if
95
96 values(l) = values(l) * 8.
97 l = l + 1
98
99 if (i < dim1) then
100 rowptr(l) = i + dim1 * (j-1) + dim1 * dim2 * (k-1) + 1
101 colptr(l) = (i-1) + dim1 * (j-1) + dim1 * dim2 * (k-1) + 1
102 values(l) = - 1.
103 l = l + 1
104 end if
105 if (j < dim2) then
106 rowptr(l) = (i-1) + dim1 * j + dim1 * dim2 * (k-1) + 1
107 colptr(l) = (i-1) + dim1 * (j-1) + dim1 * dim2 * (k-1) + 1
108 values(l) = - 1.
109 l = l + 1
110 end if
111 if (k < dim3) then
112 rowptr(l) = (i-1) + dim1 * (j-1) + dim1 * dim2 * k + 1
113 colptr(l) = (i-1) + dim1 * (j-1) + dim1 * dim2 * (k-1) + 1
114 values(l) = -1.
115 l = l + 1
116 end if
117 end do
118 end do
119 end do
120
121 if ( l .ne. nnz+1 ) then
122 write(6,*) 'l ', l, " nnz ", nnz
123 end if
124
125 call spmprintinfo( spm )
126
127 ! 2- The right hand side
128 nrhs = 10
129 allocate(x0(spm%nexp, nrhs))
130 allocate(x( spm%nexp, nrhs))
131 allocate(b( spm%nexp, nrhs))
132
133 ! Compute b = A * x, with x random
134 call spmgenrhs( spmrhsrndx, nrhs, spm, x0, spm%nexp, b, spm%nexp, info )
135
136 ! Copy x0 into x
137 x = x0
138
139 !
140 ! Check the solution
141 !
142 call spmcheckaxb( eps, nrhs, spm, x0, spm%nexp, b, spm%nexp, x, spm%nexp, info )
143
144 call spmexit( spm )
145 deallocate(x0)
146 deallocate(x)
147 deallocate(b)
148
149#if defined(SPM_WITH_MPI)
150 call mpi_finalize( info )
151#endif
152
153end program spmf_user
154
155#endif