!=======================================================================
!
!  PROGRAM  PHASE/0 2014.03 ($Rev: 410 $)
!
!  FUNCTION:  Ending_Time(), ckiter(), ChargeDensity_is_Converged(), 
!             TotalEnergy_is_Divergent(), Forces_are_Converged(), 
!             Already_Converged(), EigenValues_are_Converged(), 
!              AllKpoints_are_Calculated()
!
!  AUTHOR(S): T. Yamasaki   August/20/2003
!
!  FURTHER MODIFICATION: T. Yamasaki, December/01/2003, May/16/2005,
!                                     June/04/2005, April/10/2007
!  
!  Contact address :  Phase System Consortium
!                     E-mail: phase_system@nims.go.jp URL https://azuma.nims.go.jp
!  
!
!
!=======================================================================
!
!     The original version of this set of the computer programs "PHASE"
!  was developed by the members of the Theory Group of Joint Research
!  Center for Atom Technology (JRCAT), based in Tsukuba, in the period
!  1993-2001.
!
!     Since 2002, this set has been tuned and new functions have been
!  added to it as a part of the national project "Frontier Simulation 
!  Software for Industrial Science (FSIS)",  which is supported by
!  the IT program of the Ministry of Education, Culture, Sports,
!  Science and Technology (MEXT) of Japan. 
!     Since 2006, this program set has been developed as a part of the
!  national project "Revolutionary Simulation Software (RSS21)", which
!  is supported by the next-generation IT program of MEXT of Japan.
!   Since 2013, this program set has been further developed centering on PHASE System
!  Consortium.
!   The activity of development of this program set has been supervised by Takahisa Ohno.
!
logical function Ending_Time()
! $Id: Convergence_Check.F90 410 2014-10-30 05:20:45Z jkoga $
  use m_Const_Parameters,   only : INITIAL, CONTINUATION, FIXED_CHARGE, FIXED_CHARGE_CONTINUATION
  use m_Files,              only : nfstop,nfout,m_Files_open_nfstop,m_Files_close_nfstop
  use m_IterationNumbers,   only : iteration, iteration_ionic, iteration_electronic
  use m_Control_Parameters, only : icond, ifstop, istop, max_total_scf_iteration, max_mdstep &
       &                         , max_TS_iteration_is_given, max_mdstep_is_given, printable &
       &                         , m_CtrlP_ckcput, m_CtrlP_rd_istop
  use m_Parallelization,    only : mype,mpi_comm_group
  implicit none
  include 'mpif.h'                                      ! MPI

  logical  :: torf
  integer :: ierr

  torf = m_CtrlP_ckcput()
  Ending_Time = torf

  if(.not.torf) &
       & Ending_Time = ckiter()           ! -(contained here)
!  call mpi_barrier(mpi_comm_world, ierr)
  call mpi_barrier(mpi_comm_group, ierr)
contains
  logical function ckiter()
    integer :: imax, icaseflag
! --> T. Yamasaki, 14 July 2008
    integer, parameter :: FILE_F_INP = 1, FILE_F_INP_MDSTEP = 2
! <--
    character*8 :: file_cname
    character*9 :: c_iteration
    icaseflag = 0
    ckiter = .false.
    if(icond == INITIAL .or. icond == CONTINUATION) then
       imax = max(iteration, iteration_ionic)
#ifndef _EMPIRICAL_
       if(iteration == 0) imax = 0
#endif
!                                                                                 (max_TS_iteration_is_given, max_mdstep_is_given)
       if(max_TS_iteration_is_given .and. max_mdstep_is_given) then                   ! (.true., .true.)
! --> T. Yamasaki, 07 Aug. 2009
!!$          if(max_total_scf_iteration <= imax .or. max_mdstep <= iteration_ionic) then
          if(max_total_scf_iteration <= imax .or. max_mdstep <= iteration_ionic-1) then
! <--
             ckiter = .true.
             if(max_total_scf_iteration <= imax) then
                icaseflag = FILE_F_INP
             else
                icaseflag = FILE_F_INP_MDSTEP
             end if
          else if(ifstop >= 1) then
             ckiter = ckiter_ifstop(imax)
          end if
       else if(.not.max_mdstep_is_given) then                                         ! (.true., .false) or (.false., .false)
          if(max_total_scf_iteration <= imax) then
             ckiter = .true.
             icaseflag = FILE_F_INP
          else if(ifstop >= 1) then
             ckiter = ckiter_ifstop(imax)
          end if
       else if(.not.max_TS_iteration_is_given .and. max_mdstep_is_given) then         ! (.false., .true.)
! --> T. Yamasaki, 06 Aug. 2009
!!$          if(max_mdstep <= iteration_ionic) then
          if(max_mdstep <= iteration_ionic-1) then
! <--
             ckiter = .true.
             icaseflag = FILE_F_INP_MDSTEP
          else if(ifstop >= 1 ) then
             ckiter = ckiter_ifstop(imax)
          end if
       end if


!!$       if(max_total_scf_iteration <= imax .or. max_mdstep <= iteration_ionic) then
!!$          ckiter = .true.
!!$          if(max_total_scf_iteration <= imax) then
!!$             icaseflag = FILE_F_INP
!!$          else
!!$             icaseflag = FILE_F_INP_MDSTEP
!!$          end if
!!$       else if(ifstop >= 1) then
!!$          if(mod(imax,ifstop) == 0) then
!!$             call m_Files_open_nfstop
!!$             call m_CtrlP_rd_istop(nfstop)        ! ->istop
!!$             if(istop >= 0 .and. istop <= imax) ckiter = .true.
!!$             call m_Files_close_nfstop
!!$          else
!!$             if(istop >= 0 .and. istop <= imax) ckiter = .true.
!!$          end if
!!$       end if
    else if(icond == FIXED_CHARGE .or. icond == FIXED_CHARGE_CONTINUATION) then

       if(iteration > max_total_scf_iteration) then
          ckiter = .true.
          icaseflag = FILE_F_INP
       else
          imax = max(iteration, iteration_electronic)
!!$          imax = iteration_electronic
!!$       if(imax > ek_max_iteration) then
!!$          ckiter = .true.
!!$       else
!!$          write(nfout,'(" iteration_electronic = ",i6)') iteration_electronic
!!$          write(nfout,'("  ifstop = ",i6)') ifstop
          if(ifstop >= 1) then
             ckiter = ckiter_ifstop(imax)
          end if
       end if
    end if
    if(ckiter) then
       if(icaseflag .eq. FILE_F_INP_MDSTEP) then
          file_cname = ' <F_INP>'
          imax = max_mdstep
          c_iteration = ' mdstep  '
       else if(icaseflag .eq. FILE_F_INP) then
          file_cname = ' <F_INP>'
          imax = max_total_scf_iteration
          c_iteration = 'iteration'
       else
          file_cname = '<F_STOP>'
          imax = istop
          c_iteration = 'iteration'
       end if
       if(printable) write(nfout,'(" --- This job stops because the ",a9," has exceeded " &
                              & ,i6," set in the ",a8," file ---")') c_iteration, imax,file_cname
    end if
  end function ckiter

  logical function ckiter_ifstop(imax)
    integer, intent(in) :: imax
    ckiter_ifstop = .false.
    if(mod(imax,ifstop) == 0) then
       call m_Files_open_nfstop
       call m_CtrlP_rd_istop(nfstop)        ! ->istop
       if(istop >= 0 .and. istop <= imax) ckiter_ifstop = .true.
       call m_Files_close_nfstop
    else
       if(istop >= 0 .and. istop <= imax) ckiter_ifstop = .true.
    end if

  end function ckiter_ifstop

