5 integer(kind
=8) :: subintervals
= 100
8 FUNCTION integrate(ibeg
, iend
, myfun
, p
) result(val
)
10 ! beginning of integration interval
11 real(kind
=8), intent(in
) :: ibeg
12 ! ending of integration interval
13 real(kind
=8), intent(in
) :: iend
14 ! function to be integrated
15 procedure(funint
) :: myfun
17 integer(kind
=4), intent(in
) :: p
18 ! result of integration
20 END FUNCTION integrate
24 FUNCTION quadrature(qbeg
, qend
, fun
) result(val
)
26 real(kind
=8), intent(in
) :: qbeg
, qend
27 procedure(funint
) :: fun
29 END FUNCTION quadrature
33 FUNCTION funint(x
) result(y
)
35 real(kind
=8), intent(in
) :: x
42 FUNCTION integrate_generic(ibeg
, iend
, fun
, quad
) result(val
)
44 real(kind
=8), intent(in
) :: ibeg
45 real(kind
=8), intent(in
) :: iend
46 procedure(funint
) :: fun
47 procedure(quadrature
) :: quad
49 real(kind
=8) :: val
, subinterval_width
, qbeg
, qend
, partsums(48)
50 logical :: partsums_mask(48) = .true
.
51 real(kind
=8), allocatable
:: partval
[:]
53 integer(kind
=8) :: min_i
, max_i
, i
, j
, subintervals_per_thread
58 subintervals_per_thread
= &
59 (subintervals
+ num_images() - 1) / num_images()
61 min_i
= subintervals_per_thread
* (this_image() - 1) + 1
62 max_i
= min(subintervals
, subintervals_per_thread
* this_image())
64 subinterval_width
= (iend
- ibeg
) / subintervals
66 ! compute integral using quadrature pointed by quad
70 qend
= ibeg
+ i
* subinterval_width
71 qbeg
= ibeg
+ (i
- 1) * subinterval_width
72 val
= quad(qbeg
, qend
, fun
)
75 IF (partsums_mask(j
)) THEN
76 partsums_mask(j
) = .false
.
81 val
= val
+ partsums(j
)
82 partsums_mask(j
) = .true
.
88 IF (.not
. partsums_mask(j
)) partval
= partval
+ partsums(j
)
91 IF (this_image() == 1 .and
. num_images() > 1) THEN
92 sync
images([(im
, im
= 2, num_images())])
93 partval
= partval
+ sum([(partval
[im
], im
= 2, num_images())])
94 sync
images([(im
, im
= 2, num_images())])
97 IF (this_image() /= 1) THEN
104 END FUNCTION integrate_generic
106 FUNCTION newton_cotes(ibeg
, iend
, fun
, p
) result(val
)
108 real(kind
=8), intent(in
) :: ibeg
109 real(kind
=8), intent(in
) :: iend
110 procedure(funint
) :: fun
111 integer(kind
=4), intent(in
) :: p
114 procedure(quadrature
), pointer :: quad
118 STOP "negative interpolationg polynomial order passed"
124 quad
=> simpson_1_third
126 STOP "Newton-Cotes quadratures only implemented for order < 3"
129 val
= integrate_generic(ibeg
, iend
, fun
, quad
)
130 END FUNCTION newton_cotes
132 FUNCTION rectangle(qbeg
, qend
, fun
) result(val
)
134 real(kind
=8), intent(in
) :: qbeg
, qend
135 procedure(funint
) :: fun
138 val
= (qend
- qbeg
) * fun((qend
+ qbeg
) * 0.5)
139 END FUNCTION rectangle
141 FUNCTION trapeze(qbeg
, qend
, fun
) result(val
)
143 real(kind
=8), intent(in
) :: qbeg
, qend
144 procedure(funint
) :: fun
147 val
= (qend
- qbeg
) * 0.5 * (fun(qbeg
) + fun(qend
))
150 FUNCTION simpson_1_third(qbeg
, qend
, fun
) result(val
)
152 real(kind
=8), intent(in
) :: qbeg
, qend
153 procedure(funint
) :: fun
156 val
= (qend
- qbeg
) * (1/6.0) * &
157 (fun(qbeg
) + 4 * fun ((qbeg
+ qend
) * 0.5) + fun(qend
))
158 END FUNCTION simpson_1_third
160 FUNCTION gauss(ibeg
, iend
, fun
, p
) result(val
)
162 real(kind
=8), intent(in
) :: ibeg
163 real(kind
=8), intent(in
) :: iend
164 procedure(funint
) :: fun
165 integer(kind
=4), intent(in
) :: p
168 procedure(quadrature
), pointer :: quad
172 STOP "non-positive Legendre polynomial order passed"
180 STOP "Gauss quadratures only implemented with roots of" &
181 // " Legendgre polynomial of order <= 3"
184 val
= integrate_generic(ibeg
, iend
, fun
, quad
)
187 FUNCTION gauss_generic(mid
, halfwidth
, fun
, points
, weights
) &
190 real(kind
=8), intent(in
) :: mid
, halfwidth
, points(:), weights(:)
191 procedure(funint
) :: fun
196 val
= halfwidth
* sum(weights
* &
197 [(fun(points(i
) * halfwidth
+ mid
), i
= 1, size(points
))])
198 END FUNCTION gauss_generic
200 FUNCTION gauss_n1(qbeg
, qend
, fun
) result(val
)
202 real(kind
=8), intent(in
) :: qbeg
, qend
203 procedure(funint
) :: fun
204 real(kind
=8) :: val
, weights(1) = [2], points(1) = [0]
206 val
= gauss_generic((qbeg
+ qend
) * 0.5, (qend
- qbeg
) * 0.5, &
207 fun
, points
, weights
)
208 END FUNCTION gauss_n1
210 FUNCTION gauss_n2(qbeg
, qend
, fun
) result(val
)
212 real(kind
=8), intent(in
) :: qbeg
, qend
213 procedure(funint
) :: fun
214 real(kind
=8) :: val
, weights(2) = [1, 1], &
215 points(2) = [1 / sqrt(3.0), -1 / sqrt(3.0)]
217 val
= gauss_generic((qbeg
+ qend
) * 0.5, (qend
- qbeg
) * 0.5, &
218 fun
, points
, weights
)
219 END FUNCTION gauss_n2
221 FUNCTION gauss_n3(qbeg
, qend
, fun
) result(val
)
223 real(kind
=8), intent(in
) :: qbeg
, qend
224 procedure(funint
) :: fun
225 real(kind
=8) :: val
, weights(3) = [8 / 9.0, 5 / 9.0, 5 / 9.0],&
226 points(3) = [0.0, sqrt(3 / 5.0), -sqrt(3 / 5.0)]
228 val
= gauss_generic((qbeg
+ qend
) * 0.5, (qend
- qbeg
) * 0.5, &
229 fun
, points
, weights
)
230 END FUNCTION gauss_n3
232 END MODULE quadratures