bspline/m_bspline_matrix.f90
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | !> The B-spline matrix module | ||
| 2 | !> | ||
| 3 | !> This module provides functions to compute matrices related to B-spline spaces, such as mass and divgrad | ||
| 4 | module m_bspline_matrix | ||
| 5 | #include "petsc.fi" | ||
| 6 | implicit none | ||
| 7 | |||
| 8 | private | ||
| 9 | public :: mass_matrix, divgrad_matrix | ||
| 10 | |||
| 11 | !> @brief Compute the mass matrix of two B-spline spaces | ||
| 12 | interface mass_matrix | ||
| 13 | module procedure mass_matrix_1d | ||
| 14 | end interface | ||
| 15 | |||
| 16 | !> @brief Compute the divgrad matrix of a B-spline basis (i.e., the discretization of the Laplace operator) | ||
| 17 | interface divgrad_matrix | ||
| 18 | module procedure divgrad_matrix_1d | ||
| 19 | end interface | ||
| 20 | contains | ||
| 21 | |||
| 22 | !> @brief Compute the mass matrix of two B-spline spaces | ||
| 23 | !> | ||
| 24 | !> @param[out] M The mass matrix | ||
| 25 | !> @param[in] bspline1 The first B-spline spaces | ||
| 26 | !> @param[in] bspline2 The second B-spline spaces | ||
| 27 | !> @param[in] coordfun _(optional)_ The coordinate function | ||
| 28 | !> @param[in] n_quad_extra _(optional)_ The additional number of quadrature points on top of those needed for exact integration of | ||
| 29 | !> the B-spline spaces | ||
| 30 | 7716 | subroutine mass_matrix_1d(M, bspline1, bspline2, coordfun, n_quad_extra) | |
| 31 | use m_common, only: wp, user_function_1d_interface | ||
| 32 | use m_bspline_basis, only: BSplineSpace, size, get_internal_and_actual_inds | ||
| 33 | use m_bspline_quadrature, only: BSplineQuadrature, quadrature_product, n_quad_exact, DEFAULT_EXTRA_QUADRATURE_POINTS | ||
| 34 | |||
| 35 | implicit none | ||
| 36 | |||
| 37 | Mat, intent(out) :: M | ||
| 38 | type(BSplineSpace), intent(in) :: bspline1, bspline2 | ||
| 39 | procedure(user_function_1d_interface), optional :: coordfun | ||
| 40 | integer, intent(in), optional :: n_quad_extra | ||
| 41 | |||
| 42 | 7716 | type(BSplineQuadrature) :: bspline1_quad, bspline2_quad | |
| 43 | integer :: ierr, n_quad, n_quad_extra_ | ||
| 44 | integer :: j1, j2, j1_internal, j2_internal, j1_minus_i, j2_minus_i, i, ndx | ||
| 45 | integer :: local_nz_per_row, nonlocal_nz_per_row, j2_minus_i_max | ||
| 46 | logical :: bspline_mirrored_1, bspline_mirrored_2, equal_spaces | ||
| 47 | real(wp), allocatable :: vals(:, :), coordfun_vals(:), bspline1_vals(:) | ||
| 48 | integer, allocatable :: cols(:), rows(:) | ||
| 49 | real(wp) :: val, x | ||
| 50 | |||
| 51 | 7716 | n_quad = n_quad_exact(bspline1, bspline2) | |
| 52 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 6 taken 7716 times.
|
7716 | if (present(coordfun)) then |
| 53 | ✗ | if (present(n_quad_extra)) then | |
| 54 | ✗ | n_quad_extra_ = n_quad_extra | |
| 55 | else | ||
| 56 | n_quad_extra_ = DEFAULT_EXTRA_QUADRATURE_POINTS | ||
| 57 | end if | ||
| 58 | ✗ | n_quad = n_quad + n_quad_extra_ | |
| 59 | end if | ||
| 60 | |||
| 61 |
1/2✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 7716 times.
|
7716 | if (bspline1%nr_intervals /= bspline2%nr_intervals) then |
| 62 | ✗ | error stop "B-spline spaces must have the same number of intervals for the computation of the mass matrix" | |
| 63 | end if | ||
| 64 | |||
| 65 |
3/6✓ Branch 10 → 11 taken 7716 times.
✗ Branch 10 → 12 not taken.
✓ Branch 12 → 13 taken 7716 times.
✗ Branch 12 → 14 not taken.
✓ Branch 14 → 15 taken 7716 times.
✗ Branch 14 → 16 not taken.
|
7716 | bspline1_quad = BSplineQuadrature(bspline1, n_quad) |
| 66 |
3/6✓ Branch 18 → 19 taken 7716 times.
✗ Branch 18 → 20 not taken.
✓ Branch 20 → 21 taken 7716 times.
✗ Branch 20 → 22 not taken.
✓ Branch 22 → 23 taken 7716 times.
✗ Branch 22 → 24 not taken.
|
7716 | bspline2_quad = BSplineQuadrature(bspline2, n_quad) |
| 67 | |||
| 68 | ! Create a sparse matrix | ||
| 69 | 7716 | local_nz_per_row = 1 + bspline1%degree + bspline2%degree | |
| 70 | 7716 | nonlocal_nz_per_row = 0 ! NOTE: sequential | |
| 71 | call MatCreateAIJ(PETSC_COMM_SELF, size(bspline1), & | ||
| 72 | & size(bspline2), size(bspline1), & | ||
| 73 | & size(bspline2), local_nz_per_row, PETSC_NULL_INTEGER_ARRAY, nonlocal_nz_per_row, & | ||
| 74 |
1/2✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 7716 times.
|
7716 | & PETSC_NULL_INTEGER_ARRAY, M, ierr); CHKERRQ(ierr) |
| 75 | |||
| 76 |
8/16✗ Branch 27 → 28 not taken.
✓ Branch 27 → 29 taken 7716 times.
✓ Branch 29 → 28 taken 7716 times.
✗ Branch 29 → 30 not taken.
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 32 taken 7716 times.
✓ Branch 32 → 31 taken 7716 times.
✗ Branch 32 → 33 not taken.
✓ Branch 33 → 34 taken 7716 times.
✗ Branch 33 → 35 not taken.
✓ Branch 35 → 36 taken 7716 times.
✗ Branch 35 → 37 not taken.
✗ Branch 37 → 38 not taken.
✓ Branch 37 → 39 taken 7716 times.
✗ Branch 39 → 40 not taken.
✓ Branch 39 → 41 taken 7716 times.
|
30864 | allocate (vals(0:bspline2%degree, 0:bspline1%degree)) |
| 77 |
6/12✗ Branch 41 → 42 not taken.
✓ Branch 41 → 43 taken 7716 times.
✓ Branch 43 → 42 taken 7716 times.
✗ Branch 43 → 44 not taken.
✓ Branch 44 → 45 taken 7716 times.
✗ Branch 44 → 46 not taken.
✓ Branch 46 → 47 taken 7716 times.
✗ Branch 46 → 48 not taken.
✗ Branch 48 → 49 not taken.
✓ Branch 48 → 50 taken 7716 times.
✗ Branch 50 → 51 not taken.
✓ Branch 50 → 52 taken 7716 times.
|
23148 | allocate (cols(0:bspline2%degree)) |
| 78 |
6/12✗ Branch 52 → 53 not taken.
✓ Branch 52 → 54 taken 7716 times.
✓ Branch 54 → 53 taken 7716 times.
✗ Branch 54 → 55 not taken.
✓ Branch 55 → 56 taken 7716 times.
✗ Branch 55 → 57 not taken.
✓ Branch 57 → 58 taken 7716 times.
✗ Branch 57 → 59 not taken.
✗ Branch 59 → 60 not taken.
✓ Branch 59 → 61 taken 7716 times.
✗ Branch 61 → 62 not taken.
✓ Branch 61 → 63 taken 7716 times.
|
23148 | allocate (rows(0:bspline1%degree)) |
| 79 | |||
| 80 |
6/12✗ Branch 63 → 64 not taken.
✓ Branch 63 → 65 taken 7716 times.
✓ Branch 65 → 64 taken 7716 times.
✗ Branch 65 → 66 not taken.
✓ Branch 66 → 67 taken 7716 times.
✗ Branch 66 → 68 not taken.
✓ Branch 68 → 69 taken 7716 times.
✗ Branch 68 → 70 not taken.
✗ Branch 70 → 71 not taken.
✓ Branch 70 → 72 taken 7716 times.
✗ Branch 72 → 73 not taken.
✓ Branch 72 → 74 taken 7716 times.
|
23148 | allocate (coordfun_vals(1:n_quad)) |
| 81 |
2/2✓ Branch 74 → 75 taken 39116 times.
✓ Branch 74 → 76 taken 7716 times.
|
46832 | coordfun_vals = 1._wp |
| 82 | |||
| 83 |
4/8✗ Branch 76 → 77 not taken.
✓ Branch 76 → 78 taken 7716 times.
✓ Branch 78 → 77 taken 7716 times.
✗ Branch 78 → 79 not taken.
✗ Branch 79 → 80 not taken.
✓ Branch 79 → 81 taken 7716 times.
✗ Branch 81 → 82 not taken.
✓ Branch 81 → 83 taken 7716 times.
|
15432 | allocate (bspline1_vals(1:n_quad)) |
| 84 | |||
| 85 | equal_spaces = size(bspline1) == size(bspline2) .and. & | ||
| 86 | (bspline1%is_scaled .eqv. bspline2%is_scaled) .and. & | ||
| 87 |
2/4✓ Branch 83 → 84 taken 7716 times.
✗ Branch 83 → 85 not taken.
✗ Branch 84 → 85 not taken.
✓ Branch 84 → 86 taken 7716 times.
|
7716 | (bspline1%is_periodic .eqv. bspline2%is_periodic) |
| 88 | |||
| 89 |
1/2✗ Branch 87 → 88 not taken.
✓ Branch 87 → 90 taken 7716 times.
|
7716 | PetscCall(MatSetFromOptions(M, ierr)) |
| 90 |
1/2✓ Branch 90 → 91 taken 7716 times.
✗ Branch 90 → 97 not taken.
|
7716 | if (equal_spaces) then |
| 91 |
1/2✗ Branch 92 → 93 not taken.
✓ Branch 92 → 94 taken 7716 times.
|
7716 | PetscCall(MatSetOption(M, MAT_SYMMETRIC, PETSC_TRUE, ierr)) |
| 92 |
1/2✗ Branch 95 → 96 not taken.
✓ Branch 95 → 97 taken 7716 times.
|
7716 | PetscCall(MatSetOption(M, MAT_SPD, PETSC_TRUE, ierr)) |
| 93 | end if | ||
| 94 |
1/2✗ Branch 98 → 99 not taken.
✓ Branch 98 → 100 taken 7716 times.
|
7716 | PetscCall(MatSetUp(M, ierr)) |
| 95 | |||
| 96 |
2/2✓ Branch 101 → 102 taken 172270 times.
✓ Branch 101 → 175 taken 7716 times.
|
179986 | do i = 0, bspline1%nr_intervals - 1 |
| 97 |
1/2✗ Branch 102 → 103 not taken.
✓ Branch 102 → 107 taken 172270 times.
|
172270 | if (present(coordfun)) then |
| 98 | ✗ | do ndx = 1, n_quad | |
| 99 | ✗ | x = (i + .5_wp + bspline1_quad%nodes(ndx) / 2) * bspline1_quad%bspline%h | |
| 100 | ✗ | coordfun_vals(ndx) = coordfun(x) | |
| 101 | end do | ||
| 102 | end if | ||
| 103 |
2/2✓ Branch 108 → 109 taken 860030 times.
✓ Branch 108 → 149 taken 172270 times.
|
1032300 | do j1_minus_i = 0, bspline1%degree |
| 104 | 860030 | call get_internal_and_actual_inds(bspline1, i, j1_minus_i, j1, j1_internal, bspline_mirrored_1) | |
| 105 |
2/2✓ Branch 110 → 111 taken 52765 times.
✓ Branch 110 → 119 taken 807265 times.
|
860030 | if (bspline_mirrored_1) then |
| 106 |
4/8✓ Branch 111 → 112 taken 52765 times.
✗ Branch 111 → 113 not taken.
✗ Branch 112 → 113 not taken.
✓ Branch 112 → 116 taken 52765 times.
✗ Branch 113 → 114 not taken.
✗ Branch 113 → 115 not taken.
✓ Branch 117 → 118 taken 372215 times.
✓ Branch 117 → 127 taken 52765 times.
|
477745 | bspline1_vals = bspline1_quad%bspline_at_nodes(j1_internal, bspline1%degree - j1_minus_i)%data(n_quad:1:-1) |
| 107 | else | ||
| 108 |
4/8✓ Branch 119 → 120 taken 807265 times.
✗ Branch 119 → 121 not taken.
✗ Branch 120 → 121 not taken.
✓ Branch 120 → 124 taken 807265 times.
✗ Branch 121 → 122 not taken.
✗ Branch 121 → 123 not taken.
✓ Branch 125 → 126 taken 4206223 times.
✓ Branch 125 → 127 taken 807265 times.
|
5820753 | bspline1_vals = bspline1_quad%bspline_at_nodes(j1_internal, j1_minus_i)%data(1:n_quad) |
| 109 | end if | ||
| 110 |
3/4✗ Branch 127 → 128 not taken.
✓ Branch 127 → 129 taken 860030 times.
✓ Branch 130 → 131 taken 4578438 times.
✓ Branch 130 → 132 taken 860030 times.
|
6298498 | bspline1_vals = bspline1_vals * bspline1_quad%weights |
| 111 | |||
| 112 |
1/2✗ Branch 132 → 133 not taken.
✓ Branch 132 → 134 taken 860030 times.
|
860030 | if (equal_spaces) then |
| 113 | j2_minus_i_max = j1_minus_i | ||
| 114 | else | ||
| 115 | j2_minus_i_max = bspline2%degree | ||
| 116 | end if | ||
| 117 |
2/2✓ Branch 135 → 136 taken 2719234 times.
✓ Branch 135 → 147 taken 860030 times.
|
3579264 | do j2_minus_i = 0, j2_minus_i_max |
| 118 | 2719234 | call get_internal_and_actual_inds(bspline2, i, j2_minus_i, j2, j2_internal, bspline_mirrored_2) | |
| 119 | |||
| 120 | val = 0._wp | ||
| 121 |
2/2✓ Branch 137 → 138 taken 141660 times.
✓ Branch 137 → 140 taken 2577574 times.
|
2719234 | if (bspline_mirrored_2) then |
| 122 |
2/2✓ Branch 138 → 139 taken 1051512 times.
✓ Branch 138 → 143 taken 141660 times.
|
1193172 | do ndx = 1, n_quad |
| 123 | val = val + coordfun_vals(ndx) * bspline1_vals(ndx) *& | ||
| 124 | 1193172 | & bspline2_quad%bspline_at_nodes(j2_internal, bspline2%degree - j2_minus_i)%data(n_quad + 1 - ndx) | |
| 125 | end do | ||
| 126 | else | ||
| 127 |
2/2✓ Branch 140 → 141 taken 2577574 times.
✓ Branch 140 → 142 taken 14277136 times.
|
16854710 | do ndx = 1, n_quad |
| 128 | val = val + coordfun_vals(ndx) * bspline1_vals(ndx) * & | ||
| 129 | 16854710 | & bspline2_quad%bspline_at_nodes(j2_internal, j2_minus_i)%data(ndx) | |
| 130 | end do | ||
| 131 | end if | ||
| 132 | |||
| 133 | 2719234 | vals(j2_minus_i, j1_minus_i) = val | |
| 134 |
2/2✓ Branch 144 → 145 taken 860030 times.
✓ Branch 144 → 146 taken 1859204 times.
|
6298498 | if (j1_minus_i == bspline1%degree) then |
| 135 | 860030 | cols(j2_minus_i) = j2 | |
| 136 | end if | ||
| 137 | end do | ||
| 138 | |||
| 139 | 1892330 | rows(j1_minus_i) = j1 | |
| 140 | end do | ||
| 141 | |||
| 142 |
1/2✓ Branch 150 → 151 taken 172270 times.
✗ Branch 150 → 159 not taken.
|
172270 | if (equal_spaces) then |
| 143 |
2/2✓ Branch 152 → 153 taken 860030 times.
✓ Branch 152 → 158 taken 172270 times.
|
1032300 | do j1_minus_i = 0, bspline1%degree |
| 144 |
2/2✓ Branch 154 → 155 taken 1859204 times.
✓ Branch 154 → 156 taken 860030 times.
|
2891504 | do j2_minus_i = j1_minus_i + 1, bspline2%degree |
| 145 | 2719234 | vals(j2_minus_i, j1_minus_i) = vals(j1_minus_i, j2_minus_i) | |
| 146 | end do | ||
| 147 | end do | ||
| 148 | end if | ||
| 149 | |||
| 150 | ! NOTE: vals is transposed for fast acces, this means the role of rows and cols is swapped | ||
| 151 |
9/12✗ Branch 159 → 160 not taken.
✓ Branch 159 → 161 taken 172270 times.
✓ Branch 161 → 162 taken 860030 times.
✓ Branch 161 → 166 taken 172270 times.
✓ Branch 163 → 164 taken 4578438 times.
✓ Branch 163 → 165 taken 860030 times.
✓ Branch 166 → 167 taken 172270 times.
✗ Branch 166 → 168 not taken.
✓ Branch 169 → 170 taken 4578438 times.
✓ Branch 169 → 171 taken 172270 times.
✗ Branch 172 → 173 not taken.
✓ Branch 172 → 174 taken 172270 times.
|
10196892 | PetscCall(MatSetValues(M, size(cols), cols, size(rows), rows, [vals(:, :)], ADD_VALUES, ierr)) |
| 152 | end do | ||
| 153 | |||
| 154 |
1/2✗ Branch 176 → 177 not taken.
✓ Branch 176 → 178 taken 7716 times.
|
7716 | deallocate (vals) |
| 155 |
1/2✗ Branch 178 → 179 not taken.
✓ Branch 178 → 180 taken 7716 times.
|
7716 | deallocate (cols) |
| 156 |
1/2✗ Branch 180 → 181 not taken.
✓ Branch 180 → 182 taken 7716 times.
|
7716 | deallocate (rows) |
| 157 | |||
| 158 |
1/2✗ Branch 182 → 183 not taken.
✓ Branch 182 → 184 taken 7716 times.
|
7716 | deallocate (coordfun_vals) |
| 159 | |||
| 160 |
1/2✗ Branch 184 → 185 not taken.
✓ Branch 184 → 186 taken 7716 times.
|
7716 | deallocate (bspline1_vals) |
| 161 | |||
| 162 |
1/2✗ Branch 187 → 188 not taken.
✓ Branch 187 → 190 taken 7716 times.
|
7716 | PetscCall(MatAssemblyBegin(M, MAT_FINAL_ASSEMBLY, ierr)) |
| 163 |
1/2✗ Branch 191 → 192 not taken.
✓ Branch 191 → 193 taken 7716 times.
|
7716 | PetscCall(MatAssemblyEnd(M, MAT_FINAL_ASSEMBLY, ierr)) |
| 164 | |||
| 165 |
11/22✗ Branch 193 → 194 not taken.
✓ Branch 193 → 195 taken 7716 times.
✗ Branch 195 → 196 not taken.
✓ Branch 195 → 197 taken 7716 times.
✗ Branch 197 → 198 not taken.
✓ Branch 197 → 199 taken 7716 times.
✗ Branch 199 → 200 not taken.
✓ Branch 199 → 201 taken 7716 times.
✓ Branch 201 → 202 taken 7716 times.
✗ Branch 201 → 203 not taken.
✓ Branch 203 → 204 taken 7716 times.
✗ Branch 203 → 205 not taken.
✓ Branch 205 → 206 taken 7716 times.
✗ Branch 205 → 207 not taken.
✗ Branch 207 → 208 not taken.
✓ Branch 207 → 209 taken 7716 times.
✓ Branch 209 → 210 taken 7716 times.
✗ Branch 209 → 211 not taken.
✓ Branch 211 → 212 taken 7716 times.
✗ Branch 211 → 213 not taken.
✓ Branch 213 → 214 taken 7716 times.
✗ Branch 213 → 215 not taken.
|
7716 | end subroutine mass_matrix_1d |
| 166 | |||
| 167 | !> @brief Compute the difference matrix (consisting of a '1' and a '-1' for each row) of a 1D B-spline space | ||
| 168 | !> | ||
| 169 | !> @param[out] D The difference matrix | ||
| 170 | !> @param[in] bspline The B-spline space | ||
| 171 | 48 | subroutine difference_matrix(D, bspline) | |
| 172 | use m_common, only: wp | ||
| 173 | use m_bspline_basis, only: BSplineSpace, size | ||
| 174 | implicit none | ||
| 175 | |||
| 176 | Mat, intent(out) :: D | ||
| 177 | type(BSplineSpace), intent(in) :: bspline | ||
| 178 | |||
| 179 | integer :: n_basis, ierr, row, c0, c1, n_rows | ||
| 180 | integer :: local_nz_per_row, nonlocal_nz_per_row | ||
| 181 | |||
| 182 | 48 | n_basis = size(bspline) | |
| 183 | |||
| 184 |
1/2✓ Branch 2 → 3 taken 48 times.
✗ Branch 2 → 4 not taken.
|
48 | if (.not. bspline%is_periodic) then |
| 185 | 48 | n_rows = n_basis - 1 | |
| 186 | else | ||
| 187 | ✗ | n_rows = n_basis | |
| 188 | end if | ||
| 189 | |||
| 190 | 48 | local_nz_per_row = 2 | |
| 191 | 48 | nonlocal_nz_per_row = 0 ! NOTE: currently sequential | |
| 192 | |||
| 193 | ! Create a sparse matrix | ||
| 194 | call MatCreateAIJ(PETSC_COMM_SELF, n_rows, n_basis, n_rows, & | ||
| 195 | & n_basis, local_nz_per_row, PETSC_NULL_INTEGER_ARRAY, nonlocal_nz_per_row,& | ||
| 196 |
1/2✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 48 times.
|
48 | & PETSC_NULL_INTEGER_ARRAY, D, ierr); CHKERRQ(ierr) |
| 197 | |||
| 198 |
1/2✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 48 times.
|
48 | PetscCall(MatSetFromOptions(D, ierr)) |
| 199 |
1/2✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 48 times.
|
48 | PetscCall(MatSetUp(D, ierr)) |
| 200 | |||
| 201 | ! Set the values of the matrix | ||
| 202 |
2/2✓ Branch 15 → 16 taken 1680 times.
✓ Branch 15 → 25 taken 48 times.
|
1728 | do row = 0, n_rows - 1 |
| 203 | c0 = row | ||
| 204 | 1680 | c1 = mod(row + 1, n_basis) | |
| 205 | |||
| 206 |
5/6✓ Branch 17 → 18 taken 1680 times.
✓ Branch 17 → 19 taken 1680 times.
✓ Branch 20 → 21 taken 3360 times.
✓ Branch 20 → 22 taken 1680 times.
✓ Branch 23 → 15 taken 1680 times.
✗ Branch 23 → 24 not taken.
|
6768 | PetscCall(MatSetValues(D, 1, [row], 2, [c0, c1], [-1._wp, +1._wp], INSERT_VALUES, ierr)) |
| 207 | end do | ||
| 208 | |||
| 209 |
1/2✗ Branch 27 → 28 not taken.
✓ Branch 27 → 29 taken 48 times.
|
48 | PetscCall(MatAssemblyBegin(D, MAT_FINAL_ASSEMBLY, ierr)) |
| 210 |
1/2✗ Branch 30 → 31 not taken.
✓ Branch 30 → 32 taken 48 times.
|
48 | PetscCall(MatAssemblyEnd(D, MAT_FINAL_ASSEMBLY, ierr)) |
| 211 | end subroutine | ||
| 212 | |||
| 213 | !> @brief Compute the divgrad (Laplace) matrix of a 1D B-spline space | ||
| 214 | !> | ||
| 215 | !> @param[out] The resulting Laplace matrix | ||
| 216 | !> @param[in] bspline The B-spline space | ||
| 217 | !> @param[in] dbspline The derivative B-spline space | ||
| 218 | 96 | subroutine divgrad_matrix_1d(L, bspline, dbspline) | |
| 219 | use m_common, only: wp | ||
| 220 | use m_bspline_basis, only: BSplineSpace, size | ||
| 221 | |||
| 222 | implicit none | ||
| 223 | |||
| 224 | Mat, intent(out) :: L | ||
| 225 | type(BSplineSpace), intent(in) :: bspline, dbspline | ||
| 226 | |||
| 227 | Mat :: D, M | ||
| 228 | Vec :: nullspace_vec | ||
| 229 | MatNullSpace :: nullspace | ||
| 230 | integer :: ierr | ||
| 231 | integer :: n_basis, dn_basis, i | ||
| 232 | real(wp) :: tmp | ||
| 233 | real(wp) :: EXPECTED_FILL_RATIO = 1.0_wp | ||
| 234 | |||
| 235 | 48 | n_basis = size(bspline) | |
| 236 | dn_basis = size(dbspline) | ||
| 237 | |||
| 238 | 48 | call mass_matrix(M, dbspline, dbspline) | |
| 239 | 48 | call difference_matrix(D, bspline) | |
| 240 | |||
| 241 |
1/2✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 48 times.
|
48 | PetscCall(MatPtAP(M, D, MAT_INITIAL_MATRIX, EXPECTED_FILL_RATIO, L, ierr)) |
| 242 | |||
| 243 |
1/2✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 48 times.
|
48 | PetscCall(MatDestroy(M, ierr)) |
| 244 |
1/2✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 48 times.
|
48 | PetscCall(MatDestroy(D, ierr)) |
| 245 | |||
| 246 | ! The Laplace matrix still has a nullspace (no boundary conditions are imposed) | ||
| 247 |
1/2✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 48 times.
|
48 | PetscCall(VecCreate(PETSC_COMM_SELF, nullspace_vec, ierr)) |
| 248 |
1/2✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 48 times.
|
48 | PetscCall(VecSetSizes(nullspace_vec, n_basis, n_basis, ierr)) |
| 249 |
1/2✗ Branch 20 → 21 not taken.
✓ Branch 20 → 22 taken 48 times.
|
48 | PetscCall(VecSetFromOptions(nullspace_vec, ierr)) |
| 250 |
2/2✓ Branch 23 → 24 taken 1728 times.
✓ Branch 23 → 28 taken 48 times.
|
1776 | do i = 0, n_basis - 1 |
| 251 |
1/2✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 1728 times.
|
1776 | PetscCall(VecSetValue(nullspace_vec, i, 1._wp, INSERT_VALUES, ierr)) |
| 252 | end do | ||
| 253 |
1/2✗ Branch 30 → 31 not taken.
✓ Branch 30 → 32 taken 48 times.
|
48 | PetscCall(VecNormalize(nullspace_vec, tmp, ierr)) |
| 254 | |||
| 255 |
1/2✗ Branch 33 → 34 not taken.
✓ Branch 33 → 35 taken 48 times.
|
48 | PetscCall(VecAssemblyBegin(nullspace_vec, ierr)) |
| 256 |
1/2✗ Branch 36 → 37 not taken.
✓ Branch 36 → 38 taken 48 times.
|
48 | PetscCall(VecAssemblyEnd(nullspace_vec, ierr)) |
| 257 | |||
| 258 |
3/4✓ Branch 39 → 40 taken 48 times.
✓ Branch 39 → 41 taken 48 times.
✗ Branch 42 → 43 not taken.
✓ Branch 42 → 44 taken 48 times.
|
96 | PetscCall(MatNullSpaceCreate(PETSC_COMM_SELF, PETSC_FALSE, 1, [nullspace_vec], nullspace, ierr)) |
| 259 | |||
| 260 |
1/2✗ Branch 45 → 46 not taken.
✓ Branch 45 → 47 taken 48 times.
|
48 | PetscCall(MatSetNullSpace(L, nullspace, ierr)) |
| 261 |
1/2✗ Branch 48 → 49 not taken.
✓ Branch 48 → 50 taken 48 times.
|
48 | PetscCall(MatNullSpaceDestroy(nullspace, ierr)) |
| 262 | |||
| 263 | 48 | end subroutine divgrad_matrix_1d | |
| 264 | end module m_bspline_matrix | ||
| 265 |