end function Ending_Time

#ifndef _EMPIRICAL_
logical function ChargeDensity_is_Converged()
  use m_Files,          only : nfout
  use m_Const_Parameters, only : ON, FIXED_CHARGE, FIXED_CHARGE_CONTINUATION, WHOLE, INITIALLY, DP, YES
  use m_Control_Parameters, only : printable, sw_submat_is_on, submat_is_done_this_iter, icond &
       &                     , m_CtrlP_set_renew_wf, sw_hubbard, nspin, m_CtrlP_get_edelta &
       &                     , m_CtrlP_clear_lmm_status_store &
       &                     , max_scf_iteration, max_scf_iteration_is_given
  use m_Charge_Density, only : m_CD_is_converged_core
  use m_Total_Energy,   only : m_TE_is_converged &
      &                      , m_TE_Converged_Hubbard_Energy, m_TE_edeltb
  use m_ES_WF_by_submat,only : m_ESsubmat_dealloc, m_ESsubmat_reset_non_diagon
  use m_Force,          only : m_Force_get_fec_count
  use m_ES_occup,       only : m_ESoc_efermi_diff, m_ESoc_new_total_spin, m_ESoc_total_spin0
  use m_Crystal_Structure,only : sw_fix_total_spin_in, sw_fix_total_spin,spin_fix_period &
       &                     , m_CS_set_total_spin, m_CS_free_fixed_total_spin, m_CS_fix_total_spin
  use m_Ionic_System,   only : natm2
  use m_IterationNumbers, only : iteration_electronic, iteration_ionic

! ====================== added by K. Tagami ======================= 12.0Exp
  use m_Const_Parameters,    only  : ALL_AT_ONCE, EK_CONVERGED
  use m_Control_Parameters,  only : fixed_charge_k_parallel, &
       &                            m_CtrlP_set_iconvergence,xctype
! ================================================================ 12.0Exp

! ====================== KT_Test ========================================= 12.5Exp
  use m_Const_Parameters,    only  : OFF
  use m_Control_Parameters,   only : sw_hybrid_functional, &
       &                             truncate_vxw_updating, sw_update_vxw, oneshot
! ======================================================================== 12.5Exp

  implicit none
  logical, save :: renew_wf_again = .false.
  logical :: EigenValues_are_Converged
  integer ::       fec_counter
!!$  real(kind=DP) :: total_spin_new, m_ESoc_new_total_spin, m_ESoc_efermi_diff &
!!$       &          ,Delta_Efermi
  real(kind=DP) :: total_spin_new, Delta_Efermi
  logical :: totalenergy_is_converged
  real(kind=DP) :: edeltb, edelta
  real(kind=DP),parameter :: delta_efermi_lower = 0.002
  real(kind=DP),parameter :: factor_initial = 10.0
  real(kind=DP),save :: factor = factor_initial

  if(icond == FIXED_CHARGE .or. icond == FIXED_CHARGE_CONTINUATION) then
     if(EigenValues_are_Converged()) then
        ChargeDensity_is_Converged = .true.
! ==================================== added by K. Tagami ============ 12.0Exp
        if ( fixed_charge_k_parallel == ALL_AT_ONCE ) then
           call m_CtrlP_set_iconvergence(EK_CONVERGED)
        endif
! ==================================================================== 12.0Exp
     else
        ChargeDensity_is_Converged = .false.
     end if
     return
  end if

  call m_Force_get_fec_count(fec_counter)
  if(fec_counter /= 0) then
     ChargeDensity_is_Converged = .true.
     if(printable) &
          & write(nfout,'(" !Convergence_Check: fec_counter = ",i8," is not zero")') fec_counter
  else
     if(renew_wf_again) then
        ChargeDensity_is_Converged = .true.
     else
! --> T. Yamasaki 07th Aug. 2009
        totalenergy_is_converged = m_TE_is_converged(nfout)
!!$        if(m_TE_is_converged(nfout)) then
        if(totalenergy_is_converged) then
           if(nspin == 2 .and. sw_fix_total_spin == YES .and. spin_fix_period == INITIALLY) then
              ChargeDensity_is_Converged = .false.
           else
              ChargeDensity_is_Converged = m_CD_is_converged_core(nfout)
           end if
! <--
        else
           ChargeDensity_is_Converged = .false.
        endif
! --> T. Yamasaki 06th Aug. 2009
        if(nspin == 2 .and. sw_fix_total_spin == YES .and. spin_fix_period >= INITIALLY) then
! -->       17th Aug. 2009
           if(spin_fix_period.gt.1 .and. iteration_electronic>=spin_fix_period)then
              call m_CS_free_fixed_total_spin(nfout)
           else if(iteration_electronic>=20 .and. spin_fix_period==INITIALLY) then
!!$                 Delta_efermi = m_ESoc_efermi_diff()
!!$              if(totalenergy_is_converged .and. dabs(Delta_efermi) < delta_efermi_lower ) then
!!$              if(totalenergy_is_converged .and. dabs(Delta_efermi) < delta_efermi_lower ) then
!!$                 if(printable) write(nfout,'(" !** dabs(Delta_efermi) = dabs(",f16.8 &
!!$                      &                        ,") < Delta_efermi_lower = ",f16.8, " and total energy is converged")') &
!!$                      &               delta_efermi, delta_efermi_lower
!!$                 call m_CS_free_fix_total_spin(nfout) ! sw_fix_total_spin = NO
              edeltb = m_TE_edeltb()
              call m_CtrlP_get_edelta(edelta)
              if(dabs(edeltb) < edelta*natm2*factor) then
                 factor = factor/2.0
                 if(factor < 1.0) factor = 1.0
                 if(printable) write(nfout,'(" dabs(edeltb) = dabs(",f16.12,") < edelta*natm2*factor = ",f16.12)') &
                      & edeltb, edelta*natm2*factor
! -->   
                 if(iteration_ionic >= 10) then   ! This is a test case
