Globals Library 1.0
Loading...
Searching...
No Matches
modGaussQuadrature.f90
Go to the documentation of this file.
1!> @brief Module for computation of 1d and tensorized
2!> 2d Gauss points
4
5 use globals
6
7 implicit none
8
9 private
10
11 type, public :: gaussq
12 !> Number of 1d Gauss points
13 integer :: ngauss
14 !> Dimension (`::ngauss`)
15 !> Coefficients of 1d Gauss points on \f$[-1,+1]\f$.
16 real(kind=double), allocatable :: coeff1d(:)
17 !> Dimension (`::ngauss`)
18 !> Cordinate of Gauss points on interval \f$[a,b]\f$.
19 !> Only allocated, it will be
20 !> gauss = (b-a)/2 coeff + (a+b) /2.
21 real(kind=double), allocatable :: coord_ab(:)
22 !> Dimension (`::ngauss`).
23 !> Weight of 1d Gauss points on \f$[-1,+1]\f$.
24 real(kind=double), allocatable :: weight1d(:)
25 !> Dimension (`::ngauss`).
26 !> Weight of 1d Gauss points on \f$[a,b]\f$.
27 real(kind=double), allocatable :: weight_ab(:)
28 !> Dimension (`::ngauss`,2).
29 !> Cordinate of 2d gauss points (first column
30 !> \f$x\f$, second column \f$y\f$)
31 real(kind=double), allocatable :: coord_cell(:, :)
32 !> Dimension (`::ngauss`,2).
33 !> Weights of 2d Gauss points (first column
34 !> \f$x\f$, second column \f$y\f$)
35 real(kind=double), allocatable :: weight_cell(:, :)
36 !> Dimension (`::ngauss`**2)
37 !> Tensioral production of 1d Gauss weights
38 real(kind=double), allocatable :: weight2d(:)
39 contains
40 !> Static constructor for `gaussquadrature::gaussq`
41 procedure, public, pass :: init => init_gaussq
42 !> Static destructor for `gaussquadrature::gaussq`
43 procedure, public, pass :: kill => kill_gaussq
44 !> Info procedure for `gaussquadrature::gaussq`
45 procedure, public, pass :: info => info_gaussq
46 !> Procedure to compute Gauss points of \f$[a,b]\f$
47 procedure, public, pass :: on_interval
48 !> Procedure to compute Gauss points of \f$[a_x,b_x] \times [a_y,b_y]\f$
49 procedure, public, pass :: on_cell
50 end type gaussq
51
52contains
53
54 !>-------------------------------------------------------------
55 !> @brief Static constructor for `gaussquadrature::gaussq`
56 !> @details Allocate all the variables. Define variable
57 !> `gaussq::coeff1d` and `gaussq::weight1d`.
58 !>
59 !> @param[in ] lun_err: unit number for error messages
60 !> @param[in ] ngauss: Number of Gauss points
61 !<-------------------------------------------------------------
62 subroutine init_gaussq(this, lun_err, ngauss)
63
64 implicit none
65 class(gaussq), intent(inout) :: this
66 integer, intent(in) :: lun_err
67 integer, intent(in) :: ngauss
68 !local
69 logical :: rc
70 integer :: res
71 integer :: i, j, m
72
73 this%ngauss = ngauss
74 allocate ( &
75 this%coeff1d(ngauss), &
76 this%coord_ab(ngauss), &
77 this%weight1d(ngauss), &
78 this%weight_ab(ngauss), &
79 this%coord_cell(ngauss, 2), &
80 this%weight_cell(ngauss, 2), &
81 this%weight2d(ngauss**2), &
82 stat=res)
83 if (res .ne. 0) rc = ioerr(lun_err, err_alloc, 'init_gaussq', &
84 ' member coeff1d, points1d, weight1d, weight2d ', res)
85
86 call gaussquad(lun_err, ngauss, this%coeff1d, this%weight1d)
87
88 m = 0
89 do i = 1, ngauss
90 do j = 1, ngauss
91 m = m + 1
92 this%weight2d(m) = this%weight1d(i)*this%weight1d(j)
93 end do
94 end do
95
96 contains
97
98 subroutine gaussquad(lun_err, ngauss, coefcoord, weight)
99 implicit none
100 integer, intent(in) :: lun_err
101 integer, intent(in) :: ngauss
102 real(kind=double), intent(out) :: coefcoord(ngauss)
103 real(kind=double), intent(out) :: weight(ngauss)
104 ! local
105 integer :: info, lwork, j
106 logical :: rc
107 integer :: res
108 real(kind=double), allocatable :: u(:)
109 real(kind=double), allocatable :: work(:)
110 real(kind=double), allocatable :: a(:, :)
111
112 lwork = 20*ngauss
113 allocate ( &
114 u(ngauss - 1), &
115 work(20*ngauss), &
116 a(ngauss, ngauss), &
117 stat=res)
118 if (res .ne. 0) rc = ioerr(lun_err, err_alloc, 'gaussquad', &
119 ' local array u, work, A', res)
120
121 a = 0.d0
122 do j = 1, ngauss - 1
123 a(j, j + 1) = j/sqrt(4.0d0*j**2 - one)
124 end do
125
126 call dsyev('V', 'U', ngauss, a, ngauss, coefcoord, work, lwork, info)
127 weight(:) = 2*a(1, :)**2
128 deallocate (u, work, a, stat=res)
129 if (res .ne. 0) rc = ioerr(lun_err, err_dealloc, 'gaussquad', &
130 ' local array u, work, A', res)
131
132 end subroutine gaussquad
133
134 end subroutine init_gaussq
135
136 !>-------------------------------------------------------------
137 !> @brief Static destructor for `gaussquadrature::gaussq`
138 !> @details Deallocate all the variables.
139 !>
140 !> @param[in ] lun_err: unit number for error messagges
141 !<-------------------------------------------------------------
142 subroutine kill_gaussq(this, lun_err)
143 implicit none
144 class(gaussq), intent(inout) :: this
145 integer, intent(in) :: lun_err
146 !local
147 logical :: rc
148 integer :: res
149
150 this%ngauss = 0
151 deallocate ( &
152 this%coeff1d, &
153 this%coord_ab, &
154 this%weight1d, &
155 this%weight_ab, &
156 this%coord_cell, &
157 this%weight_cell, &
158 this%weight2d, &
159 stat=res)
160 if (res .ne. 0) rc = ioerr(lun_err, err_dealloc, 'kill_gaussq', &
161 ' member coeff1d, weight1d, weight2d', res)
162
163 end subroutine kill_gaussq
164
165 !>-------------------------------------------------------------
166 !> @brief Info procedure for `gaussquadrature::gaussq`
167 !>
168 !> @param[in ] lun_out: unit number for output messagges
169 !<-------------------------------------------------------------
170 subroutine info_gaussq(this, lun_out)
171 implicit none
172 class(gaussq), intent(in) :: this
173 integer, intent(in) :: lun_out
174 !local
175 integer :: i
176
177 write (lun_out, *) 'Nmb of Gauss points = ', this%ngauss
178 do i = 1, this%ngauss
179 write (lun_out, *) 'Gauss coeff1d, weight1d = ', &
180 this%coeff1d(i), this%weight1d(i)
181 end do
182
183 end subroutine info_gaussq
184
185 !>-------------------------------------------------------------
186 !> @brief Compute Gauss points on the interval \f$[a,b]\f$.
187 !> @details Define variables `gaussq::coord_ab` and
188 !> `gaussq::weight_ab`.
189 !>
190 !> @param[in ] a: left endpoint of interval
191 !> @param[in ] b: right endpoint of interval
192 !<-------------------------------------------------------------
193 subroutine on_interval(this, a, b)
194 implicit none
195 class(gaussq), intent(inout) :: this
196 real(double), intent(in) :: a, b
197
198 this%coord_ab(:) = onehalf*((b - a)*this%coeff1d(:) + (a + b))
199 this%weight_ab(:) = onehalf*(b - a)*this%weight1d(:)
200
201 end subroutine on_interval
202
203 !>-------------------------------------------------------------
204 !> @brief Compute Gauss points of \f$[a_x,b_x] \times [a_y,b_y]\f$
205 !> @details Gauss points in \f$\mathbb{R}^{2}\f$ are computed by
206 !> tensorization of 1d Gauss points. Define variables
207 !> `gaussq::coord_cell` and `gaussq::weight_cell`.
208 !>
209 !> @param[in ] ax: left endpoint interval variable \f$x\f$.
210 !> @param[in ] bx: right endpoint interval variable \f$x\f$.
211 !> @param[in ] ay: left endpoint interval variable \f$y\f$.
212 !> @param[in ] by: right endpoint interval variable y.
213 !<-------------------------------------------------------------
214 subroutine on_cell(this, ax, bx, ay, by)
215 implicit none
216 class(gaussq), intent(inout) :: this
217 real(double), intent(in) :: ax, bx, ay, by
218
219 this%coord_cell(:, 1) = onehalf*((bx - ax)*this%coeff1d(:) + (ax + bx))
220 this%coord_cell(:, 2) = onehalf*((by - ay)*this%coeff1d(:) + (ay + by))
221
222 this%weight_cell(:, 1) = onehalf*(bx - ax)*this%weight1d(:)
223 this%weight_cell(:, 2) = onehalf*(by - ay)*this%weight1d(:)
224
225 end subroutine on_cell
226
227end module gaussquadrature
subroutine gaussquad(lun_err, ngauss, coefcoord, weight)
Module for computation of 1d and tensorized 2d Gauss points.
subroutine info_gaussq(this, lun_out)
Info procedure for gaussquadrature::gaussq.
subroutine init_gaussq(this, lun_err, ngauss)
Static constructor for gaussquadrature::gaussq.
subroutine on_interval(this, a, b)
Compute Gauss points on the interval .
subroutine on_cell(this, ax, bx, ay, by)
Compute Gauss points of .
subroutine kill_gaussq(this, lun_err)
Static destructor for gaussquadrature::gaussq.
integer, parameter err_alloc
Error allocation failed.
integer, parameter err_dealloc
Error deallocation failed.
logical function ioerr(lun, errno, call_proc, add_msg, add_int)
Handle and write alert I/O warnings and errors.