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-09-19 17:42:43 Functions: 81.8 % 11 9

            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