! <--
                    Delta_efermi = m_ESoc_efermi_diff()
                    if( dabs(Delta_efermi) < delta_efermi_lower ) then
                       if(printable) write(nfout,'(" !** dabs(Delta_efermi) = dabs(",f16.8 &
                            &                        ,") < Delta_efermi_lower = ",f16.8, " and total energy is converged")') &
                            &               delta_efermi, delta_efermi_lower
                       call m_CS_free_fixed_total_spin(nfout) ! sw_fix_total_spin = NO
                    else
                       if(totalenergy_is_converged) ChargeDensity_is_Converged = m_CD_is_converged_core(nfout)
                       if(.not.ChargeDensity_is_Converged) then
                          total_spin_new = m_ESoc_new_total_spin()
                          call m_CS_set_total_spin(nfout,total_spin_new)
                       end if
                    end if
                 else
                    if(totalenergy_is_converged) ChargeDensity_is_Converged = m_CD_is_converged_core(nfout)
                    if(.not.ChargeDensity_is_Converged) then
                       total_spin_new = m_ESoc_new_total_spin()
                       call m_CS_set_total_spin(nfout,total_spin_new)
                    end if
                 end if
              end if
           end if
!!$           if(iteration_electronic>=30 .and. mod(iteration_electronic,10)==1) then
!!$              Delta_efermi = m_ESoc_efermi_diff()
!!$              if(totalenergy_is_converged .and. dabs(Delta_efermi) < delta_efermi_lower ) then
!!$                 if(printable) write(nfout,'(" !** dabs(Delta_efermi) = dabs(",f16.8 &
!!$                      &                        ,") < Delta_efermi_lower = ",f16.8, " and total energy is converged")') &
!!$                      &               delta_efermi, delta_efermi_lower
!!$                 call m_CS_free_fix_total_spin(nfout) ! sw_fix_total_spin = NO
!!$              else
!!$                 total_spin_new = m_ESoc_new_total_spin()
!!$                 call m_CS_set_total_spin(nfout,total_spin_new)
!!$              end if
!!$           end if
! <--
        end if
! <--
     end if

! =========================== KT_Test ================= 12.5Exp
     if ( sw_hybrid_functional == ON ) then
        if ( truncate_vxw_updating .and. sw_update_vxw == OFF ) then
           ChargeDensity_is_Converged = .true.
        end if
     end if
! ====================================================== 12.5Exp

     if(sw_hubbard == ON) then
        if(m_TE_Converged_Hubbard_Energy(nfout)) then
           ChargeDensity_is_Converged = .true.
        end if
     end if

! --> T. Yamasaki, 18th Aug. 2009
     if(max_scf_iteration_is_given) then
        if(iteration_electronic >= max_scf_iteration) then
           ChargeDensity_is_Converged = .true.
        end if
     end if
! <--
     if(ChargeDensity_is_Converged) then
        if(renew_wf_again) then
           renew_wf_again = .false.
           call m_ESsubmat_dealloc()
        else if(sw_submat_is_on .and. .not.renew_wf_again) then
           if(.not.submat_is_done_this_iter) then
              if(printable) write(nfout,'(" !! sw_submat_is_on = .true. and renew_wf_again = .false.")')
              ChargeDensity_is_Converged = .false.
              renew_wf_again = .true.
              call m_ESsubmat_reset_non_diagon()
           end if
        else ! if(.not.sw_submat_is_on .and. .not.renew_wf_again) then
           call m_ESsubmat_dealloc()
        end if
! --> T. Yamasaki, 17th Aug. 2009
        if(nspin == 2 .and. sw_fix_total_spin_in == YES .and. spin_fix_period == INITIALLY) then
           call m_CS_fix_total_spin(nfout)
           total_spin_new = m_ESoc_total_spin0()
           call m_CS_set_total_spin(nfout,total_spin_new)
           factor = factor_initial
        end if
! <--
        call m_CtrlP_clear_lmm_status_store() ! --> T. Yamasaki, 18th Aug. 2009
#ifndef DISABLE_VDWDF
        if(xctype == 'vdwdf'.and.oneshot) call vdW_oneshot()
#endif
     end if
     call m_CtrlP_set_renew_wf(renew_wf_again)
  end if
end function ChargeDensity_is_Converged

logical function TotalEnergy_is_Divergent()
  use m_Total_Energy, only : m_TE_is_Divergent_core
  use m_Files,        only : nfout
! --> T. Yamasaki, 22nd July 2008
  use m_Control_Parameters,only : ipri,m_CtrlP_etot_1dsrch_divergent
  use m_IterationNumbers,  only : iteration_ionic, iteration_electronic
  implicit none
  TotalEnergy_is_Divergent = m_TE_is_Divergent_core(nfout)
  if(iteration_ionic > 1 .and. .not.TotalEnergy_is_Divergent) then
     TotalEnergy_is_Divergent = m_CtrlP_etot_1dsrch_divergent(iteration_electronic)
     if(TotalEnergy_is_Divergent) then
        if(ipri >= 1) write(nfout,'(" m_CtrlP_etot_1dsrch_divergent is .true.")')
     end if
  end if
! <--
end function TotalEnergy_is_Divergent

#endif

logical function AllForces_are_Converged()
  AllForces_are_Converged = .true.
end function AllForces_are_Converged

logical function Forces_are_Converged()
  use m_Control_Parameters, only : imdalg, ipriforce, icond, sw_phonon_oneshot &
       &                         , m_CtrlP_set_iconvergence &
       &                         , m_CtrlP_what_is_mdalg,sw_optimize_lattice &
#ifndef _EMPIRICAL_
       &                         , m_CtrlP_renew_edelta_ontheway, m_CtrlP_edelta_final &
       &                         , m_CtrlP_reset_edelta_ontheway
#else
       &                         , m_CtrlP_renew_edelta_ontheway, m_CtrlP_edelta_final
#endif
  use m_Const_Parameters,   only : DP,QUENCHED_CONSTRAINT,BLUEMOON &
       &                         , TEMPERATURE_CONTROL, FORCE_CONVERGED &
       &                         , VERLET, CNSTRA, ORDINA, WITHOUTTAG &
       &                         , WITHTAG, PHONON_FORCE &
       &                         , FIXED_CHARGE, FIXED_CHARGE_CONTINUATION, ON, INITIAL, OFF
  use m_Files,              only : nfout
  use m_IterationNumbers,   only : iteration_ionic,iteration,iteration_electronic
  use m_Ionic_System,       only : constraints_exist, move_constrained_plane &
       &                         , ekina,ega,almda,mdmode &
       &                         , forcmx_constraint_quench, cps, natm &
       &                         , m_IS_force_check_md_cnstr &
       &                         , m_IS_set_mdmode_cnstra &
       &                         , m_IS_set_mdmode_ordina &
       &                         , m_IS_evaluate_v_verlet &
! --> T. Yamasaki, 18 July 2008
       &                         , m_IS_cnstr_is_fixed_nhp &
       &                         , m_IS_force_check_md_nhp 
! <--
#ifndef _EMPIRICAL_
  use m_Phonon,             only : m_Phonon_Check_iteration
#endif
  use m_Force,              only : forcmx, forc_l &
       &                         , m_Forces_are_Converged_core
