8 integer,
parameter :: dp = kind(0.0d0)
14 real(dp),
allocatable :: ampl(:)
15 real(dp),
allocatable :: sigma(:)
16 real(dp),
allocatable :: r0(:,:)
22 public :: gauss_gradient
23 public :: gauss_laplacian
24 public :: gauss_laplacian_cyl
30 subroutine gauss_init(gs, amplitudes, sigmas, locations)
31 type(
gauss_t),
intent(inout) :: gs
32 real(dp),
intent(in) :: amplitudes(:)
33 real(dp),
intent(in) :: sigmas(:)
34 real(dp),
intent(in) :: locations(:,:)
36 if (
size(locations, 2) /=
size(amplitudes) .or. &
37 size(sigmas) /=
size(amplitudes))
then
38 stop
"gauss_init: arguments do not match in size"
41 gs%n_gauss =
size(amplitudes)
42 gs%n_dim =
size(locations, 1)
44 allocate(gs%ampl(gs%n_gauss))
45 allocate(gs%sigma(gs%n_gauss))
46 allocate(gs%r0(gs%n_dim, gs%n_gauss))
51 end subroutine gauss_init
54 real(dp) function gauss_value(gs, r)
56 real(dp),
intent(in) :: r(gs%n_dim)
61 gauss_value = gauss_value + gauss_single(gs, r, n)
63 end function gauss_value
66 real(dp) function gauss_single(gs, r, ix)
68 real(dp),
intent(in) :: r(gs%n_dim)
69 integer,
intent(in) :: ix
70 real(dp) :: xrel(gs%n_dim)
72 xrel = (r-gs%r0(:, ix)) / gs%sigma(ix)
73 gauss_single = gs%ampl(ix) * exp(-sum(xrel**2))
74 end function gauss_single
76 subroutine gauss_gradient(gs, r, grad)
78 real(dp),
intent(in) :: r(gs%n_dim)
79 real(dp),
intent(out) :: grad(gs%n_dim)
81 real(dp) :: xrel(gs%n_dim)
85 xrel = (r-gs%r0(:, ix)) / gs%sigma(ix)
86 grad = grad - 2 * xrel/gs%sigma(ix) * &
87 gauss_single(gs, r, ix)
89 end subroutine gauss_gradient
92 real(dp) function gauss_laplacian(gs, r)
94 real(dp),
intent(in) :: r(gs%n_dim)
96 real(dp) :: xrel(gs%n_dim)
100 xrel = (r-gs%r0(:, ix)) / gs%sigma(ix)
101 gauss_laplacian = gauss_laplacian + 4/gs%sigma(ix)**2 * &
102 (sum(xrel**2) - 0.5_dp * gs%n_dim) * gauss_single(gs, r, ix)
104 end function gauss_laplacian
107 real(dp) function gauss_laplacian_cyl(gs, r)
108 type(
gauss_t),
intent(in) :: gs
109 real(dp),
intent(in) :: r(gs%n_dim)
111 real(dp) :: xrel(gs%n_dim)
113 gauss_laplacian_cyl = 0
114 do ix = 1, gs%n_gauss
115 xrel = (r-gs%r0(:, ix)) / gs%sigma(ix)
116 gauss_laplacian_cyl = gauss_laplacian_cyl + 4/gs%sigma(ix)**2 * &
117 (sum(xrel**2) - 1 - 0.5_dp * (r(1)-gs%r0(1, ix))/r(1)) * &
118 gauss_single(gs, r, ix)
120 end function gauss_laplacian_cyl
123 real(dp) function gauss_4th(gs, r)
124 type(
gauss_t),
intent(in) :: gs
125 real(dp),
intent(in) :: r(gs%n_dim)
127 real(dp) :: xrel(gs%n_dim), d4(gs%n_dim)
130 do ix = 1, gs%n_gauss
131 xrel = (r-gs%r0(:, ix)) / gs%sigma(ix)
132 d4 = d4 + gauss_single(gs, r, ix) / gs%sigma(ix)**4 * &
133 (16 * xrel**4 - 48 * xrel**2 + 12)
135 gauss_4th = norm2(d4)
136 end function gauss_4th
This module can be used to construct solutions consisting of one or more Gaussians.
A type to store a collection of gaussians in.