source: trunk/src/run_ape.F90 @ 627

Revision 627, 8.8 KB checked in by tiago, 19 months ago (diff)
  • Added some changes that were missing in previous commit.
  • Corrected some spacing errors.
  • Added GSL support for 4-dimensional systems of equations.
  • First steps on RSDFT implementation.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
RevLine 
[570]1!! Copyright (C) 2004-2011 M. Oliveira, F. Nogueira
[106]2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
16!! 02111-1307, USA.
[540]17!!
18!! $Id$
[106]19
[195]20#include "global.h"
[106]21
[543]22module run_ape_m
23  use global_m
24  use oct_parser_m
25  use utilities_m
26  use messages_m
27  use units_m
28  use output_m
29  use wave_equations_integrator_m
[452]30  use eigensolver_m
[543]31  use atom_m
[570]32  use numerical_tests_m
[106]33  implicit none
34
35
36                    !---Global Variables---!
37
38  !The stack
39  integer :: stack(100) = 0
40  integer :: n_inst     = 0
41
42  !Modes
[578]43  integer, parameter :: AE         = 1,  &
44                        PP_GEN     = 2,  &
45                        PP_TEST    = 4,  &
46                        PP_CONVERT = 8,  &
47                        NUM_TESTS  = 16, &
48                        XC_EVAL    = 32
[106]49
50  !Instructions
[608]51  integer, parameter :: ATOM_AE_CREATE  = 1,  &
52                        ATOM_AE_SAVE    = 2,  &
53                        ATOM_AE_LOAD    = 3,  &
54                        ATOM_AE_XC_EVAL = 4,  &
55                        ATOM_AE_END     = 5,  &
56                        ATOM_PS_CREATE  = 11, &
57                        ATOM_PS_SAVE    = 12, &
58                        ATOM_PS_LOAD    = 13, &
59                        ATOM_PS_TEST    = 14, &
60                        ATOM_PS_END     = 15, &
61                        ATOM_KB_END     = 16, &
62                        NUMERICAL_TESTS = 30, &
63                        LEAVE           = 100
[106]64
65
66                    !---Public/Private Statements---!
67
68  private
[578]69  public :: run, AE, PP_GEN, PP_TEST, NUM_TESTS, XC_EVAL
[106]70
71
72contains
73
74  subroutine run()
75    !-----------------------------------------------------------------------!
[369]76    ! This subroutine reads the run mode and puts the corresponding tasks   !
77    ! in a stack. It then performs all the tasks that are in the stack by   !
78    ! calling the appropriate subroutines.                                  !
79    !                                                                       !
[106]80    !-----------------------------------------------------------------------!
[544]81    integer             :: calcmode, mode_test, inst, message_length
82    type(integrator_t)  :: integrator_sp, integrator_dp
83    type(eigensolver_t) :: eigensolver
84    type(atom_t)        :: ae_atom, ps_atom, kb_atom
[106]85
[153]86    call push_sub("run")
87
[106]88    !Read calculation mode
[252]89    call oct_parse_int('CalculationMode', AE + PP_GEN, calcmode)
[106]90
[252]91    !Write what the code is going to do and check the input
92    message(1) = "Calculation Type:"
93    message_length = 1
94    mode_test = calcmode
95    if (iand(calcmode, AE) /= 0) then
96      message_length = message_length + 1
97      message(message_length) = "  Atomic Calculation"
98      mode_test = mode_test - iand(AE, calcmode)
99    end if
100    if (iand(calcmode, PP_GEN) /= 0) then
101      message_length = message_length + 1
102      message(message_length) = "  PseudoPotential Generation"
103      mode_test = mode_test - iand(PP_GEN, calcmode)
104    end if
105    if (iand(calcmode, PP_TEST) /= 0) then
106      message_length = message_length + 1
107      message(message_length) = "  PseudoPotential Test"
108      mode_test = mode_test - iand(PP_TEST, calcmode)
109    end if
110    if (iand(calcmode, PP_CONVERT) /= 0) then
111      message_length = message_length + 1
112      message(message_length) = "  PseudoPotential File Conversion"
113      mode_test = mode_test - iand(PP_CONVERT, calcmode)
114    end if
[570]115    if (iand(calcmode, NUM_TESTS) /= 0) then
116      message_length = message_length + 1
117      message(message_length) = "  Numerical Tests"
118      mode_test = mode_test - iand(NUM_TESTS, calcmode)
119    end if
[578]120    if (iand(calcmode, XC_EVAL) /= 0) then
121      message_length = message_length + 1
122      message(message_length) = "  Exchange-Correlation Evaluation"
123      mode_test = mode_test - iand(XC_EVAL, calcmode)
124    end if
[252]125    if (mode_test /= 0) then
126      write(message(1), '(A,I2,A)') "Input: '", calcmode, "' is not a valid CalculationMode"
127      call write_fatal(1)
128    else
129      call write_info(message_length)
130    end if
[431]131
[106]132    !Initialize stack
133    !Remember this is a stack: first in last out!
[608]134    call push(LEAVE) !Last thing to do is always to exit
[106]135
[252]136    !Are we going to convert the pseudopotential data?
137    if (iand(calcmode, PP_CONVERT) /= 0) then
[608]138      call push(ATOM_PS_END)
139      call push(ATOM_PS_LOAD)
[252]140    end if
[106]141
[252]142    !Are we going to test the pseudopotentials?
143    if (iand(calcmode, PP_TEST) /= 0) then
[608]144      call push(ATOM_PS_END)
145      call push(ATOM_PS_TEST)
146      call push(ATOM_PS_LOAD)
[252]147    end if
[106]148
[252]149    !Are we going to do a pseudopotential generation?
150    if (iand(calcmode, PP_GEN) /= 0) then
[608]151      call push(ATOM_AE_END)
152      call push(ATOM_PS_END)
153      call push(ATOM_KB_END)
154      call push(ATOM_PS_SAVE)
155      call push(ATOM_PS_CREATE)
156      call push(ATOM_AE_LOAD)
[252]157    end if
[204]158
[252]159    !Are we going to do an all-electron calculation?
160    if (iand(calcmode, AE) /= 0) then
[608]161      call push(ATOM_AE_END)
162      call push(ATOM_AE_SAVE)
163      call push(ATOM_AE_CREATE)
[252]164    end if
[250]165
[570]166    !Are we going to perform numerical tests?
167    if (iand(calcmode, NUM_TESTS) /= 0) then
[608]168      call push(NUMERICAL_TESTS)
[570]169    end if
170
[578]171    !Are we going to evaluate the xc potential and energy?
172    if (iand(calcmode, XC_EVAL) /= 0) then
[608]173      call push(ATOM_AE_END)
174      call push(ATOM_AE_XC_EVAL)
175      call push(ATOM_AE_LOAD)
[578]176    end if
177
[106]178    !Initialize things needed for all modes
179    call units_init()
[452]180    call eigensolver_init(eigensolver)
[106]181
182    !Main loop: do everything that is in the stack
183    do
184      call pop(inst)
185      select case (inst)
[608]186      case (ATOM_AE_CREATE)
[452]187        message(1) = ""
188        message(2) = ""
189        message(3) = str_center("-- All Electron Calculation --", 70)
190        call write_info(3)
191
[580]192        call output_init("ae")
[452]193        call atom_null(ae_atom)
[627]194        call atom_create_ae(ae_atom, eigensolver)
[452]195        call atom_output(ae_atom, "ae")
[580]196        call output_end("ae")
[452]197
[608]198      case (ATOM_AE_SAVE)
[452]199        call atom_save(ae_atom, "ae")
200
[608]201      case (ATOM_AE_LOAD)
[452]202        call atom_null(ae_atom)
203        call atom_load(ae_atom, "ae")
204
[608]205      case (ATOM_AE_XC_EVAL)
[580]206        message(1) = ""
207        message(2) = ""
208        message(3) = str_center("-- Exchage-Correlation Evaluation --", 70)
209        call output_init("xc")
[578]210        call atom_xc_eval(ae_atom)
[580]211        call output_end("xc")
[578]212
[608]213      case (ATOM_AE_END)
[452]214        call atom_end(ae_atom)
215
[608]216      case (ATOM_PS_CREATE)
[452]217        message(1) = ""
218        message(2) = ""
219        message(3) = str_center("-- Pseudopotential Generation --", 70)
220        call write_info(3)
221
[580]222        call output_init("pp")
223        call output_init("kb")
[452]224        call atom_null(ps_atom)
225        call atom_null(kb_atom)
[627]226        call atom_create_ps(ae_atom, ps_atom, kb_atom, eigensolver)
[452]227        call atom_output(ps_atom, "pp")
228        call atom_output(kb_atom, "kb")
[580]229        call output_end("pp")
230        call output_end("kb")
[452]231
[608]232      case (ATOM_PS_SAVE)
[452]233        call atom_save(ps_atom, "pp")
234
[608]235      case (ATOM_PS_LOAD)
[452]236        call atom_null(ps_atom)
237        call atom_load(ps_atom, "pp")
238
[608]239      case (ATOM_PS_TEST)
[452]240        message(1) = ""
241        message(2) = ""
242        message(3) = str_center("-- Pseudopotential Testing --", 70)
243        call write_info(3)
244
[580]245        call output_init("tests")
[627]246        call atom_test(ps_atom, eigensolver)
[580]247        call output_end("tests")
[608]248      case (ATOM_PS_END)
[452]249        call atom_end(ps_atom)
[608]250      case (NUMERICAL_TESTS)
[580]251        message(1) = ""
252        message(2) = ""
253        message(3) = str_center("-- Numerical Tests --", 70)
254        call output_init("nt")
[570]255        call numerical_tests_run()
[580]256        call output_end("nt")
[608]257      case (LEAVE)
[106]258        exit
259      end select
260    end do
261
262    !End things needed for all modes
[452]263    call eigensolver_end(eigensolver)
[106]264
[153]265    call pop_sub()
[369]266  contains
[106]267
[369]268    subroutine push(inst)
269      integer, intent(in) :: inst
[106]270
[369]271      if (n_inst == 100) then
272        message(1) = "Too many instructions in stack"
273        call write_fatal(1)
274      end if
275      n_inst = n_inst + 1
276      stack(n_inst) = inst
[106]277
[369]278    end subroutine push
[106]279
[369]280    subroutine pop(inst)
281      integer, intent(out) :: inst
[106]282
[369]283      if (n_inst == 0) then
284        message(1) = "Not enough instructions in stack"
285        call write_fatal(1)
286      end if
287      inst = stack(n_inst)
288      stack(n_inst) = 0
289      n_inst = n_inst - 1
[106]290
[369]291    end subroutine pop
[106]292
[369]293  end subroutine run
294
[543]295end module run_ape_m
Note: See TracBrowser for help on using the repository browser.