!!$       &                         , m_Forces_clear_fec_counter
  use m_Total_Energy,       only : etotal

  implicit none
  integer :: mdalg

  if(icond == FIXED_CHARGE .or. icond == FIXED_CHARGE_CONTINUATION) then
     Forces_are_Converged = .true.
     return
  end if

  if(imdalg == QUENCHED_CONSTRAINT) then
     if(constraints_exist .and. move_constrained_plane) then
        if(m_IS_force_check_md_cnstr() .and. m_CtrlP_edelta_final()) then
           call m_IS_set_mdmode_cnstra()
#ifndef _EMPIRICAL_
           call m_CtrlP_reset_edelta_ontheway()
#endif
        else
           call m_IS_set_mdmode_ordina()
        end if
        Forces_are_Converged = .false.
     else
        call m_IS_set_mdmode_ordina()
        Forces_are_Converged = m_IS_force_check_md_cnstr()
        if(.not.m_CtrlP_edelta_final()) Forces_are_Converged = .false.
        if(ipriforce >= 3)  then
           if(Forces_are_Converged) then
              write(nfout,'(" Forces_are_Converged(2) = .true.")')
           else
              write(nfout,'(" Forces_are_Converged(2) = .false.")')
           end if
        end if
     end if
  else if(imdalg == TEMPERATURE_CONTROL .or. imdalg == VERLET) then
     Forces_are_Converged = .false.
#ifndef _EMPIRICAL_
  else if(imdalg == PHONON_FORCE) then
     if(sw_phonon_oneshot == ON) then
        Forces_are_Converged = .true.
     else
        Forces_are_Converged = m_Phonon_Check_iteration(iteration_ionic)
	icond = INITIAL  ! asms
     end if
#endif
  else if(imdalg /= BLUEMOON) then
     if(constraints_exist .and. move_constrained_plane) then
        if(m_Forces_are_Converged_core() .and. m_CtrlP_edelta_final()) then ! This is a different
           !                                                                  line to the case of
           !                                                                 (imdalg == 
           !                                                                   QUENCHED_CONSTRAINT). 
           call m_IS_set_mdmode_cnstra()
#ifndef _EMPIRICAL_
           call m_CtrlP_reset_edelta_ontheway()
#endif
        else
           call m_IS_set_mdmode_ordina()
        end if
        Forces_are_Converged = .false.
!  --> T. Yamasaki, 18 July 2008
     else if(constraints_exist .and. m_IS_cnstr_is_fixed_nhp()) then
        if(m_IS_force_check_md_nhp()) then
           Forces_are_Converged = .true.
        else
           Forces_are_Converged = .false.
        end if
! <--
     else
        call m_IS_set_mdmode_ordina()
        Forces_are_Converged = m_Forces_are_Converged_core()
        if(.not.m_CtrlP_edelta_final()) Forces_are_Converged = .false.
     end if
  end if
  if(Forces_are_Converged) call m_CtrlP_set_iconvergence(FORCE_CONVERGED)
  mdalg = m_CtrlP_what_is_mdalg()

  if(Forces_are_Converged) then
!!$     call m_Forces_clear_fec_counter()
     if(mdalg == VERLET) call m_IS_evaluate_v_verlet(mdalg,forc_l)

     call wd_forces_cps_etotal_and_etc(mdalg,.true.) ! nfdynm
     if(sw_optimize_lattice==OFF) call wd_forces_cps_etotal_and_etc(mdalg,.false.) ! nfenf
#ifndef _EMPIRICAL_
     call m_CtrlP_reset_edelta_ontheway()
#endif
  else
     if(imdalg /= BLUEMOON .and. imdalg /= TEMPERATURE_CONTROL &
          & .and. imdalg /= VERLET .and. imdalg /= PHONON_FORCE) then 
        if(imdalg /= QUENCHED_CONSTRAINT) then
           call m_CtrlP_renew_edelta_ontheway(nfout,etotal,forcmx,iteration_ionic,iteration,iteration_electronic)
        else if(imdalg == QUENCHED_CONSTRAINT) then
           call m_CtrlP_renew_edelta_ontheway(nfout,etotal,forcmx_constraint_quench,iteration_ionic,iteration,iteration_electronic)
        end if
     end if
  end if
end function Forces_are_Converged

logical function UnitCell_Converged(force_converged)
   use m_Control_Parameters, only : sw_optimize_lattice,imdalg,m_CtrlP_reset_iconvergence,icond
   use m_Const_Parameters, only : OFF,FIXED_CHARGE,FIXED_CHARGE_CONTINUATION
   use m_UnitCell, only : m_UC_converged
   implicit none
   logical, intent(in) :: force_converged
   if(icond == FIXED_CHARGE .or. icond == FIXED_CHARGE_CONTINUATION) then
      UnitCell_Converged = .true.
      return
   endif
   if(sw_optimize_lattice==OFF)then
      UnitCell_Converged = force_converged
      return
   endif
   UnitCell_Converged = m_UC_converged()
   if(force_converged) call wd_forces_cps_etotal_and_etc(imdalg,.false.) ! nfenf
   if(.not.UnitCell_Converged) call m_CtrlP_reset_iconvergence()
end function UnitCell_Converged


subroutine wd_forces_cps_etotal_and_etc(mdalg,flag_dynm)
  use m_Const_Parameters,   only : DP,QUENCHED_CONSTRAINT, BLUEMOON &
       &                         , TEMPERATURE_CONTROL &
       &                         , VERLET, CNSTRA, WITHOUTTAG &
       &                         , WITHTAG, OFF, ON
  use m_Files,              only : nfout, nfenf, nfdynm, m_Files_flush_nfdynm, m_Files_flush_nfenf, nfdynm_cif
  use m_IterationNumbers,   only : iteration_ionic,iteration,iteration_electronic,iteration_unit_cell
  use m_Parallelization,    only : mype
  use m_Control_Parameters, only : ipriforce, iprivelocity &
       &                         , m_CtrlP_flag_wd_force &
       &                         , m_CtrlP_set_flag_wd_force_1 &
       &                         , sw_optimize_lattice &
       &                         , sw_cif_output, xctype, printable
  use m_Force,              only : forcmx &
       &                         , m_Force_wd_force_and_cps &
       &                         , m_Force_wd_force_cps_cpd &
!!$       &                         , m_Force_cal_absforc &
       &                         , m_Force_wd_force_and_cps_lim &
       &                         , m_Force_wd_force_cps_cpd_lim
  use m_Ionic_System,       only : ekina,ega,almda,mdmode &
       &                         , forcmx_constraint_quench, cps,cpd_l,natm &
       &                         , constraints_exist, forcmx_hyperplane_vert &
       &                         , m_IS_cnstr_is_fixed_nhp &
       &                         , m_IS_wd_speciesname_etc &
       &                         , m_IS_dump_cif
  use m_Total_Energy,       only : etotal
  use m_Stress,             only : m_Stress_get_stressmx
  use m_XC_Potential,       only : ecor

  implicit none
  integer, intent(in) :: mdalg
  logical, intent(in) :: flag_dynm

  integer, parameter :: N_FORC = 10

  integer :: flag_wd_force

  if(flag_dynm) then
     flag_wd_force = m_CtrlP_flag_wd_force()
     call wd_forces_and_cps(flag_wd_force)
     if(flag_wd_force == 0) call m_CtrlP_set_flag_wd_force_1()
  else
     call wd_etotal_etc()
  end if

