root/trunk/src/opt_control_defstates.F90 @ 2908

Revision 2908, 13.6 KB (checked in by acastro, 3 years ago)

I moved the function restart_look to the states module, where
it belongs. I also collected some code that was replicated in various
places, and put it as a "restart_look_and_read" subroutine.

Line 
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
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.
17!!
18!! $Id: opt_control.F90 2870 2007-04-28 06:26:47Z acastro $
19
20
21  ! ---------------------------------------------------------
22  subroutine def_istate(oct, gr, geo, initial_state)
23    type(oct_t), intent(in)       :: oct
24    type(grid_t), intent(in)      :: gr
25    type(geometry_t), intent(in)  :: geo
26    type(states_t), intent(inout) :: initial_state
27
28    integer           :: i, kk, no_c, state, no_blk, kpoints, nst, dim
29    C_POINTER         :: blk
30    integer           :: p, ik, ib, idim, inst, inik
31    integer           :: id ,is, ip, ierr, no_states, isize
32    character(len=10) :: fname
33    type(states_t)    :: tmp_st
34    FLOAT             :: x(MAX_DIM), r, psi_re, psi_im
35    CMPLX             :: c_weight
36   
37    call push_sub('opt_control.def_istate')
38
39    select case(oct%istype)
40    case(oct_is_groundstate)
41      message(1) =  'Info: Using Ground State for InitialState'
42      call write_info(1)
43      call restart_read(trim(tmpdir)//'restart_gs', initial_state, gr, geo, ierr)
44
45    case(oct_is_excited) 
46      message(1) =  'Info: Using Excited State for InitialState'
47      call write_info(1)
48
49      !%Variable OCTTargetStateNumber
50      !%Type integer
51      !%Section Optimal Control
52      !%Default 2
53      !%Description
54      !% Specify the target state, ordered by energy
55      !%End
56      call loct_parse_int(check_inp('OCTInitialStateNumber'), 2, state)
57
58      !TODO: The following lines of code do not look too clear, and will probably break easily.
59      !They should also be isolated and taken away, since they are repeated in several places.
60      tmp_st = initial_state
61      call restart_look_and_read(trim(tmpdir)//'restart_gs', tmp_st, gr, geo, ierr)
62      if(ierr.ne.0) then
63        write(message(1),'(a)') 'Could not read ground-state wavefunctions from '//trim(tmpdir)//'restart_gs.'
64        call write_fatal(1)
65      end if
66      initial_state%zpsi(:, :, 1, 1) = tmp_st%zpsi(:, :, state, 1)
67
68    case(oct_is_superposition)   
69      message(1) =  'Info: Using Superposition of States for InitialState'
70      call write_info(1)
71
72      !%Variable OCTInitialSuperposition
73      !%Type block
74      !%Section Optimal Control
75      !%Description
76      !% The syntax of each line is, then:
77      !%
78      !% <tt>%OCTInitialSuperposition
79      !% <br>&nbsp;&nbsp;state1 | weight1 | state2 | weight2 | ...
80      !% <br>%</tt>
81      !%
82      !% Note that weight can be complex, to produce current carrying superpositions.
83      !% Example:
84      !%
85      !% <tt>%OCTInitialSuperposition
86      !% <br>&nbsp;&nbsp;1 | 1 | 2 | -1 | ...
87      !% <br>%</tt>
88      !%
89      !%End
90      if(loct_parse_block(check_inp('OCTInitialSuperposition'),blk)==0) then
91
92        tmp_st = initial_state
93        call restart_look_and_read(trim(tmpdir)//'restart_gs', tmp_st, gr, geo, ierr)
94        if(ierr.ne.0) then
95          write(message(1),'(a)') 'Could not read ground-state wavefunctions from '//trim(tmpdir)//'restart_gs.'
96          call write_fatal(1)
97        end if
98
99        no_blk = loct_parse_block_n(blk)
100        ! TODO: One should check that the states requested are actually present in tmp_st   
101        do i=1, no_blk
102          ! The structure of the block is:
103          ! domain | function_type | center | width | weight
104          no_c = loct_parse_block_cols(blk, i-1)
105          initial_state%zpsi(:,:,i,1) = M_z0
106          do kk=1, no_c, 2
107            call loct_parse_block_int(blk, i-1, kk-1, state)
108            call loct_parse_block_cmplx(blk, i-1, kk, c_weight)
109            initial_state%zpsi(:,:,1,1) = initial_state%zpsi(:,:,1,1) + c_weight * tmp_st%zpsi(:,:,state,1)
110          enddo
111        end do
112        call states_end(tmp_st)
113
114        ! normalize state
115        do ik = 1, initial_state%d%nik
116          do p  = initial_state%st_start, initial_state%st_end
117            call zstates_normalize_orbital(gr%m, initial_state%d%dim, &
118              initial_state%zpsi(:,:, p, ik))
119          enddo
120        enddo
121
122      end if
123     
124    case(oct_is_userdefined)
125      message(1) =  'Info: Building userdefined InitialState'
126      call write_info(1)
127     
128      !%Variable OCTInitialUserdefined
129      !%Type block
130      !%Section Optimal Control
131      !%Description
132      !%
133      !% Example:
134      !%
135      !% <tt>%UserDefinedStates
136      !% <br>&nbsp;&nbsp; 1 | 1 | 1 |  "exp(-r^2)*exp(-i*0.2*x)"
137      !% <br>%</tt>
138      !% 
139      !%End
140      if(loct_parse_block(check_inp('OCTInitialUserdefined'),blk)==0) then
141       
142        no_states = loct_parse_block_n(blk)
143        do ib = 1, no_states
144          write(6,*) 'HELLO USERDEF'
145          call loct_parse_block_int(blk, ib-1, 0, idim)
146          call loct_parse_block_int(blk, ib-1, 1, inst)
147          call loct_parse_block_int(blk, ib-1, 2, inik)
148          write(6,*) ' DEBUG: ', idim,inst,inik
149          ! read formula strings and convert to C strings
150          do id = 1, initial_state%d%dim
151            do is = 1, initial_state%nst
152              do ik = 1, initial_state%d%nik   
153               
154                ! does the block entry match and is this node responsible?
155                if(.not.(id.eq.idim .and. is.eq.inst .and. ik.eq.inik    &
156                  .and. initial_state%st_start.le.is .and. initial_state%st_end.ge.is) ) cycle
157               
158                ! parse formula string
159                call loct_parse_block_string(                            &
160                  blk, ib-1, 3, initial_state%user_def_states(id, is, ik))
161                ! convert to C string
162                call conv_to_C_string(initial_state%user_def_states(id, is, ik))
163               
164                do ip = 1, gr%m%np
165                  x = gr%m%x(ip, :)
166                  r = sqrt(sum(x(:)**2))
167                 
168                  ! parse user defined expressions
169                  call loct_parse_expression(psi_re, psi_im,             &
170                    x(1), x(2), x(3), r, M_ZERO, initial_state%user_def_states(id, is, ik))
171                  ! fill state
172                  !write(6,*) psi_re, psi_im
173                  initial_state%zpsi(ip, id, is, ik) = psi_re + M_zI*psi_im
174                end do
175                ! normalize orbital
176                call zstates_normalize_orbital(gr%m, initial_state%d%dim, initial_state%zpsi(:,:, is, ik))
177              end do
178            end do
179          enddo
180        end do
181        call loct_parse_block_end(blk)
182      else
183        message(1) = '"UserDefinedStates" has to be specified as block.'
184        call write_fatal(1)
185      end if
186     
187    case default
188      write(message(1),'(a)') "No valid initial state defined."
189      write(message(2),'(a)') "Choosing the ground state."
190      call write_info(2)
191    end select
192   
193    call pop_sub()
194  end subroutine def_istate
195
196
197  ! ----------------------------------------------------------------------
198  subroutine def_toperator(oct, gr, geo, target_state)
199    type(oct_t), intent(in)       :: oct
200    type(grid_t), intent(in)      :: gr
201    type(geometry_t), intent(in)  :: geo
202    type(states_t), intent(inout) :: target_state
203
204    integer           :: i, kpoints, dim, nst, no_c, state, ierr, isize, ik, ib, &
205                         no_states, kk, p, ip, no_blk
206    C_POINTER         :: blk
207    FLOAT             :: x(MAX_DIM), r, psi_re, psi_im
208    CMPLX             :: c_weight     
209    type(states_t)    :: tmp_st
210    character(len=1024) :: expression
211    character(len=10) :: fname
212
213
214    call push_sub('opt_control.def_toperator')
215
216    select case(oct%totype)
217    case(oct_tg_groundstate)
218      message(1) =  'Info: Using Ground State for TargetOperator'
219      call write_info(1)
220      call restart_read(trim(tmpdir)//'restart_gs', target_state, gr, geo, ierr)
221      if(ierr.ne.0) then
222        write(message(1),'(a)') 'Could not read ground-state wavefunctions from '//trim(tmpdir)//'restart_gs.'
223        call write_fatal(1)
224      end if
225     
226    case(oct_tg_excited)
227      message(1) =  'Info: Using Excited State for TargetOperator'
228      call write_info(1)
229
230      !%Variable OCTTargetStateNumber
231      !%Type integer
232      !%Section Optimal Control
233      !%Default 2
234      !%Description
235      !% Specify the target state, ordered by energy.
236      !%End
237      call loct_parse_int(check_inp('OCTTargetStateNumber'), 2, state)
238
239      !TODO: The following lines of code do not look too clear, and will probably break easily.
240      tmp_st = target_state
241      call restart_look_and_read(trim(tmpdir)//'restart_gs', tmp_st, gr, geo, ierr)
242      if(ierr.ne.0) then
243        write(message(1),'(a)') 'Could not read ground-state wavefunctions from '//trim(tmpdir)//'restart_gs.'
244        call write_fatal(1)
245      end if
246
247      target_state%zpsi(:, :, 1, 1) = tmp_st%zpsi(:, :, state, 1)
248      call states_end(tmp_st)
249
250    case(oct_tg_superposition) 
251      message(1) =  'Info: Using Superposition of States for TargetOperator'
252      call write_info(1)
253
254      !%Variable OCTTargetSuperposition
255      !%Type block
256      !%Section Optimal Control
257      !%Description
258      !% The syntax of each line is, then:
259      !%
260      !% <tt>%OCTTargetSuperposition
261      !% <br>&nbsp;&nbsp;state1 | weight1 | state2 | weight2 | ...
262      !% <br>%</tt>
263      !%
264      !% Example:
265      !%
266      !% <tt>%OCTTargetSuperposition
267      !% <br>&nbsp;&nbsp;1 | 1 | 2 | -1 | ...
268      !% <br>%</tt>
269      !%
270      !%End
271      if(loct_parse_block(check_inp('OCTTargetSuperposition'),blk)==0) then
272
273        tmp_st = target_state
274        call restart_look_and_read(trim(tmpdir)//'restart_gs', tmp_st, gr, geo, ierr)
275        if(ierr.ne.0) then
276          write(message(1),'(a)') 'Could not read ground-state wavefunctions from '//trim(tmpdir)//'restart_gs.'
277          call write_fatal(1)
278        end if
279
280        no_blk = loct_parse_block_n(blk)
281        ! TODO: for each orbital           
282        do i=1, no_blk
283          ! The structure of the block is:
284          ! domain | function_type | center | width | weight
285          no_c = loct_parse_block_cols(blk, i-1)
286          target_state%zpsi(:,:,i,1) = M_z0
287          do kk=1, no_c, 2
288            call loct_parse_block_int(blk, i-1, kk-1, state)
289            call loct_parse_block_cmplx(blk, i-1, kk, c_weight)
290            target_state%zpsi(:, :, 1, 1) = target_state%zpsi(:, :, 1, 1) + c_weight * tmp_st%zpsi(:, :, state, 1)
291          enddo
292        end do
293        call states_end(tmp_st)
294
295        ! normalize state
296        do ik = 1, target_state%d%nik
297          do p  = target_state%st_start, target_state%st_end
298            call zstates_normalize_orbital(gr%m, target_state%d%dim, target_state%zpsi(:,:, p, ik))
299          enddo
300        enddo
301
302      end if
303     
304
305    case(oct_tg_userdefined)
306      message(1) =  'Info: Using userdefined state for Targetoperator'
307      call write_info(1)
308      !%Variable OCTInitialUserdefined
309      !%Type block
310      !%Section Optimal Control
311      !%Description
312      !%
313      !% Example:
314      !%
315      !% <tt>%UserDefinedStates
316      !% <br>&nbsp;&nbsp; 1 | 1 | 1 |  "exp(-r^2)*exp(-i*0.2*x)"
317      !% <br>%</tt>
318      !% 
319      !%End
320
321    case(oct_tg_local)
322
323      message(1) =  'Info: Using Local Target'
324      call write_info(1)
325      !%Variable OCTLocalTarget
326      !%Type block
327      !%Section Optimal Control
328      !%Description
329      !% This block defines the shape and position of the local target operator.
330      !% It is possible to define several local operators which are then summed up.
331      !% The syntax of each line is, then:
332      !%
333      !% <tt>%OCTLocalTarget
334      !% <br>&nbsp;&nbsp; "exp(-r^2)*exp(-i*0.2*x)"
335      !% <br>%</tt>
336      !% 
337      !% Example
338      !%
339      !% <tt>%OCTLocalTarget
340      !% <br>&nbsp;&nbsp; "exp(-r^2)*exp(-i*0.2*x)"
341      !% <br>%</tt>
342      !%
343      !%End
344      ! parse input
345     
346      if(loct_parse_block(check_inp('OCTLocalTarget'),blk)==0) then
347        no_states = loct_parse_block_n(blk)
348        target_state%zpsi(:, 1, 1, 1) = m_z0
349
350        do ib = 1, no_states
351          ! parse formula string
352          call loct_parse_block_string(blk, ib-1, 0, expression)
353          ! convert to C string
354          call conv_to_C_string(expression)
355         
356          do ip = 1, gr%m%np
357            x = gr%m%x(ip, :)
358            r = sqrt(sum(x(:)**2))
359           
360            ! parse user defined expressions
361            call loct_parse_expression(psi_re, psi_im, &
362              x(1), x(2), x(3), r, M_ZERO, expression)
363           
364            ! fill state
365            target_state%zpsi(ip, 1, 1, 1) = target_state%zpsi(ip, 1, 1, 1) &
366              + psi_re + M_zI*psi_im
367          end do
368         
369          ! normalize orbital
370          call zstates_normalize_orbital(gr%m, target_state%d%dim, &
371            target_state%zpsi(:,:, 1, 1))
372        end do
373        call loct_parse_block_end(blk)
374      else
375        message(1) = '"OCTLocalTarget" has to be specified as block.'
376        call write_fatal(1)
377      end if
378
379    case(oct_tg_td_local)
380      target_state%zpsi(:,1,1,1) = M_z0
381
382    case default
383      write(message(1),'(a)') "Target Operator not properly defined."
384      call write_fatal(1)
385    end select
386   
387    call pop_sub()
388  end subroutine def_toperator
Note: See TracBrowser for help on using the browser.