[Wien] on-site hybrid functionals

Peter Blaha peter.blaha at tuwien.ac.at
Tue Aug 4 15:49:17 CEST 2026


Dear Kateryna,

I checked your case and could reproduce the problem.

runeece   does not use   lapwdm  (as it should when so is on), but 
simply  lapw2 -orb -so -up/dn

lapw2 produces a "symmetric" density matrix, which explains your problem.

I modified runeece and now it uses again lapwdm when -so is set.
This produces the desired asymmetry in the dmat occupations.

The error concerns only:   runsp -eece -so

runsp -so     or
runsp -eece   were ok.

Best regards and thanks for the report

Peter
-------------- next part --------------
#!/bin/tcsh -f
unalias rm
set name  = $0
set bin   = $name:h		#directory of WIEN-executables
if !(-d $bin) set bin = .
set name  = $name:t 		#name of this script-file
set logfile = :log
set tmp   = (:$name)		#temporary files
set scratchstring =

#---> functions & subroutines
alias	testinput	'set errin="\!:1";if (! -e \!:1 || -z \!:1) goto \!:2'
alias	teststatus	'if ($status) goto error'
alias	testerror	'if ( -e \!:1.error && ! -z \!:1.error) goto error'
alias   cleandayfile    'grep -v "\[" $dayfile >.tmp;'\
                        'mv .tmp $dayfile'
alias	output		'set date = `date +"(%T)"`;'\
			'printf ">   %s\t%s " "\!:*" "$date" >> $dayfile'

alias	exec		'($bin/x  \!:*) >> $dayfile;'\
			'teststatus'

alias	total_exec	'output \!:*;'\
			'exec \!:*;'\
                        'cleandayfile;'\
			'testerror \!:1;'\
			'testerror up\!:1;'\
			'testerror dn\!:1;'

#---> handling of input options
echo ">   ($name) options: $argv"	>> $logfile
alias sb 'shift; breaksw'	#definition used in switch
set in1orig
set para
set so
set vresp
set tau
unset help		#set -> help output
set complex		#set -> complex calculation
set cmplx		#set -> complex calculation
set file    = `pwd`
set file    = $file:t		#tail of file-names
set dayfile = $file.dayfile	#main output-file
unset sp_c
unset afm               # Added by ldm
unset fsm               # Added by ldm

