Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief utils to manipulate splines on the regular grid of a pw
10 : !> \par History
11 : !> 01.2014 move routines related to input_section_types to separate file.
12 : !> \author Ole Schuett
13 : ! **************************************************************************************************
14 : MODULE cp_spline_utils
15 : USE input_section_types, ONLY: section_vals_type,&
16 : section_vals_val_get
17 : USE kinds, ONLY: dp
18 : USE pw_methods, ONLY: do_standard_sum,&
19 : pw_axpy,&
20 : pw_zero
21 : USE pw_pool_types, ONLY: pw_pool_type
22 : USE pw_spline_utils, ONLY: &
23 : add_coarse2fine, add_fine2coarse, find_coeffs, pw_spline_do_precond, &
24 : pw_spline_precond_create, pw_spline_precond_release, pw_spline_precond_set_kind, &
25 : pw_spline_precond_type, spl3_1d_transf_border1, spl3_1d_transf_coeffs, spl3_nopbc, &
26 : spl3_nopbct, spl3_pbc
27 : USE pw_types, ONLY: pw_r3d_rs_type
28 : #include "../base/base_uses.f90"
29 :
30 : IMPLICIT NONE
31 : PRIVATE
32 :
33 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_spline_utils'
34 :
35 : PUBLIC :: pw_prolongate_s3, pw_restrict_s3
36 :
37 : ! input constants
38 : INTEGER, PARAMETER, PUBLIC :: pw_interp = 1, &
39 : spline3_nopbc_interp = 2, &
40 : spline3_pbc_interp = 3
41 :
42 : CONTAINS
43 :
44 : ! **************************************************************************************************
45 : !> \brief restricts the function from a fine grid to a coarse one
46 : !> \param pw_fine_in the fine grid
47 : !> \param pw_coarse_out the coarse grid
48 : !> \param coarse_pool ...
49 : !> \param param_section ...
50 : !> \author fawzi
51 : !> \note
52 : !> extremely slow (but correct) version
53 : ! **************************************************************************************************
54 9558 : SUBROUTINE pw_restrict_s3(pw_fine_in, pw_coarse_out, coarse_pool, param_section)
55 :
56 : TYPE(pw_r3d_rs_type), INTENT(IN) :: pw_fine_in
57 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: pw_coarse_out
58 : TYPE(pw_pool_type), POINTER :: coarse_pool
59 : TYPE(section_vals_type), POINTER :: param_section
60 :
61 : CHARACTER(len=*), PARAMETER :: routineN = 'pw_restrict_s3'
62 :
63 : INTEGER :: aint_precond, handle, interp_kind, &
64 : max_iter, precond_kind
65 : INTEGER, DIMENSION(2, 3) :: bo
66 : INTEGER, SAVE :: ifile = 0
67 : LOGICAL :: pbc, safe_computation, success
68 : REAL(kind=dp) :: eps_r, eps_x
69 : TYPE(pw_r3d_rs_type) :: coeffs, values
70 : TYPE(pw_spline_precond_type) :: precond
71 :
72 1062 : ifile = ifile + 1
73 1062 : CALL timeset(routineN, handle)
74 : CALL section_vals_val_get(param_section, "safe_computation", &
75 1062 : l_val=safe_computation)
76 : CALL section_vals_val_get(param_section, "aint_precond", &
77 1062 : i_val=aint_precond)
78 : CALL section_vals_val_get(param_section, "precond", &
79 1062 : i_val=precond_kind)
80 : CALL section_vals_val_get(param_section, "max_iter", &
81 1062 : i_val=max_iter)
82 : CALL section_vals_val_get(param_section, "eps_r", &
83 1062 : r_val=eps_r)
84 : CALL section_vals_val_get(param_section, "eps_x", &
85 1062 : r_val=eps_x)
86 : CALL section_vals_val_get(param_section, "kind", &
87 1062 : i_val=interp_kind)
88 :
89 1062 : pbc = (interp_kind == spline3_pbc_interp)
90 1062 : CPASSERT(pbc .OR. interp_kind == spline3_nopbc_interp)
91 10620 : bo = pw_coarse_out%pw_grid%bounds_local
92 1062 : CALL coarse_pool%create_pw(values)
93 1062 : CALL pw_zero(values)
94 :
95 : CALL add_fine2coarse(fine_values_pw=pw_fine_in, &
96 : coarse_coeffs_pw=values, &
97 : weights_1d=spl3_1d_transf_coeffs/2._dp, w_border0=0.5_dp, &
98 : w_border1=spl3_1d_transf_border1/2._dp, pbc=pbc, &
99 1062 : safe_computation=safe_computation)
100 :
101 1062 : CALL coarse_pool%create_pw(coeffs)
102 : CALL pw_spline_precond_create(precond, precond_kind=aint_precond, &
103 1062 : pool=coarse_pool, pbc=pbc, transpose=.TRUE.)
104 1062 : CALL pw_spline_do_precond(precond, values, coeffs)
105 1062 : CALL pw_spline_precond_set_kind(precond, precond_kind)
106 1062 : IF (pbc) THEN
107 : success = find_coeffs(values=values, coeffs=coeffs, &
108 : linOp=spl3_pbc, preconditioner=precond, pool=coarse_pool, &
109 0 : eps_r=eps_r, eps_x=eps_x, max_iter=max_iter, sumtype=do_standard_sum)
110 : ELSE
111 : success = find_coeffs(values=values, coeffs=coeffs, &
112 : linOp=spl3_nopbct, preconditioner=precond, pool=coarse_pool, &
113 1062 : eps_r=eps_r, eps_x=eps_x, max_iter=max_iter, sumtype=do_standard_sum)
114 : END IF
115 1062 : CALL pw_spline_precond_release(precond)
116 :
117 1062 : CALL pw_zero(pw_coarse_out)
118 1062 : CALL pw_axpy(coeffs, pw_coarse_out)
119 :
120 1062 : CALL coarse_pool%give_back_pw(values)
121 1062 : CALL coarse_pool%give_back_pw(coeffs)
122 1062 : CALL timestop(handle)
123 :
124 9558 : END SUBROUTINE pw_restrict_s3
125 :
126 : ! **************************************************************************************************
127 : !> \brief prolongates a function from a coarse grid into a fine one
128 : !> \param pw_coarse_in the coarse grid
129 : !> \param pw_fine_out the fine grid
130 : !> \param coarse_pool ...
131 : !> \param param_section ...
132 : !> \author fawzi
133 : !> \note
134 : !> extremely slow (but correct) version
135 : ! **************************************************************************************************
136 20340 : SUBROUTINE pw_prolongate_s3(pw_coarse_in, pw_fine_out, coarse_pool, &
137 : param_section)
138 : TYPE(pw_r3d_rs_type), INTENT(IN) :: pw_coarse_in, pw_fine_out
139 : TYPE(pw_pool_type), POINTER :: coarse_pool
140 : TYPE(section_vals_type), POINTER :: param_section
141 :
142 : CHARACTER(len=*), PARAMETER :: routineN = 'pw_prolongate_s3'
143 :
144 : INTEGER :: aint_precond, handle, interp_kind, &
145 : max_iter, precond_kind
146 : INTEGER, DIMENSION(2, 3) :: bo
147 : INTEGER, SAVE :: ifile = 0
148 : LOGICAL :: pbc, safe_computation, success
149 : REAL(kind=dp) :: eps_r, eps_x
150 : TYPE(pw_r3d_rs_type) :: coeffs
151 : TYPE(pw_spline_precond_type) :: precond
152 :
153 2260 : ifile = ifile + 1
154 2260 : CALL timeset(routineN, handle)
155 2260 : CALL coarse_pool%create_pw(coeffs)
156 22600 : bo = pw_coarse_in%pw_grid%bounds_local
157 : CALL section_vals_val_get(param_section, "safe_computation", &
158 2260 : l_val=safe_computation)
159 : CALL section_vals_val_get(param_section, "aint_precond", &
160 2260 : i_val=aint_precond)
161 : CALL section_vals_val_get(param_section, "precond", &
162 2260 : i_val=precond_kind)
163 : CALL section_vals_val_get(param_section, "max_iter", &
164 2260 : i_val=max_iter)
165 : CALL section_vals_val_get(param_section, "eps_r", &
166 2260 : r_val=eps_r)
167 : CALL section_vals_val_get(param_section, "eps_x", &
168 2260 : r_val=eps_x)
169 : CALL section_vals_val_get(param_section, "kind", &
170 2260 : i_val=interp_kind)
171 :
172 2260 : pbc = (interp_kind == spline3_pbc_interp)
173 2260 : CPASSERT(pbc .OR. interp_kind == spline3_nopbc_interp)
174 : CALL pw_spline_precond_create(precond, precond_kind=aint_precond, &
175 2260 : pool=coarse_pool, pbc=pbc, transpose=.FALSE.)
176 2260 : CALL pw_spline_do_precond(precond, pw_coarse_in, coeffs)
177 2260 : CALL pw_spline_precond_set_kind(precond, precond_kind)
178 2260 : IF (pbc) THEN
179 : success = find_coeffs(values=pw_coarse_in, coeffs=coeffs, &
180 : linOp=spl3_pbc, preconditioner=precond, pool=coarse_pool, &
181 : eps_r=eps_r, eps_x=eps_x, &
182 0 : max_iter=max_iter, sumtype=do_standard_sum)
183 : ELSE
184 : success = find_coeffs(values=pw_coarse_in, coeffs=coeffs, &
185 : linOp=spl3_nopbc, preconditioner=precond, pool=coarse_pool, &
186 : eps_r=eps_r, eps_x=eps_x, &
187 2260 : max_iter=max_iter, sumtype=do_standard_sum)
188 : END IF
189 2260 : CPASSERT(success)
190 2260 : CALL pw_spline_precond_release(precond)
191 :
192 : CALL add_coarse2fine(coarse_coeffs_pw=coeffs, &
193 : fine_values_pw=pw_fine_out, &
194 : weights_1d=spl3_1d_transf_coeffs, &
195 : w_border0=1._dp, &
196 : w_border1=spl3_1d_transf_border1, &
197 2260 : pbc=pbc, safe_computation=safe_computation)
198 :
199 2260 : CALL coarse_pool%give_back_pw(coeffs)
200 :
201 2260 : CALL timestop(handle)
202 :
203 20340 : END SUBROUTINE pw_prolongate_s3
204 :
205 : END MODULE cp_spline_utils
|