1 ! Copyright 2019 Wojciech Kosior
3 ! This is free and unencumbered software released into the public domain.
5 ! Anyone is free to copy, modify, publish, use, compile, sell, or
6 ! distribute this software, either in source code form or as a compiled
7 ! binary, for any purpose, commercial or non-commercial, and by any
10 ! In jurisdictions that recognize copyright laws, the author or authors
11 ! of this software dedicate any and all copyright interest in the
12 ! software to the public domain. We make this dedication for the benefit
13 ! of the public at large and to the detriment of our heirs and
14 ! successors. We intend this dedication to be an overt act of
15 ! relinquishment in perpetuity of all present and future rights to this
16 ! software under copyright law.
18 ! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 ! EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 ! MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 ! IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 ! OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ! ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 ! OTHER DEALINGS IN THE SOFTWARE.
26 ! For more information, please refer to <http://unlicense.org/>
32 integer(kind
=8) :: subintervals
= 100
35 FUNCTION integrate(ibeg
, iend
, myfun
, p
) result(val
)
37 ! beginning of integration interval
38 real(kind
=8), intent(in
) :: ibeg
39 ! ending of integration interval
40 real(kind
=8), intent(in
) :: iend
41 ! function to be integrated
42 procedure(funint
) :: myfun
44 integer(kind
=4), intent(in
) :: p
45 ! result of integration
47 END FUNCTION integrate
51 FUNCTION quadrature(qbeg
, qend
, fun
) result(val
)
53 real(kind
=8), intent(in
) :: qbeg
, qend
54 procedure(funint
) :: fun
56 END FUNCTION quadrature
60 FUNCTION funint(x
) result(y
)
62 real(kind
=8), intent(in
) :: x
69 FUNCTION integrate_generic(ibeg
, iend
, fun
, quad
) result(val
)
71 real(kind
=8), intent(in
) :: ibeg
72 real(kind
=8), intent(in
) :: iend
73 procedure(funint
) :: fun
74 procedure(quadrature
) :: quad
76 real(kind
=8) :: val
, subinterval_width
, qbeg
, qend
, partsums(48)
77 logical :: partsums_mask(48) = .true
.
78 real(kind
=8), allocatable
:: partval
[:]
80 integer(kind
=8) :: min_i
, max_i
, i
, j
, subintervals_per_thread
85 subintervals_per_thread
= &
86 (subintervals
+ num_images() - 1) / num_images()
88 min_i
= subintervals_per_thread
* (this_image() - 1) + 1
89 max_i
= min(subintervals
, subintervals_per_thread
* this_image())
91 subinterval_width
= (iend
- ibeg
) / subintervals
93 ! compute integral using quadrature pointed by quad
97 qend
= ibeg
+ i
* subinterval_width
98 qbeg
= ibeg
+ (i
- 1) * subinterval_width
99 val
= quad(qbeg
, qend
, fun
)
102 IF (partsums_mask(j
)) THEN
103 partsums_mask(j
) = .false
.
108 val
= val
+ partsums(j
)
109 partsums_mask(j
) = .true
.
115 IF (.not
. partsums_mask(j
)) partval
= partval
+ partsums(j
)
118 IF (this_image() == 1 .and
. num_images() > 1) THEN
119 sync
images([(im
, im
= 2, num_images())])
120 partval
= partval
+ sum([(partval
[im
], im
= 2, num_images())])
121 sync
images([(im
, im
= 2, num_images())])
124 IF (this_image() /= 1) THEN
131 END FUNCTION integrate_generic
133 FUNCTION newton_cotes(ibeg
, iend
, fun
, p
) result(val
)
134 USE, intrinsic :: ieee_arithmetic
137 real(kind
=8), intent(in
) :: ibeg
138 real(kind
=8), intent(in
) :: iend
139 procedure(funint
) :: fun
140 integer(kind
=4), intent(in
) :: p
143 procedure(quadrature
), pointer :: quad
151 quad
=> simpson_1_third
153 val
= ieee_value(val
, ieee_quiet_nan
)
157 val
= integrate_generic(ibeg
, iend
, fun
, quad
)
158 END FUNCTION newton_cotes
160 FUNCTION rectangle(qbeg
, qend
, fun
) result(val
)
162 real(kind
=8), intent(in
) :: qbeg
, qend
163 procedure(funint
) :: fun
166 val
= (qend
- qbeg
) * fun((qend
+ qbeg
) * 0.5)
167 END FUNCTION rectangle
169 FUNCTION trapeze(qbeg
, qend
, fun
) result(val
)
171 real(kind
=8), intent(in
) :: qbeg
, qend
172 procedure(funint
) :: fun
175 val
= (qend
- qbeg
) * 0.5 * (fun(qbeg
) + fun(qend
))
178 FUNCTION simpson_1_third(qbeg
, qend
, fun
) result(val
)
180 real(kind
=8), intent(in
) :: qbeg
, qend
181 procedure(funint
) :: fun
184 val
= (qend
- qbeg
) * (1/6.0) * &
185 (fun(qbeg
) + 4 * fun ((qbeg
+ qend
) * 0.5) + fun(qend
))
186 END FUNCTION simpson_1_third
188 FUNCTION gauss(ibeg
, iend
, fun
, p
) result(val
)
189 USE, intrinsic :: ieee_arithmetic
192 real(kind
=8), intent(in
) :: ibeg
193 real(kind
=8), intent(in
) :: iend
194 procedure(funint
) :: fun
195 integer(kind
=4), intent(in
) :: p
198 procedure(quadrature
), pointer :: quad
208 val
= ieee_value(val
, ieee_quiet_nan
)
212 val
= integrate_generic(ibeg
, iend
, fun
, quad
)
215 FUNCTION gauss_generic(mid
, halfwidth
, fun
, points
, weights
) &
218 real(kind
=8), intent(in
) :: mid
, halfwidth
, points(:), weights(:)
219 procedure(funint
) :: fun
224 val
= halfwidth
* sum(weights
* &
225 [(fun(points(i
) * halfwidth
+ mid
), i
= 1, size(points
))])
226 END FUNCTION gauss_generic
228 FUNCTION gauss_n1(qbeg
, qend
, fun
) result(val
)
230 real(kind
=8), intent(in
) :: qbeg
, qend
231 procedure(funint
) :: fun
232 real(kind
=8) :: val
, weights(1) = [2], points(1) = [0]
234 val
= gauss_generic((qbeg
+ qend
) * 0.5, (qend
- qbeg
) * 0.5, &
235 fun
, points
, weights
)
236 END FUNCTION gauss_n1
238 FUNCTION gauss_n2(qbeg
, qend
, fun
) result(val
)
240 real(kind
=8), intent(in
) :: qbeg
, qend
241 procedure(funint
) :: fun
242 real(kind
=8) :: val
, weights(2) = [1, 1], &
243 points(2) = [1 / sqrt(3.0), -1 / sqrt(3.0)]
245 val
= gauss_generic((qbeg
+ qend
) * 0.5, (qend
- qbeg
) * 0.5, &
246 fun
, points
, weights
)
247 END FUNCTION gauss_n2
249 FUNCTION gauss_n3(qbeg
, qend
, fun
) result(val
)
251 real(kind
=8), intent(in
) :: qbeg
, qend
252 procedure(funint
) :: fun
253 real(kind
=8) :: val
, weights(3) = [8 / 9.0, 5 / 9.0, 5 / 9.0],&
254 points(3) = [0.0, sqrt(3 / 5.0), -sqrt(3 / 5.0)]
256 val
= gauss_generic((qbeg
+ qend
) * 0.5, (qend
- qbeg
) * 0.5, &
257 fun
, points
, weights
)
258 END FUNCTION gauss_n3
260 END MODULE quadratures