while ($#argv)
  switch ($1)
  case -[H|h]:
    set help; sb
  case -so:
    set so = -so; sb
  case -p:
    set para = -p; sb
  case -in1orig:
    set in1orig = -in1orig; sb
  case -vresp:
    set vresp = -vresp; sb
  case -tau:
    set tau = -tau; sb
  case -sp_c:           #LDM
    set sp_c  = -sp_c; sb
  case -afm:            #LDM
    set afm   = -afm; sb
  case -fsm:            #LDM
    set fsm   = -fsm; sb
  case -scratch:
    shift;set scratch = $1
    set ncar=`echo $scratch |wc -m`
    @ ncar --
    set lcar=`echo $scratch | cut -c$ncar`
    if("$lcar" != '/' ) set scratch=`echo "${scratch}/"`
    set scratchstring="-scratch $scratch"
    if ( "$scratch" == "./" ) then
        set scratch=
        set scratchstring=
    else if(! -e "$scratch" ) then
        mkdir -p $scratch
    endif
    shift; breaksw  
  default:
    set command = $1
    shift; breaksw
  endsw
end

if($?help) goto help

#set file=$1
set infile=$file.ineece
testinput	$infile error_input

unalias grep
#set mode=`grep HYBR $infile`
#if ($#mode == 0 ) then
#  set mode=`grep EECE $infile`
#  if ($#mode == 0 ) then
#    echo ERROR: HYBR or EECE keywords not found in $infile
#    goto error_input
#  endif
#endif
#if ($#mode >= 2 ) set mode =$mode[1]

if ( -e $file.in1c && ! -z $file.in1c) set complex=c
if( "$so" == "-so" ) set complex=c
if( $complex == c ) set cmplx=-c
testinput	$file.in2$complex error_input

if (-e $file.scfeece) rm $file.scfeece

set nattest=`head -1 $infile`
#echo $#nattest $nattest
set emin=$nattest[1]
set nat=$nattest[2]


#initialize arrays
echo 0 > temp_mist
set i=1
while($i <= $nat )
echo 0 >> temp_mist
@ i ++
end
set atom_info=`cat temp_mist`
set l_max=`cat temp_mist`
set l_value1=`cat temp_mist`
set l_value2=`cat temp_mist`
set l_value3=`cat temp_mist`
set l_value4=`cat temp_mist`
rm temp_mist

#parse input file
set lmax=0
set i=1
while($i <= $nat )
@ j = 1 + $i
set test=`head -$j $infile | tail -1`
set atom_info[$i]=$test[1]
set l_max[$i]=$test[2]
set l_value1[$i]=$test[3]
if( $#test > 3 ) then
  set l_value2[$i]=$test[4]
endif
if( $#test > 4 ) then
  set l_value3[$i]=$test[5]
endif
if( $#test > 5 ) then
  set l_value4[$i]=$test[6]
endif
if($lmax < $l_max[$i] ) set lmax=$l_max[$i]
@ i ++
end

@ i ++
set mode=`head -$i $infile | tail -1|cut -c1-4`
#if ($#mode >= 2 ) set mode =$mode[1]
set modecheck=`echo $mode|grep HYBR`
if ($#modecheck == 0 ) then
  set modecheck=`echo $mode|grep EECE`
  if ($#modecheck == 0 ) then
    echo ERROR: HYBR or EECE keywords not found in $infile
    goto error_input
  endif
endif
@ i ++
set orbline=`head -$i $infile | tail -1`
#
#echo nat $nat
#echo lmax $lmax

#loop over l: prepare atomcount for the multiple l-cases
set natind=(0 0 0 0)
set l=1
while ($l <= $lmax)
  set i=1
  while ($i <= $nat)
  if($l_max[$i] >= $l) then
      @ natind[$l] ++
  endif
  @ i ++  
  end
@ l ++
end

if(-e $file.in0eece ) then
   set luse1=(`head -2 $file.in0eece |tail -1`)
   if($#luse1 <= 4 ) set luse1=($luse1 0 0 0 0)
    set luse=$luse1[4]
     if ($luse <= 0 && $luse >= -8) set luse=12
     if ($luse >= 0 && $luse <= 8) set luse=12
else
   set luse=30
   set i=1
   while ($i <= $nat)
     if($l_value1[$i] == 3) set luse=46
     @ i ++  
   end
endif

#loop over l: prepare input files (indm, in2, inorb) and call jexex
set l=1
while ($l <= $lmax)
#echo case $l
#head -1 $file.indm$complex > $file.indm$complex
echo $emin >         $file.indm$complex
echo $natind[$l] >>         $file.indm$complex
echo 'TOT  EECE (TOT,FOR,QTL,EFG,FERMI)' >$file.in2${complex}eece
set nocut=`head -2 $file.in2${complex} |tail -1 `
echo $emin $nocut[2-] >>  $file.in2${complex}eece
head -3 $file.in2${complex} |tail -1 >>$file.in2${complex}eece
echo $natind[$l] >>         $file.in2${complex}eece
#head -2 $file.inorb  > $file.inorb
echo "1  $natind[$l]  5        nmod, natorb, ipr" > $file.inorb
echo "PRATT 1.0 " >> $file.inorb
  set i=1
  while($i <= $nat )
  if($l_max[$i] >= $l ) then
   if($l == 1) then
         echo  $atom_info[$i] 1 $l_value1[$i] >>       $file.indm${complex}
         echo  $atom_info[$i] 1 $l_value1[$i] >>       $file.in2${complex}eece
         echo  $atom_info[$i] 1 $l_value1[$i] >>       $file.inorb
   endif
   if($l == 2  ) then
         echo  $atom_info[$i] 1 $l_value2[$i] >>       $file.indm${complex}
         echo  $atom_info[$i] 1 $l_value2[$i] >>       $file.in2${complex}eece
         echo  $atom_info[$i] 1 $l_value2[$i] >>       $file.inorb
   endif
   if($l == 3 ) then
         echo  $atom_info[$i] 1 $l_value3[$i] >>       $file.indm${complex}
         echo  $atom_info[$i] 1 $l_value3[$i] >>       $file.in2${complex}eece
         echo  $atom_info[$i] 1 $l_value3[$i] >>       $file.inorb
   endif
   if($l == 4 ) then
         echo  $atom_info[$i] 1 $l_value4[$i] >>       $file.indm${complex}
         echo  $atom_info[$i] 1 $l_value4[$i] >>       $file.in2${complex}eece
         echo  $atom_info[$i] 1 $l_value4[$i] >>       $file.inorb
   endif
  else
#   echo  $atom_info[$i] 0 0 >>         $file.indm${complex}
#   echo  $atom_info[$i] 0 0 >>         $file.in2${complex}eece
#   echo  $atom_info[$i] 0 0 >>         $file.inorb
  endif
  @ i ++
  end
set i=`wc $file.in2${complex}`
set ii=$i[1]
@ ii --
@ ii --
@ ii --
tail -$ii $file.in2${complex}  >>$file.in2${complex}eece
echo ' 4                        nsic'       >>$file.inorb
echo $orbline                               >>$file.inorb
head -1 $file.in0              > $file.in0eece
#
# Optional LDM addition. Use a different VXC (e.g. LDA) for -eece to avoid failures of GGAs
if ( -e $file.in0eece_lda ) then
        head -1 $file.in0eece_lda > $file.in0eece
endif

echo "NR2V $mode IFFT $luse"             >> $file.in0eece
head -3 $file.in0 |tail -1     >> $file.in0eece

echo " " >> $file.in0eece
echo " " >> $file.in0eece
cat $file.inorb >> $file.in0eece

# LDM addition, paste variable Hybrid fraction (use either LDM or VAR or something else)
grep -e LDM -e VAR $file.ineece -A200 | tail -n +2 | cut -f $l -d" " >> $file.inorb

#end of input files

#FSM addition
if( $?fsm )then
        head -1 $file.in2${complex}eece > $file.in2${complex}eeceup
        head -1 $file.in2${complex}eece > $file.in2${complex}eecedn
        head -2 $file.in2${complex}up | tail -1 >> $file.in2${complex}eeceup
        head -2 $file.in2${complex}dn | tail -1 >> $file.in2${complex}eecedn
        tail -n +3 $file.in2${complex}eece >> $file.in2${complex}eeceup
        tail -n +3 $file.in2${complex}eece >> $file.in2${complex}eecedn
endif

#jexex  $file

lapwdm:
if ( -e $file.scfdmup ) rm $file.scfdmup 
if ( -e $file.scfdmdn ) rm $file.scfdmdn
#testinput	$file.in2c error_input
#if ( ! $?dm ) then 
# if ( "$orb" != "-orb" ) goto lapw1cs
# if ( $?orbc ) goto lapw1cs
#endif
if ( "$so" == '-so' ) then
testinput	$file.indmc error_input
total_exec	lapwdm -up $para $so $cmplx $scratchstring
if ( $?sp_c ) then              #LDM
  cp $file.dmatup $file.dmatdn
endif
cat $file.scfdmup>>$file.scfeece
endif
###  cp $file.scfdmup $file.scfdmdn
###  cp $file.vorbup  $file.vorbdn
###else if ( "$so" != "-so" ) then
###  total_exec	lapwdm -dn $para $cmplx $scratchstring
###endif
###  cat $file.scfdmdn>>$file.scfeece

lapw2:
####cp $file.in2eece_no20 $file.in2eece 
#testinput	$file.in2c error_input
if ( $?fsm ) then
  cp $file.in2${complex}eeceup $file.in2${complex}eece
  foreach i ( $file.energyUP* )
  if (! -z $i ) then
    set h1 = `echo $i|sed "s/energyUP/energyup/"`
    set h2 = `echo $i|sed "s/energyUP/energydn/"`
    cp $i $h1
    cp $i $h2
  endif
  end
endif
set orbind='-orb'
if ( "$so" == '-so' ) set orbind=
total_exec	lapw2 $cmplx -up $so $para $vresp $tau -eece $orbind $in1orig  $scratchstring

if ( $?sp_c) then                               #LDM
  cp $file.clmvalupeece $file.clmvaldneece
  if( -e $file.vrespvalup) cp $file.vrespvalup $file.vrespvaldn
  if( -e $file.tauvalup) cp $file.tauvalup $file.tauvaldn
  cp $file.scf2up $file.scf2dn
  cp $file.dmatup $file.dmatdn
  cp $file.vorbup  $file.vorbdn
else
#  total_exec	lapw2 $cmplx -dn $so $para $vresp $tau -eece -orb $in1orig  $scratchstring

# LDM addition. Can probably also remove lapw2 call above (needs checking)
  if ( $?afm) then
    total_exec      clmcopy -eece
    if( "$tau" == '-tau' ) total_exec      clmcopy -tau
    if( "$vresp" == '-vresp' ) total_exec      clmcopy -vresp 
  else
    if ( $?fsm ) then
        cp $file.in2${complex}eecedn $file.in2${complex}eece
        foreach i ( $file.energyDN* )
        if (! -z $i ) then
                set h1 = `echo $i|sed "s/energyDN/energyup/"`
                set h2 = `echo $i|sed "s/energyDN/energydn/"`
                cp $i $h1
                cp $i $h2
        endif
        end
    endif
    total_exec    lapw2 $cmplx -dn $so $para $vresp $tau -eece $orbind $in1orig  $scratchstring
  endif

endif

if ( $?fsm)then
        foreach i ( $file.energyDN* )
        if (! -z $i ) then
                set h1 = `echo $i|sed "s/energyDN/energydn/"`
                mv $i $h1
        endif
        end
        foreach i ( $file.energyUP* )
        if (! -z $i ) then
                set h1 = `echo $i|sed "s/energyUP/energyup/"`
                cp $i $h1
        endif
        end
endif

cat $file.scf2up>>$file.scfeece
cat $file.scf2dn>>$file.scfeece

#mixer_vresp:
#testinput       $file.inm_vresp lapw0
#if(-e $file.vrespcorup ) then
#   rm  $file.vrespcor*
#endif
#total_exec      mixer_vresp
#grep -e "CTO " -e NEC $file.outputvrespm | sed 's/:/:VRESP/' >> $file.scf

lapw0:
#testinput	$file.in0 error_input
rm -f $file.eeceup $file.eecedn
total_exec	lapw0 $para -eece
  cat $file.scf0>>$file.scfeece

orb:
total_exec	orb -up $para

if ( $?sp_c ) then                      #LDM
  cp $file.scforbup $file.scforbdn
  cp $file.vorbup   $file.vorbdn
  cp $file.eeceup   $file.eecedn
  cp $file.vorbup_old $file.vorbdn_old
else
  total_exec	orb -dn $para
endif

cat $file.scforbup>>$file.scfeece
cat $file.scforbdn>>$file.scfeece

cp $file.vorbup $file.vorbup_$l
cp $file.vorbdn $file.vorbdn_$l

@ l ++
end

#create vorb files (small LDM Change)
echo "  1  1  $nat  0.000000E+00 nmod, nsp, natorb " >$file.vorbup0
echo "  1 -1  $nat  0.000000E+00 nmod, nsp, natorb " >$file.vorbdn0

set line1=(3 3 3 3)
set line2=(3 3 3 3)
# atom loop
set i=1
while( $i <= $nat )
echo " $atom_info[$i] $l_max[$i]  atom type, number of L" >>$file.vorbup0
echo " $atom_info[$i] $l_max[$i]  atom type, number of L" >>$file.vorbdn0
# l loop
  set l=1
  while ($l <= $l_max[$i])
# Small LDM change here to encode dmat norms for mixer
  set lvalue=`head -$line1[$l] $file.vorbup_$l | tail -1 `
  echo  $lvalue[1]  EECE    L, $lvalue[3] $lvalue[4] modus >>         $file.vorbup0
  set lvalue=`head -$line1[$l] $file.vorbdn_$l | tail -1 `
  echo  $lvalue[1]  EECE    L, $lvalue[3] $lvalue[4] modus >>         $file.vorbdn0
  @ line2[$l] = (2 * $lvalue[1] + 1) *(2 * $lvalue[1] + 1)
  @ line1[$l] = $line1[$l]  + $line2[$l] 
  head -$line1[$l] $file.vorbup_$l | tail -$line2[$l] >>$file.vorbup0
  head -$line1[$l] $file.vorbdn_$l | tail -$line2[$l] >>$file.vorbdn0
  @ line1[$l] ++
  @ line1[$l] ++
  @ l ++
  end
@ i ++
end

mv $file.vorbup0 $file.vorbup
mv $file.vorbdn0 $file.vorbdn

cat $file.scfeece >> $file.scf

exit 0


error_input:					#error exit	
printf "\n>   stop error: the required input file $errin for the next step could not be found\n"		>> $dayfile
exit 9

error:					#error exit	
printf "\n>   stop error\n"		>> $dayfile
exit 9

help:					#help exit 
cat << theend 

PROGRAM:	$0

PURPOSE:	running (spinpolarized) exact-exchange/hybrid DFT part of 
                scf-cycle in WIEN
		to be called within the case-directory, needs case.ineece
		has to be located in '$WIENROOT' directory

USAGE:		$name [OPTIONS]

OPTIONS:
-fsm  ->        runs in FSM mode
-afm  ->        runs in AFM mode
-vresp -->      activates vresp-files
-tau   -->      activates tau-files
-so   ->	run SCF including spin-orbit coupling
-p    ->        run k-points in parallel (needs .machine file [speed:name])
-sp_c ->        run only spin-up and cp spin-up to spin-dn files
-scratch dir -> set scratch directory (for vector files)
theend

exit 1



More information about the Wien mailing list