contains
    subroutine wd_etotal_etc
    integer        :: wd_flag = 0
    real(kind=DP)  :: econst
    real(kind=DP)  :: stressmx
    real(kind=DP)  :: big=10000000.d0
    if(wd_flag == 0) then
       if(mdalg == VERLET .or. mdalg == TEMPERATURE_CONTROL) then
          if(mype == 0) write(nfenf,*) &
               & ' iter_ion, iter_total, etotal, ekina, econst, forcmx'
       else if(mdalg == BLUEMOON) then
          if(mype == 0) write(nfenf,*) &
               & ' iter_ion, iter,etotal,ekina,econst,almda,forcmx'
       else
          if(sw_optimize_lattice==OFF)then
          if(mype == 0) write(nfenf,*) ' iter_ion, iter_total, etotal, forcmx'
          else
          if(mype == 0) write(nfenf,*) ' iter_unitcell, iter_ion, iter_total, etotal, forcmx, stressmx'
          endif
       end if
       wd_flag = 1
    end if
    if(xctype=='ggapbey')then
       if(printable) then
          write(nfout,'(a)') ' !** subtracting the correlation energy from the total energy'
          write(nfout,'(a)') ' !** since xctype is ggapbey '
       endif
       etotal = etotal-ecor
    endif
    if(mdalg == VERLET .or. mdalg == TEMPERATURE_CONTROL) then
       if(mdalg == TEMPERATURE_CONTROL) then
          econst = etotal + ega
       else
          econst = etotal + ekina
       end if
       if(mype == 0) then
          if(mdmode == CNSTRA) then
             if(abs(etotal)<big)then
             write(nfenf,'(" ",i5,i8,4f20.10,"  converged_in_a_plane")') iteration_ionic, iteration &
                  &, etotal, ekina, econst,  forcmx
             else
             write(nfenf,'(" ",i5,i8," ",f0.10," ",f0.10," ",f0.10," ",f0.10,"  converged_in_a_plane")') &
                  & iteration_ionic, iteration, etotal, ekina, econst,  forcmx
             endif
          else
             if(abs(etotal)<big)then
             write(nfenf,'(" ",i5,i8,4f20.10)') iteration_ionic, iteration &
                  &, etotal, ekina, econst,  forcmx
             else
             write(nfenf,'(" ",i5,i8," ",f0.10," ",f0.10," ",f0.10," ",f0.10)') iteration_ionic, iteration &
                  &, etotal, ekina, econst,  forcmx
             endif
          end if
       end if
    else if(mdalg == BLUEMOON) then
       econst = etotal + ega
       if(mype == 0) then
            if(abs(etotal)<big)then
            write(nfenf,'(" ",i5,i8,5f20.8)') iteration_ionic, iteration &
            &, etotal, ekina, econst, almda, forcmx
            else
            write(nfenf,'(" ",i5,i8," ",f0.8," ",f0.8," ",f0.8," ",f0.8," ",f0.8)') iteration_ionic, iteration &
            &, etotal, ekina, econst, almda, forcmx
            endif
       endif
    else if(mdalg == QUENCHED_CONSTRAINT) then
       if(mype == 0) then
          if(mdmode == CNSTRA) then
             if(abs(etotal)<big)then
             write(nfenf,'(" ",i5,i8,2f20.10," converged_in_a_plane")') iteration_ionic, iteration &
                  &, etotal, forcmx_constraint_quench
             else
             write(nfenf,'(" ",i5,i8," ",f0.10," ",f0.10," converged_in_a_plane")') iteration_ionic, iteration &
                  &, etotal, forcmx_constraint_quench
             endif
          else
             if(abs(etotal)<big)then
             write(nfenf,'(" ",i5,i8,2f20.10)') iteration_ionic, iteration &
                  &, etotal, forcmx_constraint_quench
             else
             write(nfenf,'(" ",i5,i8," ",f0.10," ",f0.10)') iteration_ionic, iteration &
                  &, etotal, forcmx_constraint_quench
             endif
          end if
       end if
    else
       if(mype == 0) then
          if(mdmode == CNSTRA) then
             if(abs(etotal)<big)then
             write(nfenf,'(" ",i5,i8,2f20.10," converged_in_a_plane")') iteration_ionic, iteration &
                  &, etotal, forcmx
             else
             write(nfenf,'(" ",i5,i8," ",f0.10," ",f0.10," converged_in_a_plane")') iteration_ionic, iteration &
                  &, etotal, forcmx
             endif
          else
             if(sw_optimize_lattice==OFF)then
!  --> T. Yamasaki, 18 July 2008
             if(constraints_exist .and. m_IS_cnstr_is_fixed_nhp() &
                  & .and. forcmx_hyperplane_vert < forcmx ) then
                if(abs(etotal)<big)then
                write(nfenf,'(" ",i5,i8,2f20.10)') iteration_ionic, iteration &
                     &, etotal, forcmx_hyperplane_vert
                else
                write(nfenf,'(" ",i5,i8," ",f0.10," ",f0.10)') iteration_ionic, iteration &
                     &, etotal, forcmx_hyperplane_vert
                endif
             else
                if(abs(etotal)<big)then
                write(nfenf,'(" ",i5,i8,2f20.10)') iteration_ionic, iteration &
                     &, etotal, forcmx
                else
                write(nfenf,'(" ",i5,i8," ",f0.10," ",f0.10)') iteration_ionic, iteration &
                     &, etotal, forcmx
                endif
             end if
!  <--
             else
                stressmx = m_Stress_get_stressmx()
                if(stressmx>=0) then
                  if(abs(etotal)<big)then
                  write(nfenf,'(" ",i5,i5,i8,3f20.10)') iteration_unit_cell, iteration_ionic, iteration &
                       &, etotal, forcmx,stressmx
                  else
                  write(nfenf,'(" ",i5,i5,i8," ",f0.10," ",f0.10," ",f0.10)') iteration_unit_cell, iteration_ionic, iteration &
                       &, etotal, forcmx,stressmx
                  endif
                else
                  if(abs(etotal)<big)then
                  write(nfenf,'(" ",i5,i5,i8,2f20.10)') iteration_unit_cell, iteration_ionic, iteration &
                       &, etotal, forcmx
                  else
                  write(nfenf,'(" ",i5,i5,i8," ",f0.10," ",f0.10)') iteration_unit_cell, iteration_ionic, iteration &
                       &, etotal, forcmx
                  endif
                endif
             endif
          end if
       end if
    end if
    call m_Files_flush_nfenf()

  end subroutine wd_etotal_etc

  subroutine wd_forces_and_cps(flag_wd_force)
!
! (iprivelocity)
!    Modified by T. Yamasaki, April/10/2007
! 
    integer, intent(in) :: flag_wd_force
    character(len=256) :: ch
