LCOV - code coverage report
Current view: top level - src/77_ddb - m_ddb_piezo.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 86.1 % 360 310
Test Date: 2026-11-09 20:57:54 Functions: 100.0 % 1 1
Branches: 88.1 % 388 342

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_ddb_piezo
       2                 :             : !! NAME
       3                 :             : !!  m_ddb_piezo
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!
       7                 :             : !! COPYRIGHT
       8                 :             : !!  Copyright (C) 1999-2026 ABINIT group (XW)
       9                 :             : !!  This file is distributed under the terms of the
      10                 :             : !!  GNU General Public License, see ~abinit/COPYING
      11                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      12                 :             : !!
      13                 :             : !! SOURCE
      14                 :             : 
      15                 :             : #if defined HAVE_CONFIG_H
      16                 :             : #include "config.h"
      17                 :             : #endif
      18                 :             : 
      19                 :             : #include "abi_common.h"
      20                 :             : 
      21                 :             : module m_ddb_piezo
      22                 :             : 
      23                 :             :  use defs_basis
      24                 :             :  use m_abicore
      25                 :             :  use m_errors
      26                 :             :  use m_nctk
      27                 :             :  use netcdf
      28                 :             : 
      29                 :             :  use m_fstrings,       only : sjoin, itoa
      30                 :             :  use m_hide_lapack,    only : matrginv
      31                 :             :  use m_anaddb_dataset, only : anaddb_dataset_type
      32                 :             : 
      33                 :             :  implicit none
      34                 :             : 
      35                 :             :  private
      36                 :             : !!***
      37                 :             : 
      38                 :             :  public :: ddb_piezo
      39                 :             : !!***
      40                 :             : 
      41                 :             : contains
      42                 :             : !!***
      43                 :             : 
      44                 :             : !!****f* ABINIT/ddb_piezo
      45                 :             : !!
      46                 :             : !! NAME
      47                 :             : !! ddb_piezo
      48                 :             : !!
      49                 :             : !! FUNCTION
      50                 :             : !! Get the piezoelectric tensor (e-tensor), both clamped ion and relaxed ion;
      51                 :             : !! Compute physical(relaxed ion) piezoeletric (d, g, h) tensors;
      52                 :             : !! Compute relaxed ion and free stress dielectric tensor;
      53                 :             : !! Compute relaxed ion elastic and compliance tensors under fixed
      54                 :             : !! displacement field boundary conditions.
      55                 :             : !!
      56                 :             : !! INPUTS
      57                 :             : !! inp= (derived datatype) contains all the input variables
      58                 :             : !! blkval(2,3,mpert,3,mpert,nblok)=
      59                 :             : !!   second derivatives of total energy with respect to electric fields
      60                 :             : !!   atom displacements,strain,...... all in cartesian coordinates
      61                 :             : !! dielt_rlx=relaxed ion dielectric tensor
      62                 :             : !! iblok= bolk number in DDB file contains 2 derivative of energy
      63                 :             : !! instrain=force response internal strain tensor
      64                 :             : !! iout=out file number
      65                 :             : !! mpert=maximum number of ipert
      66                 :             : !! natom=number of atoms in unit cell
      67                 :             : !! nblok=number of total bloks in DDB file
      68                 :             : !! ucvol=unit cell volume
      69                 :             : !! ncid=the id of the open NetCDF file. Set to nctk_noid if netcdf output is not wanted.
      70                 :             : !!
      71                 :             : !! OUTPUT
      72                 :             : !! piezo = piezoelectric tensor
      73                 :             : !!
      74                 :             : !! NOTES
      75                 :             : !! The elastic (compliance) tensors calculated here are under fixed D-field boundary
      76                 :             : !! condition, which include piezoelectric corrections to the elastic (compliance)
      77                 :             : !! tensors calculated in ddb_elast.F90 whose boundary condition is fixed E-field.
      78                 :             : !!
      79                 :             : !! SOURCE
      80                 :             : 
      81                 :           5 : subroutine ddb_piezo(inp,blkval,dielt_rlx,elast,iblok,instrain,iout,mpert,natom,nblok,piezo,ucvol,ncid)
      82                 :             : 
      83                 :             : !Arguments-------------------------------------------
      84                 :             : !scalars
      85                 :             :  integer,intent(in) :: iblok,iout,mpert,natom,nblok,ncid
      86                 :             :  real(dp),intent(in) :: ucvol
      87                 :             :  type(anaddb_dataset_type),intent(in) :: inp
      88                 :             : !arrays
      89                 :             :  real(dp),intent(in) :: blkval(2,3,mpert,3,mpert,nblok),dielt_rlx(3,3)
      90                 :             :  real(dp),intent(in) :: elast(6,6),instrain(3*natom,6)
      91                 :             :  real(dp),intent(out) :: piezo(6,3)
      92                 :             : 
      93                 :             : !Local variables---------------------------------------
      94                 :             : !scalars
      95                 :             :  integer :: idir1,idir2,ier,ii1,ii2,ipert1,ipert2,ivarA,ivarB,ncerr
      96                 :             :  character(len=500) :: message
      97                 :             :  logical :: iwrite
      98                 :             : !arrays
      99                 :          10 :  real(dp) :: Amatr(3*natom-3,3*natom-3),Apmatr(3*natom,3*natom)
     100                 :          10 :  real(dp) :: Bmatr(2,((3*natom-3)*(3*natom-2))/2)
     101                 :          10 :  real(dp) :: Bpmatr(2,(3*natom*(3*natom+1))/2),Cmatr(3*natom-3,3*natom-3)
     102                 :          10 :  real(dp) :: Cpmatr(3*natom,3*natom),Nmatr(3*natom,3*natom),beta_tensor(3,3)
     103                 :             :  real(dp) :: compliance(6,6),compliance_dis(6,6)
     104                 :          10 :  real(dp) :: d2cart_relaxed(2,3,mpert,3,mpert,nblok),d_tensor(6,3)
     105                 :          10 :  real(dp) :: dielt_stress(3,3),eigval(3*natom-3),eigvalp(3*natom)
     106                 :          10 :  real(dp) :: eigvec(2,3*natom-3,3*natom-3),eigvecp(2,3*natom,3*natom)
     107                 :             :  real(dp) :: elast_dis(6,6),g_tensor(3,6),h_tensor(3,6)
     108                 :          10 :  real(dp) :: kmatrix(3*natom,3*natom),new1(6,3*natom),piezo_clamped(6,3)
     109                 :          10 :  real(dp) :: piezo_correction(6,3),piezo_relaxed(6,3),zhpev1(2,2*3*natom-4)
     110                 :          10 :  real(dp) :: zhpev1p(2,2*3*natom-1),zhpev2(3*3*natom-5),zhpev2p(3*3*natom-2)
     111                 :          10 :  real(dp) :: zstar1(3,3*natom),zstar2(3*natom,3)
     112                 :             : 
     113                 :             : !****************************************************************
     114                 :             : 
     115                 :             : !extraction of the clamped ion piezoelectric constants from blkvals
     116                 :           5 :  iwrite = iout > 0
     117                 :             : 
     118                 :             : !the six strain perturbations
     119         [ +  + ]:          35 :  do ivarA=1,6
     120                 :             : !  the three E-field perturbations
     121         [ +  + ]:         125 :    do ivarB=1,3
     122                 :             : !    judge if the ivarA>3 or not
     123         [ +  + ]:          90 :      if(ivarA>3) then
     124                 :          45 :        idir1=ivarA-3
     125                 :          45 :        ipert1=natom+4
     126                 :             : !      for the shear part of the strain
     127                 :             :      else if(ivarA<=3) then
     128                 :          45 :        idir1=ivarA
     129                 :          45 :        ipert1=natom+3
     130                 :             : !      for the diagonal part of strain
     131                 :             :      end if
     132                 :          90 :      idir2=ivarB
     133                 :          90 :      ipert2=natom+2 !for the E-field perturbation only
     134                 :         120 :      piezo(ivarA,ivarB)=blkval(1,idir2,ipert2,idir1,ipert1,iblok)
     135                 :             :    end do
     136                 :             :  end do
     137                 :             : 
     138                 :             : !consider the volume and the -Qe before the piezo
     139                 :             : !according to the (30) in notes, the units are tranformed from atomic units to the SI units
     140         [ +  + ]:          35 :  do ivarA=1,6
     141         [ +  + ]:         125 :    do ivarB=1,3
     142                 :         120 :      piezo(ivarA,ivarB)=piezo(ivarA,ivarB)*AmuBohr2_Cm2
     143                 :             : !    now it is in the SI unit
     144                 :             :    end do
     145                 :             :  end do
     146                 :             : 
     147                 :             : !give the values of d2cart_relaxed as the same as blkval
     148                 :             : !and also give the initial values of piezo_clamped and piezo_relaxed
     149   [ +  +  +  +  :       25911 :  d2cart_relaxed(:,:,:,:,:,:)=blkval(:,:,:,:,:,:)
          +  +  +  +  +  
                +  +  + ]
     150                 :           5 :  piezo_clamped(:,:)=piezo(:,:)
     151                 :             : 
     152                 :             : !********************************************************************
     153                 :             : !print the main results of the piezoelectric constants
     154         [ +  - ]:           5 :  if(inp%piezoflag==1.or.inp%piezoflag==3 .or. inp%piezoflag==7)then
     155                 :           5 :    write(message,'(3a)')ch10,' Proper piezoelectric constants (clamped ion) (unit:c/m^2)',ch10
     156                 :           5 :    call wrtout(std_out,message,'COLL')
     157                 :             : 
     158         [ +  + ]:          35 :    do ivarA=1,6
     159                 :          35 :      write(std_out,'(3f16.8)')piezo_clamped(ivarA,1),piezo_clamped(ivarA,2),piezo_clamped(ivarA,3)
     160                 :             :    end do
     161                 :             : 
     162                 :           5 :    call wrtout(iout,message,'COLL')
     163         [ -  + ]:           5 :    if (iwrite) then
     164         [ +  + ]:          35 :      do ivarA=1,6
     165                 :          35 :        write(iout,'(3f16.8)')piezo_clamped(ivarA,1),piezo_clamped(ivarA,2),piezo_clamped(ivarA,3)
     166                 :             :      end do
     167                 :             :    end if
     168                 :             :  end if
     169                 :             : 
     170                 :             : !the next is the calculation of the relaxed ion piezoelectric constants
     171                 :             : !first extract the K(force constant) matrix
     172                 :             : 
     173                 :             : !if (piezoflag==2 .or. inp%piezoflag==3)then
     174                 :             : !extracting force matrix at gamma
     175         [ +  + ]:          19 :  do ipert1=1,natom
     176         [ +  + ]:          61 :    do ii1=1,3
     177                 :          42 :      ivarA=ii1+3*(ipert1-1)
     178         [ +  + ]:         188 :      do ipert2=1,natom
     179         [ +  + ]:         570 :        do ii2=1,3
     180                 :         396 :          ivarB=ii2+3*(ipert2-1)
     181                 :         528 :          kmatrix(ivarA,ivarB)=blkval(1,ii1,ipert1,ii2,ipert2,iblok)
     182                 :             :        end do
     183                 :             :      end do
     184                 :             :    end do
     185                 :             :  end do
     186                 :             : 
     187   [ +  +  +  + ]:         443 :  Apmatr(:,:)=kmatrix(:,:)
     188                 :             : 
     189                 :             : !DEBUG
     190                 :             : !kmatrix values
     191                 :             : !write(std_out,'(/,a,/)')'the force constant matrix'
     192                 :             : !do ivarA=1,3*natom
     193                 :             : !write(std_out,'(/)')
     194                 :             : !do ivarB=1,3*natom
     195                 :             : !write(std_out,'(es16.6)')kmatrix(ivarB,ivarA)
     196                 :             : !end do
     197                 :             : !end do
     198                 :             : !ENDDEBUG
     199                 :             : 
     200   [ +  +  +  + ]:         443 :  Nmatr(:,:)=zero
     201                 :             : 
     202         [ +  + ]:          47 :  do ivarA=1,3*natom
     203         [ +  + ]:         443 :    do ivarB=1,3*natom
     204   [ +  +  +  + ]:         396 :      if (mod(ivarA,3)==0 .and. mod(ivarB,3)==0) Nmatr(ivarA,ivarB)=one
     205   [ +  +  +  + ]:         396 :      if (mod(ivarA,3)==1 .and. mod(ivarB,3)==1) Nmatr(ivarA,ivarB)=one
     206   [ +  +  +  + ]:         438 :      if (mod(ivarA,3)==2 .and. mod(ivarB,3)==2) Nmatr(ivarA,ivarB)=one
     207                 :             :    end do
     208                 :             :  end do
     209                 :             : 
     210                 :             : !DEBUG
     211                 :             : !do ivarA=1,3*natom
     212                 :             : !write(std_out,'(/)')
     213                 :             : !do ivarB=1,3*natom
     214                 :             : !write(std_out,'(es16.6)')Nmatr(ivarB,ivarA)
     215                 :             : !end do
     216                 :             : !end do
     217                 :             : !ENDDEBUG
     218                 :             : 
     219                 :             : !starting the pseudoinversing processes
     220                 :             : !then get the eigenvectors of the big matrix,give values to matrixBp
     221                 :             :  ii1=1
     222         [ +  + ]:          47 :  do ivarA=1,3*natom
     223         [ +  + ]:         266 :    do ivarB=1,ivarA
     224                 :         219 :      Bpmatr(1,ii1)=Nmatr(ivarB,ivarA)
     225                 :         261 :      ii1=ii1+1
     226                 :             :    end do
     227                 :             :  end do
     228                 :             : 
     229                 :             : !the imaginary part of the force matrix
     230         [ +  + ]:         224 :  Bpmatr(2,:)=zero
     231                 :             : !then call the subroutines CHPEV and ZHPEV to get the eigenvectors
     232                 :           5 :  call ZHPEV ('V','U',3*natom,Bpmatr,eigvalp,eigvecp,3*natom,zhpev1p,zhpev2p,ier)
     233         [ -  + ]:           5 :  ABI_CHECK(ier == 0, sjoin("ZHPEV returned:", itoa(ier)))
     234                 :             : 
     235                 :             : !DEBUG
     236                 :             : !the eigenval and eigenvec
     237                 :             : !write(std_out,'(/,a,/)')'the eigenvalues and eigenvectors'
     238                 :             : !do ivarA=1,3*natom
     239                 :             : !write(std_out,'(/)')
     240                 :             : !write(std_out,'(es16.6)')eigvalp(ivarA)
     241                 :             : !end do
     242                 :             : !do ivarA=1,3*natom
     243                 :             : !write(std_out,'(/)')
     244                 :             : !do ivarB=1,3*natom
     245                 :             : !write(std_out,'(es16.6)')eigvecp(1,ivarB,ivarA)
     246                 :             : !end do
     247                 :             : !end do
     248                 :             : !ENDDEBUG
     249                 :             : 
     250                 :             : !then do the muplication to get the reduced matrix,in two steps
     251                 :             : !After this the force constant matrix is decouple in two bloks,
     252                 :             : !accoustic and optical ones
     253   [ +  +  +  + ]:         443 :  Cpmatr(:,:)=zero
     254         [ +  + ]:          47 :  do ivarA=1,3*natom
     255         [ +  + ]:         443 :    do ivarB=1,3*natom
     256         [ +  + ]:        4542 :      do ii1=1,3*natom
     257                 :             :        Cpmatr(ivarA,ivarB)=Cpmatr(ivarA,ivarB)+eigvecp(1,ii1,ivarA)*&
     258                 :        4500 : &       Apmatr(ii1,ivarB)
     259                 :             :      end do
     260                 :             :    end do
     261                 :             :  end do
     262                 :             : 
     263   [ +  +  +  + ]:         443 :  Apmatr(:,:)=zero
     264         [ +  + ]:          47 :  do ivarA=1,3*natom
     265         [ +  + ]:         443 :    do ivarB=1,3*natom
     266         [ +  + ]:        4542 :      do ii1=1,3*natom
     267                 :             :        Apmatr(ivarA,ivarB)=Apmatr(ivarA,ivarB)+Cpmatr(ivarA,ii1)*&
     268                 :        4500 : &       eigvecp(1,ii1,ivarB)
     269                 :             :      end do
     270                 :             :    end do
     271                 :             :  end do
     272                 :             : 
     273                 :             : !DEBUG
     274                 :             : !the blok diago
     275                 :             : !write(std_out,'(/,a,/)')'Apmatr'
     276                 :             : !do ivarA=1,3*natom
     277                 :             : !write(std_out,'(/)')
     278                 :             : !do ivarB=1,3*natom
     279                 :             : !write(std_out,'(es16.6)')Apmatr(ivarA,ivarB)
     280                 :             : !end do
     281                 :             : !end do
     282                 :             : !ENDDEBUG
     283                 :             : 
     284                 :             : !check the last three eigenvalues whether too large or not
     285                 :             :  ivarB=0
     286         [ +  + ]:          20 :  do ivarA=3*natom-2,3*natom
     287         [ +  + ]:          20 :    if (ABS(Apmatr(ivarA,ivarA))>tol6) ivarB=1
     288                 :             :  end do
     289         [ +  + ]:           5 :  if(ivarB==1)then
     290                 :           4 :    write(message,'(a,a,a,a,a,a,a,a,a,a,3es16.6)')ch10,&
     291                 :           4 : &   ' ddb_piezo : WARNING -',ch10,&
     292                 :           4 : &   '  Acoustic sum rule violation met : the eigenvalues of accoustic mode',ch10,&
     293                 :           4 : &   '  are too large at Gamma point',ch10,&
     294                 :           4 : &   '  Increase cutoff energy or k-points sampling.',ch10,&
     295                 :           8 : &   '  The three eigenvalues are:',Apmatr(3*natom-2,3*natom-2),Apmatr(3*natom-1,natom-1),Apmatr(3*natom,3*natom)
     296                 :           4 :    call wrtout(std_out, message, 'COLL')
     297                 :           4 :    call wrtout(iout,message,'COLL')
     298                 :             :  end if
     299                 :             : 
     300                 :             : !give the value of reduced matrix form Apmatr to Amatr
     301         [ +  + ]:          32 :  do ivarA=1,3*natom-3
     302         [ +  + ]:         221 :    do ivarB=1,3*natom-3
     303                 :         216 :      Amatr(ivarA,ivarB)=Apmatr(ivarA,ivarB)
     304                 :             :    end do
     305                 :             :  end do
     306                 :             : !now the reduced matrix is in the matrixA, the convert it
     307                 :             : !first give the give the value of matixB from matrixA
     308                 :             :  ii1=1
     309         [ +  + ]:          32 :  do ivarA=1,3*natom-3
     310         [ +  + ]:         140 :    do ivarB=1,ivarA
     311                 :         108 :      Bmatr(1,ii1)=Amatr(ivarB,ivarA)
     312                 :         135 :      ii1=ii1+1
     313                 :             :    end do
     314                 :             :  end do
     315         [ +  + ]:         113 :  Bmatr(2,:)=zero
     316                 :             : 
     317                 :             : !call the subroutines CHPEV and ZHPEV to get the eigenvectors and the eigenvalues
     318                 :           5 :  call ZHPEV ('V','U',3*natom-3,Bmatr,eigval,eigvec,3*natom-3,zhpev1,zhpev2,ier)
     319         [ -  + ]:           5 :  ABI_CHECK(ier == 0, sjoin("ZHPEV returned:", itoa(ier)))
     320                 :             : 
     321                 :             : !check the unstable phonon modes, if the first is negative then print warning message
     322         [ -  + ]:           5 :  if(eigval(1)<-1.0*tol8)then
     323                 :           0 :    write(message,'(a,a,a,a,a,a)') ch10,&
     324                 :           0 : &   ' ddb_piezo : WARNING -',ch10,&
     325                 :           0 : &   '  Unstable eigenvalue detected in force constant matrix at Gamma point',ch10,&
     326                 :           0 : &   '  The system under calculation is physically unstable.'
     327                 :           0 :    call wrtout(std_out, message, 'COLL')
     328                 :           0 :    call wrtout(iout,message,'COLL')
     329                 :             :  end if
     330                 :             : 
     331                 :             : !do the matrix multiplication to get pseudoinverse inverse matrix
     332   [ +  +  +  + ]:         221 :  Cmatr(:,:)=zero
     333   [ +  +  +  + ]:         221 :  Amatr(:,:)=zero
     334         [ +  + ]:          32 :  do ivarA=1,3*natom-3
     335                 :          32 :    Cmatr(ivarA,ivarA)=one/eigval(ivarA)
     336                 :             :  end do
     337                 :             : 
     338         [ +  + ]:          32 :  do ivarA=1,3*natom-3
     339         [ +  + ]:         221 :    do ivarB=1,3*natom-3
     340         [ +  + ]:        1755 :      do ii1=1,3*natom-3
     341                 :             :        Amatr(ivarA,ivarB)=Amatr(ivarA,ivarB)+eigvec(1,ivarA,ii1)*&
     342                 :        1728 : &       Cmatr(ii1,ivarB)
     343                 :             :      end do
     344                 :             :    end do
     345                 :             :  end do
     346                 :             : 
     347                 :             : !the second mulplication
     348   [ +  +  +  + ]:         221 :  Cmatr(:,:)=zero
     349         [ +  + ]:          32 :  do ivarA=1,3*natom-3
     350         [ +  + ]:         221 :    do ivarB=1,3*natom-3
     351         [ +  + ]:        1755 :      do ii1=1,3*natom-3
     352                 :             :        Cmatr(ivarA,ivarB)=Cmatr(ivarA,ivarB)+&
     353                 :        1728 : &       Amatr(ivarA,ii1)*eigvec(1,ivarB,ii1)
     354                 :             :      end do
     355                 :             :    end do
     356                 :             :  end do
     357                 :             : 
     358                 :             : !DEBUG
     359                 :             : !write(std_out,'(/,a,/)')'the pseudo inverse of the force matrix'
     360                 :             : !do ivarA=1,3*natom
     361                 :             : !write(std_out,'(/)')
     362                 :             : !do ivarB=1,3*natom
     363                 :             : !write(std_out,'(es16.6)')Cmatr(ivarA,ivarB)
     364                 :             : !end do
     365                 :             : !end do
     366                 :             : !ENDDEBUG
     367                 :             : 
     368                 :             : !so now the inverse of the reduced matrix is in the matrixC
     369                 :             : !now do another mulplication to get the pseudoinverse of the original
     370   [ +  +  +  + ]:         443 :  Cpmatr(:,:)=zero
     371   [ +  +  +  + ]:         443 :  Apmatr(:,:)=zero
     372         [ +  + ]:          32 :  do ivarA=1,3*natom-3
     373         [ +  + ]:         221 :    do ivarB=1,3*natom-3
     374                 :         216 :      Cpmatr(ivarA,ivarB)=Cmatr(ivarA,ivarB)
     375                 :             :    end do
     376                 :             :  end do
     377                 :             : 
     378                 :             : !now times the eigvecp
     379         [ +  + ]:          47 :  do ivarA=1,3*natom
     380         [ +  + ]:         443 :    do ivarB=1,3*natom
     381         [ +  + ]:        4542 :      do ii1=1,3*natom
     382                 :        4500 :        Apmatr(ivarA,ivarB)=Apmatr(ivarA,ivarB)+eigvecp(1,ivarA,ii1)*Cpmatr(ii1,ivarB)
     383                 :             :      end do
     384                 :             :    end do
     385                 :             :  end do
     386                 :             : 
     387   [ +  +  +  + ]:         443 :  Cpmatr(:,:)=zero
     388         [ +  + ]:          47 :  do ivarA=1,3*natom
     389         [ +  + ]:         443 :    do ivarB=1,3*natom
     390         [ +  + ]:        4542 :      do ii1=1,3*natom
     391                 :             :        Cpmatr(ivarA,ivarB)=Cpmatr(ivarA,ivarB)+&
     392                 :        4500 : &       Apmatr(ivarA,ii1)*eigvecp(1,ivarB,ii1)
     393                 :             :      end do
     394                 :             :    end do
     395                 :             :  end do
     396                 :             : 
     397                 :             : !now the inverse in in Cpmatr
     398   [ +  +  +  + ]:         443 :  kmatrix(:,:)=Cpmatr(:,:)
     399                 :             : !transfer the inverse of k-matrix back to the k matrix
     400                 :             : !so now the inverse of k matrix is in the kmatrix
     401                 :             : !ending the part for pseudoinversing the K matrix
     402                 :             : 
     403                 :             : !we still need the z-star matrix
     404         [ +  + ]:          20 :  do idir1=1,3
     405                 :             :    d2cart_relaxed(1,idir1,natom+2,idir1,natom+2,iblok)=&
     406                 :          20 : &   d2cart_relaxed(1,idir1,natom+2,idir1,natom+2,iblok)-1.0_dp
     407                 :             :  end do
     408                 :             : 
     409         [ +  + ]:          20 :  do idir1=1,3
     410         [ +  + ]:          65 :    do idir2=1,3
     411         [ +  + ]:         150 :      do ii1=1,2
     412                 :             :        d2cart_relaxed(ii1,idir1,natom+2,idir2,natom+2,iblok)=&
     413                 :         135 : &       d2cart_relaxed(ii1,idir1,natom+2,idir2,natom+2,iblok)/four_pi
     414                 :             :      end do
     415                 :             :    end do
     416                 :             :  end do
     417                 :             : 
     418         [ +  + ]:          20 :  do ivarA=1,3
     419                 :          15 :    idir1=ivarA
     420                 :          15 :    ipert1=natom+2
     421         [ +  + ]:          62 :    do ipert2=1,natom
     422         [ +  + ]:         183 :      do idir2=1,3
     423                 :         126 :        ivarB=idir2+3*(ipert2-1)
     424                 :         168 :        zstar1(ivarA,ivarB)=d2cart_relaxed(1,idir1,ipert1,idir2,ipert2,iblok)
     425                 :             :      end do
     426                 :             :    end do
     427                 :             :  end do
     428                 :             : 
     429                 :             : !then get the inverse of the zstar1 for zstar2(3*natom,3)
     430         [ +  + ]:          47 :  do ivarA=1,3*natom
     431         [ +  + ]:         173 :    do ivarB=1,3
     432                 :         168 :      zstar2(ivarA,ivarB)=zstar1(ivarB,ivarA)
     433                 :             :    end do
     434                 :             :  end do
     435                 :             : !the the matrix I need for the multiplication is in kmatrix and zstar2
     436                 :             : 
     437                 :             : !the first matrix mulplication
     438   [ +  +  +  + ]:         299 :  new1(:,:)=zero
     439         [ +  + ]:          35 :  do ii1=1,6
     440         [ +  + ]:         287 :    do ii2=1,3*natom
     441         [ +  + ]:        2658 :      do ivarA=1,3*natom
     442                 :             :        new1(ii1,ii2)=new1(ii1,ii2)+instrain(ivarA,ii1)*&
     443                 :        2628 : &       kmatrix(ivarA,ii2)
     444                 :             :      end do
     445                 :             :    end do
     446                 :             :  end do
     447                 :             : 
     448                 :             : !do the second matrix mulplication
     449                 :           5 :  piezo_correction(:,:)=zero
     450         [ +  + ]:          35 :  do ii1=1,6
     451         [ +  + ]:         125 :    do ii2=1,3
     452         [ +  + ]:         876 :      do ivarA=1,3*natom
     453                 :             :        piezo_correction(ii1,ii2)=piezo_correction(ii1,ii2)+&
     454                 :         846 : &       new1(ii1,ivarA)* zstar2(ivarA,ii2)
     455                 :             :      end do
     456                 :             :    end do
     457                 :             :  end do
     458                 :             : 
     459                 :             : !then consider the volume and the change the unit form atomic to SI
     460         [ +  + ]:          35 :  do ii1=1,6
     461         [ +  + ]:         125 :    do ii2=1,3
     462                 :          90 :      piezo_correction(ii1,ii2)= (piezo_correction(ii1,ii2) / ucvol)*AmuBohr2_Cm2
     463                 :         120 :      piezo_relaxed(ii1,ii2)=piezo_clamped(ii1,ii2)+ piezo_correction(ii1,ii2)
     464                 :             :    end do
     465                 :             :  end do
     466                 :             : !end the calculation of piezoelectric constants
     467                 :             : 
     468                 :             : !then print out the relaxed ion piezoelectric constants
     469                 :             : 
     470         [ +  - ]:           5 :  if(inp%piezoflag==2.or.inp%piezoflag==3 .or. inp%piezoflag==7)then
     471         [ -  + ]:           5 :    if(inp%instrflag==0)then
     472                 :           0 :      write(message,'(a,a,a,a,a,a,a,a)' )ch10,&
     473                 :           0 : &     ' WARNING: in order to get the piezoelectric tensor (relaxed ion), ',ch10,&
     474                 :           0 : &     '  one needs information about internal strain ',ch10,&
     475                 :           0 : &     '  one should set  instrflag==1;',ch10,&
     476                 :           0 : &     '  otherwise the program will continue but will give wrong values.'
     477                 :           0 :      call wrtout(std_out,message,'COLL')
     478                 :           0 :      call wrtout(iout,message,'COLL')
     479                 :             :    end if
     480                 :           5 :    write(message,'(3a)')ch10,' Proper piezoelectric constants (relaxed ion) (unit:c/m^2)',ch10
     481                 :           5 :    call wrtout(std_out,message,'COLL')
     482         [ +  + ]:          35 :    do ivarA=1,6
     483                 :          35 :      write(std_out,'(3f16.8)')piezo_relaxed(ivarA,1),piezo_relaxed(ivarA,2),piezo_relaxed(ivarA,3)
     484                 :             :    end do
     485                 :             : 
     486                 :           5 :    call wrtout(iout,message,'COLL')
     487         [ +  - ]:           5 :    if (iwrite) then
     488         [ +  + ]:          35 :      do ivarA=1,6
     489                 :          35 :        write(iout,'(3f16.8)')piezo_relaxed(ivarA,1),piezo_relaxed(ivarA,2),piezo_relaxed(ivarA,3)
     490                 :             :      end do
     491                 :             :    end if
     492                 :             :  end if
     493                 :             : 
     494                 :             : !DEBUG
     495                 :             : !check the values of the relaxed ion dielectric tensor
     496                 :             : !write(message,'(a,a,a,a)')ch10,'debug the dielt tensor values ',&
     497                 :             : !&  '(unit:c/m^2)',ch10
     498                 :             : !call wrtout(std_out,message,'COLL')
     499                 :             : !do ivarA=1,3
     500                 :             : !write(std_out,'(3f16.8)')dielt_rlx(ivarA,1),dielt_rlx(ivarA,2),dielt_rlx(ivarA,3)
     501                 :             : !end do
     502                 :             : !END DEBUG
     503                 :             : 
     504                 :             : !DEBUG
     505                 :             : !print the relaxed ion elast tensor
     506                 :             : !write(message,'(a,a,a,a)')ch10,' debugElastic Tensor(relaxed ion)',&
     507                 :             : !&  '(unit:10^2GP,VOIGT notation):',ch10
     508                 :             : !call wrtout(std_out,message,'COLL')
     509                 :             : !do ivarA=1,6
     510                 :             : !write(std_out,'(6f12.7)')elast(ivarA,1)/100.00_dp,elast(ivarA,2)/100.00_dp,&
     511                 :             : !&   elast(ivarA,3)/100.00_dp,elast(ivarA,4)/100.00_dp,&
     512                 :             : !&   elast(ivarA,5)/100.00_dp,elast(ivarA,6)/100.00_dp
     513                 :             : !end do
     514                 :             : !ENDDEBUG
     515                 :             : 
     516                 :             : !Start to compute the piezoelectric d tensors
     517                 :             : !first initialize the d_tensor values
     518                 :             : !first make sure the elastic tensor is not zero
     519                 :           5 :  d_tensor(:,:)=zero
     520         [ +  - ]:           5 :  if(inp%elaflag>1)then
     521                 :             : !  then get the relaxed ion compliance tensor
     522                 :           5 :    compliance(:,:)=elast(:,:)
     523                 :           5 :    call matrginv(compliance,6,6)
     524         [ +  + ]:          35 :    do ivarA=1,6
     525         [ +  + ]:         125 :      do ivarB=1,3
     526         [ +  + ]:         660 :        do ii1=1,6
     527                 :             :          d_tensor(ivarA,ivarB)=d_tensor(ivarA,ivarB)+compliance(ivarA,ii1)*&
     528                 :         630 : &         piezo_relaxed(ii1,ivarB)
     529                 :             :        end do
     530                 :             :      end do
     531                 :             :    end do
     532                 :             : !  then convert in to the right unit pc/N
     533         [ +  + ]:          35 :    do ivarA=1,6
     534         [ +  + ]:         125 :      do ivarB=1,3
     535                 :         120 :        d_tensor(ivarA,ivarB)=1000*d_tensor(ivarA,ivarB)
     536                 :             :      end do
     537                 :             :    end do
     538                 :             :  end if
     539                 :             : 
     540                 :             : !then print out the results of d tensor in log and output files
     541         [ +  + ]:           5 :  if(inp%piezoflag==4 .or. inp%piezoflag==7)then
     542   [ +  -  +  -  :           2 :    if(inp%instrflag==0 .or. inp%elaflag==0 .or. inp%elaflag==1)then
                   -  + ]
     543                 :           0 :      write(message,'(12a)' )ch10,&
     544                 :           0 : &     ' WARNING:in order to get the piezoelectric d tensor(relaxed ion),', ch10,&
     545                 :           0 : &     ' one needs the elastic tensor(relaxed ion) and piezoelectric e tensor',ch10,&
     546                 :           0 : &     ' the latter needs the information of internal strain;',ch10,&
     547                 :           0 : &     ' please check that both instrflag and elaflag are set to correct numbers',ch10,&
     548                 :           0 : &     ' (elaflag= 2,3,4, or 5; instrflag=1)',ch10,&
     549                 :           0 : &     ' otherwise the program  will continue but give wrong values.'
     550                 :           0 :      call wrtout(std_out,message,'COLL')
     551                 :           0 :      call wrtout(iout,message,'COLL')
     552                 :             :    end if
     553                 :           2 :    write(message,'(3a)')ch10,' Piezoelectric d tensor (relaxed ion) (unit:pc/N)',ch10
     554                 :           2 :    call wrtout(std_out,message,'COLL')
     555         [ +  + ]:          14 :    do ivarA=1,6
     556                 :          14 :      write(std_out,'(3f16.8)')d_tensor(ivarA,1),d_tensor(ivarA,2),d_tensor(ivarA,3)
     557                 :             :    end do
     558                 :           2 :    call wrtout(iout,message,'COLL')
     559         [ +  - ]:           2 :    if (iwrite) then
     560         [ +  + ]:          14 :      do ivarA=1,6
     561                 :          14 :        write(iout,'(3f16.8)')d_tensor(ivarA,1),d_tensor(ivarA,2),d_tensor(ivarA,3)
     562                 :             :      end do
     563                 :             :    end if
     564                 :             :  end if
     565                 :             : !end the part of piezoelectric d tensor (relaxed ion only).
     566                 :             : 
     567                 :             : !then start to compute the piezoelectric g tensor
     568                 :             : !according to the equation, we first need to know the information
     569                 :             : !of the free-stress dielectric tensor
     570                 :             : !first make sure dielt_rlx exits, so we do not invert zero matrix
     571                 :           5 :  dielt_stress(:,:)=zero
     572                 :           5 :  g_tensor(:,:)=zero
     573         [ +  + ]:           5 :  if(inp%dieflag>0)then
     574         [ +  + ]:          12 :    do ivarA=1,3
     575         [ +  + ]:          39 :      do ivarB=1,3
     576                 :          27 :        dielt_stress(ivarA,ivarB)=zero
     577         [ +  + ]:         198 :        do ii1=1,6
     578                 :             :          dielt_stress(ivarA,ivarB)=dielt_stress(ivarA,ivarB)+&
     579                 :         189 : &         piezo_relaxed(ii1,ivarA)*d_tensor(ii1,ivarB)
     580                 :             :        end do
     581                 :             :      end do
     582                 :             :    end do
     583                 :             : 
     584                 :             : !  then combine the relaxed ion(fixed strain) dielectric
     585                 :             : !  tensor and also restore the unit
     586         [ +  + ]:          12 :    do ivarA=1,3
     587         [ +  + ]:          39 :      do ivarB=1,3
     588                 :             :        dielt_stress(ivarA,ivarB)=dielt_rlx(ivarA,ivarB)+&
     589                 :          36 : &       dielt_stress(ivarA,ivarB)/(eps0*1.0e12)
     590                 :             :      end do
     591                 :             :    end do
     592                 :             : 
     593                 :             : !  DEBUG
     594                 :             : !  write(message,'(a,a,a,a)')ch10,'debug the free stress dielectric tensor ',&
     595                 :             : !  &  '(unit:pc/N)',ch10
     596                 :             : !  call wrtout(std_out,message,'COLL')
     597                 :             : !  do ivarA=1,3
     598                 :             : !  write(std_out,'(3f16.8)')dielt_stress(ivarA,1),dielt_stress(ivarA,2),&
     599                 :             : !  &    dielt_stress(ivarA,3)
     600                 :             : !  end do
     601                 :             : !  ENDDEBUG
     602                 :             : 
     603                 :             : !  then get the g tensor
     604                 :             :    beta_tensor(:,:)=0
     605                 :           3 :    beta_tensor(:,:)=dielt_stress(:,:)
     606                 :             : 
     607                 :           3 :    call matrginv(beta_tensor,3,3)
     608         [ +  + ]:          12 :    do ivarA=1,3
     609         [ +  + ]:          66 :      do ivarB=1,6
     610                 :          54 :        g_tensor(ivarA,ivarB)=zero
     611         [ +  + ]:         225 :        do ii1=1,3
     612                 :             :          g_tensor(ivarA,ivarB)=g_tensor(ivarA,ivarB)+beta_tensor(ivarA,ii1)*&
     613                 :         216 : &         d_tensor(ivarB,ii1)
     614                 :             :        end do
     615                 :             :      end do
     616                 :             :    end do
     617                 :             : !  then restore the unit to be m^2/C
     618         [ +  + ]:          12 :    do ivarA=1,3
     619         [ +  + ]:          66 :      do ivarB=1,6
     620                 :          63 :        g_tensor(ivarA,ivarB)=g_tensor(ivarA,ivarB)/(eps0*1.0e12)
     621                 :             :      end do
     622                 :             :    end do
     623                 :             :  end if
     624                 :             : !then print out the final results of the g tensors(relaxed ion)
     625         [ +  + ]:           5 :  if(inp%piezoflag==5 .or. inp%piezoflag==7)then
     626                 :             :    if(inp%instrflag==0 .or. inp%elaflag==0&
     627                 :             : &   .or.  inp%elaflag==1 .or.  inp%elaflag==0&
     628   [ +  -  +  -  :           2 : &   .or. inp%dieflag==2 .or. inp%dieflag==1)then
          +  -  +  -  -  
                      + ]
     629                 :           0 :      write(message,'(a,a,a,a,a,a,a,a)' )ch10,&
     630                 :           0 : &     ' WARNING:in order to get the piezoelectric g tensor(relaxed ion),',ch10,&
     631                 :           0 : &     ' need internal strain, dielectric(relaxed-ion) and elastic(realxed ion)',ch10,&
     632                 :           0 : &     ' please set instrflag==1, elaflag==2,3,4 or 5, dieflag==3 or 4',ch10,&
     633                 :           0 : &     ' otherwise the program will still continue but give wrong values.'
     634                 :           0 :      call wrtout(std_out,message,'COLL')
     635                 :           0 :      call wrtout(iout,message,'COLL')
     636                 :             :    end if
     637                 :             : 
     638                 :           2 :    write(message,'(3a)')ch10,' Piezoelectric g tensor (relaxed ion) (unit:m^2/c)',ch10
     639                 :           2 :    call wrtout(std_out,message,'COLL')
     640         [ +  + ]:          14 :    do ivarA=1,6
     641                 :          14 :      write(std_out,'(3f16.8)')g_tensor(1,ivarA),g_tensor(2,ivarA),g_tensor(3,ivarA)
     642                 :             :    end do
     643                 :           2 :    call wrtout(iout,message,'COLL')
     644         [ +  - ]:           2 :    if (iwrite) then
     645         [ +  + ]:          14 :      do ivarA=1,6
     646                 :          14 :        write(iout,'(3f16.8)')g_tensor(1,ivarA),g_tensor(2,ivarA),g_tensor(3,ivarA)
     647                 :             :      end do
     648                 :             :    end if
     649                 :             :  end if
     650                 :             : !end the part of piezoelectric g tensor (relaxed ion only).
     651                 :             : 
     652                 :             : !then start the part for computation of h tensor
     653                 :           5 :  h_tensor(:,:)=zero
     654                 :             : !first make sure the dielt_rlx is not zero in the memory
     655         [ +  + ]:           5 :  if(inp%dieflag>0)then
     656                 :             :    beta_tensor(:,:)=0
     657                 :           3 :    beta_tensor(:,:)=dielt_rlx(:,:)
     658                 :             : !  write(std_out,*)' call matrginv 3, dielt_rlx(:,:)= ',dielt_rlx(:,:)
     659                 :             : 
     660                 :           3 :    call matrginv(beta_tensor,3,3)
     661         [ +  + ]:          12 :    do ivarA=1,3
     662         [ +  + ]:          66 :      do ivarB=1,6
     663                 :          54 :        h_tensor(ivarA,ivarB)=zero
     664         [ +  + ]:         225 :        do ii1=1,3
     665                 :             :          h_tensor(ivarA,ivarB)=h_tensor(ivarA,ivarB)+beta_tensor(ivarA,ii1)*&
     666                 :         216 : &         piezo_relaxed(ivarB,ii1)
     667                 :             :        end do
     668                 :             :      end do
     669                 :             :    end do
     670                 :             : !  then restore the unit to be N/c
     671         [ +  + ]:          12 :    do ivarA=1,3
     672         [ +  + ]:          66 :      do ivarB=1,6
     673                 :          63 :        h_tensor(ivarA,ivarB)=1000.0*(h_tensor(ivarA,ivarB)/(eps0*1.0e12))
     674                 :             :      end do
     675                 :             :    end do
     676                 :             :  end if
     677                 :             : !then print out the final results of h tensors
     678         [ +  + ]:           5 :  if(inp%piezoflag==6 .or. inp%piezoflag==7)then
     679   [ +  -  +  -  :           2 :    if(inp%instrflag==0 .or. inp%dieflag==1 .or. &
                   -  + ]
     680                 :             : &   inp%dieflag==2)then
     681                 :           0 :      write(message,'(a,a,a,a,a,a,a,a)' )ch10,&
     682                 :           0 : &     ' WARNING: in order to get the h tensor, ',ch10,&
     683                 :           0 : &     ' one needs information about internal strain and dielectric(relaxed ion)',ch10,&
     684                 :           0 : &     ' one should set dieflag==3 or 4 and instrflag==1;',ch10,&
     685                 :           0 : &     ' otherwise the program will continue but give wrong values.'
     686                 :           0 :      call wrtout(std_out,message,'COLL')
     687                 :           0 :      call wrtout(iout,message,'COLL')
     688                 :             :    end if
     689                 :           2 :    write(message,'(3a)')ch10,' Piezoelectric h tensor (relaxed ion) (unit:GN/c)',ch10
     690                 :           2 :    call wrtout(std_out,message,'COLL')
     691         [ +  + ]:          14 :    do ivarA=1,6
     692                 :          14 :      write(std_out,'(3f16.8)')h_tensor(1,ivarA),h_tensor(2,ivarA),h_tensor(3,ivarA)
     693                 :             :    end do
     694                 :           2 :    call wrtout(iout,message,'COLL')
     695         [ +  - ]:           2 :    if (iwrite) then
     696         [ +  + ]:          14 :      do ivarA=1,6
     697                 :          14 :        write(iout,'(3f16.8)')h_tensor(1,ivarA),h_tensor(2,ivarA),h_tensor(3,ivarA)
     698                 :             :      end do
     699                 :             :    end if
     700                 :             :  end if
     701                 :             : !end the part of piezoelectric h tensor (relaxed ion only).
     702                 :             : 
     703                 :             : !print the free stress dielectric tensor
     704         [ +  + ]:           5 :  if(inp%dieflag==4)then
     705                 :           2 :    write(message, '(a,a)')ch10,'************************************************'
     706                 :           2 :    call wrtout(std_out,message,'COLL')
     707                 :           2 :    call wrtout(iout,message,'COLL')
     708   [ +  -  +  -  :           2 :    if(inp%instrflag==0 .or. inp%elaflag==0 .or. inp%elaflag==1)then
                   -  + ]
     709                 :           0 :      write(message,'(a,a,a,a,a,a,a,a)' )ch10,&
     710                 :           0 : &     ' WARNING: in order to get the free stress dielectric tensor,',ch10,&
     711                 :           0 : &     ' one needs internal strain and elastic (relaxed ion)', ch10,&
     712                 :           0 : &     ' we need set elaflag==2,3,4 or 5 and instrflag==1.',ch10,&
     713                 :           0 : &     ' otherwise the program may continue but give wrong and nonsense values.'
     714                 :           0 :      call wrtout(std_out,message,'COLL')
     715                 :           0 :      call wrtout(iout,message,'COLL')
     716                 :             :    end if
     717                 :           2 :    write(message,'(a,a,a)')ch10,' Free stress dielectric tensor (dimensionless)',ch10
     718                 :           2 :    call wrtout(std_out,message,'COLL')
     719         [ +  + ]:           8 :    do ivarA=1,3
     720                 :           8 :      write(std_out,'(3f16.8)')dielt_stress(ivarA,1),dielt_stress(ivarA,2),dielt_stress(ivarA,3)
     721                 :             :    end do
     722                 :           2 :    call wrtout(iout,message,'COLL')
     723         [ +  - ]:           2 :    if (iwrite) then
     724         [ +  + ]:           8 :      do ivarA=1,3
     725                 :           8 :        write(iout,'(3f16.8)')dielt_stress(ivarA,1),dielt_stress(ivarA,2),dielt_stress(ivarA,3)
     726                 :             :      end do
     727                 :             :    end if
     728                 :             :  end if
     729                 :             : !end the part of printing out the free stress dielectric tensor
     730                 :             : 
     731                 :             : !then print out the fixed displacement elastic tensor
     732                 :           5 :  elast_dis = zero; compliance_dis = zero
     733                 :             : 
     734   [ +  +  +  - ]:           5 :  if(inp%elaflag==4 .and. inp%dieflag>0)then
     735                 :             :    if(inp%instrflag==0 .or. inp%dieflag==1 .or. &
     736   [ +  -  +  -  :           2 : &   inp%dieflag==2 .or. inp%dieflag==0)then
                   -  + ]
     737                 :           0 :      write(message,'(a,a,a,a,a,a,a,a)' )ch10,&
     738                 :           0 : &     ' WARNING: in order to get the elatic(fixed D field) tensor, ',ch10,&
     739                 :           0 : &     ' one needs information about internal strain and dielectric(relaxed ion)',ch10,&
     740                 :           0 : &     ' one should set dieflag==3 or 4 and instrflag==1;',ch10,&
     741                 :           0 : &     ' otherwise the program will continue but give wrong values.'
     742                 :           0 :      call wrtout(std_out,message,'COLL')
     743                 :           0 :      call wrtout(iout,message,'COLL')
     744                 :             :    end if
     745                 :             : 
     746                 :             : !Then begin the computation of the fixed displacement elastic and compliance tensor(relaxed ion)
     747         [ +  + ]:          14 :    do ivarA=1,6
     748         [ +  + ]:          86 :      do ivarB=1,6
     749                 :          72 :        elast_dis(ivarA,ivarB)=zero
     750         [ +  + ]:         300 :        do ii1=1,3
     751                 :             :          elast_dis(ivarA,ivarB)=elast_dis(ivarA,ivarB)+&
     752                 :         288 : &         h_tensor(ii1,ivarA)*piezo_relaxed(ivarB,ii1)
     753                 :             :        end do
     754                 :             :      end do
     755                 :             :    end do
     756                 :             : !Then should add the relaxed ion fixed E-field values
     757         [ +  + ]:          14 :    do ivarA=1,6
     758         [ +  + ]:          86 :      do ivarB=1,6
     759                 :          84 :        elast_dis(ivarA,ivarB)=elast_dis(ivarA,ivarB)+elast(ivarA,ivarB)
     760                 :             :      end do
     761                 :             :    end do
     762                 :             : 
     763                 :           2 :    write(message, '(a,a)')ch10,'************************************************'
     764                 :           2 :    call wrtout(std_out,message,'COLL')
     765                 :           2 :    call wrtout(iout,message,'COLL')
     766                 :           2 :    write(message,'(5a)')ch10,&
     767                 :           2 : &   ' Elastic Tensor (relaxed ion) (unit:10^2GP)',ch10,&
     768                 :           4 : &   '  (at fixed displacement field boundary condition)',ch10
     769                 :           2 :    call wrtout(std_out,message,'COLL')
     770         [ +  + ]:          14 :    do ivarA=1,6
     771                 :          12 :      write(std_out,'(6f12.7)')elast_dis(ivarA,1)/100.00_dp,elast_dis(ivarA,2)/100.00_dp,&
     772                 :          12 : &     elast_dis(ivarA,3)/100.00_dp,elast_dis(ivarA,4)/100.00_dp,&
     773                 :          26 : &     elast_dis(ivarA,5)/100.00_dp,elast_dis(ivarA,6)/100.00_dp
     774                 :             :    end do
     775                 :           2 :    call wrtout(iout,message,'COLL')
     776         [ +  - ]:           2 :    if (iwrite) then
     777         [ +  + ]:          14 :      do ivarA=1,6
     778                 :          12 :        write(iout,'(6f12.7)')elast_dis(ivarA,1)/100.00_dp,elast_dis(ivarA,2)/100.00_dp,&
     779                 :          12 : &       elast_dis(ivarA,3)/100.00_dp,elast_dis(ivarA,4)/100.00_dp,&
     780                 :          26 : &       elast_dis(ivarA,5)/100.00_dp,elast_dis(ivarA,6)/100.00_dp
     781                 :             :      end do
     782                 :             :    end if
     783                 :             : !  then invert the above to get the corresponding compliance tensor
     784                 :             :    compliance_dis(:,:)=0
     785                 :           2 :    compliance_dis(:,:)=elast_dis(:,:)
     786                 :             : 
     787                 :           2 :    call matrginv(compliance_dis,6,6)
     788                 :             : !  then print out the compliance tensor at fixed displacement field
     789                 :           2 :    write(message,'(5a)')ch10,&
     790                 :           2 : &   ' Compliance  Tensor (relaxed ion) (unit: 10^-2(GP)^-1)',ch10,&
     791                 :           4 : &   '  (at fixed displacement field boundary condition)',ch10
     792                 :           2 :    call wrtout(std_out,message,'COLL')
     793         [ +  + ]:          14 :    do ivarB=1,6
     794                 :          12 :      write(std_out,'(6f12.7)')compliance_dis(ivarB,1)*100.00_dp,&
     795                 :          12 : &     compliance_dis(ivarB,2)*100.00_dp,&
     796                 :          12 : &     compliance_dis(ivarB,3)*100.00_dp,compliance_dis(ivarB,4)*100.00_dp,&
     797                 :          12 : &     compliance_dis(ivarB,5)*100.00_dp,&
     798                 :          26 : &     compliance_dis(ivarB,6)*100.00_dp
     799                 :             :    end do
     800                 :           2 :    call wrtout(iout,message,'COLL')
     801                 :             : 
     802         [ +  - ]:           2 :    if (iwrite) then
     803         [ +  + ]:          14 :      do ivarB=1,6
     804                 :          12 :        write(iout,'(6f12.7)')compliance_dis(ivarB,1)*100.00,&
     805                 :          12 : &       compliance_dis(ivarB,2)*100.00_dp,&
     806                 :          12 : &       compliance_dis(ivarB,3)*100.00_dp,compliance_dis(ivarB,4)*100.00_dp,&
     807                 :          12 : &       compliance_dis(ivarB,5)*100.00_dp,&
     808                 :          26 : &       compliance_dis(ivarB,6)*100.00_dp
     809                 :             :      end do
     810                 :             :    end if
     811                 :             :  end if
     812                 :             : !end if the elaflag==4 for the fixed didplacement field elastic tensor
     813                 :             : !end the part for computation of elastic at fixed displacement field
     814                 :             : 
     815                 :             :  ! write tensors to netcdf file.
     816         [ +  - ]:           5 :  if (ncid /= nctk_noid) then
     817                 :             :    ncerr = nctk_def_arrays(ncid, [ &
     818                 :             :      nctkarr_t("piezo_clamped_ion", "dp", "six, three"), &
     819                 :             :      nctkarr_t("piezo_relaxed_ion", "dp", "six, three"), &
     820                 :             :      nctkarr_t("d_tensor_relaxed_ion", "dp", "six, three"), &
     821                 :             :      nctkarr_t("g_tensor_relaxed_ion", "dp", "three, six"), &
     822                 :             :      nctkarr_t("h_tensor_relaxed_ion", "dp", "three, six"), &
     823                 :             :      nctkarr_t("free_stress_dielectric_tensor", "dp", "three, three"), &
     824                 :             :      nctkarr_t("elastic_tensor_relaxed_ion_fixed_D", "dp", "six, six"), &
     825                 :             :      nctkarr_t("compliance_tensor_relaxed_ion_fixed_D", "dp", "six, six")], &
     826         [ +  + ]:          45 :    defmode=.True.)
     827         [ -  + ]:           5 :    NCF_CHECK(ncerr)
     828                 :             :    ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: &
     829         [ +  + ]:          25 :        "elaflag", "piezoflag", "instrflag", "dieflag"])
     830         [ -  + ]:           5 :    NCF_CHECK(ncerr)
     831                 :             : 
     832         [ -  + ]:           5 :    NCF_CHECK(nctk_set_datamode(ncid))
     833                 :             :    ncerr = nctk_write_iscalars(ncid, [character(len=nctk_slen) :: &
     834                 :             :      "elaflag", "piezoflag", "instrflag", "dieflag"], &
     835   [ +  +  +  + ]:          45 :      [inp%elaflag, inp%piezoflag, inp%instrflag, inp%dieflag])
     836         [ -  + ]:           5 :    NCF_CHECK(ncerr)
     837         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "piezo_clamped_ion"), piezo_clamped))
     838         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "piezo_relaxed_ion"), piezo_relaxed))
     839         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "d_tensor_relaxed_ion"), d_tensor))
     840         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "g_tensor_relaxed_ion"), g_tensor))
     841         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "h_tensor_relaxed_ion"), h_tensor))
     842         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "free_stress_dielectric_tensor"), dielt_stress))
     843         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "elastic_tensor_relaxed_ion_fixed_D"), elast_dis))
     844         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "compliance_tensor_relaxed_ion_fixed_D"), compliance_dis))
     845                 :             :  end if
     846                 :             : 
     847                 :           5 : end subroutine ddb_piezo
     848                 :             : !!***
     849                 :             : 
     850                 :             : end module m_ddb_piezo
     851                 :             : !!***
        

Generated by: LCOV version 2.3-1