subroutine CalcBMat_mixed (natoms, xyzatm, indzmat, dzdc)

!----------------------------------------------------------------------
!  Copyright 2003-2014 Ecole Normale Supérieure de Lyon, 
!  Centre National de la Recherche Scientifique,
!  Université Claude Bernard Lyon 1. All rights reserved.
!
!  This work is registered with the Agency for the Protection of Programs 
!  as IDDN.FR.001.100009.000.S.P.2014.000.30625
!
!  Authors: P. Fleurat-Lessard, P. Dayal
!  Contact: optnpath@gmail.com
!
! This file is part of "Opt'n Path".
!
!  "Opt'n Path" is free software: you can redistribute it and/or modify
!  it under the terms of the GNU Affero General Public License as
!  published by the Free Software Foundation, either version 3 of the License,
!  or (at your option) any later version.
!
!  "Opt'n Path" is distributed in the hope that it will be useful,
!  but WITHOUT ANY WARRANTY; without even the implied warranty of
!
!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!  GNU Affero General Public License for more details.
!
!  You should have received a copy of the GNU Affero General Public License
!  along with "Opt'n Path". If not, see <http://www.gnu.org/licenses/>.
!
! Contact The Office of Technology Licensing, valorisation@ens-lyon.fr,
! for commercial licensing opportunities.
!----------------------------------------------------------------------

  use Io_module
  use Path_module, only : NCart

  IMPLICIT NONE


  integer(KINT), INTENT(IN) :: natoms, indzmat(natoms,5)
  real(KREAL), INTENT(IN)   :: xyzatm(3,natoms)
  real(KREAL), INTENT(OUT)   :: dzdc(3*natoms,3*natoms)


!!!!!!!!!!!!!!!!!!!!!
!
! This routine computes the derivatives of the internal coordinates
! with respect to the cartesian coordinates.
! This is what is called the B matrix in Baker coordinates :
! B(i,j)=dz_i/dx_j
!
! it uses the same routines as Calc_baker
!
! Here, it is used for mixed Cart+Z-mat system
!
!!!!!!!!!!!!!!!!!!!!!!
!
! Input:
! natoms: number of atoms
! xyzatm(3,natoms): cartesian geometry
! indzmat(natoms,5): index of the Z-matrix definition
! atmass(natoms): mass of the atoms
! atome(natoms): ??
!
! Output:
! dzdc(3*natoms,3*natoms): B matrix
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


  INTERFACE
     function valid(string) result (isValid)
       CHARACTER(*), intent(in) :: string
       logical                  :: isValid
     END function VALID
  END INTERFACE

  LOGICAL :: debug
  INTEGER(KINT) :: i,j,k,iat, istart
  INTEGER(KINT) :: iat1, iat2, iat3, iat4



  ! ======================================================================

  debug=valid('CalcBMat').OR.valid('CalcBMat_mixed')

  if (debug) Call Header('Entering CalcBMat_mixed')
  if (debug) THEN
     WRITE(*,*) 'DBG CalcBMat_mixed Xyzatm '
     DO iat=1,natoms
        write(*,'(1X,I5,3(1X,F15.6))') iat, xyzatm(1:3,iat)
     END DO
     WRITE(*,*) 'DBG CalcBMat_mixed IndZmat'
     DO iat=1,natoms
        write(*,'(6(1X,I5))') iat, indzmat(iat,1:4)
     END DO
  END IF

  dzdc=0.d0
  do i = 1, NCart
     iat=indzmat(i,1)
     do j=1,3
        k=(iat-1)*3+j
        dzdc(k,k)=1.d0
     END DO
  END DO

    IF (NCart.EQ.1) THEN
       if (natoms.ge.2) THEN
          iat1=indzmat(2,1)
          iat2=indzmat(2,2)
          Call CONSTRAINTS_BONDLENGTH_DER(Natoms,iat1,iAT2, xyzatm, dzdc(1,4))
         END IF
    END IF
    IF (NCart.LE.2) THEN
       if (natoms.ge.3) THEN
          iat1=indzmat(3,1)
          iat2=indzmat(3,2)
          iat3=indzmat(3,3)
          Call CONSTRAINTS_BONDLENGTH_DER(Natoms,iat1,iAT2, xyzatm, dzdc(1,7))
          CALL CONSTRAINTS_BONDANGLE_DER(Natoms,iAt1,iAT2,iAt3, xyzatm, dzdc(1,8))
       END IF
    END IF

    IStart=max(NCart+1,4)
    k=(IStart-1)*3+1
  DO I=IStart, Natoms
     iat1=indzmat(i,1)
     iat2=indzmat(i,2)
     iat3=indzmat(i,3)
     iat4=indzmat(i,4)
     Call CONSTRAINTS_BONDLENGTH_DER(Natoms,iat1,iAT2, xyzatm, dzdc(1,k))
     k=k+1
     CALL CONSTRAINTS_BONDANGLE_DER(Natoms,iAt1,iAT2,iAt3, xyzatm, dzdc(1,k))
     k=k+1
     CALL CONSTRAINTS_TORSION_DER2(Natoms,iat1,iat2,iat3,iat4, xyzatm, dzdc(1,k)) 
     k=k+1
  END DO
             




  if (debug) Call Header('CalcBMat_mixed over')

  ! ======================================================================

end subroutine CalcBMat_mixed