!!$    real(kind=DP) :: forc_lower

    if(flag_wd_force == 0) then
       call m_IS_wd_speciesname_etc(nfdynm)
    end if

    if(mype == 0 .and. iprivelocity <= 1) then
       if(mdmode == CNSTRA) then
          write(nfdynm,'(" cps and forc at (iter_ion, iter_total = " &
               & ,i5,i8," ) converged_in_a_plane")') iteration_ionic, iteration
       else
          write(nfdynm,'(" cps and forc at (iter_ion, iter_total = " &
               & ,i5,i8," )")') iteration_ionic, iteration
       end if
    else if(mype == 0 .and. iprivelocity >= 2) then
       if(mdmode == CNSTRA) then
          write(nfdynm,'(" cps cpd and forc at (iter_ion, iter_total = " &
               & ,i5,i8," ) converged_in_a_plane")') iteration_ionic, iteration
       else
          write(nfdynm,'(" cps cpd and forc at (iter_ion, iter_total = " &
               & ,i5,i8," )")') iteration_ionic, iteration
       end if
    end if

    if(iprivelocity <= 1.and.mype==0) then
       call m_Force_wd_force_and_cps(nfdynm, WITHOUTTAG, cps, natm)
    else if(iprivelocity >= 2.and.mype==0) then
       call m_Force_wd_force_cps_cpd(nfdynm, WITHOUTTAG,cps,cpd_l,natm)
    end if

    if(mype==0.and.sw_cif_output==ON)then
       write(ch,*) iteration_ionic
       call m_IS_dump_cif(nfdynm_cif,'iteration_ionic_'//trim(adjustl(ch)))
    endif

    call m_Files_flush_nfdynm()

    if(ipriforce >= 1) then
       if(mype == 0 .and. iprivelocity <= 1) then
          write(nfout,'(" !forc cps and forc at (iter_ion, iter_total = " &
               & ,i5,i8," )")') iteration_ionic, iteration
       else if(mype == 0 .and. iprivelocity >= 2) then
          write(nfout,'(" !forc cps cpd and forc at (iter_ion, iter_total = " &
               & ,i5,i8," )")') iteration_ionic, iteration
       end if
    end if
#ifdef _DEBUG_WRITE_
    if(ipriforce >= 1) then
#else
    if(ipriforce == 1 .and. natm > N_FORC) then
!!$       call m_Force_cal_absforc(N_FORC, forc_lower)
!!$       write(nfout,'(" forc_lower = ",e12.4)') forc_lower
       if(iprivelocity <= 1) then
          call m_Force_wd_force_and_cps_lim(nfout, WITHTAG, cps, natm, N_FORC)
       else if(iprivelocity >= 2) then
          call m_Force_wd_force_cps_cpd_lim(nfout, WITHTAG, cps,cpd_l,natm, N_FORC)
       end if
    else if(ipriforce >= 2 .or. (ipriforce == 1 .and. natm <= N_FORC) ) then
#endif
       if(iprivelocity <= 1) then
          call m_Force_wd_force_and_cps(nfout, WITHTAG, cps, natm)
       else if(iprivelocity >= 2) then
          call m_Force_wd_force_cps_cpd(nfout, WITHTAG, cps,cpd_l,natm)
       end if
    end if

  end subroutine wd_forces_and_cps

end subroutine wd_forces_cps_etotal_and_etc

#ifndef _EMPIRICAL_
logical function Force_errors_are_tolerable()
  use m_Const_Parameters,   only : OFF, ON
  use m_Files,              only : nfout
  use m_Control_Parameters, only : force_error_check_mode &
       &                         , force_error_check_rangeL, sw_phonon
!!$       &                         , m_CtrlP_what_is_mdalg
  use m_Force,              only : forcmx, m_Force_error_tolerable &
       &                         , m_Force_clear_fec_counter

  implicit none
!!$  integer :: mdalg

!!$  if(force_error_check_mode == OFF .or. forcmx < force_error_check_rangeL) then
  if(sw_phonon == ON .or. force_error_check_mode == OFF .or. forcmx < force_error_check_rangeL) then
     Force_errors_are_tolerable = .true.
     ! --> T. Yamasaki, August 8 2008
     call m_Force_clear_fec_counter()
     ! <--
  else
     if(m_Force_error_tolerable(nfout)) then
        Force_errors_are_tolerable = .true.
     else
        Force_errors_are_tolerable = .false.
     end if
  end if
  
!!$  mdalg = m_CtrlP_what_is_mdalg()
!!$  if(Force_errors_are_tolerable) call wd_forces_cps_etotal_and_etc(mdalg)
end function Force_errors_are_tolerable
#endif

logical function Already_Converged()
  use m_Control_Parameters, only : iconvergence_previous_job &
      &                          , sw_phonon, sw_calc_force, max_total_scf_iteration
  use m_Const_Parameters, only :   FORCE_CONVERGED
  implicit none
  if(iconvergence_previous_job >= FORCE_CONVERGED) then
     Already_Converged = .true.
  else
     Already_Converged = .false.
  end if
  if(sw_phonon == 1 .and. sw_calc_force == 0) Already_Converged = .true.
  if(max_total_scf_iteration <= 0) Already_Converged = .true.
end function Already_Converged

logical function MultiReplicaMode()
  use m_Control_Parameters, only  : multiple_replica_mode
  use m_Ionic_System,       only  : number_of_replicas
  use m_Const_Parameters, only    : ON
  if(multiple_replica_mode == ON .and. number_of_replicas >= 2) then
     MultiReplicaMode = .true.
  else
     MultiReplicaMode = .false.
  end if
end function MultiReplicaMode

#ifndef _EMPIRICAL_
logical function EigenValues_are_Converged()
  use m_Const_Parameters,     only : EK, SCF,GRID, ON, YES, FIXED_CHARGE, FIXED_CHARGE_CONTINUATION &
       &                           , ONE_BY_ONE, OFF
  use m_Control_Parameters,   only : ekmode,nspin,neg,max_total_scf_iteration,ipri,ipriekzaj,iprievdff &
       &                           , ek_max_iteration, sw_berry_phase, sw_ekzaj, printable, icond &
       &                           , fixed_charge_k_parallel
  use m_IterationNumbers,     only : iteration_electronic, iteration, nk_converged &
       &                           , m_Iter_set_converged_nk, nkgroup, nk_in_the_process
  use m_Files,                only : nfout, nfeng, nfzaj &
       &                           , m_Files_open_nfzaj_with_check
  use m_Kpoints,              only : kv3_ek, kv3
  use m_Parallelization,      only : nrank_k, npes, ierr, mype, mpi_comm_group
  use m_Electronic_Structure, only : m_ES_eekdif, m_ES_eekdif2 &
       &                           , m_ES_cp_eko_l_to_eko_ek &
       &                           , m_ES_cp_eko_l_to_eko_ek2 &
       &                           , m_ES_wd_eko

  use m_ES_IO,                only : m_ESIO_wd_WFs_and_EVs_ek
  use m_ES_IO,                only : m_ESIO_wd_EigenValues
  use m_BerryPhase,           only : m_BP_write_wfbp, m_BP_write_wfbp_gshift

  implicit none
  include 'mpif.h'                                      ! MPI
  integer :: ipri0, kv3_t

  if(ekmode == OFF .and. &
       & (icond==FIXED_CHARGE .or. icond==FIXED_CHARGE_CONTINUATION) &
       & .and. fixed_charge_k_parallel == ONE_BY_ONE) then
     EigenValues_are_Converged = m_ES_eekdif2()
!!$     if(nrank_k >= 2) then
!!$        call m_ESIO_wd_EigenValues(nfout,iprievdff,nooccupation=YES)
!!$     end if
  else     
     EigenValues_are_Converged = m_ES_eekdif()
  end if

  if(sw_ekzaj==ON .and. ekmode==ON ) EigenValues_are_Converged = .true.

  if(EigenValues_are_Converged) then
!!$     if(nk_in_the_process >= kv3_ek) stop ' nk_in_the_process >= kv3_ek <<Eigenvalues_are_converged>>'
     if(printable) write(nfout,'(" Wave Functions have converged at ",i7," -th iteration")') iteration_electronic

! ===================== modified by K. Tagami ========================= 12.0Exp
!     if(nk_converged == 0 .and. mype==0) then
!!!$     write(nfeng,'(" nk_converged = ",i6)') nk_converged
!        write(nfeng,'(" num_kpoints = ",i6)') kv3_ek
!        write(nfeng,'(" num_bands   = ",i6)') neg
!        write(nfeng,'(" nspin       = ",i6)') nspin
!        write(nfeng,'(" Fermi energy level = "/)')
!     end if
!
     if ( fixed_charge_k_parallel == ONE_BY_ONE ) then
        if (nk_converged == 0 .and. mype==0) then
           write(nfeng,'(" num_kpoints = ",i6)') kv3_ek
           write(nfeng,'(" num_bands   = ",i6)') neg
           write(nfeng,'(" nspin       = ",i6)') nspin
           write(nfeng,'(" Fermi energy level = "/)')
        end if
     else
        if (nk_converged == 0 .and. mype==0) then
           write(nfeng,'(" num_kpoints = ",i6)') kv3
           write(nfeng,'(" num_bands   = ",i6)') neg
           write(nfeng,'(" nspin       = ",i6)') nspin
           write(nfeng,'(" Fermi energy level = "/)')
        end if
     endif
! ==================================================================== 12.0Exp

     if(ekmode == ON) then
! === DEBUG by tkato 2013/10/18 ================================================
!       call m_ES_cp_eko_l_to_eko_ek()
        call m_ES_cp_eko_l_to_eko_ek2()
! ==============================================================================
     else if((icond==FIXED_CHARGE .or. icond==FIXED_CHARGE_CONTINUATION) .and. &
           fixed_charge_k_parallel == ONE_BY_ONE) then
        call m_ES_cp_eko_l_to_eko_ek2()
     end if

     if(nrank_k >= 2) then
        call m_ESIO_wd_EigenValues(nfout,2,nooccupation=YES)
        call m_ESIO_wd_EigenValues(nfeng,2,nooccupation=YES)
     else
        call m_ES_wd_eko(nfout,mode=EK)
        call m_ES_wd_eko(nfeng,mode=EK)
     end if
!!$     if(nk_in_the_process >= kv3_ek) stop ' nk_in_the_process >= kv3_ek (2)<<Eigenvalues_are_converged>>'
  else if(iteration_electronic >= ek_max_iteration) then
!!$       & .or. iteration >= max_total_scf_iteration ) then
     if(ekmode == ON) then
