LCOV - code coverage report
Current view: top level - src/80_tdep - m_tdep_solver.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.8 % 627 588
Test Date: 2026-11-09 20:57:54 Functions: 81.8 % 11 9
Branches: 71.5 % 1394 997

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_tdep_solver
       2                 :             : !! NAME
       3                 :             : !!  m_tdep_solver
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  This module contains the TDEP Solver data type
       7                 :             : !!  which fits the IFC on the forces and displacements of the sampling.
       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_solver
      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_numeric_tools
      31                 :             :  use m_linalg_interfaces
      32                 :             :  use m_tdep_dataset,     only : atdep_dataset_type, MPI_enreg_type
      33                 :             :  use m_tdep_shell,       only : Shell_type
      34                 :             :  use m_tdep_sym,         only : Symmetries_type
      35                 :             :  use m_tdep_sampling,    only : tdep_Sampling_type
      36                 :             :  use m_tdep_model,       only : tdep_Model_type
      37                 :             :  use m_tdep_constraints, only : Constraints_type, tdep_calc_orthonorm
      38                 :             : 
      39                 :             :  implicit none
      40                 :             : 
      41                 :             :  type tdep_Solver_type
      42                 :             : 
      43                 :             :    integer :: order
      44                 :             :    ! Maximum IFC order (2, 3, or 4)
      45                 :             : 
      46                 :             :    integer :: natom
      47                 :             :    ! Number of atoms in the supercell
      48                 :             : 
      49                 :             :    integer :: natom_unitcell
      50                 :             :    ! Number of atoms in the unitcell
      51                 :             : 
      52                 :             :    integer :: my_nstep
      53                 :             :    ! Number of MD steps
      54                 :             : 
      55                 :             :    integer :: ntotcoeff
      56                 :             :    ! Total number of coefficients
      57                 :             : 
      58                 :             :    integer :: ntotconst
      59                 :             :    ! Total number of constraints
      60                 :             : 
      61                 :             :    integer :: ncoeff1st
      62                 :             :    ! Number of 1st order coefficients
      63                 :             : 
      64                 :             :    integer :: ncoeff2nd
      65                 :             :    ! Number of 2nd order coefficients
      66                 :             : 
      67                 :             :    integer :: ncoeff3rd
      68                 :             :    ! Number of 3rd order coefficients
      69                 :             : 
      70                 :             :    integer :: ncoeff4th
      71                 :             :    ! Number of 4th order coefficients
      72                 :             : 
      73                 :             :    integer :: nconst_1st
      74                 :             :    ! Number of 1st order constraints
      75                 :             : 
      76                 :             :    integer :: nconst_2nd
      77                 :             :    ! Number of 2nd order constraints
      78                 :             : 
      79                 :             :    integer :: nconst_3rd
      80                 :             :    ! Number of 3rd order constraints
      81                 :             : 
      82                 :             :    integer :: nconst_4th
      83                 :             :    ! Number of 4th order constraints
      84                 :             : 
      85                 :             :    integer :: nconst_rot2nd
      86                 :             :    integer :: nconst_huang
      87                 :             :    integer :: nconst_dynmat
      88                 :             :    integer :: nconst_rot3rd
      89                 :             :    integer :: nconst_asr3rd
      90                 :             :    integer :: nconst_rot4th
      91                 :             :    integer :: nconst_asr4th
      92                 :             : 
      93                 :             :    double precision, allocatable :: fcoeff(:,:)
      94                 :             :    ! fcoeff(3*natom*my_nstep,ntotcoeff)
      95                 :             :    ! All the cartesian displacement matrices
      96                 :             :    ! at every order (u, u*u, u*u*u, u*u*u*u).
      97                 :             : 
      98                 :             :    double precision, allocatable :: const(:,:)
      99                 :             :    ! const(ntotconst,ntotcoeff)
     100                 :             :    ! The constraint matrices.
     101                 :             : 
     102                 :             :    double precision, allocatable :: theta(:)
     103                 :             :    ! theta(ntotcoeff)
     104                 :             :    ! The IFC coefficients at all orders, as a flat array.
     105                 :             : 
     106                 :             :    double precision, allocatable :: Forces(:)
     107                 :             :    ! Forces(3*natom*my_nstep)
     108                 :             :    ! The cartesian forces for all configurations, as a flat array.
     109                 :             :    ! These are weighted by the number of configurations.
     110                 :             :    ! In case of dipole-dipole interaction, the long-range part of the
     111                 :             :    ! forces should be removed.
     112                 :             : 
     113                 :             :  end type tdep_Solver_type
     114                 :             : 
     115                 :             :  public :: tdep_solver_init
     116                 :             :  public :: tdep_solver_free
     117                 :             :  public :: tdep_solver_set_residual_forces
     118                 :             :  public :: tdep_calc_phi1fcoeff
     119                 :             :  public :: tdep_calc_phi2fcoeff
     120                 :             :  public :: tdep_calc_phi3fcoeff
     121                 :             :  public :: tdep_calc_phi4fcoeff
     122                 :             :  public :: tdep_calc_MoorePenrose
     123                 :             :  public :: tdep_calc_constraints
     124                 :             : 
     125                 :             : contains
     126                 :             : 
     127                 :             : !=====================================================================================================
     128                 :             : 
     129                 :          44 :  subroutine tdep_solver_init(Solver, Invar, Shell1at, Shell2at, Shell3at, Shell4at)
     130                 :             : 
     131                 :             :   type(tdep_Solver_type), intent(inout) :: Solver
     132                 :             :   type(atdep_dataset_type),intent(in) :: Invar
     133                 :             :   type(Shell_type),intent(in) :: Shell1at, Shell2at, Shell3at, Shell4at
     134                 :             : 
     135                 :          44 :   Solver%order = Invar%order
     136                 :          44 :   Solver%natom = Invar%natom
     137                 :          44 :   Solver%natom_unitcell = Invar%natom_unitcell
     138                 :          44 :   Solver%my_nstep = Invar%my_nstep
     139                 :             : 
     140                 :             :   !Rotational invariances (1st order)
     141                 :             :   !    constraints = 3
     142                 :          44 :   Solver%nconst_1st = 3**2
     143                 :             : 
     144                 :             :   !Rotational invariances (2nd order) + Symetry of the Dynamical Matrix + Huang invariances
     145                 :             :   !    constraints = natom*3**2 + (3*natom_unitcell)**2 + 3**4
     146                 :          44 :   Solver%nconst_rot2nd = 3**3*Solver%natom_unitcell
     147                 :          44 :   Solver%nconst_dynmat = (3*Solver%natom_unitcell)**2
     148                 :          44 :   Solver%nconst_huang  = 3**4
     149                 :          44 :   Solver%nconst_2nd = Solver%nconst_rot2nd + Solver%nconst_dynmat + Solver%nconst_huang
     150                 :             : 
     151                 :             :   !Rotational invariances (3rd order) + acoustic sum rules (3rd order)
     152                 :          44 :   Solver%nconst_3rd=0
     153         [ +  + ]:          44 :   if (Solver%order.ge.3) then
     154                 :             :   !    constraints = natom_unitcell*natom*3**4 + natom_unitcell*natom*3**3
     155                 :          14 :     Solver%nconst_rot3rd = 3**4 * Solver%natom_unitcell * Solver%natom
     156                 :          14 :     Solver%nconst_asr3rd = 3**3 * Solver%natom_unitcell * Solver%natom
     157                 :          14 :     Solver%nconst_3rd = Solver%nconst_rot3rd + Solver%nconst_asr3rd
     158                 :             :   end if
     159                 :             : 
     160                 :             :   !Rotational invariances (4th order) + acoustic sum rules (4th order)
     161                 :          44 :   Solver%nconst_4th=0
     162         [ +  + ]:          44 :   if (Solver%order.ge.4) then
     163                 :             :   !    constraints = natom_unitcell*natom**2*3**5 + natom_unitcell*natom**2*3**4
     164                 :             :   !FB   Solver%nconst_rot4th = 3**5*natom_unitcell*natom**2
     165                 :             :   !FB4TH   Solver%nconst_asr4th = 3**4*natom_unitcell*natom**2
     166                 :           8 :     Solver%nconst_rot4th = 0
     167                 :           8 :     Solver%nconst_asr4th = 0
     168                 :             :     Solver%nconst_4th = Solver%nconst_rot4th + Solver%nconst_asr4th
     169                 :             :   end if
     170                 :             : 
     171                 :          44 :   Solver%ncoeff1st = Shell1at%ntotcoeff
     172                 :          44 :   Solver%ncoeff2nd = Shell2at%ntotcoeff
     173                 :          44 :   Solver%ncoeff3rd = 0
     174                 :          44 :   Solver%ncoeff4th = 0
     175         [ +  + ]:          44 :   if (Solver%order.ge.3) Solver%ncoeff3rd = Shell3at%ntotcoeff
     176         [ +  + ]:          44 :   if (Solver%order.ge.4) Solver%ncoeff4th = Shell4at%ntotcoeff
     177                 :             : 
     178                 :          44 :   Solver%ntotcoeff = Solver%ncoeff1st  + Solver%ncoeff2nd  + Solver%ncoeff3rd  + Solver%ncoeff4th
     179                 :          44 :   Solver%ntotconst = Solver%nconst_1st + Solver%nconst_2nd + Solver%nconst_3rd + Solver%nconst_4th
     180                 :             : 
     181   [ +  -  -  +  :    25945165 :   ABI_CALLOC(Solver%fcoeff, (3*Solver%natom*Solver%my_nstep,Solver%ntotcoeff))
          +  -  -  +  +  
          -  +  -  +  -  
          -  +  -  +  -  
             +  +  +  +  
                      + ]
     182   [ -  +  +  -  :    50744071 :   ABI_CALLOC(Solver%const, (Solver%ntotconst,Solver%ntotcoeff))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  -  +  +  
                +  +  + ]
     183   [ -  +  +  -  :      417588 :   ABI_CALLOC(Solver%Forces, (3*Solver%natom*Solver%my_nstep))
          +  -  +  -  -  
          +  -  +  -  +  
                   +  + ]
     184   [ -  +  +  -  :        2873 :   ABI_CALLOC(Solver%theta, (Solver%ntotcoeff))
          +  -  +  -  -  
          +  -  +  -  +  
                   +  + ]
     185                 :             : 
     186                 :          44 :  end subroutine tdep_solver_init
     187                 :             : 
     188                 :             : !=====================================================================================================
     189                 :             : 
     190                 :          44 :  subroutine tdep_solver_free(Solver)
     191                 :             : 
     192                 :             :   type(tdep_Solver_type), intent(inout) :: Solver
     193                 :             : 
     194         [ -  + ]:          44 :   ABI_FREE(Solver%fcoeff)
     195         [ -  + ]:          44 :   ABI_FREE(Solver%const)
     196         [ -  + ]:          44 :   ABI_FREE(Solver%Forces)
     197         [ -  + ]:          44 :   ABI_FREE(Solver%theta)
     198                 :             : 
     199                 :          44 :  end subroutine tdep_solver_free
     200                 :             : 
     201                 :             : !=====================================================================================================
     202                 :             : 
     203                 :             : !!***
     204                 :             : !!****f* ABINIT/m_tdep_solver/tdep_solver_set_residual_forces
     205                 :             : !! NAME
     206                 :             : !!  tdep_solver_set_residual_forces
     207                 :             : !!
     208                 :             : !! FUNCTION
     209                 :             : !! Compute the residual forces into the solver, that is, the differences
     210                 :             : !! between the MD forces and the ones from the TDEP model.
     211                 :             : !! The model forces may be zero, but they are non-zero when we remove
     212                 :             : !! the long-range part of the IFC forces, or when we solve each IFC order
     213                 :             : !! successively, and we remove the forces from the previously computed orders.
     214                 :             : !!
     215                 :             : !! INPUTS
     216                 :             : !!  Solver = TDEP Solver object that will compute the coefficients.
     217                 :             : !!  MD = TDEP Sampling object containing the input positions and forces.
     218                 :             : !!  Model = TDEP Model object containing the IFC and corresponding forces.
     219                 :             : !!
     220                 :             : !! OUTPUT
     221                 :             : !!
     222                 :             : !! SIDE EFFECTS
     223                 :             : !!  The following quantities in MD are computed:
     224                 :             : !!
     225                 :             : !! NOTES
     226                 :             : !!
     227                 :             : !! SOURCE
     228                 :             : 
     229                 :          47 :  subroutine tdep_solver_set_residual_forces(Solver, MD, Model)
     230                 :             : 
     231                 :             :   type(tdep_Solver_type), intent(inout) :: Solver
     232                 :             :   type(tdep_Sampling_type), intent(in) :: MD
     233                 :             :   type(tdep_Model_type), intent(in) :: Model
     234                 :             : 
     235                 :             :   integer :: ii,jj,istep,iatom
     236                 :             : 
     237         [ +  + ]:        1059 :   do istep=1,MD%my_nstep
     238         [ +  + ]:      151731 :    do iatom=1,MD%natom
     239         [ +  + ]:      603700 :      do ii=1,3
     240                 :      452016 :       jj = ii + 3*(iatom-1) + 3*MD%natom*(istep-1)
     241                 :      602688 :       Solver%Forces(jj) = (MD%Forces(jj) - Model%Forces(jj)) * MD%weights(istep)
     242                 :             :      end do
     243                 :             :    end do
     244                 :             :   end do
     245                 :             : 
     246                 :          47 :  end subroutine tdep_solver_set_residual_forces
     247                 :             : 
     248                 :             : !====================================================================================================
     249                 :             : 
     250                 :          43 : subroutine tdep_calc_phi1fcoeff(Solver,Invar,Shell1at,Sym)
     251                 :             : 
     252                 :             :   type(tdep_Solver_type), intent(inout) :: Solver
     253                 :             :   type(atdep_dataset_type),intent(in) :: Invar
     254                 :             :   type(Shell_type),intent(in) :: Shell1at
     255                 :             :   type(Symmetries_type),intent(in) :: Sym
     256                 :             : 
     257                 :             :   integer :: ishell,ncoeff,ncoeff_prev,istep,iatom,iatshell,iat_mod
     258                 :             :   integer :: icoeff,isym,mu,iatref
     259                 :             :   double precision :: terme
     260                 :             : 
     261                 :          43 :   write(Invar%stdout,*) ' '
     262                 :          43 :   write(Invar%stdout,*) '#############################################################################'
     263                 :          43 :   write(Invar%stdout,*) '############## Fill the matrices used in the pseudo-inverse #################'
     264                 :          43 :   write(Invar%stdout,*) '#############################################################################'
     265                 :             : 
     266                 :          43 :   write(Invar%stdout,*) ' Compute the coefficients (at the 1st order) used in the Moore-Penrose...'
     267         [ +  + ]:         105 :   do ishell=1,Shell1at%nshell
     268         [ -  + ]:          62 :     if (Shell1at%neighbours(1,ishell)%n_interactions.eq.0) cycle
     269         [ -  - ]:          43 :     do iatshell=1,Shell1at%neighbours(1,ishell)%n_interactions
     270                 :           0 :       iatom=Shell1at%neighbours(1,ishell)%atomj_in_shell(iatshell)
     271                 :           0 :       iat_mod=mod(iatom+Invar%natom_unitcell-1,Invar%natom_unitcell)+1
     272         [ #  # ]:           0 :       if (iat_mod==1) cycle
     273                 :           0 :       iatref=Shell1at%iatref(ishell)
     274                 :           0 :       isym=Shell1at%neighbours(1,ishell)%sym_in_shell(iatshell)
     275                 :           0 :       ncoeff     =Shell1at%ncoeff(ishell)
     276                 :           0 :       ncoeff_prev=Shell1at%ncoeff_prev(ishell)
     277         [ -  - ]:          62 :       do mu=1,3
     278         [ #  # ]:           0 :         do icoeff=1,ncoeff
     279         [ #  # ]:           0 :           terme=sum(Sym%S_ref(mu,:,isym,1)*Shell1at%proj(:,icoeff,ishell))
     280         [ #  # ]:           0 :           do istep=1,Invar%my_nstep
     281                 :             :             Solver%fcoeff(mu+3*(iatom-1)+3*Invar%natom*(istep-1),icoeff+ncoeff_prev)= &
     282                 :           0 : &           Solver%fcoeff(mu+3*(iatom-1)+3*Invar%natom*(istep-1),icoeff+ncoeff_prev)+terme
     283                 :             : !           Add all the other contributions, when iat_mod==1 (due to ASR)
     284                 :             :             Solver%fcoeff(mu+3*(iatom-iat_mod+1)+3*Invar%natom*(istep-1),icoeff+ncoeff_prev)= &
     285                 :           0 : &           Solver%fcoeff(mu+3*(iatom-iat_mod+1)+3*Invar%natom*(istep-1),icoeff+ncoeff_prev)-terme
     286                 :             :           end do !istep
     287                 :             :         end do
     288                 :             :       end do
     289                 :             :     end do !iatshell
     290                 :             :   end do !ishell
     291                 :          43 :   write(Invar%stdout,*) ' ------- achieved'
     292                 :             : 
     293                 :          43 : end subroutine tdep_calc_phi1fcoeff
     294                 :             : 
     295                 :             : !====================================================================================================
     296                 :             : 
     297                 :          43 : subroutine tdep_calc_phi2fcoeff(Solver,Invar,Shell2at,Sym,MD)
     298                 :             : 
     299                 :             :   type(tdep_Solver_type), intent(inout) :: Solver
     300                 :             :   type(atdep_dataset_type),intent(in) :: Invar
     301                 :             :   type(Shell_type),intent(in) :: Shell2at
     302                 :             :   type(Symmetries_type),intent(in) :: Sym
     303                 :             :   type(tdep_Sampling_type), intent(in) :: MD
     304                 :             : 
     305                 :             :   integer :: ishell,ncoeff,ncoeff_prev,istep,iatom,jatom,iatshell
     306                 :             :   integer :: icoeff,isym
     307                 :             :   integer :: mu,nu,alpha,beta,itrans
     308                 :             :   double precision :: terme,temp
     309                 :             :   double precision :: udiff(3),SSu(3,9)
     310                 :          43 :   double precision, allocatable :: SS_ref(:,:,:,:,:)
     311                 :             : 
     312                 :             : ! For each couple of atoms, transform the Phi2 (3x3) ifc matrix using the symetry operation (S)
     313                 :             : ! Note: iatom=1 is excluded in order to take into account the atomic sum rule (see below)
     314   [ -  +  +  -  :      358210 :   ABI_MALLOC(SS_ref,(3,9,3,Sym%nsym,2)); SS_ref(:,:,:,:,:)=zero
          +  -  +  -  +  
          -  -  +  -  +  
          +  +  +  +  +  
             +  +  +  +  
                      + ]
     315         [ +  + ]:        1641 :   do isym=1,Sym%nsym
     316         [ +  + ]:        6435 :     do mu=1,3
     317         [ +  + ]:       20774 :       do alpha=1,3
     318         [ +  + ]:       62322 :         do nu=1,3
     319         [ +  + ]:      186966 :           do beta=1,3
     320                 :      129438 :             temp=Sym%S_ref(mu,alpha,isym,1)*Sym%S_ref(nu,beta,isym,1)
     321                 :      129438 :             SS_ref(mu,beta+(alpha-1)*3,nu,isym,1)=temp
     322                 :      172584 :             SS_ref(mu,alpha+(beta-1)*3,nu,isym,2)=temp
     323                 :             :           end do
     324                 :             :         end do
     325                 :             :       end do
     326                 :             :     end do
     327                 :             :   end do
     328                 :             : 
     329                 :          43 :   write(Invar%stdout,*) ' Compute the coefficients (at the 2nd order) used in the Moore-Penrose...'
     330         [ +  + ]:         522 :   do ishell=1,Shell2at%nshell
     331         [ +  + ]:       68344 :     do iatom=1,Invar%natom
     332         [ +  + ]:       67822 :       if (Shell2at%neighbours(iatom,ishell)%n_interactions.eq.0) cycle
     333         [ +  + ]:      462411 :       do iatshell=1,Shell2at%neighbours(iatom,ishell)%n_interactions
     334                 :      405630 :         jatom=Shell2at%neighbours(iatom,ishell)%atomj_in_shell(iatshell)
     335         [ +  + ]:      405630 :         if (iatom==jatom) cycle
     336                 :      399260 :         isym=Shell2at%neighbours(iatom,ishell)%sym_in_shell(iatshell)
     337                 :      399260 :         itrans=Shell2at%neighbours(iatom,ishell)%transpose_in_shell(iatshell)
     338                 :      399260 :         ncoeff     =Shell2at%ncoeff(ishell)
     339                 :      399260 :         ncoeff_prev=Shell2at%ncoeff_prev(ishell)+Solver%ncoeff1st
     340                 :             : 
     341         [ +  + ]:     8424474 :         do istep=1,Invar%my_nstep
     342                 :             : !         In order to impose the acoustic sum rule we use (u(j)-u(i))==u_j^\nu
     343                 :     7957392 :           udiff(1)=(MD%ucart(1,jatom,istep)-MD%ucart(1,iatom,istep))*MD%weights(istep)
     344                 :     7957392 :           udiff(2)=(MD%ucart(2,jatom,istep)-MD%ucart(2,iatom,istep))*MD%weights(istep)
     345                 :     7957392 :           udiff(3)=(MD%ucart(3,jatom,istep)-MD%ucart(3,iatom,istep))*MD%weights(istep)
     346                 :             : 
     347                 :             : !         F_i^\mu(t)=\sum_{\alpha\beta,j,\nu}S^{\mu\alpha}.S^{\nu\beta}.\Phi_{ij}^{\alpha\beta}.u_j^\nu(t)
     348                 :     7957392 :           SSu(:,:)=zero
     349         [ +  + ]:    31829568 :           do nu=1,3
     350   [ +  +  +  + ]:   891227904 :             SSu(:,:)=SSu(:,:)+SS_ref(:,:,nu,isym,itrans)*udiff(nu)
     351                 :             :           end do
     352         [ +  + ]:    32235198 :           do mu=1,3
     353         [ +  + ]:   134399328 :             do icoeff=1,ncoeff
     354         [ +  + ]:  1025697600 :               terme=sum(SSu(mu,:)*Shell2at%proj(:,icoeff,ishell))
     355                 :             : !FB              write(Invar%stdlog,*) 'indices=', mu+3*(iatom-1)+3*Invar%natom*(istep-1),icoeff+ncoeff_prev
     356                 :             :               Solver%fcoeff(mu+3*(iatom-1)+3*Invar%natom*(istep-1),icoeff+ncoeff_prev)= &
     357                 :   126441936 : &             Solver%fcoeff(mu+3*(iatom-1)+3*Invar%natom*(istep-1),icoeff+ncoeff_prev)+terme
     358                 :             :             end do
     359                 :             :           end do
     360                 :             : 
     361                 :             :         end do !istep
     362                 :             :       end do !iatshell
     363                 :             :     end do !iatom
     364                 :             :   end do !ishell
     365                 :          43 :   write(Invar%stdout,*) ' ------- achieved'
     366         [ -  + ]:          43 :   ABI_FREE(SS_ref)
     367                 :             : 
     368                 :          43 : end subroutine tdep_calc_phi2fcoeff
     369                 :             : 
     370                 :             : !====================================================================================================
     371                 :             : 
     372                 :          14 : subroutine tdep_calc_phi3fcoeff(Solver,Invar,Shell3at,Sym,MD)
     373                 :             : 
     374                 :             :   type(tdep_Solver_type), intent(inout) :: Solver
     375                 :             :   type(atdep_dataset_type),intent(in) :: Invar
     376                 :             :   type(Shell_type),intent(in) :: Shell3at
     377                 :             :   type(Symmetries_type),intent(in) :: Sym
     378                 :             :   type(tdep_Sampling_type), intent(in) :: MD
     379                 :             : 
     380                 :             :   integer :: ishell,ncoeff,ncoeff_prev,istep,iatom,jatom,katom
     381                 :             :   integer :: icoeff,isym,itrans,iatshell
     382                 :             :   integer :: mu,nu,xi,alpha,beta,gama,iindex
     383                 :             :   double precision :: temp
     384                 :             :   double precision :: udiff_ki(3),udiff_ji(3)
     385                 :          14 :   double precision, allocatable :: SSS_proj(:,:,:,:)
     386                 :             :   double precision :: SSS_tmp(27), proj_tmp(27)
     387                 :          14 :   type(Constraints_type) :: Const
     388                 :             : 
     389   [ -  +  +  -  :        3102 :   ABI_MALLOC(Const%Sprod,(Sym%nsym,6))
          +  -  +  -  -  
          +  -  +  +  +  
                   +  + ]
     390         [ +  + ]:         510 :   do isym=1,Sym%nsym
     391         [ +  + ]:        3486 :     do itrans=1,6
     392   [ -  +  -  +  :     2931856 :       ABI_MALLOC(Const%Sprod(isym,itrans)%SSS,(3,27,3,3)); Const%Sprod(isym,itrans)%SSS(:,:,:,:)=zero
          +  +  +  +  +  
                +  +  + ]
     393                 :             :     end do
     394                 :             :   end do
     395                 :             : 
     396                 :             : ! For each couple of atoms, transform the Phi3 (3x3x3) ifc matrix using the symetry operation (S)
     397                 :             : ! Note: iatom=1 is excluded in order to take into account the atomic sum rule (see below)
     398         [ +  + ]:         510 :   do isym=1,Sym%nsym
     399         [ +  + ]:        1998 :     do mu=1,3
     400         [ +  + ]:        6448 :       do alpha=1,3
     401         [ +  + ]:       19344 :         do nu=1,3
     402         [ +  + ]:       58032 :           do beta=1,3
     403         [ +  + ]:      174096 :             do xi=1,3
     404         [ +  + ]:      522288 :               do gama=1,3
     405                 :      361584 :                 temp=Sym%S_ref(mu,alpha,isym,1)*Sym%S_ref(nu,beta,isym,1)*Sym%S_ref(xi,gama,isym,1)
     406                 :      361584 :                 Const%Sprod(isym,1)%SSS(mu,gama+(beta-1)*3+(alpha-1)*9,nu,xi)=temp !\Phi3_efg
     407                 :      361584 :                 Const%Sprod(isym,2)%SSS(mu,gama+(beta-1)*3+(alpha-1)*9,xi,nu)=temp !\Phi3_egf
     408                 :      361584 :                 Const%Sprod(isym,3)%SSS(nu,gama+(beta-1)*3+(alpha-1)*9,mu,xi)=temp !\Phi3_feg
     409                 :      361584 :                 Const%Sprod(isym,4)%SSS(nu,gama+(beta-1)*3+(alpha-1)*9,xi,mu)=temp !\Phi3_fge
     410                 :      361584 :                 Const%Sprod(isym,5)%SSS(xi,gama+(beta-1)*3+(alpha-1)*9,mu,nu)=temp !\Phi3_gef
     411                 :      482112 :                 Const%Sprod(isym,6)%SSS(xi,gama+(beta-1)*3+(alpha-1)*9,nu,mu)=temp !\Phi3_gfe
     412                 :             :               end do
     413                 :             :             end do
     414                 :             :           end do
     415                 :             :         end do
     416                 :             :       end do
     417                 :             :     end do
     418                 :             :   end do
     419                 :             : 
     420                 :          14 :   write(Invar%stdout,*) ' Compute the coefficients (at the 3rd order) used in the Moore-Penrose...'
     421         [ +  + ]:          63 :   do ishell=1,Shell3at%nshell
     422         [ +  + ]:        8391 :     do iatom=1,Invar%natom
     423         [ +  + ]:        8328 :       if (Shell3at%neighbours(iatom,ishell)%n_interactions.eq.0) cycle
     424         [ +  + ]:       86485 :       do iatshell=1,Shell3at%neighbours(iatom,ishell)%n_interactions
     425                 :       79388 :         jatom=Shell3at%neighbours(iatom,ishell)%atomj_in_shell(iatshell)
     426                 :       79388 :         katom=Shell3at%neighbours(iatom,ishell)%atomk_in_shell(iatshell)
     427                 :             : !FB        if (iatom==jatom.or.iatom==katom) cycle
     428                 :       79388 :         isym =Shell3at%neighbours(iatom,ishell)%sym_in_shell(iatshell)
     429                 :       79388 :         itrans=Shell3at%neighbours(iatom,ishell)%transpose_in_shell(iatshell)
     430                 :       79388 :         ncoeff     =Shell3at%ncoeff(ishell)
     431                 :       79388 :         ncoeff_prev=Shell3at%ncoeff_prev(ishell)+Solver%ncoeff2nd+Solver%ncoeff1st
     432                 :             : 
     433   [ +  +  +  -  :    20913204 :         ABI_MALLOC(SSS_proj,(3,3,3,ncoeff)) ; SSS_proj(:,:,:,:)=zero
          +  -  +  +  -  
          +  -  +  +  +  
          +  +  +  +  +  
                      + ]
     434         [ +  + ]:      317552 :         do mu=1,3
     435         [ +  + ]:     1032044 :           do nu=1,3
     436         [ +  + ]:     3096132 :             do xi=1,3
     437         [ +  + ]:    60017328 :               SSS_tmp(:)=Const%Sprod(isym,itrans)%SSS(mu,:,nu,xi)
     438         [ +  + ]:    16813620 :               do icoeff=1,ncoeff
     439         [ +  + ]:   390758256 :                 proj_tmp(:)=Shell3at%proj(:,icoeff,ishell)
     440                 :    16099128 :                 SSS_proj(mu,nu,xi,icoeff)=DDOT(27,SSS_tmp,1,proj_tmp,1)
     441                 :             :               end do
     442                 :             :             end do
     443                 :             :           end do
     444                 :             :         end do
     445         [ +  + ]:     1667148 :         do istep=1,Invar%my_nstep
     446                 :     1587760 :           iindex=3*(iatom-1)+3*Invar%natom*(istep-1)
     447                 :             : !         In order to impose the acoustic sum rule we use :
     448                 :             : !FB          udiff_ji(:)=MD%ucart(:,jatom,istep)-MD%ucart(:,iatom,istep)
     449                 :             : !FB          udiff_ki(:)=MD%ucart(:,katom,istep)-MD%ucart(:,iatom,istep)
     450         [ +  + ]:     6351040 :           udiff_ji(:)=MD%ucart(:,jatom,istep)
     451         [ +  + ]:     6351040 :           udiff_ki(:)=MD%ucart(:,katom,istep)
     452                 :             : !         F_i^{\mu}(t)=\sum_{\alpha\beta\gamma,jk,\nu\xi} S^{\mu\alpha}.S^{\nu\beta}.S^{\xi\gamma}.
     453                 :             : !                      \Phi3_{ijk}^{\alpha\beta\gamma}.udiff_k^\xi(t).udiff_j^\nu(t)
     454         [ +  + ]:     6430428 :           do nu=1,3
     455         [ +  + ]:    20640880 :             do xi=1,3
     456                 :             :               Solver%fcoeff(iindex+1:iindex+3,ncoeff_prev+1:ncoeff_prev+ncoeff)= &
     457                 :             : &             Solver%fcoeff(iindex+1:iindex+3,ncoeff_prev+1:ncoeff_prev+ncoeff)+&
     458   [ +  +  +  + ]:   391203840 : &             SSS_proj(1:3,nu,xi,1:ncoeff)*udiff_ji(nu)*udiff_ki(xi)/2.d0*MD%weights(istep)
     459                 :             :             end do
     460                 :             :           end do
     461                 :             :         end do !istep
     462         [ -  + ]:       87716 :         ABI_FREE(SSS_proj)
     463                 :             :       end do !iatshell
     464                 :             :     end do !iatom
     465                 :             :   end do !ishell
     466                 :          14 :   write(Invar%stdout,*) ' ------- achieved'
     467         [ +  + ]:         510 :   do isym=1,Sym%nsym
     468         [ +  + ]:        3486 :     do itrans=1,6
     469         [ -  + ]:        3472 :       ABI_FREE(Const%Sprod(isym,itrans)%SSS)
     470                 :             :     end do
     471                 :             :   end do
     472   [ +  -  +  +  :        3004 :   ABI_FREE(Const%Sprod)
          -  +  -  +  -  
                +  -  + ]
     473                 :             : 
     474                 :          14 : end subroutine tdep_calc_phi3fcoeff
     475                 :             : 
     476                 :             : !====================================================================================================
     477                 :             : 
     478                 :           8 : subroutine tdep_calc_phi4fcoeff(Solver,Invar,Shell4at,Sym,MD)
     479                 :             : 
     480                 :             :   type(tdep_Solver_type), intent(inout) :: Solver
     481                 :             :   type(atdep_dataset_type),intent(in) :: Invar
     482                 :             :   type(Shell_type),intent(in) :: Shell4at
     483                 :             :   type(Symmetries_type),intent(in) :: Sym
     484                 :             :   type(tdep_Sampling_type), intent(inout) :: MD
     485                 :             : 
     486                 :             :   integer :: ishell,ncoeff,ncoeff_prev,istep,iatom,jatom,katom,latom
     487                 :             :   integer :: icoeff,isym,iatshell,itrans,counter
     488                 :             :   integer :: mu,nu,xi,zeta,alpha,beta,gama,delta,iindex_l,iindex_h
     489                 :             :   integer :: ncoeff_prev_l,ncoeff_prev_h
     490                 :             :   double precision :: temp,SSSS_tmp(81),proj_tmp(81)
     491                 :           8 :   double precision, allocatable :: SSSS_proj(:,:,:,:,:)
     492                 :           8 :   type(Constraints_type) :: Const
     493                 :             : 
     494   [ -  +  +  -  :        7032 :   ABI_MALLOC(Const%Sprod,(Sym%nsym,24))
          +  -  +  -  -  
          +  -  +  +  +  
                   +  + ]
     495         [ +  + ]:         292 :   do isym=1,Sym%nsym
     496         [ +  + ]:        7108 :     do itrans=1,24
     497   [ -  +  -  +  :    59899292 :       ABI_MALLOC(Const%Sprod(isym,itrans)%SSSS,(3,81,3,3,3)); Const%Sprod(isym,itrans)%SSSS(:,:,:,:,:)=zero
          +  +  +  +  +  
             +  +  +  +  
                      + ]
     498                 :             :     end do
     499                 :             :   end do
     500                 :             : 
     501                 :             : ! For each couple of atoms, transform the Phi4 (3x3x3) ifc matrix using the symetry operation (S)
     502                 :             : ! Note: iatom=1 is excluded in order to take into account the atomic sum rule (see below)
     503         [ +  + ]:         292 :   do isym=1,Sym%nsym
     504         [ +  + ]:        1144 :     do mu=1,3
     505         [ +  + ]:        3692 :       do alpha=1,3
     506         [ +  + ]:       11076 :         do nu=1,3
     507         [ +  + ]:       33228 :           do beta=1,3
     508         [ +  + ]:       99684 :             do xi=1,3
     509         [ +  + ]:      299052 :               do gama=1,3
     510         [ +  + ]:      897156 :                 do zeta=1,3
     511         [ +  + ]:     2691468 :                   do delta=1,3
     512                 :             : #if defined FC_NVHPC
     513                 :             :                     if (itrans == -1) write(std_out, *)"NVHPC freezes here that is fixed by this print statement."
     514                 :             : #endif
     515                 :             : 
     516                 :     1863324 :                     counter=delta+(gama-1)*3+(beta-1)*9+(alpha-1)*27
     517                 :             :                     temp=Sym%S_ref(mu,alpha,isym,1)*Sym%S_ref(nu  ,beta ,isym,1)*&
     518                 :     1863324 : &                        Sym%S_ref(xi,gama ,isym,1)*Sym%S_ref(zeta,delta,isym,1)
     519                 :     1863324 :                     Const%Sprod(isym,1 )%SSSS(mu,counter,nu,xi,zeta)=temp !\Phi4_efgh
     520                 :     1863324 :                     Const%Sprod(isym,2 )%SSSS(mu,counter,xi,nu,zeta)=temp !\Phi4_egfh
     521                 :     1863324 :                     Const%Sprod(isym,3 )%SSSS(nu,counter,mu,xi,zeta)=temp !\Phi4_fegh
     522                 :     1863324 :                     Const%Sprod(isym,4 )%SSSS(nu,counter,xi,mu,zeta)=temp !\Phi4_fgeh
     523                 :     1863324 :                     Const%Sprod(isym,5 )%SSSS(xi,counter,mu,nu,zeta)=temp !\Phi4_gefh
     524                 :     1863324 :                     Const%Sprod(isym,6 )%SSSS(xi,counter,nu,mu,zeta)=temp !\Phi4_gfeh
     525                 :             : 
     526                 :     1863324 :                     Const%Sprod(isym,7 )%SSSS(mu,counter,nu,zeta,xi)=temp !\Phi4_efhg
     527                 :     1863324 :                     Const%Sprod(isym,8 )%SSSS(mu,counter,xi,zeta,nu)=temp !\Phi4_eghf
     528                 :     1863324 :                     Const%Sprod(isym,9 )%SSSS(nu,counter,mu,zeta,xi)=temp !\Phi4_fehg
     529                 :     1863324 :                     Const%Sprod(isym,10)%SSSS(nu,counter,xi,zeta,mu)=temp !\Phi4_fghe
     530                 :     1863324 :                     Const%Sprod(isym,11)%SSSS(xi,counter,mu,zeta,nu)=temp !\Phi4_gehf
     531                 :     1863324 :                     Const%Sprod(isym,12)%SSSS(xi,counter,nu,zeta,mu)=temp !\Phi4_gfhe
     532                 :             : 
     533                 :     1863324 :                     Const%Sprod(isym,13)%SSSS(mu,counter,zeta,nu,xi)=temp !\Phi4_ehfg
     534                 :     1863324 :                     Const%Sprod(isym,14)%SSSS(mu,counter,zeta,xi,nu)=temp !\Phi4_ehgf
     535                 :     1863324 :                     Const%Sprod(isym,15)%SSSS(nu,counter,zeta,mu,xi)=temp !\Phi4_fheg
     536                 :     1863324 :                     Const%Sprod(isym,16)%SSSS(nu,counter,zeta,xi,mu)=temp !\Phi4_fhge
     537                 :     1863324 :                     Const%Sprod(isym,17)%SSSS(xi,counter,zeta,mu,nu)=temp !\Phi4_ghef
     538                 :     1863324 :                     Const%Sprod(isym,18)%SSSS(xi,counter,zeta,nu,mu)=temp !\Phi4_ghfe
     539                 :             : 
     540                 :     1863324 :                     Const%Sprod(isym,19)%SSSS(zeta,counter,mu,nu,xi)=temp !\Phi4_hefg
     541                 :     1863324 :                     Const%Sprod(isym,20)%SSSS(zeta,counter,mu,xi,nu)=temp !\Phi4_hegf
     542                 :     1863324 :                     Const%Sprod(isym,21)%SSSS(zeta,counter,nu,mu,xi)=temp !\Phi4_hfeg
     543                 :     1863324 :                     Const%Sprod(isym,22)%SSSS(zeta,counter,nu,xi,mu)=temp !\Phi4_hfge
     544                 :     1863324 :                     Const%Sprod(isym,23)%SSSS(zeta,counter,xi,mu,nu)=temp !\Phi4_hgef
     545                 :     2484432 :                     Const%Sprod(isym,24)%SSSS(zeta,counter,xi,nu,mu)=temp !\Phi4_hgfe
     546                 :             : 
     547                 :             :                   end do
     548                 :             :                 end do
     549                 :             :               end do
     550                 :             :             end do
     551                 :             :           end do
     552                 :             :         end do
     553                 :             :       end do
     554                 :             :     end do
     555                 :             :   end do
     556                 :             : 
     557                 :           8 :   write(Invar%stdout,*) ' Compute the coefficients (at the 4th order) used in the Moore-Penrose...'
     558         [ +  + ]:          54 :   do ishell=1,Shell4at%nshell
     559         [ +  + ]:        7886 :     do iatom=1,Invar%natom
     560         [ +  + ]:        7832 :       if (Shell4at%neighbours(iatom,ishell)%n_interactions.eq.0) cycle
     561         [ +  + ]:      250586 :       do iatshell=1,Shell4at%neighbours(iatom,ishell)%n_interactions
     562                 :      243732 :         jatom=Shell4at%neighbours(iatom,ishell)%atomj_in_shell(iatshell)
     563                 :      243732 :         katom=Shell4at%neighbours(iatom,ishell)%atomk_in_shell(iatshell)
     564                 :      243732 :         latom=Shell4at%neighbours(iatom,ishell)%atoml_in_shell(iatshell)
     565                 :      243732 :         isym =Shell4at%neighbours(iatom,ishell)%sym_in_shell(iatshell)
     566                 :      243732 :         itrans=Shell4at%neighbours(iatom,ishell)%transpose_in_shell(iatshell)
     567                 :      243732 :         ncoeff     =Shell4at%ncoeff(ishell)
     568                 :      243732 :         ncoeff_prev=Shell4at%ncoeff_prev(ishell)+Solver%ncoeff3rd+Solver%ncoeff2nd+Solver%ncoeff1st
     569                 :      243732 :         ncoeff_prev_l=ncoeff_prev+1
     570                 :      243732 :         ncoeff_prev_h=ncoeff_prev+ncoeff
     571                 :             : #if defined FC_NVHPC
     572                 :             :         if (itrans == -1) write(std_out, *)"NVHPC freezes here that is fixed by this print statement."
     573                 :             : #endif
     574   [ -  +  +  -  :   699105928 :         ABI_MALLOC(SSSS_proj,(3,3,3,3,ncoeff)) ; SSSS_proj(:,:,:,:,:)=zero
          +  -  +  -  -  
          +  -  +  +  +  
          +  +  +  +  +  
                +  +  + ]
     575         [ +  + ]:      974928 :         do mu=1,3
     576         [ +  + ]:     3168516 :           do nu=1,3
     577         [ +  + ]:     9505548 :             do xi=1,3
     578         [ +  + ]:    28516644 :               do zeta=1,3
     579         [ +  + ]:  1618867944 :                 SSSS_tmp(:)=Const%Sprod(isym,itrans)%SSSS(mu,:,nu,xi,zeta)
     580         [ +  + ]:   493830108 :                 do icoeff=1,ncoeff
     581         [ +  + ]: 38335578264 :                   proj_tmp(:)=Shell4at%proj(:,icoeff,ishell)
     582                 :             : !                 SSSS_proj(mu,nu,xi,zeta,icoeff)=DDOT(81,Const%Sprod(isym,itrans)%SSSS(mu,:,nu,xi,zeta),1,proj(:,icoeff,ishell),1)
     583                 :   487249344 :                   SSSS_proj(mu,nu,xi,zeta,icoeff)=DDOT(81,SSSS_tmp,1,proj_tmp,1)
     584                 :             :                 end do
     585                 :             :               end do
     586                 :             :             end do
     587                 :             :           end do
     588                 :             :         end do
     589         [ +  + ]:     5118372 :         do istep=1,Invar%my_nstep
     590                 :     4874640 :           iindex_l=3*(iatom-1)+3*Invar%natom*(istep-1)+1
     591                 :     4874640 :           iindex_h=3*(iatom-1)+3*Invar%natom*(istep-1)+3
     592                 :             : !         F_i^{\mu}(t)=\sum_{\alpha\beta\gamma\delta,jkl,\nu\xi\zeta} S^{\mu\alpha}.S^{\nu\beta}.S^{\xi\gamma}.S^{\zeta\delta}.
     593                 :             : !                      \Phi4_{ijkl}^{\alpha\beta\gamma\delta}.u_l^\zeta(t).u_k^\xi(t).u_j^\nu(t)
     594         [ +  + ]:    19742292 :           do nu=1,3
     595         [ +  + ]:    63370320 :             do xi=1,3
     596         [ +  + ]:   190110960 :               do zeta=1,3
     597                 :             :                 Solver%fcoeff(iindex_l:iindex_h,ncoeff_prev_l:ncoeff_prev_h)= &
     598                 :             : &               Solver%fcoeff(iindex_l:iindex_h,ncoeff_prev_l:ncoeff_prev_h)+&
     599                 :             : &               SSSS_proj(1:3,nu,xi,zeta,1:ncoeff)*MD%ucart(nu,jatom,istep)*MD%ucart(xi,katom,istep)*MD%ucart(zeta,latom,istep)/6.d0 *&
     600   [ +  +  +  + ]: 12642341760 : &               MD%weights(istep)
     601                 :             :               end do
     602                 :             :             end do
     603                 :             :           end do
     604                 :             :         end do !istep
     605         [ -  + ]:      251564 :         ABI_FREE(SSSS_proj)
     606                 :             :       end do !iatshell
     607                 :             :     end do !iatom
     608                 :             :   end do !ishell
     609                 :           8 :   write(Invar%stdout,*) ' ------- achieved'
     610         [ +  + ]:         292 :   do isym=1,Sym%nsym
     611         [ +  + ]:        7108 :     do itrans=1,24
     612         [ -  + ]:        7100 :       ABI_FREE(Const%Sprod(isym,itrans)%SSSS)
     613                 :             :     end do
     614                 :             :   end do
     615   [ +  -  +  +  :        6832 :   ABI_FREE(Const%Sprod)
          -  +  -  +  -  
                +  -  + ]
     616                 :             : 
     617                 :           8 : end subroutine tdep_calc_phi4fcoeff
     618                 :             : 
     619                 :             : !=====================================================================================================
     620                 :             : 
     621                 :          45 :  subroutine tdep_calc_MoorePenrose(Solver,simult,Invar,MPIdata)
     622                 :             : 
     623                 :             :   type(tdep_Solver_type), intent(inout) :: Solver
     624                 :             :   type(atdep_dataset_type),intent(in) :: Invar
     625                 :             :   type(MPI_enreg_type), intent(in) :: MPIdata
     626                 :             :   integer, intent(in) :: simult
     627                 :             : 
     628                 :             :   integer :: INFO,ntotcoeff,ntotconst
     629                 :             :   integer :: natnstep,nconcoef,ierr,ncoeff_prev,nconst_prev,iconst,icoeff
     630                 :          45 :   integer, allocatable :: IPIV(:)
     631                 :          45 :   double precision, allocatable :: WORK(:)
     632                 :          45 :   double precision, allocatable :: ffcoeff_tmp(:,:),fforces_tmp(:),b_const(:)
     633                 :          45 :   double precision, allocatable :: A_tot(:,:),A_inv(:,:),b_tot(:),x_tot(:)
     634                 :             : 
     635                 :          45 :   write(Invar%stdout,*) '################### And compute the pseudo-inverse ##########################'
     636                 :          45 :   write(Invar%stdout,*) '#############################################################################'
     637                 :             : 
     638                 :          45 :   natnstep = 3 * Solver%natom * Solver%my_nstep
     639                 :             : 
     640         [ +  + ]:          45 :   if (simult.eq.0) then
     641                 :             : !   Simultaneously (Invar%together=1)
     642                 :          42 :     ncoeff_prev=0
     643                 :          42 :     nconst_prev=0
     644                 :          42 :     ntotcoeff=Solver%ntotcoeff
     645                 :          42 :     ntotconst=Solver%ntotconst
     646         [ +  + ]:           3 :   else if (simult.eq.1) then
     647                 :             : !   Successively (Invar%together=0 and Invar%order=2)
     648                 :           1 :     ncoeff_prev=0
     649                 :           1 :     nconst_prev=0
     650                 :           1 :     ntotcoeff=Solver%ncoeff1st +Solver%ncoeff2nd
     651                 :           1 :     ntotconst=Solver%nconst_1st+Solver%nconst_2nd
     652         [ +  + ]:           2 :   else if (simult.eq.2) then
     653                 :             : !   Successively (Invar%together=0 and Invar%order=3)
     654                 :           1 :     ncoeff_prev=Solver%ncoeff1st +Solver%ncoeff2nd
     655                 :           1 :     nconst_prev=Solver%nconst_1st+Solver%nconst_2nd
     656                 :           1 :     ntotcoeff=Solver%ncoeff3rd
     657                 :           1 :     ntotconst=Solver%nconst_3rd
     658         [ +  - ]:           1 :   else if (simult.eq.3) then
     659                 :             : !   Successively (Invar%together=0 and Invar%order=4)
     660                 :           1 :     ncoeff_prev=Solver%ncoeff1st +Solver%ncoeff2nd +Solver%ncoeff3rd
     661                 :           1 :     nconst_prev=Solver%nconst_1st+Solver%nconst_2nd+Solver%nconst_3rd
     662                 :           1 :     ntotcoeff=Solver%ncoeff4th
     663                 :           1 :     ntotconst=Solver%nconst_4th
     664                 :             :   end if
     665                 :          45 :   nconcoef=ntotcoeff+ntotconst
     666   [ +  +  +  + ]:          45 :   if ((ntotconst.gt.0).and.(simult.ge.2)) then
     667   [ -  +  +  -  :          23 :     ABI_MALLOC(b_const,(ntotconst)) ; b_const(:)=0.d0
          +  -  -  +  -  
                +  +  + ]
     668         [ +  + ]:          21 :     do iconst=1,ntotconst
     669         [ +  + ]:         521 :       do icoeff=1,ncoeff_prev
     670                 :             :         b_const(iconst)=b_const(iconst)+&
     671                 :         520 : &         Solver%const(nconst_prev+iconst,icoeff)*Solver%theta(icoeff)
     672                 :             :       end do
     673                 :             :     end do
     674                 :             :   end if
     675                 :             : 
     676   [ -  +  +  -  :      461308 :   ABI_CALLOC(ffcoeff_tmp,(ntotcoeff,ntotcoeff))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
     677   [ -  +  +  -  :        2780 :   ABI_CALLOC(fforces_tmp,(ntotcoeff))
          +  -  +  -  -  
             +  -  +  +  
                      + ]
     678   [ -  +  +  -  :      653574 :   ABI_CALLOC(A_tot,(nconcoef,nconcoef))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
     679   [ -  +  +  -  :      653574 :   ABI_CALLOC(A_inv,(nconcoef,nconcoef))
          -  +  +  -  -  
          +  +  -  +  +  
                   +  + ]
     680   [ -  +  +  -  :        3194 :   ABI_CALLOC(b_tot,(nconcoef))
          +  -  +  -  -  
             +  +  -  +  
                      + ]
     681   [ -  +  +  -  :        3149 :   ABI_CALLOC(x_tot,(nconcoef))
          -  +  +  -  +  
                      + ]
     682                 :             :   call DGEMM('T','N',ntotcoeff,ntotcoeff,natnstep,2.d0,&
     683                 :             : &            Solver%fcoeff(:,ncoeff_prev+1:ncoeff_prev+ntotcoeff),natnstep,&
     684                 :             : &            Solver%fcoeff(:,ncoeff_prev+1:ncoeff_prev+ntotcoeff),natnstep,&
     685                 :          45 : &            0.d0,ffcoeff_tmp,ntotcoeff)
     686                 :             : ! NOTE, we have to solve F_ij = -\sum_j \Phi_ij u_j, so we add a minus sign
     687                 :             :   call DGEMV('T',natnstep,ntotcoeff,-2.d0,&
     688                 :             : &            Solver%fcoeff(:,ncoeff_prev+1:ncoeff_prev+ntotcoeff),natnstep,&
     689                 :          45 : &            Solver%Forces,1,0.d0,fforces_tmp,1)
     690                 :          45 :   call xmpi_sum(ffcoeff_tmp,MPIdata%comm_step,ierr)
     691                 :          45 :   call xmpi_sum(fforces_tmp,MPIdata%comm_step,ierr)
     692                 :             : 
     693   [ +  +  +  + ]:      461173 :   A_tot(1:ntotcoeff,1:ntotcoeff)=ffcoeff_tmp(1:ntotcoeff,1:ntotcoeff)
     694         [ -  + ]:          45 :   ABI_FREE(ffcoeff_tmp)
     695         [ +  + ]:          45 :   if (ntotconst.gt.0) then
     696                 :             :     A_tot(ntotcoeff+1:nconcoef,1:ntotcoeff)=&
     697   [ +  +  +  + ]:       88222 : &                     Solver%const(nconst_prev+1:nconst_prev+ntotconst,ncoeff_prev+1:ncoeff_prev+ntotcoeff)
     698                 :             :     A_tot(1:ntotcoeff,ntotcoeff+1:nconcoef)=&
     699   [ +  +  +  + ]:       86382 : &                     transpose(Solver%const(nconst_prev+1:nconst_prev+ntotconst,ncoeff_prev+1:ncoeff_prev+ntotcoeff))
     700                 :             : !FB    ABI_FREE(Solver%const)
     701                 :             :   end if
     702         [ +  + ]:        2690 :   b_tot(1:ntotcoeff)=fforces_tmp(:)
     703   [ +  +  +  + ]:          45 :   if ((ntotconst.gt.0).and.(simult.ge.2)) then
     704         [ +  + ]:          21 :     b_tot(ntotcoeff+1:nconcoef)=-b_const(1:ntotconst)
     705         [ -  + ]:           1 :     ABI_FREE(b_const)
     706                 :             :   end if
     707         [ -  + ]:          45 :   ABI_FREE(fforces_tmp)
     708                 :             : 
     709   [ +  -  -  +  :       15205 :   ABI_MALLOC(WORK, (5 * nconcoef)); WORK(:) = 0.d0
          +  -  +  -  +  
          -  -  +  -  +  
                   +  + ]
     710   [ -  +  +  -  :        3194 :   ABI_MALLOC(IPIV, (nconcoef)); IPIV(:) = 0
          +  -  +  -  -  
             +  +  -  +  
                      + ]
     711   [ +  +  +  + ]:      653439 :   A_inv(:,:) = A_tot(:,:)
     712                 :             :   !BEGIN DEBUG
     713                 :             :   !write(Invar%stdout,*) ' '
     714                 :             :   !write(Invar%stdout,*) ' The matrix A_inv is (before DGETRF):'
     715                 :             :   !do icoeff=1,nconcoef
     716                 :             :   !  write(Invar%stdout,*) (A_inv(icoeff,iconst), iconst=1, nconcoef)
     717                 :             :   !end do
     718                 :             :   !END DEBUG
     719                 :             : 
     720                 :             :   ! Check for small pivot elements
     721         [ +  + ]:        3059 :   do icoeff=1,nconcoef
     722         [ +  + ]:        3059 :     if (abs(A_inv(icoeff, icoeff)) < tol12) then
     723                 :         369 :       write(Invar%stdlog,*) ' WARNING: Small pivot value at index ', icoeff, ' : ', A_inv(icoeff, icoeff)
     724                 :             : !      A_inv(icoeff, icoeff) = tol14 ! Regularization to avoid numerical issues
     725   [ +  +  +  +  :    50146203 :       A_inv(icoeff, icoeff) = max(EPSILON(1.0_dp) * maxval(abs(A_inv)), tol12)
          +  +  +  -  -  
                +  -  - ]
     726                 :             :     end if
     727                 :             :   end do
     728                 :             : 
     729                 :             :   ! Perform LU factorization
     730                 :          45 :   call DGETRF(nconcoef, nconcoef, A_inv, nconcoef, IPIV, INFO)
     731         [ -  + ]:          45 :   if (INFO.ne.0) then
     732                 :           0 :     write(Invar%stdout,*) 'ERROR: Singular matrix detected in DGETRF. INFO=', INFO
     733                 :           0 :     stop
     734                 :             :   end if
     735                 :             : 
     736                 :             :   ! Check for small pivot elements
     737         [ +  + ]:        3059 :   do icoeff=1,nconcoef
     738         [ -  + ]:        3059 :     if (abs(A_inv(icoeff, icoeff)) < tol12) then
     739                 :           0 :       write(Invar%stdlog,*) ' WARNING: Small pivot value at index ', icoeff, ' : ', A_inv(icoeff, icoeff)
     740                 :             : !      A_inv(icoeff, icoeff) = tol14 ! Regularization to avoid numerical issues
     741   [ #  #  #  #  :           0 :       A_inv(icoeff, icoeff) = max(EPSILON(1.0_dp) * maxval(abs(A_inv)), tol12)
          #  #  #  #  #  
                #  #  # ]
     742                 :             :     end if
     743                 :             :   end do
     744                 :             : 
     745                 :             :   ! Compute matrix inverse using LU decomposition
     746                 :          45 :   call DGETRI(nconcoef, A_inv, nconcoef, IPIV, WORK, 5 * nconcoef, INFO)
     747         [ -  + ]:          45 :   if (INFO.ne.0) then
     748                 :           0 :     write(Invar%stdout,*) 'ERROR: Matrix inversion failed in DGETRI. INFO=', INFO
     749                 :           0 :     stop
     750                 :             :   end if
     751                 :             :   ! BEGIN DEBUG
     752                 :             :   !write(Invar%stdout,*) ' '
     753                 :             :   !write(Invar%stdout,*) ' The inverse matrix is (after DGETRI):'
     754                 :             :   !do icoeff=1,nconcoef
     755                 :             :   !  write(Invar%stdout,*) (A_inv(icoeff,iconst), iconst=1, nconcoef)
     756                 :             :   !end do
     757                 :             :   ! END DEBUG
     758                 :             : 
     759         [ -  + ]:          45 :   ABI_FREE(WORK)
     760         [ -  + ]:          45 :   ABI_FREE(IPIV)
     761                 :             : 
     762                 :          45 :   call DGEMV('N',nconcoef,nconcoef,1.d0,A_inv,nconcoef,b_tot,1,0.d0,x_tot,1)
     763                 :          45 :   write(Invar%stdout,*) ' The problem is solved'
     764                 :          45 :   write(Invar%stdout,*) ' '
     765                 :             :   !BEGIN DEBUG
     766                 :             :   !write(Invar%stdout,*) ' The solutions are:'
     767                 :             :   !do icoeff=1,nconcoef
     768                 :             :   !  write(Invar%stdout,'(1x,i4,1x,f15.10)') icoeff,x_tot(icoeff)
     769                 :             :   !end do
     770                 :             :   !write(Invar%stdout,'(a,1x,f15.10)')'  condition number=',maxval(x_tot(:))/minval(x_tot(:))
     771                 :             :   !END DEBUG
     772                 :             : 
     773         [ +  + ]:        2690 :   Solver%theta(ncoeff_prev+1:ncoeff_prev+ntotcoeff)=x_tot(1:ntotcoeff)
     774         [ -  + ]:          45 :   ABI_FREE(A_tot)
     775         [ -  + ]:          45 :   ABI_FREE(A_inv)
     776         [ -  + ]:          45 :   ABI_FREE(b_tot)
     777         [ -  + ]:          45 :   ABI_FREE(x_tot)
     778                 :             : 
     779         [ -  + ]:          90 :  end subroutine tdep_calc_MoorePenrose
     780                 :             : 
     781                 :             : 
     782                 :             : !====================================================================================================
     783                 :             : 
     784                 :          44 : subroutine tdep_calc_constraints(Solver,distance,Invar,MPIdata,Sym,&
     785                 :             : &                                Shell1at,Shell2at,Shell3at,Shell4at)
     786                 :             : 
     787                 :             :   type(tdep_Solver_type), intent(inout) :: Solver
     788                 :             :   type(atdep_dataset_type),intent(in) :: Invar
     789                 :             :   type(Symmetries_type),intent(in) :: Sym
     790                 :             :   type(MPI_enreg_type), intent(in) :: MPIdata
     791                 :             :   type(Shell_type),intent(in) :: Shell1at
     792                 :             :   type(Shell_type),intent(in) :: Shell2at
     793                 :             :   type(Shell_type),optional,intent(in) :: Shell3at
     794                 :             :   type(Shell_type),optional,intent(in) :: Shell4at
     795                 :             :   double precision, intent(in) :: distance(Invar%natom,Invar%natom,4)
     796                 :             : 
     797                 :             :   integer :: ishell,ncoeff,ncoeff_prev,iatom,jatom,katom,latom,iatshell,counter
     798                 :             :   integer :: icoeff,iconst,nconst_loc,iconst_loc,iconst_new,isym,itrans,ntotcoeff,iat_mod
     799                 :             :   integer :: mu,nu,xi,zeta,alpha,beta,gama,delta,lambda,natom_unitcell,natom,ii
     800                 :             :   double precision :: terme,temp,terme1,terme2,terme3,terme4
     801                 :          44 :   double precision, allocatable :: SS_ref(:,:,:,:,:)
     802                 :          44 :   double precision, allocatable :: vect(:,:)
     803                 :          44 :   double precision, allocatable :: const_rot1st(:,:,:)
     804                 :          44 :   double precision, allocatable :: const_rot2nd(:,:,:,:,:)
     805                 :          44 :   double precision, allocatable :: const_dynmat(:,:,:,:,:)
     806                 :          44 :   double precision, allocatable :: const_huang(:,:,:,:,:)
     807                 :             : !FB  double precision, allocatable :: const_asr4th(:,:,:,:,:,:)
     808                 :             : !FB  double precision, allocatable :: const_rot4th(:,:,:,:,:,:,:)
     809                 :          44 :   type(Constraints_type) :: Const3,Const4
     810                 :             :   logical :: order2,order3,order4
     811                 :             : 
     812                 :             :   !TODO Move parts of this routine into m_tdep_constraints
     813                 :             : 
     814                 :          44 :   natom_unitcell=Invar%natom_unitcell
     815                 :          44 :   natom         =Invar%natom
     816                 :             : 
     817                 :          44 :   order2 = .false.
     818                 :          44 :   order3 = .false.
     819                 :          44 :   order4 = .false.
     820         [ +  - ]:          44 :   if (Invar%order.ge.2) order2=.true.
     821         [ +  + ]:          44 :   if (Invar%order.ge.3) order3=.true.
     822                 :             : !FB4th  if (Invar%order.ge.4) order4=.true.
     823                 :             :   if (Invar%order.ge.4) order4=.false.
     824                 :             : 
     825                 :          44 :   write(Invar%stdout,*) ' '
     826                 :          44 :   write(Invar%stdout,*) '#############################################################################'
     827                 :          44 :   write(Invar%stdout,*) '###################### Compute the constraints ##############################'
     828                 :             : 
     829                 :             : ! For each couple of atoms, transform the Phi2 (3x3) ifc matrix using the symetry operation (S)
     830         [ +  - ]:          44 :   if (order2.or.order3) then
     831   [ -  +  +  -  :      363592 :     ABI_CALLOC(SS_ref,(3,9,3,Sym%nsym,2))
          +  -  +  -  +  
          -  -  +  -  +  
          +  +  +  +  +  
             +  +  +  +  
                      + ]
     832         [ +  + ]:        1666 :     do isym=1,Sym%nsym
     833         [ +  + ]:        6532 :       do alpha=1,3
     834         [ +  + ]:       21086 :         do mu=1,3
     835         [ +  + ]:       63258 :           do beta=1,3
     836         [ +  + ]:      189774 :             do nu=1,3
     837                 :      131382 :               temp=Sym%S_ref(alpha,mu,isym,1)*Sym%S_ref(beta,nu,isym,1)
     838                 :      131382 :               SS_ref(alpha,nu+(mu-1)*3,beta,isym,1)=temp
     839                 :      175176 :               SS_ref(alpha,mu+(nu-1)*3,beta,isym,2)=temp
     840                 :             :             end do
     841                 :             :           end do
     842                 :             :         end do
     843                 :             :       end do
     844                 :             :     end do
     845                 :             :   end if
     846                 :             : ! For each couple of atoms, transform the Phi3 (3x3x3) ifc matrix using the symetry operation (S)
     847         [ +  + ]:          44 :   if (order3.or.order4) then
     848   [ -  +  +  -  :        3102 :     ABI_MALLOC(Const3%Sprod,(Sym%nsym,6))
          +  -  +  -  -  
          +  -  +  +  +  
                   +  + ]
     849         [ +  + ]:         510 :     do isym=1,Sym%nsym
     850         [ +  + ]:        3486 :       do itrans=1,6
     851   [ -  +  -  +  :     2931856 :         ABI_CALLOC(Const3%Sprod(isym,itrans)%SSS,(3,27,3,3))
          +  +  +  +  +  
                +  +  + ]
     852                 :             :       end do
     853                 :             :     end do
     854         [ +  + ]:         510 :     do isym=1,Sym%nsym
     855         [ +  + ]:        1998 :       do alpha=1,3
     856         [ +  + ]:        6448 :         do mu=1,3
     857         [ +  + ]:       19344 :           do beta=1,3
     858         [ +  + ]:       58032 :             do nu=1,3
     859         [ +  + ]:      174096 :               do gama=1,3
     860         [ +  + ]:      522288 :                 do xi=1,3
     861                 :      361584 :                   temp=Sym%S_ref(alpha,mu,isym,1)*Sym%S_ref(beta,nu,isym,1)*Sym%S_ref(gama,xi,isym,1)
     862                 :      361584 :                   Const3%Sprod(isym,1)%SSS(alpha,xi+(nu-1)*3+(mu-1)*9,beta ,gama) =temp !\Phi3_efg
     863                 :      361584 :                   Const3%Sprod(isym,2)%SSS(alpha,xi+(nu-1)*3+(mu-1)*9,gama ,beta) =temp !\Phi3_egf
     864                 :      361584 :                   Const3%Sprod(isym,3)%SSS(beta ,xi+(nu-1)*3+(mu-1)*9,alpha,gama) =temp !\Phi3_feg
     865                 :      361584 :                   Const3%Sprod(isym,4)%SSS(beta ,xi+(nu-1)*3+(mu-1)*9,gama ,alpha)=temp !\Phi3_fge
     866                 :      361584 :                   Const3%Sprod(isym,5)%SSS(gama ,xi+(nu-1)*3+(mu-1)*9,alpha,beta) =temp !\Phi3_gef
     867                 :      482112 :                   Const3%Sprod(isym,6)%SSS(gama ,xi+(nu-1)*3+(mu-1)*9,beta ,alpha)=temp !\Phi3_gfe
     868                 :             :                 end do
     869                 :             :               end do
     870                 :             :             end do
     871                 :             :             end do
     872                 :             :         end do
     873                 :             :       end do
     874                 :             :     end do
     875                 :             :   end if
     876                 :             : 
     877                 :             : ! For each couple of atoms, transform the Phi4 (3x3x3x3) ifc matrix using the symetry operation (S)
     878                 :             :   if (order4) then
     879                 :             :     ABI_MALLOC(Const4%Sprod,(Sym%nsym,24))
     880                 :             :     do isym=1,Sym%nsym
     881                 :             :       do itrans=1,24
     882                 :             :         ABI_CALLOC(Const4%Sprod(isym,itrans)%SSSS,(3,81,3,3,3))
     883                 :             :       end do
     884                 :             :     end do
     885                 :             :     do isym=1,Sym%nsym
     886                 :             :       do alpha=1,3
     887                 :             :         do mu=1,3
     888                 :             :           do beta=1,3
     889                 :             :             do nu=1,3
     890                 :             :               do gama=1,3
     891                 :             :                 do xi=1,3
     892                 :             :                   do delta=1,3
     893                 :             :                     do zeta=1,3
     894                 :             :                       counter=zeta+(xi-1)*3+(nu-1)*9+(mu-1)*27
     895                 :             :                       temp=Sym%S_ref(alpha,mu,isym,1)*Sym%S_ref(beta  ,nu ,isym,1)*&
     896                 :             : &                          Sym%S_ref(gama,xi ,isym,1)*Sym%S_ref(delta,zeta,isym,1)
     897                 :             :                       Const4%Sprod(isym,1 )%SSSS(alpha,counter,beta,gama,delta)=temp !\Phi4_efgh
     898                 :             :                       Const4%Sprod(isym,2 )%SSSS(alpha,counter,gama,beta,delta)=temp !\Phi4_egfh
     899                 :             :                       Const4%Sprod(isym,3 )%SSSS(beta,counter,alpha,gama,delta)=temp !\Phi4_fegh
     900                 :             :                       Const4%Sprod(isym,4 )%SSSS(beta,counter,gama,alpha,delta)=temp !\Phi4_fgeh
     901                 :             :                       Const4%Sprod(isym,5 )%SSSS(gama,counter,alpha,beta,delta)=temp !\Phi4_gefh
     902                 :             :                       Const4%Sprod(isym,6 )%SSSS(gama,counter,beta,alpha,delta)=temp !\Phi4_gfeh
     903                 :             : 
     904                 :             :                       Const4%Sprod(isym,7 )%SSSS(alpha,counter,beta,delta,gama)=temp !\Phi4_efhg
     905                 :             :                       Const4%Sprod(isym,8 )%SSSS(alpha,counter,gama,delta,beta)=temp !\Phi4_eghf
     906                 :             :                       Const4%Sprod(isym,9 )%SSSS(beta,counter,alpha,delta,gama)=temp !\Phi4_fehg
     907                 :             :                       Const4%Sprod(isym,10)%SSSS(beta,counter,gama,delta,alpha)=temp !\Phi4_fghe
     908                 :             :                       Const4%Sprod(isym,11)%SSSS(gama,counter,alpha,delta,beta)=temp !\Phi4_gehf
     909                 :             :                       Const4%Sprod(isym,12)%SSSS(gama,counter,beta,delta,alpha)=temp !\Phi4_gfhe
     910                 :             : 
     911                 :             :                       Const4%Sprod(isym,13)%SSSS(alpha,counter,delta,beta,gama)=temp !\Phi4_ehfg
     912                 :             :                       Const4%Sprod(isym,14)%SSSS(alpha,counter,delta,gama,beta)=temp !\Phi4_ehgf
     913                 :             :                       Const4%Sprod(isym,15)%SSSS(beta,counter,delta,alpha,gama)=temp !\Phi4_fheg
     914                 :             :                       Const4%Sprod(isym,16)%SSSS(beta,counter,delta,gama,alpha)=temp !\Phi4_fhge
     915                 :             :                       Const4%Sprod(isym,17)%SSSS(gama,counter,delta,alpha,beta)=temp !\Phi4_ghef
     916                 :             :                       Const4%Sprod(isym,18)%SSSS(gama,counter,delta,beta,alpha)=temp !\Phi4_ghfe
     917                 :             : 
     918                 :             :                       Const4%Sprod(isym,19)%SSSS(delta,counter,alpha,beta,gama)=temp !\Phi4_hefg
     919                 :             :                       Const4%Sprod(isym,20)%SSSS(delta,counter,alpha,gama,beta)=temp !\Phi4_hegf
     920                 :             :                       Const4%Sprod(isym,21)%SSSS(delta,counter,beta,alpha,gama)=temp !\Phi4_hfeg
     921                 :             :                       Const4%Sprod(isym,22)%SSSS(delta,counter,beta,gama,alpha)=temp !\Phi4_hfge
     922                 :             :                       Const4%Sprod(isym,23)%SSSS(delta,counter,gama,alpha,beta)=temp !\Phi4_hgef
     923                 :             :                       Const4%Sprod(isym,24)%SSSS(delta,counter,gama,beta,alpha)=temp !\Phi4_hgfe
     924                 :             : 
     925                 :             :                     end do
     926                 :             :                   end do
     927                 :             :                 end do
     928                 :             :               end do
     929                 :             :             end do
     930                 :             :           end do
     931                 :             :         end do
     932                 :             :       end do
     933                 :             :     end do
     934                 :             :   end if
     935                 :             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     936                 :             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Compute the constraints !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     937                 :             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     938                 :          44 :   ntotcoeff=Solver%ntotcoeff
     939                 :             : ! First order only
     940                 :          44 :   write(Invar%stdout,*) '########################## At the 1st order #################################'
     941         [ +  - ]:          44 :   if (order2) then
     942   [ -  +  +  -  :       35765 :     ABI_CALLOC(const_rot1st, (3,3,ntotcoeff))
          +  -  +  -  -  
          +  -  +  +  +  
             +  +  +  + ]
     943   [ -  +  +  -  :      541517 :     ABI_CALLOC(const_rot2nd, (3,3,3,natom_unitcell,ntotcoeff))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
          +  +  +  +  +  
                   +  + ]
     944   [ -  +  +  -  :     1855835 :     ABI_CALLOC(const_dynmat, (3,3,natom_unitcell,natom_unitcell,ntotcoeff))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
          +  +  +  +  +  
          +  +  +  +  +  
                      + ]
     945   [ -  +  +  -  :      331793 :     ABI_CALLOC(const_huang, (3,3,3,3,ntotcoeff))
          +  -  +  -  -  
          +  -  +  +  +  
          +  +  +  +  +  
                +  +  + ]
     946         [ +  + ]:         107 :     do ishell=1,Shell1at%nshell
     947         [ -  + ]:          63 :       if (Shell1at%neighbours(1,ishell)%n_interactions.eq.0) cycle
     948         [ -  - ]:          44 :       do iatshell=1,Shell1at%neighbours(1,ishell)%n_interactions
     949                 :           0 :         iatom=Shell1at%neighbours(1,ishell)%atomj_in_shell(iatshell)
     950         [ #  # ]:           0 :         if (iatom.ge.natom_unitcell) cycle
     951         [ #  # ]:           0 :         if (iatom.eq.1) cycle
     952                 :           0 :         isym=Shell1at%neighbours(1,ishell)%sym_in_shell(iatshell)
     953                 :           0 :         ncoeff     =Shell1at%ncoeff(ishell)
     954                 :           0 :         ncoeff_prev=Shell1at%ncoeff_prev(ishell)
     955         [ -  - ]:          63 :         do alpha=1,3
     956         [ #  # ]:           0 :           do beta=1,3
     957         [ #  # ]:           0 :             do icoeff=1,ncoeff
     958                 :             : !             1/ Rotational invariances (1st order)
     959         [ #  # ]:           0 :               terme1=sum(Sym%S_ref(alpha,:,isym,1)*Shell1at%proj(:,icoeff,ishell))*distance(1,iatom,beta +1)
     960         [ #  # ]:           0 :               terme2=sum(Sym%S_ref(beta ,:,isym,1)*Shell1at%proj(:,icoeff,ishell))*distance(1,iatom,alpha+1)
     961                 :             :               const_rot1st(alpha,beta,icoeff+ncoeff_prev)= &
     962                 :           0 : &             const_rot1st(alpha,beta,icoeff+ncoeff_prev)+terme1-terme2
     963                 :             : 
     964                 :             : !             2/ Rotational invariances (for the 2nd order)
     965         [ #  # ]:           0 :               do gama=1,3
     966                 :           0 :                 terme1=zero ; terme2=zero
     967   [ #  #  #  # ]:           0 :                 if (alpha.eq.gama) terme1=sum(Sym%S_ref(beta,:,isym,1)*Shell1at%proj(:,icoeff,ishell))
     968   [ #  #  #  # ]:           0 :                 if (alpha.eq.beta) terme2=sum(Sym%S_ref(gama,:,isym,1)*Shell1at%proj(:,icoeff,ishell))
     969                 :             :                 const_rot2nd(alpha,beta,gama,iatom,icoeff+ncoeff_prev)=&
     970                 :           0 : &               const_rot2nd(alpha,beta,gama,iatom,icoeff+ncoeff_prev)+terme1-terme2
     971                 :             :                 const_rot2nd(alpha,beta,gama,1,icoeff+ncoeff_prev)=&
     972                 :           0 : &               const_rot2nd(alpha,beta,gama,1,icoeff+ncoeff_prev)-terme1+terme2
     973                 :             :               end do
     974                 :             :             end do
     975                 :             :           end do
     976                 :             :         end do
     977                 :             :       end do !iatshell
     978                 :             :     end do !ishell
     979                 :             : 
     980                 :             : !   First + second order
     981                 :          44 :     write(Invar%stdout,*) '########################## At the 2nd order #################################'
     982         [ +  + ]:         544 :     do ishell=1,Shell2at%nshell
     983         [ +  + ]:        2830 :       do iatom=1,natom_unitcell
     984         [ +  + ]:        2286 :         if (Shell2at%neighbours(iatom,ishell)%n_interactions.eq.0) cycle
     985         [ +  + ]:        6867 :         do iatshell=1,Shell2at%neighbours(iatom,ishell)%n_interactions
     986                 :        5268 :           jatom=Shell2at%neighbours(iatom,ishell)%atomj_in_shell(iatshell)
     987         [ +  + ]:        5268 :           if (iatom==jatom) cycle
     988                 :        5162 :           isym=Shell2at%neighbours(iatom,ishell)%sym_in_shell(iatshell)
     989                 :        5162 :           itrans=Shell2at%neighbours(iatom,ishell)%transpose_in_shell(iatshell)
     990                 :        5162 :           ncoeff     =Shell2at%ncoeff(ishell)
     991                 :        5162 :           ncoeff_prev=Shell2at%ncoeff_prev(ishell)+Solver%ncoeff1st
     992                 :        5162 :           iat_mod=mod(jatom+natom_unitcell-1,natom_unitcell)+1
     993                 :             : !         1/ Rotational invariances (2nd order). Number of constraints = natom_unitcell*3**2
     994         [ +  + ]:       20648 :           do alpha=1,3
     995         [ +  + ]:       67106 :             do beta=1,3
     996         [ +  + ]:      201318 :               do gama=1,3
     997         [ +  + ]:      834156 :                 do icoeff=1,ncoeff
     998         [ +  + ]:     6483240 :                   terme1=sum(SS_ref(alpha,:,beta,isym,itrans)*Shell2at%proj(:,icoeff,ishell))*distance(iatom,jatom,gama+1)
     999         [ +  + ]:     6483240 :                   terme2=sum(SS_ref(alpha,:,gama,isym,itrans)*Shell2at%proj(:,icoeff,ishell))*distance(iatom,jatom,beta+1)
    1000                 :             :                   const_rot2nd(alpha,beta,gama,iatom,icoeff+ncoeff_prev)=&
    1001                 :      787698 : &                 const_rot2nd(alpha,beta,gama,iatom,icoeff+ncoeff_prev)+terme1-terme2
    1002                 :             :                 end do
    1003                 :             :               end do
    1004                 :             :             end do
    1005                 :             :           end do
    1006                 :             : !         2/ Enforce the symetry of the dynamical matrix. Number of constraints = (3*natom_unitcell)**2
    1007                 :             : !            Note that we are unable to enforce the symetry when iatom=jatom (We have to write the equations)
    1008         [ +  + ]:       20648 :           do alpha=1,3
    1009         [ +  + ]:       67106 :             do beta=1,3
    1010         [ +  + ]:      278052 :               do icoeff=1,ncoeff
    1011                 :             :                 terme=sum(SS_ref(alpha,:,beta,isym,itrans)*Shell2at%proj(:,icoeff,ishell))-&
    1012   [ +  +  +  + ]:     4106052 : &                     sum(SS_ref(beta,:,alpha,isym,itrans)*Shell2at%proj(:,icoeff,ishell))
    1013                 :             :                 const_dynmat(alpha,beta,iatom,iat_mod,icoeff+ncoeff_prev)=&
    1014                 :      262566 : &               const_dynmat(alpha,beta,iatom,iat_mod,icoeff+ncoeff_prev)+terme
    1015                 :             :               end do
    1016                 :             :             end do
    1017                 :             :           end do
    1018                 :             : !         3/ Huang invariances. Number of constraints = 3**4
    1019         [ +  + ]:       22934 :           do alpha=1,3
    1020         [ +  + ]:       67212 :             do beta=1,3
    1021         [ +  + ]:      201318 :               do gama=1,3
    1022         [ +  + ]:      603954 :                 do lambda=1,3
    1023         [ +  + ]:     2502468 :                   do icoeff=1,ncoeff
    1024                 :             :                     terme=sum(SS_ref(alpha,:,beta,isym,itrans)*Shell2at%proj(:,icoeff,ishell))*&
    1025                 :             : &                             distance(iatom,jatom,gama+1)*&
    1026                 :             : &                             distance(iatom,jatom,lambda+1)-&
    1027                 :             : &                         sum(SS_ref(gama,:,lambda,isym,itrans)*Shell2at%proj(:,icoeff,ishell))*&
    1028                 :             : &                             distance(iatom,jatom,alpha+1)*&
    1029   [ +  +  +  + ]:    36954468 : &                             distance(iatom,jatom,beta+1)
    1030                 :             :                     const_huang(alpha,beta,gama,lambda,icoeff+ncoeff_prev)=&
    1031                 :     2363094 : &                   const_huang(alpha,beta,gama,lambda,icoeff+ncoeff_prev)+terme
    1032                 :             :                   end do
    1033                 :             :                 end do
    1034                 :             :               end do
    1035                 :             :             end do
    1036                 :             :           end do
    1037                 :             :         end do !iatshell
    1038                 :             :       end do !iatom
    1039                 :             :     end do !ishell
    1040                 :             :   end if !order=1,2
    1041                 :             : 
    1042                 :             : ! Third order
    1043         [ +  + ]:          44 :   if (order3) then
    1044                 :          14 :     write(Invar%stdout,*) '########################## At the 3rd order #################################'
    1045   [ -  +  +  -  :      659640 :     ABI_MALLOC(Const3%AsrRot3,(natom_unitcell,natom,ntotcoeff))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
          +  +  +  +  +  
                   +  + ]
    1046         [ +  + ]:          42 :     do iatom=1,natom_unitcell
    1047         [ +  + ]:        4930 :       do jatom=1,natom
    1048         [ +  + ]:      457300 :         do icoeff=1,ntotcoeff
    1049   [ -  +  -  +  :    18095360 :           ABI_MALLOC(Const3%AsrRot3(iatom,jatom,icoeff)%ABG,   (3,3,3)); Const3%AsrRot3(iatom,jatom,icoeff)%ABG(:,:,:)   =zero
          +  +  +  +  +  
                      + ]
    1050   [ -  +  -  +  :    54743352 :           ABI_MALLOC(Const3%AsrRot3(iatom,jatom,icoeff)%ABGD,(3,3,3,3)); Const3%AsrRot3(iatom,jatom,icoeff)%ABGD(:,:,:,:)=zero
          +  +  +  +  +  
                +  +  + ]
    1051                 :             :         end do
    1052                 :             :       end do
    1053                 :             :     end do
    1054         [ +  + ]:         165 :     do ishell=1,Shell2at%nshell
    1055         [ +  + ]:         476 :       do iatom=1,natom_unitcell
    1056         [ +  + ]:         311 :         if (Shell2at%neighbours(iatom,ishell)%n_interactions.eq.0) cycle
    1057         [ +  + ]:        2266 :         do iatshell=1,Shell2at%neighbours(iatom,ishell)%n_interactions
    1058                 :        1856 :           jatom=Shell2at%neighbours(iatom,ishell)%atomj_in_shell(iatshell)
    1059         [ +  + ]:        1856 :           if (iatom==jatom) cycle
    1060                 :        1828 :           isym=Shell2at%neighbours(iatom,ishell)%sym_in_shell(iatshell)
    1061                 :        1828 :           itrans=Shell2at%neighbours(iatom,ishell)%transpose_in_shell(iatshell)
    1062                 :        1828 :           ncoeff     =Shell2at%ncoeff(ishell)
    1063                 :        1828 :           ncoeff_prev=Shell2at%ncoeff_prev(ishell)+Solver%ncoeff1st
    1064                 :        1828 :           iat_mod=mod(jatom+natom_unitcell-1,natom_unitcell)+1
    1065                 :             : !         1/ Rotational invariances (coming from the 2nd order). Number of constraints = natom_unitcell*natom*3**3
    1066         [ +  - ]:        2139 :           if (Invar%order.ge.3) then
    1067         [ +  + ]:        7312 :             do alpha=1,3
    1068         [ +  + ]:       23764 :               do beta=1,3
    1069         [ +  + ]:       71292 :                 do gama=1,3
    1070         [ +  + ]:      213876 :                   do lambda=1,3
    1071         [ +  + ]:      824364 :                     do icoeff=1,ncoeff
    1072                 :      626940 :                       terme1=zero ; terme2=zero ; terme3=zero ; terme4=zero ;
    1073   [ +  +  +  + ]:     2507760 :                       if (alpha.eq.lambda) terme1=sum(SS_ref(gama  ,:,beta  ,isym,itrans)*Shell2at%proj(:,icoeff,ishell))
    1074   [ +  +  +  + ]:     2507760 :                       if (beta.eq.lambda)  terme2=sum(SS_ref(alpha ,:,gama  ,isym,itrans)*Shell2at%proj(:,icoeff,ishell))
    1075   [ +  +  +  + ]:     2507760 :                       if (alpha.eq.gama)   terme3=sum(SS_ref(lambda,:,beta  ,isym,itrans)*Shell2at%proj(:,icoeff,ishell))
    1076   [ +  +  +  + ]:     2507760 :                       if (beta.eq.gama)    terme4=sum(SS_ref(alpha ,:,lambda,isym,itrans)*Shell2at%proj(:,icoeff,ishell))
    1077         [ +  + ]:      626940 :                       if (distance(iatom,jatom,1).lt.Invar%rcut3) then
    1078                 :             :                         Const3%AsrRot3(iatom,jatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)=&
    1079                 :       34668 : &                       Const3%AsrRot3(iatom,jatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)+terme1+terme2-terme3-terme4
    1080                 :             :                       end if
    1081                 :             :                       Const3%AsrRot3(iatom,iatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)=&
    1082                 :      775008 : &                     Const3%AsrRot3(iatom,iatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)-terme1-terme2+terme3+terme4
    1083                 :             :                     end do
    1084                 :             :                   end do
    1085                 :             :                 end do
    1086                 :             :               end do
    1087                 :             :             end do
    1088                 :             :           end if !proj3rd
    1089                 :             :         end do !iatshell
    1090                 :             :       end do !iatom
    1091                 :             :     end do !ishell
    1092         [ +  + ]:          63 :     do ishell=1,Shell3at%nshell
    1093         [ +  + ]:         176 :       do iatom=1,natom_unitcell
    1094         [ +  + ]:         113 :         if (Shell3at%neighbours(iatom,ishell)%n_interactions.eq.0) cycle
    1095         [ +  + ]:        1286 :         do iatshell=1,Shell3at%neighbours(iatom,ishell)%n_interactions
    1096                 :        1144 :           jatom=Shell3at%neighbours(iatom,ishell)%atomj_in_shell(iatshell)
    1097                 :        1144 :           katom=Shell3at%neighbours(iatom,ishell)%atomk_in_shell(iatshell)
    1098                 :        1144 :           isym =Shell3at%neighbours(iatom,ishell)%sym_in_shell(iatshell)
    1099                 :        1144 :           itrans=Shell3at%neighbours(iatom,ishell)%transpose_in_shell(iatshell)
    1100                 :        1144 :           ncoeff     =Shell3at%ncoeff(ishell)
    1101                 :        1144 :           ncoeff_prev=Shell3at%ncoeff_prev(ishell)+Solver%ncoeff2nd+Solver%ncoeff1st
    1102                 :             : !         2/ Acoustic sum rules (3rd order). Number of constraints = natom_unitcell*natom*3**3
    1103         [ +  + ]:        4576 :           do alpha=1,3
    1104         [ +  + ]:       14872 :             do beta=1,3
    1105         [ +  + ]:       44616 :               do gama=1,3
    1106         [ +  + ]:      236826 :                 do icoeff=1,ncoeff
    1107         [ +  + ]:     5477976 :                   terme =sum(Const3%Sprod(isym,itrans)%SSS(alpha,:,beta,gama)*Shell3at%proj(:,icoeff,ishell))
    1108                 :             :                     Const3%AsrRot3(iatom,katom,icoeff+ncoeff_prev)%ABG(alpha,beta,gama)=&
    1109                 :      226530 : &                   Const3%AsrRot3(iatom,katom,icoeff+ncoeff_prev)%ABG(alpha,beta,gama)+terme
    1110                 :             :                 end do
    1111                 :             :               end do
    1112                 :             :             end do
    1113                 :             :           end do
    1114                 :             : !         2/ Rotational invariances (coming from the 3rd order). Number of constraints = natom_unitcell*natom*3**4
    1115         [ +  + ]:        4689 :           do alpha=1,3
    1116         [ +  + ]:       14872 :             do beta=1,3
    1117         [ +  + ]:       44616 :               do gama=1,3
    1118         [ +  + ]:      133848 :                 do lambda=1,3
    1119         [ +  + ]:      710478 :                   do icoeff=1,ncoeff
    1120                 :             :                     terme1=sum(Const3%Sprod(isym,itrans)%SSS(alpha,:,beta,gama  )&
    1121         [ +  + ]:    16433928 : &                          *Shell3at%proj(:,icoeff,ishell))*distance(iatom,katom,lambda+1)
    1122                 :             :                     terme2=sum(Const3%Sprod(isym,itrans)%SSS(alpha,:,beta,lambda)&
    1123         [ +  + ]:    16433928 : &                          *Shell3at%proj(:,icoeff,ishell))*distance(iatom,katom,gama+1)
    1124                 :             :                     Const3%AsrRot3(iatom,jatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)=&
    1125                 :      679590 : &                   Const3%AsrRot3(iatom,jatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)+terme1-terme2
    1126                 :             :                   end do
    1127                 :             :                 end do
    1128                 :             :               end do
    1129                 :             :             end do
    1130                 :             :           end do
    1131                 :             :         end do !iatshell
    1132                 :             :       end do !iatom
    1133                 :             :     end do !ishell
    1134                 :             :   end if !order=3
    1135                 :             : 
    1136                 :             : ! Fourth order
    1137                 :             :   if (order4) then
    1138                 :             :     write(Invar%stdout,*) '########################## At the 4th order #################################'
    1139                 :             :     ABI_MALLOC(Const4%AsrRot4,(natom_unitcell,natom,natom,ntotcoeff))
    1140                 :             :     do iatom=1,natom_unitcell
    1141                 :             :       do jatom=1,natom
    1142                 :             :         do katom=1,natom
    1143                 :             :           do icoeff=1,ntotcoeff
    1144                 :             :             ABI_MALLOC(Const4%AsrRot4(iatom,jatom,katom,icoeff)%ABGD,   (3,3,3,3))
    1145                 :             :                        Const4%AsrRot4(iatom,jatom,katom,icoeff)%ABGD(:,:,:,:)   =zero
    1146                 :             : !FB            ABI_MALLOC(Const4%AsrRot4(iatom,jatom,katom,icoeff)%ABGDE,(3,3,3,3,3))
    1147                 :             : !FB                       Const4%AsrRot4(iatom,jatom,katom,icoeff)%ABGDE(:,:,:,:,:)=zero
    1148                 :             :           end do
    1149                 :             :         end do
    1150                 :             :       end do
    1151                 :             :     end do
    1152                 :             : !FB    do ishell=1,Shell2at%nshell
    1153                 :             : !FB      do iatom=1,natom_unitcell
    1154                 :             : !FB        if (Shell2at%neighbours(iatom,ishell)%n_interactions.eq.0) cycle
    1155                 :             : !FB        do iatshell=1,Shell2at%neighbours(iatom,ishell)%n_interactions
    1156                 :             : !FB          jatom=Shell2at%neighbours(iatom,ishell)%atomj_in_shell(iatshell)
    1157                 :             : !FB          if (iatom==jatom) cycle
    1158                 :             : !FB          isym=Shell2at%neighbours(iatom,ishell)%sym_in_shell(iatshell)
    1159                 :             : !FB          itrans=Shell2at%neighbours(iatom,ishell)%transpose_in_shell(iatshell)
    1160                 :             : !FB          ncoeff     =Shell2at%ncoeff(ishell)
    1161                 :             : !FB          ncoeff_prev=Shell2at%ncoeff_prev(ishell)+Solver%ncoeff1st
    1162                 :             : !FB          iat_mod=mod(jatom+natom_unitcell-1,natom_unitcell)+1
    1163                 :             : !FB!         1/ Rotational invariances (coming from the 2nd order). Number of constraints = natom_unitcell*natom*3**3
    1164                 :             : !FB          if (Invar%order.ge.3) then
    1165                 :             : !FB            do alpha=1,3
    1166                 :             : !FB              do beta=1,3
    1167                 :             : !FB                do gama=1,3
    1168                 :             : !FB                  do lambda=1,3
    1169                 :             : !FB                    do icoeff=1,ncoeff
    1170                 :             : !FB                      terme1=zero ; terme2=zero ; terme3=zero ; terme4=zero ;
    1171                 :             : !FB                      if (alpha.eq.lambda) terme1=sum(SS_ref(gama  ,:,beta  ,isym,itrans)*Shell2at%proj(:,icoeff,ishell))
    1172                 :             : !FB                      if (beta.eq.lambda)  terme2=sum(SS_ref(alpha ,:,gama  ,isym,itrans)*Shell2at%proj(:,icoeff,ishell))
    1173                 :             : !FB                      if (alpha.eq.gama)   terme3=sum(SS_ref(lambda,:,beta  ,isym,itrans)*Shell2at%proj(:,icoeff,ishell))
    1174                 :             : !FB                      if (beta.eq.gama)    terme4=sum(SS_ref(alpha ,:,lambda,isym,itrans)*Shell2at%proj(:,icoeff,ishell))
    1175                 :             : !FB                      if (distance(iatom,jatom,1).lt.Invar%rcut3) then
    1176                 :             : !FB                        Const4%AsrRot3(iatom,jatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)=&
    1177                 :             : !FB&                       Const4%AsrRot3(iatom,jatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)+terme1+terme2-terme3-terme4
    1178                 :             : !FB                      end if
    1179                 :             : !FB                      Const4%AsrRot3(iatom,iatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)=&
    1180                 :             : !FB&                     Const4%AsrRot3(iatom,iatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)-terme1-terme2+terme3+terme4
    1181                 :             : !FB                    end do
    1182                 :             : !FB                  end do
    1183                 :             : !FB                end do
    1184                 :             : !FB              end do
    1185                 :             : !FB            end do
    1186                 :             : !FB          end if !proj3rd
    1187                 :             : !FB        end do !iatshell
    1188                 :             : !FB      end do !iatom
    1189                 :             : !FB    end do !ishell
    1190                 :             :     do ishell=1,Shell4at%nshell
    1191                 :             :       do iatom=1,natom_unitcell
    1192                 :             :         if (Shell4at%neighbours(iatom,ishell)%n_interactions.eq.0) cycle
    1193                 :             :         do iatshell=1,Shell4at%neighbours(iatom,ishell)%n_interactions
    1194                 :             :           jatom=Shell4at%neighbours(iatom,ishell)%atomj_in_shell(iatshell)
    1195                 :             :           katom=Shell4at%neighbours(iatom,ishell)%atomk_in_shell(iatshell)
    1196                 :             :           latom=Shell4at%neighbours(iatom,ishell)%atoml_in_shell(iatshell)
    1197                 :             :           isym =Shell4at%neighbours(iatom,ishell)%sym_in_shell(iatshell)
    1198                 :             :           itrans=Shell4at%neighbours(iatom,ishell)%transpose_in_shell(iatshell)
    1199                 :             :           ncoeff     =Shell4at%ncoeff(ishell)
    1200                 :             :           ncoeff_prev=Shell4at%ncoeff_prev(ishell)+Solver%ncoeff3rd+Solver%ncoeff2nd+Solver%ncoeff1st
    1201                 :             : !         2/ Acoustic sum rules (4th order). Number of constraints = natom_unitcell*natom**2*3**4
    1202                 :             :           do alpha=1,3
    1203                 :             :             do beta=1,3
    1204                 :             :               do gama=1,3
    1205                 :             :                 do delta=1,3
    1206                 :             :                   do icoeff=1,ncoeff
    1207                 :             :                     terme =sum(Const4%Sprod(isym,itrans)%SSSS(alpha,:,beta,gama,delta)*Shell4at%proj(:,icoeff,ishell))
    1208                 :             :                       Const4%AsrRot4(iatom,katom,latom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,delta)=&
    1209                 :             : &                     Const4%AsrRot4(iatom,katom,latom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,delta)+terme
    1210                 :             :                   end do
    1211                 :             :                 end do
    1212                 :             :               end do
    1213                 :             :             end do
    1214                 :             :           end do
    1215                 :             : !FB!         2/ Rotational invariances (coming from the 3rd order). Number of constraints = natom_unitcell*natom*3**4
    1216                 :             : !FB          do alpha=1,3
    1217                 :             : !FB            do beta=1,3
    1218                 :             : !FB              do gama=1,3
    1219                 :             : !FB                do lambda=1,3
    1220                 :             : !FB                  do icoeff=1,ncoeff
    1221                 :             : !FB                    terme1=sum(Const4%Sprod(isym,itrans)%SSS(alpha,:,beta,gama  )&
    1222                 :             : !FB                               &*Shell3at%proj(:,icoeff,ishell))*distance(iatom,katom,lambda+1)
    1223                 :             : !FB                    terme2=sum(Const4%Sprod(isym,itrans)%SSS(alpha,:,beta,lambda)&
    1224                 :             : !FB                               &*Shell3at%proj(:,icoeff,ishell))*distance(iatom,katom,gama+1)
    1225                 :             : !FB                    Const4%AsrRot3(iatom,jatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)=&
    1226                 :             : !FB&                   Const4%AsrRot3(iatom,jatom,icoeff+ncoeff_prev)%ABGD(alpha,beta,gama,lambda)+terme1-terme2
    1227                 :             : !FB                  end do
    1228                 :             : !FB                end do
    1229                 :             : !FB              end do
    1230                 :             : !FB            end do
    1231                 :             : !FB          end do
    1232                 :             :         end do !iatshell
    1233                 :             :       end do !iatom
    1234                 :             :     end do !ishell
    1235                 :             :   end if !order=4
    1236                 :             : 
    1237         [ +  - ]:          44 :   if (order2.or.order3) then
    1238         [ -  + ]:          44 :     ABI_FREE(SS_ref)
    1239                 :             :   end if
    1240         [ +  + ]:          44 :   if (order3.or.order4) then
    1241         [ +  + ]:         510 :     do isym=1,Sym%nsym
    1242         [ +  + ]:        3486 :       do itrans=1,6
    1243         [ -  + ]:        3472 :         ABI_FREE(Const3%Sprod(isym,itrans)%SSS)
    1244                 :             :       end do
    1245                 :             :     end do
    1246   [ +  -  +  +  :        2990 :     ABI_FREE(Const3%Sprod)
          -  +  -  +  -  
                +  -  + ]
    1247                 :             :   end if
    1248                 :             :   if (order4) then
    1249                 :             :     do isym=1,Sym%nsym
    1250                 :             :       do itrans=1,24
    1251                 :             :         ABI_FREE(Const4%Sprod(isym,itrans)%SSSS)
    1252                 :             :       end do
    1253                 :             :     end do
    1254                 :             :     ABI_FREE(Const4%Sprod)
    1255                 :             :   end if
    1256                 :             : 
    1257                 :             : ! Reduce the number of constraints by selecting the non-zero equations
    1258                 :          44 :   write(Invar%stdout,*) '################## Reduce the number of constraints #########################'
    1259                 :          44 :   iconst_new=0
    1260         [ +  - ]:          44 :   if (order2) then
    1261                 :             : !   1/ For Rotational invariances (1st order)
    1262                 :          44 :     iconst=0
    1263   [ -  +  +  -  :       25241 :     ABI_MALLOC(vect,(ntotcoeff,Solver%nconst_1st)) ; vect(:,:)=zero
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
    1264         [ +  + ]:         176 :     do alpha=1,3
    1265         [ +  + ]:         572 :       do beta=1,3
    1266                 :         396 :         iconst=iconst+1
    1267         [ +  + ]:       25197 :         vect(:,iconst)=const_rot1st(alpha,beta,:)
    1268                 :             :       end do
    1269                 :             :     end do
    1270                 :          44 :     call tdep_calc_orthonorm(ntotcoeff,Solver%nconst_1st,nconst_loc,vect)
    1271         [ -  + ]:          44 :     if (nconst_loc.ne.0) then
    1272         [ #  # ]:           0 :       do iconst_loc=1,nconst_loc
    1273                 :           0 :         iconst_new=iconst_new+1
    1274         [ #  # ]:           0 :         Solver%const(iconst_new,:)=vect(:,iconst_loc)
    1275                 :             :       end do
    1276                 :             :     end if
    1277         [ -  + ]:          44 :     ABI_FREE(vect)
    1278         [ -  + ]:          44 :     ABI_FREE(const_rot1st)
    1279                 :          44 :     Solver%nconst_1st=nconst_loc
    1280                 :             : 
    1281                 :             : !   2/ For Rotational invariances (2nd order)
    1282                 :          44 :     iconst=0
    1283   [ -  +  +  -  :      366593 :     ABI_MALLOC(vect,(ntotcoeff,Solver%nconst_rot2nd)) ; vect(:,:)=zero
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
    1284         [ +  + ]:         150 :     do iatom=1,natom_unitcell
    1285         [ +  + ]:         468 :       do alpha=1,3
    1286         [ +  + ]:        1378 :         do beta=1,3
    1287         [ +  + ]:        4134 :           do gama=1,3
    1288                 :        2862 :             iconst=iconst+1
    1289         [ +  + ]:      367371 :             vect(:,iconst)=const_rot2nd(alpha,beta,gama,iatom,:)
    1290                 :             :           end do
    1291                 :             :         end do
    1292                 :             :       end do
    1293                 :             :     end do
    1294                 :          44 :     call tdep_calc_orthonorm(ntotcoeff,Solver%nconst_rot2nd,nconst_loc,vect)
    1295         [ +  + ]:          44 :     if (nconst_loc.ne.0) then
    1296         [ +  + ]:         113 :       do iconst_loc=1,nconst_loc
    1297                 :         100 :         iconst_new=iconst_new+1
    1298         [ +  + ]:       33151 :         Solver%const(iconst_new,:)=vect(:,iconst_loc)
    1299                 :             :       end do
    1300                 :             :     end if
    1301         [ -  + ]:          44 :     ABI_FREE(vect)
    1302         [ -  + ]:          44 :     ABI_FREE(const_rot2nd)
    1303                 :          44 :     Solver%nconst_rot2nd=nconst_loc
    1304                 :             : 
    1305                 :             : !   3/ For symetry of the dynamical matrix
    1306                 :          44 :     iconst=0
    1307   [ -  +  +  -  :     1278239 :     ABI_MALLOC(vect,(ntotcoeff,Solver%nconst_dynmat)) ; vect(:,:)=zero
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
    1308         [ +  + ]:         150 :     do iatom=1,natom_unitcell
    1309         [ +  + ]:         664 :       do jatom=1,natom_unitcell
    1310         [ +  + ]:        2162 :         do alpha=1,3
    1311         [ +  + ]:        6682 :           do beta=1,3
    1312                 :        4626 :             iconst=iconst+1
    1313         [ +  + ]:     1279605 :             vect(:,iconst)=const_dynmat(alpha,beta,iatom,jatom,:)
    1314                 :             :           end do
    1315                 :             :         end do
    1316                 :             :       end do
    1317                 :             :     end do
    1318                 :          44 :     call tdep_calc_orthonorm(ntotcoeff,Solver%nconst_dynmat,nconst_loc,vect)
    1319         [ +  + ]:          44 :     if (nconst_loc.ne.0) then
    1320         [ +  + ]:          69 :       do iconst_loc=1,nconst_loc
    1321                 :          65 :         iconst_new=iconst_new+1
    1322         [ +  + ]:       26885 :         Solver%const(iconst_new,:)=vect(:,iconst_loc)
    1323                 :             :       end do
    1324                 :             :     end if
    1325         [ -  + ]:          44 :     ABI_FREE(vect)
    1326         [ -  + ]:          44 :     ABI_FREE(const_dynmat)
    1327                 :          44 :     Solver%nconst_dynmat=nconst_loc
    1328                 :             : 
    1329                 :             : !   4/ For Huang invariances
    1330                 :          44 :     iconst=0
    1331   [ -  +  +  -  :      225761 :     ABI_MALLOC(vect,(ntotcoeff,Solver%nconst_huang)) ; vect(:,:)=zero
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
    1332         [ +  + ]:         176 :     do alpha=1,3
    1333         [ +  + ]:         572 :       do beta=1,3
    1334         [ +  + ]:        1716 :         do gama=1,3
    1335         [ +  + ]:        5148 :           do lambda=1,3
    1336                 :        3564 :             iconst=iconst+1
    1337         [ +  + ]:      226773 :             vect(:,iconst)=const_huang(alpha,beta,gama,lambda,:)
    1338                 :             :           end do
    1339                 :             :         end do
    1340                 :             :       end do
    1341                 :             :     end do
    1342                 :          44 :     call tdep_calc_orthonorm(ntotcoeff,Solver%nconst_huang,nconst_loc,vect)
    1343         [ +  + ]:          44 :     if (nconst_loc.ne.0) then
    1344         [ +  + ]:          70 :       do iconst_loc=1,nconst_loc
    1345                 :          51 :         iconst_new=iconst_new+1
    1346         [ +  + ]:        6515 :         Solver%const(iconst_new,:)=vect(:,iconst_loc)
    1347                 :             :       end do
    1348                 :             :     end if
    1349         [ -  + ]:          44 :     ABI_FREE(vect)
    1350         [ -  + ]:          44 :     ABI_FREE(const_huang)
    1351                 :          44 :     Solver%nconst_huang=nconst_loc
    1352                 :         220 :     Solver%nconst_2nd=Solver%nconst_rot2nd+Solver%nconst_dynmat+Solver%nconst_huang
    1353                 :             :   end if
    1354                 :             : 
    1355         [ +  + ]:          44 :   if (order3) then
    1356                 :             : !   1/ For acoustic sum rules (3rd order)
    1357                 :          14 :     iconst=0
    1358   [ -  +  +  -  :    12346400 :     ABI_MALLOC(vect ,(ntotcoeff,Solver%nconst_asr3rd)) ; vect (:,:)=zero
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
    1359         [ +  + ]:          42 :     do iatom=1,natom_unitcell
    1360         [ +  + ]:        4930 :       do jatom=1,natom
    1361         [ +  + ]:       19580 :         do alpha=1,3
    1362         [ +  + ]:       63544 :           do beta=1,3
    1363         [ +  + ]:      190632 :             do gama=1,3
    1364                 :      131976 :               iconst=iconst+1
    1365         [ +  + ]:    12390336 :               do ii=1,ntotcoeff
    1366                 :    12346344 :                 vect(ii,iconst)=Const3%AsrRot3(iatom,jatom,ii)%ABG(alpha,beta,gama)
    1367                 :             :               end do
    1368                 :             :             end do
    1369                 :             :           end do
    1370                 :             :         end do
    1371                 :             :       end do
    1372                 :             :     end do
    1373                 :          14 :     call tdep_calc_orthonorm(ntotcoeff,Solver%nconst_asr3rd,nconst_loc,vect)
    1374         [ +  + ]:          14 :     if (nconst_loc.ne.0) then
    1375         [ +  + ]:          75 :       do iconst_loc=1,nconst_loc
    1376                 :          64 :         iconst_new=iconst_new+1
    1377         [ +  + ]:        8571 :         Solver%const(iconst_new,:)=vect(:,iconst_loc)
    1378                 :             :       end do
    1379                 :             :     end if
    1380         [ -  + ]:          14 :     ABI_FREE(vect)
    1381                 :          14 :     Solver%nconst_asr3rd=nconst_loc
    1382                 :             : 
    1383                 :             : !   2/ For Rotational invariances (3rd order)
    1384                 :          14 :     iconst=0
    1385   [ -  +  +  -  :    37039088 :     ABI_MALLOC(vect ,(ntotcoeff,Solver%nconst_rot3rd)) ; vect(:,:)=zero
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
    1386         [ +  + ]:          42 :     do iatom=1,natom_unitcell
    1387         [ +  + ]:        4930 :       do jatom=1,natom
    1388         [ +  + ]:       19580 :         do alpha=1,3
    1389         [ +  + ]:       63544 :           do beta=1,3
    1390         [ +  + ]:      190632 :             do gama=1,3
    1391         [ +  + ]:      571896 :               do lambda=1,3
    1392                 :      395928 :                 iconst=iconst+1
    1393         [ +  + ]:    37171008 :                 do ii=1,ntotcoeff
    1394                 :    37039032 :                   vect(ii,iconst)=Const3%AsrRot3(iatom,jatom,ii)%ABGD(alpha,beta,gama,lambda)
    1395                 :             :                   end do
    1396                 :             :               end do
    1397                 :             :             end do
    1398                 :             :           end do
    1399                 :             :         end do
    1400                 :             :       end do
    1401                 :             :     end do
    1402                 :          14 :     call tdep_calc_orthonorm(ntotcoeff,Solver%nconst_rot3rd,nconst_loc,vect)
    1403         [ +  + ]:          14 :     if (nconst_loc.ne.0) then
    1404         [ +  + ]:         101 :       do iconst_loc=1,nconst_loc
    1405                 :          90 :         iconst_new=iconst_new+1
    1406         [ +  + ]:       13631 :         Solver%const(iconst_new,:)=vect(:,iconst_loc)
    1407                 :             :       end do
    1408                 :             :     end if
    1409         [ -  + ]:          14 :     ABI_FREE(vect)
    1410         [ +  + ]:          42 :     do iatom=1,natom_unitcell
    1411         [ +  + ]:        4930 :       do jatom=1,natom
    1412         [ +  + ]:      457300 :         do icoeff=1,ntotcoeff
    1413         [ -  + ]:      452384 :           ABI_FREE(Const3%AsrRot3(iatom,jatom,icoeff)%ABG)
    1414         [ -  + ]:      457272 :           ABI_FREE(Const3%AsrRot3(iatom,jatom,icoeff)%ABGD)
    1415                 :             :         end do
    1416                 :             :       end do
    1417                 :             :     end do
    1418   [ +  -  +  +  :      452398 :     ABI_FREE(Const3%AsrRot3)
          -  +  -  +  -  
                +  -  + ]
    1419                 :          14 :     Solver%nconst_rot3rd=nconst_loc
    1420                 :          42 :     Solver%nconst_3rd=Solver%nconst_asr3rd+Solver%nconst_rot3rd
    1421                 :             :   end if
    1422                 :             : 
    1423                 :             :   if (order4) then
    1424                 :             : !   1/ For acoustic sum rules (4th order)
    1425                 :             :     iconst=0
    1426                 :             :     ABI_MALLOC(vect ,(ntotcoeff,Solver%nconst_asr4th)) ; vect (:,:)=zero
    1427                 :             :     do iatom=1,natom_unitcell
    1428                 :             :       do jatom=1,natom
    1429                 :             :         do katom=1,natom
    1430                 :             :           do alpha=1,3
    1431                 :             :             do beta=1,3
    1432                 :             :               do gama=1,3
    1433                 :             :                 do delta=1,3
    1434                 :             :                   iconst=iconst+1
    1435                 :             :                   do ii=1,ntotcoeff
    1436                 :             :                     vect(ii,iconst)=Const4%AsrRot4(iatom,jatom,katom,ii)%ABGD(alpha,beta,gama,delta)
    1437                 :             :                   end do
    1438                 :             :                 end do
    1439                 :             :               end do
    1440                 :             :             end do
    1441                 :             :           end do
    1442                 :             :         end do
    1443                 :             :       end do
    1444                 :             :     end do
    1445                 :             :     call tdep_calc_orthonorm(ntotcoeff,Solver%nconst_asr4th,nconst_loc,vect)
    1446                 :             :     if (nconst_loc.ne.0) then
    1447                 :             :       do iconst_loc=1,nconst_loc
    1448                 :             :         iconst_new=iconst_new+1
    1449                 :             :         Solver%const(iconst_new,:)=vect(:,iconst_loc)
    1450                 :             :       end do
    1451                 :             :     end if
    1452                 :             :     ABI_FREE(vect)
    1453                 :             :     Solver%nconst_asr4th=nconst_loc
    1454                 :             : 
    1455                 :             : !FB!   2/ For Rotational invariances (3rd order)
    1456                 :             : !FB    iconst=0
    1457                 :             : !FB    ABI_MALLOC(vect ,(ntotcoeff,Solver%nconst_rot3rd)) ; vect(:,:)=zero
    1458                 :             : !FB    do iatom=1,natom_unitcell
    1459                 :             : !FB      do jatom=1,natom
    1460                 :             : !FB        do alpha=1,3
    1461                 :             : !FB          do beta=1,3
    1462                 :             : !FB            do gama=1,3
    1463                 :             : !FB              do lambda=1,3
    1464                 :             : !FB                iconst=iconst+1
    1465                 :             : !FB                vect(:,iconst)=Const4%AsrRot3(iatom,jatom,:)%ABGD(alpha,beta,gama,lambda)
    1466                 :             : !FB              end do
    1467                 :             : !FB            end do
    1468                 :             : !FB          end do
    1469                 :             : !FB        end do
    1470                 :             : !FB      end do
    1471                 :             : !FB    end do
    1472                 :             : !FB    call tdep_calc_orthonorm(ntotcoeff,Solver%nconst_rot3rd,nconst_loc,vect)
    1473                 :             : !FB    if (nconst_loc.ne.0) then
    1474                 :             : !FB      do iconst_loc=1,nconst_loc
    1475                 :             : !FB        iconst_new=iconst_new+1
    1476                 :             : !FB        Solver%const(iconst_new,:)=vect(:,iconst_loc)
    1477                 :             : !FB      end do
    1478                 :             : !FB    end if
    1479                 :             : !FB    ABI_FREE(vect)
    1480                 :             : !FB    Solver%nconst_rot3rd=nconst_loc
    1481                 :             :     do iatom=1,natom_unitcell
    1482                 :             :       do jatom=1,natom
    1483                 :             :         do katom=1,natom
    1484                 :             :           do icoeff=1,ntotcoeff
    1485                 :             :             ABI_FREE(Const4%AsrRot4(iatom,jatom,katom,icoeff)%ABGD)
    1486                 :             : !FB            ABI_FREE(Const4%AsrRot4(iatom,jatom,katom,icoeff)%ABGDE)
    1487                 :             :           end do
    1488                 :             :         end do
    1489                 :             :       end do
    1490                 :             :     end do
    1491                 :             :     ABI_FREE(Const4%AsrRot4)
    1492                 :             :     Solver%nconst_rot4th=0
    1493                 :             :     Solver%nconst_4th=Solver%nconst_asr4th+Solver%nconst_rot4th
    1494                 :             :   end if
    1495                 :             : 
    1496                 :             : ! Finalize the orthonormalization
    1497                 :             : !FB  nconst=iconst_new
    1498                 :             : !FB  ABI_MALLOC(vect,(ntotcoeff,nconst)) ; vect(:,:)=zero
    1499                 :             : !FB  do iconst=1,nconst
    1500                 :             : !FB    vect(:,iconst)=Solver%const(iconst,:)
    1501                 :             : !FB  end do
    1502                 :             : !FB  ABI_FREE(Solver%const)
    1503                 :             : !FB  call tdep_calc_orthonorm(ntotcoeff,nconst,nconst_loc,vect)
    1504                 :             : !FB  Solver%ntotconst=nconst_loc
    1505                 :             : !FB  if (nconst_loc.ne.0) then
    1506                 :             : !FB    ABI_MALLOC(Solver%const ,(Solver%ntotconst,ntotcoeff)); Solver%const (:,:)=0.d0
    1507                 :             : !FB    do iconst_loc=1,nconst_loc
    1508                 :             : !FB      Solver%const(iconst_loc,:)=vect(:,iconst_loc)
    1509                 :             : !FB    end do
    1510                 :             : !FB  end if
    1511                 :             : !FB  ABI_FREE(vect)
    1512                 :          44 :   Solver%ntotconst=iconst_new
    1513         [ +  - ]:          44 :   if (MPIdata%iam_master) then
    1514                 :          44 :     open(unit=16,file=trim(Invar%output_prefix)//'_constraints.dat')
    1515                 :          44 :     write(16,*) ' ======== Constraints at the 1st order (Rotational Invariances) ========'
    1516                 :          44 :     write(16,*) ' Number of constraints =',Solver%nconst_1st
    1517                 :          44 :     write(16,*) ' ======== Constraints at the 2nd order (Rotational Invariances) ========'
    1518                 :          44 :     write(16,*) ' Number of constraints =',Solver%nconst_rot2nd
    1519                 :          44 :     write(16,*) ' ======== Constraints at the 2nd order (Dynamical Matrix) =============='
    1520                 :          44 :     write(16,*) ' Number of constraints =',Solver%nconst_dynmat
    1521                 :          44 :     write(16,*) ' ======== Constraints at the 2nd order (Huang) ========================='
    1522                 :          44 :     write(16,*) ' Number of constraints =',Solver%nconst_huang
    1523         [ +  + ]:          44 :     if (Invar%order.ge.3) then
    1524                 :          14 :       write(16,*) ' ======== Constraints at the 3rd order (Acoustic sum rules) ============'
    1525                 :          14 :       write(16,*) ' Number of constraints =',Solver%nconst_asr3rd
    1526                 :          14 :       write(16,*) ' ======== Constraints at the 3rd order (Rotational Invariances) ========'
    1527                 :          14 :       write(16,*) ' Number of constraints =',Solver%nconst_rot3rd
    1528                 :             :     end if
    1529         [ +  + ]:          44 :     if (Invar%order.ge.4) then
    1530                 :           8 :       write(16,*) ' ======== Constraints at the 4th order (Acoustic sum rules) ============'
    1531                 :           8 :       write(16,*) ' Number of constraints =',Solver%nconst_asr4th
    1532                 :           8 :       write(16,*) ' ======== Constraints at the 4th order (Rotational Invariances) ========'
    1533                 :           8 :       write(16,*) ' Number of constraints =',Solver%nconst_rot4th
    1534                 :             :     end if
    1535                 :          44 :     write(16,*) ' ======================================================================='
    1536                 :          44 :     write(16,*) ' Total number of constraints =',Solver%ntotconst
    1537                 :          44 :     close(16)
    1538                 :             :   end if
    1539                 :             : 
    1540   [ -  +  -  +  :          44 : end subroutine tdep_calc_constraints
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          -  -  -  -  -  
                      - ]
    1541                 :             : 
    1542                 :             : !====================================================================================================
    1543                 :             : 
    1544   [ #  #  #  #  :           0 : end module m_tdep_solver
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    1545                 :             : !!***
        

Generated by: LCOV version 2.3-1