(git:08825b9)
Loading...
Searching...
No Matches
pw_poisson_methods.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \par History
10!> 09.2005 created [fawzi]
11!> \author fawzi
12! **************************************************************************************************
14
17 USE kinds, ONLY: dp
18 USE mathconstants, ONLY: fourpi
19 USE mt_util, ONLY: mt0d, &
20 mt1d, &
27 USE ps_implicit_types, ONLY: mixed_bc, &
29 neumann_bc, &
35 USE ps_wavelet_types, ONLY: wavelet0d, &
36 wavelet1d, &
37 wavelet2d, &
38 wavelet3d, &
41 USE pw_grids, ONLY: pw_grid_compare, &
44 USE pw_methods, ONLY: pw_copy, &
45 pw_derive, &
48 USE pw_poisson_types, ONLY: &
53 USE pw_pool_types, ONLY: pw_pool_p_type, &
57 USE pw_types, ONLY: &
59#include "../base/base_uses.f90"
60
61 IMPLICIT NONE
62 PRIVATE
63
64 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
65 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pw_poisson_methods'
66
67 PUBLIC :: pw_poisson_rebuild, &
69
70 INTEGER, PARAMETER :: use_rs_grid = 0, &
71 use_gs_grid = 1
72
74 MODULE PROCEDURE pw_poisson_rebuild_nodens
75 MODULE PROCEDURE pw_poisson_rebuild_c1d_gs, pw_poisson_rebuild_r3d_rs
76 END INTERFACE
77
79 MODULE PROCEDURE pw_poisson_solve_nov_nodv_r3d_rs
80 MODULE PROCEDURE pw_poisson_solve_v_nodv_r3d_rs_r3d_rs
81 MODULE PROCEDURE pw_poisson_solve_v_nodv_r3d_rs_c1d_gs
82 MODULE PROCEDURE pw_poisson_solve_nov_dv_r3d_rs_r3d_rs
83 MODULE PROCEDURE pw_poisson_solve_v_dv_r3d_rs_r3d_rs_r3d_rs
84 MODULE PROCEDURE pw_poisson_solve_v_dv_r3d_rs_c1d_gs_r3d_rs
85 MODULE PROCEDURE pw_poisson_solve_nov_dv_r3d_rs_c1d_gs
86 MODULE PROCEDURE pw_poisson_solve_v_dv_r3d_rs_r3d_rs_c1d_gs
87 MODULE PROCEDURE pw_poisson_solve_v_dv_r3d_rs_c1d_gs_c1d_gs
88 MODULE PROCEDURE pw_poisson_solve_nov_nodv_c1d_gs
89 MODULE PROCEDURE pw_poisson_solve_v_nodv_c1d_gs_r3d_rs
90 MODULE PROCEDURE pw_poisson_solve_v_nodv_c1d_gs_c1d_gs
91 MODULE PROCEDURE pw_poisson_solve_nov_dv_c1d_gs_r3d_rs
92 MODULE PROCEDURE pw_poisson_solve_v_dv_c1d_gs_r3d_rs_r3d_rs
93 MODULE PROCEDURE pw_poisson_solve_v_dv_c1d_gs_c1d_gs_r3d_rs
94 MODULE PROCEDURE pw_poisson_solve_nov_dv_c1d_gs_c1d_gs
95 MODULE PROCEDURE pw_poisson_solve_v_dv_c1d_gs_r3d_rs_c1d_gs
96 MODULE PROCEDURE pw_poisson_solve_v_dv_c1d_gs_c1d_gs_c1d_gs
97 END INTERFACE
98
99 INTERFACE mt2d_hartree_stress
100 MODULE PROCEDURE mt2d_hartree_stress_r3d_rs, mt2d_hartree_stress_c1d_gs
101 END INTERFACE
102
103CONTAINS
104
105! **************************************************************************************************
106!> \brief removes all the object created from the parameters pw_pools and cell
107!> and used to solve the poisson equation like the green function and
108!> all the things allocated in pw_poisson_rebuild
109!> \param poisson_env ...
110!> \par History
111!> none
112! **************************************************************************************************
113 SUBROUTINE pw_poisson_cleanup(poisson_env)
114 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
115
116 TYPE(pw_pool_type), POINTER :: pw_pool
117
118 NULLIFY (pw_pool)
119 IF (ASSOCIATED(poisson_env%pw_pools)) THEN
120 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
121 END IF
122 IF (ASSOCIATED(poisson_env%green_fft)) THEN
123 CALL pw_green_release(poisson_env%green_fft, pw_pool=pw_pool)
124 DEALLOCATE (poisson_env%green_fft)
125 END IF
126 poisson_env%rebuild = .true.
127
128 END SUBROUTINE pw_poisson_cleanup
129
130! **************************************************************************************************
131!> \brief checks if pw_poisson_rebuild has to be called and calls it if needed
132!> \param poisson_env the object to be checked
133!> \author fawzi
134! **************************************************************************************************
135 SUBROUTINE pw_poisson_check(poisson_env)
136 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
137
138 LOGICAL :: rebuild
139 TYPE(greens_fn_type), POINTER :: green
140 TYPE(ps_wavelet_type), POINTER :: wavelet
141
142 cpassert(ASSOCIATED(poisson_env%pw_pools))
143 cpassert(poisson_env%pw_level >= lbound(poisson_env%pw_pools, 1))
144 cpassert(poisson_env%pw_level <= ubound(poisson_env%pw_pools, 1))
145 green => poisson_env%green_fft
146 wavelet => poisson_env%wavelet
147 rebuild = poisson_env%rebuild
148 rebuild = rebuild .OR. (poisson_env%method /= poisson_env%parameters%solver) &
149 .OR. .NOT. ASSOCIATED(green)
150 poisson_env%method = poisson_env%parameters%solver
151
152 IF (poisson_env%method == pw_poisson_wavelet) THEN
153 poisson_env%used_grid = use_rs_grid
154 ELSE
155 poisson_env%used_grid = use_gs_grid
156 END IF
157 IF (.NOT. rebuild) THEN
158 IF (poisson_env%parameters%ewald_type == do_ewald_spme) THEN
159 rebuild = (poisson_env%parameters%ewald_alpha /= green%p3m_alpha) .OR. rebuild
160 rebuild = (poisson_env%parameters%ewald_o_spline /= green%p3m_order) .OR. rebuild
161 END IF
162 SELECT CASE (poisson_env%method)
164 SELECT CASE (green%method)
166 CASE default
167 rebuild = .true.
168 END SELECT
169 CASE (pw_poisson_mt)
170 SELECT CASE (green%method)
171 CASE (mt0d, mt1d, mt2d)
172 CASE default
173 rebuild = .true.
174 END SELECT
175 rebuild = (poisson_env%parameters%mt_alpha /= green%mt_alpha) .OR. rebuild
176 CASE (pw_poisson_wavelet)
177 rebuild = (poisson_env%parameters%wavelet_scf_type /= wavelet%itype_scf) .OR. rebuild
178 CASE default
179 cpabort("Unknown Poisson solver")
180 END SELECT
181 END IF
182 IF (rebuild) THEN
183 poisson_env%rebuild = .true.
184 CALL pw_poisson_cleanup(poisson_env)
185 END IF
186 END SUBROUTINE pw_poisson_check
187
188! **************************************************************************************************
189!> \brief rebuilds all the internal values needed to use the poisson solver
190!> \param poisson_env the environment to rebuild
191!> \param density ...
192!> \author fawzi
193!> \note
194!> rebuilds if poisson_env%rebuild is true
195! **************************************************************************************************
196 SUBROUTINE pw_poisson_rebuild_nodens(poisson_env)
197 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
198
199 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_rebuild'
200
201 INTEGER :: handle
202
203 CALL timeset(routinen, handle)
204
205 cpassert(ASSOCIATED(poisson_env%pw_pools))
206
207 IF (poisson_env%rebuild) THEN
208 CALL pw_poisson_cleanup(poisson_env)
209 SELECT CASE (poisson_env%parameters%solver)
211 ALLOCATE (poisson_env%green_fft)
212 CALL pw_green_create(poisson_env%green_fft, cell_hmat=poisson_env%cell_hmat, &
213 pw_pool=poisson_env%pw_pools(poisson_env%pw_level)%pool, &
214 poisson_params=poisson_env%parameters, &
215 mt_super_ref_pw_grid=poisson_env%mt_super_ref_pw_grid, &
216 dct_pw_grid=poisson_env%dct_pw_grid)
217 CASE (pw_poisson_wavelet)
218 cpabort("Wavelet solver requires a density!")
220 ALLOCATE (poisson_env%green_fft)
221 CALL pw_green_create(poisson_env%green_fft, cell_hmat=poisson_env%cell_hmat, &
222 pw_pool=poisson_env%pw_pools(poisson_env%pw_level)%pool, &
223 poisson_params=poisson_env%parameters, &
224 mt_super_ref_pw_grid=poisson_env%mt_super_ref_pw_grid, &
225 dct_pw_grid=poisson_env%dct_pw_grid)
226 CALL ps_implicit_create(poisson_env%pw_pools(poisson_env%pw_level)%pool, &
227 poisson_env%parameters, &
228 poisson_env%dct_pw_grid, &
229 poisson_env%green_fft, poisson_env%implicit_env)
230 CASE (pw_poisson_none)
231 CASE default
232 cpabort("Unknown Poisson solver")
233 END SELECT
234 poisson_env%rebuild = .false.
235 END IF
236
237 CALL timestop(handle)
238
239 END SUBROUTINE pw_poisson_rebuild_nodens
240
241! **************************************************************************************************
242!> \brief rebuilds all the internal values needed to use the poisson solver
243!> \param poisson_env the environment to rebuild
244!> \param density ...
245!> \author fawzi
246!> \note
247!> rebuilds if poisson_env%rebuild is true
248! **************************************************************************************************
249 SUBROUTINE pw_poisson_rebuild_r3d_rs (poisson_env, density)
250 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
251 TYPE(pw_r3d_rs_type), INTENT(IN) :: density
252
253 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_rebuild'
254
255 INTEGER :: handle
256
257 CALL timeset(routinen, handle)
258
259 cpassert(ASSOCIATED(poisson_env%pw_pools))
260
261 IF (poisson_env%rebuild) THEN
262 CALL pw_poisson_cleanup(poisson_env)
263 SELECT CASE (poisson_env%parameters%solver)
265 ALLOCATE (poisson_env%green_fft)
266 CALL pw_green_create(poisson_env%green_fft, cell_hmat=poisson_env%cell_hmat, &
267 pw_pool=poisson_env%pw_pools(poisson_env%pw_level)%pool, &
268 poisson_params=poisson_env%parameters, &
269 mt_super_ref_pw_grid=poisson_env%mt_super_ref_pw_grid, &
270 dct_pw_grid=poisson_env%dct_pw_grid)
271 CASE (pw_poisson_wavelet)
272 cpassert(ASSOCIATED(density%pw_grid))
273 CALL ps_wavelet_create(poisson_env%parameters, poisson_env%wavelet, &
274 density%pw_grid)
276 ALLOCATE (poisson_env%green_fft)
277 CALL pw_green_create(poisson_env%green_fft, cell_hmat=poisson_env%cell_hmat, &
278 pw_pool=poisson_env%pw_pools(poisson_env%pw_level)%pool, &
279 poisson_params=poisson_env%parameters, &
280 mt_super_ref_pw_grid=poisson_env%mt_super_ref_pw_grid, &
281 dct_pw_grid=poisson_env%dct_pw_grid)
282 CALL ps_implicit_create(poisson_env%pw_pools(poisson_env%pw_level)%pool, &
283 poisson_env%parameters, &
284 poisson_env%dct_pw_grid, &
285 poisson_env%green_fft, poisson_env%implicit_env)
286 CASE (pw_poisson_none)
287 CASE default
288 cpabort("Unknown Poisson solver")
289 END SELECT
290 poisson_env%rebuild = .false.
291 END IF
292
293 CALL timestop(handle)
294
295 END SUBROUTINE pw_poisson_rebuild_r3d_rs
296! **************************************************************************************************
297!> \brief rebuilds all the internal values needed to use the poisson solver
298!> \param poisson_env the environment to rebuild
299!> \param density ...
300!> \author fawzi
301!> \note
302!> rebuilds if poisson_env%rebuild is true
303! **************************************************************************************************
304 SUBROUTINE pw_poisson_rebuild_c1d_gs (poisson_env, density)
305 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
306 TYPE(pw_c1d_gs_type), INTENT(IN) :: density
307
308 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_rebuild'
309
310 INTEGER :: handle
311
312 CALL timeset(routinen, handle)
313
314 cpassert(ASSOCIATED(poisson_env%pw_pools))
315
316 IF (poisson_env%rebuild) THEN
317 CALL pw_poisson_cleanup(poisson_env)
318 SELECT CASE (poisson_env%parameters%solver)
320 ALLOCATE (poisson_env%green_fft)
321 CALL pw_green_create(poisson_env%green_fft, cell_hmat=poisson_env%cell_hmat, &
322 pw_pool=poisson_env%pw_pools(poisson_env%pw_level)%pool, &
323 poisson_params=poisson_env%parameters, &
324 mt_super_ref_pw_grid=poisson_env%mt_super_ref_pw_grid, &
325 dct_pw_grid=poisson_env%dct_pw_grid)
326 CASE (pw_poisson_wavelet)
327 cpassert(ASSOCIATED(density%pw_grid))
328 CALL ps_wavelet_create(poisson_env%parameters, poisson_env%wavelet, &
329 density%pw_grid)
331 ALLOCATE (poisson_env%green_fft)
332 CALL pw_green_create(poisson_env%green_fft, cell_hmat=poisson_env%cell_hmat, &
333 pw_pool=poisson_env%pw_pools(poisson_env%pw_level)%pool, &
334 poisson_params=poisson_env%parameters, &
335 mt_super_ref_pw_grid=poisson_env%mt_super_ref_pw_grid, &
336 dct_pw_grid=poisson_env%dct_pw_grid)
337 CALL ps_implicit_create(poisson_env%pw_pools(poisson_env%pw_level)%pool, &
338 poisson_env%parameters, &
339 poisson_env%dct_pw_grid, &
340 poisson_env%green_fft, poisson_env%implicit_env)
341 CASE (pw_poisson_none)
342 CASE default
343 cpabort("Unknown Poisson solver")
344 END SELECT
345 poisson_env%rebuild = .false.
346 END IF
347
348 CALL timestop(handle)
349
350 END SUBROUTINE pw_poisson_rebuild_c1d_gs
351
352! **************************************************************************************************
353!> \brief Solve Poisson equation in a plane wave basis set
354!> Obtains electrostatic potential and its derivatives with respect to r
355!> from the density
356!> \param poisson_env ...
357!> \param density ...
358!> \param ehartree ...
359!> \param h_stress ...
360!> \param rho_core ...
361!> \param greenfn ...
362!> \param aux_density Hartree energy and stress tensor between 2 different densities
363!> \par History
364!> JGH (13-Mar-2001) : completely revised
365!> \author apsi
366! **************************************************************************************************
367 SUBROUTINE pw_poisson_solve_nov_nodv_r3d_rs (poisson_env, density, ehartree, &
368 h_stress, rho_core, greenfn, aux_density)
369
370 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
371 TYPE(pw_r3d_rs_type), INTENT(IN) :: density
372 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
373 REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT), &
374 OPTIONAL :: h_stress
375 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
376 TYPE(pw_r3d_rs_type), INTENT(IN), OPTIONAL :: aux_density
377
378 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
379
380 INTEGER :: handle
381 LOGICAL :: has_dielectric
382 TYPE(pw_grid_type), POINTER :: pw_grid
383 TYPE(pw_pool_type), POINTER :: pw_pool
384 TYPE(pw_r3d_rs_type) :: rhor, vhartree_rs
385 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux, tmpg
386
387 CALL timeset(routinen, handle)
388
389 CALL pw_poisson_rebuild(poisson_env, density)
390
391 has_dielectric = poisson_env%parameters%has_dielectric
392
393 ! point pw
394 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
395 pw_grid => pw_pool%pw_grid
396 ! density in G space
397 CALL pw_pool%create_pw(rhog)
398 IF (PRESENT(aux_density)) THEN
399 CALL pw_pool%create_pw(rhog_aux)
400 END IF
401
402 SELECT CASE (poisson_env%used_grid)
403 CASE (use_gs_grid)
404
405 SELECT CASE (poisson_env%green_fft%method)
407
408 CALL pw_transfer(density, rhog)
409 IF (PRESENT(aux_density)) THEN
410 CALL pw_transfer(aux_density, rhog_aux)
411 END IF
412 IF (PRESENT(ehartree)) THEN
413 CALL pw_pool%create_pw(tmpg)
414 CALL pw_copy(rhog, tmpg)
415 END IF
416 IF (PRESENT(greenfn)) THEN
417 influence_fn = greenfn
418 ELSE
419 influence_fn = poisson_env%green_fft%influence_fn
420 END IF
421 CALL pw_multiply_with(rhog, influence_fn)
422 IF (PRESENT(aux_density)) THEN
423 CALL pw_multiply_with(rhog_aux, influence_fn)
424 END IF
425 IF (PRESENT(ehartree)) THEN
426 IF (PRESENT(aux_density)) THEN
427 ehartree = 0.5_dp*pw_integral_ab(rhog_aux, tmpg)
428 ELSE
429 ehartree = 0.5_dp*pw_integral_ab(rhog, tmpg)
430 END IF
431 CALL pw_pool%give_back_pw(tmpg)
432 END IF
433
434 CASE (ps_implicit)
435
436 IF (PRESENT(h_stress)) THEN
437 cpabort("No stress tensor is implemented for the implicit Poisson solver.")
438 END IF
439
440 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
441 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
443 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
444 poisson_env%diel_rs_grid, &
445 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
446 density, rho_core=rho_core)
447 CASE (neumann_bc, mixed_bc)
448 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
449 poisson_env%diel_rs_grid, &
450 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
451 poisson_env%dct_pw_grid, &
452 poisson_env%parameters%ps_implicit_params%neumann_directions, &
453 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
454 poisson_env%implicit_env%dct_env%dests_expand, &
455 poisson_env%implicit_env%dct_env%srcs_expand, &
456 poisson_env%implicit_env%dct_env%flipg_stat, &
457 poisson_env%implicit_env%dct_env%bounds_shftd, &
458 density, rho_core=rho_core)
459 END SELECT
460 END IF
461
462 CALL pw_pool%create_pw(rhor)
463 CALL pw_pool%create_pw(vhartree_rs)
464 CALL pw_transfer(density, rhor)
465
466 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
467 CASE (periodic_bc)
468 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
469 ehartree=ehartree)
470 CASE (neumann_bc)
471 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
472 ehartree=ehartree)
473 CASE (mixed_periodic_bc)
474 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
475 electric_enthalpy=ehartree)
476 CASE (mixed_bc)
477 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
478 electric_enthalpy=ehartree)
479 END SELECT
480
481 IF (PRESENT(aux_density)) THEN
482 CALL pw_transfer(aux_density, rhor)
483 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
484 END IF
485
486 CALL pw_pool%give_back_pw(rhor)
487 CALL pw_pool%give_back_pw(vhartree_rs)
488
489 CASE DEFAULT
490 CALL cp_abort(__location__, &
491 "unknown poisson method "// &
492 cp_to_string(poisson_env%green_fft%method))
493 END SELECT
494
495 CASE (use_rs_grid)
496
497 CALL pw_pool%create_pw(rhor)
498 CALL pw_transfer(density, rhor)
499 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
500 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
501 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
502 IF (PRESENT(ehartree)) THEN
503 IF (PRESENT(aux_density)) THEN
504 ehartree = 0.5_dp*pw_integral_ab(aux_density, rhor)
505 ELSE
506 ehartree = 0.5_dp*pw_integral_ab(density, rhor)
507 END IF
508 END IF
509 IF (PRESENT(h_stress)) THEN
510 CALL pw_transfer(rhor, rhog)
511 IF (PRESENT(aux_density)) THEN
512 CALL pw_transfer(aux_density, rhor)
513 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
514 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
515 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
516 CALL pw_transfer(rhor, rhog_aux)
517 END IF
518 END IF
519 CALL pw_pool%give_back_pw(rhor)
520
521 END SELECT
522
523 IF (PRESENT(aux_density)) THEN
524 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, rhog_aux, h_stress)
525 ELSE
526 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, h_stress=h_stress)
527 END IF
528 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
529
530 CALL pw_pool%give_back_pw(rhog)
531 IF (PRESENT(aux_density)) THEN
532 CALL pw_pool%give_back_pw(rhog_aux)
533 END IF
534
535 CALL timestop(handle)
536
537 END SUBROUTINE pw_poisson_solve_nov_nodv_r3d_rs
538! **************************************************************************************************
539!> \brief Solve Poisson equation in a plane wave basis set
540!> Obtains electrostatic potential and its derivatives with respect to r
541!> from the density
542!> \param poisson_env ...
543!> \param density ...
544!> \param ehartree ...
545!> \param h_stress ...
546!> \param rho_core ...
547!> \param greenfn ...
548!> \param aux_density Hartree energy and stress tensor between 2 different densities
549!> \par History
550!> JGH (13-Mar-2001) : completely revised
551!> \author apsi
552! **************************************************************************************************
553 SUBROUTINE pw_poisson_solve_nov_nodv_c1d_gs (poisson_env, density, ehartree, &
554 h_stress, rho_core, greenfn, aux_density)
555
556 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
557 TYPE(pw_c1d_gs_type), INTENT(IN) :: density
558 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
559 REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT), &
560 OPTIONAL :: h_stress
561 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
562 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: aux_density
563
564 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
565
566 INTEGER :: handle
567 LOGICAL :: has_dielectric
568 TYPE(pw_grid_type), POINTER :: pw_grid
569 TYPE(pw_pool_type), POINTER :: pw_pool
570 TYPE(pw_r3d_rs_type) :: rhor, vhartree_rs
571 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux, tmpg
572
573 CALL timeset(routinen, handle)
574
575 CALL pw_poisson_rebuild(poisson_env, density)
576
577 has_dielectric = poisson_env%parameters%has_dielectric
578
579 ! point pw
580 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
581 pw_grid => pw_pool%pw_grid
582 ! density in G space
583 CALL pw_pool%create_pw(rhog)
584 IF (PRESENT(aux_density)) THEN
585 CALL pw_pool%create_pw(rhog_aux)
586 END IF
587
588 SELECT CASE (poisson_env%used_grid)
589 CASE (use_gs_grid)
590
591 SELECT CASE (poisson_env%green_fft%method)
593
594 CALL pw_transfer(density, rhog)
595 IF (PRESENT(aux_density)) THEN
596 CALL pw_transfer(aux_density, rhog_aux)
597 END IF
598 IF (PRESENT(ehartree)) THEN
599 CALL pw_pool%create_pw(tmpg)
600 CALL pw_copy(rhog, tmpg)
601 END IF
602 IF (PRESENT(greenfn)) THEN
603 influence_fn = greenfn
604 ELSE
605 influence_fn = poisson_env%green_fft%influence_fn
606 END IF
607 CALL pw_multiply_with(rhog, influence_fn)
608 IF (PRESENT(aux_density)) THEN
609 CALL pw_multiply_with(rhog_aux, influence_fn)
610 END IF
611 IF (PRESENT(ehartree)) THEN
612 IF (PRESENT(aux_density)) THEN
613 ehartree = 0.5_dp*pw_integral_ab(rhog_aux, tmpg)
614 ELSE
615 ehartree = 0.5_dp*pw_integral_ab(rhog, tmpg)
616 END IF
617 CALL pw_pool%give_back_pw(tmpg)
618 END IF
619
620 CASE (ps_implicit)
621
622 IF (PRESENT(h_stress)) THEN
623 cpabort("No stress tensor is implemented for the implicit Poisson solver.")
624 END IF
625
626 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
627 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
629 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
630 poisson_env%diel_rs_grid, &
631 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
632 density, rho_core=rho_core)
633 CASE (neumann_bc, mixed_bc)
634 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
635 poisson_env%diel_rs_grid, &
636 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
637 poisson_env%dct_pw_grid, &
638 poisson_env%parameters%ps_implicit_params%neumann_directions, &
639 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
640 poisson_env%implicit_env%dct_env%dests_expand, &
641 poisson_env%implicit_env%dct_env%srcs_expand, &
642 poisson_env%implicit_env%dct_env%flipg_stat, &
643 poisson_env%implicit_env%dct_env%bounds_shftd, &
644 density, rho_core=rho_core)
645 END SELECT
646 END IF
647
648 CALL pw_pool%create_pw(rhor)
649 CALL pw_pool%create_pw(vhartree_rs)
650 CALL pw_transfer(density, rhor)
651
652 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
653 CASE (periodic_bc)
654 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
655 ehartree=ehartree)
656 CASE (neumann_bc)
657 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
658 ehartree=ehartree)
659 CASE (mixed_periodic_bc)
660 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
661 electric_enthalpy=ehartree)
662 CASE (mixed_bc)
663 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
664 electric_enthalpy=ehartree)
665 END SELECT
666
667 IF (PRESENT(aux_density)) THEN
668 CALL pw_transfer(aux_density, rhor)
669 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
670 END IF
671
672 CALL pw_pool%give_back_pw(rhor)
673 CALL pw_pool%give_back_pw(vhartree_rs)
674
675 CASE DEFAULT
676 CALL cp_abort(__location__, &
677 "unknown poisson method "// &
678 cp_to_string(poisson_env%green_fft%method))
679 END SELECT
680
681 CASE (use_rs_grid)
682
683 CALL pw_pool%create_pw(rhor)
684 CALL pw_transfer(density, rhor)
685 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
686 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
687 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
688 IF (PRESENT(ehartree)) THEN
689 IF (PRESENT(aux_density)) THEN
690 IF (.NOT. PRESENT(h_stress)) CALL pw_pool%create_pw(rhog)
691 CALL pw_transfer(rhor, rhog)
692 ehartree = 0.5_dp*pw_integral_ab(aux_density, rhog)
693 IF (.NOT. PRESENT(h_stress)) CALL pw_pool%give_back_pw(rhog)
694 ELSE
695 IF (.NOT. PRESENT(h_stress)) CALL pw_pool%create_pw(rhog)
696 CALL pw_transfer(rhor, rhog)
697 ehartree = 0.5_dp*pw_integral_ab(density, rhog)
698 IF (.NOT. PRESENT(h_stress)) CALL pw_pool%give_back_pw(rhog)
699 END IF
700 END IF
701 IF (PRESENT(h_stress)) THEN
702 CALL pw_transfer(rhor, rhog)
703 IF (PRESENT(aux_density)) THEN
704 CALL pw_transfer(aux_density, rhor)
705 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
706 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
707 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
708 CALL pw_transfer(rhor, rhog_aux)
709 END IF
710 END IF
711 CALL pw_pool%give_back_pw(rhor)
712
713 END SELECT
714
715 IF (PRESENT(aux_density)) THEN
716 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, rhog_aux, h_stress)
717 ELSE
718 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, h_stress=h_stress)
719 END IF
720 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
721
722 CALL pw_pool%give_back_pw(rhog)
723 IF (PRESENT(aux_density)) THEN
724 CALL pw_pool%give_back_pw(rhog_aux)
725 END IF
726
727 CALL timestop(handle)
728
729 END SUBROUTINE pw_poisson_solve_nov_nodv_c1d_gs
730
731! **************************************************************************************************
732!> \brief Solve Poisson equation in a plane wave basis set
733!> Obtains electrostatic potential and its derivatives with respect to r
734!> from the density
735!> \param poisson_env ...
736!> \param density ...
737!> \param ehartree ...
738!> \param vhartree ...
739!> \param h_stress ...
740!> \param rho_core ...
741!> \param greenfn ...
742!> \param aux_density Hartree energy and stress tensor between 2 different densities
743!> \par History
744!> JGH (13-Mar-2001) : completely revised
745!> \author apsi
746! **************************************************************************************************
747 SUBROUTINE pw_poisson_solve_v_nodv_r3d_rs_r3d_rs (poisson_env, density, ehartree, vhartree, &
748 h_stress, rho_core, greenfn, aux_density)
749
750 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
751 TYPE(pw_r3d_rs_type), INTENT(IN) :: density
752 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
753 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: vhartree
754 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT), &
755 OPTIONAL :: h_stress
756 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
757 TYPE(pw_r3d_rs_type), INTENT(IN), OPTIONAL :: aux_density
758
759 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
760
761 INTEGER :: handle
762 LOGICAL :: has_dielectric
763 TYPE(pw_grid_type), POINTER :: pw_grid
764 TYPE(pw_pool_type), POINTER :: pw_pool
765 TYPE(pw_r3d_rs_type) :: &
766 rhor, vhartree_rs
767 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
768
769 CALL timeset(routinen, handle)
770
771 CALL pw_poisson_rebuild(poisson_env, density)
772
773 has_dielectric = poisson_env%parameters%has_dielectric
774
775 ! point pw
776 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
777 pw_grid => pw_pool%pw_grid
778 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
779 cpabort("vhartree has a different grid than the poisson solver")
780 END IF
781 ! density in G space
782 CALL pw_pool%create_pw(rhog)
783 IF (PRESENT(aux_density)) THEN
784 CALL pw_pool%create_pw(rhog_aux)
785 END IF
786
787 SELECT CASE (poisson_env%used_grid)
788 CASE (use_gs_grid)
789
790 SELECT CASE (poisson_env%green_fft%method)
792
793 CALL pw_transfer(density, rhog)
794 IF (PRESENT(aux_density)) THEN
795 CALL pw_transfer(aux_density, rhog_aux)
796 END IF
797 IF (PRESENT(greenfn)) THEN
798 influence_fn = greenfn
799 ELSE
800 influence_fn = poisson_env%green_fft%influence_fn
801 END IF
802 CALL pw_multiply_with(rhog, influence_fn)
803 IF (PRESENT(aux_density)) THEN
804 CALL pw_multiply_with(rhog_aux, influence_fn)
805 END IF
806 CALL pw_transfer(rhog, vhartree)
807 IF (PRESENT(ehartree)) THEN
808 IF (PRESENT(aux_density)) THEN
809 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
810 ELSE
811 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
812 END IF
813 END IF
814
815 CASE (ps_implicit)
816 IF (PRESENT(h_stress)) THEN
817 cpabort("No stress tensor is implemented for the implicit Poisson solver.")
818 END IF
819
820 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
821 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
823 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
824 poisson_env%diel_rs_grid, &
825 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
826 density, rho_core=rho_core)
827 CASE (neumann_bc, mixed_bc)
828 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
829 poisson_env%diel_rs_grid, &
830 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
831 poisson_env%dct_pw_grid, &
832 poisson_env%parameters%ps_implicit_params%neumann_directions, &
833 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
834 poisson_env%implicit_env%dct_env%dests_expand, &
835 poisson_env%implicit_env%dct_env%srcs_expand, &
836 poisson_env%implicit_env%dct_env%flipg_stat, &
837 poisson_env%implicit_env%dct_env%bounds_shftd, &
838 density, rho_core=rho_core)
839 END SELECT
840 END IF
841
842 CALL pw_pool%create_pw(rhor)
843 CALL pw_pool%create_pw(vhartree_rs)
844 CALL pw_transfer(density, rhor)
845
846 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
847 CASE (periodic_bc)
848 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
849 ehartree=ehartree)
850 CASE (neumann_bc)
851 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
852 ehartree=ehartree)
853 CASE (mixed_periodic_bc)
854 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
855 electric_enthalpy=ehartree)
856 CASE (mixed_bc)
857 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
858 electric_enthalpy=ehartree)
859 END SELECT
860
861 IF (PRESENT(aux_density)) THEN
862 CALL pw_transfer(aux_density, rhor)
863 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
864 END IF
865
866 CALL pw_transfer(vhartree_rs, vhartree)
867
868 CALL pw_pool%give_back_pw(rhor)
869 CALL pw_pool%give_back_pw(vhartree_rs)
870
871 CASE DEFAULT
872 CALL cp_abort(__location__, &
873 "unknown poisson method "// &
874 cp_to_string(poisson_env%green_fft%method))
875 END SELECT
876
877 CASE (use_rs_grid)
878
879 CALL pw_pool%create_pw(rhor)
880 CALL pw_transfer(density, rhor)
881 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
882 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
883 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
884 CALL pw_transfer(rhor, vhartree)
885 IF (PRESENT(ehartree)) THEN
886 IF (PRESENT(aux_density)) THEN
887 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
888 ELSE
889 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
890 END IF
891 END IF
892 IF (PRESENT(h_stress)) THEN
893 CALL pw_transfer(rhor, rhog)
894 IF (PRESENT(aux_density)) THEN
895 CALL pw_transfer(aux_density, rhor)
896 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
897 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
898 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
899 CALL pw_transfer(rhor, rhog_aux)
900 END IF
901 END IF
902 CALL pw_pool%give_back_pw(rhor)
903
904 END SELECT
905
906 IF (PRESENT(aux_density)) THEN
907 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, rhog_aux, h_stress)
908 ELSE
909 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, h_stress=h_stress)
910 END IF
911 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
912
913 CALL pw_pool%give_back_pw(rhog)
914 IF (PRESENT(aux_density)) THEN
915 CALL pw_pool%give_back_pw(rhog_aux)
916 END IF
917
918 CALL timestop(handle)
919
920 END SUBROUTINE pw_poisson_solve_v_nodv_r3d_rs_r3d_rs
921! **************************************************************************************************
922!> \brief Solve Poisson equation in a plane wave basis set
923!> Obtains electrostatic potential and its derivatives with respect to r
924!> from the density
925!> \param poisson_env ...
926!> \param density ...
927!> \param ehartree ...
928!> \param vhartree ...
929!> \param h_stress ...
930!> \param rho_core ...
931!> \param greenfn ...
932!> \param aux_density Hartree energy and stress tensor between 2 different densities
933!> \par History
934!> JGH (13-Mar-2001) : completely revised
935!> \author apsi
936! **************************************************************************************************
937 SUBROUTINE pw_poisson_solve_v_nodv_r3d_rs_c1d_gs (poisson_env, density, ehartree, vhartree, &
938 h_stress, rho_core, greenfn, aux_density)
939
940 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
941 TYPE(pw_r3d_rs_type), INTENT(IN) :: density
942 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
943 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: vhartree
944 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT), &
945 OPTIONAL :: h_stress
946 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
947 TYPE(pw_r3d_rs_type), INTENT(IN), OPTIONAL :: aux_density
948
949 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
950
951 INTEGER :: handle
952 LOGICAL :: has_dielectric
953 TYPE(pw_grid_type), POINTER :: pw_grid
954 TYPE(pw_pool_type), POINTER :: pw_pool
955 TYPE(pw_r3d_rs_type) :: &
956 rhor, vhartree_rs
957 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
958
959 CALL timeset(routinen, handle)
960
961 CALL pw_poisson_rebuild(poisson_env, density)
962
963 has_dielectric = poisson_env%parameters%has_dielectric
964
965 ! point pw
966 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
967 pw_grid => pw_pool%pw_grid
968 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
969 cpabort("vhartree has a different grid than the poisson solver")
970 END IF
971 ! density in G space
972 CALL pw_pool%create_pw(rhog)
973 IF (PRESENT(aux_density)) THEN
974 CALL pw_pool%create_pw(rhog_aux)
975 END IF
976
977 SELECT CASE (poisson_env%used_grid)
978 CASE (use_gs_grid)
979
980 SELECT CASE (poisson_env%green_fft%method)
982
983 CALL pw_transfer(density, rhog)
984 IF (PRESENT(aux_density)) THEN
985 CALL pw_transfer(aux_density, rhog_aux)
986 END IF
987 IF (PRESENT(greenfn)) THEN
988 influence_fn = greenfn
989 ELSE
990 influence_fn = poisson_env%green_fft%influence_fn
991 END IF
992 CALL pw_multiply_with(rhog, influence_fn)
993 IF (PRESENT(aux_density)) THEN
994 CALL pw_multiply_with(rhog_aux, influence_fn)
995 END IF
996 CALL pw_transfer(rhog, vhartree)
997 IF (PRESENT(ehartree)) THEN
998 IF (PRESENT(aux_density)) THEN
999 CALL pw_transfer(aux_density, rhog)
1000 ehartree = 0.5_dp*pw_integral_ab(rhog, vhartree)
1001 ELSE
1002 CALL pw_transfer(density, rhog)
1003 ehartree = 0.5_dp*pw_integral_ab(rhog, vhartree)
1004 END IF
1005 END IF
1006
1007 CASE (ps_implicit)
1008 IF (PRESENT(h_stress)) THEN
1009 cpabort("No stress tensor is implemented for the implicit Poisson solver.")
1010 END IF
1011
1012 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
1013 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1015 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1016 poisson_env%diel_rs_grid, &
1017 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1018 density, rho_core=rho_core)
1019 CASE (neumann_bc, mixed_bc)
1020 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1021 poisson_env%diel_rs_grid, &
1022 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1023 poisson_env%dct_pw_grid, &
1024 poisson_env%parameters%ps_implicit_params%neumann_directions, &
1025 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
1026 poisson_env%implicit_env%dct_env%dests_expand, &
1027 poisson_env%implicit_env%dct_env%srcs_expand, &
1028 poisson_env%implicit_env%dct_env%flipg_stat, &
1029 poisson_env%implicit_env%dct_env%bounds_shftd, &
1030 density, rho_core=rho_core)
1031 END SELECT
1032 END IF
1033
1034 CALL pw_pool%create_pw(rhor)
1035 CALL pw_pool%create_pw(vhartree_rs)
1036 CALL pw_transfer(density, rhor)
1037
1038 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1039 CASE (periodic_bc)
1040 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
1041 ehartree=ehartree)
1042 CASE (neumann_bc)
1043 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
1044 ehartree=ehartree)
1045 CASE (mixed_periodic_bc)
1046 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
1047 electric_enthalpy=ehartree)
1048 CASE (mixed_bc)
1049 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
1050 electric_enthalpy=ehartree)
1051 END SELECT
1052
1053 IF (PRESENT(aux_density)) THEN
1054 CALL pw_transfer(aux_density, rhor)
1055 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
1056 END IF
1057
1058 CALL pw_transfer(vhartree_rs, vhartree)
1059
1060 CALL pw_pool%give_back_pw(rhor)
1061 CALL pw_pool%give_back_pw(vhartree_rs)
1062
1063 CASE DEFAULT
1064 CALL cp_abort(__location__, &
1065 "unknown poisson method "// &
1066 cp_to_string(poisson_env%green_fft%method))
1067 END SELECT
1068
1069 CASE (use_rs_grid)
1070
1071 CALL pw_pool%create_pw(rhor)
1072 CALL pw_transfer(density, rhor)
1073 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
1074 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
1075 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
1076 CALL pw_transfer(rhor, vhartree)
1077 IF (PRESENT(ehartree)) THEN
1078 IF (PRESENT(aux_density)) THEN
1079 ehartree = 0.5_dp*pw_integral_ab(aux_density, rhor)
1080 ELSE
1081 ehartree = 0.5_dp*pw_integral_ab(density, rhor)
1082 END IF
1083 END IF
1084 IF (PRESENT(h_stress)) THEN
1085 CALL pw_transfer(rhor, rhog)
1086 IF (PRESENT(aux_density)) THEN
1087 CALL pw_transfer(aux_density, rhor)
1088 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
1089 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
1090 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
1091 CALL pw_transfer(rhor, rhog_aux)
1092 END IF
1093 END IF
1094 CALL pw_pool%give_back_pw(rhor)
1095
1096 END SELECT
1097
1098 IF (PRESENT(aux_density)) THEN
1099 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, rhog_aux, h_stress)
1100 ELSE
1101 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, h_stress=h_stress)
1102 END IF
1103 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
1104
1105 CALL pw_pool%give_back_pw(rhog)
1106 IF (PRESENT(aux_density)) THEN
1107 CALL pw_pool%give_back_pw(rhog_aux)
1108 END IF
1109
1110 CALL timestop(handle)
1111
1112 END SUBROUTINE pw_poisson_solve_v_nodv_r3d_rs_c1d_gs
1113! **************************************************************************************************
1114!> \brief Solve Poisson equation in a plane wave basis set
1115!> Obtains electrostatic potential and its derivatives with respect to r
1116!> from the density
1117!> \param poisson_env ...
1118!> \param density ...
1119!> \param ehartree ...
1120!> \param vhartree ...
1121!> \param h_stress ...
1122!> \param rho_core ...
1123!> \param greenfn ...
1124!> \param aux_density Hartree energy and stress tensor between 2 different densities
1125!> \par History
1126!> JGH (13-Mar-2001) : completely revised
1127!> \author apsi
1128! **************************************************************************************************
1129 SUBROUTINE pw_poisson_solve_v_nodv_c1d_gs_r3d_rs (poisson_env, density, ehartree, vhartree, &
1130 h_stress, rho_core, greenfn, aux_density)
1131
1132 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
1133 TYPE(pw_c1d_gs_type), INTENT(IN) :: density
1134 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
1135 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: vhartree
1136 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT), &
1137 OPTIONAL :: h_stress
1138 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
1139 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: aux_density
1140
1141 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
1142
1143 INTEGER :: handle
1144 LOGICAL :: has_dielectric
1145 TYPE(pw_grid_type), POINTER :: pw_grid
1146 TYPE(pw_pool_type), POINTER :: pw_pool
1147 TYPE(pw_r3d_rs_type) :: &
1148 rhor, vhartree_rs
1149 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
1150
1151 CALL timeset(routinen, handle)
1152
1153 CALL pw_poisson_rebuild(poisson_env, density)
1154
1155 has_dielectric = poisson_env%parameters%has_dielectric
1156
1157 ! point pw
1158 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
1159 pw_grid => pw_pool%pw_grid
1160 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
1161 cpabort("vhartree has a different grid than the poisson solver")
1162 END IF
1163 ! density in G space
1164 CALL pw_pool%create_pw(rhog)
1165 IF (PRESENT(aux_density)) THEN
1166 CALL pw_pool%create_pw(rhog_aux)
1167 END IF
1168
1169 SELECT CASE (poisson_env%used_grid)
1170 CASE (use_gs_grid)
1171
1172 SELECT CASE (poisson_env%green_fft%method)
1174
1175 CALL pw_transfer(density, rhog)
1176 IF (PRESENT(aux_density)) THEN
1177 CALL pw_transfer(aux_density, rhog_aux)
1178 END IF
1179 IF (PRESENT(greenfn)) THEN
1180 influence_fn = greenfn
1181 ELSE
1182 influence_fn = poisson_env%green_fft%influence_fn
1183 END IF
1184 CALL pw_multiply_with(rhog, influence_fn)
1185 IF (PRESENT(aux_density)) THEN
1186 CALL pw_multiply_with(rhog_aux, influence_fn)
1187 END IF
1188 CALL pw_transfer(rhog, vhartree)
1189 IF (PRESENT(ehartree)) THEN
1190 IF (PRESENT(aux_density)) THEN
1191 ehartree = 0.5_dp*pw_integral_ab(aux_density, rhog)
1192 ELSE
1193 ehartree = 0.5_dp*pw_integral_ab(density, rhog)
1194 END IF
1195 END IF
1196
1197 CASE (ps_implicit)
1198 IF (PRESENT(h_stress)) THEN
1199 cpabort("No stress tensor is implemented for the implicit Poisson solver.")
1200 END IF
1201
1202 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
1203 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1205 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1206 poisson_env%diel_rs_grid, &
1207 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1208 density, rho_core=rho_core)
1209 CASE (neumann_bc, mixed_bc)
1210 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1211 poisson_env%diel_rs_grid, &
1212 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1213 poisson_env%dct_pw_grid, &
1214 poisson_env%parameters%ps_implicit_params%neumann_directions, &
1215 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
1216 poisson_env%implicit_env%dct_env%dests_expand, &
1217 poisson_env%implicit_env%dct_env%srcs_expand, &
1218 poisson_env%implicit_env%dct_env%flipg_stat, &
1219 poisson_env%implicit_env%dct_env%bounds_shftd, &
1220 density, rho_core=rho_core)
1221 END SELECT
1222 END IF
1223
1224 CALL pw_pool%create_pw(rhor)
1225 CALL pw_pool%create_pw(vhartree_rs)
1226 CALL pw_transfer(density, rhor)
1227
1228 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1229 CASE (periodic_bc)
1230 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
1231 ehartree=ehartree)
1232 CASE (neumann_bc)
1233 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
1234 ehartree=ehartree)
1235 CASE (mixed_periodic_bc)
1236 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
1237 electric_enthalpy=ehartree)
1238 CASE (mixed_bc)
1239 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
1240 electric_enthalpy=ehartree)
1241 END SELECT
1242
1243 IF (PRESENT(aux_density)) THEN
1244 CALL pw_transfer(aux_density, rhor)
1245 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
1246 END IF
1247
1248 CALL pw_transfer(vhartree_rs, vhartree)
1249
1250 CALL pw_pool%give_back_pw(rhor)
1251 CALL pw_pool%give_back_pw(vhartree_rs)
1252
1253 CASE DEFAULT
1254 CALL cp_abort(__location__, &
1255 "unknown poisson method "// &
1256 cp_to_string(poisson_env%green_fft%method))
1257 END SELECT
1258
1259 CASE (use_rs_grid)
1260
1261 CALL pw_pool%create_pw(rhor)
1262 CALL pw_transfer(density, rhor)
1263 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
1264 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
1265 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
1266 CALL pw_transfer(rhor, vhartree)
1267 IF (PRESENT(ehartree)) THEN
1268 IF (PRESENT(aux_density)) THEN
1269 CALL pw_transfer(vhartree, rhog)
1270 ehartree = 0.5_dp*pw_integral_ab(aux_density, rhog)
1271 ELSE
1272 CALL pw_transfer(vhartree, rhog)
1273 ehartree = 0.5_dp*pw_integral_ab(density, rhog)
1274 END IF
1275 END IF
1276 IF (PRESENT(h_stress)) THEN
1277 CALL pw_transfer(rhor, rhog)
1278 IF (PRESENT(aux_density)) THEN
1279 CALL pw_transfer(aux_density, rhor)
1280 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
1281 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
1282 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
1283 CALL pw_transfer(rhor, rhog_aux)
1284 END IF
1285 END IF
1286 CALL pw_pool%give_back_pw(rhor)
1287
1288 END SELECT
1289
1290 IF (PRESENT(aux_density)) THEN
1291 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, rhog_aux, h_stress)
1292 ELSE
1293 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, h_stress=h_stress)
1294 END IF
1295 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
1296
1297 CALL pw_pool%give_back_pw(rhog)
1298 IF (PRESENT(aux_density)) THEN
1299 CALL pw_pool%give_back_pw(rhog_aux)
1300 END IF
1301
1302 CALL timestop(handle)
1303
1304 END SUBROUTINE pw_poisson_solve_v_nodv_c1d_gs_r3d_rs
1305! **************************************************************************************************
1306!> \brief Solve Poisson equation in a plane wave basis set
1307!> Obtains electrostatic potential and its derivatives with respect to r
1308!> from the density
1309!> \param poisson_env ...
1310!> \param density ...
1311!> \param ehartree ...
1312!> \param vhartree ...
1313!> \param h_stress ...
1314!> \param rho_core ...
1315!> \param greenfn ...
1316!> \param aux_density Hartree energy and stress tensor between 2 different densities
1317!> \par History
1318!> JGH (13-Mar-2001) : completely revised
1319!> \author apsi
1320! **************************************************************************************************
1321 SUBROUTINE pw_poisson_solve_v_nodv_c1d_gs_c1d_gs (poisson_env, density, ehartree, vhartree, &
1322 h_stress, rho_core, greenfn, aux_density)
1323
1324 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
1325 TYPE(pw_c1d_gs_type), INTENT(IN) :: density
1326 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
1327 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: vhartree
1328 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT), &
1329 OPTIONAL :: h_stress
1330 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
1331 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: aux_density
1332
1333 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
1334
1335 INTEGER :: handle
1336 LOGICAL :: has_dielectric
1337 TYPE(pw_grid_type), POINTER :: pw_grid
1338 TYPE(pw_pool_type), POINTER :: pw_pool
1339 TYPE(pw_r3d_rs_type) :: &
1340 rhor, vhartree_rs
1341 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
1342
1343 CALL timeset(routinen, handle)
1344
1345 CALL pw_poisson_rebuild(poisson_env, density)
1346
1347 has_dielectric = poisson_env%parameters%has_dielectric
1348
1349 ! point pw
1350 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
1351 pw_grid => pw_pool%pw_grid
1352 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
1353 cpabort("vhartree has a different grid than the poisson solver")
1354 END IF
1355 ! density in G space
1356 CALL pw_pool%create_pw(rhog)
1357 IF (PRESENT(aux_density)) THEN
1358 CALL pw_pool%create_pw(rhog_aux)
1359 END IF
1360
1361 SELECT CASE (poisson_env%used_grid)
1362 CASE (use_gs_grid)
1363
1364 SELECT CASE (poisson_env%green_fft%method)
1366
1367 CALL pw_transfer(density, rhog)
1368 IF (PRESENT(aux_density)) THEN
1369 CALL pw_transfer(aux_density, rhog_aux)
1370 END IF
1371 IF (PRESENT(greenfn)) THEN
1372 influence_fn = greenfn
1373 ELSE
1374 influence_fn = poisson_env%green_fft%influence_fn
1375 END IF
1376 CALL pw_multiply_with(rhog, influence_fn)
1377 IF (PRESENT(aux_density)) THEN
1378 CALL pw_multiply_with(rhog_aux, influence_fn)
1379 END IF
1380 CALL pw_transfer(rhog, vhartree)
1381 IF (PRESENT(ehartree)) THEN
1382 IF (PRESENT(aux_density)) THEN
1383 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
1384 ELSE
1385 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
1386 END IF
1387 END IF
1388
1389 CASE (ps_implicit)
1390 IF (PRESENT(h_stress)) THEN
1391 cpabort("No stress tensor is implemented for the implicit Poisson solver.")
1392 END IF
1393
1394 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
1395 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1397 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1398 poisson_env%diel_rs_grid, &
1399 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1400 density, rho_core=rho_core)
1401 CASE (neumann_bc, mixed_bc)
1402 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1403 poisson_env%diel_rs_grid, &
1404 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1405 poisson_env%dct_pw_grid, &
1406 poisson_env%parameters%ps_implicit_params%neumann_directions, &
1407 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
1408 poisson_env%implicit_env%dct_env%dests_expand, &
1409 poisson_env%implicit_env%dct_env%srcs_expand, &
1410 poisson_env%implicit_env%dct_env%flipg_stat, &
1411 poisson_env%implicit_env%dct_env%bounds_shftd, &
1412 density, rho_core=rho_core)
1413 END SELECT
1414 END IF
1415
1416 CALL pw_pool%create_pw(rhor)
1417 CALL pw_pool%create_pw(vhartree_rs)
1418 CALL pw_transfer(density, rhor)
1419
1420 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1421 CASE (periodic_bc)
1422 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
1423 ehartree=ehartree)
1424 CASE (neumann_bc)
1425 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
1426 ehartree=ehartree)
1427 CASE (mixed_periodic_bc)
1428 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
1429 electric_enthalpy=ehartree)
1430 CASE (mixed_bc)
1431 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
1432 electric_enthalpy=ehartree)
1433 END SELECT
1434
1435 IF (PRESENT(aux_density)) THEN
1436 CALL pw_transfer(aux_density, rhor)
1437 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
1438 END IF
1439
1440 CALL pw_transfer(vhartree_rs, vhartree)
1441
1442 CALL pw_pool%give_back_pw(rhor)
1443 CALL pw_pool%give_back_pw(vhartree_rs)
1444
1445 CASE DEFAULT
1446 CALL cp_abort(__location__, &
1447 "unknown poisson method "// &
1448 cp_to_string(poisson_env%green_fft%method))
1449 END SELECT
1450
1451 CASE (use_rs_grid)
1452
1453 CALL pw_pool%create_pw(rhor)
1454 CALL pw_transfer(density, rhor)
1455 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
1456 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
1457 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
1458 CALL pw_transfer(rhor, vhartree)
1459 IF (PRESENT(ehartree)) THEN
1460 IF (PRESENT(aux_density)) THEN
1461 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
1462 ELSE
1463 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
1464 END IF
1465 END IF
1466 IF (PRESENT(h_stress)) THEN
1467 CALL pw_transfer(rhor, rhog)
1468 IF (PRESENT(aux_density)) THEN
1469 CALL pw_transfer(aux_density, rhor)
1470 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
1471 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
1472 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
1473 CALL pw_transfer(rhor, rhog_aux)
1474 END IF
1475 END IF
1476 CALL pw_pool%give_back_pw(rhor)
1477
1478 END SELECT
1479
1480 IF (PRESENT(aux_density)) THEN
1481 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, rhog_aux, h_stress)
1482 ELSE
1483 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, h_stress=h_stress)
1484 END IF
1485 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
1486
1487 CALL pw_pool%give_back_pw(rhog)
1488 IF (PRESENT(aux_density)) THEN
1489 CALL pw_pool%give_back_pw(rhog_aux)
1490 END IF
1491
1492 CALL timestop(handle)
1493
1494 END SUBROUTINE pw_poisson_solve_v_nodv_c1d_gs_c1d_gs
1495
1496! **************************************************************************************************
1497!> \brief Solve Poisson equation in a plane wave basis set
1498!> Obtains electrostatic potential and its derivatives with respect to r
1499!> from the density
1500!> \param poisson_env ...
1501!> \param density ...
1502!> \param ehartree ...
1503!> \param dvhartree ...
1504!> \param h_stress ...
1505!> \param rho_core ...
1506!> \param greenfn ...
1507!> \param aux_density Hartree energy and stress tensor between 2 different densities
1508!> \par History
1509!> JGH (13-Mar-2001) : completely revised
1510!> \author apsi
1511! **************************************************************************************************
1512 SUBROUTINE pw_poisson_solve_nov_dv_r3d_rs_r3d_rs (poisson_env, density, ehartree, &
1513 dvhartree, h_stress, rho_core, greenfn, aux_density)
1514
1515 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
1516 TYPE(pw_r3d_rs_type), INTENT(IN) :: density
1517 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
1518 TYPE(pw_r3d_rs_type), DIMENSION(3) :: dvhartree
1519 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT), &
1520 OPTIONAL :: h_stress
1521 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
1522 TYPE(pw_r3d_rs_type), INTENT(IN), OPTIONAL :: aux_density
1523
1524 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
1525
1526 INTEGER :: handle
1527 LOGICAL :: has_dielectric
1528 TYPE(pw_grid_type), POINTER :: pw_grid
1529 TYPE(pw_pool_type), POINTER :: pw_pool
1530 TYPE(pw_r3d_rs_type) :: &
1531 rhor, vhartree_rs
1532 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux, tmpg
1533
1534 CALL timeset(routinen, handle)
1535
1536 CALL pw_poisson_rebuild(poisson_env, density)
1537
1538 has_dielectric = poisson_env%parameters%has_dielectric
1539
1540 ! point pw
1541 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
1542 pw_grid => pw_pool%pw_grid
1543 ! density in G space
1544 CALL pw_pool%create_pw(rhog)
1545 IF (PRESENT(aux_density)) THEN
1546 CALL pw_pool%create_pw(rhog_aux)
1547 END IF
1548
1549 SELECT CASE (poisson_env%used_grid)
1550 CASE (use_gs_grid)
1551
1552 SELECT CASE (poisson_env%green_fft%method)
1554
1555 CALL pw_transfer(density, rhog)
1556 IF (PRESENT(aux_density)) THEN
1557 CALL pw_transfer(aux_density, rhog_aux)
1558 END IF
1559 IF (PRESENT(ehartree)) THEN
1560 CALL pw_pool%create_pw(tmpg)
1561 CALL pw_copy(rhog, tmpg)
1562 END IF
1563 IF (PRESENT(greenfn)) THEN
1564 influence_fn = greenfn
1565 ELSE
1566 influence_fn = poisson_env%green_fft%influence_fn
1567 END IF
1568 CALL pw_multiply_with(rhog, influence_fn)
1569 IF (PRESENT(aux_density)) THEN
1570 CALL pw_multiply_with(rhog_aux, influence_fn)
1571 END IF
1572 IF (PRESENT(ehartree)) THEN
1573 IF (PRESENT(aux_density)) THEN
1574 ehartree = 0.5_dp*pw_integral_ab(rhog_aux, tmpg)
1575 ELSE
1576 ehartree = 0.5_dp*pw_integral_ab(rhog, tmpg)
1577 END IF
1578 CALL pw_pool%give_back_pw(tmpg)
1579 END IF
1580
1581 CASE (ps_implicit)
1582 IF (PRESENT(h_stress)) THEN
1583 cpabort("No stress tensor is implemented for the implicit Poisson solver.")
1584 END IF
1585
1586 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
1587 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1589 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1590 poisson_env%diel_rs_grid, &
1591 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1592 density, rho_core=rho_core)
1593 CASE (neumann_bc, mixed_bc)
1594 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1595 poisson_env%diel_rs_grid, &
1596 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1597 poisson_env%dct_pw_grid, &
1598 poisson_env%parameters%ps_implicit_params%neumann_directions, &
1599 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
1600 poisson_env%implicit_env%dct_env%dests_expand, &
1601 poisson_env%implicit_env%dct_env%srcs_expand, &
1602 poisson_env%implicit_env%dct_env%flipg_stat, &
1603 poisson_env%implicit_env%dct_env%bounds_shftd, &
1604 density, rho_core=rho_core)
1605 END SELECT
1606 END IF
1607
1608 CALL pw_pool%create_pw(rhor)
1609 CALL pw_pool%create_pw(vhartree_rs)
1610 CALL pw_transfer(density, rhor)
1611
1612 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1613 CASE (periodic_bc)
1614 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
1615 ehartree=ehartree)
1616 CASE (neumann_bc)
1617 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
1618 ehartree=ehartree)
1619 CASE (mixed_periodic_bc)
1620 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
1621 electric_enthalpy=ehartree)
1622 CASE (mixed_bc)
1623 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
1624 electric_enthalpy=ehartree)
1625 END SELECT
1626
1627 CALL pw_transfer(rhor, rhog)
1628
1629 IF (PRESENT(aux_density)) THEN
1630 CALL pw_transfer(aux_density, rhor)
1631 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
1632 END IF
1633
1634 CALL pw_pool%give_back_pw(rhor)
1635 CALL pw_pool%give_back_pw(vhartree_rs)
1636
1637 CASE DEFAULT
1638 CALL cp_abort(__location__, &
1639 "unknown poisson method "// &
1640 cp_to_string(poisson_env%green_fft%method))
1641 END SELECT
1642
1643 CASE (use_rs_grid)
1644
1645 CALL pw_pool%create_pw(rhor)
1646 CALL pw_transfer(density, rhor)
1647 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
1648 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
1649 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
1650 CALL pw_transfer(rhor, rhog)
1651 IF (PRESENT(ehartree)) THEN
1652 ehartree = 0.5_dp*pw_integral_ab(density, rhor)
1653 END IF
1654 CALL pw_pool%give_back_pw(rhor)
1655
1656 END SELECT
1657
1658 IF (PRESENT(aux_density)) THEN
1659 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
1660 ELSE
1661 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
1662 END IF
1663 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
1664
1665 CALL pw_pool%give_back_pw(rhog)
1666 IF (PRESENT(aux_density)) THEN
1667 CALL pw_pool%give_back_pw(rhog_aux)
1668 END IF
1669
1670 CALL timestop(handle)
1671
1672 END SUBROUTINE pw_poisson_solve_nov_dv_r3d_rs_r3d_rs
1673! **************************************************************************************************
1674!> \brief Solve Poisson equation in a plane wave basis set
1675!> Obtains electrostatic potential and its derivatives with respect to r
1676!> from the density
1677!> \param poisson_env ...
1678!> \param density ...
1679!> \param ehartree ...
1680!> \param dvhartree ...
1681!> \param h_stress ...
1682!> \param rho_core ...
1683!> \param greenfn ...
1684!> \param aux_density Hartree energy and stress tensor between 2 different densities
1685!> \par History
1686!> JGH (13-Mar-2001) : completely revised
1687!> \author apsi
1688! **************************************************************************************************
1689 SUBROUTINE pw_poisson_solve_nov_dv_r3d_rs_c1d_gs (poisson_env, density, ehartree, &
1690 dvhartree, h_stress, rho_core, greenfn, aux_density)
1691
1692 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
1693 TYPE(pw_r3d_rs_type), INTENT(IN) :: density
1694 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
1695 TYPE(pw_c1d_gs_type), DIMENSION(3) :: dvhartree
1696 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT), &
1697 OPTIONAL :: h_stress
1698 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
1699 TYPE(pw_r3d_rs_type), INTENT(IN), OPTIONAL :: aux_density
1700
1701 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
1702
1703 INTEGER :: handle
1704 LOGICAL :: has_dielectric
1705 TYPE(pw_grid_type), POINTER :: pw_grid
1706 TYPE(pw_pool_type), POINTER :: pw_pool
1707 TYPE(pw_r3d_rs_type) :: &
1708 rhor, vhartree_rs
1709 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux, tmpg
1710
1711 CALL timeset(routinen, handle)
1712
1713 CALL pw_poisson_rebuild(poisson_env, density)
1714
1715 has_dielectric = poisson_env%parameters%has_dielectric
1716
1717 ! point pw
1718 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
1719 pw_grid => pw_pool%pw_grid
1720 ! density in G space
1721 CALL pw_pool%create_pw(rhog)
1722 IF (PRESENT(aux_density)) THEN
1723 CALL pw_pool%create_pw(rhog_aux)
1724 END IF
1725
1726 SELECT CASE (poisson_env%used_grid)
1727 CASE (use_gs_grid)
1728
1729 SELECT CASE (poisson_env%green_fft%method)
1731
1732 CALL pw_transfer(density, rhog)
1733 IF (PRESENT(aux_density)) THEN
1734 CALL pw_transfer(aux_density, rhog_aux)
1735 END IF
1736 IF (PRESENT(ehartree)) THEN
1737 CALL pw_pool%create_pw(tmpg)
1738 CALL pw_copy(rhog, tmpg)
1739 END IF
1740 IF (PRESENT(greenfn)) THEN
1741 influence_fn = greenfn
1742 ELSE
1743 influence_fn = poisson_env%green_fft%influence_fn
1744 END IF
1745 CALL pw_multiply_with(rhog, influence_fn)
1746 IF (PRESENT(aux_density)) THEN
1747 CALL pw_multiply_with(rhog_aux, influence_fn)
1748 END IF
1749 IF (PRESENT(ehartree)) THEN
1750 IF (PRESENT(aux_density)) THEN
1751 ehartree = 0.5_dp*pw_integral_ab(rhog_aux, tmpg)
1752 ELSE
1753 ehartree = 0.5_dp*pw_integral_ab(rhog, tmpg)
1754 END IF
1755 CALL pw_pool%give_back_pw(tmpg)
1756 END IF
1757
1758 CASE (ps_implicit)
1759 IF (PRESENT(h_stress)) THEN
1760 cpabort("No stress tensor is implemented for the implicit Poisson solver.")
1761 END IF
1762
1763 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
1764 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1766 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1767 poisson_env%diel_rs_grid, &
1768 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1769 density, rho_core=rho_core)
1770 CASE (neumann_bc, mixed_bc)
1771 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1772 poisson_env%diel_rs_grid, &
1773 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1774 poisson_env%dct_pw_grid, &
1775 poisson_env%parameters%ps_implicit_params%neumann_directions, &
1776 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
1777 poisson_env%implicit_env%dct_env%dests_expand, &
1778 poisson_env%implicit_env%dct_env%srcs_expand, &
1779 poisson_env%implicit_env%dct_env%flipg_stat, &
1780 poisson_env%implicit_env%dct_env%bounds_shftd, &
1781 density, rho_core=rho_core)
1782 END SELECT
1783 END IF
1784
1785 CALL pw_pool%create_pw(rhor)
1786 CALL pw_pool%create_pw(vhartree_rs)
1787 CALL pw_transfer(density, rhor)
1788
1789 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1790 CASE (periodic_bc)
1791 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
1792 ehartree=ehartree)
1793 CASE (neumann_bc)
1794 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
1795 ehartree=ehartree)
1796 CASE (mixed_periodic_bc)
1797 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
1798 electric_enthalpy=ehartree)
1799 CASE (mixed_bc)
1800 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
1801 electric_enthalpy=ehartree)
1802 END SELECT
1803
1804 CALL pw_transfer(rhor, rhog)
1805
1806 IF (PRESENT(aux_density)) THEN
1807 CALL pw_transfer(aux_density, rhor)
1808 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
1809 END IF
1810
1811 CALL pw_pool%give_back_pw(rhor)
1812 CALL pw_pool%give_back_pw(vhartree_rs)
1813
1814 CASE DEFAULT
1815 CALL cp_abort(__location__, &
1816 "unknown poisson method "// &
1817 cp_to_string(poisson_env%green_fft%method))
1818 END SELECT
1819
1820 CASE (use_rs_grid)
1821
1822 CALL pw_pool%create_pw(rhor)
1823 CALL pw_transfer(density, rhor)
1824 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
1825 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
1826 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
1827 CALL pw_transfer(rhor, rhog)
1828 IF (PRESENT(ehartree)) THEN
1829 ehartree = 0.5_dp*pw_integral_ab(density, rhor)
1830 END IF
1831 CALL pw_pool%give_back_pw(rhor)
1832
1833 END SELECT
1834
1835 IF (PRESENT(aux_density)) THEN
1836 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
1837 ELSE
1838 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
1839 END IF
1840 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
1841
1842 CALL pw_pool%give_back_pw(rhog)
1843 IF (PRESENT(aux_density)) THEN
1844 CALL pw_pool%give_back_pw(rhog_aux)
1845 END IF
1846
1847 CALL timestop(handle)
1848
1849 END SUBROUTINE pw_poisson_solve_nov_dv_r3d_rs_c1d_gs
1850! **************************************************************************************************
1851!> \brief Solve Poisson equation in a plane wave basis set
1852!> Obtains electrostatic potential and its derivatives with respect to r
1853!> from the density
1854!> \param poisson_env ...
1855!> \param density ...
1856!> \param ehartree ...
1857!> \param dvhartree ...
1858!> \param h_stress ...
1859!> \param rho_core ...
1860!> \param greenfn ...
1861!> \param aux_density Hartree energy and stress tensor between 2 different densities
1862!> \par History
1863!> JGH (13-Mar-2001) : completely revised
1864!> \author apsi
1865! **************************************************************************************************
1866 SUBROUTINE pw_poisson_solve_nov_dv_c1d_gs_r3d_rs (poisson_env, density, ehartree, &
1867 dvhartree, h_stress, rho_core, greenfn, aux_density)
1868
1869 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
1870 TYPE(pw_c1d_gs_type), INTENT(IN) :: density
1871 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
1872 TYPE(pw_r3d_rs_type), DIMENSION(3) :: dvhartree
1873 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT), &
1874 OPTIONAL :: h_stress
1875 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
1876 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: aux_density
1877
1878 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
1879
1880 INTEGER :: handle
1881 LOGICAL :: has_dielectric
1882 TYPE(pw_grid_type), POINTER :: pw_grid
1883 TYPE(pw_pool_type), POINTER :: pw_pool
1884 TYPE(pw_r3d_rs_type) :: &
1885 rhor, vhartree_rs
1886 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux, tmpg
1887
1888 CALL timeset(routinen, handle)
1889
1890 CALL pw_poisson_rebuild(poisson_env, density)
1891
1892 has_dielectric = poisson_env%parameters%has_dielectric
1893
1894 ! point pw
1895 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
1896 pw_grid => pw_pool%pw_grid
1897 ! density in G space
1898 CALL pw_pool%create_pw(rhog)
1899 IF (PRESENT(aux_density)) THEN
1900 CALL pw_pool%create_pw(rhog_aux)
1901 END IF
1902
1903 SELECT CASE (poisson_env%used_grid)
1904 CASE (use_gs_grid)
1905
1906 SELECT CASE (poisson_env%green_fft%method)
1908
1909 CALL pw_transfer(density, rhog)
1910 IF (PRESENT(aux_density)) THEN
1911 CALL pw_transfer(aux_density, rhog_aux)
1912 END IF
1913 IF (PRESENT(ehartree)) THEN
1914 CALL pw_pool%create_pw(tmpg)
1915 CALL pw_copy(rhog, tmpg)
1916 END IF
1917 IF (PRESENT(greenfn)) THEN
1918 influence_fn = greenfn
1919 ELSE
1920 influence_fn = poisson_env%green_fft%influence_fn
1921 END IF
1922 CALL pw_multiply_with(rhog, influence_fn)
1923 IF (PRESENT(aux_density)) THEN
1924 CALL pw_multiply_with(rhog_aux, influence_fn)
1925 END IF
1926 IF (PRESENT(ehartree)) THEN
1927 IF (PRESENT(aux_density)) THEN
1928 ehartree = 0.5_dp*pw_integral_ab(rhog_aux, tmpg)
1929 ELSE
1930 ehartree = 0.5_dp*pw_integral_ab(rhog, tmpg)
1931 END IF
1932 CALL pw_pool%give_back_pw(tmpg)
1933 END IF
1934
1935 CASE (ps_implicit)
1936 IF (PRESENT(h_stress)) THEN
1937 cpabort("No stress tensor is implemented for the implicit Poisson solver.")
1938 END IF
1939
1940 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
1941 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1943 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1944 poisson_env%diel_rs_grid, &
1945 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1946 density, rho_core=rho_core)
1947 CASE (neumann_bc, mixed_bc)
1948 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
1949 poisson_env%diel_rs_grid, &
1950 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
1951 poisson_env%dct_pw_grid, &
1952 poisson_env%parameters%ps_implicit_params%neumann_directions, &
1953 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
1954 poisson_env%implicit_env%dct_env%dests_expand, &
1955 poisson_env%implicit_env%dct_env%srcs_expand, &
1956 poisson_env%implicit_env%dct_env%flipg_stat, &
1957 poisson_env%implicit_env%dct_env%bounds_shftd, &
1958 density, rho_core=rho_core)
1959 END SELECT
1960 END IF
1961
1962 CALL pw_pool%create_pw(rhor)
1963 CALL pw_pool%create_pw(vhartree_rs)
1964 CALL pw_transfer(density, rhor)
1965
1966 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
1967 CASE (periodic_bc)
1968 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
1969 ehartree=ehartree)
1970 CASE (neumann_bc)
1971 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
1972 ehartree=ehartree)
1973 CASE (mixed_periodic_bc)
1974 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
1975 electric_enthalpy=ehartree)
1976 CASE (mixed_bc)
1977 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
1978 electric_enthalpy=ehartree)
1979 END SELECT
1980
1981 CALL pw_transfer(rhor, rhog)
1982
1983 IF (PRESENT(aux_density)) THEN
1984 CALL pw_transfer(aux_density, rhor)
1985 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
1986 END IF
1987
1988 CALL pw_pool%give_back_pw(rhor)
1989 CALL pw_pool%give_back_pw(vhartree_rs)
1990
1991 CASE DEFAULT
1992 CALL cp_abort(__location__, &
1993 "unknown poisson method "// &
1994 cp_to_string(poisson_env%green_fft%method))
1995 END SELECT
1996
1997 CASE (use_rs_grid)
1998
1999 CALL pw_pool%create_pw(rhor)
2000 CALL pw_transfer(density, rhor)
2001 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
2002 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
2003 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
2004 CALL pw_transfer(rhor, rhog)
2005 IF (PRESENT(ehartree)) THEN
2006 ehartree = 0.5_dp*pw_integral_ab(density, rhog)
2007 END IF
2008 CALL pw_pool%give_back_pw(rhor)
2009
2010 END SELECT
2011
2012 IF (PRESENT(aux_density)) THEN
2013 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
2014 ELSE
2015 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
2016 END IF
2017 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
2018
2019 CALL pw_pool%give_back_pw(rhog)
2020 IF (PRESENT(aux_density)) THEN
2021 CALL pw_pool%give_back_pw(rhog_aux)
2022 END IF
2023
2024 CALL timestop(handle)
2025
2026 END SUBROUTINE pw_poisson_solve_nov_dv_c1d_gs_r3d_rs
2027! **************************************************************************************************
2028!> \brief Solve Poisson equation in a plane wave basis set
2029!> Obtains electrostatic potential and its derivatives with respect to r
2030!> from the density
2031!> \param poisson_env ...
2032!> \param density ...
2033!> \param ehartree ...
2034!> \param dvhartree ...
2035!> \param h_stress ...
2036!> \param rho_core ...
2037!> \param greenfn ...
2038!> \param aux_density Hartree energy and stress tensor between 2 different densities
2039!> \par History
2040!> JGH (13-Mar-2001) : completely revised
2041!> \author apsi
2042! **************************************************************************************************
2043 SUBROUTINE pw_poisson_solve_nov_dv_c1d_gs_c1d_gs (poisson_env, density, ehartree, &
2044 dvhartree, h_stress, rho_core, greenfn, aux_density)
2045
2046 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
2047 TYPE(pw_c1d_gs_type), INTENT(IN) :: density
2048 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
2049 TYPE(pw_c1d_gs_type), DIMENSION(3) :: dvhartree
2050 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT), &
2051 OPTIONAL :: h_stress
2052 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
2053 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: aux_density
2054
2055 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
2056
2057 INTEGER :: handle
2058 LOGICAL :: has_dielectric
2059 TYPE(pw_grid_type), POINTER :: pw_grid
2060 TYPE(pw_pool_type), POINTER :: pw_pool
2061 TYPE(pw_r3d_rs_type) :: &
2062 rhor, vhartree_rs
2063 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux, tmpg
2064
2065 CALL timeset(routinen, handle)
2066
2067 CALL pw_poisson_rebuild(poisson_env, density)
2068
2069 has_dielectric = poisson_env%parameters%has_dielectric
2070
2071 ! point pw
2072 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
2073 pw_grid => pw_pool%pw_grid
2074 ! density in G space
2075 CALL pw_pool%create_pw(rhog)
2076 IF (PRESENT(aux_density)) THEN
2077 CALL pw_pool%create_pw(rhog_aux)
2078 END IF
2079
2080 SELECT CASE (poisson_env%used_grid)
2081 CASE (use_gs_grid)
2082
2083 SELECT CASE (poisson_env%green_fft%method)
2085
2086 CALL pw_transfer(density, rhog)
2087 IF (PRESENT(aux_density)) THEN
2088 CALL pw_transfer(aux_density, rhog_aux)
2089 END IF
2090 IF (PRESENT(ehartree)) THEN
2091 CALL pw_pool%create_pw(tmpg)
2092 CALL pw_copy(rhog, tmpg)
2093 END IF
2094 IF (PRESENT(greenfn)) THEN
2095 influence_fn = greenfn
2096 ELSE
2097 influence_fn = poisson_env%green_fft%influence_fn
2098 END IF
2099 CALL pw_multiply_with(rhog, influence_fn)
2100 IF (PRESENT(aux_density)) THEN
2101 CALL pw_multiply_with(rhog_aux, influence_fn)
2102 END IF
2103 IF (PRESENT(ehartree)) THEN
2104 IF (PRESENT(aux_density)) THEN
2105 ehartree = 0.5_dp*pw_integral_ab(rhog_aux, tmpg)
2106 ELSE
2107 ehartree = 0.5_dp*pw_integral_ab(rhog, tmpg)
2108 END IF
2109 CALL pw_pool%give_back_pw(tmpg)
2110 END IF
2111
2112 CASE (ps_implicit)
2113 IF (PRESENT(h_stress)) THEN
2114 cpabort("No stress tensor is implemented for the implicit Poisson solver.")
2115 END IF
2116
2117 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
2118 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
2120 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
2121 poisson_env%diel_rs_grid, &
2122 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
2123 density, rho_core=rho_core)
2124 CASE (neumann_bc, mixed_bc)
2125 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
2126 poisson_env%diel_rs_grid, &
2127 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
2128 poisson_env%dct_pw_grid, &
2129 poisson_env%parameters%ps_implicit_params%neumann_directions, &
2130 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
2131 poisson_env%implicit_env%dct_env%dests_expand, &
2132 poisson_env%implicit_env%dct_env%srcs_expand, &
2133 poisson_env%implicit_env%dct_env%flipg_stat, &
2134 poisson_env%implicit_env%dct_env%bounds_shftd, &
2135 density, rho_core=rho_core)
2136 END SELECT
2137 END IF
2138
2139 CALL pw_pool%create_pw(rhor)
2140 CALL pw_pool%create_pw(vhartree_rs)
2141 CALL pw_transfer(density, rhor)
2142
2143 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
2144 CASE (periodic_bc)
2145 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
2146 ehartree=ehartree)
2147 CASE (neumann_bc)
2148 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
2149 ehartree=ehartree)
2150 CASE (mixed_periodic_bc)
2151 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
2152 electric_enthalpy=ehartree)
2153 CASE (mixed_bc)
2154 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
2155 electric_enthalpy=ehartree)
2156 END SELECT
2157
2158 CALL pw_transfer(rhor, rhog)
2159
2160 IF (PRESENT(aux_density)) THEN
2161 CALL pw_transfer(aux_density, rhor)
2162 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
2163 END IF
2164
2165 CALL pw_pool%give_back_pw(rhor)
2166 CALL pw_pool%give_back_pw(vhartree_rs)
2167
2168 CASE DEFAULT
2169 CALL cp_abort(__location__, &
2170 "unknown poisson method "// &
2171 cp_to_string(poisson_env%green_fft%method))
2172 END SELECT
2173
2174 CASE (use_rs_grid)
2175
2176 CALL pw_pool%create_pw(rhor)
2177 CALL pw_transfer(density, rhor)
2178 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
2179 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
2180 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
2181 CALL pw_transfer(rhor, rhog)
2182 IF (PRESENT(ehartree)) THEN
2183 ehartree = 0.5_dp*pw_integral_ab(density, rhog)
2184 END IF
2185 CALL pw_pool%give_back_pw(rhor)
2186
2187 END SELECT
2188
2189 IF (PRESENT(aux_density)) THEN
2190 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
2191 ELSE
2192 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
2193 END IF
2194 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
2195
2196 CALL pw_pool%give_back_pw(rhog)
2197 IF (PRESENT(aux_density)) THEN
2198 CALL pw_pool%give_back_pw(rhog_aux)
2199 END IF
2200
2201 CALL timestop(handle)
2202
2203 END SUBROUTINE pw_poisson_solve_nov_dv_c1d_gs_c1d_gs
2204
2205! **************************************************************************************************
2206!> \brief Solve Poisson equation in a plane wave basis set
2207!> Obtains electrostatic potential and its derivatives with respect to r
2208!> from the density
2209!> \param poisson_env ...
2210!> \param density ...
2211!> \param ehartree ...
2212!> \param vhartree ...
2213!> \param dvhartree ...
2214!> \param h_stress ...
2215!> \param rho_core ...
2216!> \param greenfn ...
2217!> \param aux_density Hartree energy and stress tensor between 2 different densities
2218!> \par History
2219!> JGH (13-Mar-2001) : completely revised
2220!> \author apsi
2221! **************************************************************************************************
2222 SUBROUTINE pw_poisson_solve_v_dv_r3d_rs_r3d_rs_r3d_rs (poisson_env, density, ehartree, vhartree, &
2223 dvhartree, h_stress, rho_core, greenfn, aux_density)
2224
2225 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
2226 TYPE(pw_r3d_rs_type), INTENT(IN) :: density
2227 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
2228 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: vhartree
2229 TYPE(pw_r3d_rs_type), DIMENSION(3) :: dvhartree
2230 REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT), &
2231 OPTIONAL :: h_stress
2232 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
2233 TYPE(pw_r3d_rs_type), INTENT(IN), OPTIONAL :: aux_density
2234
2235 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
2236
2237 INTEGER :: handle
2238 LOGICAL :: has_dielectric
2239 TYPE(pw_grid_type), POINTER :: pw_grid
2240 TYPE(pw_pool_type), POINTER :: pw_pool
2241 TYPE(pw_r3d_rs_type) :: rhor, vhartree_rs
2242 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
2243
2244 CALL timeset(routinen, handle)
2245
2246 CALL pw_poisson_rebuild(poisson_env, density)
2247
2248 has_dielectric = poisson_env%parameters%has_dielectric
2249
2250 ! point pw
2251 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
2252 pw_grid => pw_pool%pw_grid
2253 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
2254 cpabort("vhartree has a different grid than the poisson solver")
2255 END IF
2256 ! density in G space
2257 CALL pw_pool%create_pw(rhog)
2258 IF (PRESENT(aux_density)) THEN
2259 CALL pw_pool%create_pw(rhog_aux)
2260 END IF
2261
2262 SELECT CASE (poisson_env%used_grid)
2263 CASE (use_gs_grid)
2264
2265 SELECT CASE (poisson_env%green_fft%method)
2267
2268 CALL pw_transfer(density, rhog)
2269 IF (PRESENT(aux_density)) THEN
2270 CALL pw_transfer(aux_density, rhog_aux)
2271 END IF
2272 IF (PRESENT(greenfn)) THEN
2273 influence_fn = greenfn
2274 ELSE
2275 influence_fn = poisson_env%green_fft%influence_fn
2276 END IF
2277 CALL pw_multiply_with(rhog, influence_fn)
2278 IF (PRESENT(aux_density)) THEN
2279 CALL pw_multiply_with(rhog_aux, influence_fn)
2280 END IF
2281 CALL pw_transfer(rhog, vhartree)
2282 IF (PRESENT(ehartree)) THEN
2283 IF (PRESENT(aux_density)) THEN
2284 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
2285 ELSE
2286 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
2287 END IF
2288 END IF
2289
2290 CASE (ps_implicit)
2291 IF (PRESENT(h_stress)) THEN
2292 CALL cp_abort(__location__, &
2293 "No stress tensor is implemented for the implicit Poisson solver.")
2294 END IF
2295
2296 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
2297 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
2299 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
2300 poisson_env%diel_rs_grid, &
2301 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
2302 density, rho_core=rho_core)
2303 CASE (neumann_bc, mixed_bc)
2304 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
2305 poisson_env%diel_rs_grid, &
2306 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
2307 poisson_env%dct_pw_grid, &
2308 poisson_env%parameters%ps_implicit_params%neumann_directions, &
2309 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
2310 poisson_env%implicit_env%dct_env%dests_expand, &
2311 poisson_env%implicit_env%dct_env%srcs_expand, &
2312 poisson_env%implicit_env%dct_env%flipg_stat, &
2313 poisson_env%implicit_env%dct_env%bounds_shftd, &
2314 density, rho_core=rho_core)
2315 END SELECT
2316 END IF
2317
2318 CALL pw_pool%create_pw(rhor)
2319 CALL pw_pool%create_pw(vhartree_rs)
2320 CALL pw_transfer(density, rhor)
2321
2322 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
2323 CASE (periodic_bc)
2324 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
2325 ehartree=ehartree)
2326 CASE (neumann_bc)
2327 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
2328 ehartree=ehartree)
2329 CASE (mixed_periodic_bc)
2330 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
2331 electric_enthalpy=ehartree)
2332 CASE (mixed_bc)
2333 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
2334 electric_enthalpy=ehartree)
2335 END SELECT
2336
2337 CALL pw_transfer(vhartree_rs, vhartree)
2338 CALL pw_transfer(rhor, rhog)
2339
2340 IF (PRESENT(aux_density)) THEN
2341 CALL pw_transfer(aux_density, rhor)
2342 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
2343 END IF
2344
2345 CALL pw_pool%give_back_pw(rhor)
2346 CALL pw_pool%give_back_pw(vhartree_rs)
2347
2348 CASE DEFAULT
2349 CALL cp_abort(__location__, &
2350 "unknown poisson method "// &
2351 cp_to_string(poisson_env%green_fft%method))
2352 END SELECT
2353
2354 CASE (use_rs_grid)
2355
2356 CALL pw_pool%create_pw(rhor)
2357 CALL pw_transfer(density, rhor)
2358 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
2359 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
2360 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
2361 CALL pw_transfer(rhor, vhartree)
2362 CALL pw_transfer(rhor, rhog)
2363 IF (PRESENT(ehartree)) THEN
2364 IF (PRESENT(aux_density)) THEN
2365 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
2366 ELSE
2367 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
2368 END IF
2369 END IF
2370 CALL pw_transfer(rhor, rhog)
2371 IF (PRESENT(aux_density)) THEN
2372 CALL pw_transfer(aux_density, rhor)
2373 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
2374 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
2375 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
2376 CALL pw_transfer(rhor, rhog_aux)
2377 END IF
2378 CALL pw_pool%give_back_pw(rhor)
2379
2380 END SELECT
2381
2382 IF (PRESENT(aux_density)) THEN
2383 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
2384 ELSE
2385 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
2386 END IF
2387 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
2388
2389 CALL pw_pool%give_back_pw(rhog)
2390 IF (PRESENT(aux_density)) THEN
2391 CALL pw_pool%give_back_pw(rhog_aux)
2392 END IF
2393
2394 CALL timestop(handle)
2395
2396 END SUBROUTINE pw_poisson_solve_v_dv_r3d_rs_r3d_rs_r3d_rs
2397! **************************************************************************************************
2398!> \brief Solve Poisson equation in a plane wave basis set
2399!> Obtains electrostatic potential and its derivatives with respect to r
2400!> from the density
2401!> \param poisson_env ...
2402!> \param density ...
2403!> \param ehartree ...
2404!> \param vhartree ...
2405!> \param dvhartree ...
2406!> \param h_stress ...
2407!> \param rho_core ...
2408!> \param greenfn ...
2409!> \param aux_density Hartree energy and stress tensor between 2 different densities
2410!> \par History
2411!> JGH (13-Mar-2001) : completely revised
2412!> \author apsi
2413! **************************************************************************************************
2414 SUBROUTINE pw_poisson_solve_v_dv_r3d_rs_c1d_gs_r3d_rs (poisson_env, density, ehartree, vhartree, &
2415 dvhartree, h_stress, rho_core, greenfn, aux_density)
2416
2417 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
2418 TYPE(pw_r3d_rs_type), INTENT(IN) :: density
2419 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
2420 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: vhartree
2421 TYPE(pw_r3d_rs_type), DIMENSION(3) :: dvhartree
2422 REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT), &
2423 OPTIONAL :: h_stress
2424 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
2425 TYPE(pw_r3d_rs_type), INTENT(IN), OPTIONAL :: aux_density
2426
2427 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
2428
2429 INTEGER :: handle
2430 LOGICAL :: has_dielectric
2431 TYPE(pw_grid_type), POINTER :: pw_grid
2432 TYPE(pw_pool_type), POINTER :: pw_pool
2433 TYPE(pw_r3d_rs_type) :: rhor, vhartree_rs
2434 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
2435
2436 CALL timeset(routinen, handle)
2437
2438 CALL pw_poisson_rebuild(poisson_env, density)
2439
2440 has_dielectric = poisson_env%parameters%has_dielectric
2441
2442 ! point pw
2443 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
2444 pw_grid => pw_pool%pw_grid
2445 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
2446 cpabort("vhartree has a different grid than the poisson solver")
2447 END IF
2448 ! density in G space
2449 CALL pw_pool%create_pw(rhog)
2450 IF (PRESENT(aux_density)) THEN
2451 CALL pw_pool%create_pw(rhog_aux)
2452 END IF
2453
2454 SELECT CASE (poisson_env%used_grid)
2455 CASE (use_gs_grid)
2456
2457 SELECT CASE (poisson_env%green_fft%method)
2459
2460 CALL pw_transfer(density, rhog)
2461 IF (PRESENT(aux_density)) THEN
2462 CALL pw_transfer(aux_density, rhog_aux)
2463 END IF
2464 IF (PRESENT(greenfn)) THEN
2465 influence_fn = greenfn
2466 ELSE
2467 influence_fn = poisson_env%green_fft%influence_fn
2468 END IF
2469 CALL pw_multiply_with(rhog, influence_fn)
2470 IF (PRESENT(aux_density)) THEN
2471 CALL pw_multiply_with(rhog_aux, influence_fn)
2472 END IF
2473 CALL pw_transfer(rhog, vhartree)
2474 IF (PRESENT(ehartree)) THEN
2475 IF (PRESENT(aux_density)) THEN
2476 CALL pw_transfer(aux_density, rhog)
2477 ehartree = 0.5_dp*pw_integral_ab(rhog, vhartree)
2478 ELSE
2479 CALL pw_transfer(density, rhog)
2480 ehartree = 0.5_dp*pw_integral_ab(rhog, vhartree)
2481 END IF
2482 END IF
2483
2484 CASE (ps_implicit)
2485 IF (PRESENT(h_stress)) THEN
2486 CALL cp_abort(__location__, &
2487 "No stress tensor is implemented for the implicit Poisson solver.")
2488 END IF
2489
2490 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
2491 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
2493 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
2494 poisson_env%diel_rs_grid, &
2495 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
2496 density, rho_core=rho_core)
2497 CASE (neumann_bc, mixed_bc)
2498 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
2499 poisson_env%diel_rs_grid, &
2500 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
2501 poisson_env%dct_pw_grid, &
2502 poisson_env%parameters%ps_implicit_params%neumann_directions, &
2503 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
2504 poisson_env%implicit_env%dct_env%dests_expand, &
2505 poisson_env%implicit_env%dct_env%srcs_expand, &
2506 poisson_env%implicit_env%dct_env%flipg_stat, &
2507 poisson_env%implicit_env%dct_env%bounds_shftd, &
2508 density, rho_core=rho_core)
2509 END SELECT
2510 END IF
2511
2512 CALL pw_pool%create_pw(rhor)
2513 CALL pw_pool%create_pw(vhartree_rs)
2514 CALL pw_transfer(density, rhor)
2515
2516 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
2517 CASE (periodic_bc)
2518 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
2519 ehartree=ehartree)
2520 CASE (neumann_bc)
2521 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
2522 ehartree=ehartree)
2523 CASE (mixed_periodic_bc)
2524 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
2525 electric_enthalpy=ehartree)
2526 CASE (mixed_bc)
2527 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
2528 electric_enthalpy=ehartree)
2529 END SELECT
2530
2531 CALL pw_transfer(vhartree_rs, vhartree)
2532 CALL pw_transfer(rhor, rhog)
2533
2534 IF (PRESENT(aux_density)) THEN
2535 CALL pw_transfer(aux_density, rhor)
2536 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
2537 END IF
2538
2539 CALL pw_pool%give_back_pw(rhor)
2540 CALL pw_pool%give_back_pw(vhartree_rs)
2541
2542 CASE DEFAULT
2543 CALL cp_abort(__location__, &
2544 "unknown poisson method "// &
2545 cp_to_string(poisson_env%green_fft%method))
2546 END SELECT
2547
2548 CASE (use_rs_grid)
2549
2550 CALL pw_pool%create_pw(rhor)
2551 CALL pw_transfer(density, rhor)
2552 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
2553 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
2554 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
2555 CALL pw_transfer(rhor, vhartree)
2556 CALL pw_transfer(rhor, rhog)
2557 IF (PRESENT(ehartree)) THEN
2558 IF (PRESENT(aux_density)) THEN
2559 ehartree = 0.5_dp*pw_integral_ab(aux_density, rhor)
2560 ELSE
2561 ehartree = 0.5_dp*pw_integral_ab(density, rhor)
2562 END IF
2563 END IF
2564 CALL pw_transfer(rhor, rhog)
2565 IF (PRESENT(aux_density)) THEN
2566 CALL pw_transfer(aux_density, rhor)
2567 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
2568 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
2569 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
2570 CALL pw_transfer(rhor, rhog_aux)
2571 END IF
2572 CALL pw_pool%give_back_pw(rhor)
2573
2574 END SELECT
2575
2576 IF (PRESENT(aux_density)) THEN
2577 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
2578 ELSE
2579 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
2580 END IF
2581 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
2582
2583 CALL pw_pool%give_back_pw(rhog)
2584 IF (PRESENT(aux_density)) THEN
2585 CALL pw_pool%give_back_pw(rhog_aux)
2586 END IF
2587
2588 CALL timestop(handle)
2589
2590 END SUBROUTINE pw_poisson_solve_v_dv_r3d_rs_c1d_gs_r3d_rs
2591! **************************************************************************************************
2592!> \brief Solve Poisson equation in a plane wave basis set
2593!> Obtains electrostatic potential and its derivatives with respect to r
2594!> from the density
2595!> \param poisson_env ...
2596!> \param density ...
2597!> \param ehartree ...
2598!> \param vhartree ...
2599!> \param dvhartree ...
2600!> \param h_stress ...
2601!> \param rho_core ...
2602!> \param greenfn ...
2603!> \param aux_density Hartree energy and stress tensor between 2 different densities
2604!> \par History
2605!> JGH (13-Mar-2001) : completely revised
2606!> \author apsi
2607! **************************************************************************************************
2608 SUBROUTINE pw_poisson_solve_v_dv_r3d_rs_r3d_rs_c1d_gs (poisson_env, density, ehartree, vhartree, &
2609 dvhartree, h_stress, rho_core, greenfn, aux_density)
2610
2611 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
2612 TYPE(pw_r3d_rs_type), INTENT(IN) :: density
2613 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
2614 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: vhartree
2615 TYPE(pw_c1d_gs_type), DIMENSION(3) :: dvhartree
2616 REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT), &
2617 OPTIONAL :: h_stress
2618 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
2619 TYPE(pw_r3d_rs_type), INTENT(IN), OPTIONAL :: aux_density
2620
2621 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
2622
2623 INTEGER :: handle
2624 LOGICAL :: has_dielectric
2625 TYPE(pw_grid_type), POINTER :: pw_grid
2626 TYPE(pw_pool_type), POINTER :: pw_pool
2627 TYPE(pw_r3d_rs_type) :: rhor, vhartree_rs
2628 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
2629
2630 CALL timeset(routinen, handle)
2631
2632 CALL pw_poisson_rebuild(poisson_env, density)
2633
2634 has_dielectric = poisson_env%parameters%has_dielectric
2635
2636 ! point pw
2637 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
2638 pw_grid => pw_pool%pw_grid
2639 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
2640 cpabort("vhartree has a different grid than the poisson solver")
2641 END IF
2642 ! density in G space
2643 CALL pw_pool%create_pw(rhog)
2644 IF (PRESENT(aux_density)) THEN
2645 CALL pw_pool%create_pw(rhog_aux)
2646 END IF
2647
2648 SELECT CASE (poisson_env%used_grid)
2649 CASE (use_gs_grid)
2650
2651 SELECT CASE (poisson_env%green_fft%method)
2653
2654 CALL pw_transfer(density, rhog)
2655 IF (PRESENT(aux_density)) THEN
2656 CALL pw_transfer(aux_density, rhog_aux)
2657 END IF
2658 IF (PRESENT(greenfn)) THEN
2659 influence_fn = greenfn
2660 ELSE
2661 influence_fn = poisson_env%green_fft%influence_fn
2662 END IF
2663 CALL pw_multiply_with(rhog, influence_fn)
2664 IF (PRESENT(aux_density)) THEN
2665 CALL pw_multiply_with(rhog_aux, influence_fn)
2666 END IF
2667 CALL pw_transfer(rhog, vhartree)
2668 IF (PRESENT(ehartree)) THEN
2669 IF (PRESENT(aux_density)) THEN
2670 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
2671 ELSE
2672 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
2673 END IF
2674 END IF
2675
2676 CASE (ps_implicit)
2677 IF (PRESENT(h_stress)) THEN
2678 CALL cp_abort(__location__, &
2679 "No stress tensor is implemented for the implicit Poisson solver.")
2680 END IF
2681
2682 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
2683 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
2685 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
2686 poisson_env%diel_rs_grid, &
2687 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
2688 density, rho_core=rho_core)
2689 CASE (neumann_bc, mixed_bc)
2690 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
2691 poisson_env%diel_rs_grid, &
2692 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
2693 poisson_env%dct_pw_grid, &
2694 poisson_env%parameters%ps_implicit_params%neumann_directions, &
2695 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
2696 poisson_env%implicit_env%dct_env%dests_expand, &
2697 poisson_env%implicit_env%dct_env%srcs_expand, &
2698 poisson_env%implicit_env%dct_env%flipg_stat, &
2699 poisson_env%implicit_env%dct_env%bounds_shftd, &
2700 density, rho_core=rho_core)
2701 END SELECT
2702 END IF
2703
2704 CALL pw_pool%create_pw(rhor)
2705 CALL pw_pool%create_pw(vhartree_rs)
2706 CALL pw_transfer(density, rhor)
2707
2708 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
2709 CASE (periodic_bc)
2710 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
2711 ehartree=ehartree)
2712 CASE (neumann_bc)
2713 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
2714 ehartree=ehartree)
2715 CASE (mixed_periodic_bc)
2716 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
2717 electric_enthalpy=ehartree)
2718 CASE (mixed_bc)
2719 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
2720 electric_enthalpy=ehartree)
2721 END SELECT
2722
2723 CALL pw_transfer(vhartree_rs, vhartree)
2724 CALL pw_transfer(rhor, rhog)
2725
2726 IF (PRESENT(aux_density)) THEN
2727 CALL pw_transfer(aux_density, rhor)
2728 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
2729 END IF
2730
2731 CALL pw_pool%give_back_pw(rhor)
2732 CALL pw_pool%give_back_pw(vhartree_rs)
2733
2734 CASE DEFAULT
2735 CALL cp_abort(__location__, &
2736 "unknown poisson method "// &
2737 cp_to_string(poisson_env%green_fft%method))
2738 END SELECT
2739
2740 CASE (use_rs_grid)
2741
2742 CALL pw_pool%create_pw(rhor)
2743 CALL pw_transfer(density, rhor)
2744 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
2745 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
2746 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
2747 CALL pw_transfer(rhor, vhartree)
2748 CALL pw_transfer(rhor, rhog)
2749 IF (PRESENT(ehartree)) THEN
2750 IF (PRESENT(aux_density)) THEN
2751 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
2752 ELSE
2753 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
2754 END IF
2755 END IF
2756 CALL pw_transfer(rhor, rhog)
2757 IF (PRESENT(aux_density)) THEN
2758 CALL pw_transfer(aux_density, rhor)
2759 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
2760 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
2761 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
2762 CALL pw_transfer(rhor, rhog_aux)
2763 END IF
2764 CALL pw_pool%give_back_pw(rhor)
2765
2766 END SELECT
2767
2768 IF (PRESENT(aux_density)) THEN
2769 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
2770 ELSE
2771 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
2772 END IF
2773 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
2774
2775 CALL pw_pool%give_back_pw(rhog)
2776 IF (PRESENT(aux_density)) THEN
2777 CALL pw_pool%give_back_pw(rhog_aux)
2778 END IF
2779
2780 CALL timestop(handle)
2781
2782 END SUBROUTINE pw_poisson_solve_v_dv_r3d_rs_r3d_rs_c1d_gs
2783! **************************************************************************************************
2784!> \brief Solve Poisson equation in a plane wave basis set
2785!> Obtains electrostatic potential and its derivatives with respect to r
2786!> from the density
2787!> \param poisson_env ...
2788!> \param density ...
2789!> \param ehartree ...
2790!> \param vhartree ...
2791!> \param dvhartree ...
2792!> \param h_stress ...
2793!> \param rho_core ...
2794!> \param greenfn ...
2795!> \param aux_density Hartree energy and stress tensor between 2 different densities
2796!> \par History
2797!> JGH (13-Mar-2001) : completely revised
2798!> \author apsi
2799! **************************************************************************************************
2800 SUBROUTINE pw_poisson_solve_v_dv_r3d_rs_c1d_gs_c1d_gs (poisson_env, density, ehartree, vhartree, &
2801 dvhartree, h_stress, rho_core, greenfn, aux_density)
2802
2803 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
2804 TYPE(pw_r3d_rs_type), INTENT(IN) :: density
2805 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
2806 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: vhartree
2807 TYPE(pw_c1d_gs_type), DIMENSION(3) :: dvhartree
2808 REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT), &
2809 OPTIONAL :: h_stress
2810 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
2811 TYPE(pw_r3d_rs_type), INTENT(IN), OPTIONAL :: aux_density
2812
2813 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
2814
2815 INTEGER :: handle
2816 LOGICAL :: has_dielectric
2817 TYPE(pw_grid_type), POINTER :: pw_grid
2818 TYPE(pw_pool_type), POINTER :: pw_pool
2819 TYPE(pw_r3d_rs_type) :: rhor, vhartree_rs
2820 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
2821
2822 CALL timeset(routinen, handle)
2823
2824 CALL pw_poisson_rebuild(poisson_env, density)
2825
2826 has_dielectric = poisson_env%parameters%has_dielectric
2827
2828 ! point pw
2829 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
2830 pw_grid => pw_pool%pw_grid
2831 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
2832 cpabort("vhartree has a different grid than the poisson solver")
2833 END IF
2834 ! density in G space
2835 CALL pw_pool%create_pw(rhog)
2836 IF (PRESENT(aux_density)) THEN
2837 CALL pw_pool%create_pw(rhog_aux)
2838 END IF
2839
2840 SELECT CASE (poisson_env%used_grid)
2841 CASE (use_gs_grid)
2842
2843 SELECT CASE (poisson_env%green_fft%method)
2845
2846 CALL pw_transfer(density, rhog)
2847 IF (PRESENT(aux_density)) THEN
2848 CALL pw_transfer(aux_density, rhog_aux)
2849 END IF
2850 IF (PRESENT(greenfn)) THEN
2851 influence_fn = greenfn
2852 ELSE
2853 influence_fn = poisson_env%green_fft%influence_fn
2854 END IF
2855 CALL pw_multiply_with(rhog, influence_fn)
2856 IF (PRESENT(aux_density)) THEN
2857 CALL pw_multiply_with(rhog_aux, influence_fn)
2858 END IF
2859 CALL pw_transfer(rhog, vhartree)
2860 IF (PRESENT(ehartree)) THEN
2861 IF (PRESENT(aux_density)) THEN
2862 CALL pw_transfer(aux_density, rhog)
2863 ehartree = 0.5_dp*pw_integral_ab(rhog, vhartree)
2864 ELSE
2865 CALL pw_transfer(density, rhog)
2866 ehartree = 0.5_dp*pw_integral_ab(rhog, vhartree)
2867 END IF
2868 END IF
2869
2870 CASE (ps_implicit)
2871 IF (PRESENT(h_stress)) THEN
2872 CALL cp_abort(__location__, &
2873 "No stress tensor is implemented for the implicit Poisson solver.")
2874 END IF
2875
2876 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
2877 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
2879 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
2880 poisson_env%diel_rs_grid, &
2881 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
2882 density, rho_core=rho_core)
2883 CASE (neumann_bc, mixed_bc)
2884 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
2885 poisson_env%diel_rs_grid, &
2886 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
2887 poisson_env%dct_pw_grid, &
2888 poisson_env%parameters%ps_implicit_params%neumann_directions, &
2889 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
2890 poisson_env%implicit_env%dct_env%dests_expand, &
2891 poisson_env%implicit_env%dct_env%srcs_expand, &
2892 poisson_env%implicit_env%dct_env%flipg_stat, &
2893 poisson_env%implicit_env%dct_env%bounds_shftd, &
2894 density, rho_core=rho_core)
2895 END SELECT
2896 END IF
2897
2898 CALL pw_pool%create_pw(rhor)
2899 CALL pw_pool%create_pw(vhartree_rs)
2900 CALL pw_transfer(density, rhor)
2901
2902 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
2903 CASE (periodic_bc)
2904 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
2905 ehartree=ehartree)
2906 CASE (neumann_bc)
2907 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
2908 ehartree=ehartree)
2909 CASE (mixed_periodic_bc)
2910 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
2911 electric_enthalpy=ehartree)
2912 CASE (mixed_bc)
2913 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
2914 electric_enthalpy=ehartree)
2915 END SELECT
2916
2917 CALL pw_transfer(vhartree_rs, vhartree)
2918 CALL pw_transfer(rhor, rhog)
2919
2920 IF (PRESENT(aux_density)) THEN
2921 CALL pw_transfer(aux_density, rhor)
2922 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
2923 END IF
2924
2925 CALL pw_pool%give_back_pw(rhor)
2926 CALL pw_pool%give_back_pw(vhartree_rs)
2927
2928 CASE DEFAULT
2929 CALL cp_abort(__location__, &
2930 "unknown poisson method "// &
2931 cp_to_string(poisson_env%green_fft%method))
2932 END SELECT
2933
2934 CASE (use_rs_grid)
2935
2936 CALL pw_pool%create_pw(rhor)
2937 CALL pw_transfer(density, rhor)
2938 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
2939 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
2940 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
2941 CALL pw_transfer(rhor, vhartree)
2942 CALL pw_transfer(rhor, rhog)
2943 IF (PRESENT(ehartree)) THEN
2944 IF (PRESENT(aux_density)) THEN
2945 ehartree = 0.5_dp*pw_integral_ab(aux_density, rhor)
2946 ELSE
2947 ehartree = 0.5_dp*pw_integral_ab(density, rhor)
2948 END IF
2949 END IF
2950 CALL pw_transfer(rhor, rhog)
2951 IF (PRESENT(aux_density)) THEN
2952 CALL pw_transfer(aux_density, rhor)
2953 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
2954 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
2955 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
2956 CALL pw_transfer(rhor, rhog_aux)
2957 END IF
2958 CALL pw_pool%give_back_pw(rhor)
2959
2960 END SELECT
2961
2962 IF (PRESENT(aux_density)) THEN
2963 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
2964 ELSE
2965 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
2966 END IF
2967 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
2968
2969 CALL pw_pool%give_back_pw(rhog)
2970 IF (PRESENT(aux_density)) THEN
2971 CALL pw_pool%give_back_pw(rhog_aux)
2972 END IF
2973
2974 CALL timestop(handle)
2975
2976 END SUBROUTINE pw_poisson_solve_v_dv_r3d_rs_c1d_gs_c1d_gs
2977! **************************************************************************************************
2978!> \brief Solve Poisson equation in a plane wave basis set
2979!> Obtains electrostatic potential and its derivatives with respect to r
2980!> from the density
2981!> \param poisson_env ...
2982!> \param density ...
2983!> \param ehartree ...
2984!> \param vhartree ...
2985!> \param dvhartree ...
2986!> \param h_stress ...
2987!> \param rho_core ...
2988!> \param greenfn ...
2989!> \param aux_density Hartree energy and stress tensor between 2 different densities
2990!> \par History
2991!> JGH (13-Mar-2001) : completely revised
2992!> \author apsi
2993! **************************************************************************************************
2994 SUBROUTINE pw_poisson_solve_v_dv_c1d_gs_r3d_rs_r3d_rs (poisson_env, density, ehartree, vhartree, &
2995 dvhartree, h_stress, rho_core, greenfn, aux_density)
2996
2997 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
2998 TYPE(pw_c1d_gs_type), INTENT(IN) :: density
2999 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
3000 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: vhartree
3001 TYPE(pw_r3d_rs_type), DIMENSION(3) :: dvhartree
3002 REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT), &
3003 OPTIONAL :: h_stress
3004 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
3005 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: aux_density
3006
3007 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
3008
3009 INTEGER :: handle
3010 LOGICAL :: has_dielectric
3011 TYPE(pw_grid_type), POINTER :: pw_grid
3012 TYPE(pw_pool_type), POINTER :: pw_pool
3013 TYPE(pw_r3d_rs_type) :: rhor, vhartree_rs
3014 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
3015
3016 CALL timeset(routinen, handle)
3017
3018 CALL pw_poisson_rebuild(poisson_env, density)
3019
3020 has_dielectric = poisson_env%parameters%has_dielectric
3021
3022 ! point pw
3023 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
3024 pw_grid => pw_pool%pw_grid
3025 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
3026 cpabort("vhartree has a different grid than the poisson solver")
3027 END IF
3028 ! density in G space
3029 CALL pw_pool%create_pw(rhog)
3030 IF (PRESENT(aux_density)) THEN
3031 CALL pw_pool%create_pw(rhog_aux)
3032 END IF
3033
3034 SELECT CASE (poisson_env%used_grid)
3035 CASE (use_gs_grid)
3036
3037 SELECT CASE (poisson_env%green_fft%method)
3039
3040 CALL pw_transfer(density, rhog)
3041 IF (PRESENT(aux_density)) THEN
3042 CALL pw_transfer(aux_density, rhog_aux)
3043 END IF
3044 IF (PRESENT(greenfn)) THEN
3045 influence_fn = greenfn
3046 ELSE
3047 influence_fn = poisson_env%green_fft%influence_fn
3048 END IF
3049 CALL pw_multiply_with(rhog, influence_fn)
3050 IF (PRESENT(aux_density)) THEN
3051 CALL pw_multiply_with(rhog_aux, influence_fn)
3052 END IF
3053 CALL pw_transfer(rhog, vhartree)
3054 IF (PRESENT(ehartree)) THEN
3055 IF (PRESENT(aux_density)) THEN
3056 ehartree = 0.5_dp*pw_integral_ab(aux_density, rhog)
3057 ELSE
3058 ehartree = 0.5_dp*pw_integral_ab(density, rhog)
3059 END IF
3060 END IF
3061
3062 CASE (ps_implicit)
3063 IF (PRESENT(h_stress)) THEN
3064 CALL cp_abort(__location__, &
3065 "No stress tensor is implemented for the implicit Poisson solver.")
3066 END IF
3067
3068 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
3069 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
3071 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
3072 poisson_env%diel_rs_grid, &
3073 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
3074 density, rho_core=rho_core)
3075 CASE (neumann_bc, mixed_bc)
3076 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
3077 poisson_env%diel_rs_grid, &
3078 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
3079 poisson_env%dct_pw_grid, &
3080 poisson_env%parameters%ps_implicit_params%neumann_directions, &
3081 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
3082 poisson_env%implicit_env%dct_env%dests_expand, &
3083 poisson_env%implicit_env%dct_env%srcs_expand, &
3084 poisson_env%implicit_env%dct_env%flipg_stat, &
3085 poisson_env%implicit_env%dct_env%bounds_shftd, &
3086 density, rho_core=rho_core)
3087 END SELECT
3088 END IF
3089
3090 CALL pw_pool%create_pw(rhor)
3091 CALL pw_pool%create_pw(vhartree_rs)
3092 CALL pw_transfer(density, rhor)
3093
3094 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
3095 CASE (periodic_bc)
3096 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
3097 ehartree=ehartree)
3098 CASE (neumann_bc)
3099 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
3100 ehartree=ehartree)
3101 CASE (mixed_periodic_bc)
3102 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
3103 electric_enthalpy=ehartree)
3104 CASE (mixed_bc)
3105 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
3106 electric_enthalpy=ehartree)
3107 END SELECT
3108
3109 CALL pw_transfer(vhartree_rs, vhartree)
3110 CALL pw_transfer(rhor, rhog)
3111
3112 IF (PRESENT(aux_density)) THEN
3113 CALL pw_transfer(aux_density, rhor)
3114 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
3115 END IF
3116
3117 CALL pw_pool%give_back_pw(rhor)
3118 CALL pw_pool%give_back_pw(vhartree_rs)
3119
3120 CASE DEFAULT
3121 CALL cp_abort(__location__, &
3122 "unknown poisson method "// &
3123 cp_to_string(poisson_env%green_fft%method))
3124 END SELECT
3125
3126 CASE (use_rs_grid)
3127
3128 CALL pw_pool%create_pw(rhor)
3129 CALL pw_transfer(density, rhor)
3130 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
3131 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
3132 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
3133 CALL pw_transfer(rhor, vhartree)
3134 CALL pw_transfer(rhor, rhog)
3135 IF (PRESENT(ehartree)) THEN
3136 IF (PRESENT(aux_density)) THEN
3137 ehartree = 0.5_dp*pw_integral_ab(aux_density, rhog)
3138 ELSE
3139 ehartree = 0.5_dp*pw_integral_ab(density, rhog)
3140 END IF
3141 END IF
3142 CALL pw_transfer(rhor, rhog)
3143 IF (PRESENT(aux_density)) THEN
3144 CALL pw_transfer(aux_density, rhor)
3145 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
3146 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
3147 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
3148 CALL pw_transfer(rhor, rhog_aux)
3149 END IF
3150 CALL pw_pool%give_back_pw(rhor)
3151
3152 END SELECT
3153
3154 IF (PRESENT(aux_density)) THEN
3155 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
3156 ELSE
3157 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
3158 END IF
3159 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
3160
3161 CALL pw_pool%give_back_pw(rhog)
3162 IF (PRESENT(aux_density)) THEN
3163 CALL pw_pool%give_back_pw(rhog_aux)
3164 END IF
3165
3166 CALL timestop(handle)
3167
3168 END SUBROUTINE pw_poisson_solve_v_dv_c1d_gs_r3d_rs_r3d_rs
3169! **************************************************************************************************
3170!> \brief Solve Poisson equation in a plane wave basis set
3171!> Obtains electrostatic potential and its derivatives with respect to r
3172!> from the density
3173!> \param poisson_env ...
3174!> \param density ...
3175!> \param ehartree ...
3176!> \param vhartree ...
3177!> \param dvhartree ...
3178!> \param h_stress ...
3179!> \param rho_core ...
3180!> \param greenfn ...
3181!> \param aux_density Hartree energy and stress tensor between 2 different densities
3182!> \par History
3183!> JGH (13-Mar-2001) : completely revised
3184!> \author apsi
3185! **************************************************************************************************
3186 SUBROUTINE pw_poisson_solve_v_dv_c1d_gs_c1d_gs_r3d_rs (poisson_env, density, ehartree, vhartree, &
3187 dvhartree, h_stress, rho_core, greenfn, aux_density)
3188
3189 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
3190 TYPE(pw_c1d_gs_type), INTENT(IN) :: density
3191 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
3192 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: vhartree
3193 TYPE(pw_r3d_rs_type), DIMENSION(3) :: dvhartree
3194 REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT), &
3195 OPTIONAL :: h_stress
3196 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
3197 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: aux_density
3198
3199 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
3200
3201 INTEGER :: handle
3202 LOGICAL :: has_dielectric
3203 TYPE(pw_grid_type), POINTER :: pw_grid
3204 TYPE(pw_pool_type), POINTER :: pw_pool
3205 TYPE(pw_r3d_rs_type) :: rhor, vhartree_rs
3206 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
3207
3208 CALL timeset(routinen, handle)
3209
3210 CALL pw_poisson_rebuild(poisson_env, density)
3211
3212 has_dielectric = poisson_env%parameters%has_dielectric
3213
3214 ! point pw
3215 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
3216 pw_grid => pw_pool%pw_grid
3217 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
3218 cpabort("vhartree has a different grid than the poisson solver")
3219 END IF
3220 ! density in G space
3221 CALL pw_pool%create_pw(rhog)
3222 IF (PRESENT(aux_density)) THEN
3223 CALL pw_pool%create_pw(rhog_aux)
3224 END IF
3225
3226 SELECT CASE (poisson_env%used_grid)
3227 CASE (use_gs_grid)
3228
3229 SELECT CASE (poisson_env%green_fft%method)
3231
3232 CALL pw_transfer(density, rhog)
3233 IF (PRESENT(aux_density)) THEN
3234 CALL pw_transfer(aux_density, rhog_aux)
3235 END IF
3236 IF (PRESENT(greenfn)) THEN
3237 influence_fn = greenfn
3238 ELSE
3239 influence_fn = poisson_env%green_fft%influence_fn
3240 END IF
3241 CALL pw_multiply_with(rhog, influence_fn)
3242 IF (PRESENT(aux_density)) THEN
3243 CALL pw_multiply_with(rhog_aux, influence_fn)
3244 END IF
3245 CALL pw_transfer(rhog, vhartree)
3246 IF (PRESENT(ehartree)) THEN
3247 IF (PRESENT(aux_density)) THEN
3248 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
3249 ELSE
3250 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
3251 END IF
3252 END IF
3253
3254 CASE (ps_implicit)
3255 IF (PRESENT(h_stress)) THEN
3256 CALL cp_abort(__location__, &
3257 "No stress tensor is implemented for the implicit Poisson solver.")
3258 END IF
3259
3260 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
3261 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
3263 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
3264 poisson_env%diel_rs_grid, &
3265 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
3266 density, rho_core=rho_core)
3267 CASE (neumann_bc, mixed_bc)
3268 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
3269 poisson_env%diel_rs_grid, &
3270 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
3271 poisson_env%dct_pw_grid, &
3272 poisson_env%parameters%ps_implicit_params%neumann_directions, &
3273 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
3274 poisson_env%implicit_env%dct_env%dests_expand, &
3275 poisson_env%implicit_env%dct_env%srcs_expand, &
3276 poisson_env%implicit_env%dct_env%flipg_stat, &
3277 poisson_env%implicit_env%dct_env%bounds_shftd, &
3278 density, rho_core=rho_core)
3279 END SELECT
3280 END IF
3281
3282 CALL pw_pool%create_pw(rhor)
3283 CALL pw_pool%create_pw(vhartree_rs)
3284 CALL pw_transfer(density, rhor)
3285
3286 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
3287 CASE (periodic_bc)
3288 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
3289 ehartree=ehartree)
3290 CASE (neumann_bc)
3291 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
3292 ehartree=ehartree)
3293 CASE (mixed_periodic_bc)
3294 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
3295 electric_enthalpy=ehartree)
3296 CASE (mixed_bc)
3297 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
3298 electric_enthalpy=ehartree)
3299 END SELECT
3300
3301 CALL pw_transfer(vhartree_rs, vhartree)
3302 CALL pw_transfer(rhor, rhog)
3303
3304 IF (PRESENT(aux_density)) THEN
3305 CALL pw_transfer(aux_density, rhor)
3306 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
3307 END IF
3308
3309 CALL pw_pool%give_back_pw(rhor)
3310 CALL pw_pool%give_back_pw(vhartree_rs)
3311
3312 CASE DEFAULT
3313 CALL cp_abort(__location__, &
3314 "unknown poisson method "// &
3315 cp_to_string(poisson_env%green_fft%method))
3316 END SELECT
3317
3318 CASE (use_rs_grid)
3319
3320 CALL pw_pool%create_pw(rhor)
3321 CALL pw_transfer(density, rhor)
3322 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
3323 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
3324 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
3325 CALL pw_transfer(rhor, vhartree)
3326 CALL pw_transfer(rhor, rhog)
3327 IF (PRESENT(ehartree)) THEN
3328 IF (PRESENT(aux_density)) THEN
3329 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
3330 ELSE
3331 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
3332 END IF
3333 END IF
3334 CALL pw_transfer(rhor, rhog)
3335 IF (PRESENT(aux_density)) THEN
3336 CALL pw_transfer(aux_density, rhor)
3337 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
3338 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
3339 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
3340 CALL pw_transfer(rhor, rhog_aux)
3341 END IF
3342 CALL pw_pool%give_back_pw(rhor)
3343
3344 END SELECT
3345
3346 IF (PRESENT(aux_density)) THEN
3347 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
3348 ELSE
3349 CALL calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
3350 END IF
3351 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
3352
3353 CALL pw_pool%give_back_pw(rhog)
3354 IF (PRESENT(aux_density)) THEN
3355 CALL pw_pool%give_back_pw(rhog_aux)
3356 END IF
3357
3358 CALL timestop(handle)
3359
3360 END SUBROUTINE pw_poisson_solve_v_dv_c1d_gs_c1d_gs_r3d_rs
3361! **************************************************************************************************
3362!> \brief Solve Poisson equation in a plane wave basis set
3363!> Obtains electrostatic potential and its derivatives with respect to r
3364!> from the density
3365!> \param poisson_env ...
3366!> \param density ...
3367!> \param ehartree ...
3368!> \param vhartree ...
3369!> \param dvhartree ...
3370!> \param h_stress ...
3371!> \param rho_core ...
3372!> \param greenfn ...
3373!> \param aux_density Hartree energy and stress tensor between 2 different densities
3374!> \par History
3375!> JGH (13-Mar-2001) : completely revised
3376!> \author apsi
3377! **************************************************************************************************
3378 SUBROUTINE pw_poisson_solve_v_dv_c1d_gs_r3d_rs_c1d_gs (poisson_env, density, ehartree, vhartree, &
3379 dvhartree, h_stress, rho_core, greenfn, aux_density)
3380
3381 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
3382 TYPE(pw_c1d_gs_type), INTENT(IN) :: density
3383 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
3384 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: vhartree
3385 TYPE(pw_c1d_gs_type), DIMENSION(3) :: dvhartree
3386 REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT), &
3387 OPTIONAL :: h_stress
3388 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
3389 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: aux_density
3390
3391 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
3392
3393 INTEGER :: handle
3394 LOGICAL :: has_dielectric
3395 TYPE(pw_grid_type), POINTER :: pw_grid
3396 TYPE(pw_pool_type), POINTER :: pw_pool
3397 TYPE(pw_r3d_rs_type) :: rhor, vhartree_rs
3398 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
3399
3400 CALL timeset(routinen, handle)
3401
3402 CALL pw_poisson_rebuild(poisson_env, density)
3403
3404 has_dielectric = poisson_env%parameters%has_dielectric
3405
3406 ! point pw
3407 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
3408 pw_grid => pw_pool%pw_grid
3409 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
3410 cpabort("vhartree has a different grid than the poisson solver")
3411 END IF
3412 ! density in G space
3413 CALL pw_pool%create_pw(rhog)
3414 IF (PRESENT(aux_density)) THEN
3415 CALL pw_pool%create_pw(rhog_aux)
3416 END IF
3417
3418 SELECT CASE (poisson_env%used_grid)
3419 CASE (use_gs_grid)
3420
3421 SELECT CASE (poisson_env%green_fft%method)
3423
3424 CALL pw_transfer(density, rhog)
3425 IF (PRESENT(aux_density)) THEN
3426 CALL pw_transfer(aux_density, rhog_aux)
3427 END IF
3428 IF (PRESENT(greenfn)) THEN
3429 influence_fn = greenfn
3430 ELSE
3431 influence_fn = poisson_env%green_fft%influence_fn
3432 END IF
3433 CALL pw_multiply_with(rhog, influence_fn)
3434 IF (PRESENT(aux_density)) THEN
3435 CALL pw_multiply_with(rhog_aux, influence_fn)
3436 END IF
3437 CALL pw_transfer(rhog, vhartree)
3438 IF (PRESENT(ehartree)) THEN
3439 IF (PRESENT(aux_density)) THEN
3440 ehartree = 0.5_dp*pw_integral_ab(aux_density, rhog)
3441 ELSE
3442 ehartree = 0.5_dp*pw_integral_ab(density, rhog)
3443 END IF
3444 END IF
3445
3446 CASE (ps_implicit)
3447 IF (PRESENT(h_stress)) THEN
3448 CALL cp_abort(__location__, &
3449 "No stress tensor is implemented for the implicit Poisson solver.")
3450 END IF
3451
3452 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
3453 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
3455 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
3456 poisson_env%diel_rs_grid, &
3457 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
3458 density, rho_core=rho_core)
3459 CASE (neumann_bc, mixed_bc)
3460 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
3461 poisson_env%diel_rs_grid, &
3462 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
3463 poisson_env%dct_pw_grid, &
3464 poisson_env%parameters%ps_implicit_params%neumann_directions, &
3465 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
3466 poisson_env%implicit_env%dct_env%dests_expand, &
3467 poisson_env%implicit_env%dct_env%srcs_expand, &
3468 poisson_env%implicit_env%dct_env%flipg_stat, &
3469 poisson_env%implicit_env%dct_env%bounds_shftd, &
3470 density, rho_core=rho_core)
3471 END SELECT
3472 END IF
3473
3474 CALL pw_pool%create_pw(rhor)
3475 CALL pw_pool%create_pw(vhartree_rs)
3476 CALL pw_transfer(density, rhor)
3477
3478 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
3479 CASE (periodic_bc)
3480 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
3481 ehartree=ehartree)
3482 CASE (neumann_bc)
3483 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
3484 ehartree=ehartree)
3485 CASE (mixed_periodic_bc)
3486 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
3487 electric_enthalpy=ehartree)
3488 CASE (mixed_bc)
3489 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
3490 electric_enthalpy=ehartree)
3491 END SELECT
3492
3493 CALL pw_transfer(vhartree_rs, vhartree)
3494 CALL pw_transfer(rhor, rhog)
3495
3496 IF (PRESENT(aux_density)) THEN
3497 CALL pw_transfer(aux_density, rhor)
3498 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
3499 END IF
3500
3501 CALL pw_pool%give_back_pw(rhor)
3502 CALL pw_pool%give_back_pw(vhartree_rs)
3503
3504 CASE DEFAULT
3505 CALL cp_abort(__location__, &
3506 "unknown poisson method "// &
3507 cp_to_string(poisson_env%green_fft%method))
3508 END SELECT
3509
3510 CASE (use_rs_grid)
3511
3512 CALL pw_pool%create_pw(rhor)
3513 CALL pw_transfer(density, rhor)
3514 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
3515 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
3516 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
3517 CALL pw_transfer(rhor, vhartree)
3518 CALL pw_transfer(rhor, rhog)
3519 IF (PRESENT(ehartree)) THEN
3520 IF (PRESENT(aux_density)) THEN
3521 ehartree = 0.5_dp*pw_integral_ab(aux_density, rhog)
3522 ELSE
3523 ehartree = 0.5_dp*pw_integral_ab(density, rhog)
3524 END IF
3525 END IF
3526 CALL pw_transfer(rhor, rhog)
3527 IF (PRESENT(aux_density)) THEN
3528 CALL pw_transfer(aux_density, rhor)
3529 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
3530 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
3531 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
3532 CALL pw_transfer(rhor, rhog_aux)
3533 END IF
3534 CALL pw_pool%give_back_pw(rhor)
3535
3536 END SELECT
3537
3538 IF (PRESENT(aux_density)) THEN
3539 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
3540 ELSE
3541 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
3542 END IF
3543 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
3544
3545 CALL pw_pool%give_back_pw(rhog)
3546 IF (PRESENT(aux_density)) THEN
3547 CALL pw_pool%give_back_pw(rhog_aux)
3548 END IF
3549
3550 CALL timestop(handle)
3551
3552 END SUBROUTINE pw_poisson_solve_v_dv_c1d_gs_r3d_rs_c1d_gs
3553! **************************************************************************************************
3554!> \brief Solve Poisson equation in a plane wave basis set
3555!> Obtains electrostatic potential and its derivatives with respect to r
3556!> from the density
3557!> \param poisson_env ...
3558!> \param density ...
3559!> \param ehartree ...
3560!> \param vhartree ...
3561!> \param dvhartree ...
3562!> \param h_stress ...
3563!> \param rho_core ...
3564!> \param greenfn ...
3565!> \param aux_density Hartree energy and stress tensor between 2 different densities
3566!> \par History
3567!> JGH (13-Mar-2001) : completely revised
3568!> \author apsi
3569! **************************************************************************************************
3570 SUBROUTINE pw_poisson_solve_v_dv_c1d_gs_c1d_gs_c1d_gs (poisson_env, density, ehartree, vhartree, &
3571 dvhartree, h_stress, rho_core, greenfn, aux_density)
3572
3573 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
3574 TYPE(pw_c1d_gs_type), INTENT(IN) :: density
3575 REAL(kind=dp), INTENT(out), OPTIONAL :: ehartree
3576 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: vhartree
3577 TYPE(pw_c1d_gs_type), DIMENSION(3) :: dvhartree
3578 REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT), &
3579 OPTIONAL :: h_stress
3580 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rho_core, greenfn
3581 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: aux_density
3582
3583 CHARACTER(len=*), PARAMETER :: routineN = 'pw_poisson_solve'
3584
3585 INTEGER :: handle
3586 LOGICAL :: has_dielectric
3587 TYPE(pw_grid_type), POINTER :: pw_grid
3588 TYPE(pw_pool_type), POINTER :: pw_pool
3589 TYPE(pw_r3d_rs_type) :: rhor, vhartree_rs
3590 TYPE(pw_c1d_gs_type) :: influence_fn, rhog, rhog_aux
3591
3592 CALL timeset(routinen, handle)
3593
3594 CALL pw_poisson_rebuild(poisson_env, density)
3595
3596 has_dielectric = poisson_env%parameters%has_dielectric
3597
3598 ! point pw
3599 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
3600 pw_grid => pw_pool%pw_grid
3601 IF (.NOT. pw_grid_compare(pw_pool%pw_grid, vhartree%pw_grid)) THEN
3602 cpabort("vhartree has a different grid than the poisson solver")
3603 END IF
3604 ! density in G space
3605 CALL pw_pool%create_pw(rhog)
3606 IF (PRESENT(aux_density)) THEN
3607 CALL pw_pool%create_pw(rhog_aux)
3608 END IF
3609
3610 SELECT CASE (poisson_env%used_grid)
3611 CASE (use_gs_grid)
3612
3613 SELECT CASE (poisson_env%green_fft%method)
3615
3616 CALL pw_transfer(density, rhog)
3617 IF (PRESENT(aux_density)) THEN
3618 CALL pw_transfer(aux_density, rhog_aux)
3619 END IF
3620 IF (PRESENT(greenfn)) THEN
3621 influence_fn = greenfn
3622 ELSE
3623 influence_fn = poisson_env%green_fft%influence_fn
3624 END IF
3625 CALL pw_multiply_with(rhog, influence_fn)
3626 IF (PRESENT(aux_density)) THEN
3627 CALL pw_multiply_with(rhog_aux, influence_fn)
3628 END IF
3629 CALL pw_transfer(rhog, vhartree)
3630 IF (PRESENT(ehartree)) THEN
3631 IF (PRESENT(aux_density)) THEN
3632 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
3633 ELSE
3634 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
3635 END IF
3636 END IF
3637
3638 CASE (ps_implicit)
3639 IF (PRESENT(h_stress)) THEN
3640 CALL cp_abort(__location__, &
3641 "No stress tensor is implemented for the implicit Poisson solver.")
3642 END IF
3643
3644 IF (has_dielectric .AND. PRESENT(rho_core)) THEN
3645 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
3647 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
3648 poisson_env%diel_rs_grid, &
3649 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
3650 density, rho_core=rho_core)
3651 CASE (neumann_bc, mixed_bc)
3652 CALL dielectric_compute(poisson_env%implicit_env%dielectric, &
3653 poisson_env%diel_rs_grid, &
3654 poisson_env%pw_pools(poisson_env%pw_level)%pool, &
3655 poisson_env%dct_pw_grid, &
3656 poisson_env%parameters%ps_implicit_params%neumann_directions, &
3657 poisson_env%implicit_env%dct_env%recv_msgs_bnds, &
3658 poisson_env%implicit_env%dct_env%dests_expand, &
3659 poisson_env%implicit_env%dct_env%srcs_expand, &
3660 poisson_env%implicit_env%dct_env%flipg_stat, &
3661 poisson_env%implicit_env%dct_env%bounds_shftd, &
3662 density, rho_core=rho_core)
3663 END SELECT
3664 END IF
3665
3666 CALL pw_pool%create_pw(rhor)
3667 CALL pw_pool%create_pw(vhartree_rs)
3668 CALL pw_transfer(density, rhor)
3669
3670 SELECT CASE (poisson_env%parameters%ps_implicit_params%boundary_condition)
3671 CASE (periodic_bc)
3672 CALL implicit_poisson_solver_periodic(poisson_env, rhor, vhartree_rs, &
3673 ehartree=ehartree)
3674 CASE (neumann_bc)
3675 CALL implicit_poisson_solver_neumann(poisson_env, rhor, vhartree_rs, &
3676 ehartree=ehartree)
3677 CASE (mixed_periodic_bc)
3678 CALL implicit_poisson_solver_mixed_periodic(poisson_env, rhor, vhartree_rs, &
3679 electric_enthalpy=ehartree)
3680 CASE (mixed_bc)
3681 CALL implicit_poisson_solver_mixed(poisson_env, rhor, vhartree_rs, &
3682 electric_enthalpy=ehartree)
3683 END SELECT
3684
3685 CALL pw_transfer(vhartree_rs, vhartree)
3686 CALL pw_transfer(rhor, rhog)
3687
3688 IF (PRESENT(aux_density)) THEN
3689 CALL pw_transfer(aux_density, rhor)
3690 ehartree = 0.5_dp*pw_integral_ab(rhor, vhartree_rs)
3691 END IF
3692
3693 CALL pw_pool%give_back_pw(rhor)
3694 CALL pw_pool%give_back_pw(vhartree_rs)
3695
3696 CASE DEFAULT
3697 CALL cp_abort(__location__, &
3698 "unknown poisson method "// &
3699 cp_to_string(poisson_env%green_fft%method))
3700 END SELECT
3701
3702 CASE (use_rs_grid)
3703
3704 CALL pw_pool%create_pw(rhor)
3705 CALL pw_transfer(density, rhor)
3706 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
3707 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
3708 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
3709 CALL pw_transfer(rhor, vhartree)
3710 CALL pw_transfer(rhor, rhog)
3711 IF (PRESENT(ehartree)) THEN
3712 IF (PRESENT(aux_density)) THEN
3713 ehartree = 0.5_dp*pw_integral_ab(aux_density, vhartree)
3714 ELSE
3715 ehartree = 0.5_dp*pw_integral_ab(density, vhartree)
3716 END IF
3717 END IF
3718 CALL pw_transfer(rhor, rhog)
3719 IF (PRESENT(aux_density)) THEN
3720 CALL pw_transfer(aux_density, rhor)
3721 CALL cp2k_distribution_to_z_slices(rhor, poisson_env%wavelet, rhor%pw_grid)
3722 CALL ps_wavelet_solve(poisson_env%wavelet, rhor%pw_grid)
3723 CALL z_slices_to_cp2k_distribution(rhor, poisson_env%wavelet, rhor%pw_grid)
3724 CALL pw_transfer(rhor, rhog_aux)
3725 END IF
3726 CALL pw_pool%give_back_pw(rhor)
3727
3728 END SELECT
3729
3730 IF (PRESENT(aux_density)) THEN
3731 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree=dvhartree)
3732 ELSE
3733 CALL calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, h_stress=h_stress, dvhartree=dvhartree)
3734 END IF
3735 CALL mt2d_hartree_stress(poisson_env, density, ehartree, h_stress, aux_density, greenfn)
3736
3737 CALL pw_pool%give_back_pw(rhog)
3738 IF (PRESENT(aux_density)) THEN
3739 CALL pw_pool%give_back_pw(rhog_aux)
3740 END IF
3741
3742 CALL timestop(handle)
3743
3744 END SUBROUTINE pw_poisson_solve_v_dv_c1d_gs_c1d_gs_c1d_gs
3745
3746! **************************************************************************************************
3747!> \brief Contract the MT2D kernel strain derivative against the original reciprocal densities.
3748!> \param poisson_env Poisson environment.
3749!> \param density Original charge density before multiplication by the Coulomb kernel.
3750!> \param ehartree Hartree energy, supplying the existing plane-wave volume contribution.
3751!> \param h_stress Hartree virial in the physical periodic subspace.
3752!> \param aux_density Optional second density for the bilinear Hartree energy.
3753!> \param greenfn Optional custom kernel, whose strain dependence is unavailable.
3754! **************************************************************************************************
3755 SUBROUTINE mt2d_hartree_stress_r3d_rs (poisson_env, density, ehartree, h_stress, aux_density, greenfn)
3756 TYPE(pw_poisson_type), INTENT(IN) :: poisson_env
3757 TYPE(pw_r3d_rs_type), INTENT(IN) :: density
3758 REAL(KIND=dp), INTENT(IN), OPTIONAL :: ehartree
3759 REAL(KIND=dp), INTENT(INOUT), OPTIONAL :: h_stress(3, 3)
3760 TYPE(pw_r3d_rs_type), INTENT(IN), OPTIONAL :: aux_density
3761 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: greenfn
3762
3763 INTEGER :: alpha, beta, ig, iz
3764 REAL(KIND=dp) :: energy, kernel, strain(3, 3), tolerance
3765 TYPE(pw_c1d_gs_type) :: rho_g, rho_aux_g, weighted_g
3766 TYPE(pw_grid_type), POINTER :: grid
3767 TYPE(pw_pool_type), POINTER :: pool
3768
3769 IF (.NOT. PRESENT(h_stress)) RETURN
3770 IF (poisson_env%used_grid /= use_gs_grid) RETURN
3771 IF (poisson_env%green_fft%method /= mt2d) RETURN
3772 IF (PRESENT(greenfn)) THEN
3773 cpabort("MT2D stress for a custom Green function is not implemented")
3774 END IF
3775 iz = poisson_env%green_fft%special_dimension
3776 cpassert(iz >= 1 .AND. iz <= 3)
3777 ! The existing MT2D kernel uses a Cartesian slab normal. Permit shear
3778 ! within the periodic plane, but not mixing the vacuum axis with it.
3779 tolerance = 64.0_dp*epsilon(1.0_dp)*maxval(abs(poisson_env%cell_hmat))
3780 DO alpha = 1, 3
3781 IF (alpha == iz) cycle
3782 IF (abs(poisson_env%cell_hmat(alpha, iz)) > tolerance .OR. &
3783 abs(poisson_env%cell_hmat(iz, alpha)) > tolerance) THEN
3784 cpabort("MT2D stress requires a Cartesian slab normal")
3785 END IF
3786 END DO
3787 pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
3788 CALL pool%create_pw(rho_g)
3789 CALL pool%create_pw(weighted_g)
3790 CALL pw_transfer(density, rho_g)
3791 IF (PRESENT(aux_density)) THEN
3792 CALL pool%create_pw(rho_aux_g)
3793 CALL pw_transfer(aux_density, rho_aux_g)
3794 END IF
3795 grid => rho_g%pw_grid
3796 IF (PRESENT(ehartree)) THEN
3797 energy = ehartree
3798 ELSE
3799 weighted_g%array = rho_g%array*poisson_env%green_fft%influence_fn%array
3800 IF (PRESENT(aux_density)) THEN
3801 energy = 0.5_dp*pw_integral_ab(rho_aux_g, weighted_g)
3802 ELSE
3803 energy = 0.5_dp*pw_integral_ab(rho_g, weighted_g)
3804 END IF
3805 END IF
3806 h_stress = 0.0_dp
3807 DO alpha = 1, 3
3808 IF (alpha == iz) cycle
3809 h_stress(alpha, alpha) = energy
3810 DO beta = alpha, 3
3811 IF (beta == iz) cycle
3812 ! The Maxwell K**2 identity holds for K=4*pi/G**2.
3813 ! For MT2D use -1/2 rho_aux* rho dK/dstrain instead. The PW
3814 ! integral supplies volume, reciprocal multiplicity and MPI sum.
3815 DO ig = 1, grid%ngpts_cut_local
3816 CALL mt2d_kernel_strain(grid%g(:, ig), iz, poisson_env%green_fft%slab_size, kernel, strain)
3817 weighted_g%array(ig) = rho_g%array(ig)*strain(alpha, beta)
3818 END DO
3819 IF (PRESENT(aux_density)) THEN
3820 h_stress(alpha, beta) = h_stress(alpha, beta) &
3821 - 0.5_dp*pw_integral_ab(rho_aux_g, weighted_g)
3822 ELSE
3823 h_stress(alpha, beta) = h_stress(alpha, beta) &
3824 - 0.5_dp*pw_integral_ab(rho_g, weighted_g)
3825 END IF
3826 h_stress(beta, alpha) = h_stress(alpha, beta)
3827 END DO
3828 END DO
3829 CALL pool%give_back_pw(rho_g)
3830 CALL pool%give_back_pw(weighted_g)
3831 IF (PRESENT(aux_density)) CALL pool%give_back_pw(rho_aux_g)
3832 END SUBROUTINE mt2d_hartree_stress_r3d_rs
3833! **************************************************************************************************
3834!> \brief Contract the MT2D kernel strain derivative against the original reciprocal densities.
3835!> \param poisson_env Poisson environment.
3836!> \param density Original charge density before multiplication by the Coulomb kernel.
3837!> \param ehartree Hartree energy, supplying the existing plane-wave volume contribution.
3838!> \param h_stress Hartree virial in the physical periodic subspace.
3839!> \param aux_density Optional second density for the bilinear Hartree energy.
3840!> \param greenfn Optional custom kernel, whose strain dependence is unavailable.
3841! **************************************************************************************************
3842 SUBROUTINE mt2d_hartree_stress_c1d_gs (poisson_env, density, ehartree, h_stress, aux_density, greenfn)
3843 TYPE(pw_poisson_type), INTENT(IN) :: poisson_env
3844 TYPE(pw_c1d_gs_type), INTENT(IN) :: density
3845 REAL(KIND=dp), INTENT(IN), OPTIONAL :: ehartree
3846 REAL(KIND=dp), INTENT(INOUT), OPTIONAL :: h_stress(3, 3)
3847 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: aux_density
3848 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: greenfn
3849
3850 INTEGER :: alpha, beta, ig, iz
3851 REAL(KIND=dp) :: energy, kernel, strain(3, 3), tolerance
3852 TYPE(pw_c1d_gs_type) :: rho_g, rho_aux_g, weighted_g
3853 TYPE(pw_grid_type), POINTER :: grid
3854 TYPE(pw_pool_type), POINTER :: pool
3855
3856 IF (.NOT. PRESENT(h_stress)) RETURN
3857 IF (poisson_env%used_grid /= use_gs_grid) RETURN
3858 IF (poisson_env%green_fft%method /= mt2d) RETURN
3859 IF (PRESENT(greenfn)) THEN
3860 cpabort("MT2D stress for a custom Green function is not implemented")
3861 END IF
3862 iz = poisson_env%green_fft%special_dimension
3863 cpassert(iz >= 1 .AND. iz <= 3)
3864 ! The existing MT2D kernel uses a Cartesian slab normal. Permit shear
3865 ! within the periodic plane, but not mixing the vacuum axis with it.
3866 tolerance = 64.0_dp*epsilon(1.0_dp)*maxval(abs(poisson_env%cell_hmat))
3867 DO alpha = 1, 3
3868 IF (alpha == iz) cycle
3869 IF (abs(poisson_env%cell_hmat(alpha, iz)) > tolerance .OR. &
3870 abs(poisson_env%cell_hmat(iz, alpha)) > tolerance) THEN
3871 cpabort("MT2D stress requires a Cartesian slab normal")
3872 END IF
3873 END DO
3874 pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
3875 CALL pool%create_pw(rho_g)
3876 CALL pool%create_pw(weighted_g)
3877 CALL pw_transfer(density, rho_g)
3878 IF (PRESENT(aux_density)) THEN
3879 CALL pool%create_pw(rho_aux_g)
3880 CALL pw_transfer(aux_density, rho_aux_g)
3881 END IF
3882 grid => rho_g%pw_grid
3883 IF (PRESENT(ehartree)) THEN
3884 energy = ehartree
3885 ELSE
3886 weighted_g%array = rho_g%array*poisson_env%green_fft%influence_fn%array
3887 IF (PRESENT(aux_density)) THEN
3888 energy = 0.5_dp*pw_integral_ab(rho_aux_g, weighted_g)
3889 ELSE
3890 energy = 0.5_dp*pw_integral_ab(rho_g, weighted_g)
3891 END IF
3892 END IF
3893 h_stress = 0.0_dp
3894 DO alpha = 1, 3
3895 IF (alpha == iz) cycle
3896 h_stress(alpha, alpha) = energy
3897 DO beta = alpha, 3
3898 IF (beta == iz) cycle
3899 ! The Maxwell K**2 identity holds for K=4*pi/G**2.
3900 ! For MT2D use -1/2 rho_aux* rho dK/dstrain instead. The PW
3901 ! integral supplies volume, reciprocal multiplicity and MPI sum.
3902 DO ig = 1, grid%ngpts_cut_local
3903 CALL mt2d_kernel_strain(grid%g(:, ig), iz, poisson_env%green_fft%slab_size, kernel, strain)
3904 weighted_g%array(ig) = rho_g%array(ig)*strain(alpha, beta)
3905 END DO
3906 IF (PRESENT(aux_density)) THEN
3907 h_stress(alpha, beta) = h_stress(alpha, beta) &
3908 - 0.5_dp*pw_integral_ab(rho_aux_g, weighted_g)
3909 ELSE
3910 h_stress(alpha, beta) = h_stress(alpha, beta) &
3911 - 0.5_dp*pw_integral_ab(rho_g, weighted_g)
3912 END IF
3913 h_stress(beta, alpha) = h_stress(alpha, beta)
3914 END DO
3915 END DO
3916 CALL pool%give_back_pw(rho_g)
3917 CALL pool%give_back_pw(weighted_g)
3918 IF (PRESENT(aux_density)) CALL pool%give_back_pw(rho_aux_g)
3919 END SUBROUTINE mt2d_hartree_stress_c1d_gs
3920
3921 SUBROUTINE calc_stress_and_gradient_c1d_gs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree)
3922 TYPE(pw_poisson_type), INTENT(IN) :: poisson_env
3923 TYPE(pw_c1d_gs_type), INTENT(IN) :: rhog
3924 REAL(KIND=dp), INTENT(IN), OPTIONAL :: ehartree
3925 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rhog_aux
3926 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT), OPTIONAL :: h_stress
3927 TYPE(pw_c1d_gs_type), DIMENSION(3), INTENT(INOUT), OPTIONAL :: dvhartree
3928
3929 CHARACTER(len=*), PARAMETER :: routinen = 'pw_poisson_set'
3930
3931 REAL(kind=dp) :: ffa
3932 INTEGER :: alpha, beta, n(3), handle, i
3933 LOGICAL :: calculate_stress
3934 TYPE(pw_c1d_gs_type) :: dvg(3), dvg_aux(3)
3935 TYPE(pw_pool_type), POINTER :: pw_pool
3936
3937 CALL timeset(routinen, handle)
3938
3939 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
3940
3941 DO i = 1, 3
3942 CALL pw_pool%create_pw(dvg(i))
3943 n = 0
3944 n(i) = 1
3945 CALL pw_copy(rhog, dvg(i))
3946 CALL pw_derive(dvg(i), n)
3947 IF (PRESENT(rhog_aux)) THEN
3948 CALL pw_pool%create_pw(dvg_aux(i))
3949 CALL pw_copy(rhog_aux, dvg_aux(i))
3950 CALL pw_derive(dvg_aux(i), n)
3951 END IF
3952 END DO
3953 ! save the derivatives
3954 IF (PRESENT(dvhartree)) THEN
3955 DO i = 1, 3
3956 CALL pw_transfer(dvg(i), dvhartree(i))
3957 END DO
3958 END IF
3959 ! Calculate the contribution to the stress tensor this is only the contribution from
3960 ! the Greens FUNCTION and the volume factor of the plane waves
3961 calculate_stress = PRESENT(h_stress)
3962 IF (calculate_stress .AND. poisson_env%used_grid == use_gs_grid) THEN
3963 ! MT2D is contracted against the original density by the caller.
3964 ! Its kernel derivative does not obey the Maxwell K**2 identity.
3965 calculate_stress = poisson_env%green_fft%method /= mt2d
3966 END IF
3967 IF (calculate_stress) THEN
3968 cpassert(PRESENT(ehartree))
3969 ffa = -1.0_dp/fourpi
3970 h_stress = 0.0_dp
3971 DO alpha = 1, 3
3972 h_stress(alpha, alpha) = ehartree
3973 IF (PRESENT(rhog_aux)) THEN
3974 DO beta = alpha, 3
3975 h_stress(alpha, beta) = h_stress(alpha, beta) &
3976 + ffa*pw_integral_ab(dvg_aux(alpha), dvg(beta))
3977 h_stress(beta, alpha) = h_stress(alpha, beta)
3978 END DO
3979 ELSE
3980 DO beta = alpha, 3
3981 h_stress(alpha, beta) = h_stress(alpha, beta) &
3982 + ffa*pw_integral_ab(dvg(alpha), dvg(beta))
3983 h_stress(beta, alpha) = h_stress(alpha, beta)
3984 END DO
3985 END IF
3986 END DO
3987
3988 ! Handle the periodicity cases for the Stress Tensor
3989 SELECT CASE (poisson_env%used_grid)
3990 CASE (use_gs_grid)
3991
3992 ! FFT based Poisson-Solver
3993 SELECT CASE (poisson_env%green_fft%method)
3994 CASE (periodic3d, ps_implicit)
3995 ! Do Nothing
3996 CASE (analytic2d, mt2d)
3997 ! Zero the 1 non-periodic component. Only the periodic-subspace
3998 ! stress components are defined for 2D systems.
3999 alpha = poisson_env%green_fft%special_dimension
4000 h_stress(:, alpha) = 0.0_dp
4001 h_stress(alpha, :) = 0.0_dp
4002 CASE (analytic1d, mt1d)
4003 ! Zero the 2 non-periodic components
4004 DO alpha = 1, 3
4005 DO beta = alpha, 3
4006 IF ((alpha /= poisson_env%green_fft%special_dimension) .OR. &
4007 (beta /= poisson_env%green_fft%special_dimension)) THEN
4008 h_stress(alpha, beta) = 0.0_dp
4009 h_stress(beta, alpha) = 0.0_dp
4010 END IF
4011 END DO
4012 END DO
4013 cpabort("Stress Tensor not tested for 1D systems.")
4014 CASE (analytic0d, mt0d, multipole0d)
4015 ! Zero the full stress tensor
4016 h_stress = 0.0_dp
4017 CASE DEFAULT
4018 CALL cp_abort(__location__, &
4019 "unknown poisson method"// &
4020 cp_to_string(poisson_env%green_fft%method))
4021 END SELECT
4022
4023 CASE (use_rs_grid)
4024
4025 ! Wavelet based Poisson-Solver
4026 SELECT CASE (poisson_env%wavelet%method)
4027 CASE (wavelet3d)
4028 ! Do Nothing
4029 CASE (wavelet2d)
4030 ! Zero the 1 non-periodic component
4031 alpha = poisson_env%wavelet%special_dimension
4032 h_stress(:, alpha) = 0.0_dp
4033 h_stress(alpha, :) = 0.0_dp
4034 cpabort("Stress Tensor not tested for WAVELET 2D.")
4035 CASE (wavelet1d)
4036 ! Zero the 2 non-periodic components
4037 cpabort("WAVELET 1D not implemented!")
4038 CASE (wavelet0d)
4039 ! Zero the full stress tensor
4040 h_stress = 0.0_dp
4041 END SELECT
4042
4043 END SELECT
4044 END IF
4045
4046 DO i = 1, 3
4047 CALL pw_pool%give_back_pw(dvg(i))
4048 IF (PRESENT(rhog_aux)) THEN
4049 CALL pw_pool%give_back_pw(dvg_aux(i))
4050 END IF
4051 END DO
4052
4053 CALL timestop(handle)
4054
4055 END SUBROUTINE calc_stress_and_gradient_c1d_gs
4056 SUBROUTINE calc_stress_and_gradient_r3d_rs (poisson_env, rhog, ehartree, rhog_aux, h_stress, dvhartree)
4057 TYPE(pw_poisson_type), INTENT(IN) :: poisson_env
4058 TYPE(pw_c1d_gs_type), INTENT(IN) :: rhog
4059 REAL(KIND=dp), INTENT(IN), OPTIONAL :: ehartree
4060 TYPE(pw_c1d_gs_type), INTENT(IN), OPTIONAL :: rhog_aux
4061 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT), OPTIONAL :: h_stress
4062 TYPE(pw_r3d_rs_type), DIMENSION(3), INTENT(INOUT), OPTIONAL :: dvhartree
4063
4064 CHARACTER(len=*), PARAMETER :: routinen = 'pw_poisson_set'
4065
4066 REAL(kind=dp) :: ffa
4067 INTEGER :: alpha, beta, n(3), handle, i
4068 LOGICAL :: calculate_stress
4069 TYPE(pw_c1d_gs_type) :: dvg(3), dvg_aux(3)
4070 TYPE(pw_pool_type), POINTER :: pw_pool
4071
4072 CALL timeset(routinen, handle)
4073
4074 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
4075
4076 DO i = 1, 3
4077 CALL pw_pool%create_pw(dvg(i))
4078 n = 0
4079 n(i) = 1
4080 CALL pw_copy(rhog, dvg(i))
4081 CALL pw_derive(dvg(i), n)
4082 IF (PRESENT(rhog_aux)) THEN
4083 CALL pw_pool%create_pw(dvg_aux(i))
4084 CALL pw_copy(rhog_aux, dvg_aux(i))
4085 CALL pw_derive(dvg_aux(i), n)
4086 END IF
4087 END DO
4088 ! save the derivatives
4089 IF (PRESENT(dvhartree)) THEN
4090 DO i = 1, 3
4091 CALL pw_transfer(dvg(i), dvhartree(i))
4092 END DO
4093 END IF
4094 ! Calculate the contribution to the stress tensor this is only the contribution from
4095 ! the Greens FUNCTION and the volume factor of the plane waves
4096 calculate_stress = PRESENT(h_stress)
4097 IF (calculate_stress .AND. poisson_env%used_grid == use_gs_grid) THEN
4098 ! MT2D is contracted against the original density by the caller.
4099 ! Its kernel derivative does not obey the Maxwell K**2 identity.
4100 calculate_stress = poisson_env%green_fft%method /= mt2d
4101 END IF
4102 IF (calculate_stress) THEN
4103 cpassert(PRESENT(ehartree))
4104 ffa = -1.0_dp/fourpi
4105 h_stress = 0.0_dp
4106 DO alpha = 1, 3
4107 h_stress(alpha, alpha) = ehartree
4108 IF (PRESENT(rhog_aux)) THEN
4109 DO beta = alpha, 3
4110 h_stress(alpha, beta) = h_stress(alpha, beta) &
4111 + ffa*pw_integral_ab(dvg_aux(alpha), dvg(beta))
4112 h_stress(beta, alpha) = h_stress(alpha, beta)
4113 END DO
4114 ELSE
4115 DO beta = alpha, 3
4116 h_stress(alpha, beta) = h_stress(alpha, beta) &
4117 + ffa*pw_integral_ab(dvg(alpha), dvg(beta))
4118 h_stress(beta, alpha) = h_stress(alpha, beta)
4119 END DO
4120 END IF
4121 END DO
4122
4123 ! Handle the periodicity cases for the Stress Tensor
4124 SELECT CASE (poisson_env%used_grid)
4125 CASE (use_gs_grid)
4126
4127 ! FFT based Poisson-Solver
4128 SELECT CASE (poisson_env%green_fft%method)
4129 CASE (periodic3d, ps_implicit)
4130 ! Do Nothing
4131 CASE (analytic2d, mt2d)
4132 ! Zero the 1 non-periodic component. Only the periodic-subspace
4133 ! stress components are defined for 2D systems.
4134 alpha = poisson_env%green_fft%special_dimension
4135 h_stress(:, alpha) = 0.0_dp
4136 h_stress(alpha, :) = 0.0_dp
4137 CASE (analytic1d, mt1d)
4138 ! Zero the 2 non-periodic components
4139 DO alpha = 1, 3
4140 DO beta = alpha, 3
4141 IF ((alpha /= poisson_env%green_fft%special_dimension) .OR. &
4142 (beta /= poisson_env%green_fft%special_dimension)) THEN
4143 h_stress(alpha, beta) = 0.0_dp
4144 h_stress(beta, alpha) = 0.0_dp
4145 END IF
4146 END DO
4147 END DO
4148 cpabort("Stress Tensor not tested for 1D systems.")
4149 CASE (analytic0d, mt0d, multipole0d)
4150 ! Zero the full stress tensor
4151 h_stress = 0.0_dp
4152 CASE DEFAULT
4153 CALL cp_abort(__location__, &
4154 "unknown poisson method"// &
4155 cp_to_string(poisson_env%green_fft%method))
4156 END SELECT
4157
4158 CASE (use_rs_grid)
4159
4160 ! Wavelet based Poisson-Solver
4161 SELECT CASE (poisson_env%wavelet%method)
4162 CASE (wavelet3d)
4163 ! Do Nothing
4164 CASE (wavelet2d)
4165 ! Zero the 1 non-periodic component
4166 alpha = poisson_env%wavelet%special_dimension
4167 h_stress(:, alpha) = 0.0_dp
4168 h_stress(alpha, :) = 0.0_dp
4169 cpabort("Stress Tensor not tested for WAVELET 2D.")
4170 CASE (wavelet1d)
4171 ! Zero the 2 non-periodic components
4172 cpabort("WAVELET 1D not implemented!")
4173 CASE (wavelet0d)
4174 ! Zero the full stress tensor
4175 h_stress = 0.0_dp
4176 END SELECT
4177
4178 END SELECT
4179 END IF
4180
4181 DO i = 1, 3
4182 CALL pw_pool%give_back_pw(dvg(i))
4183 IF (PRESENT(rhog_aux)) THEN
4184 CALL pw_pool%give_back_pw(dvg_aux(i))
4185 END IF
4186 END DO
4187
4188 CALL timestop(handle)
4189
4190 END SUBROUTINE calc_stress_and_gradient_r3d_rs
4191
4192! **************************************************************************************************
4193!> \brief sets cell, grids and parameters used by the poisson solver
4194!> You should call this at least once (and set everything)
4195!> before using the poisson solver.
4196!> Smart, doesn't set the thing twice to the same value
4197!> Keeps track of the need to rebuild the poisson_env
4198!> \param poisson_env ...
4199!> \param cell_hmat ...
4200!> \param parameters ...
4201!> \param pw_pools ...
4202!> \param use_level ...
4203!> \param mt_super_ref_pw_grid ...
4204!> \param dct_pw_grid ...
4205!> \param force_rebuild ...
4206!> \author fawzi
4207!> \note
4208!> Checks everything at the end. This means that after *each* call to
4209!> this method the poisson env must be fully ready, so the first time
4210!> you have to set everything at once. Change this behaviour?
4211! **************************************************************************************************
4212 SUBROUTINE pw_poisson_set(poisson_env, cell_hmat, parameters, pw_pools, use_level, &
4213 mt_super_ref_pw_grid, dct_pw_grid, force_rebuild)
4214
4215 TYPE(pw_poisson_type), INTENT(INOUT) :: poisson_env
4216 REAL(kind=dp), DIMENSION(3, 3), INTENT(IN), &
4217 OPTIONAL :: cell_hmat
4218 TYPE(pw_poisson_parameter_type), INTENT(IN), &
4219 OPTIONAL :: parameters
4220 TYPE(pw_pool_p_type), DIMENSION(:), OPTIONAL, &
4221 POINTER :: pw_pools
4222 INTEGER, INTENT(in), OPTIONAL :: use_level
4223 TYPE(pw_grid_type), OPTIONAL, POINTER :: mt_super_ref_pw_grid, dct_pw_grid
4224 LOGICAL, INTENT(in), OPTIONAL :: force_rebuild
4225
4226 CHARACTER(len=*), PARAMETER :: routinen = 'pw_poisson_set'
4227
4228 INTEGER :: handle, i
4229 LOGICAL :: same
4230 TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: tmp_pools
4231
4232 CALL timeset(routinen, handle)
4233
4234 IF (PRESENT(parameters)) poisson_env%parameters = parameters
4235
4236 IF (PRESENT(cell_hmat)) THEN
4237 IF (any(poisson_env%cell_hmat /= cell_hmat)) THEN
4238 CALL pw_poisson_cleanup(poisson_env)
4239 END IF
4240 poisson_env%cell_hmat(:, :) = cell_hmat(:, :)
4241 poisson_env%rebuild = .true.
4242 END IF
4243
4244 IF (PRESENT(pw_pools)) THEN
4245 cpassert(ASSOCIATED(pw_pools))
4246 same = .false.
4247 IF (ASSOCIATED(poisson_env%pw_pools)) THEN
4248 same = SIZE(poisson_env%pw_pools) == SIZE(pw_pools)
4249 IF (same) THEN
4250 DO i = 1, SIZE(pw_pools)
4251 IF (.NOT. ASSOCIATED(poisson_env%pw_pools(i)%pool, &
4252 pw_pools(i)%pool)) same = .false.
4253 END DO
4254 END IF
4255 END IF
4256 IF (.NOT. same) THEN
4257 poisson_env%rebuild = .true.
4258 CALL pw_pools_copy(pw_pools, tmp_pools)
4259 CALL pw_pools_dealloc(poisson_env%pw_pools)
4260 poisson_env%pw_pools => tmp_pools
4261 END IF
4262 END IF
4263
4264 IF (PRESENT(use_level)) poisson_env%pw_level = use_level
4265
4266 IF (PRESENT(dct_pw_grid)) THEN
4267 IF (ASSOCIATED(dct_pw_grid)) THEN
4268 CALL pw_grid_retain(dct_pw_grid)
4269 END IF
4270 CALL pw_grid_release(poisson_env%dct_pw_grid)
4271 poisson_env%dct_pw_grid => dct_pw_grid
4272 END IF
4273
4274 IF (PRESENT(mt_super_ref_pw_grid)) THEN
4275 IF (ASSOCIATED(mt_super_ref_pw_grid)) THEN
4276 CALL pw_grid_retain(mt_super_ref_pw_grid)
4277 END IF
4278 CALL pw_grid_release(poisson_env%mt_super_ref_pw_grid)
4279 poisson_env%mt_super_ref_pw_grid => mt_super_ref_pw_grid
4280 END IF
4281
4282 IF (PRESENT(force_rebuild)) THEN
4283 IF (force_rebuild) poisson_env%rebuild = .true.
4284 END IF
4285
4286 CALL pw_poisson_check(poisson_env)
4287
4288 CALL timestop(handle)
4289
4290 END SUBROUTINE pw_poisson_set
4291
4292! **************************************************************************************************
4293!> \brief computes the convolution f * u using reciprocal-space multiplication
4294!> \par
4295!> Given two real-space functions f and u, this routine evaluates their
4296!> convolution by transforming both to G space, multiplying their Fourier
4297!> components, and transforming the product back to real space.
4298!> \param poisson_env poisson environment
4299!> \param func input function f in real space
4300!> \param convolution convolution result (f * u) in real space
4301!> \param u input function/kernel u in real space
4302!> \author Ziwei Chai
4303!> \date 12.03.2026
4304! **************************************************************************************************
4305 SUBROUTINE pw_func_u_convolution(poisson_env, func, convolution, u)
4306
4307 TYPE(pw_poisson_type), POINTER :: poisson_env
4308 TYPE(pw_r3d_rs_type), INTENT(IN) :: func, u
4309 TYPE(pw_r3d_rs_type), INTENT(INOUT), OPTIONAL :: convolution
4310 CHARACTER(len=*), PARAMETER :: routinen = 'pw_func_u_convolution'
4311 INTEGER :: handle
4312 TYPE(pw_grid_type), POINTER :: pw_grid
4313 TYPE(pw_pool_type), POINTER :: pw_pool
4314 TYPE(pw_c1d_gs_type) :: funcg, ug
4315
4316 CALL timeset(routinen, handle)
4317
4318 cpassert(ASSOCIATED(poisson_env))
4319 CALL pw_poisson_rebuild(poisson_env, func)
4320
4321 ! point pw
4322 pw_pool => poisson_env%pw_pools(poisson_env%pw_level)%pool
4323 pw_grid => pw_pool%pw_grid
4324 ! func and u in G space
4325 CALL pw_pool%create_pw(funcg)
4326 CALL pw_pool%create_pw(ug)
4327
4328 CALL pw_transfer(func, funcg)
4329 CALL pw_transfer(u, ug)
4330
4331 funcg%array(:) = funcg%array(:)*ug%array(:)
4332
4333 CALL pw_transfer(funcg, convolution)
4334
4335 CALL pw_pool%give_back_pw(funcg)
4336 CALL pw_pool%give_back_pw(ug)
4337
4338 CALL timestop(handle)
4339
4340 END SUBROUTINE pw_func_u_convolution
4341
4342END MODULE pw_poisson_methods
various routines to log and control the output. The idea is that decisions about where to log should ...
methods for evaluating the dielectric constant
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
real(kind=dp), parameter, public fourpi
subroutine, public mt2d_kernel_strain(g, special_dimension, slab_size, kernel, strain)
MT2D Coulomb kernel and its affine strain derivative in the periodic plane.
Definition mt_util.F:49
integer, parameter, public mt0d
Definition mt_util.F:33
integer, parameter, public mt2d
Definition mt_util.F:33
integer, parameter, public mt1d
Definition mt_util.F:33
The implicit (generalized) Poisson solver.
subroutine, public implicit_poisson_solver_periodic(poisson_env, density, v_new, ehartree)
implicit Poisson solver for periodic boundary conditions
subroutine, public implicit_poisson_solver_mixed(poisson_env, density, v_new, electric_enthalpy)
implicit Poisson solver for mixed boundary conditions (Neumann + Dirichlet)
subroutine, public implicit_poisson_solver_neumann(poisson_env, density, v_new, ehartree)
implicit Poisson solver: zero-average solution of the Poisson equation subject to homogeneous Neumann...
subroutine, public implicit_poisson_solver_mixed_periodic(poisson_env, density, v_new, electric_enthalpy)
implicit Poisson solver for mixed-periodic boundary conditions (periodic + Dirichlet)
subroutine, public ps_implicit_create(pw_pool, poisson_params, dct_pw_grid, green, ps_implicit_env)
Creates implicit Poisson solver environment.
Types containing essential information for running implicit (iterative) Poisson solver.
integer, parameter, public neumann_bc
integer, parameter, public mixed_bc
integer, parameter, public mixed_periodic_bc
integer, parameter, public periodic_bc
Definition and initialisation of the ps_wavelet data type. \history 01.2014 Renamed from ps_wavelet_t...
subroutine, public ps_wavelet_create(poisson_params, wavelet, pw_grid)
creates the ps_wavelet_type which is needed for the link to the Poisson Solver of Luigi Genovese
subroutine, public ps_wavelet_solve(wavelet, pw_grid)
...
subroutine, public z_slices_to_cp2k_distribution(density, wavelet, pw_grid)
...
subroutine, public cp2k_distribution_to_z_slices(density, wavelet, pw_grid)
...
Definition and initialisation of the ps_wavelet data type.
integer, parameter, public wavelet3d
integer, parameter, public wavelet0d
integer, parameter, public wavelet1d
integer, parameter, public wavelet2d
This module defines the grid data type and some basic operations on it.
Definition pw_grids.F:36
logical function, public pw_grid_compare(grida, gridb)
Check if two pw_grids are equal.
Definition pw_grids.F:148
subroutine, public pw_grid_release(pw_grid)
releases the given pw grid
Definition pw_grids.F:2201
subroutine, public pw_grid_retain(pw_grid)
retains the given pw grid
Definition pw_grids.F:2185
subroutine, public pw_derive(pw, n)
Calculate the derivative of a plane wave vector.
subroutine, public pw_poisson_set(poisson_env, cell_hmat, parameters, pw_pools, use_level, mt_super_ref_pw_grid, dct_pw_grid, force_rebuild)
sets cell, grids and parameters used by the poisson solver You should call this at least once (and se...
subroutine, public pw_func_u_convolution(poisson_env, func, convolution, u)
computes the convolution f * u using reciprocal-space multiplication
functions related to the poisson solver on regular grids
integer, parameter, public pw_poisson_wavelet
subroutine, public pw_green_create(green, poisson_params, cell_hmat, pw_pool, mt_super_ref_pw_grid, dct_pw_grid)
Allocates and sets up the green functions for the fft based poisson solvers.
integer, parameter, public pw_poisson_periodic
subroutine, public pw_green_release(gftype, pw_pool)
destroys the type (deallocates data)
integer, parameter, public pw_poisson_none
integer, parameter, public pw_poisson_mt
integer, parameter, public analytic2d
integer, parameter, public analytic1d
integer, parameter, public periodic3d
integer, parameter, public ps_implicit
integer, parameter, public analytic0d
integer, parameter, public multipole0d
integer, parameter, public pw_poisson_implicit
integer, parameter, public pw_poisson_analytic
integer, parameter, public do_ewald_spme
integer, parameter, public pw_poisson_multipole
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
subroutine, public pw_pools_dealloc(pools)
deallocates the given pools (releasing each of the underlying pools)
subroutine, public pw_pools_copy(source_pools, target_pools)
copies a multigrid pool, the underlying pools are shared
contains all the informations needed by the fft based poisson solvers
parameters for the poisson solver independet of input_section
environment for the poisson solver
to create arrays of pools
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...