! === DEBUG by tkato 2013/10/18 ================================================
!       call m_ES_cp_eko_l_to_eko_ek()
!       write(nfout,'(" m_ES_cp_eko_l_to_eko_ek")')
        call m_ES_cp_eko_l_to_eko_ek2()
! ==============================================================================
     else if((icond==FIXED_CHARGE .or. icond==FIXED_CHARGE_CONTINUATION) .and. &
           fixed_charge_k_parallel == ONE_BY_ONE) then
        call m_ES_cp_eko_l_to_eko_ek2()
!!$        write(nfout,'(" m_ES_cp_eko_l_to_eko_ek2")')
     end if
     if(mype == 0) then
        write(nfout,'(" Wave Functions have not converged")')
        write(nfout,'(" iteration_electronic reached to ek_max_iteration (= ",i5," )")') ek_max_iteration
     end if
     if(nrank_k >= 2) then
        call m_ESIO_wd_EigenValues(nfout,2,nooccupation=YES)
        call m_ESIO_wd_EigenValues(nfeng,2,nooccupation=YES)
     else
        call m_ES_wd_eko(nfout,mode=EK)
        call m_ES_wd_eko(nfeng,mode=EK)
     end if
     EigenValues_are_Converged = .true.
!!$     if(iteration >= max_total_scf_iteration) write(nfout,'(" iteration has reached to max_total_scf_iteration")')
     if(iteration_electronic >= ek_max_iteration .and. mype==0) & 
      & write(nfout,'(" iteration_electronic has reached to ek_max_iteration")')
  end if

! ============================== added by K. Tagami =============== 12.0Exp
  if ( fixed_charge_k_parallel /= ONE_BY_ONE ) return
! ================================================================= 12.0Exp

  if(EigenValues_are_Converged) then
     if(ipri >= 2) write(nfout,'(" ipriekzaj = ",i8," <<EigenValues_are_Converged>>")') ipriekzaj
     if(ipriekzaj >= 1 .and. ekmode /= GRID .and. sw_ekzaj/=ON) then
        call m_Files_open_nfzaj_with_check()
        call m_ESIO_wd_WFs_and_EVs_ek(nfout,nfzaj)
     end if
     if(sw_berry_phase == 1) then
        call m_BP_write_wfbp_gshift ! for the initial k-point of a strig
        call m_BP_write_wfbp
     end if
!!$     call m_Iter_set_converged_nk(nspin)
     kv3_t = min(kv3, kv3_ek-kv3*(nkgroup-1))
     call m_Iter_set_converged_nk(kv3_t)
  else
     ipri0 = iprievdff
!!$     if(nrank_k>=2) call mpi_bcast(ipri0,1,mpi_integer,0,mpi_comm_group,ierr)
     if(npes>=2)    call mpi_bcast(ipri0,1,mpi_integer,0,mpi_comm_group,ierr)
     if((ipri0 >= 1 .and. mod(iteration_electronic,10)==1) &
          .or. ipri0 >= 2 ) then
        if(printable) write(nfout,'(" iteration_electronic = ",i6)') iteration_electronic
        if(nrank_k >= 2) then
           call m_ESIO_wd_EigenValues(nfout,2,nooccupation=YES)
        else
           call m_ES_wd_eko(nfout,mode=EK)
        end if
     end if
  end if
end function EigenValues_are_Converged

