70
70
subroutine siesta_write_stress_pressure()
71
71
use m_steps, only: final
72
use siesta_geom, only: nsc
75
logical :: periodic(3)
77
! TODO, probably we need to use shaper...
78
! However, the shaper returns vectors which are
79
! not parallel to the actual lattice vectors and hence
80
! it becomes difficult to utilize them
81
! What to do for Gamma calculations?
82
periodic(:) = nsc(:) > 1
83
nD = count( periodic )
74
call write_stress_pressure_final()
86
call write_stress_pressure_final(nD, periodic)
76
call write_stress_pressure_not_final()
88
call write_stress_pressure_not_final(nD, periodic)
79
91
end subroutine siesta_write_stress_pressure
81
subroutine write_stress_pressure_not_final()
93
subroutine write_stress_pressure_not_final(nD, periodic)
89
101
use m_energies, only: FreeE
90
102
use m_stress, only: stress, kin_stress, mstress, tstress
104
integer, intent(in) :: nD ! dimensionality of the simulation
105
logical, intent(in) :: periodic(3)
94
108
real(dp):: Psol ! Pressure of "solid"
95
109
real(dp):: Press ! Pressure
96
110
real(dp):: ps(3,3) ! Auxiliary array
98
112
! Stress tensor and pressure:
100
114
! Write Voigt components of total stress tensor
142
156
' ',stress(:,1)*Ang**3/eV, &
143
157
' ',stress(:,2)*Ang**3/eV, &
144
158
' ',stress(:,3)*Ang**3/eV
162
call calc_stress_1D(periodic, stress, ps)
163
write(6,'(/,a,3(/,a,3f15.6))') &
164
'siesta: 1D stress tensor (static) (eV/Ang):', &
165
' ',ps(:,1)*Ang/eV, &
166
' ',ps(:,2)*Ang/eV, &
169
call calc_stress_2D(periodic, stress, ps)
170
write(6,'(/,a,3(/,a,3f15.6))') &
171
'siesta: 2D stress tensor (static) (eV/Ang**2):', &
172
' ',ps(:,1)*Ang**2/eV, &
173
' ',ps(:,2)*Ang**2/eV, &
174
' ',ps(:,3)*Ang**2/eV
146
177
Psol = - (stress(1,1) + stress(2,2) + stress(3,3)) / 3.0_dp
147
178
write(6,'(/,a,f20.8,a)') 'siesta: Pressure (static):', Psol/kBar, ' kBar'
157
188
' ',tstress(:,2)*Ang**3/eV, &
158
189
' ',tstress(:,3)*Ang**3/eV
193
call calc_stress_1D(periodic, tstress, ps)
194
write(6,'(/,a,3(/,a,3f15.6))') &
195
'siesta: 1D stress tensor (total) (eV/Ang):', &
196
' ',ps(:,1)*Ang/eV, &
197
' ',ps(:,2)*Ang/eV, &
200
call calc_stress_2D(periodic, tstress, ps)
201
write(6,'(/,a,3(/,a,3f15.6))') &
202
'siesta: 2D stress tensor (total) (eV/Ang**2):', &
203
' ',ps(:,1)*Ang**2/eV, &
204
' ',ps(:,2)*Ang**2/eV, &
205
' ',ps(:,3)*Ang**2/eV
160
208
Psol = - (tstress(1,1) + tstress(2,2) + tstress(3,3)) / 3.0_dp
161
209
write(6,'(/,a,f20.8,a)') 'siesta: Pressure (total):', Psol/kBar, ' kBar'
224
272
use m_iostruct, only: write_struct
225
273
use m_stress, only: stress, mstress, cstress
275
integer, intent(in) :: nD ! dimensionality of the simulation
276
logical, intent(in) :: periodic(3)
227
278
real(dp):: Pmol ! Molecular pressure (discounting Virial term)
228
279
real(dp):: Psol ! Pressure of "solid"
280
real(dp) :: ps(3,3) ! auxiliary array
230
283
! AG: Possible BUG
231
284
! The volume here refers to the "old" cell, and
241
294
dictref='siesta:stress', units='siestaUnits:eV_Ang__3')
299
call calc_stress_1D(periodic, stress, ps)
300
write(6,'(/,a,3(/,a,3f15.6))') &
301
'siesta: 1D stress tensor (static) (eV/Ang):', &
302
'siesta: ',ps(:,1)*Ang/eV, &
303
'siesta: ',ps(:,2)*Ang/eV, &
304
'siesta: ',ps(:,3)*Ang/eV
306
call calc_stress_2D(periodic, stress, ps)
307
write(6,'(/,a,3(/,a,3f15.6))') &
308
'siesta: 2D stress tensor (static) (eV/Ang**2):', &
309
'siesta: ',ps(:,1)*Ang**2/eV, &
310
'siesta: ',ps(:,2)*Ang**2/eV, &
311
'siesta: ',ps(:,3)*Ang**2/eV
244
314
! Print constrained stress tensor if different from unconstrained
245
315
if ( any(cstress /= stress ) ) then
246
316
write(6,'(/,a,3(/,a,3f12.6))') 'siesta: Constrained stress tensor (static) (eV/Ang**3):', &
252
322
dictref='siesta:cstress', &
253
323
units='siestaUnits:eV_Ang__3')
328
call calc_stress_1D(periodic, cstress, ps)
329
write(6,'(/,a,3(/,a,3f15.6))') &
330
'siesta: 1D constrained stress tensor (static) (eV/Ang):', &
331
'siesta: ',ps(:,1)*Ang/eV, &
332
'siesta: ',ps(:,2)*Ang/eV, &
333
'siesta: ',ps(:,3)*Ang/eV
335
call calc_stress_2D(periodic, cstress, ps)
336
write(6,'(/,a,3(/,a,3f15.6))') &
337
'siesta: 2D constrained stress tensor (static) (eV/Ang**2):', &
338
'siesta: ',ps(:,1)*Ang**2/eV, &
339
'siesta: ',ps(:,2)*Ang**2/eV, &
340
'siesta: ',ps(:,3)*Ang**2/eV
283
371
end subroutine write_stress_pressure_final
373
!< Transfer the stress from a chain calculation from eV / Ang ** 3 -> eV / Ang
374
subroutine calc_stress_1D(periodic, stress, stress_1d)
376
! TODO for varcel it isn't necessarily volume_of_some_cell == VOLUME(ucell)
377
use siesta_geom, only: volume_of_some_cell, ucell
379
logical, intent(in) :: periodic(3)
380
real(dp), intent(in) :: stress(3,3)
381
real(dp), intent(out) :: stress_1d(3,3)
385
stress_1d(:,:) = 0._dp
386
if ( periodic(1) ) then
387
stress_1d(1,1) = stress(1,1)
388
vlen = sqrt( dot_product(ucell(:,1), ucell(:,1)) )
389
else if ( periodic(2) ) then
390
stress_1d(2,2) = stress(2,2)
391
vlen = sqrt( dot_product(ucell(:,2), ucell(:,2)) )
392
else if ( periodic(3) ) then
393
stress_1d(3,3) = stress(3,3)
394
vlen = sqrt( dot_product(ucell(:,3), ucell(:,3)) )
396
call die('write_subs_pressure: 1D error in periodic determination')
399
stress_1d(:,:) = stress_1d(:, :) * volume_of_some_cell / vlen
401
end subroutine calc_stress_1D
403
!< Transfer the stress from a chain calculation from eV / Ang ** 3 -> eV / Ang ** 2
404
subroutine calc_stress_2D(periodic, stress, stress_2d)
406
! TODO for varcel it isn't necessarily volume_of_some_cell == VOLUME(ucell)
407
use siesta_geom, only: volume_of_some_cell, ucell
409
logical, intent(in) :: periodic(3)
410
real(dp), intent(in) :: stress(3,3)
411
real(dp), intent(out) :: stress_2d(3,3)
412
real(dp) :: vcross(3)
414
stress_2d(:,:) = stress(:,:)
415
if ( periodic(1) .and. periodic(2) ) then
416
stress_2d(:,3) = 0._dp
417
stress_2d(3,:) = 0._dp
418
call cross(ucell(:,1), ucell(:,2), vcross)
419
else if ( periodic(1) .and. periodic(3) ) then
420
stress_2d(:,2) = 0._dp
421
stress_2d(2,:) = 0._dp
422
call cross(ucell(:,1), ucell(:,3), vcross)
423
else if ( periodic(2) .and. periodic(3) ) then
424
stress_2d(:,1) = 0._dp
425
stress_2d(1,:) = 0._dp
426
call cross(ucell(:,2), ucell(:,3), vcross)
428
call die('write_subs_pressure: 2D error in periodic determination')
431
stress_2d(:,:) = stress_2d(:,:) * volume_of_some_cell / sqrt( dot_product(vcross, vcross) )
433
end subroutine calc_stress_2D
285
435
end module write_subs_pressure