Branch data Line data Source code
1 : : !!****m* ABINIT/m_tdep_sampling
2 : : !! NAME
3 : : !! m_tdep_sampling
4 : : !!
5 : : !! FUNCTION
6 : : !! This module contains the TDEP Sampling data type
7 : : !! which holds the set of configurations from which the IFC will be fit.
8 : : !!
9 : : !! COPYRIGHT
10 : : !! Copyright (C) 2011-2026 ABINIT group (GA,FB,JB)
11 : : !! This file is distributed under the terms of the
12 : : !! GNU General Public License, see ~abinit/COPYING
13 : : !! or http://www.gnu.org/copyleft/gpl.txt .
14 : : !!
15 : : !! SOURCE
16 : :
17 : : #if defined HAVE_CONFIG_H
18 : : #include "config.h"
19 : : #endif
20 : :
21 : : #include "abi_common.h"
22 : :
23 : : module m_tdep_sampling
24 : :
25 : : use defs_basis
26 : : use m_errors
27 : : use m_abicore
28 : : use m_xmpi
29 : : use m_io_tools
30 : : use m_abihist, only : abihist
31 : : use m_tdep_dataset, only : atdep_dataset_type, MPI_enreg_type
32 : : use m_tdep_latt, only : Lattice_type, tdep_make_inbox
33 : : use m_tdep_sym, only : Symmetries_type, tdep_SearchS_1at
34 : :
35 : : implicit none
36 : :
37 : : type tdep_Sampling_type
38 : :
39 : : integer :: natom
40 : : ! Number of atoms in the supercell
41 : :
42 : : integer :: natom_unitcell
43 : : ! Number of atoms in the unitcell
44 : :
45 : : integer :: my_nstep
46 : : ! Number of MD steps held locally
47 : :
48 : : integer :: nstep_tot
49 : : ! Total of MD steps
50 : :
51 : : integer, allocatable :: typat_unitcell(:)
52 : : ! typat_unitcell(natom_unitcell)
53 : : ! Atom type in the unitcell.
54 : :
55 : : integer, allocatable :: typat(:)
56 : : ! typat(natom)
57 : : ! Atom type in the supercell.
58 : :
59 : : double precision, allocatable :: xred_unitcell(:,:)
60 : : ! xred_unitcell(3, natom_unitcell)
61 : : ! Reduced equilibrium position of the atoms in the unitcell.
62 : :
63 : : double precision, allocatable :: xred_ideal(:,:)
64 : : ! xred_ideal(3, natom)
65 : : ! Reduced equilibrium position of the atoms in the supercell.
66 : :
67 : : double precision, allocatable :: xred(:,:,:)
68 : : ! xred(3, natom, my_nstep)
69 : : ! Reduced position of the atom at each step.
70 : :
71 : : double precision, allocatable :: fcart(:,:,:)
72 : : ! fcart(3, natom, my_nstep)
73 : : ! Cartesian forces at each step.
74 : :
75 : : double precision, allocatable :: etot(:)
76 : : ! etot(my_nstep)
77 : : ! Total energy at each step.
78 : :
79 : : double precision, allocatable :: weights(:)
80 : : ! weights(my_nstep)
81 : : ! The weight of each configuration for the fitting.
82 : : ! By default, these will be 1 / nstep_tot.
83 : :
84 : : double precision, allocatable :: Rlatt_cart(:,:,:)
85 : : ! Rlatt_cart(3, natom_unitcell, natom)
86 : : ! Cartesian coordinate of the lattice vectors of the unitcell
87 : : ! within the supercell, for each atom.
88 : :
89 : : double precision, allocatable :: Rlatt_scaled(:,:,:)
90 : : ! Rlatt_scaled(3, natom_unitcell, natom)
91 : : ! Rlatt_cart divided by acell_unitcell.
92 : :
93 : : double precision, allocatable :: ucart(:,:,:)
94 : : ! ucart(3, natom, my_nstep)
95 : : ! Cartesian displacements of the atoms with respect to their equilibrium
96 : : ! positions at each time step.
97 : :
98 : : double precision, allocatable :: distance(:,:,:)
99 : : ! distance(natom, natom, 4)
100 : : ! Distance between the ideal positions of the atoms in the supercell,
101 : : ! (norm, and cartesian components).
102 : :
103 : : double precision, allocatable :: Forces(:)
104 : : ! Forces(3*natom*my_nstep)
105 : : ! The cartesian forces for all configurations, as a flat array.
106 : :
107 : : end type tdep_Sampling_type
108 : :
109 : : public :: tdep_sampling_init_read
110 : : public :: tdep_sampling_free
111 : : public :: tdep_sampling_shift_xred
112 : : public :: tdep_sampling_rotate
113 : : public :: tdep_MatchIdeal2Average
114 : : public :: tdep_write_xred_average
115 : :
116 : : contains
117 : :
118 : : !=====================================================================================================
119 : :
120 : 44 : subroutine tdep_sampling_init_read(MD,Invar,MPIdata,Hist)
121 : :
122 : : type(tdep_Sampling_type), intent(inout) :: MD
123 : : type(atdep_dataset_type), intent(in) :: Invar
124 : : type(MPI_enreg_type), intent(in) :: MPIdata
125 : : type(abihist), intent(in) :: Hist
126 : :
127 : : integer :: this_istep,istep,iatom,jstep
128 : : double precision :: tmp1,tmp2,tmp3
129 : :
130 : 44 : MD%natom = Invar%natom
131 : 44 : MD%natom_unitcell = Invar%natom_unitcell
132 : 44 : MD%my_nstep = Invar%my_nstep
133 : 44 : MD%nstep_tot = Invar%nstep_tot
134 : :
135 [ - + + - : 238 : ABI_CALLOC(MD%typat_unitcell, (MD%natom_unitcell))
+ - + - -
+ - + - +
+ + ]
136 [ - + + - : 7014 : ABI_CALLOC(MD%typat, (MD%natom))
+ - + - -
+ - + - +
+ + ]
137 [ - + + - : 556 : ABI_CALLOC(MD%xred_unitcell, (3,MD%natom_unitcell))
+ - + - -
+ - + - +
+ + + + ]
138 [ - + + - : 27660 : ABI_CALLOC(MD%xred_ideal, (3,MD%natom))
+ - + - -
+ - + - +
+ + + + ]
139 [ - + + - : 557736 : ABI_CALLOC(MD%xred, (3,MD%natom,MD%my_nstep))
- + + - +
- + - - +
- + - + +
+ + + +
+ ]
140 [ - + + - : 557692 : ABI_CALLOC(MD%fcart, (3,MD%natom,MD%my_nstep))
- + + - -
+ - + - +
+ + + + +
+ ]
141 [ - + + - : 1084 : ABI_CALLOC(MD%etot, (MD%my_nstep))
+ - + - -
+ - + - +
+ + ]
142 [ - + + - : 1040 : ABI_CALLOC(MD%weights, (MD%my_nstep))
- + - + -
+ + + ]
143 [ - + + - : 5917156 : ABI_CALLOC(MD%distance, (MD%natom,MD%natom,4))
- + + - +
- + - + -
- + - + -
+ + + + +
+ + ]
144 [ - + + - : 66602 : ABI_CALLOC(MD%Rlatt_scaled, (3,MD%natom_unitcell,MD%natom))
- + + - +
- + - - +
- + - + +
+ + + +
+ ]
145 [ - + + - : 66558 : ABI_CALLOC(MD%Rlatt_cart, (3,MD%natom_unitcell,MD%natom))
- + + - -
+ - + - +
+ + + + +
+ ]
146 [ - + + - : 557692 : ABI_CALLOC(MD%ucart, (3,MD%natom,MD%my_nstep))
- + + - -
+ - + - +
+ + + + +
+ ]
147 [ + - - + : 417588 : ABI_CALLOC(MD%Forces, (3*MD%natom*MD%my_nstep))
+ - + - +
- - + - +
- + + + ]
148 : :
149 [ + + ]: 150 : MD%typat_unitcell(:) = Invar%typat_unitcell(:)
150 [ + + + + ]: 468 : MD%xred_unitcell(:,:) = Invar%xred_unitcell(:,:)
151 [ + + ]: 6926 : MD%typat(:) = Invar%typat(:)
152 : :
153 : : ! Read xred.dat, fcart.dat and etot.dat ASCII files or extract them from the HIST.nc netcdf file.
154 : 44 : write(Invar%stdout,'(a)') ' '
155 : 44 : this_istep=0
156 : 44 : jstep=0
157 [ + + ]: 44 : if (Invar%use_weights.eq.1) then
158 : 1 : open(unit=30,file=trim(Invar%input_prefix)//'_weights.dat')
159 [ + - ]: 43 : else if (Invar%use_weights.eq.0) then
160 [ + + ]: 975 : MD%weights=1.0d0/real(MD%nstep_tot)
161 : : endif
162 [ + + ]: 44 : if (Invar%netcdf) then
163 [ + + ]: 217 : do istep=Invar%nstep_min,Invar%nstep_max
164 [ + + ]: 217 : if (mod(istep-Invar%nstep_min,Invar%slice).ne.0) then
165 : : cycle
166 : : else
167 : 201 : jstep=jstep+1
168 [ - + ]: 201 : if (.not.MPIdata%my_step(jstep)) cycle
169 : 201 : this_istep=this_istep+1
170 [ + + + + ]: 62441 : MD%xred(:,:,this_istep) =Hist%xred (:,:,istep)
171 [ + + + + ]: 62441 : MD%fcart(:,:,this_istep)=Hist%fcart(:,:,istep)
172 : 211 : MD%etot(this_istep) =Hist%etot (istep)
173 : : end if
174 : : end do !istep
175 : 6 : write(Invar%stdout,'(a)') ' The positions, forces and energies are extracted from the NetCDF file: HIST.nc'
176 : : else
177 : 38 : open(unit=60,file=trim(Invar%input_prefix)//'_fcart.dat')
178 : 38 : open(unit=50,file=trim(Invar%input_prefix)//'_xred.dat')
179 : 38 : open(unit=40,file=trim(Invar%input_prefix)//'_etot.dat')
180 [ - + ]: 38 : do istep=1,Invar%nstep_min-1
181 [ # # ]: 0 : if (Invar%use_weights.eq.1) then
182 : 0 : read(30,*) tmp1
183 : : endif
184 : 0 : read(40,*) tmp1
185 [ - - ]: 38 : do iatom=1,MD%natom
186 : 0 : read(50,*) tmp1,tmp2,tmp3
187 : 0 : read(60,*) tmp1,tmp2,tmp3
188 : : end do
189 : : end do
190 [ + + ]: 799 : do istep=Invar%nstep_min,Invar%nstep_max
191 [ + + ]: 799 : if (mod(istep-Invar%nstep_min,Invar%slice).ne.0) then
192 [ - + ]: 10 : if (Invar%use_weights.eq.1) then
193 : 0 : read(30,*) tmp1
194 : : endif
195 : 10 : read(40,*) tmp1
196 [ + + ]: 1290 : do iatom=1,Invar%natom
197 : 1280 : read(50,*) tmp1,tmp2,tmp3
198 : 1290 : read(60,*) tmp1,tmp2,tmp3
199 : : end do
200 : : else
201 : 751 : jstep=jstep+1
202 [ - + ]: 751 : if (.not.MPIdata%my_step(jstep)) then
203 [ # # ]: 0 : if (Invar%use_weights.eq.1) then
204 : 0 : read(30,*) tmp1
205 : : endif
206 : 0 : read(40,*) tmp1
207 [ # # ]: 0 : do iatom=1,Invar%natom
208 : 0 : read(50,*) tmp1,tmp2,tmp3
209 : 0 : read(60,*) tmp1,tmp2,tmp3
210 : : end do
211 : : else
212 : 751 : this_istep=this_istep+1
213 [ + + ]: 751 : if (Invar%use_weights.eq.1) then
214 : 20 : read(30,*) MD%weights(this_istep)
215 : : endif
216 : 751 : read(40,*) MD%etot(this_istep)
217 [ + + ]: 124343 : do iatom=1,MD%natom
218 : 123592 : read(50,*) MD%xred (1,iatom,this_istep),MD%xred (2,iatom,this_istep),MD%xred (3,iatom,this_istep)
219 : 124343 : read(60,*) MD%fcart(1,iatom,this_istep),MD%fcart(2,iatom,this_istep),MD%fcart(3,iatom,this_istep)
220 : : end do
221 : : end if !my_step
222 : : end if !slice
223 : : end do !istep
224 : 38 : close(40)
225 : 38 : close(50)
226 : 38 : close(60)
227 : 38 : write(Invar%stdout,'(2a)') ' The positions, forces and energies are extracted from the ASCII files:',&
228 : 76 : & ' xred.dat, fcart.dat & etot.dat'
229 : : end if !netcdf
230 [ + + ]: 44 : if (Invar%use_weights.eq.1) then
231 : 1 : close(30)
232 : : end if
233 : :
234 : 44 : end subroutine tdep_sampling_init_read
235 : :
236 : : !=====================================================================================================
237 : :
238 : 44 : subroutine tdep_sampling_free(MD)
239 : :
240 : : type(tdep_Sampling_type), intent(inout) :: MD
241 : :
242 [ - + ]: 44 : ABI_FREE(MD%typat_unitcell)
243 [ - + ]: 44 : ABI_FREE(MD%typat)
244 [ - + ]: 44 : ABI_FREE(MD%xred_unitcell)
245 [ - + ]: 44 : ABI_FREE(MD%xred_ideal)
246 [ - + ]: 44 : ABI_FREE(MD%xred)
247 [ - + ]: 44 : ABI_FREE(MD%fcart)
248 [ - + ]: 44 : ABI_FREE(MD%etot)
249 [ - + ]: 44 : ABI_FREE(MD%weights)
250 [ - + ]: 44 : ABI_FREE(MD%distance)
251 [ - + ]: 44 : ABI_FREE(MD%Rlatt_scaled)
252 [ - + ]: 44 : ABI_FREE(MD%Rlatt_cart)
253 [ - + ]: 44 : ABI_FREE(MD%ucart)
254 [ - + ]: 44 : ABI_FREE(MD%Forces)
255 : :
256 : 44 : end subroutine tdep_sampling_free
257 : :
258 : : !=====================================================================================================
259 : :
260 : : ! Shift xred to keep atoms in the same unit cell at each step.
261 : 44 : subroutine tdep_sampling_shift_xred(MD,MPIdata)
262 : :
263 : : type(tdep_Sampling_type), intent(inout) :: MD
264 : : type(MPI_enreg_type), intent(in) :: MPIdata
265 : : integer :: natom,ii,iatom,istep,ierr
266 : : integer :: shift,shift_max,shift_best
267 : : double precision :: xi, dist, best_dist
268 : 44 : double precision, allocatable :: x0(:,:)
269 : :
270 : 44 : natom = MD%natom
271 [ - + + - : 132 : ABI_MALLOC(x0,(3,natom))
+ - + - -
+ - + ]
272 : :
273 : : ! Communicate xred at the first step
274 [ + + + + ]: 27572 : x0(:,:) = zero
275 [ + - ]: 44 : if (MPIdata%my_step(1)) then
276 [ + + + + ]: 27572 : x0(:,:) = MD%xred(:,:,1)
277 : : end if
278 : 44 : call xmpi_sum(x0,MPIdata%comm_step,ierr)
279 : :
280 : : ! Shift xred from all steps in the same unitcell as the first step
281 : 44 : shift_max = 1
282 [ + + ]: 996 : do istep=1, MD%my_nstep
283 [ + + ]: 140148 : do iatom=1,natom
284 [ + + ]: 557560 : do ii=1,3
285 : 417456 : best_dist = abs(MD%xred(ii,iatom,istep) - x0(ii,iatom))
286 : 417456 : shift_best = 0
287 [ + + ]: 1669824 : do shift=-shift_max,shift_max
288 : 1252368 : xi = MD%xred(ii,iatom,istep) + shift
289 : 1252368 : dist = abs(xi - x0(ii,iatom))
290 [ + + ]: 1669824 : if (dist < best_dist) then
291 : 366 : best_dist = dist
292 : 366 : shift_best = shift
293 : : end if
294 : : end do
295 : 556608 : MD%xred(ii,iatom,istep) = MD%xred(ii,iatom,istep) + shift_best
296 : : end do
297 : : end do
298 : : end do
299 : :
300 [ - + ]: 44 : ABI_FREE(x0)
301 : :
302 : 44 : end subroutine tdep_sampling_shift_xred
303 : :
304 : : !=====================================================================================================
305 : :
306 : 44 : subroutine tdep_sampling_rotate(MD,rotation_cart)
307 : :
308 : : type(tdep_Sampling_type), intent(inout) :: MD
309 : : integer :: iatom,istep
310 : : double precision :: rotation_cart(3,3)
311 : :
312 : : ! Apply rotation to fcart
313 [ + + ]: 996 : do istep=1,MD%my_nstep
314 [ + + ]: 140148 : do iatom=1,MD%natom
315 [ + + + + : 2783992 : MD%fcart(:,iatom,istep) = MATMUL(rotation_cart, MD%fcart(:,iatom,istep))
+ + + + +
- + - ]
316 : : end do
317 : : end do
318 : :
319 : 44 : end subroutine tdep_sampling_rotate
320 : :
321 : : !=====================================================================================================
322 : :
323 : : !!***
324 : : !!****f* ABINIT/m_tdep_sampling/tdep_MatchIdeal2Average
325 : : !! NAME
326 : : !! tdep_MatchIdeal2Average
327 : : !!
328 : : !! FUNCTION
329 : : !! Find the mapping between the atoms in the ideal (equilibrium) supercell,
330 : : !! and the atoms of the input moledular dynamics using their average positions.
331 : : !! Then compute the atom displacements with respect to the equilibrium positions
332 : : !! at each time step of the MD.
333 : : !!
334 : : !! INPUTS
335 : : !! MD = TDEP Sampling object containing the input positions and forces.
336 : : !! Invar = Input object containing the input variables.
337 : : !! Lattice = Lattice object describing the ideal structure.
338 : : !! Sym = Symetries object describing all the symmetry operations of the crystal.
339 : : !! MPIdata = Info on MPI parallelism.
340 : : !!
341 : : !! OUTPUT
342 : : !!
343 : : !! SIDE EFFECTS
344 : : !! The following quantities in MD are computed:
345 : : !!
346 : : !! distance = Distance between the ideal positions of the atoms in the supercell,
347 : : !! (norm, and cartesian components).
348 : : !! Forces = Cartesian forces on the atoms at each time steps, as a flat array.
349 : : !! ucart = Cartesian displacements of the atoms with respect to their equilibrium
350 : : !! positions at each time step.
351 : : !! Rlatt_cart = Cartesian coordinate of the lattice vectors of the unitcell
352 : : !! within the supercell, for each atom.
353 : : !! This array seems to have an extra dimension, for algorithmic simplicity.
354 : : !! Rlatt_scaled = Rlatt_cart divided by acell_unitcell.
355 : : !! These are used when reading an IFC file, to compare with the R vectors
356 : : !! that are stored in the file.
357 : : !!
358 : : !! Some of the reduced positions of the atoms MD%xred are shifted by a supercell
359 : : !! lattice vector in order to re-center the crystal.
360 : : !!
361 : : !! NOTES
362 : : !!
363 : : !! SOURCE
364 : :
365 : 44 : subroutine tdep_MatchIdeal2Average(MD,Invar,Lattice,Sym,MPIdata)
366 : :
367 : : type(tdep_Sampling_type),intent(inout) :: MD
368 : : type(atdep_dataset_type),intent(inout) :: Invar
369 : : type(Lattice_type),intent(in) :: Lattice
370 : : type(Symmetries_type),intent(inout) :: Sym
371 : : type(MPI_enreg_type),intent(in) :: MPIdata
372 : :
373 : : integer :: ii,jj,kk,max_ijk,iatcell,jatcell,iatom,jatom,eatom,fatom,istep
374 : : integer :: iatom_ref,ierr
375 : : integer :: ndir_match,natom_match
376 : : double precision :: tmp(3),tmp1(3),tmp2(3),Rlatt(3),xred_tmp(3),rprimd_md_tmp(3,3),distance_tmp(3)
377 : 44 : double precision, allocatable :: dist_unitcell(:,:,:),xcart_average(:,:)
378 : 44 : double precision, allocatable :: fcart_tmp(:,:,:),ucart_tmp(:,:,:)
379 : 44 : double precision, allocatable :: xred_average(:,:)
380 : 44 : double precision, allocatable :: xred_center(:,:)
381 : 44 : double precision, allocatable :: Rlatt_red (:,:,:)
382 : 44 : double precision, allocatable :: xred_ideal(:,:)
383 : : ! double precision, allocatable :: distance_average(:,:,:)
384 : 44 : integer, allocatable :: FromIdeal2Average(:)
385 : 44 : double precision, allocatable :: xcart(:,:,:)
386 : 44 : double precision, allocatable :: xcart_ideal(:,:)
387 : : logical :: ok,must_shift,discard_R
388 : : character(len=500) :: msg
389 : :
390 : 44 : write(Invar%stdout,*)' '
391 : 44 : write(Invar%stdout,*) '#############################################################################'
392 : 44 : write(Invar%stdout,*) '###### Find the matching between ideal and average positions ###############'
393 : 44 : write(Invar%stdout,*) '#############################################################################'
394 : :
395 : : !==========================================================================================
396 : : !======== 1/ Determine ideal positions and distances ======================================
397 : : !==========================================================================================
398 : 44 : write(Invar%stdout,*)' Determine ideal positions and distances...'
399 : : ! Define the bigbox with ideal positions
400 [ - + + - : 66602 : ABI_CALLOC(Rlatt_red ,(3,MD%natom_unitcell,MD%natom))
- + + - +
- + - - +
- + + + +
+ + + ]
401 [ - + + - : 27660 : ABI_CALLOC(xred_ideal,(3,MD%natom))
+ - + - -
+ - + + +
+ + ]
402 : 44 : max_ijk=20
403 : 44 : iatom=1
404 [ + + ]: 1848 : do ii=-max_ijk,max_ijk
405 [ + + ]: 75812 : do jj=-max_ijk,max_ijk
406 [ + + ]: 3108292 : do kk=-max_ijk,max_ijk
407 : :
408 : 3032524 : Rlatt(1)=real(ii-1)
409 : 3032524 : Rlatt(2)=real(jj-1)
410 : 3032524 : Rlatt(3)=real(kk-1)
411 : :
412 : 3032524 : discard_R = .false.
413 [ + + ]: 10412114 : do iatcell=1,MD%natom_unitcell
414 : :
415 [ + + ]: 7305626 : if (discard_R) cycle
416 : :
417 : : ! Compute the reduced positions
418 [ + + ]: 12141444 : tmp(:) = Rlatt(:) + MD%xred_unitcell(:,iatcell)
419 : 3035361 : call DGEMV('T',3,3,1.d0,Lattice%multiplicitym1(:,:),3,tmp(:),1,0.d0,xred_tmp(:),1)
420 : :
421 : : ! If the first atom of the pattern is in the [0;1[ range then keep all the
422 : : ! atoms of the pattern (even if the others are outside the box). Else,
423 : : ! none are taken.
424 [ + + ]: 3035361 : if (iatcell==1) then
425 [ - + + - : 27292716 : if (minval(xred_tmp(:)).lt.0.d0.or.maxval(xred_tmp(:)).ge.(1.d0-tol12)) then
+ + - + +
- + + + +
+ + ]
426 : : discard_R = .true.
427 : : cycle
428 : : end if
429 : : end if
430 : :
431 : : !GA: Why natom+1 ?
432 [ - + ]: 6882 : if (iatom.gt.(MD%natom+1)) then
433 : 0 : ABI_ERROR('The number of atoms found in the bigbox exceeds natom' )
434 : : end if
435 : :
436 [ + + ]: 27528 : xred_ideal(:,iatom) = xred_tmp(:)
437 : 6882 : call DGEMV('T',3,3,1.d0,Lattice%multiplicitym1(:,:),3,Rlatt(:),1,0.d0,Rlatt_red(:,1,iatom),1)
438 : 7309671 : iatom = iatom + 1
439 : : end do
440 : : end do
441 : : end do
442 : : end do
443 : :
444 [ - + ]: 44 : if (iatom.lt.MD%natom+1) then
445 : 0 : ABI_ERROR('The number of atoms found in the big box is smaller than natom')
446 : : end if
447 : :
448 : : ! Compute the distances between ideal positions in the SUPERcell
449 [ + + ]: 6926 : do eatom=1,MD%natom
450 [ + + ]: 1479234 : do fatom=1,MD%natom
451 [ + + ]: 5889232 : tmp(:)=xred_ideal(:,fatom)-xred_ideal(:,eatom)
452 : 1472308 : call tdep_make_inbox(tmp,1,1d-4)
453 [ + + + + ]: 19140004 : rprimd_md_tmp(:,:)=Lattice%rprimd_md(:,:)
454 [ + + ]: 5889232 : distance_tmp(:)=MD%distance(eatom,fatom,2:4)
455 : 1472308 : call DGEMV('T',3,3,1.d0,rprimd_md_tmp,3,tmp,1,0.d0,distance_tmp,1)
456 [ + + ]: 5889232 : MD%distance(eatom,fatom,2:4)=distance_tmp(:)
457 [ + + ]: 5889232 : do ii=1,3
458 : : ! Remove the rounding errors before writing (for non regression testing purposes)
459 [ + + ]: 4416924 : if (abs(MD%distance(eatom,fatom,ii+1)).lt.tol8) MD%distance(eatom,fatom,ii+1)=zero
460 : 5889232 : MD%distance(eatom,fatom,1)=MD%distance(eatom,fatom,1)+(MD%distance(eatom,fatom,ii+1))**2
461 : : end do
462 : 1472308 : MD%distance(eatom,fatom,1)=MD%distance(eatom,fatom,1)**0.5
463 : 1479190 : MD%distance(eatom,fatom,1)=tol12 * dint(MD%distance(eatom,fatom,1) / tol12)
464 : : end do
465 : : end do
466 : :
467 : : ! Compute the distances between ideal positions in the UNITcell
468 [ - + + - : 2212 : ABI_MALLOC(dist_unitcell,(MD%natom_unitcell,MD%natom_unitcell,3)); dist_unitcell(:,:,:)=zero
- + + - +
- + - + -
- + - + +
+ + + +
+ ]
469 [ + + ]: 150 : do iatcell=1,MD%natom_unitcell
470 [ + + ]: 664 : do jatcell=1,MD%natom_unitcell
471 [ + + ]: 2056 : tmp(:) = xred_ideal(:,jatcell)-xred_ideal(:,iatcell)
472 : 514 : call tdep_make_inbox(tmp,1,tol8)
473 [ + + ]: 2162 : dist_unitcell(iatcell,jatcell,:) = tmp(:)
474 : : end do
475 : : end do
476 : :
477 : : !==========================================================================================
478 : : !======== 2/ Find the matching between the ideal and average ==============================
479 : : !======== (from the MD simulations) positions. ==========================================
480 : : !==========================================================================================
481 : : ! NOTE: - xred_center is used to find the matching with the ideal positions
482 : : ! - xred_average is used to compute the displacements (from MD trajectories)
483 : : ! The difference between those two is that xred_center will be shifted to bring
484 : : ! one of the average positions at the origin, for an easier comparison with
485 : : ! xred_ideal. Some shifts by a supercell lattice vector will be computed
486 : : ! from the difference between xred_center and xred_ideal, and those shifts
487 : : ! will be applied to xred_average and xred at all steps.
488 : :
489 : 44 : write(Invar%stdout,*)' Compute average positions...'
490 [ - + + - : 27660 : ABI_CALLOC(xred_average,(3,MD%natom))
+ - + - -
+ - + + +
+ + ]
491 [ - + + - : 27616 : ABI_CALLOC(xred_center,(3,MD%natom))
- + - + +
+ + + ]
492 : : ! Average positions from MD (on nstep steps)
493 [ + + ]: 996 : do istep=1,MD%my_nstep
494 [ + + ]: 140148 : do iatom=1,MD%natom
495 [ + + ]: 557560 : xred_average(:,iatom)=xred_average(:,iatom)+MD%xred(:,iatom,istep)
496 : : end do
497 : : end do
498 : 44 : call xmpi_sum(xred_average,MPIdata%comm_step,ierr)
499 [ + + + + ]: 27572 : xred_average(:,:) = xred_average(:,:) / real(MD%nstep_tot)
500 : :
501 : : ! Search the basis of atoms in the supercell
502 : : ! in order to find iatom_ref
503 : 44 : write(Invar%stdout,*)' Search the unitcell basis of atoms in the MD trajectory...'
504 : 44 : ok=.false.
505 [ + + + + ]: 27572 : xred_center(:,:) = xred_average(:,:)
506 : 44 : iatcell=1
507 [ + - ]: 51 : do iatom=1,MD%natom
508 [ + - ]: 51 : if (MD%typat(iatom).ne.MD%typat_unitcell(iatcell)) cycle
509 : 51 : natom_match = 0
510 [ + + ]: 7797 : do jatom=1,MD%natom
511 : :
512 [ + + ]: 30984 : tmp(:)=xred_center(:,jatom)-xred_center(:,iatom)
513 : 7746 : call tdep_make_inbox(tmp,1,Invar%tolinbox)
514 : :
515 [ + + ]: 24087 : do jatcell=1,MD%natom_unitcell
516 [ + + ]: 16403 : if (MD%typat(jatom).ne.MD%typat_unitcell(jatcell)) cycle
517 : 14263 : ndir_match = 0
518 [ + + ]: 57052 : do ii=1,3
519 [ + + ]: 57052 : if (abs(tmp(ii)-dist_unitcell(iatcell,jatcell,ii)).le.Invar%tolmotif) then
520 : 5723 : ndir_match=ndir_match+1
521 : : end if
522 : : end do
523 [ + + ]: 21896 : if (ndir_match==3) then
524 : 113 : natom_match = natom_match + 1
525 : 113 : exit
526 : : end if
527 : : end do
528 : : end do
529 [ + + ]: 51 : if (natom_match.eq.MD%natom_unitcell) then
530 : : iatom_ref = iatom
531 : : ok=.true.
532 : : exit
533 [ - + ]: 7 : else if (natom_match.gt.MD%natom_unitcell) then
534 : 0 : write(msg,'(5a)') 'Too many atoms match the unit cell.',ch10,&
535 : 0 : 'Perhaps the value of tolmotif is too large,',ch10,&
536 : 0 : 'or the value of tolinbox is too small.'
537 : 0 : ABI_ERROR(msg)
538 : : endif
539 : : end do
540 : : if (.not.ok) then
541 : 0 : call tdep_write_xred_average(Invar,MPIdata,Lattice,xred_ideal,xred_center)
542 : 0 : write(msg,'(3a)') 'The basis of atoms written in input.in file does not appear in the MD trajectory.',ch10,&
543 : 0 : 'Perhaps, you can adjust the tolerance (tolmotif).'
544 : 0 : ABI_ERROR(msg)
545 : : end if
546 [ - + ]: 44 : ABI_FREE(dist_unitcell)
547 : :
548 : 44 : write(Invar%stdout,*)' Compare ideal and average positions using PBC...'
549 : : ! Modification of xred and Rlatt tabs
550 : : ! for averaged quantities: xred_center, xred_average, xred
551 : : ! 1/ The "iatom_ref" atom is put in (0.0;0.0;0.0)
552 [ + + ]: 176 : tmp(:) = xred_center(:,iatom_ref)
553 [ + + ]: 6926 : do jatom=1,MD%natom
554 [ + + ]: 27572 : xred_center(:,jatom) = xred_center(:,jatom) - tmp(:)
555 : : end do
556 : : ! 2/ All the atoms are put in the range [-0.5;0.5[ (use of PBC)
557 [ + + ]: 6926 : do jatom=1,MD%natom
558 [ + + ]: 27528 : tmp(:)=xred_center(:,jatom)
559 : 6882 : call tdep_make_inbox(tmp,1,Invar%tolinbox,xred_center(:,jatom))
560 : 6882 : call tdep_make_inbox(tmp,1,Invar%tolinbox,xred_average(:,jatom))
561 [ + + ]: 146078 : do istep=1,MD%my_nstep
562 : 146034 : call tdep_make_inbox(tmp,1,Invar%tolinbox,MD%xred(:,jatom,istep))
563 : : end do
564 : : end do
565 : : ! Modification of xred and Rlatt tabs
566 : : ! for ideal quantities: Rlatt_red et xred_ideal
567 : : ! 1/ The atom 1 is put in (0.0;0.0;0.0)
568 [ + + ]: 176 : tmp1(:)=xred_ideal(:,1)
569 [ + + ]: 176 : tmp2(:)=Rlatt_red(:,1,1)
570 [ + + ]: 6926 : do jatom=1,MD%natom
571 [ + + ]: 27528 : xred_ideal(:,jatom)= xred_ideal(:,jatom) -tmp1(:)
572 [ + + ]: 27572 : Rlatt_red (:,1,jatom)=Rlatt_red (:,1,jatom)-tmp2(:)
573 : : end do
574 : : ! 2/ All the atoms are put in the range [-0.5;0.5[ (use of PBC)
575 [ + + ]: 6926 : do jatom=1,MD%natom
576 [ + + ]: 27528 : tmp(:)=xred_ideal(:,jatom)
577 : 6882 : call tdep_make_inbox(tmp,1,tol8,xred_ideal(:,jatom))
578 : 6926 : call tdep_make_inbox(tmp,1,tol8,Rlatt_red(:,1,jatom))
579 : : !FB call tdep_make_inbox(Rlatt_red(:,1,jatom),1,tol8)
580 : : end do
581 : :
582 : : ! When the multiplicity equals 1 along one direction, there is some trouble
583 : : ! To clean!!!!!!!
584 [ + + ]: 176 : do ii=1,3
585 : : if ((Invar%multiplicity(ii,ii).eq.1).and.(Invar%multiplicity(ii,mod(ii ,3)+1).eq.0)&
586 [ + + + + : 176 : & .and.(Invar%multiplicity(ii,mod(ii+1,3)+1).eq.0)) then
+ - ]
587 [ + + ]: 65 : Rlatt_red(ii,1,:)=0.d0
588 : 1 : write(Invar%stdout,*) 'WARNING: multiplicity=1 for ii=',ii
589 : : end if
590 : : end do
591 : :
592 : : ! Define Rlatt for all the atoms in the basis (Rlatt_red varies as a function of iatcell)
593 [ + + ]: 44 : if (MD%natom_unitcell.gt.1) then
594 [ + + ]: 93 : do iatcell=2,MD%natom_unitcell
595 [ + + + + ]: 32109 : Rlatt_red(:,iatcell,:)=Rlatt_red(:,1,:)
596 : : end do
597 : : end if
598 [ + + ]: 6926 : do iatom=1,MD%natom
599 [ + + ]: 21812 : do iatcell=1,MD%natom_unitcell
600 [ + + ]: 59544 : tmp(:)=xred_ideal(:,iatom)-xred_ideal(:,iatcell)
601 : 21768 : call tdep_make_inbox(tmp,1,tol8,Rlatt_red(:,iatcell,iatom))
602 : : end do
603 : : end do
604 [ + + ]: 44 : if (Invar%debug) then
605 [ + + ]: 12 : do iatcell=1,MD%natom_unitcell
606 : 10 : write(Invar%stdout,*) 'For iatcell=',iatcell
607 [ + + ]: 1036 : do jatom=1,MD%natom
608 : 1034 : write(Invar%stdout,'(a,i4,a,3(f16.10,1x))') 'For jatom=',jatom,', Rlatt=',Rlatt_red(1:3,iatcell,jatom)
609 : : end do
610 : : end do
611 : : end if
612 : :
613 : : ! Matching between Ideal and Average positions: xred_ideal and xred_center
614 : : ! Then, write them in the xred_average.xyz file.
615 : 44 : write(Invar%stdout,*)' Write the xred_average.xyz file with ideal and average positions...'
616 [ - + + - : 7014 : ABI_CALLOC(FromIdeal2Average,(MD%natom))
+ - + - -
+ - + +
+ ]
617 [ + + ]: 6926 : do iatom=1,MD%natom
618 : 6882 : ok =.false.
619 [ + - ]: 739595 : do jatom=1,MD%natom
620 [ + + ]: 739595 : if (MD%typat(iatom).ne.MD%typat_unitcell(mod(jatom-1,MD%natom_unitcell)+1)) cycle
621 : 624459 : must_shift=.false.
622 : 624459 : ndir_match=0
623 [ + + ]: 2497836 : do ii=1,3
624 [ + + ]: 2497836 : if (abs(xred_center(ii,iatom)-xred_ideal(ii,jatom)).le.Invar%tolmatch) then
625 : 246347 : ndir_match=ndir_match+1
626 : : else if ((abs(xred_center(ii,iatom)-xred_ideal(ii,jatom)-1.d0).le.Invar%tolmatch) &
627 [ + + + + ]: 1627030 : & .or.(abs(xred_center(ii,iatom)-xred_ideal(ii,jatom)+1.d0).le.Invar%tolmatch)) then
628 : 1114 : ndir_match=ndir_match+1
629 : 1114 : must_shift=.true.
630 : : endif
631 : : end do
632 [ + + ]: 624459 : if (ndir_match==3.and..not.must_shift) then
633 : 6882 : FromIdeal2Average(jatom)=iatom
634 : : ok=.true.
635 : : exit
636 [ - + ]: 617577 : else if (ndir_match==3.and.must_shift) then
637 [ # # ]: 0 : do ii=1,3
638 [ # # ]: 0 : if (abs(xred_center(ii,iatom)-xred_ideal(ii,jatom)-1.d0).le.Invar%tolmatch) then
639 : 0 : xred_center(ii,iatom)=xred_center(ii,iatom)-1d0
640 : 0 : xred_average(ii,iatom)=xred_average(ii,iatom)-1d0
641 [ # # ]: 0 : do istep=1,MD%my_nstep
642 : 0 : MD%xred(ii,iatom,istep)=MD%xred(ii,iatom,istep)-1d0
643 : : end do
644 : 0 : FromIdeal2Average(jatom)=iatom
645 [ # # ]: 0 : else if (abs(xred_center(ii,iatom)-xred_ideal(ii,jatom)+1.d0).le.Invar%tolmatch) then
646 : 0 : xred_center(ii,iatom)=xred_center(ii,iatom)+1d0
647 : 0 : xred_average(ii,iatom)=xred_average(ii,iatom)+1d0
648 [ # # ]: 0 : do istep=1,MD%my_nstep
649 : 0 : MD%xred(ii,iatom,istep)=MD%xred(ii,iatom,istep)+1d0
650 : : end do
651 : 0 : FromIdeal2Average(jatom)=iatom
652 : : end if
653 : : end do
654 : : ok=.true.
655 : : exit
656 : : end if
657 : : end do
658 [ - - ]: 44 : if (.not.ok) then
659 : 0 : write(Invar%stdlog,*) 'Problem to find the average position for iatom=',iatom
660 : 0 : write(Invar%stdlog,*) ' Reasons:'
661 : 0 : write(Invar%stdlog,*) ' 1/ One atom jump to another equilibrium position'
662 : 0 : write(Invar%stdlog,*) ' 2/ The system is no more solid'
663 : 0 : write(Invar%stdlog,*) ' 3/ Perhaps, you can adjust the tolerance (tolmatch)'
664 : 0 : write(Invar%stdlog,*) ' xred_center=',(xred_center(ii,iatom),ii=1,3)
665 [ # # ]: 0 : do eatom=1,MD%natom
666 : 0 : write(Invar%stdlog,'(a,1x,3(f10.6,1x))') 'I',xred_ideal (:,eatom)
667 : 0 : write(Invar%stdlog,'(a,1x,3(f10.6,1x))') 'C',xred_center(:,eatom)
668 : : end do
669 : 0 : ABI_ERROR('Problem to find the average position')
670 : : end if
671 : : end do
672 : :
673 : : ! WARNING: VERY IMPORTANT: The positions are displayed/sorted
674 : : ! (and used in the following) according to ideal positions xred_ideal.
675 : 44 : call tdep_write_xred_average(Invar,MPIdata,Lattice,xred_ideal,xred_center,FromIdeal2Average)
676 [ - + ]: 44 : ABI_FREE(xred_center)
677 : :
678 : : !====================================================================================
679 : : !====================== END OF REDUCED COORDINATES ==================================
680 : : !====================================================================================
681 : : ! a/ Get cartesian coordinates from reduced ones
682 : : ! b/ Compute ucart and fcart tabs
683 : : ! c/ The atoms are sorted according the IDEAL arrangement
684 : : ! The correspondance function is contained in: FromIdeal2Average
685 : : ! WARNING : Consequently the arrangement of the xcart* tabs is not modified.
686 : 44 : write(Invar%stdout,*)' Compute cartesian coordinates and forces...'
687 [ - + + - : 557736 : ABI_MALLOC(xcart ,(3,MD%natom,MD%my_nstep)); xcart(:,:,:)=0.d0
- + + - +
- + - - +
- + + + +
+ + + ]
688 [ - + + - : 27660 : ABI_MALLOC(xcart_ideal ,(3,MD%natom)) ; xcart_ideal(:,:)=0.d0
+ - + - -
+ - + + +
+ + ]
689 [ - + + - : 27616 : ABI_MALLOC(xcart_average,(3,MD%natom)) ; xcart_average(:,:)=0.d0
- + - + +
+ + + ]
690 [ - + + - : 557692 : ABI_MALLOC(ucart_tmp ,(3,MD%natom,MD%my_nstep)); ucart_tmp(:,:,:)=0.d0
- + + - -
+ - + + +
+ + + + ]
691 [ + + ]: 6926 : do iatom=1,MD%natom
692 : 6882 : call DGEMV('T',3,3,1.d0,Lattice%rprimd_md(:,:),3,xred_ideal (:,iatom),1,0.d0,xcart_ideal (:,iatom),1)
693 : 6882 : call DGEMV('T',3,3,1.d0,Lattice%rprimd_md(:,:),3,xred_average(:,iatom),1,0.d0,xcart_average(:,iatom),1)
694 [ + + ]: 21812 : do iatcell=1,MD%natom_unitcell
695 : 21768 : call DGEMV('T',3,3,1.d0,Lattice%rprimd_md(:,:),3,Rlatt_red(:,iatcell,iatom),1,0.d0,MD%Rlatt_cart(:,iatcell,iatom),1)
696 : : end do
697 : : end do
698 [ + + ]: 996 : do istep=1,MD%my_nstep
699 [ + + ]: 140148 : do iatom=1,MD%natom
700 : 139152 : jatom = FromIdeal2Average(iatom)
701 : : call DGEMV('T',3,3,1.d0,Lattice%rprimd_md(:,:),3,MD%xred(:,jatom,istep),&
702 : 139152 : & 1,0.d0,xcart(:,jatom,istep),1)
703 [ + + ]: 140104 : if (Invar%use_ideal_positions.eq.0) then
704 [ + + ]: 115648 : ucart_tmp(:,iatom,istep) = xcart(:,jatom,istep) - xcart_average(:,jatom)
705 : : else
706 [ + + ]: 440960 : ucart_tmp(:,iatom,istep) = xcart(:,jatom,istep) - xcart_ideal(:,iatom)
707 : : end if
708 : : end do
709 : : end do
710 [ - + ]: 44 : ABI_FREE(xred_average)
711 [ - + ]: 44 : ABI_FREE(xcart)
712 [ - + ]: 44 : ABI_FREE(xcart_ideal)
713 [ - + ]: 44 : ABI_FREE(xcart_average)
714 : :
715 : : ! Rearrangement of the fcart tabs in column --> MD%Forces
716 [ - + + - : 557736 : ABI_CALLOC(fcart_tmp,(3,MD%natom,MD%my_nstep))
- + + - +
- + - - +
- + + + +
+ + + ]
717 [ + + ]: 996 : do istep=1,MD%my_nstep
718 [ + + ]: 140148 : do iatom=1,MD%natom
719 [ + + ]: 557560 : fcart_tmp(:,iatom,istep) = MD%fcart(:,FromIdeal2Average(iatom),istep)
720 : : end do
721 : : end do
722 [ + + ]: 996 : do istep=1,MD%my_nstep
723 [ + + ]: 140148 : do jatom=1,MD%natom
724 [ + + ]: 557560 : do ii=1,3
725 : 417456 : jj = ii + 3*(jatom-1) + 3*MD%natom*(istep-1)
726 : 417456 : MD%Forces(jj) = fcart_tmp(ii,jatom,istep)
727 : 556608 : MD%ucart(ii,jatom,istep) = ucart_tmp(ii,jatom,istep)
728 : : enddo
729 : : enddo
730 : : enddo
731 [ - + ]: 44 : ABI_FREE(FromIdeal2Average)
732 [ - + ]: 44 : ABI_FREE(ucart_tmp)
733 [ - + ]: 44 : ABI_FREE(fcart_tmp)
734 : :
735 : : ! Define Rlatt_scaled, fulfilling the definition of mkphdos (ABINIT routine)
736 [ + + ]: 176 : do ii=1,3
737 [ + + ]: 572 : rprimd_md_tmp(ii,:) = Lattice%rprimd_md(ii,:) / Lattice%acell_unitcell(ii)
738 : : end do
739 [ + + ]: 6926 : do iatom=1,MD%natom
740 [ + + ]: 21812 : do iatcell=1,MD%natom_unitcell
741 : 21768 : call DGEMV('T',3,3,1.d0,rprimd_md_tmp,3,Rlatt_red(:,iatcell,iatom),1,0.d0,MD%Rlatt_scaled(:,iatcell,iatom),1)
742 : : end do
743 : : end do
744 : :
745 : : ! Find the symetry operation between 2 atoms
746 : 44 : call tdep_SearchS_1at(Invar,MPIdata,Sym,xred_ideal)
747 [ + + + + ]: 27572 : MD%xred_ideal(:,:)=xred_ideal(:,:)
748 [ - + ]: 44 : ABI_FREE(xred_ideal)
749 [ - + ]: 44 : ABI_FREE(Rlatt_red)
750 : :
751 : 44 : end subroutine tdep_MatchIdeal2Average
752 : :
753 : : !====================================================================================================
754 : :
755 : 44 : subroutine tdep_write_xred_average(Invar,MPIdata,Lattice,&
756 : 44 : xred_ideal,xred_center,&
757 : 44 : FromIdeal2Average)
758 : : type(atdep_dataset_type), intent(in) :: Invar
759 : : type(MPI_enreg_type),intent(in) :: MPIdata
760 : : type(Lattice_type),intent(in) :: Lattice
761 : : double precision,intent(in) :: xred_ideal(3,Invar%natom)
762 : : double precision,intent(in) :: xred_center(3,Invar%natom)
763 : : integer,intent(in),optional :: FromIdeal2Average(Invar%natom)
764 : :
765 : : integer :: unt
766 : : !integer :: natom,natom_unitcell
767 : : integer :: iatom,jatom,ii,jj
768 : : !logical :: with_xcart
769 : 44 : integer,allocatable :: ideal2average(:)
770 : : double precision :: rprimd(3,3)
771 : : double precision :: xred_C(3),xred_I(3),xcart_C(3),xcart_I(3)
772 : :
773 [ + - ]: 44 : if (MPIdata%iam_master) then
774 : :
775 [ + + + + ]: 572 : rprimd(:,:) = Lattice%rprimd_md(:,:)
776 : :
777 [ - + + - : 132 : ABI_MALLOC(ideal2average,(Invar%natom))
+ - + - -
+ - + ]
778 [ + + ]: 6926 : ideal2average(:)=0
779 [ + - ]: 44 : if (present(FromIdeal2Average)) then
780 [ + + ]: 6926 : ideal2average(:) = FromIdeal2Average(:)
781 : : else
782 [ # # ]: 0 : do iatom=1,Invar%natom
783 : 0 : ideal2average(iatom) = iatom
784 : : end do
785 : : end if
786 : :
787 : 44 : unt=31
788 : 44 : open(unit=unt,file=trim(Invar%output_prefix)//'_xred_average.xyz')
789 : 44 : write(unt,'(a,i4)') '# natom = ',Invar%natom
790 : 44 : write(unt,'(a,i4)') '# natom_unitcell = ',Invar%natom_unitcell
791 [ + - + + : 572 : write(unt,'(a,9(f4.1,1x))') '# multiplicity = ',((Lattice%multiplicity(ii,jj),jj=1,3),ii=1,3 )
+ - + + ]
792 : 44 : write(unt,'(a)') '#'
793 : :
794 : 44 : write(unt,'(a1,1x,a8,2x,a6,2x,2(a5,30x))') '#', 'position', 'iatom', 'xred ', 'xcart'
795 : 44 : write(unt,'(a)')''
796 : :
797 : 44 : xred_I = zero
798 : 44 : xred_C = zero
799 [ + + ]: 6926 : do iatom=1,Invar%natom
800 : 6882 : jatom = ideal2average(iatom)
801 [ + + ]: 27528 : xred_I = xred_ideal (:,iatom)
802 [ + + ]: 27528 : xred_C = xred_center(:,jatom)
803 : :
804 : 6882 : xcart_I(:)=zero
805 : 6882 : xcart_C(:)=zero
806 : 6882 : call DGEMV('T',3,3,1.d0,rprimd(:,:),3,xred_I,1,0.d0,xcart_I,1)
807 : 6882 : call DGEMV('T',3,3,1.d0,rprimd(:,:),3,xred_C,1,0.d0,xcart_C,1)
808 : :
809 : 6882 : write(unt,'(2x,a6,4x,i6,2x,3(f10.6,1x),2x,3(f10.6,1x))')'Ideal ',iatom,xred_I,xcart_I
810 : 6882 : write(unt,'(2x,a6,4x,i6,2x,3(f10.6,1x),2x,3(f10.6,1x))')'Center',jatom,xred_C,xcart_C
811 : 6926 : write(unt,'(a)')''
812 : :
813 : : end do
814 : :
815 : 44 : close(unt)
816 [ - + ]: 44 : ABI_FREE(ideal2average)
817 : : end if
818 : :
819 [ + - ]: 44 : end subroutine tdep_write_xred_average
820 : :
821 : : !====================================================================================================
822 : :
823 [ # # # # : 139152 : end module m_tdep_sampling
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
824 : : !!***
|