logical function AllKpoints_are_Calculated()
  use m_Files,              only : nfout
  use m_Const_Parameters,   only : EK_CONVERGED
  use m_IterationNumbers,   only : nk_converged, m_Iter_nk_incre2
  use m_Control_Parameters, only : nspin, ipri, m_CtrlP_set_iconvergence
  use m_Kpoints,            only : kv3_ek

  AllKpoints_are_Calculated = .false.
  if(ipri >= 2) write(nfout,'(" !!! nk_converged = ",i8)') nk_converged
  if(nk_converged+nspin-1 >= kv3_ek) then
     AllKpoints_are_Calculated = .true.
     if(ipri >= 1) write(nfout,'(" All kpoints have been calculated ")')
  end if
  if(AllKpoints_are_Calculated) then
     call m_CtrlP_set_iconvergence(EK_CONVERGED)
     call m_Iter_nk_incre2(nspin,kv3_ek)
  end if
end function AllKpoints_are_Calculated

logical function AllKpoints_are_Converged()
  use m_Files,              only : nfout
  use m_Const_Parameters,   only : EK_CONVERGED
  use m_IterationNumbers,   only : nk_in_the_process
  use m_Control_Parameters, only : ipri, m_CtrlP_set_iconvergence
  use m_Kpoints,            only : kv3_ek

  AllKpoints_are_Converged = .false.
  if(nk_in_the_process > kv3_ek) then
     AllKpoints_are_Converged = .true.
     if(ipri >= 1) write(nfout,'(" All Kpoints have been converged")')
  end if
  if(AllKpoints_are_Converged) call m_CtrlP_set_iconvergence(EK_CONVERGED)
end function AllKpoints_are_Converged

logical function AllKpoints_are_Calculated2(nk)
  use m_Files,              only : nfout
  use m_Const_Parameters,   only : EK_CONVERGED
  use m_IterationNumbers,   only : nk_converged, nk_in_the_process, m_Iter_nk_incre2
  use m_Control_Parameters, only : ipri, nspin, m_CtrlP_set_iconvergence
  use m_Kpoints,            only : kv3_ek, kv3

  integer, intent(inout) :: nk

  nk = nk + kv3
  if(ipri >= 1) write(nfout,'(" nk, nk_in_the_process = ",2i8)') nk,nk_in_the_process
!!$  if(nk >= kv3_ek) then
!!$  if(nk_in_the_process >= kv3_ek) then
!!$  if(nk_in_the_process+kv3 >= kv3_ek) then
  if(nk_converged >= kv3_ek) then
     AllKpoints_are_Calculated2 = .true.
     call m_Iter_nk_incre2(nspin,kv3_ek) !-> nk_in_the_process
  else
     AllKpoints_are_Calculated2 = .false.
  end if
  if(AllKpoints_are_Calculated2) call m_CtrlP_set_iconvergence(EK_CONVERGED)
end function AllKpoints_are_Calculated2

subroutine Set_converged_nk()
  use m_IterationNumbers,   only : m_Iter_set_converged_nk
  use m_Control_Parameters, only : nspin
  call m_Iter_set_converged_nk(nspin)
end subroutine Set_converged_nk

logical function Already_Converged2()
  ! coded by T. Yamasaki, 31 May 2007
  use m_Const_Parameters, only : FORCE_CONVERGED
  use m_Control_Parameters, only : iconvergence, iconvergence_previous_job
  if(iconvergence >= FORCE_CONVERGED .or. iconvergence_previous_job >= FORCE_CONVERGED) then
     Already_Converged2 = .true.
  else
     Already_Converged2 = .false.
  end if
end function Already_Converged2

logical function Already_Converged_for_kgroup()
  use m_Kpoints, only           : kv3_ek, kv3
  use m_IterationNumbers, only  : nkgroup, nk_in_the_process
  use m_Control_Parameters,only : ipri,nspin
  use m_Const_Parameters, only  : EK_CONVERGED
  use m_Electronic_Structure, only : iconv_ek
  use m_Files, only             : nfout
  integer :: i
  Already_Converged_for_kgroup = .true.
  do i = nk_in_the_process, min(nk_in_the_process + kv3, kv3_ek)
     if(iconv_ek(i) < EK_CONVERGED) then
        Already_Converged_for_kgroup = .false.
        exit
     end if
  end do
  if(ipri >= 2 .and. .not.Already_Converged_for_kgroup) then
     write(nfout,'(" -- Convergence status for ek --")')
     write(nfout,'(40i2)') (iconv_ek(i),i=nk_in_the_process, min(nk_in_the_process+kv3,kv3_ek))
  end if
!!$  if(Already_Converged_for_kgroup) call m_Iter_nkgroup_incre() !-> nk_in_the_process
end function Already_Converged_for_kgroup

logical function Positron_Bulk()
  ! Coded by T. Yamasaki, 29 Oct. 2003
  use m_Const_Parameters, only :   BULK
  use m_Control_Parameters, only : sw_positron
  if(sw_positron == BULK) then
     Positron_Bulk = .true.
  else
     Positron_Bulk = .false.
  end if
end function Positron_Bulk

logical function Positron_Defect()
  ! Coded by T. Yamasaki, 11 Dec. 2005
  use m_Const_Parameters, only :   DEFECT
  use m_Control_Parameters, only : sw_positron
  if(sw_positron == DEFECT) then
     Positron_Defect = .true.
  else
     Positron_Defect = .false.
  end if
end function Positron_Defect

logical function Structure_is_fixed()
  ! Coded by T. Yamasaki, 25 Jul. 2008
  use m_Const_Parameters, only :   ON, VERLET
  use m_Control_Parameters, only : sw_fix &
       &                         , m_CtrlP_set_iconvergence &
       &                         , m_CtrlP_what_is_mdalg
  use m_Const_Parameters,   only : FORCE_CONVERGED
  use m_Ionic_System,       only : m_IS_evaluate_v_verlet
  use m_Force,              only : forc_l
  integer :: mdalg

  if(sw_fix == ON) then
     Structure_is_fixed = .true.
  else
     Structure_is_fixed = .false.
  end if
  if(Structure_is_fixed) call m_CtrlP_set_iconvergence(FORCE_CONVERGED)
  if(Structure_is_fixed) then
     mdalg = m_CtrlP_what_is_mdalg()
     if(mdalg == VERLET) call m_IS_evaluate_v_verlet(mdalg,forc_l)
     call wd_forces_cps_etotal_and_etc(mdalg,.true.) ! nfdynm
     call wd_forces_cps_etotal_and_etc(mdalg,.false.) ! nfenf
  end if
end function Structure_is_fixed

logical function Hubbard_model()
  use m_Const_Parameters, only : ON
  use m_Control_Parameters, only : sw_hubbard
  use m_Total_Energy,   only : m_TE_Converged_Hubbard_Energy
  implicit none
  Hubbard_model=.false.
  if(sw_hubbard == ON) then
     Hubbard_model=.true.
     !!if(m_TE_Converged_Hubbard_Energy(nfout)) Hubbard_model=.false.
  end if
  !!$write(6,*) "Hubbard_model=",Hubbard_model
end function Hubbard_model
#endif
