Afivo 0.3
All Classes Namespaces Functions Variables Pages
m_gaussians.f90
1!> This module can be used to construct solutions consisting of one or more
2!> Gaussians.
4
5 implicit none
6 private
7
8 integer, parameter :: dp = kind(0.0d0)
9
10 !> A type to store a collection of gaussians in
12 integer :: n_gauss !< Number of gaussians
13 integer :: n_dim !< Dimensionality
14 real(dp), allocatable :: ampl(:) !< Amplitudes
15 real(dp), allocatable :: sigma(:) !< Widths
16 real(dp), allocatable :: r0(:,:) !< Centers
17 end type gauss_t
18
19 public :: gauss_t
20 public :: gauss_init
21 public :: gauss_value
22 public :: gauss_gradient
23 public :: gauss_laplacian
24 public :: gauss_laplacian_cyl
25 public :: gauss_4th
26
27contains
28
29 !> Initialize a structure with parameters
30 subroutine gauss_init(gs, amplitudes, sigmas, locations)
31 type(gauss_t), intent(inout) :: gs !< Type storing the gaussians
32 real(dp), intent(in) :: amplitudes(:) !< Their amplitudes
33 real(dp), intent(in) :: sigmas(:) !< Their widths
34 real(dp), intent(in) :: locations(:,:) !< Their locations
35
36 if (size(locations, 2) /= size(amplitudes) .or. &
37 size(sigmas) /= size(amplitudes)) then
38 stop "gauss_init: arguments do not match in size"
39 end if
40
41 gs%n_gauss = size(amplitudes)
42 gs%n_dim = size(locations, 1)
43
44 allocate(gs%ampl(gs%n_gauss))
45 allocate(gs%sigma(gs%n_gauss))
46 allocate(gs%r0(gs%n_dim, gs%n_gauss))
47
48 gs%ampl = amplitudes
49 gs%sigma = sigmas
50 gs%r0 = locations
51 end subroutine gauss_init
52
53 !> Return the value of the sum of gaussians at r
54 real(dp) function gauss_value(gs, r)
55 type(gauss_t), intent(in) :: gs
56 real(dp), intent(in) :: r(gs%n_dim)
57 integer :: n
58
59 gauss_value = 0
60 do n = 1, gs%n_gauss
61 gauss_value = gauss_value + gauss_single(gs, r, n)
62 end do
63 end function gauss_value
64
65 !> Return the value of a single gaussian at r
66 real(dp) function gauss_single(gs, r, ix)
67 type(gauss_t), intent(in) :: gs
68 real(dp), intent(in) :: r(gs%n_dim)
69 integer, intent(in) :: ix
70 real(dp) :: xrel(gs%n_dim)
71
72 xrel = (r-gs%r0(:, ix)) / gs%sigma(ix)
73 gauss_single = gs%ampl(ix) * exp(-sum(xrel**2))
74 end function gauss_single
75
76 subroutine gauss_gradient(gs, r, grad)
77 type(gauss_t), intent(in) :: gs
78 real(dp), intent(in) :: r(gs%n_dim)
79 real(dp), intent(out) :: grad(gs%n_dim)
80 integer :: ix
81 real(dp) :: xrel(gs%n_dim)
82
83 grad = 0
84 do ix = 1, gs%n_gauss
85 xrel = (r-gs%r0(:, ix)) / gs%sigma(ix)
86 grad = grad - 2 * xrel/gs%sigma(ix) * &
87 gauss_single(gs, r, ix)
88 end do
89 end subroutine gauss_gradient
90
91 !> Summed Laplacian of the gaussians in Cartesian coordinates
92 real(dp) function gauss_laplacian(gs, r)
93 type(gauss_t), intent(in) :: gs
94 real(dp), intent(in) :: r(gs%n_dim)
95 integer :: ix
96 real(dp) :: xrel(gs%n_dim)
97
98 gauss_laplacian = 0
99 do ix = 1, gs%n_gauss
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)
103 end do
104 end function gauss_laplacian
105
106 !> Summed Laplacian of the gaussians in (r,z) coordinates
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)
110 integer :: ix
111 real(dp) :: xrel(gs%n_dim)
112
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)
119 end do
120 end function gauss_laplacian_cyl
121
122 !> Fourth derivative of the gaussians in Cartesian coordinates
123 real(dp) function gauss_4th(gs, r)
124 type(gauss_t), intent(in) :: gs
125 real(dp), intent(in) :: r(gs%n_dim)
126 integer :: ix
127 real(dp) :: xrel(gs%n_dim), d4(gs%n_dim)
128
129 d4 = 0
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)
134 end do
135 gauss_4th = norm2(d4)
136 end function gauss_4th
137
138end module m_gaussians
This module can be used to construct solutions consisting of one or more Gaussians.
Definition: m_gaussians.f90:3
A type to store a collection of gaussians in.
Definition: m_gaussians.f90:11