Octopus
jellium.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!! Copyright (C) 2023-2024 N. Tancogne-Dejean
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19#include "global.h"
20
21module jellium_oct_m
22 use debug_oct_m
23 use global_oct_m
24 use io_oct_m
26 use mpi_oct_m
28 use parser_oct_m
31 use unit_oct_m
33
34 implicit none
35
36 private
37 public :: &
38 jellium_t, &
45
46 integer, public, parameter :: &
47 SPECIES_JELLIUM = 3, & !< jellium sphere.
50 species_usdef = 123, &
53
54 type, abstract, extends(species_t) :: jellium_t
55 private
56
57 real(real64) :: omega
58
59 contains
60 procedure :: iwf_fix_qn => jellium_iwf_fix_qn
61 procedure :: get_iwf_radius => jellium_get_iwf_radius
62 procedure :: is_local => jellium_is_local
63 procedure :: init_potential => jellium_init_potential
64 procedure :: debug => jellium_debug
65 procedure :: build => jellium_build
66 procedure :: get_omega => jellium_get_omega
67 procedure :: is_user_defined => jellium_user_defined
68 end type jellium_t
69
70 type, extends(jellium_t) :: jellium_sphere_t
71 private
72
73 real(real64) :: jradius
74
75 contains
76 procedure :: radius => jellium_radius
77 procedure :: set_radius => jellium_set_radius
79 end type jellium_sphere_t
80
81 type, extends(jellium_t) :: jellium_slab_t
82 private
83
84 real(real64) :: jthick
85
86 contains
87 procedure :: thickness => jellium_thick
88 procedure :: set_thickness => jellium_set_thickness
89 procedure :: get_density => jellium_slab_density
91 end type jellium_slab_t
92
93 type, extends(jellium_t) :: jellium_charge_t
94 private
95
96 character(len=200), public :: density_formula
97
98 contains
99 procedure :: rho_string => jellium_rho_string
101 end type jellium_charge_t
102
103 type, extends (jellium_t) :: species_from_file_t
104 private
105
106 contains
108 end type species_from_file_t
109
110 type, extends (jellium_t) :: species_user_defined_t
111 private
112
113 character(len=1024), public :: potential_formula
114 contains
115 procedure :: user_pot => jellium_userdef_pot
118
119 type, extends (jellium_t) :: species_charge_density_t
120 private
121
122 character(len=200), public :: density_formula
123 contains
124 procedure :: rho_string => species_rho_string
127
128 interface jellium_sphere_t
129 procedure jellium_sphere_constructor
130 end interface jellium_sphere_t
131
132 interface jellium_slab_t
133 procedure jellium_slab_constructor
134 end interface jellium_slab_t
135
136 interface jellium_charge_t
137 procedure jellium_charge_constructor
138 end interface jellium_charge_t
139
140 interface species_from_file_t
142 end interface species_from_file_t
143
144 interface species_user_defined_t
146 end interface species_user_defined_t
147
149 procedure species_charge_density_constructor
150 end interface species_charge_density_t
151
153contains
154
156 ! ---------------------------------------------------------
157 function jellium_slab_constructor(label, index) result(spec)
158 class(jellium_slab_t), pointer :: spec
159 character(len=*), intent(in) :: label
160 integer, intent(in) :: index
163
164 safe_allocate(spec)
166 call species_init(spec, label, index)
167
168 spec%omega = m_zero
169 spec%jthick = -m_one
170
174 ! ---------------------------------------------------------
175 subroutine jellium_slab_finalize(this)
176 type(jellium_slab_t), intent(inout) :: this
177
178 push_sub(jellium_slab_finalize)
180 call species_end(this)
181
185 ! ---------------------------------------------------------
186 function jellium_sphere_constructor(label, index) result(spec)
187 class(jellium_sphere_t), pointer :: spec
188 character(len=*), intent(in) :: label
189 integer, intent(in) :: index
190
192
193 safe_allocate(spec)
195 call species_init(spec, label, index)
196
197 spec%omega = m_zero
198 spec%jradius = m_half
199
201 end function jellium_sphere_constructor
203
204 ! ---------------------------------------------------------
205 subroutine jellium_sphere_finalize(this)
206 type(jellium_sphere_t), intent(inout) :: this
207
209
210 call species_end(this)
213 end subroutine jellium_sphere_finalize
215 ! ---------------------------------------------------------
216 function jellium_charge_constructor(label, index) result(spec)
217 class(jellium_charge_t), pointer :: spec
218 character(len=*), intent(in) :: label
219 integer, intent(in) :: index
222
223 safe_allocate(spec)
224
225 call species_init(spec, label, index)
226
227 spec%omega = m_zero
228 spec%density_formula = ""
229
231 end function jellium_charge_constructor
232
233
234 ! ---------------------------------------------------------
235 subroutine jellium_charge_finalize(this)
236 type(jellium_charge_t), intent(inout) :: this
237
239
240 call species_end(this)
241
243 end subroutine jellium_charge_finalize
244
245
246 ! ---------------------------------------------------------
247 function species_from_file_constructor(label, index) result(spec)
248 class(species_from_file_t), pointer :: spec
249 character(len=*), intent(in) :: label
250 integer, intent(in) :: index
251
253
254 safe_allocate(spec)
255
256 call species_init(spec, label, index)
257
258 spec%omega = m_zero
259
262
263 ! ---------------------------------------------------------
264 subroutine species_from_file_finalize(this)
265 type(species_from_file_t), intent(inout) :: this
266
268
269 call species_end(this)
272 end subroutine species_from_file_finalize
273
274
275 ! ---------------------------------------------------------
276 function species_user_defined_constructor(label, index) result(spec)
277 class(species_user_defined_t), pointer :: spec
278 character(len=*), intent(in) :: label
279 integer, intent(in) :: index
280
282
283 safe_allocate(spec)
284
285 call species_init(spec, label, index)
286
287 spec%potential_formula = ""
288 spec%omega = m_zero
289
292
293
294 ! ---------------------------------------------------------
295 subroutine species_user_defined_finalize(this)
296 type(species_user_defined_t), intent(inout) :: this
297
299
300 call species_end(this)
301
303 end subroutine species_user_defined_finalize
304
305
306 ! ---------------------------------------------------------
307 function species_charge_density_constructor(label, index) result(spec)
308 class(species_charge_density_t), pointer :: spec
309 character(len=*), intent(in) :: label
310 integer, intent(in) :: index
313
314 safe_allocate(spec)
315
316 call species_init(spec, label, index)
317
318 spec%omega = m_zero
319 spec%density_formula = ""
320
323
324
325 ! ---------------------------------------------------------
326 subroutine species_charge_density_finalize(this)
327 type(species_charge_density_t), intent(inout) :: this
328
331 call species_end(this)
332
335
336 ! ---------------------------------------------------------
337 real(real64) pure function jellium_get_omega(spec)
338 class(jellium_t), intent(in) :: spec
339 jellium_get_omega = spec%omega
340 end function jellium_get_omega
341
343 ! ---------------------------------------------------------
344 real(real64) pure function jellium_radius(spec)
345 class(jellium_sphere_t), intent(in) :: spec
346 jellium_radius = spec%jradius
347 end function jellium_radius
348
349 ! ---------------------------------------------------------
350 pure subroutine jellium_set_radius(spec, radius)
351 class(jellium_sphere_t), intent(inout) :: spec
352 real(real64), intent(in) :: radius
353 spec%jradius = radius
354 end subroutine jellium_set_radius
355
356 ! ---------------------------------------------------------
357 real(real64) pure function jellium_thick(spec)
358 class(jellium_slab_t), intent(in) :: spec
359 jellium_thick = spec%jthick
360 end function jellium_thick
361
362 ! ---------------------------------------------------------
363 pure subroutine jellium_set_thickness(spec, thick)
364 class(jellium_slab_t), intent(inout) :: spec
365 real(real64), intent(in) :: thick
366 spec%jthick = thick
367 end subroutine jellium_set_thickness
368
369 ! ---------------------------------------------------------
370 character(len=200) pure function jellium_rho_string(spec)
371 class(jellium_charge_t), intent(in) :: spec
372 jellium_rho_string = trim(spec%density_formula)
373 end function jellium_rho_string
374
375 ! ---------------------------------------------------------
376 character(len=200) pure function species_rho_string(spec)
377 class(species_charge_density_t), intent(in) :: spec
378 species_rho_string = trim(spec%density_formula)
379 end function species_rho_string
380
381
382 ! ---------------------------------------------------------
383 complex(real64) function jellium_userdef_pot(spec, dim, xx, r)
384 class(species_user_defined_t), intent(in) :: spec
385 integer, intent(in) :: dim
386 real(real64), intent(in) :: xx(:)
387 real(real64), intent(in) :: r
388
389 real(real64) :: pot_re, pot_im
391 ! no push_sub, called too many times
392
393 call parse_expression(pot_re, pot_im, dim, xx, r, m_zero, spec%potential_formula)
394 jellium_userdef_pot = cmplx(pot_re, pot_im, real64)
395
396 end function jellium_userdef_pot
397
398 ! ---------------------------------------------------------
405 real(real64) function jellium_userdef_omega(spec, dim) result(omega)
406 class(species_user_defined_t), intent(in) :: spec
407 integer, intent(in) :: dim
408
409 real(real64), parameter :: delta = 0.01_real64
410 real(real64), parameter :: omega_default = 0.1_real64
411 real(real64) :: xx(dim), vv(3), curvature, dv2
412 integer :: idir, ii, ndir
413
414 push_sub(jellium_userdef_omega)
415
416 curvature = m_zero
417 ndir = 0
418 do idir = 1, dim
419 do ii = 1, 3
420 xx = m_zero
421 xx(idir) = ii * delta
422 vv(ii) = real(jellium_userdef_pot(spec, dim, xx, norm2(xx)), real64)
423 end do
424 ! Second derivative of the potential at 2*delta along the direction idir.
425 ! For a harmonic potential, V = omega^2 * x^2 / 2, this gives exactly omega^2.
426 dv2 = (vv(3) - m_two*vv(2) + vv(1)) / delta**2
427 if (dv2 > m_zero) then
428 curvature = curvature + dv2
429 ndir = ndir + 1
430 end if
431 end do
433 if (ndir > 0) then
434 omega = sqrt(curvature / ndir)
435 else
436 ! The potential is not confining close to the origin (e.g. a constant potential or a
437 ! double well), so no length scale can be extracted from it and we use a default value.
438 omega = omega_default
439 end if
440
441 pop_sub(jellium_userdef_omega)
442 end function jellium_userdef_omega
443
444 ! ---------------------------------------------------------
446 subroutine jellium_iwf_fix_qn(spec, namespace, nspin, dim)
447 class(jellium_t), intent(inout) :: spec
448 type(namespace_t), intent(in) :: namespace
449 integer, intent(in) :: nspin
450 integer, intent(in) :: dim
451
452 integer :: is, i, n1, n2, n3
453
454 push_sub(jellium_iwf_fix_qn)
455
456 select case (dim)
457 case (1)
458 do is = 1, nspin
459 do i = 1, spec%niwfs
460 spec%iwf_i(i, is) = i
461 spec%iwf_n(i, is) = 0
462 spec%iwf_l(i, is) = 0
463 spec%iwf_m(i, is) = 0
464 spec%iwf_j(i) = m_zero
465 end do
466 end do
467
468 case (2)
469 do is = 1, nspin
470 i = 1
471 n1 = 1
472 n2 = 1
473 do
474 spec%iwf_i(i, is) = n1
475 spec%iwf_n(i, is) = 1
476 spec%iwf_l(i, is) = n2
477 spec%iwf_m(i, is) = 0
478 spec%iwf_j(i) = m_zero
479 i = i + 1
480 if (i>spec%niwfs) exit
481
482 spec%iwf_i(i, is) = n1+1
483 spec%iwf_n(i, is) = 1
484 spec%iwf_l(i, is) = n2
485 spec%iwf_m(i, is) = 0
486 spec%iwf_j(i) = m_zero
487 i = i + 1
488 if (i>spec%niwfs) exit
489
490 spec%iwf_i(i, is) = n1
491 spec%iwf_n(i, is) = 1
492 spec%iwf_l(i, is) = n2+1
493 spec%iwf_m(i, is) = 0
494 spec%iwf_j(i) = m_zero
495 i = i + 1
496 if (i>spec%niwfs) exit
497
498 n1 = n1 + 1; n2 = n2 + 1
499 end do
500 end do
501
502 case (3)
503 do is = 1, nspin
504 i = 1
505 n1 = 1
506 n2 = 1
507 n3 = 1
508 do
509 spec%iwf_i(i, is) = n1
510 spec%iwf_n(i, is) = 1
511 spec%iwf_l(i, is) = n2
512 spec%iwf_m(i, is) = n3
513 spec%iwf_j(i) = m_zero
514 i = i + 1
515 if (i>spec%niwfs) exit
516
517 spec%iwf_i(i, is) = n1+1
518 spec%iwf_n(i, is) = 1
519 spec%iwf_l(i, is) = n2
520 spec%iwf_m(i, is) = n3
521 spec%iwf_j(i) = m_zero
522 i = i + 1
523 if (i>spec%niwfs) exit
524
525 spec%iwf_i(i, is) = n1
526 spec%iwf_n(i, is) = 1
527 spec%iwf_l(i, is) = n2+1
528 spec%iwf_m(i, is) = 0
529 spec%iwf_j(i) = m_zero
530 i = i + 1
531 if (i>spec%niwfs) exit
532
533 spec%iwf_i(i, is) = n1
534 spec%iwf_n(i, is) = 1
535 spec%iwf_l(i, is) = n2
536 spec%iwf_m(i, is) = n3+1
537 spec%iwf_j(i) = m_zero
538 i = i + 1
539 if (i>spec%niwfs) exit
540
541 spec%iwf_i(i, is) = n1+1
542 spec%iwf_n(i, is) = 1
543 spec%iwf_l(i, is) = n2+1
544 spec%iwf_m(i, is) = n3
545 spec%iwf_j(i) = m_zero
546 i = i + 1
547 if (i>spec%niwfs) exit
548
549 spec%iwf_i(i, is) = n1+1
550 spec%iwf_n(i, is) = 1
551 spec%iwf_l(i, is) = n2
552 spec%iwf_m(i, is) = n3+1
553 spec%iwf_j(i) = m_zero
554 i = i + 1
555 if (i>spec%niwfs) exit
556
557 spec%iwf_i(i, is) = n1
558 spec%iwf_n(i, is) = 1
559 spec%iwf_l(i, is) = n2+1
560 spec%iwf_m(i, is) = n3+1
561 spec%iwf_j(i) = m_zero
562 i = i + 1
563 if (i>spec%niwfs) exit
564
565 n1 = n1 + 1
566 n2 = n2 + 1
567 n3 = n3 + 1
568 end do
569 end do
570 case default
571 ! Not doing anything to allow for N-D simulations
572 end select
573
574 pop_sub(jellium_iwf_fix_qn)
575 end subroutine jellium_iwf_fix_qn
576
577 ! ---------------------------------------------------------
579 real(real64) pure function jellium_get_iwf_radius(spec, ii, is, threshold) result(radius)
580 class(jellium_t), intent(in) :: spec
581 integer, intent(in) :: ii
582 integer, intent(in) :: is
583 real(real64), optional, intent(in) :: threshold
584
585 integer :: nmax
586
587 real(real64) threshold_
588
589 threshold_ = optional_default(threshold, 0.001_real64)
590
591 ! We scale the radius with the quantum number. Here we assume 1D, which is an upper bound for higher dimensions.
592 ! The increase in radius is given by the Hermite polynomial
593 ! Note that for spinless particles, this is not correct
594 nmax = max(floor(spec%get_zval()/ m_two - m_one), 1)
595 radius = sqrt(-m_two*log(threshold_)/spec%omega) * sqrt(nmax + m_half)
596
597 ! The values for hydrogenic and harmonic-oscillator wavefunctions
598 ! come from taking the exponential part (i.e. the one that controls
599 ! the asymptotic behavior at large r), and setting it equal to
600 ! the threshold.
601 end function jellium_get_iwf_radius
602
603 ! ---------------------------------------------------------
604 logical pure function jellium_is_local(spec) result(is_local)
605 class(jellium_t), intent(in) :: spec
606
607 is_local = .true.
608 end function jellium_is_local
609
610 ! ---------------------------------------------------------
612 ! ---------------------------------------------------------
613 subroutine jellium_init_potential(this, namespace, grid_cutoff, filter)
614 class(jellium_t), intent(inout) :: this
615 type(namespace_t), intent(in) :: namespace
616 real(real64), intent(in) :: grid_cutoff
617 integer, intent(in) :: filter
618
619 real(real64) :: spacing
620
621 push_sub(jellium_init_potential)
622
623 ! The guess orbitals are a Gaussian of width sigma = 1/sqrt(omega) times Hermite
624 ! polynomials. A width narrower than the spacing cannot be represented on the mesh
625 spacing = m_pi / grid_cutoff
626 this%omega = min(this%omega, m_one/spacing**2)
627
629 end subroutine jellium_init_potential
630
631 ! ---------------------------------------------------------
632 subroutine jellium_debug(spec, dir, namespace, gmax)
633 class(jellium_t), intent(in) :: spec
634 character(len=*), intent(in) :: dir
635 type(namespace_t), intent(in) :: namespace
636 real(real64), intent(in) :: gmax
637
638 character(len=256) :: dirname
639 integer :: iunit
640
641 if (.not. mpi_world%is_root()) then
642 return
643 end if
644
645 push_sub(jellium_debug)
646
647 dirname = trim(dir)//'/'//trim(spec%get_label())
648
649 call io_mkdir(dirname, namespace)
650
651 iunit = io_open(trim(dirname)//'/info', namespace, action='write')
652
653 write(iunit, '(a,i3)') 'Index = ', spec%get_index()
654 write(iunit, '(2a)') 'Label = ', trim(spec%get_label())
655 write(iunit, '(a,f15.2)') 'z_val = ', spec%get_zval()
656 write(iunit, '(a,f15.2)') 'mass = ', spec%get_mass()
657 write(iunit, '(a,f15.2)') 'vdw_radius = ', spec%get_vdw_radius()
658 write(iunit, '(a,l1)') 'local = ', spec%is_local()
659
660 select type(spec)
661 type is(species_from_file_t)
662 write(iunit, '(a,f15.2)') 'z = ', spec%get_z()
663 write(iunit,'(a)') 'Species read from file "'//trim(spec%get_filename())//'".'
664 type is(jellium_sphere_t)
665 write(iunit, '(a,f15.2)') 'z = ', spec%get_z()
666 write(iunit, '(a,f15.2)') 'jradius= ', spec%radius()
667 type is(jellium_slab_t)
668 write(iunit, '(a,f15.2)') 'z = ', spec%get_z()
669 write(iunit, '(a,f15.2)') 'jthick= ', spec%thickness()
671 write(iunit, '(2a)') 'usdef = ', trim(spec%potential_formula)
672 end select
673
674 write(iunit, '(a,i3)') 'hubbard_l = ', spec%get_hubbard_l()
675 write(iunit, '(a,f15.2)') 'hubbard_U = ', spec%get_hubbard_U()
676 write(iunit, '(a,f15.2)') 'hubbard_j = ', spec%get_hubbard_j()
677 write(iunit, '(a,f15.2)') 'hubbard_alpha = ', spec%get_hubbard_alpha()
678
679 call io_close(iunit)
680 pop_sub(jellium_debug)
681 end subroutine jellium_debug
682
683 ! ---------------------------------------------------------
684 subroutine jellium_build(spec, namespace, ispin, dim, print_info)
685 class(jellium_t), intent(inout) :: spec
686 type(namespace_t), intent(in) :: namespace
687 integer, intent(in) :: ispin
688 integer, intent(in) :: dim
689 logical, optional, intent(in) :: print_info
690
691 logical :: print_info_
692 integer :: i
693
694 push_sub(jellium_build)
695
696 print_info_ = optional_default(print_info, .true.)
697
698 ! masses are always in amu, so convert them to a.u.
699 call spec%set_mass(units_to_atomic(unit_amu, spec%get_mass()))
700
701 spec%has_density = .false.
702
703 select type (spec)
705 if (print_info_) then
706 write(message(1),'(a,a,a)') 'Species "',trim(spec%get_label()),'" is a user-defined potential.'
707 i = min(237, len_trim(spec%potential_formula)-1) ! I subtract 1 to avoid the non-printable C "end-of-string" character.
708 write(message(2),'(a,a)') ' Potential = ', trim(spec%potential_formula(1:i))
709 if (len(trim(spec%potential_formula)) > 237) then
710 message(2) = trim(message(2))//'...'
711 end if
712 call messages_info(2, namespace=namespace)
713 end if
714 spec%niwfs = int(max(2*spec%get_zval(), m_one))
715
716 ! spec%omega is used to build the guess orbitals, given by a Gaussian radial enveloppe
717 ! of width \sigma = 1/sqrt(omega) times Hermite polynomials. We get it from the
718 ! curvature of the potential, which sets the length scale of the problem.
719 spec%omega = jellium_userdef_omega(spec, dim)
720
721 type is(species_from_file_t)
722 if (print_info_) then
723 write(message(1),'(a)') 'Species read from file "'//trim(spec%get_filename())//'".'
724 call messages_info(1, namespace=namespace)
725 end if
726 spec%niwfs = 2*nint(spec%get_zval()+m_half)
727 spec%omega = 0.1_real64
728
729 type is(jellium_sphere_t)
730 if (print_info_) then
731 write(message(1),'(a,a,a)') 'Species "', trim(spec%get_label()), &
732 '" is a jellium sphere / approximated point particle.'
733 write(message(2),'(a,f11.6)') ' Valence charge = ', spec%get_zval()
734 write(message(3),'(a,f11.6)') ' Radius [a.u] = ', spec%jradius
735 write(message(4),'(a,f11.6)') ' Rs [a.u] = ', spec%jradius * spec%get_zval() ** (-m_one/m_three)
736 call messages_info(4, namespace=namespace)
737 end if
738 spec%niwfs = species_closed_shell_size(2*nint(spec%get_zval()+m_half))
739 spec%omega = 0.1_real64
740
741 type is(jellium_slab_t)
742 if (print_info_) then
743 write(message(1),'(a,a,a)') 'Species "',trim(spec%get_label()),'" is a jellium slab.'
744 write(message(2),'(a,f11.6)') ' Valence charge = ', spec%get_zval()
745 write(message(3),'(a,f11.6)') ' Thickness [a.u] = ', spec%jthick
746 !write(message(4),'(a,f11.6)') ' Rs [a.u] = ', ( M_THREE /( M_FOUR *M_PI ) &
747 !& *spec%get_zval() /( *sb%lsize(1) *sb%lsize(2) ) )**(1.0/3.0)
748 call messages_info(3, namespace=namespace)
749 end if
750 spec%niwfs = 2*nint(spec%get_zval()+m_half)
751 spec%omega = 0.1_real64
752
753 type is(jellium_charge_t)
754 spec%niwfs = int(max(2*spec%get_zval(), m_one))
755 spec%omega = spec%get_zval()
756 spec%has_density = .true.
757 if (print_info_) then
758 write(message(1),'(a,a,a)') 'Species "', trim(spec%get_label()), '" is a distribution of charge:'
759 write(message(2),'(a,a,a)') ' rho is enclosed in volume defined by the "', &
760 trim(spec%density_formula), '" block'
761 write(message(3),'(a,f11.6)') ' Z = ', spec%get_zval()
762 call messages_info(3, namespace=namespace)
763 end if
764
766 spec%niwfs = int(max(2*spec%get_zval(), m_one))
767 spec%omega = spec%get_zval()
768 spec%has_density = .true.
769 if (print_info_) then
770 write(message(1),'(a,a,a)') 'Species "', trim(spec%get_label()), '" is a distribution of charge:'
771 write(message(2),'(a,a)') ' rho = ', trim(spec%density_formula)
772 write(message(3),'(a,f11.6)') ' Z = ', spec%get_zval()
773 call messages_info(3, namespace=namespace)
774 end if
775 class default
776 call messages_input_error(namespace, 'Species', 'Unknown species type')
777 end select
778
779 ! since there is no real cap, make sure there are at least a few available
780 spec%niwfs = max(5, spec%niwfs)
781
782 safe_allocate(spec%iwf_n(1:spec%niwfs, 1:ispin))
783 safe_allocate(spec%iwf_l(1:spec%niwfs, 1:ispin))
784 safe_allocate(spec%iwf_m(1:spec%niwfs, 1:ispin))
785 safe_allocate(spec%iwf_i(1:spec%niwfs, 1:ispin))
786 safe_allocate(spec%iwf_j(1:spec%niwfs))
787
788 call spec%iwf_fix_qn(namespace, ispin, dim)
789
790 write(message(1),'(a,i6,a,i6)') 'Number of orbitals: ', spec%niwfs
791 if (print_info_) call messages_info(1, namespace=namespace)
792
793 pop_sub(jellium_build)
794 end subroutine jellium_build
795
796 ! ---------------------------------------------------------
798 logical pure function jellium_user_defined(spec)
799 class(jellium_t), intent(in) :: spec
800
801 select type(spec)
802 class is(species_user_defined_t)
806 class is(species_from_file_t)
808 class default
809 jellium_user_defined = .false.
810 end select
811
812 end function jellium_user_defined
813
814 ! ---------------------------------------------------------
816 real(real64) pure function jellium_slab_density(slab, box_dim) result(density)
817 class(jellium_slab_t), intent(in) :: slab
818 real(real64), intent(in) :: box_dim(:)
819
820 ! Note the factor of 4 as box_dim is half of the box size
821 density = slab%get_zval() / (box_dim(1) * box_dim(2) * m_four * slab%jthick)
822
823 end function jellium_slab_density
824end module jellium_oct_m
825
826!! Local Variables:
827!! mode: f90
828!! coding: utf-8
829!! End:
double log(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
double floor(double __x) __attribute__((__nothrow__
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_half
Definition: global.F90:206
real(real64), parameter, public m_one
Definition: global.F90:201
Definition: io.F90:116
subroutine species_user_defined_finalize(this)
Definition: jellium.F90:391
real(real64) pure function jellium_get_omega(spec)
Definition: jellium.F90:433
real(real64) pure function jellium_radius(spec)
Definition: jellium.F90:440
logical pure function jellium_user_defined(spec)
Is the species user-defined or not.
Definition: jellium.F90:894
logical pure function jellium_is_local(spec)
Definition: jellium.F90:700
pure subroutine jellium_set_thickness(spec, thick)
Definition: jellium.F90:459
subroutine jellium_iwf_fix_qn(spec, namespace, nspin, dim)
set up quantum numbers of orbitals
Definition: jellium.F90:542
integer, parameter, public species_charge_density
user-defined function for charge density
Definition: jellium.F90:141
integer, parameter, public species_jellium_charge_density
jellium volume read from file
Definition: jellium.F90:141
real(real64) function jellium_userdef_omega(spec, dim)
Estimate the frequency of the Gaussian envelope, exp(-omega*r^2/2), used to build the guess orbitals ...
Definition: jellium.F90:501
subroutine jellium_charge_finalize(this)
Definition: jellium.F90:331
class(jellium_slab_t) function, pointer jellium_slab_constructor(label, index)
Definition: jellium.F90:253
class(species_user_defined_t) function, pointer species_user_defined_constructor(label, index)
Definition: jellium.F90:372
subroutine jellium_slab_finalize(this)
Definition: jellium.F90:271
subroutine jellium_build(spec, namespace, ispin, dim, print_info)
Definition: jellium.F90:780
real(real64) pure function jellium_get_iwf_radius(spec, ii, is, threshold)
Return radius outside which orbital is less than threshold value 0.001.
Definition: jellium.F90:675
class(jellium_charge_t) function, pointer jellium_charge_constructor(label, index)
Definition: jellium.F90:312
class(jellium_sphere_t) function, pointer jellium_sphere_constructor(label, index)
Definition: jellium.F90:282
pure subroutine jellium_set_radius(spec, radius)
Definition: jellium.F90:446
subroutine species_charge_density_finalize(this)
Definition: jellium.F90:422
character(len=200) pure function jellium_rho_string(spec)
Definition: jellium.F90:466
subroutine species_from_file_finalize(this)
Definition: jellium.F90:360
real(real64) pure function jellium_thick(spec)
Definition: jellium.F90:453
real(real64) pure function jellium_slab_density(slab, box_dim)
Returns the electron density of a jellium slab.
Definition: jellium.F90:912
complex(real64) function jellium_userdef_pot(spec, dim, xx, r)
Definition: jellium.F90:479
integer, parameter, public species_from_file
Definition: jellium.F90:141
class(species_from_file_t) function, pointer species_from_file_constructor(label, index)
Definition: jellium.F90:343
integer, parameter, public species_usdef
user-defined function for local potential
Definition: jellium.F90:141
subroutine jellium_sphere_finalize(this)
Definition: jellium.F90:301
class(species_charge_density_t) function, pointer species_charge_density_constructor(label, index)
Definition: jellium.F90:403
integer, parameter, public species_jellium_slab
jellium slab.
Definition: jellium.F90:141
subroutine jellium_init_potential(this, namespace, grid_cutoff, filter)
Some operations like filtering of the potentials.
Definition: jellium.F90:709
character(len=200) pure function species_rho_string(spec)
Definition: jellium.F90:472
subroutine jellium_debug(spec, dir, namespace, gmax)
Definition: jellium.F90:728
subroutine, public species_end(species)
Definition: species.F90:503
subroutine, public species_init(this, label, index)
Initializes a species object. This should be the first routine to be called (before species_read and ...
Definition: species.F90:292
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
This module defines the unit system, used for input and output.
An abstract class for species. Derived classes include jellium, all electron, and pseudopotential spe...
Definition: species.F90:147
int true(void)