Merge branch 'leadoff' master
authorhackbard <hackbard@hackdaworld.org>
Mon, 20 Feb 2012 15:55:56 +0000 (16:55 +0100)
committerhackbard <hackbard@hackdaworld.org>
Mon, 20 Feb 2012 15:55:56 +0000 (16:55 +0100)
Conflicts:
Makefile
moldyn.c
potentials/albe.c
potentials/albe.h
runmd

 ... hopefully fixed! Just a test to merge leadoff back to master! :)

71 files changed:
Makefile
TODO.txt [new file with mode: 0644]
atom_match.c [new file with mode: 0644]
bond_analyze.c
bond_analyze_script [new file with mode: 0755]
calc_delta_e
diffusion_calc_ver2.c [new file with mode: 0644]
logfile [new file with mode: 0644]
mdrun.c
mdrun.h
moldyn.c
moldyn.h
msd_calc.c [new file with mode: 0644]
pair_corr_calc_script
pair_correlation_calc.c
parcasconv [new file with mode: 0755]
potentials/albe.c
potentials/albe.h
potentials/albe_fast.c [new file with mode: 0644]
potentials/tersoff.c
potentials/tersoff.h
povconv
pse.h
random/random.c
remember_me.txt
runmd
s2xyz.c [new file with mode: 0644]
s2xyz_script [new file with mode: 0755]
sic.c
vasp_tools/Makefile [new file with mode: 0644]
vasp_tools/acos.c [new file with mode: 0644]
vasp_tools/angle_calc [new file with mode: 0755]
vasp_tools/avg_disp [new file with mode: 0755]
vasp_tools/constraint_mig_script [new file with mode: 0755]
vasp_tools/create_dbc [new file with mode: 0755]
vasp_tools/create_intf_crude [new file with mode: 0755]
vasp_tools/create_lattice.c [new file with mode: 0644]
vasp_tools/disp_calc [new file with mode: 0755]
vasp_tools/dist_calc [new file with mode: 0755]
vasp_tools/e_coh [new file with mode: 0755]
vasp_tools/e_f [new file with mode: 0755]
vasp_tools/e_f_tersoff [new file with mode: 0755]
vasp_tools/e_fc [new file with mode: 0755]
vasp_tools/e_fc_tersoff [new file with mode: 0755]
vasp_tools/e_form [new file with mode: 0755]
vasp_tools/e_form_tersoff [new file with mode: 0755]
vasp_tools/get_ks_levels [new file with mode: 0755]
vasp_tools/interPOS [new file with mode: 0755]
vasp_tools/lastxyz2video [new file with mode: 0755]
vasp_tools/mig_calc [new file with mode: 0755]
vasp_tools/mig_fullct.sh [new file with mode: 0755]
vasp_tools/o_init2moldyn [new file with mode: 0755]
vasp_tools/outcar2moldyn [new file with mode: 0755]
vasp_tools/pc_calc.c [new file with mode: 0644]
vasp_tools/pc_script [new file with mode: 0755]
vasp_tools/poscar2moldyn [new file with mode: 0755]
vasp_tools/ppm2avi [new file with mode: 0755]
vasp_tools/runvasp_rx200 [new file with mode: 0755]
vasp_tools/runvasp_rx200_gamma [new file with mode: 0755]
vasp_tools/sd_rot.patch [new file with mode: 0644]
vasp_tools/sd_rot_all-atoms.patch [new file with mode: 0644]
vasp_tools/search_bonds [new file with mode: 0755]
vasp_tools/stdvis [new file with mode: 0755]
vasp_tools/tXYZp.c [new file with mode: 0644]
vasp_tools/tXp.c [new file with mode: 0644]
vasp_tools/trafoXposcar [new file with mode: 0755]
vasp_tools/visualize [new file with mode: 0755]
vasp_tools/visualize_contcar [new file with mode: 0755]
visual_atoms.c
visual_atoms_script [new file with mode: 0755]
visualize

index 1b19d50..fa40909 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,34 +1,60 @@
-CC = gcc
+CC = gcc-4.3
+#CC = gcc-3.4
 
-CFLAGS = -Wall
+CFLAGS = -Wall -Winline
 #CFLAGS += -Wextra -pedantic
-CFLAGS += -O3
+
+CFLAGS += -O3 -march=native -msse2 -mfpmath=sse
+#CFLAGS += -O3 -march=athlon64
+
 CFLAGS += -g
-CFLAGS += -ffloat-store
+#CFLAGS += -pg
+#CFLAGS += -ffloat-store
+
+#CFLAGS += -DPARALLEL -fopenmp
+#CFLAGS += -DPTHREADS -lpthread
+#CFLAGS += -DVISUAL_THREAD -lpthread
+#CFLAGS += -DPTHREADS -DVISUAL_THREAD -lpthread
 
-CFLAGS += -DALBE
+#CFLAGS += -DALBE
+CFLAGS += -DALBE_FAST
 #CFLAGS += -DTERSOFF_ORIG
 
 #CFLAGS += -DSTATIC_LISTS
+CFLAGS += -DLOWMEM_LISTS
 
-#CFLAGS += -DNDEBUG
+#CFLAGS += -DPDEBUG
 #CFLAGS += -DDEBUG
-#CFLAGS += -DDSTART=-1 -DDEND=3 -DDATOM=0
+#CFLAGS += -DDSTART=50 -DDEND=60 -DDATOM=0
 #CFLAGS += -DVDEBUG
 
+#CFLAGS += -DQUENCH
+
 LDFLAGS = -lm
+
+#LDFLAGS += -lc_p
 #LDFLAGS += -lefence
 
 DEPS = moldyn.o random/random.o list/list.o
 DEPS += potentials/lennard_jones.o potentials/harmonic_oscillator.o
-DEPS += potentials/tersoff.o potentials/albe.o potentials/albe_orig.o
+DEPS += potentials/tersoff.o potentials/albe.o
+DEPS += potentials/albe_fast.o
 
-ALL = mdrun sic fluctuation_calc postproc pair_correlation_calc diffusion_calc
-ALL += bond_analyze search_bonds visual_atoms display_atom_data
+SRC = moldyn.c random/random.c list/list.c
+SRC += potentials/lennard_jones.c potentials/harmonic_oscillator.c
+SRC += potentials/tersoff.c potentials/albe.c
+SRC += potentials/albe_fast.c
+
+#ALL = mdrun sic fluctuation_calc postproc pair_correlation_calc diffusion_calc
+ALL = mdrun fluctuation_calc postproc pair_correlation_calc diffusion_calc
+ALL += diffusion_calc_ver2 bond_analyze search_bonds visual_atoms
+ALL += display_atom_data atom_match msd_calc s2xyz
 
 all: $(ALL)
 
-mdrun: $(DEPS)
+# main code. using SRC, much more efficient code is produced!
+mdrun: $(SRC)
+#mdrun: $(DEPS)
 
 sic: $(DEPS) config.h
 
@@ -38,6 +64,8 @@ pair_correlation_calc: $(DEPS)
 
 diffusion_calc: $(DEPS)
 
+diffusion_calc_ver2: $(DEPS)
+
 bond_analyze: $(DEPS)
 
 search_bonds: $(DEPS)
@@ -46,6 +74,12 @@ visual_atoms: $(DEPS)
 
 display_atom_data: $(DEPS)
 
+atom_match: $(DEPS)
+
+msd_calc: $(DEPS)
+
+s2xyz: $(DEPS)
+
 .PHONY:clean
 clean:
        rm -vf $(ALL) *.o */*.o
diff --git a/TODO.txt b/TODO.txt
new file mode 100644 (file)
index 0000000..d10b149
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,93 @@
+parcas
+******
+more DOUBLECHECKs with PARCAS !!!!
+
+  * E_kin
+  * x/y/z(t) of both
+  * video of hex -> 100db
+
+implement
+*********
+
+ - improve ins_m_atoms (merge to general ins_atoms function maybe)
+
+   * modified first: try rules to better distribute Si and C   ***
+   * general cleanup
+   * type 1 square, type 2 radius!
+
+ - clean up mdrun
+ - config sanity checks
+
+ - anneal -> from current to T with rate R
+
+ - check virial calc, where does the - come from?
+
+ - angular distribution
+ - structurfactoranalyze (see nordlund paper)
+
+ - filled atoms need atom attrib?!?!? or aattr pre prerun
+
+ - bond_analyze to dump xyz file of atoms
+
+ - improve diff calc
+
+ - pthreads:
+
+   * threads nur einmal oeffnen
+   * verteilung auf laufende threads
+
+ - potentials:
+   
+   * tersoff fast
+   * meam
+
+ - optimize code!
+
+   * 6.56
+   * -> 6.16 (albe_potential_force_calc) unoptimized
+   * -> 7.05 first variable optimization
+   * -> 5.53 2nd variable mod (moving out of blocks)
+   * -> 5.12 source c files (orig albe) /wo float-store (otherwise 9.x)
+   * -> 5.00 source c, fpu_set() (orig albe)
+   * -> 5.04 source c, fpu_set() (albe fast) (same w -finline-functions)
+   * -> 4.55 source c, fpu(), albe orig, fast-math ;)
+   * -> 4.12 source c, fpu(), albe fast
+   * -> 4.06 source c, fpu(), albe fast, arch opts
+   * -> 3.54 ^ + c,d,h,gamma opts
+   * -> 3.50 ^ + static lists
+   * -> 3.37 source c, albe f, arch opts, c,d,h,gamma
+             + lowmem lists (test for bigger + atoms!)
+   * -> 3.31(36) ^ + inline v_calc
+
+   * -> 4.44 orig albe, lowmem, source c, arch opts
+
+   todo:
+    - listen ! estimate time
+    - more in fast (also think about -> 'type')
+    - inline
+
+simulation runs
+***************
+
+- start with small nuclei and amorphous surrounding
+- tctrl only in outer regions
+- only 1 atom per timestep
+- melting exps (both, anneal + interface method)
+- interstitials:
+  - sic ints (compare!)
+  - more interstitial combinations
+  - characterize interstitials by PCF, then inc temperature
+
+learn
+*****
+
+- ab initio / dft itself (find good docs)
+- checkout abinit in the same time
+- checkout thight binding
+- of course md theory!
+
+write
+*****
+
+- results >> thesis!
+
diff --git a/atom_match.c b/atom_match.c
new file mode 100644 (file)
index 0000000..7eb5556
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * atom_match.c - match atoms and process
+ *
+ * author: frank.zirkelbach@physik.uni-augsburg.de
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+
+#include "moldyn.h"
+
+#define PSE_NAME
+#define PSE_COL
+#include "pse.h"
+#undef PSE_NAME
+#undef PSE_COL
+
+#define ME     "[atom match]"
+
+#define LAND   0
+#define LOR    1
+
+#define SELECT         1
+#define UNSELECT       0
+
+#define S_COL_NO_OVERRIDE      0
+#define S_COL_NONE             1
+#define S_COL_BLUE             2
+#define S_COL_RED              3
+#define S_COL_BLACK            4
+
+/* rule types */
+#define RT_ELEMENT             0
+
+typedef int t_element;
+
+typedef struct s_rule {
+       u8 type;
+       u8 logic_op;
+       void *params;
+} t_rule;
+
+typedef struct s_am {
+       int count;
+       t_rule rule[32];
+       char infile[128];
+} t_am;
+
+int parse_rule(t_am *am,char *line) {
+
+       int wcnt;
+       char *wptr;
+       char word[16][64];
+
+       t_element *element;
+
+       wcnt=0;
+       while(1) {
+               if(wcnt)
+                       wptr=strtok(NULL," ");
+               else
+                       wptr=strtok(line," ");
+               if(wptr==NULL)
+                       break;
+               strncpy(word[wcnt],wptr,64);
+               wcnt+=1;
+       }
+
+       switch(word[0][0]) {
+               case 'e':
+                       am->rule[am->count].params=malloc(sizeof(t_element));
+                       element=am->rule[am->count].params;
+                       if(element==NULL) {
+                               printf("%s malloc (element).\n",ME);
+                               return -1;
+                       }
+                       *element=atoi(word[1]);
+                       break;
+               /*
+               case '':
+                       break;
+               case '':
+                       break;
+               */
+               default:
+                       return -1;
+       }
+
+       return 0;
+}
+
+int parse_argv(int argc,char **argv,t_am *am) {
+
+       int i;
+       int ret;
+
+       memset(am,0,sizeof(t_am));
+       ret=0;
+
+       for(i=1;i<argc;i++) {
+               if(argv[i][0]=='-') {
+                       switch(argv[i][1]) {
+                               case 'i':
+                                       // infile
+                                       strncpy(am->infile,argv[++i],128);
+                                       break;
+                               case 'a':
+                                       // and rule
+                                       am->rule[am->count].logic_op=LAND;
+                                       ret=parse_rule(am,argv[++i]);
+                                       am->count+=1;
+                                       break;
+                               case 'o':
+                                       // or rule
+                                       am->rule[am->count].logic_op=LOR;
+                                       ret=parse_rule(am,argv[++i]);
+                                       am->count+=1;
+                                       break;
+                               case 'p':
+                                       // how to process data
+                                       break;
+                               default:
+                                       printf("%s unknown switch: %s\n",
+                                               ME,argv[i]);
+                                       return -1;
+                       
+                       }
+               }
+               else {
+                       printf("%s unknown argument: %s\n",ME,argv[i]);
+                       return -1;
+               }
+       }
+
+       return ret;
+}
+
+int main(int argc,char **argv) {
+
+       t_am am;
+       t_moldyn moldyn;
+       u8 *sel_atom;
+       u8 *sel_color;
+       int i,j,acnt;
+       t_atom *atom;
+
+       t_element *e;
+
+       memset(&moldyn,0,sizeof(t_moldyn));
+
+       if(parse_argv(argc,argv,&am)<0) {
+               printf("%s aborted (bad args).\n",ME);
+               return -1;
+       }
+
+       if(moldyn_read_save_file(&moldyn,am.infile)<0) {
+               printf("%s aborted (bad infile).\n",ME);
+               return -1;
+       }
+
+       acnt=moldyn.count;
+       atom=moldyn.atom;
+
+       link_cell_init(&moldyn,VERBOSE);
+
+       /* alloc select status and color memory */
+       sel_atom=malloc(acnt*sizeof(u8));
+       if(sel_atom==NULL) {
+               printf("%s aborted (malloc failed).\n",ME);
+               return -1;
+       }
+       sel_color=malloc(acnt*sizeof(u8));
+       if(sel_color==NULL) {
+               printf("%s aborted (malloc failed).\n",ME);
+               return -1;
+       }
+
+       /* apply rules */
+       for(i=0;i<am.count;i++) {
+
+               /* initialize status and color in first run */
+               if(i==0) {
+                       if(am.rule[0].logic_op==LAND)
+                               memset(sel_atom,SELECT,acnt*sizeof(u8));
+                       else
+                               memset(sel_atom,UNSELECT,acnt*sizeof(u8));
+               }
+
+               /* rules */
+               switch(am.rule[i].type) {
+                       case RT_ELEMENT:
+                               e=am.rule[0].params;
+                               if(am.rule[i].type==LAND)
+                                       for(j=0;j<acnt;j++)
+                                               if(atom[j].element==*e)
+                                                       sel_atom[j]&=SELECT;
+                                               else
+                                                       sel_atom[j]&=UNSELECT;
+                               else
+                                       for(j=0;j<acnt;j++)
+                                               if(atom[j].element==*e)
+                                                       sel_atom[j]|=SELECT;
+                               break;
+                       default:
+                               printf("%s unknown rule %c -> skipped.\n",
+                                       ME,am.rule[i].type);
+                               break;
+               }
+       }
+
+       /* process data */
+       for(i=0;i<acnt;i++)
+               if(sel_atom[i]==SELECT)
+                       printf("%s %f %f %f %s %f\n",
+                              pse_name[atom[i].element],
+                              atom[i].r.x,atom[i].r.y,atom[i].r.z,
+                              pse_col[atom[i].element],
+                              atom[i].ekin);
+
+       /* exit and cleanup */
+       free(sel_atom);
+       free(sel_color);
+       link_cell_shutdown(&moldyn);
+       moldyn_free_save_file(&moldyn);
+       
+       return 0;
+}
index 6c46251..3992894 100644 (file)
@@ -55,7 +55,8 @@ int main(int argc,char **argv) {
        /* analyzing ... */
        bond_analyze(&moldyn,quality);
 
-       printf("[bond analyze] quality = %f | %f\n",quality[0],quality[1]);
+       printf("[bond analyze] t: %f | quality = %f | %f | %d\n",
+               moldyn.time,quality[0],quality[1],moldyn.count);
 
        moldyn_free_save_file(&moldyn);
 
diff --git a/bond_analyze_script b/bond_analyze_script
new file mode 100755 (executable)
index 0000000..7ae0bb5
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+if [ ! -d $1 ]; then
+       echo "$1 is not a directory"
+       exit 1
+fi
+
+echo "processing $1 ..."
+
+rm -f $1/bond_analyze.txt
+
+for i in $1/*.save; do
+       bai="`./bond_analyze $i | grep '\[bond' | grep quality`"
+       time=`echo $bai | awk '{ print $4 }'`
+       quality4=`echo $bai | awk '{ print $8 }'`
+       quality3=`echo $bai | awk '{ print $10 }'`
+       count=`echo $bai | awk '{ print $12 }'`
+       echo "$time $quality4 $quality3 $count" >> $1/bond_analyze.txt
+done
+
+echo "done"
index 4ff46fb..eff07c9 100755 (executable)
@@ -1,9 +1,40 @@
 #!/bin/bash
 
+# guess potential
+pot=`grep ^potential $1/config | awk '{ print $2 }'`
+
+echo
+if [ "$pot" = "tersoff" ]; then
+echo "potential: $pot"
+musi=-4.629595
+muc=-7.421824
+music=-12.37363
+else
+echo "potential: $pot"
+musi=-4.628414
+muc=-7.373091
+music=-12.679618
+fi
+echo
+
 file=`ls $1/atomic_conf_* | tail -1`
 atom_cnt=`grep '# \[P\]' $file | awk '{ print $3 }'`
-e0=`grep ^0 $1/energy | awk '{ print $4 }'`
-e1=`tail -n 1 $1/energy | awk '{ print $4 }'`
+e0=`awk 'NR==2' $1/energy | awk '{ print $3 }'`
+e1=`tail -n 1 $1/energy | awk '{ print $3 }'`
+ed0=`awk 'NR==2' $1/energy | awk '{ print $6 }'`
+ed1=`tail -n 1 $1/energy | awk '{ print $6 }'`
+si_cnt=`grep ^Si $file | wc -l`
+c_cnt=`grep ^C $file | wc -l`
+
+echo "-------------------------------------------------------------------------"
+echo "  Formation energy [eV]: #Si=$si_cnt, #C=$c_cnt, #tot=$atom_cnt"
+echo "-------------------------------------------------------------------------"
+
+echo "$si_cnt $c_cnt $e1 $e0" | \
+       awk '{ print "   Gao: "($3-$4)*($1+$2) }'
+echo "$si_cnt $c_cnt $musi $muc $e1 $music" | \
+       #awk '{ print "   Posselt: "$5*($1+$2)-0.5*($1+$2)*$6-0.5*($1-$2)*($3-$4) }'
+       awk '{ print "   Posselt: "$5*($1+$2)-$1*$3-$2*$4 }'
+echo "$si_cnt $c_cnt $musi $music $e1 $music" | \
+       awk '{ print "   Tersoff: "$5*($1+$2)-$1*$3-$2*($4-$3) }'
 
-echo "$e0 $e1 $atom_cnt" | \
-       awk '{ print ($2-$1)*$3" eV" }'
diff --git a/diffusion_calc_ver2.c b/diffusion_calc_ver2.c
new file mode 100644 (file)
index 0000000..ef071a0
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * calculation of diffusion coefficient (version 2)
+ *
+ * author: frank.zirkelbach@physik.uni-augsburg.de
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "moldyn.h"
+
+#define CM     1.0e8
+
+int usage(char *prog) {
+
+       printf("\nusage:\n");
+       printf("  %s <save file 1> <save file 2>\n\n",prog);
+
+       return -1;
+}
+
+int main(int argc,char **argv) {
+
+       t_moldyn moldyn_0,moldyn_1;
+       int ret,i,a_cnt,b_cnt;
+       double dx,dy,dz,dc[3];
+
+       if(argc!=3) {
+               usage(argv[0]);
+               return -1;
+       }
+
+       memset(&moldyn_0,0,sizeof(t_moldyn));
+       memset(&moldyn_1,0,sizeof(t_moldyn));
+
+       a_cnt=0;
+       b_cnt=0;
+
+       dc[0]=0.0;
+       dc[1]=0.0;
+       dc[2]=0.0;
+
+       printf("[diffusion calc] reading save files ...\n");
+       ret=moldyn_read_save_file(&moldyn_0,argv[1]);
+       if(ret) {
+               printf("[diffusion calc] exit!\n");
+               return ret;
+       }
+       ret=moldyn_read_save_file(&moldyn_1,argv[2]);
+       if(ret) {
+               printf("[diffusion calc] exit!\n");
+               return ret;
+       }
+
+       if(moldyn_0.count!=moldyn_1.count) {
+               printf("[diffusion calc] atom count mismatch\n");
+               return -1;
+       }
+
+       for(i=0;i<moldyn_0.count;i++) {
+               dx=moldyn_0.atom[i].r.x/moldyn_0.dim.x;
+               dy=moldyn_0.atom[i].r.y/moldyn_0.dim.y;
+               dz=moldyn_0.atom[i].r.z/moldyn_0.dim.z;
+               dx-=(moldyn_1.atom[i].r.x/moldyn_1.dim.x);
+               dy-=(moldyn_1.atom[i].r.y/moldyn_1.dim.y);
+               dz-=(moldyn_1.atom[i].r.z/moldyn_1.dim.z);
+               if(dx>0.5)
+                       dx-=0.5;
+               if(dx<-0.5)
+                       dx+=0.5;
+               if(dy>0.5)
+                       dy-=0.5;
+               if(dy<-0.5)
+                       dy+=0.5;
+               if(dz>0.5)
+                       dz-=0.5;
+               if(dz<-0.5)
+                       dz+=0.5;
+               dx*=moldyn_1.dim.x;
+               dy*=moldyn_1.dim.y;
+               dz*=moldyn_1.dim.z;
+               if(moldyn_0.atom[i].brand) {
+                       b_cnt+=1;
+                       dc[1]+=dx*dx+dy*dy+dz*dz;
+               }
+               else {
+                       a_cnt+=1;
+                       dc[0]+=dx*dx+dy*dy+dz*dz;
+               }
+               dc[2]+=dx*dx+dy*dy+dz*dz;
+       }
+
+       dc[0]*=(1.0/(6.0*(moldyn_1.time-moldyn_0.time)*a_cnt));
+       dc[1]*=(1.0/(6.0*(moldyn_1.time-moldyn_0.time)*b_cnt));
+       dc[2]*=(1.0/(6.0*(moldyn_1.time-moldyn_0.time)*moldyn_0.count));
+
+       dc[0]*=(SECOND/(CM*CM));
+       dc[1]*=(SECOND/(CM*CM));
+       dc[2]*=(SECOND/(CM*CM));
+
+       printf("diffusion coefficients: %.10f %.10f %.10f [cm^2/s]\n",
+              dc[0],dc[1],dc[2]);
+
+       return 0;
+}
+
diff --git a/logfile b/logfile
new file mode 100644 (file)
index 0000000..150c159
--- /dev/null
+++ b/logfile
@@ -0,0 +1,125 @@
+it's never too late to start a logfile ...
+                               #######
+
+
+05.06.2009:
+-----------
+
+local: c_in_si_mig_01
+
+migratin of defects tests
+
+06.05.2009:
+-----------
+
+local: si_0k, si_20, si_1250, si_2050
+       c_0k, c_20, c_1250, c_2050
+       sic_0k, sic_20, sic_1250, sic_2050
+
+ fully relaxed si, c or sic at given temperature, using albe pot
+
+       ... _tersoff
+
+ same, using tersoff pot
+
+       ... _check
+
+ same, without tp-ctrl, to check conservation of energy (both, tersoff an albe)
+
+04.05.2009:
+-----------
+
+local: c_in_si_prec_01
+
+ 3x3 lattice si, insertion of same amount of carbon at 2050 celsius, relax 1 ns
+
+06.04.2009:
+-----------
+
+./posic_2009_02/saves/c_in_si_prec_10 <- 2050
+./posic_2009_02/saves/c_in_si_prec_11 <- 1650
+./posic_2009_02/saves/c_in_si_prec_12 <- 1250
+
+ like 07, 08, 09 but using tersoff = tersoff + total volume
+
+./posic_2009_02/saves/c_in_si_prec_12_cnt0k
+
+ continued, cooling down to 0k
+
+./posic_2009_02/saves/c_in_si_prec_07_cnt0k
+./posic_2009_02/saves/c_in_si_prec_09_cnt0k
+
+ continued (from 23.02.09), cooling down to 0K
+
+23.02.2009:
+-----------
+
+./posic_2009_02/saves/c_in_si_prec_2050_01
+./posic_2009_02/saves/c_in_si_prec_2050_02 WARNING: bullshit notation! see below
+./posic_2009_02/saves/c_in_si_prec_2050_03
+
+ c in sphere of r = 2.5 nm at 01 = 2050 02 = 1650 03 = 1250 celsius
+
+local: sic_prec_08-tup1250 / 1650 / 2050
+
+ sic prec at 1250 / 1650 / 2050 celsius
+
+./posic_2009_02/saves/c_in_si_prec_04
+./posic_2009_02/saves/c_in_si_prec_05
+./posic_2009_02/saves/c_in_si_prec_06
+
+ like first three, using tersoff <- TODO
+
+./posic_2009_02/saves/c_in_si_prec_07 <- 2050
+./posic_2009_02/saves/c_in_si_prec_08 <- 1650
+./posic_2009_02/saves/c_in_si_prec_09 <- 1250
+
+ like first three (albe!) into total volume
+
+TODO: - kleine si mit genausoviel c ins
+      - c in groesseres gebiet (tot oder so?)
+      - c in grosses gebiet + 'mehr' c
+
+19.02.2009:
+-----------
+
+local: sic_prec_08*
+
+ - sic in si, free run for 2ps, tctrl to 23 celsius 
+ - more tctrl and annealing
+
+09.02.2009:
+-----------
+
+./posic_2009_01/saves/c_in_si_prec_1650-2150_v2_04
+
+ tersoff instead of albe, cr = 1.5 angstrom, insertion into sphere r=2.5
+
+06.02.2009:
+-----------
+
+adapted parcas albe sic parameters, dcut of si-1 unmodified!
+
+13.01.2009:
+-----------
+
+./posic_2009_01/saves/c_in_si_prec_1650-2150_v2_03
+
+ as 02, but cr of Si-C increased to 1.9
+
+12.01.2009:
+-----------
+
+./posic_2009_01/saves/c_in_si_prec_1650-2150_v2_02
+
+ as 01, but: c insertion cr check for another c atom increased to 2.7 angstrom
+
+08.01.2009:
+-----------
+
+INS_SPHERE implemented
+
+./posic_2009_01/saves/c_in_si_prec_1650-2150_v2_01
+
+ 316 x 10 C -> Si, v2: sphere r=2.5 nm, t=1650(+500)
+
diff --git a/mdrun.c b/mdrun.c
index 907388a..26fbc87 100644 (file)
--- a/mdrun.c
+++ b/mdrun.c
@@ -94,9 +94,18 @@ int add_stage(t_mdrun *mdrun,u8 type,void *params) {
                case STAGE_DISPLACE_ATOM:
                        psize=sizeof(t_displace_atom_params);
                        break;
+               case STAGE_DEL_ATOMS:
+                       psize=sizeof(t_del_atoms_params);
+                       break;
+               case STAGE_MODIFY_ATOMS:
+                       psize=sizeof(t_modify_atoms_params);
+                       break;
                case STAGE_INSERT_ATOMS:
                        psize=sizeof(t_insert_atoms_params);
                        break;
+               case STAGE_INSERT_MIXED_ATOMS:
+                       psize=sizeof(t_insert_mixed_atoms_params);
+                       break;
                case STAGE_CONTINUE:
                        psize=sizeof(t_continue_params);
                        break;
@@ -109,6 +118,21 @@ int add_stage(t_mdrun *mdrun,u8 type,void *params) {
                case STAGE_CHSATTR:
                        psize=sizeof(t_chsattr_params);
                        break;
+               case STAGE_SET_TEMP:
+                       psize=sizeof(t_set_temp_params);
+                       break;
+               case STAGE_SET_TIMESTEP:
+                       psize=sizeof(t_set_timestep_params);
+                       break;
+               case STAGE_FILL:
+                       psize=sizeof(t_fill_params);
+                       break;
+               case STAGE_THERMAL_INIT:
+                       psize=0;
+                       break;
+               case STAGE_CRT:
+                       psize=sizeof(t_crt_params);
+                       break;
                default:
                        printf("%s unknown stage type: %02x\n",ME,type);
                        return -1;
@@ -142,16 +166,23 @@ int mdrun_parse_config(t_mdrun *mdrun) {
        char error[128];
        char line[128];
        char *wptr;
-       char word[16][64];
+       char word[32][64];
        int wcnt;
        int i,o;
 
        t_displace_atom_params dap;
+       t_modify_atoms_params map;
        t_insert_atoms_params iap;
+       t_insert_mixed_atoms_params imp;
        t_continue_params cp;
        t_anneal_params ap;
        t_chaattr_params cap;
        t_chsattr_params csp;
+       t_set_temp_params stp;
+       t_set_timestep_params stsp;
+       t_fill_params fp;
+       t_del_atoms_params delp;
+       t_crt_params crtp;
 
        /* open config file */
        fd=open(mdrun->cfile,O_RDONLY);
@@ -176,10 +207,17 @@ int mdrun_parse_config(t_mdrun *mdrun) {
 
                // reset
                memset(&iap,0,sizeof(t_insert_atoms_params));
+               memset(&map,0,sizeof(t_modify_atoms_params));
+               memset(&imp,0,sizeof(t_insert_mixed_atoms_params));
                memset(&cp,0,sizeof(t_continue_params));
                memset(&ap,0,sizeof(t_anneal_params));
                memset(&cap,0,sizeof(t_chaattr_params));
                memset(&csp,0,sizeof(t_chsattr_params));
+               memset(&stp,0,sizeof(t_set_temp_params));
+               memset(&stsp,0,sizeof(t_set_timestep_params));
+               memset(&fp,0,sizeof(t_fill_params));
+               memset(&delp,0,sizeof(t_del_atoms_params));
+               memset(&crtp,0,sizeof(t_crt_params));
 
                // get command + args
                wcnt=0;
@@ -250,21 +288,133 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                                mdrun->lattice=FCC;
                        if(!strncmp(word[1],"diamond",7))
                                mdrun->lattice=DIAMOND;
+                       if(!strncmp(word[1],"none",4))
+                               mdrun->lattice=NONE;
+                       if(wcnt==3)
+                               mdrun->lc=atof(word[2]);
                }
                else if(!strncmp(word[0],"element1",8)) {
                        mdrun->element1=atoi(word[1]);
-                       mdrun->m1=pse_mass[mdrun->element1];
                }
                else if(!strncmp(word[0],"element2",8)) {
                        mdrun->element2=atoi(word[1]);
-                       mdrun->m2=pse_mass[mdrun->element2];
                }
                else if(!strncmp(word[0],"fill",6)) {
-                       // only lc mode by now
-                       mdrun->lx=atoi(word[2]);
-                       mdrun->ly=atoi(word[3]);
-                       mdrun->lz=atoi(word[4]);
-                       mdrun->lc=atof(word[5]);
+                       // default values
+                       fp.fill_element=mdrun->element1;
+                       fp.fill_brand=0;
+                       fp.lattice=mdrun->lattice;
+                       fp.p_params.type=0;
+                       fp.d_params.type=0;
+                       fp.d_params.stype=0;
+                       // parse fill command
+                       i=1;
+                       while(i<wcnt) {
+                               if(!strncmp(word[i],"lc",2)) {
+                                       fp.lx=atoi(word[++i]);
+                                       fp.ly=atoi(word[++i]);
+                                       fp.lz=atoi(word[++i]);
+                                       fp.lc=atof(word[++i]);
+                                       mdrun->lc=fp.lc;
+                                       continue;
+                               }
+                               if(!strncmp(word[i],"eb",2)) {
+                                       fp.fill_element=atoi(word[++i]);
+                                       fp.fill_brand=atoi(word[++i]);
+                                       continue;
+                               }
+                               if(word[i][0]=='p') {
+                                       i+=1;
+                                       switch(word[i][0]) {
+                                       case 'i':
+                                               if(word[i][1]=='r')
+                                               fp.p_params.type=PART_INSIDE_R;
+                                               else
+                                               fp.p_params.type=PART_INSIDE_D;
+                                               break;
+                                       case 'o':
+                                               if(word[i][1]=='r')
+                                               fp.p_params.type=PART_OUTSIDE_R;
+                                               else
+                                               fp.p_params.type=PART_OUTSIDE_D;
+                                               break;
+                                       default:
+                                               break;
+                                       }
+                                       if((fp.p_params.type==PART_INSIDE_R)||
+                                         (fp.p_params.type==PART_OUTSIDE_R)) {
+                                               fp.p_params.r=atof(word[++i]);  
+                                               fp.p_params.p.x=atof(word[++i]);
+                                               fp.p_params.p.y=atof(word[++i]);
+                                               fp.p_params.p.z=atof(word[++i]);
+                                       }
+                                       if((fp.p_params.type==PART_INSIDE_D)||
+                                          (fp.p_params.type==PART_OUTSIDE_D)) {
+                                               fp.p_params.p.x=atof(word[++i]);
+                                               fp.p_params.p.y=atof(word[++i]);
+                                               fp.p_params.p.z=atof(word[++i]);
+                                               fp.p_params.d.x=atof(word[++i]);
+                                               fp.p_params.d.y=atof(word[++i]);
+                                               fp.p_params.d.z=atof(word[++i]);
+                                       }
+                                       continue;
+                               }
+                               if(word[i][0]=='d') {
+                                       switch(word[++i][0]) {
+                                               case '0':
+
+                               fp.d_params.type=DEFECT_TYPE_0D;
+                               if(!strncmp(word[i+1],"dbx",3)) {
+                                       fp.d_params.stype=DEFECT_STYPE_DB_X;
+                               }
+                               if(!strncmp(word[i+1],"dby",3)) {
+                                       fp.d_params.stype=DEFECT_STYPE_DB_Y;
+                               }
+                               if(!strncmp(word[i+1],"dbz",3)) {
+                                       fp.d_params.stype=DEFECT_STYPE_DB_Z;
+                               }
+                               if(!strncmp(word[i+1],"dbr",3)) {
+                                       fp.d_params.stype=DEFECT_STYPE_DB_R;
+                               }
+                               i+=1;
+                               fp.d_params.od=atof(word[++i]);
+                               fp.d_params.dd=atof(word[++i]);
+                               fp.d_params.element=atoi(word[++i]);
+                               fp.d_params.brand=atoi(word[++i]);
+                               // parsed in future
+               fp.d_params.attr=ATOM_ATTR_HB|ATOM_ATTR_VA;
+               fp.d_params.attr|=ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP;
+                               break;
+
+                                               case '1':
+                               fp.d_params.type=DEFECT_TYPE_1D;
+                               break;
+                                               case '2':
+                               fp.d_params.type=DEFECT_TYPE_2D;
+                               break;
+                                               case '3':
+                               fp.d_params.type=DEFECT_TYPE_3D;
+                               break;
+                                               default:
+                                                       break;
+                                       }
+                                       continue;
+
+                               }
+                               // offset
+                               if(word[i][0]=='o') {
+                                       fp.o_params.o.x=atof(word[++i])*fp.lc;
+                                       fp.o_params.o.y=atof(word[++i])*fp.lc;
+                                       fp.o_params.o.z=atof(word[++i])*fp.lc;
+                                       fp.o_params.use=1;
+                                       continue;
+                               }
+                               i+=1;
+                       }
+                       add_stage(mdrun,STAGE_FILL,&fp);
+               }
+               else if(!strncmp(word[0],"thermal_init",12)) {
+                       add_stage(mdrun,STAGE_THERMAL_INIT,NULL);
                }
                else if(!strncmp(word[0],"aattr",5)) {
                        // for aatrib line we need a special stage
@@ -280,24 +430,30 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                                        case 'e':
                                                cap.type|=CHAATTR_ELEMENT;
                                                break;
+                                       case 'n':
+                                               cap.type|=CHAATTR_NUMBER;
                                        default:
                                                break;
                                }
                        }
                        i=2;
                        if(cap.type&CHAATTR_REGION) {
-                               cap.x0=atof(word[1]);   
-                               cap.y0=atof(word[2]);   
-                               cap.z0=atof(word[3]);   
-                               cap.x1=atof(word[4]);   
-                               cap.y1=atof(word[5]);   
-                               cap.z1=atof(word[6]);
+                               cap.x0=atof(word[2]);   
+                               cap.y0=atof(word[3]);   
+                               cap.z0=atof(word[4]);   
+                               cap.x1=atof(word[5]);   
+                               cap.y1=atof(word[6]);   
+                               cap.z1=atof(word[7]);
                                i+=6;
                        }
                        if(cap.type&CHAATTR_ELEMENT) {
                                cap.element=atoi(word[i]);
                                i+=1;
                        }
+                       if(cap.type&CHAATTR_NUMBER) {
+                               cap.element=atoi(word[i]);
+                               i+=1;
+                       }
                        for(o=0;o<strlen(word[i]);o++) {
                                switch(word[i][o]) {
                                        case 'b':
@@ -333,7 +489,9 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                        csp.type=0;
                        for(i=1;i<wcnt;i++) {
                                if(!strncmp(word[i],"pctrl",5)) {
-                                       csp.ptau=0.01/(atof(word[++i])*GPA);
+                                       csp.ptau=atof(word[++i]);
+                                       if(csp.ptau>0)
+                                               csp.ptau=0.01/(csp.ptau*GPA);
                                        csp.type|=CHSATTR_PCTRL;
                                }
                                if(!strncmp(word[i],"tctrl",5)) {
@@ -384,6 +542,29 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                                dap.dz=atof(word[5]);
                                add_stage(mdrun,STAGE_DISPLACE_ATOM,&dap);
                        }
+                       else if(!strncmp(word[1],"del_atoms",9)) {
+                               delp.o.x=atof(word[2]);
+                               delp.o.y=atof(word[3]);
+                               delp.o.z=atof(word[4]);
+                               delp.r=atof(word[5]);
+                               add_stage(mdrun,STAGE_DEL_ATOMS,&delp);
+                       }
+                       else if(!strncmp(word[1],"mod_atoms",8)) {
+                               i=2;
+                               while(i<wcnt) {
+                                       if(!strncmp(word[i],"t",1)) {
+                                               map.tag=atoi(word[++i]);
+                                               i+=1;
+                                       }
+                                       if(!strncmp(word[i],"ekin",5)) {
+                                               map.ekin.x=atof(word[++i])*EV;
+                                               map.ekin.y=atof(word[++i])*EV;
+                                               map.ekin.z=atof(word[++i])*EV;
+                                               i+=1;
+                                       }
+                               }
+                               add_stage(mdrun,STAGE_MODIFY_ATOMS,&map);
+                       }
                        else if(!strncmp(word[1],"ins_atoms",9)) {
                                iap.ins_steps=atoi(word[2]);
                                iap.ins_atoms=atoi(word[3]);
@@ -424,26 +605,96 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                                                iap.y0=atof(word[9]);
                                                iap.z0=atof(word[10]);
                                                break;
+                                       case 'P':
+                                               iap.type=INS_RELPOS;
+                                               iap.x0=atof(word[8]);
+                                               iap.y0=atof(word[9]);
+                                               iap.z0=atof(word[10]);
+                                               break;
                                        case 'r':
-                                               if(word[8][0]=='t') {
+                                               switch(word[8][0]) {
+
+                                               case 't':
                                                        iap.type=INS_TOTAL;
                                                        iap.cr=atof(word[9]);
-                                               }
-                                               else {
-                                                       iap.type=INS_REGION;
-                                                       iap.x0=atof(word[8]);
-                                                       iap.y0=atof(word[9]);
-                                                       iap.z0=atof(word[10]);
-                                                       iap.x1=atof(word[11]);
-                                                       iap.y1=atof(word[12]);
-                                                       iap.z1=atof(word[13]);
-                                                       iap.cr=atof(word[14]);
+                                                       break;
+                                               case 'r':
+                                                       iap.type=INS_RECT;
+                                                       iap.x0=atof(word[9]);
+                                                       iap.y0=atof(word[10]);
+                                                       iap.z0=atof(word[11]);
+                                                       iap.x1=atof(word[12]);
+                                                       iap.y1=atof(word[13]);
+                                                       iap.z1=atof(word[14]);
+                                                       iap.cr=atof(word[15]);
+                                                       break;
+                                               case 's':
+                                                       iap.type=INS_SPHERE;
+                                                       iap.x0=atof(word[9]);
+                                                       iap.y0=atof(word[10]);
+                                                       iap.z0=atof(word[11]);
+                                                       iap.x1=atof(word[12]);
+                                                       iap.cr=atof(word[13]);
+                                                       break;
+                                               default:
+                                                       break;
                                                }
                                        default:
                                                break;
                                }
                                add_stage(mdrun,STAGE_INSERT_ATOMS,&iap);
                        }
+
+
+                       // HERE WE GO ...
+
+                       else if(!strncmp(word[1],"ins_m_atoms",11)) {
+                               imp.element1=atoi(word[2]);
+                               imp.element2=atoi(word[3]);
+                               imp.amount1=atoi(word[4]);
+                               imp.amount2=atoi(word[5]);
+                               imp.brand1=atoi(word[6]);
+                               imp.brand2=atoi(word[7]);
+                               imp.crmin=atof(word[8]);
+                               imp.crmax=atof(word[9]);
+                               /* do this later ...
+                               for(i=0;i<strlen(word[8]);i++) {
+                                       switch(word[8][i]) {
+                                               case 'b':
+                                                       imp.attr|=ATOM_ATTR_VB;
+                                                       break;
+                                               case 'h':
+                                                       imp.attr|=ATOM_ATTR_HB;
+                                                       break;
+                                               case 'v':
+                                                       imp.attr|=ATOM_ATTR_VA;
+                                                       break;
+                                               case 'f':
+                                                       imp.attr|=ATOM_ATTR_FP;
+                                                       break;
+                                               case '1':
+                                                       imp.attr|=ATOM_ATTR_1BP;
+                                                       break;
+                                               case '2':
+                                                       imp.attr|=ATOM_ATTR_2BP;
+                                                       break;
+                                               case '3':
+                                                       imp.attr|=ATOM_ATTR_3BP;
+                                                       break;
+                                               default:
+                                                       break;
+                                       }
+                               }
+                               */
+                               imp.attr1=ATOM_ATTR_HB|ATOM_ATTR_VA|ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_FP;
+                               imp.attr2=ATOM_ATTR_HB|ATOM_ATTR_VA|ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_FP;
+                               add_stage(mdrun,STAGE_INSERT_MIXED_ATOMS,&imp);
+                       }
+
+
+
+
+
                        else if(!strncmp(word[1],"continue",8)) {
                                cp.runs=atoi(word[2]);
                                add_stage(mdrun,STAGE_CONTINUE,&cp);
@@ -452,8 +703,30 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                                ap.count=0;
                                ap.runs=atoi(word[2]);
                                ap.dt=atof(word[3]);
+                               ap.interval=atoi(word[4]);
                                add_stage(mdrun,STAGE_ANNEAL,&ap);
                        }
+                       else if(!strncmp(word[1],"set_temp",8)) {
+                               if(word[2][0]=='c') {
+                                       stp.type=SET_TEMP_CURRENT;
+                                       stp.val=0.0;
+                               }
+                               else {
+                                       stp.type=SET_TEMP_VALUE;
+                                       stp.val=atof(word[2]);
+                               }
+                               add_stage(mdrun,STAGE_SET_TEMP,&stp);
+                       }
+                       else if(!strncmp(word[1],"set_timestep",12)) {
+                               stsp.tau=atof(word[2]);
+                               add_stage(mdrun,STAGE_SET_TIMESTEP,&stsp);
+                       }
+                       else if(!strncmp(word[1],"crt",3)) {
+                               crtp.type=atoi(word[2]);
+                               crtp.steps=atoi(word[3]);
+                               strncpy(crtp.file,word[4],127);
+                               add_stage(mdrun,STAGE_CRT,&crtp);
+                       }
                        else {
                                printf("%s unknown stage type: %s\n",
                                       ME,word[1]);
@@ -527,6 +800,80 @@ int displace_atom(t_moldyn *moldyn,t_mdrun *mdrun) {
        return 0;
 }
 
+int del_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
+
+       t_stage *stage;
+       t_del_atoms_params *delp;
+       int i;
+       t_3dvec dist;
+       u8 outer;
+
+       outer=0;        
+       stage=mdrun->stage.current->data;
+       delp=stage->params;
+
+       if(delp->r<0)
+               outer=1;
+
+       for(i=0;i<moldyn->count;i++) {
+               v3_sub(&dist,&(delp->o),&(moldyn->atom[i].r));
+//printf("%d ----> %f %f %f = %f | %f\n",i,dist.x,dist.y,dist.z,v3_absolute_square(&dist),delp->r*delp->r);
+               if(v3_absolute_square(&dist)<=(delp->r*delp->r)) {
+                       if(!outer) {
+                               del_atom(moldyn,moldyn->atom[i].tag);
+                               printf("%s atom deleted: %d %d %d\n",ME,
+                                      moldyn->atom[i].tag,
+                                      moldyn->atom[i].element,
+                                      moldyn->atom[i].brand);
+                       }
+               }
+               else {
+                       if(outer) {
+                               del_atom(moldyn,moldyn->atom[i].tag);
+                               printf("%s atom deleted: %d %d %d\n",ME,
+                                      moldyn->atom[i].tag,
+                                      moldyn->atom[i].element,
+                                      moldyn->atom[i].brand);
+                       }
+               }
+       }
+
+       return 0;
+}
+
+int modify_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
+
+       t_modify_atoms_params *map;
+       t_stage *stage;
+       t_atom *atom;
+       t_3dvec v;
+       int i;
+
+       atom=moldyn->atom;
+       stage=mdrun->stage.current->data;
+       map=stage->params;
+       v.x=0.0; v.y=0.0; v.z=0.0;
+
+       for(i=0;i<moldyn->count;i++) {
+               if(atom[i].tag==map->tag) {
+                       v.x=sqrt(2.0*fabs(map->ekin.x)/atom[i].mass);
+                       if(map->ekin.x<0.0)
+                               v.x=-v.x;
+                       v.y=sqrt(2.0*fabs(map->ekin.y)/atom[i].mass);
+                       if(map->ekin.y<0.0)
+                               v.y=-v.y;
+                       v.z=sqrt(2.0*fabs(map->ekin.z)/atom[i].mass);
+                       if(map->ekin.z<0.0)
+                               v.z=-v.z;
+                       v3_copy(&(atom[i].v),&v);
+                       printf("%s atom modified: v = (%f %f %f)\n",
+                               ME,v.x,v.y,v.z);
+               }
+       }       
+
+       return 0;
+}
+
 int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
 
        t_insert_atoms_params *iap;
@@ -573,7 +920,7 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
                        z0=-z/2.0;
                        cr_check=TRUE;
                        break;
-               case INS_REGION:
+               case INS_RECT:
                        x=iap->x1-iap->x0;
                        x0=iap->x0;
                        y=iap->y1-iap->y0;
@@ -582,7 +929,17 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
                        z0=iap->z0;
                        cr_check=TRUE;
                        break;
+               case INS_SPHERE:
+                       x=2.0*iap->x1;
+                       x0=iap->x0-iap->x1;
+                       y=x;
+                       y0=iap->y0-iap->x1;
+                       z=x;
+                       z0=iap->z0-iap->x1;
+                       cr_check=TRUE;
+                       break;
                case INS_POS:
+               case INS_RELPOS:
                        x0=iap->x0;
                        y0=iap->y0;
                        z0=iap->z0;
@@ -598,7 +955,7 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
        while(cnt<iap->ins_atoms) {
                run=1;
                while(run) {
-                       if(iap->type!=INS_POS) {
+                       if((iap->type!=INS_POS)&&(iap->type!=INS_RELPOS)) {
                                r.x=rand_get_double(&(moldyn->random))*x;
                                r.y=rand_get_double(&(moldyn->random))*y;
                                r.z=rand_get_double(&(moldyn->random))*z;
@@ -608,9 +965,16 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
                                r.y=0.0;
                                r.z=0.0;
                        }
-                       r.x+=x0;
-                       r.y+=y0;
-                       r.z+=z0;
+                       if(iap->type==INS_RELPOS) {
+                               r.x+=x0*mdrun->lc;
+                               r.y+=y0*mdrun->lc;
+                               r.z+=z0*mdrun->lc;
+                       }
+                       else {
+                               r.x+=x0;
+                               r.y+=y0;
+                               r.z+=z0;
+                       }
                        // offset
                        if(iap->type!=INS_TOTAL) {
                                r.x+=o;
@@ -633,19 +997,146 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
                                                dmin=d;
                                }
                        }
+                       if(iap->type==INS_SPHERE) {
+                               if((r.x-iap->x0)*(r.x-iap->x0)+
+                                  (r.y-iap->y0)*(r.y-iap->y0)+
+                                  (r.z-iap->z0)*(r.z-iap->z0)>
+                                  (iap->x1*iap->x1)) {
+                                       run=1;
+                               }
+                       }
                }
-               add_atom(moldyn,iap->element,pse_mass[iap->element],
+               add_atom(moldyn,iap->element,
                         iap->brand,iap->attr,&r,&v);
                printf("%s atom inserted (%d/%d): %f %f %f\n",
                       ME,(iap->cnt_steps+1)*iap->ins_atoms,
                       iap->ins_steps*iap->ins_atoms,r.x,r.y,r.z);
-               printf("  -> d2 = %f/%f\n",dmin,iap->cr*iap->cr);
+               printf("  attributes: ");
+               if(iap->attr&ATOM_ATTR_VB)
+                       printf("b ");
+               if(iap->attr&ATOM_ATTR_HB)
+                       printf("h ");
+               if(iap->attr&ATOM_ATTR_VA)
+                       printf("v ");
+               if(iap->attr&ATOM_ATTR_FP)
+                       printf("f ");
+               if(iap->attr&ATOM_ATTR_1BP)
+                       printf("1 ");
+               if(iap->attr&ATOM_ATTR_2BP)
+                       printf("2 ");
+               if(iap->attr&ATOM_ATTR_3BP)
+                       printf("3 ");
+               printf("\n");
+               printf("  d2 = %f/%f\n",dmin,iap->cr*iap->cr);
                cnt+=1;
        }
 
        return 0;
 }
 
+int insert_mixed_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
+
+       t_stage *stage;
+       t_insert_mixed_atoms_params *imp;
+       t_atom *atom;
+       double x,x0,y,y0,z,z0;
+       double dmin,d,cmin,cmax;
+       u8 retry;
+       t_3dvec r,v,dist;
+       int i;
+       
+
+       stage=mdrun->stage.current->data;
+       imp=stage->params;
+
+       x=moldyn->dim.x;
+       x0=-x/2.0;
+       y=moldyn->dim.y;
+       y0=-y/2.0;
+       z=moldyn->dim.z;
+       z0=-z/2.0;
+
+       v.x=0.0;
+       v.y=0.0;
+       v.z=0.0;
+
+       cmin=imp->crmin*imp->crmin;
+       cmax=imp->crmax*imp->crmax;
+
+       while(imp->amount1|imp->amount2) {
+               if(imp->amount1) {
+                       retry=1;
+                       while(retry) {
+                               retry=0;
+                               r.x=rand_get_double(&(moldyn->random))*x;
+                               r.y=rand_get_double(&(moldyn->random))*y;
+                               r.z=rand_get_double(&(moldyn->random))*z;
+                               r.x+=x0;
+                               r.y+=y0;
+                               r.z+=z0;
+                               dmin=1000.0;    // for sure too high!
+                               for(i=0;i<moldyn->count;i++) {
+                                       atom=&(moldyn->atom[i]);
+                                       v3_sub(&dist,&(atom->r),&r);
+                                       check_per_bound(moldyn,&dist);
+                                       d=v3_absolute_square(&dist);
+                                       if(d<cmin) {
+                                               retry=1;
+                                               break;
+                                       }
+                                       if(d<dmin)
+                                               dmin=d;
+                               }
+                               if(dmin!=1000.0)
+                                       if(dmin>cmax)
+                                               retry=1;
+                       }
+                       add_atom(moldyn,imp->element1,
+                                 imp->brand1,imp->attr1,&r,&v);
+                       printf("%s (mixed) atom inserted (%d): %f %f %f\n",
+                               ME,imp->amount1,r.x,r.y,r.z);
+                       printf("  -> d2 = %f/%f/%f\n",dmin,cmin,cmax);
+                       imp->amount1-=1;
+               }
+               if(imp->amount2) {
+                       retry=1;
+                       while(retry) {
+                               retry=0;
+                               r.x=rand_get_double(&(moldyn->random))*x;
+                               r.y=rand_get_double(&(moldyn->random))*y;
+                               r.z=rand_get_double(&(moldyn->random))*z;
+                               r.x+=x0;
+                               r.y+=y0;
+                               r.z+=z0;
+                               dmin=1000.0;    // for sure too high!
+                               for(i=0;i<moldyn->count;i++) {
+                                       atom=&(moldyn->atom[i]);
+                                       v3_sub(&dist,&(atom->r),&r);
+                                       check_per_bound(moldyn,&dist);
+                                       d=v3_absolute_square(&dist);
+                                       if(d<cmin) {
+                                               retry=1;
+                                               break;
+                                       }
+                                       if(d<dmin)
+                                               dmin=d;
+                               }
+                               if(dmin!=1000.0)
+                                       if(dmin>cmax)
+                                               retry=1;
+                       }
+                       add_atom(moldyn,imp->element2,
+                                 imp->brand2,imp->attr2,&r,&v);
+                       printf("%s (mixed) atom inserted (%d): %f %f %f\n",
+                               ME,imp->amount2,r.x,r.y,r.z);
+                       printf("  -> d2 = %f/%f/%f\n",dmin,cmin,cmax);
+                       imp->amount2-=1;
+               }
+       }
+
+       return 0;
+}
+
 int chaatr(t_moldyn *moldyn,t_mdrun *mdrun) {
 
        t_stage *stage;
@@ -662,23 +1153,32 @@ int chaatr(t_moldyn *moldyn,t_mdrun *mdrun) {
                        if(cap->element!=atom->element)
                                continue;
                }
+               if(cap->type&CHAATTR_NUMBER) {
+                       if(cap->element!=atom->tag)
+                               continue;
+               }
                if(cap->type&CHAATTR_REGION) {
-                       if(cap->x0<atom->r.x)
+                       if(cap->x0>atom->r.x)
                                continue;
-                       if(cap->y0<atom->r.y)
+                       if(cap->y0>atom->r.y)
                                continue;
-                       if(cap->z0<atom->r.z)
+                       if(cap->z0>atom->r.z)
                                continue;
-                       if(cap->x1>atom->r.x)
+                       if(cap->x1<atom->r.x)
                                continue;
-                       if(cap->y1>atom->r.y)
+                       if(cap->y1<atom->r.y)
                                continue;
-                       if(cap->z1>atom->r.z)
+                       if(cap->z1<atom->r.z)
                                continue;
                }
+               if(!(cap->type&CHAATTR_TOTALV))
+                       printf("  changing attributes of atom %d (0x%x)\n",
+                              i,cap->attr);
                atom->attr=cap->attr;
        }
 
+       printf("\n\n");
+
        return 0;
 }
 
@@ -694,13 +1194,13 @@ int chsattr(t_moldyn *moldyn,t_mdrun *mdrun) {
                if(csp->ptau>0)
                        set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau);
                else
-                       set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau);
+                       set_p_scale(moldyn,P_SCALE_NONE,1.0);
        }
        if(csp->type&CHSATTR_TCTRL) {
                if(csp->ttau>0)
                        set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau);
                else
-                       set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau);
+                       set_t_scale(moldyn,T_SCALE_NONE,1.0);
        }
        if(csp->type&CHSATTR_PRELAX) {
                if(csp->dp<0)
@@ -729,6 +1229,138 @@ int chsattr(t_moldyn *moldyn,t_mdrun *mdrun) {
        return 0;
 }
 
+int crt(t_moldyn *moldyn,t_mdrun *mdrun) {
+
+       t_stage *stage;
+       t_crt_params *crtp;
+
+       int fd;
+       char line[128];
+       char *wptr;
+       int acount;
+       int ret;
+       void *ptr;
+
+       t_atom *atom;
+       t_3dvec disp;
+       double frac;
+       int i;
+       
+       stage=mdrun->stage.current->data;
+       crtp=stage->params;
+
+       acount=0;
+
+       /* initial stuff */
+
+       if(crtp->count==0) {
+               printf("  crt init\n");
+               // read final positions, constraints and do the alloc
+               fd=open(crtp->file,O_RDONLY);
+               if(fd<0) {
+                       perror("[mdrun] FATAL reading constraints file");
+                       return fd;
+               }
+               while(1) {
+                       ret=get_line(fd,line,128);
+                       // check for end of file
+                       if(ret<=0) {
+                               printf("  read %d atom positions\n",acount);
+                               if(acount!=moldyn->count)
+                                       printf("  atom count mismatch!!!\n");
+                               printf("\n");
+                               break;
+                       }
+                       // ignore # lines and \n
+                       if((line[0]=='#')|(ret==1))
+                               continue;
+                       // allocate new memory
+                       ptr=realloc(crtp->r_fin,(acount+1)*sizeof(t_3dvec));
+                       if(ptr==NULL) {
+                               perror("[mdrun] FATAL realloc crt positions");
+                               return -1;
+                       }
+                       crtp->r_fin=ptr;
+                       ptr=realloc(constraints,(acount+1)*3*sizeof(u8));
+                       if(ptr==NULL) {
+                               perror("[mdrun] FATAL realloc crt constraints");
+                               return -1;
+                       }
+                       constraints=ptr;
+                       // ignore type
+                       wptr=strtok(line," \t");
+                       // read x y z
+                       wptr=strtok(NULL," \t");
+                       crtp->r_fin[acount].x=atof(wptr);
+                       wptr=strtok(NULL," \t");
+                       crtp->r_fin[acount].y=atof(wptr);
+                       wptr=strtok(NULL," \t");
+                       crtp->r_fin[acount].z=atof(wptr);
+                       // read constraints
+                       wptr=strtok(NULL," \t");
+                       constraints[3*acount]=atoi(wptr);
+                       wptr=strtok(NULL," \t");
+                       constraints[3*acount+1]=atoi(wptr);
+                       wptr=strtok(NULL," \t");
+                       constraints[3*acount+2]=atoi(wptr);
+                       // done reading
+                       acount+=1;
+               }
+               close(fd);
+               // allocate trafo angles
+               trafo_angle=malloc(acount*2*sizeof(double));
+               if(trafo_angle==NULL) {
+                       perror("[mdrun] FATAL alloc trafo angles");
+                       return -1;
+               }
+               // set crt mode
+               crtt=crtp->type;
+       }
+
+       /* write a save file s-crt_xofy.save */
+       snprintf(line,128,"%s/s-crt_%03dof%03d.save",
+                moldyn->vlsdir,crtp->count,crtp->steps);
+       fd=open(line,O_WRONLY|O_TRUNC|O_CREAT,S_IRUSR|S_IWUSR);
+       if(fd<0) perror("[mdrun] crt save fd open");
+       else {
+               write(fd,moldyn,sizeof(t_moldyn));
+               write(fd,moldyn->atom,
+                     moldyn->count*sizeof(t_atom));
+       }
+       close(fd);
+       /* visualize atoms */
+       visual_atoms(moldyn);
+
+       /* output energy */
+       printf("  crt energy: %d - %f\n\n",
+              crtp->count,(moldyn->ekin+moldyn->energy)/EV);
+
+       /* crt routines: calculate displacement + set individual constraints */
+
+       printf("  crt step %d of %d in total\n\n",crtp->count+1,crtp->steps);
+
+       if((crtp->type==1)|(crtp->count==0))
+               printf("  crt angle update\n\n");
+               
+       for(i=0;i<moldyn->count;i++) {
+               // calc displacements
+               atom=moldyn->atom;
+               v3_sub(&disp,&(crtp->r_fin[i]),&(atom[i].r));
+               // angles
+               if((crtp->type==1)|(crtp->count==0)) {
+                       trafo_angle[2*i]=atan2(disp.x,disp.y);
+                       trafo_angle[2*i+1]=-atan2(disp.z,
+                                          sqrt(disp.x*disp.x+disp.y*disp.y));
+               }
+               // move atoms
+               frac=1.0/(crtp->steps-crtp->count);
+               v3_scale(&disp,&disp,frac);
+               v3_add(&(atom[i].r),&(atom[i].r),&disp);
+       }
+
+       return 0;
+}
+
 #define stage_print(m) if(!(stage->executed)) \
                                printf("%s",m)
 
@@ -739,12 +1371,17 @@ int mdrun_hook(void *ptr1,void *ptr2) {
        t_stage *stage;
        t_list *sl;
        int steps;
-       double tau;
        u8 change_stage;
+       t_3dvec o;
 
        t_insert_atoms_params *iap;
+       t_insert_mixed_atoms_params *imp;
        t_continue_params *cp;
        t_anneal_params *ap;
+       t_set_temp_params *stp;
+       t_set_timestep_params *stsp;
+       t_fill_params *fp;
+       t_crt_params *crtp;
 
        moldyn=ptr1;
        mdrun=ptr2;
@@ -760,9 +1397,8 @@ int mdrun_hook(void *ptr1,void *ptr2) {
        /* get stage description */
        stage=sl->current->data;
 
-       /* default steps and tau values */
+       /* steps in next schedule */
        steps=mdrun->relax_steps;
-       tau=mdrun->timestep;
 
        /* check whether relaxation steps are necessary */
        if((check_pressure(moldyn,mdrun)==TRUE)&\
@@ -780,6 +1416,16 @@ int mdrun_hook(void *ptr1,void *ptr2) {
                                displace_atom(moldyn,mdrun);
                                change_stage=TRUE;
                                break;
+                       case STAGE_DEL_ATOMS:
+                               stage_print(" -> del atoms\n\n");
+                               del_atoms(moldyn,mdrun);
+                               change_stage=TRUE;
+                               break;
+                       case STAGE_MODIFY_ATOMS:
+                               stage_print(" -> modify atoms\n\n");
+                               modify_atoms(moldyn,mdrun);
+                               change_stage=TRUE;
+                               break;
                        case STAGE_INSERT_ATOMS:
                                stage_print("  -> insert atoms\n\n");
                                iap=stage->params;
@@ -790,6 +1436,18 @@ int mdrun_hook(void *ptr1,void *ptr2) {
                                insert_atoms(moldyn,mdrun);
                                iap->cnt_steps+=1;
                                break;
+
+
+
+                       case STAGE_INSERT_MIXED_ATOMS:
+                               stage_print("  -> insert mixed atoms\n\n");
+                               imp=stage->params;
+                               insert_mixed_atoms(moldyn,mdrun);
+                               change_stage=TRUE;
+                               break;
+
+
+
                        case STAGE_CONTINUE:
                                stage_print("  -> continue\n\n");
                                if(stage->executed==TRUE) {
@@ -810,17 +1468,103 @@ int mdrun_hook(void *ptr1,void *ptr2) {
                                        set_temperature(moldyn,
                                                        moldyn->t_ref+ap->dt);
                                ap->count+=1;
+                               steps=ap->interval;
                                break;
                        case STAGE_CHAATTR:
-                               stage_print("  -> chaattr\n\n");
+                               stage_print("  -> change atom attributes\n\n");
                                chaatr(moldyn,mdrun);
                                change_stage=TRUE;
                                break;
                        case STAGE_CHSATTR:
-                               stage_print("  -> chsattr\n\n");
+                               stage_print("  -> change sys attributes\n\n");
                                chsattr(moldyn,mdrun);
                                change_stage=TRUE;
                                break;
+                       case STAGE_SET_TEMP:
+                               stage_print("  -> set temperature\n\n");
+                               stp=stage->params;
+                               if(stp->type&SET_TEMP_CURRENT) {
+                                       set_temperature(moldyn,moldyn->t_avg);
+                               }
+                               else {
+                                       set_temperature(moldyn,stp->val);
+                               }
+                               change_stage=TRUE;
+                               break;
+                       case STAGE_SET_TIMESTEP:
+                               stage_print("  -> set timestep\n\n");
+                               stsp=stage->params;
+                               mdrun->timestep=stsp->tau;
+                               change_stage=TRUE;
+                               break;
+                       case STAGE_FILL:
+                               stage_print("  -> fill lattice\n\n");
+                               fp=stage->params;
+                               switch(fp->lattice) {
+                                       case ZINCBLENDE:
+
+                                       o.x=0.5*0.25*fp->lc;
+                                       o.y=o.x;
+                                       o.z=o.x;
+                                       create_lattice(moldyn,
+                                                      FCC,fp->lc,
+                                                      mdrun->element1,
+                                                      DEFAULT_ATOM_ATTR,0,
+                                                      fp->lx,fp->ly,fp->lz,
+                                                      &o,
+                                                      &(fp->p_params),
+                                                      &(fp->d_params),
+                                                      &(fp->o_params));
+                                       o.x+=0.25*fp->lc;
+                                       o.y=o.x;
+                                       o.z=o.x;
+                                       create_lattice(moldyn,
+                                                      FCC,fp->lc,
+                                                      mdrun->element2,
+                                                      DEFAULT_ATOM_ATTR,1,
+                                                      fp->lx,fp->ly,fp->lz,
+                                                      &o,
+                                                      &(fp->p_params),
+                                                      &(fp->d_params),
+                                                      &(fp->o_params));
+                                       break;
+
+                                       default:
+
+                                       create_lattice(moldyn,
+                                                      fp->lattice,fp->lc,
+                                                      fp->fill_element,
+                                                      DEFAULT_ATOM_ATTR,
+                                                      fp->fill_brand,
+                                                      fp->lx,fp->ly,fp->lz,
+                                                      NULL,
+                                                      &(fp->p_params),
+                                                      &(fp->d_params),
+                                                      &(fp->o_params));
+                                       break;
+                               }
+                               moldyn_bc_check(moldyn);
+                               change_stage=TRUE;
+                               break;
+                       case STAGE_THERMAL_INIT:
+                               stage_print("  -> thermal init\n\n");
+                               thermal_init(moldyn,TRUE);
+                               change_stage=TRUE;
+                               break;
+                       case STAGE_CRT:
+                               stage_print("  -> constraint relaxation");
+                               stage_print(" technique\n\n");
+                               crtp=stage->params;
+                               if(crtp->count==crtp->steps) {
+                                       free(constraints);
+                                       free(trafo_angle);
+                                       free(crtp->r_fin);
+                                       change_stage=TRUE;
+                                       break;
+                               }
+                               crt(moldyn,mdrun);
+                               crtp->count+=1;
+                               break;
                        default:
                                printf("%s unknwon stage type\n",ME);
                                break;
@@ -837,7 +1581,6 @@ int mdrun_hook(void *ptr1,void *ptr2) {
                                return 0;
                        }
                        steps=0;
-                       tau=mdrun->timestep;
                }
 
        }
@@ -850,7 +1593,7 @@ int mdrun_hook(void *ptr1,void *ptr2) {
        }
 
        /* continue simulation */
-       moldyn_add_schedule(moldyn,steps,tau);
+       moldyn_add_schedule(moldyn,steps,mdrun->timestep);
 
        return 0;
 }
@@ -859,12 +1602,17 @@ int main(int argc,char **argv) {
 
        t_mdrun mdrun;
        t_moldyn moldyn;
-       t_3dvec o;
+       //t_3dvec o;
 
        /* clear structs */
        memset(&mdrun,0,sizeof(t_mdrun));
        memset(&moldyn,0,sizeof(t_moldyn));
 
+       /* init crt variables */
+       crtt=0;
+       constraints=NULL;
+       trafo_angle=NULL;
+
        /* parse arguments */
        if(mdrun_parse_argv(&mdrun,argc,argv)<0)
                return -1;
@@ -939,26 +1687,33 @@ int main(int argc,char **argv) {
        /* initial lattice and dimensions */
        set_dim(&moldyn,mdrun.dim.x,mdrun.dim.y,mdrun.dim.z,mdrun.vis);
        set_pbc(&moldyn,mdrun.pbcx,mdrun.pbcy,mdrun.pbcz);
+       /* replaced by fill stage !! 
        switch(mdrun.lattice) {
                case FCC:
-                       create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element1,
-                                      mdrun.m1,DEFAULT_ATOM_ATTR,0,mdrun.lx,
-                                      mdrun.ly,mdrun.lz,NULL);
+                       create_lattice(&moldyn,FCC,mdrun.lc,mdrun.fill_element,
+                                      mdrun.m1,DEFAULT_ATOM_ATTR,
+                                       mdrun.fill_brand,mdrun.lx,
+                                      mdrun.ly,mdrun.lz,NULL,0,NULL);
                        break;
                case DIAMOND:
-                       create_lattice(&moldyn,DIAMOND,mdrun.lc,mdrun.element1,
-                                      mdrun.m1,DEFAULT_ATOM_ATTR,0,mdrun.lx,
-                                      mdrun.ly,mdrun.lz,NULL);
+                       create_lattice(&moldyn,DIAMOND,mdrun.lc,
+                                       mdrun.fill_element,
+                                      mdrun.m1,DEFAULT_ATOM_ATTR,
+                                       mdrun.fill_brand,mdrun.lx,
+                                      mdrun.ly,mdrun.lz,NULL,0,NULL);
                        break;
                case ZINCBLENDE:
                        o.x=0.5*0.25*mdrun.lc; o.y=o.x; o.z=o.x;
                        create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element1,
                                       mdrun.m1,DEFAULT_ATOM_ATTR,0,mdrun.lx,
-                                      mdrun.ly,mdrun.lz,&o);
+                                      mdrun.ly,mdrun.lz,&o,0,NULL);
                        o.x+=0.25*mdrun.lc; o.y=o.x; o.z=o.x;
                        create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element2,
                                       mdrun.m2,DEFAULT_ATOM_ATTR,1,mdrun.lx,
-                                      mdrun.ly,mdrun.lz,&o);
+                                      mdrun.ly,mdrun.lz,&o,0,NULL);
+                       break;
+               case NONE:
+                       set_nn_dist(&moldyn,mdrun.nnd);
                        break;
                default:
                        printf("%s unknown lattice type: %02x\n",
@@ -966,11 +1721,14 @@ int main(int argc,char **argv) {
                        return -1;
        }
        moldyn_bc_check(&moldyn);
+       replaced by fill stage !! */
 
        /* temperature and pressure */
        set_temperature(&moldyn,mdrun.temperature);
        set_pressure(&moldyn,mdrun.pressure);
+       /* replaced thermal_init stage
        thermal_init(&moldyn,TRUE);
+       */
 
 addsched:
        /* first schedule */
diff --git a/mdrun.h b/mdrun.h
index d065d57..b8ed70c 100644 (file)
--- a/mdrun.h
+++ b/mdrun.h
@@ -43,10 +43,18 @@ typedef struct s_stage {
 
 #define STAGE_DISPLACE_ATOM                    0x00
 #define STAGE_INSERT_ATOMS                     0x01
-#define STAGE_CONTINUE                         0x02
-#define STAGE_ANNEAL                           0x03
-#define STAGE_CHAATTR                          0x04
-#define STAGE_CHSATTR                          0x05
+#define STAGE_INSERT_MIXED_ATOMS               0x02
+#define STAGE_CONTINUE                         0x03
+#define STAGE_ANNEAL                           0x04
+#define STAGE_CHAATTR                          0x05
+#define STAGE_CHSATTR                          0x06
+#define STAGE_SET_TEMP                         0x07
+#define STAGE_SET_TIMESTEP                     0x08
+#define STAGE_FILL                             0x09
+#define STAGE_THERMAL_INIT                     0x10
+#define STAGE_DEL_ATOMS                                0x11
+#define STAGE_MODIFY_ATOMS                     0x12
+#define STAGE_CRT                              0x13
 
 typedef struct s_mdrun {
        char cfile[128];                        // config file
@@ -66,13 +74,9 @@ typedef struct s_mdrun {
        u8 pbcz;
 
        int element1;                           // element 1
-       double m1;
        int element2;                           // element 2
-       double m2;
+
        double lc;                              // lattice constant
-       int lx;                                 // amount of lc units
-       int ly;
-       int lz;
        u8 lattice;                             // type of lattice
 
        u8 sattr;                               // system attributes
@@ -107,6 +111,17 @@ typedef struct s_displace_atom_params {
        double dx,dy,dz;
 } t_displace_atom_params;
 
+typedef struct s_del_atoms_params {
+       double r;
+       t_3dvec o;
+} t_del_atoms_params;
+
+typedef struct s_modify_aoms_params {
+       u8 type;
+       int tag;
+       t_3dvec ekin;
+} t_modify_atoms_params;
+
 typedef struct s_insert_atoms_params {
        u8 type;
        double x0,y0,z0,x1,y1,z1;
@@ -119,9 +134,24 @@ typedef struct s_insert_atoms_params {
        u8 attr;
 } t_insert_atoms_params;
 
+typedef struct s_insert_mixed_atoms_params {
+       int element1;
+       int element2;
+       int amount1;
+       int amount2;
+       u8 brand1;
+       u8 brand2;
+       u8 attr1;
+       u8 attr2;
+       double crmin;
+       double crmax;
+} t_insert_mixed_atoms_params;
+
 #define INS_TOTAL                              0x01
-#define INS_REGION                             0x02
-#define INS_POS                                        0x03
+#define INS_RECT                               0x02
+#define INS_SPHERE                             0x03
+#define INS_POS                                        0x04
+#define INS_RELPOS                             0x05
 
 typedef struct s_continue_params {
        int runs;
@@ -131,6 +161,7 @@ typedef struct s_anneal_params {
        int runs;
        int count;
        double dt;
+       int interval;
 } t_anneal_params;
 
 typedef struct s_chaattr_params {
@@ -144,6 +175,7 @@ typedef struct s_chaattr_params {
 #define CHAATTR_TOTALV                         0x01
 #define CHAATTR_REGION                         0x02
 #define CHAATTR_ELEMENT                                0x04
+#define CHAATTR_NUMBER                         0x08
 
 typedef struct s_chsattr_params {
        u8 type;
@@ -162,9 +194,51 @@ typedef struct s_chsattr_params {
 #define CHSATTR_AVGRST                         0x10
 #define CHSATTR_RSTEPS                         0x20
 
+typedef struct s_set_temp_params {
+       u8 type;
+       double val;
+} t_set_temp_params;
+
+#define SET_TEMP_CURRENT                       0x01
+#define SET_TEMP_VALUE                         0x02
+
+typedef struct s_set_timestep_params {
+       double tau;
+} t_set_timestep_params;
+
+typedef struct s_fill_params {
+       double lc;                              // lattice constant
+       int lx;                                 // amount of lc units
+       int ly;
+       int lz;
+       u8 lattice;
+       int fill_element;
+       u8 fill_brand;
+       t_part_params p_params;
+       t_defect_params d_params;
+       t_offset_params o_params;
+} t_fill_params;
+
+typedef struct s_crt_params {
+       u8 type;
+       char file[128];
+       t_3dvec *r_fin;
+       u8 *constraints;
+       int steps;
+       int count;
+} t_crt_params;
+
 /*
- * function prototypes
+ * extern variables
  */
 
+// constraint relaxation technique
+extern u8 crtt;
+extern u8 *constraints;
+extern double *trafo_angle;
+
+/*
+ * function prototypes
+ */
 
 #endif
index 010b8ed..1d6e0b7 100644 (file)
--- a/moldyn.c
+++ b/moldyn.c
 #include <time.h>
 #include <math.h>
 
+#include <fpu_control.h>
+
+#ifdef PARALLEL
+#include <omp.h>
+#endif
+
+#if defined PTHREADS || defined VISUAL_THREAD
+#include <pthread.h>
+#endif
+
 #include "moldyn.h"
 #include "report/report.h"
 
 #include "potentials/tersoff.h"
 #endif
 
+/* pse */
+#define PSE_MASS
+#define PSE_NAME
+#define PSE_COL
+#include "pse.h"
+#undef PSE_MASS
+#undef PSE_NAME
+#undef PSE_COL
+
+#ifdef PTHREADS
+/* global mutexes */
+pthread_mutex_t *amutex;
+pthread_mutex_t emutex;
+#endif
+
+/* fully constrained relaxation technique - global pointers */
+u8 crtt;
+u8 *constraints;
+double *trafo_angle;
+
 /*
  * the moldyn functions
  */
@@ -39,6 +69,9 @@ int moldyn_init(t_moldyn *moldyn,int argc,char **argv) {
 
        printf("[moldyn] init\n");
 
+       /* only needed if compiled without -msse2 (float-store prob!) */
+       //fpu_set_rtd();
+
        memset(moldyn,0,sizeof(t_moldyn));
 
        moldyn->argc=argc;
@@ -47,13 +80,28 @@ int moldyn_init(t_moldyn *moldyn,int argc,char **argv) {
        rand_init(&(moldyn->random),NULL,1);
        moldyn->random.status|=RAND_STAT_VERBOSE;
 
+#ifdef PTHREADS
+       pthread_mutex_init(&emutex,NULL);
+#endif
+
        return 0;
 }
 
 int moldyn_shutdown(t_moldyn *moldyn) {
 
+#ifdef PTHREADS
+       int i;
+#endif
+
        printf("[moldyn] shutdown\n");
 
+#ifdef PTHREADS
+       for(i=0;i<moldyn->count;i++)
+               pthread_mutex_destroy(&(amutex[i]));
+       free(amutex);
+       pthread_mutex_destroy(&emutex);
+#endif
+
        moldyn_log_shutdown(moldyn);
        link_cell_shutdown(moldyn);
        rand_close(&(moldyn->random));
@@ -216,11 +264,11 @@ int set_potential(t_moldyn *moldyn,u8 type) {
 
        switch(type) {
                case MOLDYN_POTENTIAL_TM:
-                       moldyn->func_i0=tersoff_mult_1bp;
-                       moldyn->func_j1=tersoff_mult_3bp_j1;
-                       moldyn->func_j1_k0=tersoff_mult_3bp_k1;
-                       moldyn->func_j1c=tersoff_mult_3bp_j2;
-                       moldyn->func_j1_k1=tersoff_mult_3bp_k2;
+                       //moldyn->func1b=tersoff_mult_1bp;
+                       moldyn->func3b_j1=tersoff_mult_3bp_j1;
+                       moldyn->func3b_k1=tersoff_mult_3bp_k1;
+                       moldyn->func3b_j2=tersoff_mult_3bp_j2;
+                       moldyn->func3b_k2=tersoff_mult_3bp_k2;
                        moldyn->check_2b_bond=tersoff_mult_check_2b_bond;
                        break;
                case MOLDYN_POTENTIAL_AO:
@@ -482,8 +530,10 @@ int moldyn_log_shutdown(t_moldyn *moldyn) {
  * creating lattice functions
  */
 
-int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass,
-                   u8 attr,u8 brand,int a,int b,int c,t_3dvec *origin) {
+int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,
+                   u8 attr,u8 brand,int a,int b,int c,t_3dvec *origin,
+                   t_part_params *p_params,t_defect_params *d_params,
+                   t_offset_params *o_params) {
 
        int new,count;
        int ret;
@@ -491,15 +541,37 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass,
        void *ptr;
        t_atom *atom;
        char name[16];
+#ifdef PTHREADS
+       pthread_mutex_t *mutex;
+#endif
 
        new=a*b*c;
        count=moldyn->count;
 
        /* how many atoms do we expect */
+       if(type==NONE) {
+               new*=1;
+               printf("[moldyn] WARNING: create 'none' lattice called");
+       }
        if(type==CUBIC) new*=1;
        if(type==FCC) new*=4;
        if(type==DIAMOND) new*=8;
 
+       /* defects */
+       if(d_params->type) {
+               switch(d_params->stype) {
+                       case DEFECT_STYPE_DB_X:
+                       case DEFECT_STYPE_DB_Y:
+                       case DEFECT_STYPE_DB_Z:
+                       case DEFECT_STYPE_DB_R:
+                               new*=2;
+                               break;
+                       default:
+                               printf("[moldyn] WARNING: cl unknown defect\n");
+                               break;
+               }
+       }
+
        /* allocate space for atoms */
        ptr=realloc(moldyn->atom,(count+new)*sizeof(t_atom));
        if(!ptr) {
@@ -509,6 +581,16 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass,
        moldyn->atom=ptr;
        atom=&(moldyn->atom[count]);
 
+#ifdef PTHREADS
+       ptr=realloc(amutex,(count+new)*sizeof(pthread_mutex_t));
+       if(!ptr) {
+               perror("[moldyn] mutex realloc (add atom)");
+               return -1;
+       }
+       amutex=ptr;
+       mutex=&(amutex[count]);
+#endif
+
        /* no atoms on the boundaries (only reason: it looks better!) */
        if(!origin) {
                orig.x=0.5*lc;
@@ -523,22 +605,28 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass,
 
        switch(type) {
                case CUBIC:
+                       if(o_params->use)
+                               v3_add(&orig,&orig,&(o_params->o));
                        set_nn_dist(moldyn,lc);
-                       ret=cubic_init(a,b,c,lc,atom,&orig);
+                       ret=cubic_init(a,b,c,lc,atom,&orig,p_params,d_params);
                        strcpy(name,"cubic");
                        break;
                case FCC:
                        if(!origin)
                                v3_scale(&orig,&orig,0.5);
+                       if(o_params->use)
+                               v3_add(&orig,&orig,&(o_params->o));
                        set_nn_dist(moldyn,0.5*sqrt(2.0)*lc);
-                       ret=fcc_init(a,b,c,lc,atom,&orig);
+                       ret=fcc_init(a,b,c,lc,atom,&orig,p_params,d_params);
                        strcpy(name,"fcc");
                        break;
                case DIAMOND:
                        if(!origin)
                                v3_scale(&orig,&orig,0.25);
+                       if(o_params->use)
+                               v3_add(&orig,&orig,&(o_params->o));
                        set_nn_dist(moldyn,0.25*sqrt(3.0)*lc);
-                       ret=diamond_init(a,b,c,lc,atom,&orig);
+                       ret=diamond_init(a,b,c,lc,atom,&orig,p_params,d_params);
                        strcpy(name,"diamond");
                        break;
                default:
@@ -548,25 +636,62 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass,
 
        /* debug */
        if(ret!=new) {
-               printf("[moldyn] creating lattice failed\n");
+               printf("[moldyn] creating %s lattice (lc=%f) incomplete\n",
+                      name,lc);
+               printf("  (ignore for partial lattice creation)\n");
                printf("  amount of atoms\n");
                printf("  - expected: %d\n",new);
                printf("  - created: %d\n",ret);
+       }
+
+       moldyn->count+=ret;
+       if(ret==new)
+               printf("[moldyn] created %s lattice with %d atoms\n",name,ret);
+
+       for(new=0;new<ret;new++) {
+               atom[new].element=element;
+               atom[new].mass=pse_mass[element];
+               atom[new].attr=attr;
+               atom[new].brand=brand;
+               atom[new].tag=count+new;
+               check_per_bound(moldyn,&(atom[new].r));
+               atom[new].r_0=atom[new].r;
+#ifdef PTHREADS
+               pthread_mutex_init(&(mutex[new]),NULL);
+#endif
+               if(d_params->type) {
+                       new+=1;
+                       atom[new].element=d_params->element;
+                       atom[new].mass=pse_mass[d_params->element];
+                       atom[new].attr=d_params->attr;
+                       atom[new].brand=d_params->brand;
+                       atom[new].tag=count+new;
+                       check_per_bound(moldyn,&(atom[new].r));
+                       atom[new].r_0=atom[new].r;
+#ifdef PTHREADS
+                       pthread_mutex_init(&(mutex[new]),NULL);
+#endif
+               }
+       }
+
+       /* fix allocation */
+       ptr=realloc(moldyn->atom,moldyn->count*sizeof(t_atom));
+       if(!ptr) {
+               perror("[moldyn] realloc (create lattice - alloc fix)");
                return -1;
        }
+       moldyn->atom=ptr;
 
-       moldyn->count+=new;
-       printf("[moldyn] created %s lattice with %d atoms\n",name,new);
+// WHAT ABOUT AMUTEX !!!!
 
-       for(ret=0;ret<new;ret++) {
-               atom[ret].element=element;
-               atom[ret].mass=mass;
-               atom[ret].attr=attr;
-               atom[ret].brand=brand;
-               atom[ret].tag=count+ret;
-               check_per_bound(moldyn,&(atom[ret].r));
-               atom[ret].r_0=atom[ret].r;
+#ifdef LOWMEM_LISTS
+       ptr=realloc(moldyn->lc.subcell->list,moldyn->count*sizeof(int));
+       if(!ptr) {
+               perror("[moldyn] list realloc (create lattice)");
+               return -1;
        }
+       moldyn->lc.subcell->list=ptr;
+#endif
 
        /* update total system mass */
        total_mass_calc(moldyn);
@@ -574,7 +699,7 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass,
        return ret;
 }
 
-int add_atom(t_moldyn *moldyn,int element,double mass,u8 brand,u8 attr,
+int add_atom(t_moldyn *moldyn,int element,u8 brand,u8 attr,
              t_3dvec *r,t_3dvec *v) {
 
        t_atom *atom;
@@ -591,6 +716,25 @@ int add_atom(t_moldyn *moldyn,int element,double mass,u8 brand,u8 attr,
        }
        moldyn->atom=ptr;
 
+#ifdef LOWMEM_LISTS
+       ptr=realloc(moldyn->lc.subcell->list,(count+1)*sizeof(int));
+       if(!ptr) {
+               perror("[moldyn] list realloc (add atom)");
+               return -1;
+       }
+       moldyn->lc.subcell->list=ptr;
+#endif
+
+#ifdef PTHREADS
+       ptr=realloc(amutex,(count+1)*sizeof(pthread_mutex_t));
+       if(!ptr) {
+               perror("[moldyn] mutex realloc (add atom)");
+               return -1;
+       }
+       amutex=ptr;
+       pthread_mutex_init(&(amutex[count]),NULL);
+#endif
+
        atom=moldyn->atom;
 
        /* initialize new atom */
@@ -598,7 +742,7 @@ int add_atom(t_moldyn *moldyn,int element,double mass,u8 brand,u8 attr,
        atom[count].r=*r;
        atom[count].v=*v;
        atom[count].element=element;
-       atom[count].mass=mass;
+       atom[count].mass=pse_mass[element];
        atom[count].brand=brand;
        atom[count].tag=count;
        atom[count].attr=attr;
@@ -615,6 +759,9 @@ int del_atom(t_moldyn *moldyn,int tag) {
 
        t_atom *new,*old;
        int cnt;
+#if defined LOWMEM_LISTS || defined PTHREADS
+       void *ptr;
+#endif
 
        old=moldyn->atom;
 
@@ -637,16 +784,81 @@ int del_atom(t_moldyn *moldyn,int tag) {
 
        free(old);
 
+#ifdef LOWMEM_LISTS
+       ptr=realloc(moldyn->lc.subcell->list,moldyn->count*sizeof(int));
+       if(!ptr) {
+               perror("[moldyn] list realloc (del atom)");
+               return -1;
+       }
+       moldyn->lc.subcell->list=ptr;
+       // update lists
+       link_cell_update(moldyn);
+#endif
+
+#ifdef PTHREADS
+       ptr=realloc(amutex,moldyn->count*sizeof(pthread_mutex_t));
+       if(!ptr) {
+               perror("[moldyn] mutex realloc (add atom)");
+               return -1;
+       }
+       amutex=ptr;
+       pthread_mutex_destroy(&(amutex[moldyn->count+1]));
+#endif
+
+
        return 0;
 }
 
+#define        set_atom_positions(pos) \
+       if(d_params->type) {\
+               d_o.x=0; d_o.y=0; d_o.z=0;\
+               d_d.x=0; d_d.y=0; d_d.z=0;\
+               switch(d_params->stype) {\
+                       case DEFECT_STYPE_DB_X:\
+                               d_o.x=d_params->od;\
+                               d_d.x=d_params->dd;\
+                               break;\
+                       case DEFECT_STYPE_DB_Y:\
+                               d_o.y=d_params->od;\
+                               d_d.y=d_params->dd;\
+                               break;\
+                       case DEFECT_STYPE_DB_Z:\
+                               d_o.z=d_params->od;\
+                               d_d.z=d_params->dd;\
+                               break;\
+                       case DEFECT_STYPE_DB_R:\
+                               break;\
+                       default:\
+                               printf("[moldyn] WARNING: unknown defect\n");\
+                               break;\
+               }\
+               v3_add(&dr,&pos,&d_o);\
+               v3_copy(&(atom[count].r),&dr);\
+               count+=1;\
+               v3_add(&dr,&pos,&d_d);\
+               v3_copy(&(atom[count].r),&dr);\
+               count+=1;\
+       }\
+       else {\
+               v3_copy(&(atom[count].r),&pos);\
+               count+=1;\
+       }
+
 /* cubic init */
-int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
+int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin,
+               t_part_params *p_params,t_defect_params *d_params) {
 
        int count;
        t_3dvec r;
        int i,j,k;
        t_3dvec o;
+       t_3dvec dist;
+       t_3dvec p;
+       t_3dvec d_o;
+       t_3dvec d_d;
+       t_3dvec dr;
+
+       p.x=0; p.y=0; p.z=0;
 
        count=0;
        if(origin)
@@ -654,14 +866,54 @@ int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
        else
                v3_zero(&o);
 
+       /* shift partition values */
+       if(p_params->type) {
+               p.x=p_params->p.x+(a*lc)/2.0;
+               p.y=p_params->p.y+(b*lc)/2.0;
+               p.z=p_params->p.z+(c*lc)/2.0;
+       }
+
        r.x=o.x;
        for(i=0;i<a;i++) {
                r.y=o.y;
                for(j=0;j<b;j++) {
                        r.z=o.z;
                        for(k=0;k<c;k++) {
-                               v3_copy(&(atom[count].r),&r);
-                               count+=1;
+                               switch(p_params->type) {
+                                       case PART_INSIDE_R:
+                                               v3_sub(&dist,&r,&p);
+                       if(v3_absolute_square(&dist)<
+                           (p_params->r*p_params->r)) {
+                               set_atom_positions(r);
+                       }
+                                               break;
+                                       case PART_OUTSIDE_R:
+                                               v3_sub(&dist,&r,&p);
+                       if(v3_absolute_square(&dist)>=
+                           (p_params->r*p_params->r)) {
+                               set_atom_positions(r);
+                       }
+                                               break;
+                                       case PART_INSIDE_D:
+                                               v3_sub(&dist,&r,&p);
+                       if((fabs(dist.x)<p_params->d.x)&&
+                          (fabs(dist.y)<p_params->d.y)&&
+                          (fabs(dist.z)<p_params->d.z)) {
+                               set_atom_positions(r);
+                       }
+                                               break;
+                                       case PART_OUTSIDE_D:
+                                               v3_sub(&dist,&r,&p);
+                       if((fabs(dist.x)>=p_params->d.x)||
+                          (fabs(dist.y)>=p_params->d.y)||
+                          (fabs(dist.z)>=p_params->d.z)) {
+                               set_atom_positions(r);
+                       }
+                                               break;
+                                       default:        
+                                               set_atom_positions(r);
+                                               break;
+                               }
                                r.z+=lc;
                        }
                        r.y+=lc;
@@ -679,12 +931,18 @@ int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
 }
 
 /* fcc lattice init */
-int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
+int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin,
+             t_part_params *p_params,t_defect_params *d_params) {
 
        int count;
        int i,j,k,l;
        t_3dvec o,r,n;
        t_3dvec basis[3];
+       t_3dvec dist;
+       t_3dvec p;
+       t_3dvec d_d,d_o,dr;
+
+       p.x=0; p.y=0; p.z=0;
 
        count=0;
        if(origin)
@@ -701,6 +959,13 @@ int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
        basis[2].y=0.5*lc;
        basis[2].z=0.5*lc;
 
+       /* shift partition values */
+       if(p_params->type) {
+               p.x=p_params->p.x+(a*lc)/2.0;
+               p.y=p_params->p.y+(b*lc)/2.0;
+               p.z=p_params->p.z+(c*lc)/2.0;
+       }
+
        /* fill up the room */
        r.x=o.x;
        for(i=0;i<a;i++) {
@@ -709,15 +974,81 @@ int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
                        r.z=o.z;
                        for(k=0;k<c;k++) {
                                /* first atom */
-                               v3_copy(&(atom[count].r),&r);
-                               count+=1;
-                               r.z+=lc;
+                               switch(p_params->type) {
+                                       case PART_INSIDE_R:
+                                               v3_sub(&dist,&r,&p);
+                       if(v3_absolute_square(&dist)<
+                          (p_params->r*p_params->r)) {
+                               set_atom_positions(r);
+                       }
+                                               break;
+                                       case PART_OUTSIDE_R:
+                                               v3_sub(&dist,&r,&p);
+                       if(v3_absolute_square(&dist)>=
+                          (p_params->r*p_params->r)) {
+                               set_atom_positions(r);
+                       }
+                                               break;
+                                       case PART_INSIDE_D:
+                                               v3_sub(&dist,&r,&p);
+                       if((fabs(dist.x)<p_params->d.x)&&
+                          (fabs(dist.y)<p_params->d.y)&&
+                          (fabs(dist.z)<p_params->d.z)) {
+                               set_atom_positions(r);
+                       }
+                                               break;
+                                       case PART_OUTSIDE_D:
+                                               v3_sub(&dist,&r,&p);
+                       if((fabs(dist.x)>=p_params->d.x)||
+                          (fabs(dist.y)>=p_params->d.y)||
+                          (fabs(dist.z)>=p_params->d.z)) {
+                               set_atom_positions(r);
+                       }
+                                               break;
+                                       default:
+                                               set_atom_positions(r);
+                                               break;
+                               }
                                /* the three face centered atoms */
                                for(l=0;l<3;l++) {
                                        v3_add(&n,&r,&basis[l]);
-                                       v3_copy(&(atom[count].r),&n);
-                                       count+=1;
+                                       switch(p_params->type) {
+                                               case PART_INSIDE_R:
+                       v3_sub(&dist,&n,&p);
+                       if(v3_absolute_square(&dist)<
+                          (p_params->r*p_params->r)) {
+                               set_atom_positions(n);
+                       }
+                                                       break;
+                                               case PART_OUTSIDE_R:
+                       v3_sub(&dist,&n,&p);
+                       if(v3_absolute_square(&dist)>=
+                          (p_params->r*p_params->r)) {
+                               set_atom_positions(n);
+                       }
+                                                       break;
+                                       case PART_INSIDE_D:
+                                               v3_sub(&dist,&n,&p);
+                       if((fabs(dist.x)<p_params->d.x)&&
+                          (fabs(dist.y)<p_params->d.y)&&
+                          (fabs(dist.z)<p_params->d.z)) {
+                               set_atom_positions(n);
+                       }
+                                               break;
+                                       case PART_OUTSIDE_D:
+                                               v3_sub(&dist,&n,&p);
+                       if((fabs(dist.x)>=p_params->d.x)||
+                          (fabs(dist.y)>=p_params->d.y)||
+                          (fabs(dist.z)>=p_params->d.z)) {
+                               set_atom_positions(n);
+                       }
+                                               break;
+                                               default:
+                                                       set_atom_positions(n);
+                                                       break;
+                                       }
                                }
+                               r.z+=lc;
                        }
                        r.y+=lc;
                }
@@ -734,12 +1065,13 @@ int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
        return count;
 }
 
-int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
+int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin,
+                 t_part_params *p_params,t_defect_params *d_params) {
 
        int count;
        t_3dvec o;
 
-       count=fcc_init(a,b,c,lc,atom,origin);
+       count=fcc_init(a,b,c,lc,atom,origin,p_params,d_params);
 
        o.x=0.25*lc;
        o.y=0.25*lc;
@@ -747,7 +1079,7 @@ int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
 
        if(origin) v3_add(&o,&o,origin);
 
-       count+=fcc_init(a,b,c,lc,&atom[count],&o);
+       count+=fcc_init(a,b,c,lc,&atom[count],&o,p_params,d_params);
 
        return count;
 }
@@ -825,7 +1157,9 @@ double temperature_calc(t_moldyn *moldyn) {
 
        /* assume up to date kinetic energy, which is 3/2 N k_B T */
 
-       moldyn->t=(2.0*moldyn->ekin)/(3.0*K_BOLTZMANN*moldyn->count);
+       if(moldyn->count)
+               moldyn->t=(2.0*moldyn->ekin)/(3.0*K_BOLTZMANN*moldyn->count);
+       else moldyn->t=0.0;
 
        return moldyn->t;
 }
@@ -879,7 +1213,7 @@ int scale_velocity(t_moldyn *moldyn,u8 equi_init) {
                scale*=2.0;
        else
                if(moldyn->pt_scale&T_SCALE_BERENDSEN)
-                       scale=1.0+(scale-1.0)/moldyn->t_tc;
+                       scale=1.0+(scale-1.0)*moldyn->tau/moldyn->t_tc;
        scale=sqrt(scale);
 
        /* velocity scaling */
@@ -925,8 +1259,8 @@ double virial_sum(t_moldyn *moldyn) {
        }
 
        /* global virial (absolute coordinates) */
-       virial=&(moldyn->gvir);
-       moldyn->gv=virial->xx+virial->yy+virial->zz;
+       //virial=&(moldyn->gvir);
+       //moldyn->gv=virial->xx+virial->yy+virial->zz;
 
        return moldyn->virial;
 }
@@ -947,9 +1281,16 @@ double pressure_calc(t_moldyn *moldyn) {
        moldyn->p=2.0*moldyn->ekin+moldyn->virial;
        moldyn->p/=(3.0*moldyn->volume);
 
+       //moldyn->px=2.0*moldyn->ekinx+moldyn->vir.xx;
+       //moldyn->px/=moldyn->volume;
+       //moldyn->py=2.0*moldyn->ekiny+moldyn->vir.yy;
+       //moldyn->py/=moldyn->volume;
+       //moldyn->pz=2.0*moldyn->ekinz+moldyn->vir.zz;
+       //moldyn->pz/=moldyn->volume;
+
        /* pressure (absolute coordinates) */
-       moldyn->gp=2.0*moldyn->ekin+moldyn->gv;
-       moldyn->gp/=(3.0*moldyn->volume);
+       //moldyn->gp=2.0*moldyn->ekin+moldyn->gv;
+       //moldyn->gp/=(3.0*moldyn->volume);
 
        return moldyn->p;
 }
@@ -974,11 +1315,11 @@ int average_reset(t_moldyn *moldyn) {
 
        /* virial */
        moldyn->virial_sum=0.0;
-       moldyn->gv_sum=0.0;
+       //moldyn->gv_sum=0.0;
 
        /* pressure */
        moldyn->p_sum=0.0;
-       moldyn->gp_sum=0.0;
+       //moldyn->gp_sum=0.0;
        moldyn->tp_sum=0.0;
 
        return 0;
@@ -1016,14 +1357,14 @@ int average_and_fluctuation_calc(t_moldyn *moldyn) {
        /* virial */
        moldyn->virial_sum+=moldyn->virial;
        moldyn->virial_avg=moldyn->virial_sum/denom;
-       moldyn->gv_sum+=moldyn->gv;
-       moldyn->gv_avg=moldyn->gv_sum/denom;
+       //moldyn->gv_sum+=moldyn->gv;
+       //moldyn->gv_avg=moldyn->gv_sum/denom;
 
        /* pressure */
        moldyn->p_sum+=moldyn->p;
        moldyn->p_avg=moldyn->p_sum/denom;
-       moldyn->gp_sum+=moldyn->gp;
-       moldyn->gp_avg=moldyn->gp_sum/denom;
+       //moldyn->gp_sum+=moldyn->gp;
+       //moldyn->gp_avg=moldyn->gp_sum/denom;
        moldyn->tp_sum+=moldyn->tp;
        moldyn->tp_avg=moldyn->tp_sum/denom;
 
@@ -1177,11 +1518,40 @@ int scale_atoms(t_moldyn *moldyn,u8 dir,double scale,u8 x,u8 y,u8 z) {
        return 0;
 }
 
+int scale_atoms_ind(t_moldyn *moldyn,double x,double y,double z) {
+
+       int i;
+       t_3dvec *r;
+
+       for(i=0;i<moldyn->count;i++) {
+               r=&(moldyn->atom[i].r);
+               r->x*=x;
+               r->y*=y;
+               r->z*=z;
+       }
+
+       return 0;
+}
+
+int scale_dim_ind(t_moldyn *moldyn,double x,double y,double z) {
+
+       t_3dvec *dim;
+
+       dim=&(moldyn->dim);
+
+       dim->x*=x;
+       dim->y*=y;
+       dim->z*=z;
+
+       return 0;
+}
+
 int scale_volume(t_moldyn *moldyn) {
 
        t_3dvec *dim,*vdim;
        double scale;
        t_linkcell *lc;
+       //double sx,sy,sz;
 
        vdim=&(moldyn->vis.dim);
        dim=&(moldyn->dim);
@@ -1189,16 +1559,28 @@ int scale_volume(t_moldyn *moldyn) {
 
        /* scaling factor */
        if(moldyn->pt_scale&P_SCALE_BERENDSEN) {
-               scale=1.0-(moldyn->p_ref-moldyn->p)*moldyn->p_tc;
+               scale=1.0-(moldyn->p_ref-moldyn->p)*moldyn->p_tc*moldyn->tau;
                scale=pow(scale,ONE_THIRD);
        }
        else {
                scale=pow(moldyn->p/moldyn->p_ref,ONE_THIRD);
        }
 
+
+       /*      
+       sx=1.0-(moldyn->p_ref-moldyn->px)*moldyn->p_tc*moldyn->tau;
+       sy=1.0-(moldyn->p_ref-moldyn->py)*moldyn->p_tc*moldyn->tau;
+       sz=1.0-(moldyn->p_ref-moldyn->pz)*moldyn->p_tc*moldyn->tau;
+       sx=pow(sx,ONE_THIRD);
+       sy=pow(sy,ONE_THIRD);
+       sz=pow(sz,ONE_THIRD);
+       */
+
        /* scale the atoms and dimensions */
        scale_atoms(moldyn,SCALE_DIRECT,scale,TRUE,TRUE,TRUE);
        scale_dim(moldyn,SCALE_DIRECT,scale,TRUE,TRUE,TRUE);
+       //scale_atoms_ind(moldyn,sx,sy,sz);
+       //scale_dim_ind(moldyn,sx,sy,sz);
 
        /* visualize dimensions */
        if(vdim->x!=0) {
@@ -1220,6 +1602,9 @@ int scale_volume(t_moldyn *moldyn) {
                lc->x*=scale;
                lc->y*=scale;
                lc->z*=scale;
+               //lc->x*=sx;
+               //lc->y*=sx;
+               //lc->z*=sy;
        }
 
        return 0;
@@ -1233,10 +1618,16 @@ double e_kin_calc(t_moldyn *moldyn) {
 
        atom=moldyn->atom;
        moldyn->ekin=0.0;
+       //moldyn->ekinx=0.0;
+       //moldyn->ekiny=0.0;
+       //moldyn->ekinz=0.0;
 
        for(i=0;i<moldyn->count;i++) {
                atom[i].ekin=0.5*atom[i].mass*v3_absolute_square(&(atom[i].v));
                moldyn->ekin+=atom[i].ekin;
+               //moldyn->ekinx+=0.5*atom[i].mass*atom[i].v.x*atom[i].v.x;
+               //moldyn->ekiny+=0.5*atom[i].mass*atom[i].v.y*atom[i].v.y;
+               //moldyn->ekinz+=0.5*atom[i].mass*atom[i].v.z*atom[i].v.z;
        }
 
        return moldyn->ekin;
@@ -1284,7 +1675,9 @@ double estimate_time_step(t_moldyn *moldyn,double nn_dist) {
 int link_cell_init(t_moldyn *moldyn,u8 vol) {
 
        t_linkcell *lc;
+#ifndef LOWMEM_LISTS
        int i;
+#endif
 
        lc=&(moldyn->lc);
 
@@ -1299,6 +1692,8 @@ int link_cell_init(t_moldyn *moldyn,u8 vol) {
 
 #ifdef STATIC_LISTS
        lc->subcell=malloc(lc->cells*sizeof(int*));
+#elif LOWMEM_LISTS
+       lc->subcell=malloc(sizeof(t_lowmem_list));
 #else
        lc->subcell=malloc(lc->cells*sizeof(t_list));
 #endif
@@ -1309,12 +1704,16 @@ int link_cell_init(t_moldyn *moldyn,u8 vol) {
        }
 
        if(lc->cells<27)
-               printf("[moldyn] FATAL: less then 27 subcells!\n");
+               printf("[moldyn] FATAL: less then 27 subcells! (%d)\n",
+                       lc->cells);
 
        if(vol) {
 #ifdef STATIC_LISTS
                printf("[moldyn] initializing 'static' linked cells (%d)\n",
                       lc->cells);
+#elif LOWMEM_LISTS
+               printf("[moldyn] initializing 'lowmem' linked cells (%d)\n",
+                      lc->cells);
 #else
                printf("[moldyn] initializing 'dynamic' linked cells (%d)\n",
                       lc->cells);
@@ -1338,6 +1737,17 @@ int link_cell_init(t_moldyn *moldyn,u8 vol) {
                               i,lc->subcell[0],lc->subcell);
                */
        }
+#elif LOWMEM_LISTS
+       lc->subcell->head=malloc(lc->cells*sizeof(int));
+       if(lc->subcell->head==NULL) {
+               perror("[moldyn] head init (malloc)");
+               return -1;
+       }
+       lc->subcell->list=malloc(moldyn->count*sizeof(int));
+       if(lc->subcell->list==NULL) {
+               perror("[moldyn] list init (malloc)");
+               return -1;
+       }
 #else
        for(i=0;i<lc->cells;i++)
                list_init_f(&(lc->subcell[i]));
@@ -1352,22 +1762,26 @@ int link_cell_init(t_moldyn *moldyn,u8 vol) {
 int link_cell_update(t_moldyn *moldyn) {
 
        int count,i,j,k;
-       int nx,ny;
+       int nx,nxy;
        t_atom *atom;
        t_linkcell *lc;
 #ifdef STATIC_LISTS
        int p;
+#elif LOWMEM_LISTS
+       int p;
 #endif
 
        atom=moldyn->atom;
        lc=&(moldyn->lc);
 
        nx=lc->nx;
-       ny=lc->ny;
+       nxy=nx*lc->ny;
 
        for(i=0;i<lc->cells;i++)
 #ifdef STATIC_LISTS
-               memset(lc->subcell[i],0,(MAX_ATOMS_PER_LIST+1)*sizeof(int));
+               memset(lc->subcell[i],-1,(MAX_ATOMS_PER_LIST+1)*sizeof(int));
+#elif LOWMEM_LISTS
+               lc->subcell->head[i]=-1;
 #else
                list_destroy_f(&(lc->subcell[i]));
 #endif
@@ -1379,7 +1793,7 @@ int link_cell_update(t_moldyn *moldyn) {
        
 #ifdef STATIC_LISTS
                p=0;
-               while(lc->subcell[i+j*nx+k*nx*ny][p]!=0)
+               while(lc->subcell[i+j*nx+k*nxy][p]!=-1)
                        p++;
 
                if(p>=MAX_ATOMS_PER_LIST) {
@@ -1387,9 +1801,13 @@ int link_cell_update(t_moldyn *moldyn) {
                        return -1;
                }
 
-               lc->subcell[i+j*nx+k*nx*ny][p]=count;
+               lc->subcell[i+j*nx+k*nxy][p]=count;
+#elif LOWMEM_LISTS
+               p=i+j*nx+k*nxy;
+               lc->subcell->list[count]=lc->subcell->head[p];
+               lc->subcell->head[p]=count;
 #else
-               list_add_immediate_f(&(lc->subcell[i+j*nx+k*nx*ny]),
+               list_add_immediate_f(&(lc->subcell[i+j*nx+k*nxy]),
                                     &(atom[count]));
                /*
                if(j==0&&k==0)
@@ -1405,6 +1823,8 @@ int link_cell_update(t_moldyn *moldyn) {
 int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,
 #ifdef STATIC_LISTS
                               int **cell
+#elif LOWMEM_LISTS
+                              int *cell
 #else
                               t_list *cell
 #endif
@@ -1430,7 +1850,11 @@ int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,
                printf("[moldyn] WARNING: lcni %d/%d %d/%d %d/%d\n",
                       i,nx,j,ny,k,nz);
 
+#ifndef LOWMEM_LISTS
        cell[0]=lc->subcell[i+j*nx+k*a];
+#else
+       cell[0]=lc->subcell->head[i+j*nx+k*a];
+#endif
        for(ci=-1;ci<=1;ci++) {
                bx=0;
                x=i+ci;
@@ -1454,10 +1878,19 @@ int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,
                                }
                                if(!(ci|cj|ck)) continue;
                                if(bx|by|bz) {
+#ifndef LOWMEM_LISTS
                                        cell[--count2]=lc->subcell[x+y*nx+z*a];
+#else
+                               cell[--count2]=lc->subcell->head[x+y*nx+z*a];
+#endif
+                                       
                                }
                                else {
+#ifndef LOWMEM_LISTS
                                        cell[count1++]=lc->subcell[x+y*nx+z*a];
+#else
+                               cell[count1++]=lc->subcell->head[x+y*nx+z*a];
+#endif
                                }
                        }
                }
@@ -1470,11 +1903,19 @@ int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,
 
 int link_cell_shutdown(t_moldyn *moldyn) {
 
+#ifndef LOWMEM_LISTS
        int i;
+#endif
        t_linkcell *lc;
 
        lc=&(moldyn->lc);
 
+#if LOWMEM_LISTS
+       free(lc->subcell->head);
+       free(lc->subcell->list);
+
+#else
+
        for(i=0;i<lc->cells;i++) {
 #ifdef STATIC_LISTS
                free(lc->subcell[i]);
@@ -1483,6 +1924,7 @@ int link_cell_shutdown(t_moldyn *moldyn) {
                list_destroy_f(&(lc->subcell[i]));
 #endif
        }
+#endif
 
        free(lc->subcell);
 
@@ -1551,6 +1993,17 @@ int moldyn_integrate(t_moldyn *moldyn) {
        struct timeval t1,t2;
        //double tp;
 
+#ifdef VISUAL_THREAD
+       u8 first,change;
+       pthread_t io_thread;
+       int ret;
+       t_moldyn md_copy;
+       t_atom *atom_copy;
+
+       first=1;
+       change=0;
+#endif
+
        sched=&(moldyn->schedule);
        atom=moldyn->atom;
 
@@ -1585,9 +2038,11 @@ int moldyn_integrate(t_moldyn *moldyn) {
                printf("[moldyn] WARNING: cutoff > 0.5 x dim.y\n");
        if(moldyn->cutoff>0.5*moldyn->dim.z)
                printf("[moldyn] WARNING: cutoff > 0.5 x dim.z\n");
-       ds=0.5*atom[0].f.x*moldyn->tau_square/atom[0].mass;
-       if(ds>0.05*moldyn->nnd)
+       if(moldyn->count) {
+               ds=0.5*atom[0].f.x*moldyn->tau_square/atom[0].mass;
+               if(ds>0.05*moldyn->nnd)
                printf("[moldyn] WARNING: forces too high / tau too small!\n");
+       }
 
        /* zero absolute time */
        // should have right values!
@@ -1597,6 +2052,21 @@ int moldyn_integrate(t_moldyn *moldyn) {
        /* debugging, ignore */
        moldyn->debug=0;
 
+       /* zero & init moldyn copy */
+#ifdef VISUAL_THREAD
+       memset(&md_copy,0,sizeof(t_moldyn));
+       atom_copy=malloc(moldyn->count*sizeof(t_atom));
+       if(atom_copy==NULL) {
+               perror("[moldyn] malloc atom copy (init)");
+               return -1;
+       }
+#endif
+
+#ifdef PTHREADS
+       printf("##################\n");
+       printf("# USING PTHREADS #\n");
+       printf("##################\n");
+#endif
        /* tell the world */
        printf("[moldyn] integration start, go get a coffee ...\n");
 
@@ -1624,11 +2094,11 @@ int moldyn_integrate(t_moldyn *moldyn) {
                temperature_calc(moldyn);
                virial_sum(moldyn);
                pressure_calc(moldyn);
-               /*
+#ifdef PDEBUG  
                thermodynamic_pressure_calc(moldyn);
                printf("\n\nDEBUG: numeric pressure calc: %f\n\n",
                       moldyn->tp/BAR);
-               */
+#endif
 
                /* calculate fluctuations + averages */
                average_and_fluctuation_calc(moldyn);
@@ -1643,10 +2113,11 @@ int moldyn_integrate(t_moldyn *moldyn) {
                if(e) {
                        if(!(moldyn->total_steps%e))
                                dprintf(moldyn->efd,
-                                       "%f %f %f %f\n",
+                                       "%f %f %f %f %f %f\n",
                                        moldyn->time,moldyn->ekin/energy_scale,
                                        moldyn->energy/energy_scale,
-                                       get_total_energy(moldyn)/energy_scale);
+                                       get_total_energy(moldyn)/energy_scale,
+                                       moldyn->ekin/EV,moldyn->energy/EV);
                }
                if(m) {
                        if(!(moldyn->total_steps%m)) {
@@ -1662,7 +2133,7 @@ int moldyn_integrate(t_moldyn *moldyn) {
                                dprintf(moldyn->pfd,
                                        "%f %f %f %f %f %f %f\n",moldyn->time,
                                         moldyn->p/BAR,moldyn->p_avg/BAR,
-                                        moldyn->gp/BAR,moldyn->gp_avg/BAR,
+                                        moldyn->p/BAR,moldyn->p_avg/BAR,
                                         moldyn->tp/BAR,moldyn->tp_avg/BAR);
                        }
                }
@@ -1676,12 +2147,16 @@ int moldyn_integrate(t_moldyn *moldyn) {
                if(v) {
                        if(!(moldyn->total_steps%v)) {
                                dprintf(moldyn->vfd,
-                                       "%f %f\n",moldyn->time,moldyn->volume);
+                                       "%f %f %f %f %f\n",moldyn->time,
+                                                          moldyn->volume,
+                                                          moldyn->dim.x,
+                                                          moldyn->dim.y,
+                                                          moldyn->dim.z);
                        }
                }
                if(s) {
                        if(!(moldyn->total_steps%s)) {
-                               snprintf(dir,128,"%s/s-%07.f.save",
+                               snprintf(dir,128,"%s/s-%08.f.save",
                                         moldyn->vlsdir,moldyn->time);
                                fd=open(dir,O_WRONLY|O_TRUNC|O_CREAT,
                                        S_IRUSR|S_IWUSR);
@@ -1696,20 +2171,54 @@ int moldyn_integrate(t_moldyn *moldyn) {
                }
                if(a) {
                        if(!(moldyn->total_steps%a)) {
+#ifdef VISUAL_THREAD
+       /* check whether thread has not terminated yet */
+       if(!first) {
+               ret=pthread_join(io_thread,NULL);
+       }
+       first=0;
+       /* prepare and start thread */
+       if(moldyn->count!=md_copy.count) {
+               free(atom_copy);
+               change=1;
+       }
+       memcpy(&md_copy,moldyn,sizeof(t_moldyn));
+       if(change) {
+               atom_copy=malloc(moldyn->count*sizeof(t_atom));
+               if(atom_copy==NULL) {
+                       perror("[moldyn] malloc atom copy (change)");
+                       return -1;
+               }
+       }
+       md_copy.atom=atom_copy;
+       memcpy(atom_copy,moldyn->atom,moldyn->count*sizeof(t_atom));
+       change=0;
+       ret=pthread_create(&io_thread,NULL,visual_atoms,&md_copy);
+       if(ret) {
+               perror("[moldyn] create visual atoms thread\n");
+               return -1;
+       }
+#else
                                visual_atoms(moldyn);
+#endif
                        }
                }
 
                /* display progress */
-               //if(!(moldyn->total_steps%10)) {
+#ifndef PDEBUG
+               if(!(i%10)) {
+#endif
                        /* get current time */
                        gettimeofday(&t2,NULL);
 
-printf("\rsched:%d, steps:%d/%d, T:%4.1f/%4.1f P:%4.1f/%4.1f V:%6.1f (%d)",
+printf("sched:%d, steps:%d/%d, T:%4.1f/%4.1f P:%4.1f/%4.1f V:%6.1f (%d)\n",
        sched->count,i,moldyn->total_steps,
        moldyn->t,moldyn->t_avg,
+#ifndef PDEBUG
        moldyn->p/BAR,moldyn->p_avg/BAR,
-       //moldyn->p/BAR,(moldyn->p-2.0*moldyn->ekin/(3.0*moldyn->volume))/BAR,
+#else
+       moldyn->p/BAR,(moldyn->p-2.0*moldyn->ekin/(3.0*moldyn->volume))/BAR,
+#endif
        moldyn->volume,
        (int)(t2.tv_sec-t1.tv_sec));
 
@@ -1717,7 +2226,9 @@ printf("\rsched:%d, steps:%d/%d, T:%4.1f/%4.1f P:%4.1f/%4.1f V:%6.1f (%d)",
 
                        /* copy over time */
                        t1=t2;
-               //}
+#ifndef PDEBUG
+               }
+#endif
 
                /* increase absolute time */
                moldyn->time+=moldyn->tau;
@@ -1738,6 +2249,59 @@ printf("\rsched:%d, steps:%d/%d, T:%4.1f/%4.1f P:%4.1f/%4.1f V:%6.1f (%d)",
 
        }
 
+       /* writing a final save file! */
+       if(s) {
+               snprintf(dir,128,"%s/s-final.save",moldyn->vlsdir);
+               fd=open(dir,O_WRONLY|O_TRUNC|O_CREAT,S_IRUSR|S_IWUSR);
+               if(fd<0) perror("[moldyn] save fd open");
+               else {
+                       write(fd,moldyn,sizeof(t_moldyn));
+                       write(fd,moldyn->atom,
+                             moldyn->count*sizeof(t_atom));
+               }
+               close(fd);
+       }
+       /* writing a final visual file! */
+       if(a)
+               visual_atoms(moldyn);
+
+       return 0;
+}
+
+/* basis trafo */
+
+#define FORWARD                0
+#define BACKWARD       1
+
+int basis_trafo(t_3dvec *r,u8 dir,double z,double x) {
+
+       t_3dvec tmp;
+
+       if(dir==FORWARD) {
+               if(z!=0.0) {
+                       v3_copy(&tmp,r);
+                       r->x=cos(z)*tmp.x-sin(z)*tmp.y;
+                       r->y=sin(z)*tmp.x+cos(z)*tmp.y;
+               }
+               if(x!=0.0) {
+                       v3_copy(&tmp,r);
+                       r->y=cos(x)*tmp.y-sin(x)*tmp.z;
+                       r->z=sin(x)*tmp.y+cos(x)*tmp.z;
+               }
+       }
+       else {
+               if(x!=0.0) {
+                       v3_copy(&tmp,r);
+                       r->y=cos(-x)*tmp.y-sin(-x)*tmp.z;
+                       r->z=sin(-x)*tmp.y+cos(-x)*tmp.z;
+               }
+               if(z!=0.0) {
+                       v3_copy(&tmp,r);
+                       r->x=cos(-z)*tmp.x-sin(-z)*tmp.y;
+                       r->y=sin(-z)*tmp.x+cos(-z)*tmp.y;
+               }
+       }
+
        return 0;
 }
 
@@ -1756,15 +2320,47 @@ int velocity_verlet(t_moldyn *moldyn) {
        tau_square=moldyn->tau_square;
 
        for(i=0;i<count;i++) {
+
                /* check whether fixed atom */
                if(atom[i].attr&ATOM_ATTR_FP)
                        continue;
+
                /* new positions */
                h=0.5/atom[i].mass;
+
+               /* constraint relaxation */
+               if(crtt) {
+                       // forces
+                       basis_trafo(&(atom[i].f),FORWARD,
+                                   trafo_angle[2*i],trafo_angle[2*i+1]);
+                       if(constraints[3*i])
+                               atom[i].f.x=0;
+                       if(constraints[3*i+1])
+                               atom[i].f.y=0;
+                       if(constraints[3*i+2])
+                               atom[i].f.z=0;
+                       basis_trafo(&(atom[i].f),BACKWARD,
+                                   trafo_angle[2*i],trafo_angle[2*i+1]);
+                       // velocities
+                       basis_trafo(&(atom[i].v),FORWARD,
+                                   trafo_angle[2*i],trafo_angle[2*i+1]);
+                       if(constraints[3*i])
+                               atom[i].v.x=0;
+                       if(constraints[3*i+1])
+                               atom[i].v.y=0;
+                       if(constraints[3*i+2])
+                               atom[i].v.z=0;
+                       basis_trafo(&(atom[i].v),BACKWARD,
+                                   trafo_angle[2*i],trafo_angle[2*i+1]);
+               }
+
+#ifndef QUENCH
                v3_scale(&delta,&(atom[i].v),tau);
                v3_add(&(atom[i].r),&(atom[i].r),&delta);
+#endif
                v3_scale(&delta,&(atom[i].f),h*tau_square);
                v3_add(&(atom[i].r),&(atom[i].r),&delta);
+               //check_per_bound_and_care_for_pbc(moldyn,&(atom[i]));
                check_per_bound(moldyn,&(atom[i].r));
 
                /* velocities [actually v(t+tau/2)] */
@@ -1779,12 +2375,47 @@ int velocity_verlet(t_moldyn *moldyn) {
        link_cell_update(moldyn);
 
        /* forces depending on chosen potential */
-       potential_force_calc(moldyn);
+#ifndef ALBE_FAST
+       // if albe, use albe force calc routine
+       //if(moldyn->func3b_j1==albe_mult_3bp_j1)
+       //      albe_potential_force_calc(moldyn);
+       //else
+               potential_force_calc(moldyn);
+#else
+       albe_potential_force_calc(moldyn);
+#endif
 
        for(i=0;i<count;i++) {
                /* check whether fixed atom */
                if(atom[i].attr&ATOM_ATTR_FP)
                        continue;
+
+               /* constraint relaxation */
+               if(crtt) {
+                       // forces
+                       basis_trafo(&(atom[i].f),FORWARD,
+                                   trafo_angle[2*i],trafo_angle[2*i+1]);
+                       if(constraints[3*i])
+                               atom[i].f.x=0;
+                       if(constraints[3*i+1])
+                               atom[i].f.y=0;
+                       if(constraints[3*i+2])
+                               atom[i].f.z=0;
+                       basis_trafo(&(atom[i].f),BACKWARD,
+                                   trafo_angle[2*i],trafo_angle[2*i+1]);
+                       // velocities
+                       basis_trafo(&(atom[i].v),FORWARD,
+                                   trafo_angle[2*i],trafo_angle[2*i+1]);
+                       if(constraints[3*i])
+                               atom[i].v.x=0;
+                       if(constraints[3*i+1])
+                               atom[i].v.y=0;
+                       if(constraints[3*i+2])
+                               atom[i].v.z=0;
+                       basis_trafo(&(atom[i].v),BACKWARD,
+                                   trafo_angle[2*i],trafo_angle[2*i+1]);
+               }
+
                /* again velocities [actually v(t+tau)] */
                v3_scale(&delta,&(atom[i].f),0.5*tau/atom[i].mass);
                v3_add(&(atom[i].v),&(atom[i].v),&delta);
@@ -1812,6 +2443,9 @@ int potential_force_calc(t_moldyn *moldyn) {
        int *neighbour_i[27];
        int p,q;
        t_atom *atom;
+#elif LOWMEM_LISTS
+       int neighbour_i[27];
+       int p,q;
 #else
        t_list neighbour_i[27];
        t_list neighbour_i2[27];
@@ -1834,6 +2468,10 @@ int potential_force_calc(t_moldyn *moldyn) {
        memset(&(moldyn->gvir),0,sizeof(t_virial));
 
        /* reset force, site energy and virial of every atom */
+#ifdef PARALLEL
+       i=omp_get_thread_num();
+       #pragma omp parallel for private(virial)
+#endif
        for(i=0;i<count;i++) {
 
                /* reset force */
@@ -1890,10 +2528,17 @@ int potential_force_calc(t_moldyn *moldyn) {
 #ifdef STATIC_LISTS
                                p=0;
 
-                               while(neighbour_i[j][p]!=0) {
+                               while(neighbour_i[j][p]!=-1) {
 
                                        jtom=&(atom[neighbour_i[j][p]]);
                                        p++;
+#elif LOWMEM_LISTS
+                               p=neighbour_i[j];
+
+                               while(p!=-1) {
+
+                                       jtom=&(itom[p]);
+                                       p=lc->subcell->list[p];
 #else
                                this=&(neighbour_i[j]);
                                list_reset_f(this);
@@ -1972,22 +2617,10 @@ int potential_force_calc(t_moldyn *moldyn) {
                                                                   bc_ik|bc_ij);
 #ifdef STATIC_LISTS
                                        }
-#else
-                                       } while(list_next_f(that)!=\
-                                               L_NO_NEXT_ELEMENT);
-#endif
-
-                               }
-
-                               /* finish of first j loop after first k loop */
-                               if(moldyn->func_j0e)
-                                       moldyn->func_j0e(moldyn,
-                                                        &(itom[i]),
-                                                        jtom,
-                                                        bc_ij);
-
 #ifdef STATIC_LISTS
                                }
+#elif LOWMEM_LISTS
+                               }
 #else
                                } while(list_next_f(this)!=L_NO_NEXT_ELEMENT);
 #endif
@@ -2000,6 +2633,15 @@ int potential_force_calc(t_moldyn *moldyn) {
                if(!(itom[i].attr&ATOM_ATTR_3BP))
                        continue;
 
+               /* copy the neighbour lists */
+#ifdef STATIC_LISTS
+               /* no copy needed for static lists */
+#elif LOWMEM_LISTS
+               /* no copy needed for lowmem lists */
+#else
+               memcpy(neighbour_i2,neighbour_i,27*sizeof(t_list));
+#endif
+
                /* second loop over atoms j */
                for(j=0;j<27;j++) {
 
@@ -2007,10 +2649,17 @@ int potential_force_calc(t_moldyn *moldyn) {
 #ifdef STATIC_LISTS
                        p=0;
 
-                       while(neighbour_i[j][p]!=0) {
+                       while(neighbour_i[j][p]!=-1) {
 
                                jtom=&(atom[neighbour_i[j][p]]);
                                p++;
+#elif LOWMEM_LISTS
+                               p=neighbour_i[j];
+
+                               while(p!=-1) {
+
+                                       jtom=&(itom[p]);
+                                       p=lc->subcell->list[p];
 #else
                        this=&(neighbour_i[j]);
                        list_reset_f(this);
@@ -2051,10 +2700,17 @@ int potential_force_calc(t_moldyn *moldyn) {
 #ifdef STATIC_LISTS
                                        q=0;
 
-                                       while(neighbour_i[j][q]!=0) {
+                                       while(neighbour_i[k][q]!=-1) {
 
                                                ktom=&(atom[neighbour_i[k][q]]);
                                                q++;
+#elif LOWMEM_LISTS
+                                       q=neighbour_i[k];
+
+                                       while(q!=-1) {
+
+                                               ktom=&(itom[q]);
+                                               q=lc->subcell->list[q];
 #else
                                        that=&(neighbour_i2[k]);
                                        list_reset_f(that);
@@ -2075,13 +2731,16 @@ int potential_force_calc(t_moldyn *moldyn) {
                                                if(ktom==&(itom[i]))
                                                        continue;
 
-                                               moldyn->func_j1_k0(moldyn,
-                                                                  &(itom[i]),
-                                                                  jtom,
-                                                                  ktom,
-                                                                  bc_ik|bc_ij);
+                                               moldyn->func3b_k1(moldyn,
+                                                                 &(itom[i]),
+                                                                 jtom,
+                                                                 ktom,
+                                                                 bc_ik|bc_ij);
+
 #ifdef STATIC_LISTS
                                        }
+#elif LOWMEM_LISTS
+                                       }
 #else
                                        } while(list_next_f(that)!=\
                                                L_NO_NEXT_ELEMENT);
@@ -2107,10 +2766,17 @@ int potential_force_calc(t_moldyn *moldyn) {
 #ifdef STATIC_LISTS
                                        q=0;
 
-                                       while(neighbour_i[j][q]!=0) {
+                                       while(neighbour_i[k][q]!=-1) {
 
                                                ktom=&(atom[neighbour_i[k][q]]);
                                                q++;
+#elif LOWMEM_LISTS
+                                       q=neighbour_i[k];
+
+                                       while(q!=-1) {
+
+                                               ktom=&(itom[q]);
+                                               q=lc->subcell->list[q];
 #else
                                        that=&(neighbour_i2[k]);
                                        list_reset_f(that);
@@ -2139,6 +2805,8 @@ int potential_force_calc(t_moldyn *moldyn) {
 
 #ifdef STATIC_LISTS
                                        }
+#elif LOWMEM_LISTS
+                                       }
 #else
                                        } while(list_next_f(that)!=\
                                                L_NO_NEXT_ELEMENT);
@@ -2156,6 +2824,8 @@ int potential_force_calc(t_moldyn *moldyn) {
                                }
 #ifdef STATIC_LISTS
                        }
+#elif LOWMEM_LISTS
+                       }
 #else
                        } while(list_next_f(this)!=L_NO_NEXT_ELEMENT);
 #endif
@@ -2182,6 +2852,9 @@ int potential_force_calc(t_moldyn *moldyn) {
 #endif
 
        /* some postprocessing */
+#ifdef PARALLEL
+       #pragma omp parallel for
+#endif
        for(i=0;i<count;i++) {
                /* calculate global virial */
                moldyn->gvir.xx+=itom[i].r.x*itom[i].f.x;
@@ -2193,7 +2866,7 @@ int potential_force_calc(t_moldyn *moldyn) {
 
                /* check forces regarding the given timestep */
                if(v3_norm(&(itom[i].f))>\
-                  0.1*moldyn->nnd*itom[i].mass/moldyn->tau_square)
+                   0.1*moldyn->nnd*itom[i].mass/moldyn->tau_square)
                        printf("[moldyn] WARNING: pfc (high force: atom %d)\n",
                               i);
        }
@@ -2250,6 +2923,51 @@ int check_per_bound(t_moldyn *moldyn,t_3dvec *a) {
        return 0;
 }
         
+int check_per_bound_and_care_for_pbc(t_moldyn *moldyn,t_atom *a) {
+       
+       double x,y,z;
+       t_3dvec *dim;
+
+       dim=&(moldyn->dim);
+
+       x=dim->x/2;
+       y=dim->y/2;
+       z=dim->z/2;
+
+       if(moldyn->status&MOLDYN_STAT_PBX) {
+               if(a->r.x>=x) {
+                       a->pbc[0]+=1;
+                       a->r.x-=dim->x;
+               }
+               else if(-a->r.x>x) {
+                       a->pbc[0]-=1;
+                       a->r.x+=dim->x;
+               }
+       }
+       if(moldyn->status&MOLDYN_STAT_PBY) {
+               if(a->r.y>=y) {
+                       a->pbc[1]+=1;
+                       a->r.y-=dim->y;
+               }
+               else if(-a->r.y>y) {
+                       a->pbc[1]-=1;
+                       a->r.y+=dim->y;
+               }
+       }
+       if(moldyn->status&MOLDYN_STAT_PBZ) {
+               if(a->r.z>=z) {
+                       a->pbc[2]+=1;
+                       a->r.z-=dim->z;
+               }
+               else if(-a->r.z>z) {
+                       a->pbc[2]-=1;
+                       a->r.z+=dim->z;
+               }
+       }
+
+       return 0;
+}
+        
 /*
  * debugging / critical check functions
  */
@@ -2340,7 +3058,7 @@ int moldyn_read_save_file(t_moldyn *moldyn,char *file) {
        if(fsize!=sizeof(t_moldyn)+size) {
                corr=fsize-sizeof(t_moldyn)-size;
                printf("[moldyn] WARNING: lsf (illegal file size)\n");
-               printf("  moifying offset:\n");
+               printf("  modifying offset:\n");
                printf("  - current pos: %d\n",sizeof(t_moldyn));
                printf("  - atom size: %d\n",size);
                printf("  - file size: %d\n",fsize);
@@ -2363,6 +3081,16 @@ int moldyn_read_save_file(t_moldyn *moldyn,char *file) {
                size-=cnt;
        }
 
+#ifdef PTHREADS
+       amutex=malloc(moldyn->count*sizeof(pthread_mutex_t));
+       if(amutex==NULL) {
+               perror("[moldyn] load save file (mutexes)");
+               return -1;
+       }
+       for(cnt=0;cnt<moldyn->count;cnt++)
+               pthread_mutex_init(&(amutex[cnt]),NULL);
+#endif
+
        // hooks etc ...
 
        return 0;
@@ -2394,13 +3122,16 @@ int process_2b_bonds(t_moldyn *moldyn,void *data,
 #ifdef STATIC_LISTS
        int *neighbour[27];
        int p;
+#elif LOWMEM_LISTS
+       int neighbour[27];
+       int p;
 #else
        t_list neighbour[27];
+       t_list *this;
 #endif
        u8 bc;
        t_atom *itom,*jtom;
        int i,j;
-       t_list *this;
 
        lc=&(moldyn->lc);
        itom=moldyn->atom;
@@ -2420,10 +3151,17 @@ int process_2b_bonds(t_moldyn *moldyn,void *data,
 #ifdef STATIC_LISTS
                        p=0;
 
-                       while(neighbour[j][p]!=0) {
+                       while(neighbour[j][p]!=-1) {
 
                                jtom=&(moldyn->atom[neighbour[j][p]]);
                                p++;
+#elif LOWMEM_LISTS
+                       p=neighbour[j];
+
+                       while(p!=-1) {
+
+                               jtom=&(itom[p]);
+                               p=lc->subcell->list[p];
 #else
                        this=&(neighbour[j]);
                        list_reset_f(this);
@@ -2441,6 +3179,8 @@ int process_2b_bonds(t_moldyn *moldyn,void *data,
 
 #ifdef STATIC_LISTS
                        }
+#elif LOWMEM_LISTS
+                       }
 #else
                        } while(list_next_f(this)!=L_NO_NEXT_ELEMENT);
 #endif
@@ -2451,6 +3191,84 @@ int process_2b_bonds(t_moldyn *moldyn,void *data,
 
 }
 
+/*
+ * function to find neighboured atoms
+ */
+
+int process_neighbours(t_moldyn *moldyn,void *data,t_atom *atom,
+                       int (*process)(t_moldyn *moldyn,t_atom *atom,t_atom *natom,
+                                     void *data,u8 bc)) {
+
+       t_linkcell *lc;
+#ifdef STATIC_LISTS
+       int *neighbour[27];
+       int p;
+#elif LOWMEM_LISTS
+       int neighbour[27];
+       int p;
+#else
+       t_list neighbour[27];
+       t_list *this;
+#endif
+       u8 bc;
+       t_atom *natom;
+       int j;
+
+       lc=&(moldyn->lc);
+       
+       /* neighbour indexing */
+       link_cell_neighbour_index(moldyn,
+                                 (atom->r.x+moldyn->dim.x/2)/lc->x,
+                                 (atom->r.y+moldyn->dim.y/2)/lc->x,
+                                 (atom->r.z+moldyn->dim.z/2)/lc->x,
+                                 neighbour);
+
+       for(j=0;j<27;j++) {
+
+               bc=(j<lc->dnlc)?0:1;
+
+#ifdef STATIC_LISTS
+               p=0;
+
+               while(neighbour[j][p]!=-1) {
+
+                       natom=&(moldyn->atom[neighbour[j][p]]);
+                       p++;
+#elif LOWMEM_LISTS
+               p=neighbour[j];
+
+               while(p!=-1) {
+
+                       natom=&(moldyn->atom[p]);
+                       p=lc->subcell->list[p];
+#else
+               this=&(neighbour[j]);
+               list_reset_f(this);
+
+               if(this->start==NULL)
+                       continue;
+
+               do {
+
+                       natom=this->current->data;
+#endif
+
+                       /* process bond */
+                       process(moldyn,atom,natom,data,bc);
+
+#ifdef STATIC_LISTS
+               }
+#elif LOWMEM_LISTS
+               }
+#else
+               } while(list_next_f(this)!=L_NO_NEXT_ELEMENT);
+#endif
+       }
+
+       return 0;
+
+}
+
 /*
  * post processing functions
  */
@@ -2485,6 +3303,7 @@ int calculate_diffusion_coefficient(t_moldyn *moldyn,double *dc) {
        int i;
        t_atom *atom;
        t_3dvec dist;
+       t_3dvec final_r;
        double d2;
        int a_cnt;
        int b_cnt;
@@ -2498,8 +3317,12 @@ int calculate_diffusion_coefficient(t_moldyn *moldyn,double *dc) {
 
        for(i=0;i<moldyn->count;i++) {
 
-               v3_sub(&dist,&(atom[i].r),&(atom[i].r_0));
-               check_per_bound(moldyn,&dist);
+               /* care for pb crossing */
+               final_r.x=atom[i].r.x+atom[i].pbc[0]*moldyn->dim.x;
+               final_r.y=atom[i].r.y+atom[i].pbc[1]*moldyn->dim.y;
+               final_r.z=atom[i].r.z+atom[i].pbc[2]*moldyn->dim.z;
+               /* calculate distance */
+               v3_sub(&dist,&final_r,&(atom[i].r_0));
                d2=v3_absolute_square(&dist);
 
                if(atom[i].brand) {
@@ -2521,6 +3344,57 @@ int calculate_diffusion_coefficient(t_moldyn *moldyn,double *dc) {
        return 0;
 }
 
+int calculate_msd(t_moldyn *moldyn,double *msd) {
+
+       int i;
+       t_atom *atom;
+       t_3dvec dist;
+       t_3dvec final_r;
+       double d2;
+       int a_cnt;
+       int b_cnt;
+
+       atom=moldyn->atom;
+       msd[0]=0;
+       msd[1]=0;
+       msd[2]=0;
+       a_cnt=0;
+       b_cnt=0;
+
+       for(i=0;i<moldyn->count;i++) {
+
+               /* care for pb crossing */
+               if(atom[i].pbc[0]|atom[i].pbc[1]|atom[i].pbc[2]) {
+                       printf("[moldyn] msd pb crossings for atom %d\n",i);
+                       printf("  x: %d y: %d z: %d\n",
+                              atom[i].pbc[0],atom[i].pbc[1],atom[i].pbc[2]);
+               }
+               final_r.x=atom[i].r.x+atom[i].pbc[0]*moldyn->dim.x;
+               final_r.y=atom[i].r.y+atom[i].pbc[1]*moldyn->dim.y;
+               final_r.z=atom[i].r.z+atom[i].pbc[2]*moldyn->dim.z;
+               /* calculate distance */
+               v3_sub(&dist,&final_r,&(atom[i].r_0));
+               d2=v3_absolute_square(&dist);
+
+               if(atom[i].brand) {
+                       b_cnt+=1;
+                       msd[1]+=d2;
+               }
+               else {
+                       a_cnt+=1;
+                       msd[0]+=d2;
+               }
+
+               msd[2]+=d2;
+       }
+
+       msd[0]/=a_cnt;
+       msd[1]/=b_cnt;
+       msd[2]/=moldyn->count;
+               
+       return 0;
+}
+
 int bonding_analyze(t_moldyn *moldyn,double *cnt) {
 
        return 0;
@@ -2666,9 +3540,8 @@ int bond_analyze_process(t_moldyn *moldyn,t_atom *itom,t_atom *jtom,
        ba=data;
 
        /* increase total bond counter
-        * ... double counting!
         */
-       ba->tcnt+=2;
+       ba->tcnt+=1;
 
        if(itom->brand==0)
                ba->acnt[jtom->tag]+=1;
@@ -2685,10 +3558,11 @@ int bond_analyze_process(t_moldyn *moldyn,t_atom *itom,t_atom *jtom,
 
 int bond_analyze(t_moldyn *moldyn,double *quality) {
 
-       // by now: # bonds of type 'a-4b' and 'b-4a' / # bonds total
-
-       int qcnt;
-       int ccnt,cset;
+       int qcnt4;
+       int qcnt3;
+       int ccnt4;
+       int ccnt3;
+       int bcnt;
        t_ba ba;
        int i;
        t_atom *atom;
@@ -2708,9 +3582,9 @@ int bond_analyze(t_moldyn *moldyn,double *quality) {
        memset(ba.bcnt,0,moldyn->count*sizeof(int));
 
        ba.tcnt=0;
-       qcnt=0;
-       ccnt=0;
-       cset=0;
+       qcnt4=0; qcnt3=0;
+       ccnt4=0; ccnt3=0;
+       bcnt=0;
 
        atom=moldyn->atom;
 
@@ -2719,27 +3593,30 @@ int bond_analyze(t_moldyn *moldyn,double *quality) {
        for(i=0;i<moldyn->count;i++) {
                if(atom[i].brand==0) {
                        if((ba.acnt[i]==0)&(ba.bcnt[i]==4))
-                               qcnt+=4;
+                               qcnt4+=4;
+                       if((ba.acnt[i]==0)&(ba.bcnt[i]==3))
+                               qcnt3+=3;
                }
                else {
                        if((ba.acnt[i]==4)&(ba.bcnt[i]==0)) {
-                               qcnt+=4;
-                               ccnt+=1;
+                               qcnt4+=4;
+                               ccnt4+=1;
+                       }
+                       if((ba.acnt[i]==3)&(ba.bcnt[i]==0)) {
+                               qcnt3+=4;
+                               ccnt3+=1;
                        }
-                       cset+=1;
+                       bcnt+=1;
                }
        }
 
-       printf("[moldyn] bond analyze: c_cnt=%d | set=%d\n",ccnt,cset);
-       printf("[moldyn] bond analyze: q_cnt=%d | tot=%d\n",qcnt,ba.tcnt);
-
        if(quality) {
-               quality[0]=1.0*ccnt/cset;
-               quality[1]=1.0*qcnt/ba.tcnt;
+               quality[0]=1.0*ccnt4/bcnt;
+               quality[1]=1.0*ccnt3/bcnt;
        }
        else {
-               printf("[moldyn] bond analyze: c_bnd_q=%f\n",1.0*qcnt/ba.tcnt);
-               printf("[moldyn] bond analyze:   tot_q=%f\n",1.0*qcnt/ba.tcnt);
+               printf("[moldyn] bond analyze: %f %f\n",
+                      1.0*ccnt4/bcnt,1.0*ccnt3/bcnt);
        }
 
        return 0;
@@ -2777,7 +3654,11 @@ int visual_bonds_process(t_moldyn *moldyn,t_atom *itom,t_atom *jtom,
        return 0;
 }
 
+#ifdef VISUAL_THREAD
+void *visual_atoms(void *ptr) {
+#else
 int visual_atoms(t_moldyn *moldyn) {
+#endif
 
        int i;
        char file[128+64];
@@ -2786,6 +3667,12 @@ int visual_atoms(t_moldyn *moldyn) {
        t_visual *v;
        t_atom *atom;
        t_vb vb;
+       t_3dvec strain;
+#ifdef VISUAL_THREAD
+       t_moldyn *moldyn;
+
+       moldyn=ptr;
+#endif
 
        v=&(moldyn->vis);
        dim.x=v->dim.x;
@@ -2795,31 +3682,39 @@ int visual_atoms(t_moldyn *moldyn) {
 
        help=(dim.x+dim.y);
 
-       sprintf(file,"%s/atomic_conf_%07.f.xyz",v->fb,moldyn->time);
+       sprintf(file,"%s/atomic_conf_%08.f.xyz",v->fb,moldyn->time);
        vb.fd=open(file,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
        if(vb.fd<0) {
                perror("open visual save file fd");
+#ifndef VISUAL_THREAD
                return -1;
+#endif
        }
 
        /* write the actual data file */
 
        // povray header
-       dprintf(vb.fd,"# [P] %d %07.f <%f,%f,%f>\n",
+       dprintf(vb.fd,"# [P] %d %08.f <%f,%f,%f>\n",
                moldyn->count,moldyn->time,help/40.0,help/40.0,-0.8*help);
 
        // atomic configuration
-       for(i=0;i<moldyn->count;i++)
+       for(i=0;i<moldyn->count;i++) {
+               v3_sub(&strain,&(atom[i].r),&(atom[i].r_0));
+               check_per_bound(moldyn,&strain);
                // atom type, positions, color and kinetic energy
                dprintf(vb.fd,"%s %f %f %f %s %f\n",pse_name[atom[i].element],
                                                    atom[i].r.x,
                                                    atom[i].r.y,
                                                    atom[i].r.z,
                                                    pse_col[atom[i].element],
-                                                   atom[i].ekin);
+                                                   //atom[i].ekin);
+                                                   sqrt(v3_absolute_square(&strain)));
+       }
        
        // bonds between atoms
+#ifndef VISUAL_THREAD
        process_2b_bonds(moldyn,&vb,visual_bonds_process);
+#endif
        
        // boundaries
        if(dim.x) {
@@ -2865,6 +3760,32 @@ int visual_atoms(t_moldyn *moldyn) {
 
        close(vb.fd);
 
+#ifdef VISUAL_THREAD
+       pthread_exit(NULL);
+
+}
+#else
+
+       return 0;
+}
+#endif
+
+/*
+ * fpu cntrol functions
+ */
+
+// set rounding to double (eliminates -ffloat-store!)
+int fpu_set_rtd(void) {
+
+       fpu_control_t ctrl;
+
+       _FPU_GETCW(ctrl);
+
+       ctrl&=~_FPU_EXTENDED;
+       ctrl|=_FPU_DOUBLE;
+
+       _FPU_SETCW(ctrl);
+
        return 0;
 }
 
index b2d6a34..0670f3d 100644 (file)
--- a/moldyn.h
+++ b/moldyn.h
@@ -45,6 +45,7 @@ typedef struct s_atom {
        u8 brand;               /* brand id */
        int tag;                /* atom unique id (number of atom) */
        u8 attr;                /* attributes */
+       int pbc[3];             /* pb crossing in x, y and z direction */
 } t_atom;
 
 #define ATOM_ATTR_FP   0x01    /* fixed position (bulk material) */
@@ -58,6 +59,12 @@ typedef struct s_atom {
 
 #define DEFAULT_ATOM_ATTR      0x74    // 1,2,3 body interaction + visualize
 
+/* special list structure for low mem approach */
+typedef struct s_lowmem_list {
+       int *head;
+       int *list;
+} t_lowmem_list;
+
 /* cell lists */
 typedef struct s_linkcell {
        int nx,ny,nz;           /* amount of cells in x, y and z direction */
@@ -66,6 +73,8 @@ typedef struct s_linkcell {
        double x,y,z;           /* the actual cell lengthes */
 #ifdef STATIC_LISTS
        int **subcell;          /* pointer to the cell lists */
+#elif LOWMEM_LISTS
+       t_lowmem_list *subcell; /* low mem approach list */
 #else
        t_list *subcell;        /* pointer to the cell lists */
 #endif
@@ -132,14 +141,22 @@ typedef struct s_moldyn {
        double t_sum;           /* sum over all t */
        double t_avg;           /* average value of t */
 
+       /* for sale! */
        t_virial gvir;          /* global virial (absolute coordinates) */
-       double gv;
-       double gv_sum;
-       double gv_avg;
-
-       double gp;              /* pressure computed from global virial */
-       double gp_sum;          /* sum over all gp */
-       double gp_avg;          /* average value of gp */
+       //double gv;
+       //double gv_sum;
+       //double gv_avg;
+       double sale1;
+       double sale2;
+       double sale3;
+
+       // gp stuff exchanged by kinetic energies
+       //double gp;            /* pressure computed from global virial */
+       //double gp_sum;                /* sum over all gp */
+       //double gp_avg;                /* average value of gp */
+       double ekinx;
+       double ekiny;
+       double ekinz;
 
        t_virial vir;           /* actual virial */
        double virial;
@@ -245,6 +262,43 @@ typedef struct s_vb {
        int fd;
 } t_vb;
 
+typedef struct s_part_params {
+       u8 type;
+       double r;
+       t_3dvec p;
+       t_3dvec d;
+} t_part_params;
+
+#define PART_INSIDE_R   1
+#define PART_OUTSIDE_R  2
+#define PART_INSIDE_D   3
+#define PART_OUTSIDE_D  4
+
+typedef struct s_defect_params {
+       u8 type;
+       u8 stype;
+       double od;
+       double dd;
+       int element;
+       u8 brand;
+       u8 attr;
+} t_defect_params;
+
+#define DEFECT_TYPE_0D 1
+#define DEFECT_TYPE_1D 2
+#define DEFECT_TYPE_2D 3
+#define DEFECT_TYPE_3D 4
+
+#define DEFECT_STYPE_DB_X      1
+#define DEFECT_STYPE_DB_Y      2
+#define DEFECT_STYPE_DB_Z      3
+#define DEFECT_STYPE_DB_R      4
+
+typedef struct s_offset_params {
+       t_3dvec o;
+       u8 use;
+} t_offset_params;
+
 /*
  *
  *  defines
@@ -356,12 +410,13 @@ typedef struct s_vb {
 #define FCC                    0x02
 #define DIAMOND                        0x04
 #define ZINCBLENDE             0x08
+#define NONE                   0x80
 
 /*
  * more includes
  */
 
-#include "pse.h"
+//#include "pse.h"
 
 /*
  *
@@ -391,14 +446,19 @@ int moldyn_set_report(t_moldyn *moldyn,char *author,char *title);
 int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer);
 int moldyn_log_shutdown(t_moldyn *moldyn);
 
-int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass,
-                   u8 attr,u8 brand,int a,int b,int c,t_3dvec *origin);
-int add_atom(t_moldyn *moldyn,int element,double mass,u8 brand,u8 attr,
+int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,
+                   u8 attr,u8 brand,int a,int b,int c,t_3dvec *origin,
+                   t_part_params *p_params,t_defect_params *d_params,
+                   t_offset_params *o_params);
+int add_atom(t_moldyn *moldyn,int element,u8 brand,u8 attr,
              t_3dvec *r,t_3dvec *v);
 int del_atom(t_moldyn *moldyn,int tag);
-int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin);
-int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin);
-int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin);
+int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin,
+               t_part_params *p_params,t_defect_params *d_params);
+int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin,
+             t_part_params *p_params,t_defect_params *d_params);
+int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin,
+                 t_part_params *p_params,t_defect_params *d_params);
 int destroy_atoms(t_moldyn *moldyn);
 
 int thermal_init(t_moldyn *moldyn,u8 equi_init);
@@ -427,6 +487,8 @@ int link_cell_init(t_moldyn *moldyn,u8 vol);
 int link_cell_update(t_moldyn *moldyn);
 #ifdef STATIC_LISTS
 int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,int **cell);
+#elif LOWMEM_LISTS
+int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,int *cell);
 #else
 int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,t_list *cell);
 #endif
@@ -445,6 +507,7 @@ int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d);
 //inline int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d)
 //     __attribute__((always_inline));
 int check_per_bound(t_moldyn *moldyn,t_3dvec *a);
+int check_per_bound_and_care_for_pbc(t_moldyn *moldyn,t_atom *a);
 //inline int check_per_bound(t_moldyn *moldyn,t_3dvec *a)
 //     __attribute__((always_inline));
 
@@ -456,10 +519,15 @@ int moldyn_load(t_moldyn *moldyn);
 int process_2b_bonds(t_moldyn *moldyn,void *data,
                      int (*process)(t_moldyn *moldyn,t_atom *itom,t_atom *jtom,
                                     void *data,u8 bc));
+int process_neighbours(t_moldyn *moldyn,void *data,t_atom *atom,
+                       int (*process)(t_moldyn *moldyn,t_atom *atom,t_atom *natom,
+                                      void *data,u8 bc));
+
 int get_line(int fd,char *line,int max);
 
 int pair_correlation_init(t_moldyn *moldyn,double dr);
 int calculate_diffusion_coefficient(t_moldyn *moldyn,double *dc);
+int calculate_msd(t_moldyn *moldyn,double *msd);
 int calculate_pair_correlation_process(t_moldyn *moldyn,t_atom *itom,
                                        t_atom *jtom,void *data,u8 bc);
 int calculate_pair_correlation(t_moldyn *moldyn,double dr,void *ptr);
@@ -470,7 +538,13 @@ int bond_analyze(t_moldyn *moldyn,double *quality);
 int visual_init(t_moldyn *moldyn,char *filebase);
 int visual_bonds_process(t_moldyn *moldyn,t_atom *itom,t_atom *jtom,
                          void *data,u8 bc);
+#ifdef VISUAL_THREAD
+void *visual_atoms(void *ptr);
+#else
 int visual_atoms(t_moldyn *moldyn);
+#endif
+
+int fpu_set_rtd(void);
 
 #endif
 
diff --git a/msd_calc.c b/msd_calc.c
new file mode 100644 (file)
index 0000000..80388d8
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * calculation of mean square displacement
+ *
+ * author: frank.zirkelbach@physik.uni-augsburg.de
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "moldyn.h"
+
+int usage(char *prog) {
+
+       printf("\nusage:\n");
+       printf("  %s <save file>\n\n",prog);
+
+       return -1;
+}
+
+int main(int argc,char **argv) {
+
+       t_moldyn moldyn;
+       int ret;
+       double msd[3];
+
+       if(argc!=2) {
+               usage(argv[0]);
+               return -1;
+       }
+
+       memset(&moldyn,0,sizeof(t_moldyn));
+
+       printf("[msd calc] reading save file ...\n");
+       ret=moldyn_read_save_file(&moldyn,argv[1]);
+       if(ret) {
+               printf("[msd calc] exit!\n");
+               return ret;
+       }
+
+       calculate_msd(&moldyn,msd);
+       
+       printf("MSD - %f ps: %.10f %.10f %.10f\n",moldyn.time,
+              msd[0],msd[1],msd[2]);
+
+       return 0;
+}
+
index 67ba32c..8006e1f 100755 (executable)
@@ -7,7 +7,7 @@
 
 do_it() {
        echo "processing $1 ..."
-       ./pair_correlation_calc $1 $2
+       ./pair_correlation_calc $2 $1
        trg=`echo $1 | sed 's%s-%pair_corr-%' | sed 's%.save%%'`
        mv pair_corr_func.txt $trg
        echo "done"
index efe81ad..26db76b 100644 (file)
@@ -19,7 +19,7 @@
 int usage(char *prog) {
 
        printf("\nusage:\n");
-       printf("  %s <save file> <dr>\n\n",prog);
+       printf("  %s <dr> <save file 1> [<save file 2> ...]\n\n",prog);
 
        return -1;
 }
@@ -28,56 +28,81 @@ int main(int argc,char **argv) {
 
        t_moldyn moldyn;
        int ret;
-       double *stat;
+       double *stat,*total;
        int slots;
-       int i;
+       int i,j;
        double dr;
        int fd;
+       unsigned char first;
 
-       if(argc!=3) {
+       if(argc<3) {
                usage(argv[0]);
                return -1;
        }
 
-       memset(&moldyn,0,sizeof(t_moldyn));
+       dr=atof(argv[1]);
+
+       first=1;
+       stat=NULL;
+       total=NULL;
+
+       for(j=2;j<argc;j++) {
+
+               memset(&moldyn,0,sizeof(t_moldyn));
+
+               printf("[pair corr calc] reading save file ...\n");
+               ret=moldyn_read_save_file(&moldyn,argv[j]);
+               if(ret) {
+                       printf("[pair corr calc] exit!\n");
+                       return ret;
+               }
+
+               //moldyn.cutoff*=2;
+               //moldyn.cutoff_square*=4;
+               moldyn.cutoff=6.0;
+               moldyn.cutoff_square=36.0;
+
+               slots=moldyn.cutoff/dr;
+               printf("[pair corr calc]\n");
+               printf("  slots: %d\n",slots);
+               printf("  cutoff: %f\n",moldyn.cutoff);
+               printf("  dr: %f\n",dr);
+
+               if(first) {
+                       stat=(double *)malloc(3*slots*sizeof(double));
+                       total=(double *)malloc(3*slots*sizeof(double));
+                       first=0;
+                       if(stat==NULL) {
+                               perror("[pair corr calc] alloc mem (stat)");
+                               return -1;
+                       }
+                       if(total==NULL) {
+                               perror("[pair corr calc] alloc mem (toal)");
+                               return -1;
+                       }
+                       memset(total,0,3*slots*sizeof(double));
+               }
+
+               /* link cell init */
+               link_cell_init(&moldyn,VERBOSE);
+
+               calculate_pair_correlation(&moldyn,dr,stat);
+
+               for(i=0;i<3*slots;i++)
+                       total[i]+=stat[i];
 
-       printf("[pair corr calc] reading save file ...\n");
-       ret=moldyn_read_save_file(&moldyn,argv[1]);
-       if(ret) {
-               printf("[pair corr calc] exit!\n");
-               return ret;
        }
 
-       moldyn.cutoff*=2;
-       moldyn.cutoff_square*=4;
-
-       dr=atof(argv[2]);
-       slots=moldyn.cutoff/dr;
-       printf("[pair corr calc]\n");
-       printf("  slots: %d\n",slots);
-       printf("  cutoff: %f\n",moldyn.cutoff);
-       printf("  dr: %f\n",dr);
-
-       stat=(double *)malloc(3*slots*sizeof(double));
-       if(stat==NULL) {
-               perror("[pair corr calc] alloc mem");
-               return -1;
-       }
-
-       /* link cell init */
-       link_cell_init(&moldyn,VERBOSE);
-
-       calculate_pair_correlation(&moldyn,dr,stat);
-
        fd=open("pair_corr_func.txt",
                O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
        dprintf(fd,"#r #ab #aa #bb\n");
        for(i=0;i<slots;i++)
                dprintf(fd,"%f %f %f %f\n",
-                       i*dr,stat[i],stat[slots+i],stat[2*slots+i]);
+                       i*dr,total[i],total[slots+i],total[2*slots+i]);
        close(fd);
 
        free(stat);
+       free(total);
 
        moldyn_free_save_file(&moldyn);
 
diff --git a/parcasconv b/parcasconv
new file mode 100755 (executable)
index 0000000..9f23771
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+#
+# convert parcas output to moldyn output
+# frank.zirkelbach@physik.uni-augsburg.de
+#
+
+if [ ! -f $1 ]; then
+        echo "no valid file"
+        exit 1
+fi
+
+if [ ! -d $2 ]; then
+        echo "no valid directory"
+        exit 1
+fi
+
+cat $1 | while read amount; do
+       read a b step time c d vol1 vol2 vol3
+       trgname="$2/atomic_conf_`printf "%07d" $step`.xyz"
+       echo "# [P] $amount $time <2.443050,2.443050,-78.177600>" > $trgname
+       ((cnt=0))
+       while read sort x y z type n; do
+               color="Yellow"
+               [ "$sort" = "C" ] && color="Gray"
+               echo "$sort $x $y $z $color 0.0" >> $trgname
+               ((cnt+=1))
+               [ "$cnt" = "$amount" ] && break
+       done
+done
+
index 9d8336e..9f98282 100644 (file)
@@ -105,6 +105,15 @@ int albe_mult_set_params(t_moldyn *moldyn,int element1,int element2) {
        p->S2[0]=p->S[0]*p->S[0];
        p->S2[1]=p->S[1]*p->S[1];
        p->S2mixed=p->Smixed*p->Smixed;
+       p->c2[0]=p->c[0]*p->c[0];
+       p->c2[1]=p->c[1]*p->c[1];
+       p->c2_mixed=p->c_mixed*p->c_mixed;
+       p->d2[0]=p->d[0]*p->d[0];
+       p->d2[1]=p->d[1]*p->d[1];
+       p->d2_mixed=p->d_mixed*p->d_mixed;
+       p->c2d2[0]=p->c2[0]/p->d2[0];
+       p->c2d2[1]=p->c2[1]/p->d2[1];
+       p->c2d2_m=p->c2_mixed/p->d2_mixed;
 
        printf("[albe] mult parameter info:\n");
        printf("  S (A)  | %f | %f | %f\n",p->S[0],p->S[1],p->Smixed);
@@ -301,40 +310,18 @@ int albe_mult_i0_j0_k0(t_moldyn *moldyn,
                dgk=*(exchange->gamma_[k])*2.0*frac_k*h_cos_k/d2_h_cos2_k;
        }
 
-       /* zeta - for albe: ik depending g function */
-//if(ai->tag==0) {
-//     printf("------> %.15f %.15f\n",dj,dk);
-//     printf("------> %.15f %.15f\n",dj,dk);
-//}
-
-       exchange->zeta[j]+=(exchange->f_c[k]*gk);
-       exchange->zeta[k]+=(exchange->f_c[j]*gj);
-
-       /* cos theta derivatives */
-       v3_scale(&dcosdrj,&distk,djdk_inv);             // j
-       v3_scale(&tmp,&distj,-cos_theta/exchange->d2[j]);
-       v3_add(&dcosdrj,&dcosdrj,&tmp);
-       v3_scale(&dcosdrk,&distj,djdk_inv);             // k
-       v3_scale(&tmp,&distk,-cos_theta/exchange->d2[k]);
-       v3_add(&dcosdrk,&dcosdrk,&tmp);
+#ifdef DEBUG
+       if(ai==&(moldyn->atom[DATOM])) 
+               printf("zeta_ij: %f %f %f %f\n",f_c_ik*g,f_c_ik,g,d_ik);
+#endif
 
-       /* zeta derivatives */
-       dzjj=&(exchange->dzeta[j][j]);
-       dzkk=&(exchange->dzeta[k][k]);
-       dzjk=&(exchange->dzeta[j][k]);
-       dzkj=&(exchange->dzeta[k][j]);
-       v3_scale(&tmp,&dcosdrj,exchange->f_c[k]*dgk);
-       v3_add(dzjj,dzjj,&tmp);                         // j j
-       v3_scale(&tmp,&dcosdrk,exchange->f_c[j]*dgj);
-       v3_add(dzkk,dzkk,&tmp);                         // k k
-       v3_scale(&tmp,&distk,-exchange->df_c[k]*gk);    // dk rik = - di rik
-       v3_add(dzjk,dzjk,&tmp);
-       v3_scale(&tmp,&dcosdrk,exchange->f_c[k]*dgk);
-       v3_add(dzjk,dzjk,&tmp);                         // j k
-       v3_scale(&tmp,&distj,-exchange->df_c[j]*gj);    // dj rij = - di rij
-       v3_add(dzkj,dzkj,&tmp);
-       v3_scale(&tmp,&dcosdrj,exchange->f_c[j]*dgj);
-       v3_add(dzkj,dzkj,&tmp);                         // k j
+       /* store even more data for second k loop */
+       exchange->g[kcount]=g;
+       exchange->dg[kcount]=dg;
+       exchange->d_ik[kcount]=d_ik;
+       exchange->cos_theta[kcount]=cos_theta;
+       exchange->f_c_ik[kcount]=f_c_ik;
+       exchange->df_c_ik[kcount]=df_c_ik;
 
        /* increase k counter */
        exchange->kcnt+=1;
@@ -440,11 +427,21 @@ printf("    t: %.15f %.15f %.15f\n",ai->f.x,ai->f.y,ai->f.z);
        v3_scale(&force,&force,-1.0); // dri rij = - drj rij
        v3_add(&(aj->f),&(aj->f),&force);
 
-#ifdef NDEBUG
-if(aj->tag==0) {
-printf("force: %.15f %.15f %.15f | %d %d (ji) %.15f\n",force.x,force.y,force.z,aj->tag,ai->tag,exchange->zeta[j]);
-printf("    t: %.15f %.15f %.15f\n",aj->f.x,aj->f.y,aj->f.z);
-}
+       /* virial */
+       virial_calc(ai,&force,&(exchange->dist_ij));
+
+#ifdef DEBUG
+       if((ai==&(moldyn->atom[DATOM]))|(aj==&(moldyn->atom[DATOM]))) {
+               printf("force 3bp (j2): [%d %d sum]\n",ai->tag,aj->tag);
+               printf("  adding %f %f %f\n",force.x,force.y,force.z);
+               if(ai==&(moldyn->atom[DATOM]))
+                       printf("  total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z);
+               if(aj==&(moldyn->atom[DATOM]))
+                       printf("  total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z);
+               printf("  energy: %f = %f %f %f %f\n",0.5*f_c*(b*f_a+f_r),
+                                                   f_c,b,f_a,f_r);
+               printf("          %f %f %f\n",exchange->zeta_ij,.0,.0);
+       }
 #endif
 
        /* virial */
@@ -501,39 +498,89 @@ int albe_mult_i0_j2_k0(t_moldyn *moldyn,
                return 0;
        }
 
-       /* k!=j & check whether to run k */
-       k=exchange->kcnt;
-       j=exchange->j2cnt;
-       if((k==j)|(exchange->skip[k])) {
-               exchange->kcnt+=1;
-               return 0;
-       }
-       
-       /* force contribution (drk derivative) */
-       v3_scale(&force,&(exchange->dzeta[j][k]),exchange->pre_dzeta);
-       v3_add(&(ak->f),&(ak->f),&force);
+       /* prefactor dzeta */
+       pre_dzeta=exchange->pre_dzeta;
 
-#ifdef NDEBUG
-if(ak->tag==0) {
-printf("force: %.15f %.15f %.15f | %d %d %d (k der)\n",force.x,force.y,force.z,ai->tag,aj->tag,ak->tag);
-printf("    t: %.15f %.15f %.15f\n",ak->f.x,ak->f.y,ak->f.z);
-}
+       /* dist_ik, d_ik */
+       dist_ik=exchange->dist_ik[kcount];
+       d_ik=exchange->d_ik[kcount];
+
+       /* f_c_ik, df_c_ik */
+       f_c_ik=exchange->f_c_ik[kcount];
+       df_c_ik=exchange->df_c_ik[kcount];
+
+       /* dist_ij, d_ij2, d_ij */
+       dist_ij=exchange->dist_ij;
+       d_ij2=exchange->d_ij2;
+       d_ij=exchange->d_ij;
+
+       /* g, dg, cos_theta */
+       g=exchange->g[kcount];
+       dg=exchange->dg[kcount];
+       cos_theta=exchange->cos_theta[kcount];
+
+       /* cos_theta derivatives wrt j,k */
+       dijdik_inv=1.0/(d_ij*d_ik);
+       v3_scale(&dcosdrj,&dist_ik,dijdik_inv);         // j
+       v3_scale(&tmp,&dist_ij,-cos_theta/d_ij2);
+       v3_add(&dcosdrj,&dcosdrj,&tmp);
+       v3_scale(&dcosdrk,&dist_ij,dijdik_inv);         // k
+       v3_scale(&tmp,&dist_ik,-cos_theta/d_ik2);
+       v3_add(&dcosdrk,&dcosdrk,&tmp);
+
+       /* f_c_ik * dg, df_c_ik * g */
+       fcdg=f_c_ik*dg;
+       dfcg=df_c_ik*g;
+
+       /* derivative wrt j */
+       v3_scale(&force,&dcosdrj,fcdg*pre_dzeta);
+
+       /* force contribution */
+       v3_add(&(aj->f),&(aj->f),&force);
+
+#ifdef DEBUG
+       if(aj==&(moldyn->atom[DATOM])) {
+               printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag);
+               printf("  adding %f %f %f\n",force.x,force.y,force.z);
+               printf("  total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z);
+               printf("  angle: %f\n",acos(cos_theta)*360.0/(2*M_PI));
+               printf("    d ij ik = %f %f\n",d_ij,d_ik);
+       }
 #endif
 
        /* virial */
-       virial_calc(ai,&force,&(exchange->dist[k]));
+       virial_calc(ai,&force,&dist_ij);
 
+       /* force contribution to atom i */
        v3_scale(&force,&force,-1.0);
        v3_add(&(ai->f),&(ai->f),&force);
 
-#ifdef NDEBUG
-if(ai->tag==0) {
-printf("force: %.15f %.15f %.15f | %d %d %d -- %d(i contr k der)\n",force.x,force.y,force.z,ai->tag,aj->tag,ak->tag,k);
-printf("    t: %.15f %.15f %.15f\n",ai->f.x,ai->f.y,ai->f.z);
-printf("  ## %f\n",exchange->d[k]);
-}
+       /* derivative wrt k */
+       v3_scale(&force,&dist_ik,-1.0*dfcg); // dri rik = - drk rik
+       v3_scale(&tmp,&dcosdrk,fcdg);
+       v3_add(&force,&force,&tmp);
+       v3_scale(&force,&force,pre_dzeta);
+
+       v3_scale(&force,&force,-1.0);
+       v3_add(&(ai->f),&(ai->f),&force);
+
+#ifdef DEBUG
+       if(ak==&(moldyn->atom[DATOM])) {
+               printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag);
+               printf("  adding %f %f %f\n",force.x,force.y,force.z);
+               printf("  total k: %f %f %f\n",ak->f.x,ak->f.y,ak->f.z);
+               printf("  angle: %f\n",acos(cos_theta)*360.0/(2*M_PI));
+               printf("    d ij ik = %f %f\n",d_ij,d_ik);
+       }
 #endif
 
+       /* virial */
+       virial_calc(ai,&force,&dist_ik);
+       
+       /* force contribution to atom i */
+       v3_scale(&force,&force,-1.0);
+       v3_add(&(ai->f),&(ai->f),&force);
+
        /* increase k counter */
        exchange->kcnt+=1;
 
index 39c4df8..9687655 100644 (file)
@@ -64,31 +64,32 @@ typedef struct s_albe_mult_params {
        double c[2];
        double c2[2];
        double c_mixed;
+       double c2[2];
        double c2_mixed;
        double d[2];
        double d2[2];
        double d_mixed;
+       double d2[2];
        double d2_mixed;
-       double c2d2[2];
-       double c2d2_m;
        double h[2];
        double h_mixed;
+       double c2d2[2];
+       double c2d2_m;
 
        t_albe_exchange exchange;       /* exchange between 2bp and 3bp calc */
 } t_albe_mult_params;
 
 /* function prototypes */
 int albe_mult_set_params(t_moldyn *moldyn,int element1,int elemnt2);
-int albe_mult_i0(t_moldyn *moldyn,t_atom *ai);
-int albe_mult_i0_j0(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc);
-int albe_mult_i0_j0_k0(t_moldyn *moldyn,
-                       t_atom *ai,t_atom *aj,t_atom *ak,u8 bc);
-int albe_mult_i0_j1(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc);
-int albe_mult_i0_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc);
-int albe_mult_i0_j2_k0(t_moldyn *moldyn,
-                       t_atom *ai,t_atom *aj,t_atom *ak,u8 bc);
-int albe_mult_i0_j3(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc);
+int albe_mult_3bp_j1(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc);
+int albe_mult_3bp_k1(t_moldyn *moldyn,
+                     t_atom *ai,t_atom *aj,t_atom *ak,u8 bc);
+int albe_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc);
+int albe_mult_3bp_k2(t_moldyn *moldyn,
+                     t_atom *ai,t_atom *aj,t_atom *ak,u8 bc);
 int albe_mult_check_2b_bond(t_moldyn *moldyn,t_atom *itom,t_atom *jtom,u8 bc);
+/* fast */
+int albe_potential_force_calc(t_moldyn *moldyn);
 
 /* albe potential parameter defines */
 
@@ -102,35 +103,35 @@ int albe_mult_check_2b_bond(t_moldyn *moldyn,t_atom *itom,t_atom *jtom,u8 bc);
 #define ALBE_MU_SI             (1.4761*sqrt(2.0/1.842))
 #define ALBE_GAMMA_SI          0.114354
 #define ALBE_C_SI              2.00494
-#define ALBE_D_SI              0.81472
+#define ALBE_D_SI              0.814719
 #define ALBE_H_SI              0.259
 #define ALBE_LC_SI             5.429
 
 // carbon
 #define ALBE_R_C               (2.00-0.15)
 #define ALBE_S_C               (2.00+0.15)
-#define ALBE_A_C               (6.00*EV/1.167)
-#define ALBE_B_C               (-2.167*6.00*EV/1.167)
-#define ALBE_R0_C              1.4276
-#define ALBE_LAMBDA_C          (2.0099*sqrt(2.0*2.167))
-#define ALBE_MU_C              (2.0099*sqrt(2.0/2.167))
-#define ALBE_GAMMA_C           0.11233
-#define ALBE_C_C               181.910
-#define ALBE_D_C               6.28433
-#define ALBE_H_C               0.5556
+#define ALBE_A_C               (6.00*EV/1.1671419)
+#define ALBE_B_C               (-2.1671419*6.00*EV/1.1671419)
+#define ALBE_R0_C              1.4276442
+#define ALBE_LAMBDA_C          (2.0099457*sqrt(2.0*2.1671419))
+#define ALBE_MU_C              (2.0099457*sqrt(2.0/2.1671419))
+#define ALBE_GAMMA_C           0.1123327
+#define ALBE_C_C               181.9100526
+#define ALBE_D_C               6.2843249
+#define ALBE_H_C               0.5556181
 #define ALBE_LC_C              3.566
 
 // mixed: silicon carbide
 #define ALBE_R_SIC             (2.40-0.20)
 #define ALBE_S_SIC             (2.40+0.20)
-#define ALBE_A_SIC             (4.36*EV/0.847)
-#define ALBE_B_SIC             (-1.847*4.36*EV/0.847)
+#define ALBE_A_SIC             (4.36*EV/0.8474739)
+#define ALBE_B_SIC             (-1.8474739*4.36*EV/0.8474739)
 #define ALBE_R0_SIC            1.79
-#define ALBE_LAMBDA_SIC                (1.6991*sqrt(2.0*1.847))
-#define ALBE_MU_SIC            (1.6991*sqrt(2.0/1.847))
-#define ALBE_GAMMA_SIC         0.011877
-#define ALBE_C_SIC             273987
-#define ALBE_D_SIC             180.314
+#define ALBE_LAMBDA_SIC                (1.6990751*sqrt(2.0*1.8474739))
+#define ALBE_MU_SIC            (1.6990751*sqrt(2.0/1.8474739))
+#define ALBE_GAMMA_SIC         0.0118769
+#define ALBE_C_SIC             273986.61
+#define ALBE_D_SIC             180.31411
 #define ALBE_H_SIC             0.68
 #define ALBE_LC_SIC            4.359
 
diff --git a/potentials/albe_fast.c b/potentials/albe_fast.c
new file mode 100644 (file)
index 0000000..79162b1
--- /dev/null
@@ -0,0 +1,1460 @@
+/*
+ * test: albe_new.c
+ *
+ * author: Frank Zirkelbach <frank.zirkelbach@physik.uni-augsburg.de>
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+
+#ifdef PARALLEL
+#include <omp.h>
+#endif
+
+#ifdef PTHREADS
+#include <pthread.h>
+#define MAX_THREADS 2
+#endif
+
+#include "../moldyn.h"
+#include "../math/math.h"
+#include "albe.h"
+
+#ifdef PTHREADS
+extern pthread_mutex_t *amutex;
+extern pthread_mutex_t emutex;
+#endif
+
+/*
+ * virial calculation
+ */
+
+#define albe_v_calc(a,f,d)     (a)->virial.xx+=(f)->x*(d)->x; \
+                               (a)->virial.yy+=(f)->y*(d)->y; \
+                               (a)->virial.zz+=(f)->z*(d)->z; \
+                               (a)->virial.xy+=(f)->x*(d)->y; \
+                               (a)->virial.xz+=(f)->x*(d)->z; \
+                               (a)->virial.yz+=(f)->y*(d)->z
+
+#ifndef PTHREADS
+
+int albe_potential_force_calc(t_moldyn *moldyn) {
+
+       int i,j,k,count;
+       t_atom *itom,*jtom,*ktom;
+       t_virial *virial;
+       t_linkcell *lc;
+#ifdef STATIC_LISTS
+       int *neighbour_i[27];
+       int p,q;
+#elif LOWMEM_LISTS
+       int neighbour_i[27];
+       int p,q;
+#else
+       t_list neighbour_i[27];
+       t_list neighbour_i2[27];
+       t_list *this,*that;
+#endif
+       u8 bc_ij,bc_ik;
+       int dnlc;
+#ifdef PTHREADS
+       int ret;
+       t_kdata kdata[27];
+       pthread_t kthread[27];
+#endif
+
+       // needed to work
+       t_atom *ai;
+
+       // optimized
+       t_albe_mult_params *params;
+       t_albe_exchange *exchange;
+       t_3dvec dist_ij;
+       double d_ij2;
+       double d_ij;
+       u8 brand_i;
+       double S2;
+       int kcount;
+       double zeta_ij;
+       double pre_dzeta;
+
+       // more ...
+       double Rk,Sk,Sk2;
+       t_3dvec dist_ik;
+       double d_ik2,d_ik;
+       double cos_theta,h_cos,d2_h_cos2,frac,g,dg,s_r,arg;
+       double f_c_ik,df_c_ik;
+
+       t_3dvec force;
+       double f_a,df_a,b,db,f_c,df_c;
+       double f_r,df_r;
+       double scale;
+       double mu,B;
+       double lambda,A;
+       double r0;
+       double S,R;
+       double energy;
+
+       double dijdik_inv,fcdg,dfcg;
+       t_3dvec dcosdrj,dcosdrk;
+       t_3dvec tmp;
+
+       // even more ...
+       double gamma_i;
+       double c_i;
+       double d_i;
+       double h_i;
+       double ci2;
+       double di2;
+       double ci2di2;
+
+       count=moldyn->count;
+       itom=moldyn->atom;
+       lc=&(moldyn->lc);
+
+       // optimized
+       params=moldyn->pot_params;
+       exchange=&(params->exchange);
+
+
+       /* reset energy */
+       moldyn->energy=0.0;
+
+       /* reset global virial */
+       memset(&(moldyn->gvir),0,sizeof(t_virial));
+
+       /* reset force, site energy and virial of every atom */
+#ifdef PARALLEL
+       #pragma omp parallel for private(virial)
+#endif
+       for(i=0;i<count;i++) {
+
+               /* reset force */
+               v3_zero(&(itom[i].f));
+
+               /* reset virial */
+               virial=(&(itom[i].virial));
+               virial->xx=0.0;
+               virial->yy=0.0;
+               virial->zz=0.0;
+               virial->xy=0.0;
+               virial->xz=0.0;
+               virial->yz=0.0;
+       
+               /* reset site energy */
+               itom[i].e=0.0;
+
+       }
+
+       /* get energy, force and virial of every atom */
+
+       /* first (and only) loop over atoms i */
+       for(i=0;i<count;i++) {
+
+               if(!(itom[i].attr&ATOM_ATTR_3BP))
+                       continue;
+
+               link_cell_neighbour_index(moldyn,
+                                         (itom[i].r.x+moldyn->dim.x/2)/lc->x,
+                                         (itom[i].r.y+moldyn->dim.y/2)/lc->y,
+                                         (itom[i].r.z+moldyn->dim.z/2)/lc->z,
+                                         neighbour_i);
+
+               dnlc=lc->dnlc;
+
+               /* copy the neighbour lists */
+#ifdef STATIC_LISTS
+#elif LOWMEM_LISTS
+#else
+               memcpy(neighbour_i2,neighbour_i,27*sizeof(t_list));
+#endif
+
+               ai=&(itom[i]);
+               brand_i=ai->brand;
+
+               /* loop over atoms j */
+               for(j=0;j<27;j++) {
+
+                       bc_ij=(j<dnlc)?0:1;
+#ifdef STATIC_LISTS
+                       p=0;
+
+                       while(neighbour_i[j][p]!=-1) {
+
+                               jtom=&(itom[neighbour_i[j][p]]);
+                               p++;
+#elif LOWMEM_LISTS
+                       p=neighbour_i[j];
+
+                       while(p!=-1) {
+
+                               jtom=&(itom[p]);
+                               p=lc->subcell->list[p];
+#else
+                       this=&(neighbour_i[j]);
+                       list_reset_f(this);
+
+                       if(this->start==NULL)
+                               continue;
+
+                       do {
+
+                               jtom=this->current->data;
+#endif
+
+                               if(jtom==&(itom[i]))
+                                       continue;
+
+                               if(!(jtom->attr&ATOM_ATTR_3BP))
+                                       continue;
+
+                               /* reset 3bp run */
+                               moldyn->run3bp=1;
+
+
+/* j1 func here ... */
+/* albe 3 body potential function (first ij loop) */
+
+       /* reset zeta sum */
+       zeta_ij=0.0;
+
+       /*
+        * set ij depending values
+        */
+
+       if(brand_i==jtom->brand) {
+               S2=params->S2[brand_i];
+       }
+       else {
+               S2=params->S2mixed;
+       }
+
+       /* dist_ij, d_ij2 */
+       v3_sub(&dist_ij,&(jtom->r),&(ai->r));
+       if(bc_ij) check_per_bound(moldyn,&dist_ij);
+       d_ij2=v3_absolute_square(&dist_ij);
+
+       /* if d_ij2 > S2 => no force & potential energy contribution */
+       if(d_ij2>S2)
+               continue;
+
+       /* d_ij */
+       d_ij=sqrt(d_ij2);
+
+       /* reset k counter for first k loop */
+       kcount=0;
+
+                               /* first loop over atoms k */
+                               for(k=0;k<27;k++) {
+
+                                       bc_ik=(k<dnlc)?0:1;
+#ifdef STATIC_LISTS
+                                       q=0;
+
+                                       while(neighbour_i[k][q]!=-1) {
+
+                                               ktom=&(itom[neighbour_i[k][q]]);
+                                               q++;
+#elif LOWMEM_LISTS
+                                       q=neighbour_i[k];
+
+                                       while(q!=-1) {
+
+                                               ktom=&(itom[q]);
+                                               q=lc->subcell->list[q];
+#else
+                                       that=&(neighbour_i2[k]);
+                                       list_reset_f(that);
+                                       
+                                       if(that->start==NULL)
+                                               continue;
+
+                                       do {
+                                               ktom=that->current->data;
+#endif
+
+                                               if(!(ktom->attr&ATOM_ATTR_3BP))
+                                                       continue;
+
+                                               if(ktom==jtom)
+                                                       continue;
+
+                                               if(ktom==&(itom[i]))
+                                                       continue;
+
+/* k1 func here ... */
+/* albe 3 body potential function (first k loop) */
+
+       if(kcount>ALBE_MAXN) {
+               printf("FATAL: neighbours = %d\n",kcount);
+               printf("  -> %d %d %d\n",ai->tag,jtom->tag,ktom->tag);
+       }
+
+       /* ik constants */
+       if(brand_i==ktom->brand) {
+               Rk=params->R[brand_i];
+               Sk=params->S[brand_i];
+               Sk2=params->S2[brand_i];
+               /* albe needs i,k depending c,d,h and gamma values */
+               gamma_i=params->gamma[brand_i];
+               c_i=params->c[brand_i];
+               d_i=params->d[brand_i];
+               h_i=params->h[brand_i];
+               ci2=params->c2[brand_i];
+               di2=params->d2[brand_i];
+               ci2di2=params->c2d2[brand_i];
+       }
+       else {
+               Rk=params->Rmixed;
+               Sk=params->Smixed;
+               Sk2=params->S2mixed;
+               /* albe needs i,k depending c,d,h and gamma values */
+               gamma_i=params->gamma_m;
+               c_i=params->c_mixed;
+               d_i=params->d_mixed;
+               h_i=params->h_mixed;
+               ci2=params->c2_mixed;
+               di2=params->d2_mixed;
+               ci2di2=params->c2d2_m;
+       }
+
+       /* dist_ik, d_ik2 */
+       v3_sub(&dist_ik,&(ktom->r),&(ai->r));
+       if(bc_ik) check_per_bound(moldyn,&dist_ik);
+       d_ik2=v3_absolute_square(&dist_ik);
+
+       /* store data for second k loop */
+       exchange->dist_ik[kcount]=dist_ik;
+       exchange->d_ik2[kcount]=d_ik2;
+
+       /* return if not within cutoff */
+       if(d_ik2>Sk2) {
+               kcount++;
+               continue;
+       }
+
+       /* d_ik */
+       d_ik=sqrt(d_ik2);
+
+       /* cos theta */
+       cos_theta=v3_scalar_product(&dist_ij,&dist_ik)/(d_ij*d_ik);
+
+       /* g_ijk 
+       h_cos=*(exchange->h_i)+cos_theta; // + in albe formalism
+       d2_h_cos2=exchange->di2+(h_cos*h_cos);
+       frac=exchange->ci2/d2_h_cos2;
+       g=*(exchange->gamma_i)*(1.0+exchange->ci2di2-frac);
+       dg=2.0*frac**(exchange->gamma_i)*h_cos/d2_h_cos2; // + in albe f..
+       */
+
+       h_cos=h_i+cos_theta; // + in albe formalism
+       d2_h_cos2=di2+(h_cos*h_cos);
+       frac=ci2/d2_h_cos2;
+       g=gamma_i*(1.0+ci2di2-frac);
+       dg=2.0*frac*gamma_i*h_cos/d2_h_cos2; // + in albe f..
+
+       /* zeta sum += f_c_ik * g_ijk */
+       if(d_ik<=Rk) {
+               zeta_ij+=g;
+               f_c_ik=1.0;
+               df_c_ik=0.0;
+       }
+       else {
+               s_r=Sk-Rk;
+               arg=M_PI*(d_ik-Rk)/s_r;
+               f_c_ik=0.5+0.5*cos(arg);
+               df_c_ik=0.5*sin(arg)*(M_PI/(s_r*d_ik));
+               zeta_ij+=f_c_ik*g;
+       }
+
+       /* store even more data for second k loop */
+       exchange->g[kcount]=g;
+       exchange->dg[kcount]=dg;
+       exchange->d_ik[kcount]=d_ik;
+       exchange->cos_theta[kcount]=cos_theta;
+       exchange->f_c_ik[kcount]=f_c_ik;
+       exchange->df_c_ik[kcount]=df_c_ik;
+
+       /* increase k counter */
+       kcount++;
+
+#ifdef STATIC_LISTS
+                                       }
+#elif LOWMEM_LISTS
+                                       }
+#else
+                                       } while(list_next_f(that)!=\
+                                               L_NO_NEXT_ELEMENT);
+#endif
+
+                               }
+
+/* j2 func here ... */
+
+
+       if(brand_i==jtom->brand) {
+               S=params->S[brand_i];
+               R=params->R[brand_i];
+               B=params->B[brand_i];
+               A=params->A[brand_i];
+               r0=params->r0[brand_i];
+               mu=params->mu[brand_i];
+               lambda=params->lambda[brand_i];
+       }
+       else {
+               S=params->Smixed;
+               R=params->Rmixed;
+               B=params->Bmixed;
+               A=params->Amixed;
+               r0=params->r0_mixed;
+               mu=params->mu_m;
+               lambda=params->lambda_m;
+       }
+
+       /* f_c, df_c */
+       if(d_ij<R) {
+               f_c=1.0;
+               df_c=0.0;
+       }
+       else {
+               s_r=S-R;
+               arg=M_PI*(d_ij-R)/s_r;
+               f_c=0.5+0.5*cos(arg);
+               df_c=0.5*sin(arg)*(M_PI/(s_r*d_ij));
+       }
+
+       /* f_a, df_a */
+       f_a=-B*exp(-mu*(d_ij-r0));
+       df_a=mu*f_a/d_ij;
+
+       /* f_r, df_r */
+       f_r=A*exp(-lambda*(d_ij-r0));
+       df_r=lambda*f_r/d_ij;
+
+       /* b, db */
+       if(zeta_ij==0.0) {
+               b=1.0;
+               db=0.0;
+       }
+       else {
+               b=1.0/sqrt(1.0+zeta_ij);
+               db=-0.5*b/(1.0+zeta_ij);
+       }
+
+       /* force contribution for atom i */
+#ifdef MATTONI
+       scale=-0.5*(f_c*(df_r-b*df_a)); // - in albe formalism
+#else
+       scale=-0.5*(f_c*(df_r-b*df_a)+df_c*(f_r-b*f_a)); // - in albe formalism
+#endif
+       v3_scale(&force,&(dist_ij),scale);
+       v3_add(&(ai->f),&(ai->f),&force);
+
+       /* force contribution for atom j */
+       v3_scale(&force,&force,-1.0); // dri rij = - drj rij
+       v3_add(&(jtom->f),&(jtom->f),&force);
+
+       /* virial */
+       albe_v_calc(ai,&force,&(dist_ij));
+       //virial_calc(ai,&force,&(dist_ij));
+
+#ifdef DEBUG
+if(moldyn->time>DSTART&&moldyn->time<DEND) {
+       if((ai==&(moldyn->atom[DATOM]))|(jtom==&(moldyn->atom[DATOM]))) {
+               printf("force 3bp (j2): [%d %d sum]\n",ai->tag,jtom->tag);
+               printf("  adding %f %f %f\n",force.x,force.y,force.z);
+               if(ai==&(moldyn->atom[0]))
+                       printf("  total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z);
+               if(jtom==&(moldyn->atom[0]))
+                       printf("  total j: %f %f %f\n",jtom->f.x,jtom->f.y,jtom->f.z);
+               printf("  energy: %f = %f %f %f %f\n",0.5*f_c*(b*f_a+f_r),
+                                                   f_c,b,f_a,f_r);
+               printf("          %f %f %f\n",zeta_ij,.0,.0);
+       }
+}
+#endif
+
+       /* dzeta prefactor = - f_c f_a db, (* -0.5 due to force calc) */
+       pre_dzeta=0.5*f_a*f_c*db;
+
+       /* energy contribution */
+       energy=0.5*f_c*(f_r-b*f_a); // - in albe formalism
+       moldyn->energy+=energy;
+       ai->e+=energy;
+
+       /* reset k counter for second k loop */
+       kcount=0;
+               
+
+                               /* second loop over atoms k */
+                               for(k=0;k<27;k++) {
+
+                                       bc_ik=(k<dnlc)?0:1;
+#ifdef STATIC_LISTS
+                                       q=0;
+
+                                       while(neighbour_i[k][q]!=-1) {
+
+                                               ktom=&(itom[neighbour_i[k][q]]);
+                                               q++;
+#elif LOWMEM_LISTS
+                                       q=neighbour_i[k];
+
+                                       while(q!=-1) {
+
+                                               ktom=&(itom[q]);
+                                               q=lc->subcell->list[q];
+#else
+                                       that=&(neighbour_i2[k]);
+                                       list_reset_f(that);
+                                       
+                                       if(that->start==NULL)
+                                               continue;
+
+                                       do {
+                                               ktom=that->current->data;
+#endif
+
+                                               if(!(ktom->attr&ATOM_ATTR_3BP))
+                                                       continue;
+
+                                               if(ktom==jtom)
+                                                       continue;
+
+                                               if(ktom==&(itom[i]))
+                                                       continue;
+
+
+/* k2 func here ... */
+/* albe 3 body potential function (second k loop) */
+
+       if(kcount>ALBE_MAXN)
+               printf("FATAL: neighbours!\n");
+
+       /* d_ik2 */
+       d_ik2=exchange->d_ik2[kcount];
+
+       if(brand_i==ktom->brand)
+               Sk2=params->S2[brand_i];
+       else
+               Sk2=params->S2mixed;
+
+       /* return if d_ik > S */
+       if(d_ik2>Sk2) {
+               kcount++;
+               continue;
+       }
+
+       /* dist_ik, d_ik */
+       dist_ik=exchange->dist_ik[kcount];
+       d_ik=exchange->d_ik[kcount];
+
+       /* f_c_ik, df_c_ik */
+       f_c_ik=exchange->f_c_ik[kcount];
+       df_c_ik=exchange->df_c_ik[kcount];
+
+       /* g, dg, cos_theta */
+       g=exchange->g[kcount];
+       dg=exchange->dg[kcount];
+       cos_theta=exchange->cos_theta[kcount];
+
+       /* cos_theta derivatives wrt j,k */
+       dijdik_inv=1.0/(d_ij*d_ik);
+       v3_scale(&dcosdrj,&dist_ik,dijdik_inv);         // j
+       v3_scale(&tmp,&dist_ij,-cos_theta/d_ij2);
+       v3_add(&dcosdrj,&dcosdrj,&tmp);
+       v3_scale(&dcosdrk,&dist_ij,dijdik_inv);         // k
+       v3_scale(&tmp,&dist_ik,-cos_theta/d_ik2);
+       v3_add(&dcosdrk,&dcosdrk,&tmp);
+
+       /* f_c_ik * dg, df_c_ik * g */
+       fcdg=f_c_ik*dg;
+       dfcg=df_c_ik*g;
+
+       /* derivative wrt j */
+       v3_scale(&force,&dcosdrj,fcdg*pre_dzeta);
+
+       /* force contribution */
+       v3_add(&(jtom->f),&(jtom->f),&force);
+
+#ifdef DEBUG
+if(moldyn->time>DSTART&&moldyn->time<DEND) {
+       if(jtom==&(moldyn->atom[DATOM])) {
+               printf("force 3bp (k2): [%d %d %d]\n",ai->tag,jtom->tag,ktom->tag);
+               printf("  adding %f %f %f\n",force.x,force.y,force.z);
+               printf("  total j: %f %f %f\n",jtom->f.x,jtom->f.y,jtom->f.z);
+               printf("  angle: %f\n",acos(cos_theta)*360.0/(2*M_PI));
+               printf("    d ij ik = %f %f\n",d_ij,d_ik);
+       }
+}
+#endif
+
+       /* virial */
+       albe_v_calc(ai,&force,&dist_ij);
+       //virial_calc(ai,&force,&dist_ij);
+
+       /* force contribution to atom i */
+       v3_scale(&force,&force,-1.0);
+       v3_add(&(ai->f),&(ai->f),&force);
+
+       /* derivative wrt k */
+#ifdef MATTONI
+       v3_scale(&tmp,&dcosdrk,fcdg);
+       v3_scale(&force,&tmp,pre_dzeta);
+#else
+       v3_scale(&force,&dist_ik,-1.0*dfcg); // dri rik = - drk rik
+       v3_scale(&tmp,&dcosdrk,fcdg);
+       v3_add(&force,&force,&tmp);
+       v3_scale(&force,&force,pre_dzeta);
+#endif
+
+       /* force contribution */
+       v3_add(&(ktom->f),&(ktom->f),&force);
+
+#ifdef DEBUG
+if(moldyn->time>DSTART&&moldyn->time<DEND) {
+       if(ktom==&(moldyn->atom[DATOM])) {
+               printf("force 3bp (k2): [%d %d %d]\n",ai->tag,jtom->tag,ktom->tag);
+               printf("  adding %f %f %f\n",force.x,force.y,force.z);
+               printf("  total k: %f %f %f\n",ktom->f.x,ktom->f.y,ktom->f.z);
+               printf("  angle: %f\n",acos(cos_theta)*360.0/(2*M_PI));
+               printf("    d ij ik = %f %f\n",d_ij,d_ik);
+       }
+}
+#endif
+
+       /* virial */
+       albe_v_calc(ai,&force,&dist_ik);
+       //virial_calc(ai,&force,&dist_ik);
+       
+       /* force contribution to atom i */
+       v3_scale(&force,&force,-1.0);
+       v3_add(&(ai->f),&(ai->f),&force);
+
+       /* increase k counter */
+       kcount++;       
+
+
+
+#ifdef STATIC_LISTS
+                                       }
+#elif LOWMEM_LISTS
+                                       }
+#else
+                                       } while(list_next_f(that)!=\
+                                               L_NO_NEXT_ELEMENT);
+#endif
+
+                               }
+                               
+#ifdef STATIC_LISTS
+                       }
+#elif LOWMEM_LISTS
+                       }
+#else
+                       } while(list_next_f(this)!=L_NO_NEXT_ELEMENT);
+#endif
+               
+               }
+               
+#ifdef DEBUG
+       //printf("\n\n");
+#endif
+#ifdef VDEBUG
+       printf("\n\n");
+#endif
+
+       }
+
+#ifdef DEBUG
+       //printf("\nATOM 0: %f %f %f\n\n",itom->f.x,itom->f.y,itom->f.z);
+       if(moldyn->time>DSTART&&moldyn->time<DEND) {
+               printf("force:\n");
+               printf("  x: %0.40f\n",moldyn->atom[DATOM].f.x);
+               printf("  y: %0.40f\n",moldyn->atom[DATOM].f.y);
+               printf("  z: %0.40f\n",moldyn->atom[DATOM].f.z);
+       }
+#endif
+
+       /* some postprocessing */
+#ifdef PARALLEL
+       #pragma omp parallel for
+#endif
+       for(i=0;i<count;i++) {
+               /* calculate global virial */
+               moldyn->gvir.xx+=itom[i].r.x*itom[i].f.x;
+               moldyn->gvir.yy+=itom[i].r.y*itom[i].f.y;
+               moldyn->gvir.zz+=itom[i].r.z*itom[i].f.z;
+               moldyn->gvir.xy+=itom[i].r.y*itom[i].f.x;
+               moldyn->gvir.xz+=itom[i].r.z*itom[i].f.x;
+               moldyn->gvir.yz+=itom[i].r.z*itom[i].f.y;
+
+               /* check forces regarding the given timestep */
+               if(v3_norm(&(itom[i].f))>\
+                   0.1*moldyn->nnd*itom[i].mass/moldyn->tau_square)
+                       printf("[moldyn] WARNING: pfc (high force: atom %d)\n",
+                              i);
+       }
+
+       return 0;
+}
+
+
+#else // PTHREADS
+
+
+typedef struct s_pft_data {
+       t_moldyn *moldyn;
+       int start,end;
+} t_pft_data;
+
+void *potential_force_thread(void *ptr) {
+
+       t_pft_data *pft_data;
+       t_moldyn *moldyn;
+       t_albe_exchange ec;
+
+       int i,j,k,count;
+       t_atom *itom,*jtom,*ktom;
+       t_linkcell *lc;
+#ifdef STATIC_LISTS
+       int *neighbour_i[27];
+       int p,q;
+#elif LOWMEM_LISTS
+       int neighbour_i[27];
+       int p,q;
+#else
+       t_list neighbour_i[27];
+       t_list neighbour_i2[27];
+       t_list *this,*that;
+#endif
+       u8 bc_ij,bc_ik;
+       int dnlc;
+
+       // needed to work
+       t_atom *ai;
+
+       // optimized
+       t_albe_mult_params *params;
+       t_albe_exchange *exchange;
+       t_3dvec dist_ij;
+       double d_ij2;
+       double d_ij;
+       u8 brand_i;
+       double S2;
+       int kcount;
+       double zeta_ij;
+       double pre_dzeta;
+
+       // more ...
+       double Rk,Sk,Sk2;
+       t_3dvec dist_ik;
+       double d_ik2,d_ik;
+       double cos_theta,h_cos,d2_h_cos2,frac,g,dg,s_r,arg;
+       double f_c_ik,df_c_ik;
+
+       t_3dvec force;
+       double f_a,df_a,b,db,f_c,df_c;
+       double f_r,df_r;
+       double scale;
+       double mu,B;
+       double lambda,A;
+       double r0;
+       double S,R;
+       double energy;
+
+       double dijdik_inv,fcdg,dfcg;
+       t_3dvec dcosdrj,dcosdrk;
+       t_3dvec tmp;
+
+       // even more ...
+       double gamma_i;
+       double c_i;
+       double d_i;
+       double h_i;
+       double ci2;
+       double di2;
+       double ci2di2;
+
+       pft_data=ptr;
+       moldyn=pft_data->moldyn;
+       exchange=&ec;
+
+       count=moldyn->count;
+       itom=moldyn->atom;
+       lc=&(moldyn->lc);
+
+       // optimized
+       params=moldyn->pot_params;
+
+       /* get energy, force and virial for atoms */
+
+       for(i=pft_data->start;i<pft_data->end;i++) {
+
+               if(!(itom[i].attr&ATOM_ATTR_3BP))
+                       return 0;
+
+               // thread safe this way!
+               dnlc=link_cell_neighbour_index(moldyn,
+                                         (itom[i].r.x+moldyn->dim.x/2)/lc->x,
+                                         (itom[i].r.y+moldyn->dim.y/2)/lc->y,
+                                         (itom[i].r.z+moldyn->dim.z/2)/lc->z,
+                                         neighbour_i);
+
+               /* copy the neighbour lists */
+#ifdef STATIC_LISTS
+#elif LOWMEM_LISTS
+#else
+               memcpy(neighbour_i2,neighbour_i,27*sizeof(t_list));
+#endif
+
+               ai=&(itom[i]);
+               brand_i=ai->brand;
+
+               /* loop over atoms j */
+               for(j=0;j<27;j++) {
+
+                       bc_ij=(j<dnlc)?0:1;
+#ifdef STATIC_LISTS
+                       p=0;
+
+                       while(neighbour_i[j][p]!=-1) {
+
+                               jtom=&(itom[neighbour_i[j][p]]);
+                               p++;
+#elif LOWMEM_LISTS
+                       p=neighbour_i[j];
+
+                       while(p!=-1) {
+
+                               jtom=&(itom[p]);
+                               p=lc->subcell->list[p]; // thread safe!
+#else
+                       this=&(neighbour_i[j]);
+                       list_reset_f(this);
+
+                       if(this->start==NULL)
+                               continue;
+
+                       do {
+
+                               jtom=this->current->data;
+#endif
+
+                               if(jtom==&(itom[i]))
+                                       continue;
+
+                               if(!(jtom->attr&ATOM_ATTR_3BP))
+                                       continue;
+
+                               /* reset 3bp run */
+                               moldyn->run3bp=1;
+
+
+/* j1 func here ... */
+/* albe 3 body potential function (first ij loop) */
+
+       /* reset zeta sum */
+       zeta_ij=0.0;
+
+       /*
+        * set ij depending values
+        */
+
+       if(brand_i==jtom->brand) {
+               S2=params->S2[brand_i];
+       }
+       else {
+               S2=params->S2mixed;
+       }
+
+       /* dist_ij, d_ij2 */
+       v3_sub(&dist_ij,&(jtom->r),&(ai->r));
+       if(bc_ij) check_per_bound(moldyn,&dist_ij);
+       d_ij2=v3_absolute_square(&dist_ij);
+
+       /* if d_ij2 > S2 => no force & potential energy contribution */
+       if(d_ij2>S2)
+               continue;
+
+       /* d_ij */
+       d_ij=sqrt(d_ij2);
+
+       /* reset k counter for first k loop */
+       kcount=0;
+
+                               /* first loop over atoms k */
+                               for(k=0;k<27;k++) {
+
+                                       bc_ik=(k<dnlc)?0:1;
+#ifdef STATIC_LISTS
+                                       q=0;
+
+                                       while(neighbour_i[k][q]!=-1) {
+
+                                               ktom=&(itom[neighbour_i[k][q]]);
+                                               q++;
+#elif LOWMEM_LISTS
+                                       q=neighbour_i[k];
+
+                                       while(q!=-1) {
+
+                                               ktom=&(itom[q]);
+                                               q=lc->subcell->list[q];
+#else
+                                       that=&(neighbour_i2[k]);
+                                       list_reset_f(that);
+                                       
+                                       if(that->start==NULL)
+                                               continue;
+
+                                       do {
+                                               ktom=that->current->data;
+#endif
+
+                                               if(!(ktom->attr&ATOM_ATTR_3BP))
+                                                       continue;
+
+                                               if(ktom==jtom)
+                                                       continue;
+
+                                               if(ktom==&(itom[i]))
+                                                       continue;
+
+/* k1 func here ... */
+/* albe 3 body potential function (first k loop) */
+
+       if(kcount>ALBE_MAXN) {
+               printf("FATAL: neighbours = %d\n",kcount);
+               printf("  -> %d %d %d\n",ai->tag,jtom->tag,ktom->tag);
+       }
+
+       /* ik constants */
+       if(brand_i==ktom->brand) {
+               Rk=params->R[brand_i];
+               Sk=params->S[brand_i];
+               Sk2=params->S2[brand_i];
+               /* albe needs i,k depending c,d,h and gamma values */
+               gamma_i=params->gamma[brand_i];
+               c_i=params->c[brand_i];
+               d_i=params->d[brand_i];
+               h_i=params->h[brand_i];
+               ci2=params->c2[brand_i];
+               di2=params->d2[brand_i];
+               ci2di2=params->c2d2[brand_i];
+       }
+       else {
+               Rk=params->Rmixed;
+               Sk=params->Smixed;
+               Sk2=params->S2mixed;
+               /* albe needs i,k depending c,d,h and gamma values */
+               gamma_i=params->gamma_m;
+               c_i=params->c_mixed;
+               d_i=params->d_mixed;
+               h_i=params->h_mixed;
+               ci2=params->c2_mixed;
+               di2=params->d2_mixed;
+               ci2di2=params->c2d2_m;
+       }
+
+       /* dist_ik, d_ik2 */
+       v3_sub(&dist_ik,&(ktom->r),&(ai->r));
+       if(bc_ik) check_per_bound(moldyn,&dist_ik);
+       d_ik2=v3_absolute_square(&dist_ik);
+
+       /* store data for second k loop */
+       exchange->dist_ik[kcount]=dist_ik;
+       exchange->d_ik2[kcount]=d_ik2;
+
+       /* return if not within cutoff */
+       if(d_ik2>Sk2) {
+               kcount++;
+               continue;
+       }
+
+       /* d_ik */
+       d_ik=sqrt(d_ik2);
+
+       /* cos theta */
+       cos_theta=v3_scalar_product(&dist_ij,&dist_ik)/(d_ij*d_ik);
+
+       /* g_ijk 
+       h_cos=*(exchange->h_i)+cos_theta; // + in albe formalism
+       d2_h_cos2=exchange->di2+(h_cos*h_cos);
+       frac=exchange->ci2/d2_h_cos2;
+       g=*(exchange->gamma_i)*(1.0+exchange->ci2di2-frac);
+       dg=2.0*frac**(exchange->gamma_i)*h_cos/d2_h_cos2; // + in albe f..
+       */
+
+       h_cos=h_i+cos_theta; // + in albe formalism
+       d2_h_cos2=di2+(h_cos*h_cos);
+       frac=ci2/d2_h_cos2;
+       g=gamma_i*(1.0+ci2di2-frac);
+       dg=2.0*frac*gamma_i*h_cos/d2_h_cos2; // + in albe f..
+
+       /* zeta sum += f_c_ik * g_ijk */
+       if(d_ik<=Rk) {
+               zeta_ij+=g;
+               f_c_ik=1.0;
+               df_c_ik=0.0;
+       }
+       else {
+               s_r=Sk-Rk;
+               arg=M_PI*(d_ik-Rk)/s_r;
+               f_c_ik=0.5+0.5*cos(arg);
+               df_c_ik=0.5*sin(arg)*(M_PI/(s_r*d_ik));
+               zeta_ij+=f_c_ik*g;
+       }
+
+       /* store even more data for second k loop */
+       exchange->g[kcount]=g;
+       exchange->dg[kcount]=dg;
+       exchange->d_ik[kcount]=d_ik;
+       exchange->cos_theta[kcount]=cos_theta;
+       exchange->f_c_ik[kcount]=f_c_ik;
+       exchange->df_c_ik[kcount]=df_c_ik;
+
+       /* increase k counter */
+       kcount++;
+
+#ifdef STATIC_LISTS
+                                       }
+#elif LOWMEM_LISTS
+                                       }
+#else
+                                       } while(list_next_f(that)!=\
+                                               L_NO_NEXT_ELEMENT);
+#endif
+
+                               }
+
+/* j2 func here ... */
+
+
+       if(brand_i==jtom->brand) {
+               S=params->S[brand_i];
+               R=params->R[brand_i];
+               B=params->B[brand_i];
+               A=params->A[brand_i];
+               r0=params->r0[brand_i];
+               mu=params->mu[brand_i];
+               lambda=params->lambda[brand_i];
+       }
+       else {
+               S=params->Smixed;
+               R=params->Rmixed;
+               B=params->Bmixed;
+               A=params->Amixed;
+               r0=params->r0_mixed;
+               mu=params->mu_m;
+               lambda=params->lambda_m;
+       }
+
+       /* f_c, df_c */
+       if(d_ij<R) {
+               f_c=1.0;
+               df_c=0.0;
+       }
+       else {
+               s_r=S-R;
+               arg=M_PI*(d_ij-R)/s_r;
+               f_c=0.5+0.5*cos(arg);
+               df_c=0.5*sin(arg)*(M_PI/(s_r*d_ij));
+       }
+
+       /* f_a, df_a */
+       f_a=-B*exp(-mu*(d_ij-r0));
+       df_a=mu*f_a/d_ij;
+
+       /* f_r, df_r */
+       f_r=A*exp(-lambda*(d_ij-r0));
+       df_r=lambda*f_r/d_ij;
+
+       /* b, db */
+       if(zeta_ij==0.0) {
+               b=1.0;
+               db=0.0;
+       }
+       else {
+               b=1.0/sqrt(1.0+zeta_ij);
+               db=-0.5*b/(1.0+zeta_ij);
+       }
+
+       /* force contribution for atom i */
+#ifdef MATTONI
+       scale=-0.5*(f_c*(df_r-b*df_a)); // - in albe formalism
+#else
+       scale=-0.5*(f_c*(df_r-b*df_a)+df_c*(f_r-b*f_a)); // - in albe formalism
+#endif
+       v3_scale(&force,&(dist_ij),scale);
+       if(pthread_mutex_lock(&(amutex[ai->tag])))
+               perror("[albe fast] mutex lock (1)\n");
+       v3_add(&(ai->f),&(ai->f),&force);
+       if(pthread_mutex_unlock(&(amutex[ai->tag])))
+               perror("[albe fast] mutex unlock (1)\n");
+
+       /* force contribution for atom j */
+       v3_scale(&force,&force,-1.0); // dri rij = - drj rij
+       if(pthread_mutex_lock(&(amutex[jtom->tag])))
+               perror("[albe fast] mutex lock (2)\n");
+       v3_add(&(jtom->f),&(jtom->f),&force);
+       if(pthread_mutex_unlock(&(amutex[jtom->tag])))
+               perror("[albe fast] mutex unlock (2)\n");
+
+       /* virial */
+       if(pthread_mutex_lock(&(amutex[ai->tag])))
+               perror("[albe fast] mutex lock (3)\n");
+       albe_v_calc(ai,&force,&(dist_ij));
+       //virial_calc(ai,&force,&(dist_ij));
+       if(pthread_mutex_unlock(&(amutex[ai->tag])))
+               perror("[albe fast] mutex unlock (3)\n");
+
+#ifdef DEBUG
+if(moldyn->time>DSTART&&moldyn->time<DEND) {
+       if((ai==&(moldyn->atom[DATOM]))|(jtom==&(moldyn->atom[DATOM]))) {
+               printf("force 3bp (j2): [%d %d sum]\n",ai->tag,jtom->tag);
+               printf("  adding %f %f %f\n",force.x,force.y,force.z);
+               if(ai==&(moldyn->atom[0]))
+                       printf("  total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z);
+               if(jtom==&(moldyn->atom[0]))
+                       printf("  total j: %f %f %f\n",jtom->f.x,jtom->f.y,jtom->f.z);
+               printf("  energy: %f = %f %f %f %f\n",0.5*f_c*(b*f_a+f_r),
+                                                   f_c,b,f_a,f_r);
+               printf("          %f %f %f\n",zeta_ij,.0,.0);
+       }
+}
+#endif
+
+       /* dzeta prefactor = - f_c f_a db, (* -0.5 due to force calc) */
+       pre_dzeta=0.5*f_a*f_c*db;
+
+       /* energy contribution */
+       energy=0.5*f_c*(f_r-b*f_a); // - in albe formalism
+       if(pthread_mutex_lock(&emutex))
+               perror("[albe fast] mutex lock (energy)\n");
+       moldyn->energy+=energy;
+       if(pthread_mutex_unlock(&emutex))
+               perror("[albe fast] mutex unlock (energy)\n");
+       if(pthread_mutex_lock(&(amutex[ai->tag])))
+               perror("[albe fast] mutex lock (4)\n");
+       ai->e+=energy;
+       if(pthread_mutex_unlock(&(amutex[ai->tag])))
+               perror("[albe fast] mutex unlock (4)\n");
+
+       /* reset k counter for second k loop */
+       kcount=0;
+               
+
+                               /* second loop over atoms k */
+                               for(k=0;k<27;k++) {
+
+                                       bc_ik=(k<dnlc)?0:1;
+#ifdef STATIC_LISTS
+                                       q=0;
+
+                                       while(neighbour_i[k][q]!=-1) {
+
+                                               ktom=&(itom[neighbour_i[k][q]]);
+                                               q++;
+#elif LOWMEM_LISTS
+                                       q=neighbour_i[k];
+
+                                       while(q!=-1) {
+
+                                               ktom=&(itom[q]);
+                                               q=lc->subcell->list[q];
+#else
+                                       that=&(neighbour_i2[k]);
+                                       list_reset_f(that);
+                                       
+                                       if(that->start==NULL)
+                                               continue;
+
+                                       do {
+                                               ktom=that->current->data;
+#endif
+
+                                               if(!(ktom->attr&ATOM_ATTR_3BP))
+                                                       continue;
+
+                                               if(ktom==jtom)
+                                                       continue;
+
+                                               if(ktom==&(itom[i]))
+                                                       continue;
+
+
+/* k2 func here ... */
+/* albe 3 body potential function (second k loop) */
+
+       if(kcount>ALBE_MAXN)
+               printf("FATAL: neighbours!\n");
+
+       /* d_ik2 */
+       d_ik2=exchange->d_ik2[kcount];
+
+       if(brand_i==ktom->brand)
+               Sk2=params->S2[brand_i];
+       else
+               Sk2=params->S2mixed;
+
+       /* return if d_ik > S */
+       if(d_ik2>Sk2) {
+               kcount++;
+               continue;
+       }
+
+       /* dist_ik, d_ik */
+       dist_ik=exchange->dist_ik[kcount];
+       d_ik=exchange->d_ik[kcount];
+
+       /* f_c_ik, df_c_ik */
+       f_c_ik=exchange->f_c_ik[kcount];
+       df_c_ik=exchange->df_c_ik[kcount];
+
+       /* g, dg, cos_theta */
+       g=exchange->g[kcount];
+       dg=exchange->dg[kcount];
+       cos_theta=exchange->cos_theta[kcount];
+
+       /* cos_theta derivatives wrt j,k */
+       dijdik_inv=1.0/(d_ij*d_ik);
+       v3_scale(&dcosdrj,&dist_ik,dijdik_inv);         // j
+       v3_scale(&tmp,&dist_ij,-cos_theta/d_ij2);
+       v3_add(&dcosdrj,&dcosdrj,&tmp);
+       v3_scale(&dcosdrk,&dist_ij,dijdik_inv);         // k
+       v3_scale(&tmp,&dist_ik,-cos_theta/d_ik2);
+       v3_add(&dcosdrk,&dcosdrk,&tmp);
+
+       /* f_c_ik * dg, df_c_ik * g */
+       fcdg=f_c_ik*dg;
+       dfcg=df_c_ik*g;
+
+       /* derivative wrt j */
+       v3_scale(&force,&dcosdrj,fcdg*pre_dzeta);
+
+       /* force contribution */
+       if(pthread_mutex_lock(&(amutex[jtom->tag])))
+               perror("[albe fast] mutex lock (5)\n");
+       v3_add(&(jtom->f),&(jtom->f),&force);
+       if(pthread_mutex_unlock(&(amutex[jtom->tag])))
+               perror("[albe fast] mutex unlock (5)\n");
+
+#ifdef DEBUG
+if(moldyn->time>DSTART&&moldyn->time<DEND) {
+       if(jtom==&(moldyn->atom[DATOM])) {
+               printf("force 3bp (k2): [%d %d %d]\n",ai->tag,jtom->tag,ktom->tag);
+               printf("  adding %f %f %f\n",force.x,force.y,force.z);
+               printf("  total j: %f %f %f\n",jtom->f.x,jtom->f.y,jtom->f.z);
+               printf("  angle: %f\n",acos(cos_theta)*360.0/(2*M_PI));
+               printf("    d ij ik = %f %f\n",d_ij,d_ik);
+       }
+}
+#endif
+
+       /* virial */
+       if(pthread_mutex_lock(&(amutex[ai->tag])))
+               perror("[albe fast] mutex lock (6)\n");
+       albe_v_calc(ai,&force,&dist_ij);
+       //virial_calc(ai,&force,&dist_ij);
+
+       /* force contribution to atom i */
+       v3_scale(&force,&force,-1.0);
+       v3_add(&(ai->f),&(ai->f),&force);
+       if(pthread_mutex_unlock(&(amutex[ai->tag])))
+               perror("[albe fast] mutex unlock (6)\n");
+
+       /* derivative wrt k */
+#ifdef MATTONI
+       v3_scale(&tmp,&dcosdrk,fcdg);
+       v3_scale(&force,&tmp,pre_dzeta);
+#else
+       v3_scale(&force,&dist_ik,-1.0*dfcg); // dri rik = - drk rik
+       v3_scale(&tmp,&dcosdrk,fcdg);
+       v3_add(&force,&force,&tmp);
+       v3_scale(&force,&force,pre_dzeta);
+#endif
+
+       /* force contribution */
+       if(pthread_mutex_lock(&(amutex[ktom->tag])))
+               perror("[albe fast] mutex lock (7)\n");
+       v3_add(&(ktom->f),&(ktom->f),&force);
+       if(pthread_mutex_unlock(&(amutex[ktom->tag])))
+               perror("[albe fast] mutex unlock (7)\n");
+
+#ifdef DEBUG
+if(moldyn->time>DSTART&&moldyn->time<DEND) {
+       if(ktom==&(moldyn->atom[DATOM])) {
+               printf("force 3bp (k2): [%d %d %d]\n",ai->tag,jtom->tag,ktom->tag);
+               printf("  adding %f %f %f\n",force.x,force.y,force.z);
+               printf("  total k: %f %f %f\n",ktom->f.x,ktom->f.y,ktom->f.z);
+               printf("  angle: %f\n",acos(cos_theta)*360.0/(2*M_PI));
+               printf("    d ij ik = %f %f\n",d_ij,d_ik);
+       }
+}
+#endif
+
+       /* virial */
+       if(pthread_mutex_lock(&(amutex[ai->tag])))
+               perror("[albe fast] mutex lock (8)\n");
+       albe_v_calc(ai,&force,&dist_ik);
+       //virial_calc(ai,&force,&dist_ik);
+       
+       /* force contribution to atom i */
+       v3_scale(&force,&force,-1.0);
+       v3_add(&(ai->f),&(ai->f),&force);
+       if(pthread_mutex_unlock(&(amutex[ai->tag])))
+               perror("[albe fast] mutex unlock (8)\n");
+
+       /* increase k counter */
+       kcount++;       
+
+
+
+#ifdef STATIC_LISTS
+                                       }
+#elif LOWMEM_LISTS
+                                       }
+#else
+                                       } while(list_next_f(that)!=\
+                                               L_NO_NEXT_ELEMENT);
+#endif
+
+                               }
+                               
+#ifdef STATIC_LISTS
+                       }
+#elif LOWMEM_LISTS
+                       }
+#else
+                       } while(list_next_f(this)!=L_NO_NEXT_ELEMENT);
+#endif
+               
+               }
+
+       } // i loop
+               
+#ifdef DEBUG
+       //printf("\n\n");
+#endif
+#ifdef VDEBUG
+       printf("\n\n");
+#endif
+
+#ifdef DEBUG
+       //printf("\nATOM 0: %f %f %f\n\n",itom->f.x,itom->f.y,itom->f.z);
+       if(moldyn->time>DSTART&&moldyn->time<DEND) {
+               printf("force:\n");
+               printf("  x: %0.40f\n",moldyn->atom[DATOM].f.x);
+               printf("  y: %0.40f\n",moldyn->atom[DATOM].f.y);
+               printf("  z: %0.40f\n",moldyn->atom[DATOM].f.z);
+       }
+#endif
+
+       pthread_exit(NULL);
+
+       return 0;
+}
+
+int albe_potential_force_calc(t_moldyn *moldyn) {
+
+       int i,j,ret;
+       t_pft_data pft_data[MAX_THREADS];
+       int count;
+       pthread_t pft_thread[MAX_THREADS];
+       t_atom *itom;
+       t_virial *virial;
+
+       count=moldyn->count;
+       itom=moldyn->atom;
+
+       /* reset energy */
+       moldyn->energy=0.0;
+
+       /* reset global virial */
+       memset(&(moldyn->gvir),0,sizeof(t_virial));
+
+       /* reset force, site energy and virial of every atom */
+       for(i=0;i<count;i++) {
+
+               /* reset force */
+               v3_zero(&(itom[i].f));
+
+               /* reset virial */
+               virial=&(itom[i].virial);
+               virial->xx=0.0;
+               virial->yy=0.0;
+               virial->zz=0.0;
+               virial->xy=0.0;
+               virial->xz=0.0;
+               virial->yz=0.0;
+       
+               /* reset site energy */
+               itom[i].e=0.0;
+
+       }
+
+       /* start threads */
+       for(j=0;j<MAX_THREADS;j++) {
+
+               /* prepare thread data */
+               pft_data[j].moldyn=moldyn;
+               pft_data[j].start=j*(count/MAX_THREADS);
+               if(j==MAX_THREADS-1) {
+                       pft_data[j].end=count;
+               }
+               else {
+                       pft_data[j].end=pft_data[j].start;
+                       pft_data[j].end+=count/MAX_THREADS;
+               }
+
+               ret=pthread_create(&(pft_thread[j]),NULL,
+                                   potential_force_thread,
+                                   &(pft_data[j]));
+               if(ret)  {
+                       perror("[albe fast] pf thread create");
+                       return ret;
+               }
+       }
+
+       /* join threads */
+       for(j=0;j<MAX_THREADS;j++) {
+
+               ret=pthread_join(pft_thread[j],NULL);
+               if(ret) {
+                       perror("[albe fast] pf thread join");
+                       return ret;
+               }
+       }
+
+       /* some postprocessing */
+       for(i=0;i<count;i++) {
+               /* calculate global virial */
+               moldyn->gvir.xx+=itom[i].r.x*itom[i].f.x;
+               moldyn->gvir.yy+=itom[i].r.y*itom[i].f.y;
+               moldyn->gvir.zz+=itom[i].r.z*itom[i].f.z;
+               moldyn->gvir.xy+=itom[i].r.y*itom[i].f.x;
+               moldyn->gvir.xz+=itom[i].r.z*itom[i].f.x;
+               moldyn->gvir.yz+=itom[i].r.z*itom[i].f.y;
+
+               /* check forces regarding the given timestep */
+               if(v3_norm(&(itom[i].f))>\
+                   0.1*moldyn->nnd*itom[i].mass/moldyn->tau_square)
+                       printf("[moldyn] WARNING: pfc (high force: atom %d)\n",
+                              i);
+       }
+
+       return 0;
+}
+
+#endif // PTHREADS
index 5039ff7..4ca7141 100644 (file)
@@ -85,20 +85,28 @@ int tersoff_mult_set_params(t_moldyn *moldyn,int element1,int element2) {
                        p->h[1]=TM_H_C;
                        break;
                default:
-                       printf("[tersoff] WARNING: element1\n");
+                       printf("[tersoff] WARNING: element2\n");
                        return -1;
        }
 
        printf("[tersoff] parameter completion\n");
        p->S2[0]=p->S[0]*p->S[0];
        p->S2[1]=p->S[1]*p->S[1];
-       p->Smixed=sqrt(p->S[0]*p->S[1]);
-       p->S2mixed=p->Smixed*p->Smixed;
+       p->S2mixed=p->S[0]*p->S[1];
+       p->Smixed=sqrt(p->S2mixed);
        p->Rmixed=sqrt(p->R[0]*p->R[1]);
        p->Amixed=sqrt(p->A[0]*p->A[1]);
        p->Bmixed=sqrt(p->B[0]*p->B[1]);
        p->lambda_m=0.5*(p->lambda[0]+p->lambda[1]);
        p->mu_m=0.5*(p->mu[0]+p->mu[1]);
+       p->betaini[0]=pow(p->beta[0],p->n[0]);
+       p->betaini[1]=pow(p->beta[1],p->n[1]);
+       p->ci2[0]=p->c[0]*p->c[0];
+       p->ci2[1]=p->c[1]*p->c[1];
+       p->di2[0]=p->d[0]*p->d[0];
+       p->di2[1]=p->d[1]*p->d[1];
+       p->ci2di2[0]=p->ci2[0]/p->di2[0];
+       p->ci2di2[1]=p->ci2[1]/p->di2[1];
 
        printf("[tersoff] mult parameter info:\n");
        printf("  S (A)  | %f | %f | %f\n",p->S[0],p->S[1],p->Smixed);
@@ -118,36 +126,6 @@ int tersoff_mult_set_params(t_moldyn *moldyn,int element1,int element2) {
        return 0;
 }
 
-/* tersoff 1 body part */
-int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai) {
-
-       int brand;
-       t_tersoff_mult_params *params;
-       t_tersoff_exchange *exchange;
-       
-       brand=ai->brand;
-       params=moldyn->pot_params;
-       exchange=&(params->exchange);
-
-       /*
-        * simple: point constant parameters only depending on atom i to
-        *         their right values
-        */
-
-       exchange->beta_i=&(params->beta[brand]);
-       exchange->n_i=&(params->n[brand]);
-       exchange->c_i=&(params->c[brand]);
-       exchange->d_i=&(params->d[brand]);
-       exchange->h_i=&(params->h[brand]);
-
-       exchange->betaini=pow(*(exchange->beta_i),*(exchange->n_i));
-       exchange->ci2=params->c[brand]*params->c[brand];
-       exchange->di2=params->d[brand]*params->d[brand];
-       exchange->ci2di2=exchange->ci2/exchange->di2;
-
-       return 0;
-}
-       
 /* tersoff 2 body part */
 int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) {
 
@@ -239,7 +217,7 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) {
 #endif
 
        /* virial */
-       virial_calc(aj,&force,&dist_ij);
+       virial_calc(ai,&force,&dist_ij);
 
        /* energy 2bp contribution */
        energy=f_r*f_c;
@@ -364,10 +342,10 @@ int tersoff_mult_3bp_k1(t_moldyn *moldyn,
        cos_theta=v3_scalar_product(&dist_ij,&dist_ik)/(d_ij*d_ik);
 
        /* g_ijk */
-       h_cos=*(exchange->h_i)-cos_theta;
-       d2_h_cos2=exchange->di2+(h_cos*h_cos);
-       frac=exchange->ci2/d2_h_cos2;
-       g=1.0+exchange->ci2di2-frac;
+       h_cos=params->h[brand]-cos_theta;
+       d2_h_cos2=params->di2[brand]+(h_cos*h_cos);
+       frac=params->ci2[brand]/d2_h_cos2;
+       g=1.0+params->ci2di2[brand]-frac;
        dg=-2.0*frac*h_cos/d2_h_cos2;
 
        /* zeta sum += f_c_ik * g_ijk */
@@ -385,11 +363,8 @@ int tersoff_mult_3bp_k1(t_moldyn *moldyn,
        }
 
 #ifdef DEBUG
-       if((ai==&(moldyn->atom[0]))|
-          (aj==&(moldyn->atom[864]))|
-          (ak==&(moldyn->atom[1003]))) {
-               printf(" -> %f %f %f\n",exchange->ci2di2,frac,h_cos);
-       }
+       if(ai==&(moldyn->atom[DATOM]))
+               printf("zeta_ij: %f %f %f %f\n",f_c_ik*g,f_c_ik,g,d_ik);
 #endif
 
        /* store even more data for second k loop */
@@ -425,8 +400,8 @@ int tersoff_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) {
        params=moldyn->pot_params;
        exchange=&(params->exchange);
 
-       brand=aj->brand;
-       if(brand==ai->brand) {
+       brand=ai->brand;
+       if(brand==aj->brand) {
                S=params->S[brand];
                R=params->R[brand];
                B=params->B[brand];
@@ -473,8 +448,8 @@ int tersoff_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) {
                db=0.0;
        }
        else {
-               ni=*(exchange->n_i);
-               tmp=exchange->betaini*pow(exchange->zeta_ij,ni-1.0);
+               ni=params->n[brand];
+               tmp=params->betaini[brand]*pow(exchange->zeta_ij,ni-1.0);
                b=(1.0+exchange->zeta_ij*tmp);
                db=chi*pow(b,-1.0/(2.0*ni)-1.0);
                b=db*b;
@@ -489,12 +464,12 @@ int tersoff_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) {
        v3_add(&(aj->f),&(aj->f),&force);
 
 #ifdef DEBUG
-       if((ai==&(moldyn->atom[0]))|(aj==&(moldyn->atom[0]))) {
+       if((ai==&(moldyn->atom[DATOM]))|(aj==&(moldyn->atom[DATOM]))) {
                printf("force 3bp (j2): [%d %d sum]\n",ai->tag,aj->tag);
                printf("adding %f %f %f\n",force.x,force.y,force.z);
-               if(ai==&(moldyn->atom[0]))
+               if(ai==&(moldyn->atom[DATOM]))
                        printf("total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z);
-               if(aj==&(moldyn->atom[0]))
+               if(aj==&(moldyn->atom[DATOM]))
                        printf("total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z);
                printf("energy: %f = %f %f %f %f\n",0.5*f_c*(b*f_a+f_r),
                                                    f_c,b,f_a,f_r);
@@ -503,7 +478,7 @@ int tersoff_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) {
 #endif
 
        /* virial */
-       virial_calc(aj,&force,&(exchange->dist_ij));
+       virial_calc(ai,&force,&(exchange->dist_ij));
 
        /* dzeta prefactor = - 0.5 f_c f_a db */
        exchange->pre_dzeta=-0.5*f_a*f_c*db;
@@ -534,7 +509,7 @@ int tersoff_mult_3bp_k2(t_moldyn *moldyn,
        double pre_dzeta;
        double f_c_ik,df_c_ik;
        double dijdik_inv,fcdg,dfcg;
-       t_3dvec dcosdri,dcosdrj,dcosdrk;
+       t_3dvec dcosdrj,dcosdrk;
        t_3dvec force,tmp;
 
        params=moldyn->pot_params;
@@ -588,30 +563,11 @@ int tersoff_mult_3bp_k2(t_moldyn *moldyn,
        v3_scale(&dcosdrk,&dist_ij,dijdik_inv);
        v3_scale(&tmp,&dist_ik,-cos_theta/d_ik2);
        v3_add(&dcosdrk,&dcosdrk,&tmp);
-       v3_add(&dcosdri,&dcosdrj,&dcosdrk);
-       v3_scale(&dcosdri,&dcosdri,-1.0);
 
        /* f_c_ik * dg, df_c_ik * g */
        fcdg=f_c_ik*dg;
        dfcg=df_c_ik*g;
 
-       /* derivative wrt i */
-       v3_scale(&force,&dist_ik,dfcg);
-       v3_scale(&tmp,&dcosdri,fcdg);
-       v3_add(&force,&force,&tmp);
-       v3_scale(&force,&force,pre_dzeta);
-
-       /* force contribution */
-       v3_add(&(ai->f),&(ai->f),&force);
-       
-#ifdef DEBUG
-       if(ai==&(moldyn->atom[0])) {
-               printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag);
-               printf("adding %f %f %f\n",force.x,force.y,force.z);
-               printf("total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z);
-       }
-#endif
-
        /* derivative wrt j */
        v3_scale(&force,&dcosdrj,fcdg*pre_dzeta);
 
@@ -619,17 +575,22 @@ int tersoff_mult_3bp_k2(t_moldyn *moldyn,
        v3_add(&(aj->f),&(aj->f),&force);
 
 #ifdef DEBUG
-       if(aj==&(moldyn->atom[0])) {
+       if(aj==&(moldyn->atom[DATOM])) {
                printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag);
-               printf("adding %f %f %f\n",force.x,force.y,force.z);
-               printf("total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z);
+               printf("  adding %f %f %f\n",force.x,force.y,force.z);
+               printf("  total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z);
+               printf("  angle: %f\n",acos(cos_theta)*360.0/(2*M_PI));
+               printf("    d ij ik = %f %f\n",d_ij,d_ik);
        }
 #endif
 
        /* virial */
-       v3_scale(&force,&force,-1.0);
        virial_calc(ai,&force,&dist_ij);
 
+       /* force contribution to atom i */
+       v3_scale(&force,&force,-1.0);
+       v3_add(&(ai->f),&(ai->f),&force);
+
        /* derivative wrt k */
        v3_scale(&force,&dist_ik,-1.0*dfcg); // dri rik = - drk rik
        v3_scale(&tmp,&dcosdrk,fcdg);
@@ -640,19 +601,24 @@ int tersoff_mult_3bp_k2(t_moldyn *moldyn,
        v3_add(&(ak->f),&(ak->f),&force);
 
 #ifdef DEBUG
-       if(ak==&(moldyn->atom[0])) {
+       if(ak==&(moldyn->atom[DATOM])) {
                printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag);
-               printf("adding %f %f %f\n",force.x,force.y,force.z);
-               printf("total k: %f %f %f\n",ak->f.x,ak->f.y,ak->f.z);
+               printf("  adding %f %f %f\n",force.x,force.y,force.z);
+               printf("  total k: %f %f %f\n",ak->f.x,ak->f.y,ak->f.z);
+               printf("  angle: %f\n",acos(cos_theta)*360.0/(2*M_PI));
+               printf("    d ij ik = %f %f\n",d_ij,d_ik);
        }
 #endif
 
        /* virial */
-       v3_scale(&force,&force,-1.0);
        virial_calc(ai,&force,&dist_ik);
+
+       /* force contribution to atom i */
+       v3_scale(&force,&force,-1.0);
+       v3_add(&(ai->f),&(ai->f),&force);
        
        /* increase k counter */
-       exchange->kcount++;     
+       exchange->kcount++;
 
        return 0;
 
index a23503a..2e4f242 100644 (file)
@@ -28,17 +28,6 @@ typedef struct s_tersoff_echange {
        double dg[TERSOFF_MAXN];
        double cos_theta[TERSOFF_MAXN];
 
-       double *beta_i;
-       double *n_i;
-       double *c_i;
-       double *d_i;
-       double *h_i;
-
-       double ci2;
-       double di2;
-       double ci2di2;
-       double betaini;
-
        double zeta_ij;
        double pre_dzeta;
 
@@ -70,12 +59,17 @@ typedef struct s_tersoff_mult_params {
        double d[2];
        double h[2];
 
+       double ci2[2];
+       double di2[2];
+       double ci2di2[2];
+       double betaini[2];
+
        t_tersoff_exchange exchange;    /* exchange between 2bp and 3bp calc */
 } t_tersoff_mult_params;
 
 /* function prototypes */
 int tersoff_mult_set_params(t_moldyn *moldyn,int element1,int element2);
-int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai);
+//int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai);
 int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc);
 int tersoff_mult_3bp_j1(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc);
 int tersoff_mult_3bp_k1(t_moldyn *moldyn,
diff --git a/povconv b/povconv
index 122b3e8..0983b8e 100755 (executable)
--- a/povconv
+++ b/povconv
@@ -5,18 +5,20 @@
 # frank.zirkelbach@physik.uni-augsburg.de
 #
 
-if [ ! -d $1 ]; then
-        echo "no valid directory"
-        exit 1
-fi
+#if [ ! -d $1 ]; then
+#        echo "no valid directory"
+#        exit 1
+#fi
 
-TRG=$1/md.movie
+TRG="mdlat.in.xyz"
 
 rm -f $TRG
 
 ((frame=1))
 
-for file in $1/atomic_conf_*.xyz; do
+#for file in $1/atomic_conf_*.xyz; do
+
+file=$1
 
        count=`grep '# \[P\]' $file | awk '{ print $3 }'`
        time=`grep '# \[P\]' $file | awk '{ print $4 }'`
@@ -37,13 +39,14 @@ for file in $1/atomic_conf_*.xyz; do
 
        cat $file | grep -v '^#' | while read name x y z color temp; do
                # well, i only use Si and C
-               [ "$name" = "Si" ] && type=1
-               [ "$name" = "C" ] && type=2
-               echo "$name $x $y $z $type ${ac}" >> $TRG
+               [ "$name" = "Si" ] && type=0
+               [ "$name" = "C" ] && type=1
+               #echo "$name $x $y $z $type ${ac}" >> $TRG
+               echo "$name $x $y $z $type" >> $TRG
                ((ac+=1))
        done
 
        ((frame+=1))
-done
+#done
 
        
diff --git a/pse.h b/pse.h
index 3391d26..c746f2d 100644 (file)
--- a/pse.h
+++ b/pse.h
@@ -7,6 +7,7 @@
 
 #include "moldyn.h"
 
+#ifdef PSE_MASS
 static double pse_mass[]={
        0,
        0,
@@ -28,7 +29,9 @@ static double pse_mass[]={
        0,
        0,
 };
+#endif
 
+#ifdef PSE_LC
 static double pse_lc[]={
        0,
        0,
@@ -50,7 +53,9 @@ static double pse_lc[]={
        0,
        0,
 };
+#endif
 
+#ifdef PSE_NAME
 static char *pse_name[]={
        "*",
        "H",
@@ -72,7 +77,9 @@ static char *pse_name[]={
        "Cl",
        "Ar",
 };
+#endif
 
+#ifdef PSE_COL
 static char *pse_col[]={
        "*",
        "White",
@@ -94,4 +101,5 @@ static char *pse_col[]={
        "Cl",
        "Ar",
 };
+#endif
 
index 902cdef..292bc69 100644 (file)
@@ -109,6 +109,7 @@ double rand_get_gauss(t_random *random) {
                return random->gauss;
        }
 
+       a=0; b=0;
        w=0;
        while((w>=1.0)||(w==0.0)) {
                a=-2.0*rand_get_double(random)+1.0;
index 7247fbb..3ae541e 100644 (file)
@@ -11,3 +11,13 @@ c-c
 
 3.1: saves/c_in_si_prec_450_01/s-0566000.save 239458 240660 110 - 100
                                               239703 241605 100 - 100
+
+
+concatenated, differently oriented 100 dumbbells
+################################################
+
+posic_new/saves/c_in_si_prec_450_tot_02/s-0272000.save b 3.08 0.01
+
+ atoms 238338/1 238631/1 - 3.078045
+ atoms 238461/1 244278/1 - 3.085715
+
diff --git a/runmd b/runmd
index d50d9ae..609bcf3 100755 (executable)
--- a/runmd
+++ b/runmd
@@ -8,13 +8,15 @@ if [ ! -f ./config ]; then
        exit
 fi
 
-[ ! -d $1 ] && mkdir $1
+[ ! -d $1 ] && mkdir -p $1
 
 ./clean $1
 
 cp -v config $1/config
 
-time ./mdrun -c ./config -s $1
+mkdir -p logs
+logfile=logs/run_`basename $1`.log
+time ./mdrun -c ./config -s $1 | tee $logfile
 
 if [ "$?" == "0" ]; then
        #./perms
@@ -22,9 +24,28 @@ if [ "$?" == "0" ]; then
                # whole simulation cell
                #./visualize -w 640 -h 480 -d $1
 
-               # center unit cell
+               # crt
+               mkdir -p $1/crt
+               check=`grep crt\ init $logfile`
+               if [ "$check" = "  crt init" ]; then
+                       grep crt\ energy $logfile | \
+                               awk -F: '{ print $2 }' | \
+                               awk -F\ -\  '{ print $1 " " $2 }' > \
+                               $1/crt/energy
+                       for i in $1/s-crt_*.save; do
+                               nr=`basename $i | awk -F_ '{ print $2 }' | \
+                                       awk -F. '{ print $1 }'`
+                               ./s2xyz $i > $1/crt/atomic_conf_${nr}.xyz
+                       done
+                       ./visualize -w 640 -h 480 -d $1/crt \
+                                   -nll -0.56 -0.56 -0.76 -fur 0.56 0.56 0.56 \
+                                   -b -0.5 -0.5 -0.5 0.5 0.5 0.5 \
+                                   -c -0.2 -2.0 0.6 -L 0 0 -0.1 \
+                                   -r 0.6 -B 0.1
+               fi
+
                ./visualize -w 640 -h 480 -d $1 \
-                           -nll -0.56 -0.56 -0.56 -fur 0.56 0.56 0.56 \
+                           -nll -0.56 -0.56 -0.76 -fur 0.56 0.56 0.56 \
                            -b -0.5 -0.5 -0.5 0.5 0.5 0.5 \
                            -c -0.2 -2.0 0.6 -L 0 0 -0.1 \
                            -r 0.6 -B 0.1
@@ -32,5 +53,7 @@ if [ "$?" == "0" ]; then
                # old rasmol
                #rasmol -32 -nodisplay < $1/visualize.scr > /dev/null 2>&1
                ./ppm2avi $1
+
        fi
 fi
+
diff --git a/s2xyz.c b/s2xyz.c
new file mode 100644 (file)
index 0000000..5163e41
--- /dev/null
+++ b/s2xyz.c
@@ -0,0 +1,55 @@
+/*
+ * calcultae pair correlation function
+ *
+ * author: frank.zirkelbach@physik.uni-augsburg.de
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "moldyn.h"
+
+#define ME "[s2xyz]"
+
+int main(int argc,char **argv) {
+
+       t_moldyn moldyn;
+       int i,ret;
+       char color[2][64];
+       char type[2][8];
+
+       memset(&moldyn,0,sizeof(t_moldyn));
+
+       strcpy(color[0],"Yellow");
+       strcpy(type[0],"Si");
+       strcpy(color[1],"Gray");
+       strcpy(type[1],"C");
+
+       ret=moldyn_read_save_file(&moldyn,argv[1]);
+       if(ret) {
+               printf("%s exit!\n",ME);
+               return ret;
+       }
+
+
+       printf("# [P] %d 0 <0,0,0>\n",moldyn.count);
+
+       for(i=0;i<moldyn.count;i++)
+               printf("%s %f %f %f %s %f\n",
+                      type[moldyn.atom[i].brand],
+                      moldyn.atom[i].r.x,
+                      moldyn.atom[i].r.y,
+                      moldyn.atom[i].r.z,
+                      color[moldyn.atom[i].brand],
+                      moldyn.atom[i].ekin/EV);
+
+       return 0;
+}
+
diff --git a/s2xyz_script b/s2xyz_script
new file mode 100755 (executable)
index 0000000..98ee7f5
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+DIR="$1"
+
+for i in $1/s-*.save; do
+       FILE="`basename $i`"
+       NUM="`echo $FILE | awk -F- '{ print $2 }' | awk -F. '{ print $1 }'`"
+       TRG="$DIR/atomic_conf_${NUM}.xyz"
+       echo "converting $i -> $TRG"
+       ./s2xyz $i > $TRG
+done
+
+       
+       
diff --git a/sic.c b/sic.c
index e33d934..375c6d5 100644 (file)
--- a/sic.c
+++ b/sic.c
@@ -121,7 +121,7 @@ int insert_atoms(t_moldyn *moldyn) {
                                        dmin=d;
                        }
                }
-               add_atom(moldyn,INS_TYPE,INS_MASS,INS_BRAND,
+               add_atom(moldyn,INS_TYPE,INS_BRAND,
                         ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|\
                         INS_ATTR,
                         &r,&v);
@@ -325,25 +325,25 @@ int main(int argc,char **argv) {
        // diamond
 #ifdef ALBE
  #ifdef INIT_SI
-       create_lattice(&md,DIAMOND,ALBE_LC_SI,SI,M_SI,
+       create_lattice(&md,DIAMOND,ALBE_LC_SI,SI,
                       ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB,
-                      0,LCNTX,LCNTY,LCNTZ,NULL);
+                      0,LCNTX,LCNTY,LCNTZ,NULL,0,NULL);
  #endif
  #ifdef INIT_C
-       create_lattice(&md,DIAMOND,ALBE_LC_C,C,M_C,
+       create_lattice(&md,DIAMOND,ALBE_LC_C,C,
                       ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB,
-                      1,LCNTX,LCNTY,LCNTZ,NULL);
+                      1,LCNTX,LCNTY,LCNTZ,NULL,0,NULL);
  #endif
 #else
  #ifdef INIT_SI
-       create_lattice(&md,DIAMOND,LC_SI,SI,M_SI,
+       create_lattice(&md,DIAMOND,LC_SI,SI,
                       ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB,
-                      0,LCNTX,LCNTY,LCNTZ,NULL);
+                      0,LCNTX,LCNTY,LCNTZ,NULL,0,NULL);
  #endif
  #ifdef INIT_C
-       create_lattice(&md,DIAMOND,LC_C,SI,M_SI,
+       create_lattice(&md,DIAMOND,LC_C,SI,
                       ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB,
-                      1,LCNTX,LCNTY,LCNTZ,NULL);
+                      1,LCNTX,LCNTY,LCNTZ,NULL,0,NULL);
  #endif
 #endif
 
@@ -351,22 +351,22 @@ int main(int argc,char **argv) {
 #ifdef INIT_3CSIC
  #ifdef ALBE
        r.x=0.5*0.25*ALBE_LC_SIC; r.y=r.x; r.z=r.x;
-       create_lattice(&md,FCC,ALBE_LC_SIC,SI,M_SI,
+       create_lattice(&md,FCC,ALBE_LC_SIC,SI,
                       ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB,
-                      0,LCNTX,LCNTY,LCNTZ,&r);
+                      0,LCNTX,LCNTY,LCNTZ,&r,0,NULL);
        r.x+=0.25*ALBE_LC_SIC; r.y=r.x; r.z=r.x;
-       create_lattice(&md,FCC,ALBE_LC_SIC,C,M_C,
+       create_lattice(&md,FCC,ALBE_LC_SIC,C,
                       ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB|ATOM_ATTR_VB,
-                      1,LCNTX,LCNTY,LCNTZ,&r);
+                      1,LCNTX,LCNTY,LCNTZ,&r,0,NULL);
  #else
        r.x=0.5*0.25*TM_LC_SIC; r.y=r.x; r.z=r.x;
-       create_lattice(&md,FCC,TM_LC_SIC,SI,M_SI,
+       create_lattice(&md,FCC,TM_LC_SIC,SI,
                       ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB,
-                      0,LCNTX,LCNTY,LCNTZ,&r);
+                      0,LCNTX,LCNTY,LCNTZ,&r,0,NULL);
        r.x+=0.25*TM_LC_SIC; r.y=r.x; r.z=r.x;
-       create_lattice(&md,FCC,TM_LC_SIC,C,M_C,
+       create_lattice(&md,FCC,TM_LC_SIC,C,
                       ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB,
-                      1,LCNTX,LCNTY,LCNTZ,&r);
+                      1,LCNTX,LCNTY,LCNTZ,&r,0,NULL);
  #endif
 #endif
 
diff --git a/vasp_tools/Makefile b/vasp_tools/Makefile
new file mode 100644 (file)
index 0000000..177b5e9
--- /dev/null
@@ -0,0 +1,12 @@
+CC = gcc-4.3
+
+CFLAGS = -Wall -Winline
+CFLAGS += -O3 -march=native -msse2 -mfpmath=sse
+CFLAGS += -g
+
+LDFLAGS = -lm
+
+ALL = create_lattice
+
+all: $(ALL)
+
diff --git a/vasp_tools/acos.c b/vasp_tools/acos.c
new file mode 100644 (file)
index 0000000..609a6dc
--- /dev/null
@@ -0,0 +1,11 @@
+/* acos */
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+
+int main(int argc,char **argv) {
+       printf("%f\n",180.0/M_PI*acos(atof(argv[1])));
+       return 0;
+}
+
diff --git a/vasp_tools/angle_calc b/vasp_tools/angle_calc
new file mode 100755 (executable)
index 0000000..b23d51d
--- /dev/null
@@ -0,0 +1,101 @@
+#!/bin/bash
+
+file=$1
+atom=$2
+btom=$3
+ctom=$4
+
+((offset=8))
+
+scale=`sed -n 2p $file`
+X1=`sed -n 3p $file | awk '{ print $1 }'`
+X2=`sed -n 3p $file | awk '{ print $2 }'`
+X3=`sed -n 3p $file | awk '{ print $3 }'`
+Y1=`sed -n 4p $file | awk '{ print $1 }'`
+Y2=`sed -n 4p $file | awk '{ print $2 }'`
+Y3=`sed -n 4p $file | awk '{ print $3 }'`
+Z1=`sed -n 5p $file | awk '{ print $1 }'`
+Z2=`sed -n 5p $file | awk '{ print $2 }'`
+Z3=`sed -n 5p $file | awk '{ print $3 }'`
+export X1 X2 X3
+export Y1 Y2 Y3
+export Z1 Z2 Z3
+
+((line1=atom+offset))
+((line2=btom+offset))
+((line3=ctom+offset))
+
+temp="`sed -n ${line1}p $1`"
+xa=`echo $temp | awk '{ print $1 }'`
+ya=`echo $temp | awk '{ print $2 }'`
+za=`echo $temp | awk '{ print $3 }'`
+
+temp="`sed -n ${line2}p $1`"
+xb=`echo $temp | awk '{ print $1 }'`
+yb=`echo $temp | awk '{ print $2 }'`
+zb=`echo $temp | awk '{ print $3 }'`
+
+temp="`sed -n ${line3}p $1`"
+xc=`echo $temp | awk '{ print $1 }'`
+yc=`echo $temp | awk '{ print $2 }'`
+zc=`echo $temp | awk '{ print $3 }'`
+
+echo -en "angle: "
+foo=`echo "$xa $ya $za $xb $yb $zb $xc $yc $zc $scale" | \
+       awk ' \
+       BEGIN {
+               X1=ENVIRON["X1"]; X2=ENVIRON["X2"]; X3=ENVIRON["X3"]
+               Y1=ENVIRON["Y1"]; Y2=ENVIRON["Y2"]; Y3=ENVIRON["Y3"]
+               Z1=ENVIRON["Z1"]; Z2=ENVIRON["Z2"]; Z3=ENVIRON["Z3"]
+               pi=3.14159265
+       }       
+       {
+               X=sqrt(X1^2+X2^2+X3^2)
+               Y=sqrt(Y1^2+Y2^2+Y3^2)
+               Z=sqrt(Z1^2+Z2^2+Z3^2)
+               dx=$1-$4
+               dy=$2-$5
+               dz=$3-$6
+               if(dx>1/2)
+                       dx-=1
+               if(dx<-1/2)
+                       dx+=1
+               if(dy>1/2)
+                       dy-=1
+               if(dy<-1/2)
+                       dy+=1
+               if(dz>1/2)
+                       dz-=1
+               if(dz<-1/2)
+                       dz+=1
+               Dx=$1-$7
+               Dy=$2-$8
+               Dz=$3-$9
+               if(Dx>1/2)
+                       Dx-=1
+               if(Dx<-1/2)
+                       Dx+=1
+               if(Dy>1/2)
+                       Dy-=1
+               if(Dy<-1/2)
+                       Dy+=1
+               if(Dz>1/2)
+                       Dz-=1
+               if(Dz<-1/2)
+                       Dz+=1
+               dxt=dx*X1+dy*Y1+dz*Z1
+               dyt=dx*X2+dy*Y2+dz*Z2
+               dzt=dx*X3+dy*Y3+dz*Z3
+               Dxt=Dx*X1+Dy*Y1+Dz*Z1
+               Dyt=Dx*X2+Dy*Y2+Dz*Z2
+               Dzt=Dx*X3+Dy*Y3+Dz*Z3
+               sp=dxt*Dxt+dyt*Dyt+dzt*Dzt
+               d=sqrt(dxt^2+dyt^2+dzt^2)
+               D=sqrt(Dxt^2+Dyt^2+Dzt^2)
+               print sp/(d*D)
+       }'`
+
+./acos $foo
+
+echo
+
diff --git a/vasp_tools/avg_disp b/vasp_tools/avg_disp
new file mode 100755 (executable)
index 0000000..bd0a3d2
--- /dev/null
@@ -0,0 +1,99 @@
+#!/bin/bash
+
+file=$1
+init=$2
+
+sicnt=`sed -n 6p $file | awk '{ print $1 }'`
+ccnt=`sed -n 6p $file | awk '{ print $2 }'`
+((cnt=sicnt+ccnt))
+
+((offset=8))
+
+((count=1))
+
+x=0
+y=0
+z=0
+
+while [ $count -le $cnt ]; do
+
+       ((ln=count+offset))
+
+       temp="`sed -n ${ln}p $file`"
+       xa=`echo $temp | awk '{ print $1 }'`
+       ya=`echo $temp | awk '{ print $2 }'`
+       za=`echo $temp | awk '{ print $3 }'`
+
+       temp="`sed -n ${ln}p $init`"
+       xi=`echo $temp | awk '{ print $1 }'`
+       yi=`echo $temp | awk '{ print $2 }'`
+       zi=`echo $temp | awk '{ print $3 }'`
+
+       results=`echo $xa $ya $za $xi $yi $zi | awk '{
+               xa=$1
+               if($1<0.0)
+                       xa=$1+1.0
+               if($1>1.0)
+                       xa=$1-1.0
+               ya=$2
+               if($2<0.0)
+                       ya=$2+1.0
+               if($2>1.0)
+                       ya=$2-1.0
+               za=$3
+               if($3<0.0)
+                       za=$3+1.0
+               if($3>1.0)
+                       za=$3-1.0
+
+               xi=$4
+               if($4<0.0)
+                       xi=$4+1.0
+               if($4>1.0)
+                       xi=$4-1.0
+               yi=$5
+               if($5<0.0)
+                       yi=$5+1.0
+               if($5>1.0)
+                       yi=$5-1.0
+               zi=$6
+               if($6<0.0)
+                       zi=$6+1.0
+               if($6>1.0)
+                       zi=$6-1.0
+
+               dx=xa-xi
+               dy=ya-yi
+               dz=za-zi
+
+               if(dx>0.5)
+                       dx-=1
+               else if(dx<-0.5)
+                       dx+=1
+               if(dy>0.5)
+                       dy-=1
+               else if(dy<-0.5)
+                       dy+=1
+               if(dz>0.5)
+                       dz-=1
+               else if(dz<-0.5)
+                       dz+=1
+
+               print dx " " dy " " dz
+       }'`
+
+       dx=`echo $results | awk '{ print $1 }'`
+       dy=`echo $results | awk '{ print $2 }'`
+       dz=`echo $results | awk '{ print $3 }'`
+
+       x=`echo $x $dx | awk '{ print $1+$2 }'`
+       y=`echo $y $dy | awk '{ print $1+$2 }'`
+       z=`echo $z $dz | awk '{ print $1+$2 }'`
+
+       ((count+=1))
+
+done
+
+((count-=1))
+echo $x $y $z $count | awk '{ print $1/($4*3) " " $2/($4*3) " " $3/($4*3) }'
+
diff --git a/vasp_tools/constraint_mig_script b/vasp_tools/constraint_mig_script
new file mode 100755 (executable)
index 0000000..ca74b78
--- /dev/null
@@ -0,0 +1,74 @@
+#!/bin/bash
+
+# migration
+
+fx=0.1667178996794456
+fy=0.1667178996794456
+fz=0.0655951877086257
+
+((steps=20))
+((count=0))
+
+while [ $count -lt $steps ]; do
+
+       cnt=`printf "%02d" $count`
+
+       echo
+       echo
+       echo "run simulation $cnt ..."
+       [ $count != 0 ] &&
+               echo "  c atom at: `sed -n 226p CONTCAR`"
+       echo
+       echo
+       ../vasp.4.6-gamma-ct/vasp
+
+       cp POSCAR POSCAR.${cnt}
+       cp CONTCAR CONTCAR.${cnt}
+       cp OUTCAR OUTCAR.${cnt}
+
+       ltm="`sed -n 226p CONTCAR`"
+       val1=`echo $ltm | awk '{ print $1 }'`
+       val2=`echo $ltm | awk '{ print $2 }'`
+       val3=`echo $ltm | awk '{ print $3 }'`
+       val4=`echo $ltm | awk '{ print $4 }'`
+       val5=`echo $ltm | awk '{ print $5 }'`
+       val6=`echo $ltm | awk '{ print $6 }'`
+
+       ((rest=steps-count))
+
+       nx=`echo $val1 $fx $rest | awk '{ print $1+($2-$1)/$3 }'`
+       ny=`echo $val2 $fy $rest | awk '{ print $1+($2-$1)/$3 }'`
+       nz=`echo $val3 $fz $rest | awk '{ print $1+($2-$1)/$3 }'`
+
+       sed "s%$ltm%  $nx $ny $nz $val4 $val5 $val6%" CONTCAR > POSCAR
+
+        echo
+       echo "simulation $cnt end"
+        echo "  c atom now at: `sed -n 226p CONTCAR`"
+        echo "  dis x: `echo $val1 $fx $rest | awk '{ print ($2-$1)/$3 }'`"
+        echo "  dis y: `echo $val2 $fy $rest | awk '{ print ($2-$1)/$3 }'`"
+        echo "  dis z: `echo $val3 $fz $rest | awk '{ print ($2-$1)/$3 }'`"
+        echo
+
+       newline="`echo $val1 $fx $val2 $fy $val3 $fz | awk '\
+       BEGIN {
+               zrot=0; xrot=0; xyd=0; x=0; y=0; z=0;
+       }
+       {
+               x=$2-$1; y=$4-$3; z=$6-$5;
+               zrot=180.0*atan2(x,y)/3.14159265;
+               xyd=sqrt(x^2+y^2);
+               xrot=-180.0*atan2(z,xyd)/3.14159265;
+               print zrot " " xrot
+       }'`"
+
+       ltm="`sed -n 8p POSCAR`"
+       echo "info:"
+       echo "$ltm"
+       echo "->"
+       echo "$newline"
+       sed -i "s%$ltm%$newline%" POSCAR
+
+       ((count+=1))
+done
+
diff --git a/vasp_tools/create_dbc b/vasp_tools/create_dbc
new file mode 100755 (executable)
index 0000000..4b40c44
--- /dev/null
@@ -0,0 +1,141 @@
+#!/bin/bash
+
+# create POSCAR files for db combinations
+
+deltaC=0.1969
+deltaSi=0.1211
+
+clen=3
+
+file=$1/CONTCAR
+if [ ! -f $file ]; then
+       echo "no CONTCAR file in $1 ..."
+       exit
+fi
+
+lnumber=$2
+if [ -z $lnumber ]; then
+       echo "no line number specified ..."
+       exit
+fi
+
+gline="`sed -n 6p $file`"
+sic=`echo $gline | awk '{ print $1 }'`
+cc=`echo $gline | awk '{ print $2 }'`
+((tot=sic+cc))
+((addline=tot+8))
+
+ltm=`sed -n ${lnumber}p $file`
+
+echo "line to modify:"
+echo $ltm
+
+x=`echo $ltm | awk '{ print $1 }'`
+y=`echo $ltm | awk '{ print $2 }'`
+z=`echo $ltm | awk '{ print $3 }'`
+s1=`echo $ltm | awk '{ print $4 }'`
+s2=`echo $ltm | awk '{ print $5 }'`
+s3=`echo $ltm | awk '{ print $6 }'`
+
+echo "00-1:"
+nz=`echo $z $deltaSi $clen | awk '{
+       res=$1+($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed "s%$ltm%$x $y $nz $s1 $s2 $s3%" $file > POSCAR.00-1
+nz=`echo $z $deltaC $clen | awk '{
+       res=$1-($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed -i "$addline a\
+$x $y $nz T T T" POSCAR.00-1
+
+echo "001:"
+nz=`echo $z $deltaSi $clen | awk '{
+       res=$1-($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed "s%$ltm%$x $y $nz $s1 $s2 $s3%" $file > POSCAR.001
+nz=`echo $z $deltaC $clen | awk '{
+       res=$1+($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed -i "$addline a\
+$x $y $nz T T T" POSCAR.001
+
+echo "0-10:"
+ny=`echo $y $deltaSi $clen | awk '{
+       res=$1+($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed "s%$ltm%$x $ny $z $s1 $s2 $s3%" $file > POSCAR.0-10
+ny=`echo $y $deltaC $clen | awk '{
+       res=$1-($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed -i "$addline a\
+$x $ny $z T T T" POSCAR.0-10
+
+echo "010:"
+ny=`echo $y $deltaSi $clen | awk '{
+       res=$1-($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed "s%$ltm%$x $ny $z $s1 $s2 $s3%" $file > POSCAR.010
+ny=`echo $y $deltaC $clen | awk '{
+       res=$1+($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed -i "$addline a\
+$x $ny $z T T T" POSCAR.010
+
+echo "-100:"
+nx=`echo $x $deltaSi $clen | awk '{
+       res=$1+($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed "s%$ltm%$nx $y $z $s1 $s2 $s3%" $file > POSCAR.-100
+nx=`echo $x $deltaC $clen | awk '{
+       res=$1-($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed -i "$addline a\
+$nx $y $z T T T" POSCAR.-100
+
+echo "100:"
+nx=`echo $x $deltaSi $clen | awk '{
+       res=$1-($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed "s%$ltm%$nx $y $z $s1 $s2 $s3%" $file > POSCAR.100
+nx=`echo $x $deltaC $clen | awk '{
+       res=$1+($2/$3)
+       if(res>1.0) print res-1.0
+       else if(res<0.0) print res+1.0
+       else print res
+}'`
+sed -i "$addline a\
+$nx $y $z T T T" POSCAR.100
+
diff --git a/vasp_tools/create_intf_crude b/vasp_tools/create_intf_crude
new file mode 100755 (executable)
index 0000000..f5e0c3d
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+si_file=$1
+sic_file=$2
+
+cnt_si_si=`sed -n 6p $si_file`
+cnt_si_sic=`sed -n 6p $sic_file | awk '{ print $1 }'`
+cnt_c_sic=`sed -n 6p $sic_file | awk '{ print $2 }'`
+
+lc_si=`sed -n 2p $si_file`
+
+x_si=`sed -n 3p $si_file | awk '{ print $1 }'`
+x_sic=`sed -n 3p $sic_file | awk '{ print $1 }'`
+
+h_si=`sed -n 5p $si_file | awk '{ print $3 }'`
+h_sic=`sed -n 5p $sic_file | awk '{ print $3 }'`
+h_sic=`echo $h_sic $x_si $x_sic | awk '{ print $1*$2/$3 }'`
+
+((tot_si=cnt_si_si+cnt_si_sic))
+
+h_tot=`echo $h_si + $h_sic | bc`
+
+((offset=8))
+
+# header:
+sed -n 1,4p $si_file
+echo " 0.00000 0.00000 $h_tot"
+echo " $tot_si $cnt_c_sic"
+sed -n 7,8p $si_file
+
+# silicon atoms of si lattice (bottom)
+((cnt=1))
+while [ $cnt -le $cnt_si_si ]; do
+       ((gl=cnt+offset))
+       line=`sed -n ${gl}p $si_file`
+       x=`echo $line | awk '{ print $1 }'`
+       y=`echo $line | awk '{ print $2 }'`
+       z=`echo $line | awk '{ print $3 }'`
+       nz=`echo $z $h_tot $h_si | awk '{ print $1*$3/$2 }'`
+       echo " $x $y $nz T T T"
+       ((cnt+=1))
+done
+
+# silicon atoms of sic lattice (top / 2nd fcc)
+((cnt=1))
+while [ $cnt -le $cnt_si_sic ]; do
+       ((gl=cnt+offset+cnt_c_sic))
+       line=`sed -n ${gl}p $sic_file`
+       x=`echo $line | awk '{ print $1 }'`
+       y=`echo $line | awk '{ print $2 }'`
+       z=`echo $line | awk '{ print $3 }'`
+       nz=`echo $z $h_tot $h_si $h_sic | awk '{ print $1*$4/$2 + $3/$2 }'`
+       echo " $x $y $nz T T T"
+       ((cnt+=1))
+done
+
+# carbon atoms of sic lattice (top / 1st fcc <- odd counts)
+((cnt=1))
+while [ $cnt -le $cnt_c_sic ]; do
+       ((gl=cnt+offset))
+       line=`sed -n ${gl}p $sic_file`
+       x=`echo $line | awk '{ print $1 }'`
+       y=`echo $line | awk '{ print $2 }'`
+       z=`echo $line | awk '{ print $3 }'`
+       nz=`echo $z $h_tot $h_si $h_sic | awk '{ print $1*$4/$2 + $3/$2 }'`
+       echo " $x $y $nz T T T"
+       ((cnt+=1))
+done
+
diff --git a/vasp_tools/create_lattice.c b/vasp_tools/create_lattice.c
new file mode 100644 (file)
index 0000000..658fdb4
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * create lattice (for usage in vasp POSCAR file)
+ *
+ * author: Frank Zirkelbach <frank.zirkelbach@physik.uni-augsburg.de>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "../math/math.h"
+
+/*
+ * lattice types:
+ *
+ * there is fcc/diamond/zincblende only!
+ *
+ * basis:
+ *
+ * 0: <0.5 0.5 0> <0 0.5 0.5> <0.5 0 0.5> contains 2 atoms
+ * 1: <0.5 -0.5 0> <0.5 0.5 0> <0 0 1> contains 4 atoms
+ * 2: <1 0 0> <0 1 0> <0 0 1> contains 8 atoms
+ *
+ * atoms:
+ *
+ * - type 0:
+ *   1st fcc: <0 0 0>
+ *   2nd fcc: <0.25 0.25 0.25>
+ *   -> diag: <0.25 0.25 0.25>
+ *
+ * - type 1:
+ *   1st fcc: <0 0 0> <0.5 0.5 0.5>
+ *   2nd fcc: <0.5 0 0.25> <1.0 or 0.0 0.5 0.75>
+     -> diag: <0.5 0 0.25>
+ *
+ * - type 2:
+ *   1st fcc: <0 0 0> <0.5 0.5 0> <0.5 0 0.5> <0 0.5 0.5>
+ *   2nd fcc: <0.25 0.25 0.25> <0.75 0.75 0.25> <0.75 0.25 0.75>
+ *            <0.25 0.75 0.75>
+ *   -> diag: <0.25 0.25 0.25>
+ *
+ */
+
+int main(int argc,char **argv) {
+
+       int i,j,k,l,cnt,estimated;
+       int x,y,z;
+       t_3dvec basis[3];
+       t_3dvec o[3];
+       t_3dvec dia;
+       t_3dvec r,h;
+       char type,fccdia,foa,fixstr[6];
+
+       if(argc<6) {
+               printf("usage: %s type fcc/dia lx ly lz\n",argv[0]);
+               printf("  basis types: 0, 1, 2 (see code)\n");
+               printf("  fcc/dia: 0=fcc, 1=dia\n");
+               printf(" optional: foa (fix outer atoms)\n");
+               return -1;
+       }
+
+       type=argv[1][0];
+       fccdia=argv[2][0];
+
+       x=atoi(argv[3]);
+       y=atoi(argv[4]);
+       z=atoi(argv[5]);
+
+       foa=0;
+       if(argc==7)
+               foa=1;
+
+       dia.x=0.25;
+       dia.y=0.25;
+       dia.z=0.25;
+
+       if(type=='1') {
+               dia.x=0.0;
+               dia.y=0.5;
+               dia.z=0.25;
+       }
+
+       memset(basis,0,3*sizeof(t_3dvec));
+       memset(o,0,3*sizeof(t_3dvec));
+
+       if(type=='0') {
+               basis[0].x=0.5;
+               basis[0].y=0.5;
+               basis[1].y=0.5;
+               basis[1].z=0.5;
+               basis[2].x=0.5;
+               basis[2].z=0.5;
+       }
+
+       if(type=='1') {
+               basis[0].x=0.5;
+               basis[0].y=-0.5;
+               basis[1].x=0.5;
+               basis[1].y=0.5;
+               basis[2].z=1.0;
+               o[0].x=0.5;
+               o[0].y=0.5;
+               o[0].z=0.5;
+       }
+
+       if(type=='2') {
+               basis[0].x=1.0;
+               basis[1].y=1.0;
+               basis[2].z=1.0;
+               o[0].x=0.5;
+               o[0].y=0.5;
+               o[1].x=0.5;
+               o[1].z=0.5;
+               o[2].y=0.5;
+               o[2].z=0.5;
+       }
+
+       cnt=0;
+
+       estimated=1;
+       if(fccdia=='1') estimated*=2;
+       if(type=='1') estimated*=2;
+       if(type=='2') estimated*=4;
+       estimated*=x*y*z;
+
+       // print POSCAR 'header'
+
+       printf("cubic diamond\n");
+       printf(" 5.429\n");
+
+       v3_scale(&h,&basis[0],x);
+       printf(" %.5f %.5f %.5f\n",h.x,h.y,h.z);
+       v3_scale(&h,&basis[1],y);
+       printf(" %.5f %.5f %.5f\n",h.x,h.y,h.z);
+       v3_scale(&h,&basis[2],z);
+       printf(" %.5f %.5f %.5f\n",h.x,h.y,h.z);
+
+       printf(" %d\n",estimated);
+       printf("selective dynamics\n");
+       printf("direct\n");
+
+       // now print the coordinates
+       
+       for(i=0;i<x;i++) {
+               for(j=0;j<y;j++) {
+                       for(k=0;k<z;k++) {
+
+       // first atom (all types)
+       r.x=i;
+       r.y=j;
+       r.z=k;
+
+       strcpy(fixstr,"T T T");
+       if(((r.x==0)||(r.y==0)||(r.z==0))&foa)
+               strcpy(fixstr,"F F F");
+       printf(" %.5f %.5f %.5f %s\n",r.x/x,r.y/y,r.z/z,fixstr);
+       cnt+=1;
+
+       // second atom (type 1)
+       if(type=='1') {
+               v3_add(&h,&r,&(o[0]));
+               strcpy(fixstr,"T T T");
+               if(((h.x==0)||(h.y==0)||(h.z==0))&foa)
+                       strcpy(fixstr,"F F F");
+               printf(" %.5f %.5f %.5f T T T\n",h.x/x,h.y/y,h.z/z);
+               cnt+=1;
+       }
+
+       // face centered atoms (type 2)
+       if(type=='2') {
+               for(l=0;l<3;l++) {
+                       v3_add(&h,&r,&(o[l]));
+                       strcpy(fixstr,"T T T");
+                       if(((h.x==0)||(h.y==0)||(h.z==0))&foa)
+                               strcpy(fixstr,"F F F");
+                       printf(" %.5f %.5f %.5f T T T\n",h.x/x,h.y/y,h.z/z);
+                       cnt+=1;
+               }
+       }
+
+                       }
+               }
+       }
+
+       // second fcc lattice
+       if(fccdia=='1') {
+
+       for(i=0;i<x;i++) {
+               for(j=0;j<y;j++) {
+                       for(k=0;k<z;k++) {
+
+       // first atom (all types)
+       r.x=i;
+       r.y=j;
+       r.z=k;
+
+       // add the diagonal
+       v3_add(&r,&r,&dia);
+       
+       strcpy(fixstr,"T T T");
+       if(((r.x==0)||(r.y==0)||(r.z==0))&foa)
+               strcpy(fixstr,"F F F");
+       printf(" %.5f %.5f %.5f T T T\n",r.x/x,r.y/y,r.z/z);
+       cnt+=1;
+
+       // second atom (type 1)
+       if(type=='1') {
+               v3_add(&h,&r,&(o[0]));
+               strcpy(fixstr,"T T T");
+               if(((h.x==0)||(h.y==0)||(h.z==0))&foa)
+                       strcpy(fixstr,"F F F");
+               printf(" %.5f %.5f %.5f T T T\n",h.x/x,h.y/y,h.z/z);
+               cnt+=1;
+       }
+
+       // face centered atoms (type 2)
+       if(type=='2') {
+               for(l=0;l<3;l++) {
+                       v3_add(&h,&r,&(o[l]));
+                       strcpy(fixstr,"T T T");
+                       if(((h.x==0)||(h.y==0)||(h.z==0))&foa)
+                               strcpy(fixstr,"F F F");
+                       printf(" %.5f %.5f %.5f T T T\n",h.x/x,h.y/y,h.z/z);
+                       cnt+=1;
+               }
+       }
+
+                       }
+               }
+       }
+
+
+       }
+
+
+       if(estimated!=cnt) {
+               printf("\nWARNING! counted %d ions and estimated %d ions\n\n",
+                      cnt,estimated);
+       }
+
+       return 0;
+}
diff --git a/vasp_tools/disp_calc b/vasp_tools/disp_calc
new file mode 100755 (executable)
index 0000000..00ef43e
--- /dev/null
@@ -0,0 +1,160 @@
+#!/bin/bash
+
+file=$1
+init=$2
+atom=$3
+
+if [ -n "$4" ]; then
+ref=$4
+else
+ref=$atom
+fi
+echo "atom number $ref is used as a reference ..."
+echo
+
+scale=`sed -n 2p $file`
+
+X1=`sed -n 3p $file | awk '{ print $1 }'`
+X2=`sed -n 3p $file | awk '{ print $2 }'`
+X3=`sed -n 3p $file | awk '{ print $3 }'`
+
+Y1=`sed -n 4p $file | awk '{ print $1 }'`
+Y2=`sed -n 4p $file | awk '{ print $2 }'`
+Y3=`sed -n 4p $file | awk '{ print $3 }'`
+
+Z1=`sed -n 5p $file | awk '{ print $1 }'`
+Z2=`sed -n 5p $file | awk '{ print $2 }'`
+Z3=`sed -n 5p $file | awk '{ print $3 }'`
+
+export X1 X2 X3
+export Y1 Y2 Y3
+export Z1 Z2 Z3
+
+((offset=8))
+
+echo "final:"
+echo "scale: $scale"
+echo "X: $X1 $X2 $X3"
+echo "Y: $Y1 $Y2 $Y3"
+echo "Z: $Z1 $Z2 $Z3"
+
+((line1=atom+offset))
+
+temp="`sed -n ${line1}p $1`"
+xa=`echo $temp | awk '{ print $1 }'`
+ya=`echo $temp | awk '{ print $2 }'`
+za=`echo $temp | awk '{ print $3 }'`
+echo "(x,y,z) = $xa $ya $za $scale"
+
+results=`echo "$xa $ya $za $scale" | \
+       awk ' \
+       BEGIN {
+               X1=ENVIRON["X1"]; X2=ENVIRON["X2"]; X3=ENVIRON["X3"]
+               Y1=ENVIRON["Y1"]; Y2=ENVIRON["Y2"]; Y3=ENVIRON["Y3"]
+               Z1=ENVIRON["Z1"]; Z2=ENVIRON["Z2"]; Z3=ENVIRON["Z3"]
+       }       
+       {
+               X=sqrt(X1^2+X2^2+X3^2)
+               Y=sqrt(Y1^2+Y2^2+Y3^2)
+               Z=sqrt(Z1^2+Z2^2+Z3^2)
+               x=$1*X
+               if(x>1.0)
+                       x-=1.0;
+               if(x<-1.0)
+                       x+=1.0;
+               y=$2*Y
+               if(y>1.0)
+                       y-=1.0;
+               if(y<-1.0)
+                       y+=1.0;
+               z=$3*Z
+               if(z>1.0)
+                       z-=1.0;
+               if(z<-1.0)
+                       z+=1.0;
+
+               print x*$4 " " y*$4 " " z*$4
+       }'`
+
+xf=`echo $results | awk '{ print $1 }'`
+yf=`echo $results | awk '{ print $2 }'`
+zf=`echo $results | awk '{ print $3 }'`
+echo "---> $xf $yf $zf"
+
+file=$init
+
+scale=`sed -n 2p $file`
+
+X1=`sed -n 3p $file | awk '{ print $1 }'`
+X2=`sed -n 3p $file | awk '{ print $2 }'`
+X3=`sed -n 3p $file | awk '{ print $3 }'`
+
+Y1=`sed -n 4p $file | awk '{ print $1 }'`
+Y2=`sed -n 4p $file | awk '{ print $2 }'`
+Y3=`sed -n 4p $file | awk '{ print $3 }'`
+
+Z1=`sed -n 5p $file | awk '{ print $1 }'`
+Z2=`sed -n 5p $file | awk '{ print $2 }'`
+Z3=`sed -n 5p $file | awk '{ print $3 }'`
+
+export X1 X2 X3
+export Y1 Y2 Y3
+export Z1 Z2 Z3
+
+((offset=8))
+
+echo
+echo "initial:"
+echo "scale: $scale"
+echo "X: $X1 $X2 $X3"
+echo "Y: $Y1 $Y2 $Y3"
+echo "Z: $Z1 $Z2 $Z3"
+
+((line1=ref+offset))
+
+temp="`sed -n ${line1}p $file`"
+xa=`echo $temp | awk '{ print $1 }'`
+ya=`echo $temp | awk '{ print $2 }'`
+za=`echo $temp | awk '{ print $3 }'`
+echo "(x,y,z) = $xa $ya $za $scale"
+
+results=`echo "$xa $ya $za $scale" | \
+       awk ' \
+       BEGIN {
+               X1=ENVIRON["X1"]; X2=ENVIRON["X2"]; X3=ENVIRON["X3"]
+               Y1=ENVIRON["Y1"]; Y2=ENVIRON["Y2"]; Y3=ENVIRON["Y3"]
+               Z1=ENVIRON["Z1"]; Z2=ENVIRON["Z2"]; Z3=ENVIRON["Z3"]
+       }       
+       {
+               X=sqrt(X1^2+X2^2+X3^2)
+               Y=sqrt(Y1^2+Y2^2+Y3^2)
+               Z=sqrt(Z1^2+Z2^2+Z3^2)
+               x=$1*X
+               if(x>1.0)
+                       x-=1.0;
+               if(x<-1.0)
+                       x+=1.0;
+               y=$2*Y
+               if(y>1.0)
+                       y-=1.0;
+               if(y<-1.0)
+                       y+=1.0;
+               z=$3*Z
+               if(z>1.0)
+                       z-=1.0;
+               if(z<-1.0)
+                       z+=1.0;
+
+               print x*$4 " " y*$4 " " z*$4
+       }'`
+
+xi=`echo $results | awk '{ print $1 }'`
+yi=`echo $results | awk '{ print $2 }'`
+zi=`echo $results | awk '{ print $3 }'`
+echo "---> $xi $yi $zi"
+
+echo
+echo -en "displacement: "
+echo $xf $yf $zf $xi $yi $zi | awk '{ print $1-$4 " " $2-$5 " " $3-$6 }'
+echo
+
diff --git a/vasp_tools/dist_calc b/vasp_tools/dist_calc
new file mode 100755 (executable)
index 0000000..b397053
--- /dev/null
@@ -0,0 +1,88 @@
+#!/bin/bash
+
+file=$1
+atom=$2
+btom=$3
+
+scale=`sed -n 2p $1`
+
+X1=`sed -n 3p $file | awk '{ print $1 }'`
+X2=`sed -n 3p $file | awk '{ print $2 }'`
+X3=`sed -n 3p $file | awk '{ print $3 }'`
+
+Y1=`sed -n 4p $file | awk '{ print $1 }'`
+Y2=`sed -n 4p $file | awk '{ print $2 }'`
+Y3=`sed -n 4p $file | awk '{ print $3 }'`
+
+Z1=`sed -n 5p $file | awk '{ print $1 }'`
+Z2=`sed -n 5p $file | awk '{ print $2 }'`
+Z3=`sed -n 5p $file | awk '{ print $3 }'`
+
+export X1 X2 X3
+export Y1 Y2 Y3
+export Z1 Z2 Z3
+
+((offset=8))
+
+echo "scale: $scale"
+echo "X: $X1 $X2 $X3"
+echo "Y: $Y1 $Y2 $Y3"
+echo "Z: $Z1 $Z2 $Z3"
+echo
+
+((line1=atom+offset))
+((line2=btom+offset))
+
+temp="`sed -n ${line1}p $1`"
+xa=`echo $temp | awk '{ print $1 }'`
+ya=`echo $temp | awk '{ print $2 }'`
+za=`echo $temp | awk '{ print $3 }'`
+
+echo "atom 1:"
+echo $temp
+
+temp="`sed -n ${line2}p $1`"
+xb=`echo $temp | awk '{ print $1 }'`
+yb=`echo $temp | awk '{ print $2 }'`
+zb=`echo $temp | awk '{ print $3 }'`
+
+echo "atom 2:"
+echo $temp
+
+echo -en "distance: "
+echo "$xa $ya $za $xb $yb $zb $scale" | \
+       awk ' \
+       BEGIN {
+               X1=ENVIRON["X1"]; X2=ENVIRON["X2"]; X3=ENVIRON["X3"]
+               Y1=ENVIRON["Y1"]; Y2=ENVIRON["Y2"]; Y3=ENVIRON["Y3"]
+               Z1=ENVIRON["Z1"]; Z2=ENVIRON["Z2"]; Z3=ENVIRON["Z3"]
+       }       
+       {
+               X=sqrt(X1^2+X2^2+X3^2)
+               Y=sqrt(Y1^2+Y2^2+Y3^2)
+               Z=sqrt(Z1^2+Z2^2+Z3^2)
+               dx=$1-$4
+               dy=$2-$5
+               dz=$3-$6
+               if(dx>1/2)
+                       dx-=1
+               if(dx<-1/2)
+                       dx+=1
+               if(dy>1/2)
+                       dy-=1
+               if(dy<-1/2)
+                       dy+=1
+               if(dz>1/2)
+                       dz-=1
+               if(dz<-1/2)
+                       dz+=1
+               dxt=dx*X1+dy*Y1+dz*Z1
+               dyt=dx*X2+dy*Y2+dz*Z2
+               dzt=dx*X3+dy*Y3+dz*Z3
+               dist=sqrt(dxt^2+dyt^2+dzt^2)
+               dist*=$7
+               print dist
+       }'
+
+echo
+
diff --git a/vasp_tools/e_coh b/vasp_tools/e_coh
new file mode 100755 (executable)
index 0000000..f32283f
--- /dev/null
@@ -0,0 +1,81 @@
+#!/bin/bash
+
+file=$1
+
+[ -d $1 ] && file=$1/OUTCAR
+
+echo "parsing file $file ..."
+
+sicnt=`grep 'ions per' $file | awk '{ print $5 }'`
+ccnt=`grep 'ions per' $file | awk '{ print $6 }'`
+[ -z $ccnt ] && ccnt=0
+((total=sicnt+ccnt))
+echo "  Si: $sicnt, C: $ccnt, total: $total"
+
+cutoff=`grep ENCUT $file | awk '{ print $3 }' | awk -F. '{ print $1 }'`
+echo "  cutoff: $cutoff eV"
+
+pawpp=`grep POTCAR $file | tail -1 | awk '{ print $2 }'`
+if [ "$pawpp" = "PAW_GGA" ]; then
+       ext=_paw_gga
+       echo "  GGA and PAW"
+fi
+if [ "$pawpp" = "PAW" ]; then
+       ext=_paw
+       echo "  LDA and PAW"
+fi
+if [ "$pawpp" = "US" ]; then
+       help=`grep GGA $file | grep eV | tail -1 | awk '{ print $1i }'`
+       if [ -z $help ]; then
+               ext=_gga
+       echo "  GGA and PP"
+       else
+               ext=""
+       echo "  LDA and PP"
+       fi
+fi
+
+cnt=0
+tcnt=0
+
+energy=`grep energy\ without $file | tail -1 | awk '{ print $8 }'`
+
+sifile=free_atoms/si_free_${cutoff}${ext}/OUTCAR
+cfile=free_atoms/c_free_${cutoff}${ext}/OUTCAR
+
+if [ ! -f $sifile ]; then
+       echo
+       echo "$sifile not found ..."
+       echo
+       exit
+fi
+
+if [ ! -f $cfile ]; then
+       echo
+       echo "$cfile not found ..."
+       echo
+       exit
+fi
+
+free_si=`grep energy\ without $sifile | tail -1 | awk '{ print $8 }'`
+free_c=`grep energy\ without $cfile | tail -1 | awk '{ print $8 }'`
+echo "  Si correction: $free_si eV, C correction: $free_c eV"
+
+#echo "-> $energy | $total | $sicnt | $ccnt | $free_si | $free_c <-"
+echo $energy $total | \
+       awk '{ print "  total e: " $1 " eV, per atom: " $1/$2 " eV"}'
+echo "$energy $sicnt $ccnt $free_si $free_c" | \
+       awk '{ print "  cohesive energy (Si and C): " ($1-$2*$4-$3*$5)/($2+$3) " eV, " $1-$2*$4-$3*$5 " eV" }'
+echo "$energy $sicnt $free_c" | \
+       awk '{ print "  cohesive energy (C only): " ($1-$2*$3)/$2 " eV, " $1-$2*$3 " eV" }'
+#echo "$energy $total $free_si_250" | \
+#      awk '{ print "  cohesive energy (Si only 250): " ($1-$2*$3)/$2 " eV" }'
+#echo "$energy $sicnt $free_c_650" | \
+#      awk '{ print "  cohesive energy (C only 650): " ($1-$2*$3)/($2) " eV" }'
+#echo "$energy $sicnt $ccnt $free_si_650 $free_c_650" | \
+#      awk '{ print "  cohesive energy (Si and C 650): " ($1-$2*$4-$3*$5)/($2+$3) " eV" }'
+#echo "$energy $total" | \
+#      awk '{ print "  Si:C -> cohesive energy: "$1/$2 " eV" }'
+
+echo
+
diff --git a/vasp_tools/e_f b/vasp_tools/e_f
new file mode 100755 (executable)
index 0000000..877f66c
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+ready=`grep General\ timing $1/OUTCAR | awk '{ print $1 }'`
+
+if [ "$ready" = "General" ]; then
+       echo "$i seems to be finisched ..."
+./e_form plain_si_2333_nosym_sp plain_c_2333_nosym_sp $1
+else
+       echo "$i not yet finished ..."
+fi
+
diff --git a/vasp_tools/e_f_tersoff b/vasp_tools/e_f_tersoff
new file mode 100755 (executable)
index 0000000..ef75640
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+ready=`grep General\ timing $1/OUTCAR | awk '{ print $1 }'`
+
+default="plain_si_2333_nosym_sp plain_sic_2333_nosym_sp"
+
+test=`echo $1 | awk -F_ '{ print $3 }'`
+
+if [ -d plain_si_${test}_nosym_sp ]; then
+       [ -d plain_sic_${test}_nosym_sp ] && \
+               default="plain_si_${test}_nosym_sp plain_sic_${test}_nosym_sp"
+fi
+
+if [ "$ready" = "General" ]; then
+       echo "$i seems to be finisched ..."
+       echo "reference: $default"
+#./e_form_tersoff plain_si_2333_nosym_sp plain_sic_2333_nosym_sp $1
+./e_form_tersoff $default $1
+else
+       echo "$i not yet finished ..."
+fi
+
diff --git a/vasp_tools/e_fc b/vasp_tools/e_fc
new file mode 100755 (executable)
index 0000000..af24d00
--- /dev/null
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+ready=`grep General\ timing $1/OUTCAR | awk '{ print $1 }'`
+
+if [ "$ready" = "General" ]; then
+       echo "$i seems to be finisched ..."
+
+e=`./e_form plain_si_2333_nosym_sp plain_c_2333_nosym_sp $1 | grep M2 | \
+       awk '{ print $4 }'`
+echo "E_f = $e"
+
+ec100=3.15438
+r=`echo $e $ec100 $ec100 | awk '{ print $1-$2-$3 }'`
+echo "C 100: $r"
+
+ec110=3.59738
+r=`echo $e $ec100 $ec110 | awk '{ print $1-$2-$3 }'`
+echo "C 110: $r"
+
+ecsub=1.38891
+r=`echo $e $ec100 $ecsub | awk '{ print $1-$2-$3 }'`
+echo "C sub: $r"
+
+ecbc=4.09638
+r=`echo $e $ec100 $ecbc | awk '{ print $1-$2-$3 }'`
+echo "C bc: $r"
+
+esvac=3.62905
+r=`echo $e $ec100 $esvac | awk '{ print $1-$2-$3 }'`
+echo "Si vac: $r"
+
+es110=3.38999
+r=`echo $e $ec100 $es110 | awk '{ print $1-$2-$3 }'`
+echo "Si 110: $r"
+
+estet=3.76899
+r=`echo $e $ec100 $estet | awk '{ print $1-$2-$3 }'`
+echo "Si tet: $r"
+
+eshex=3.41999
+r=`echo $e $ec100 $eshex | awk '{ print $1-$2-$3 }'`
+echo "Si hex: $r"
+
+else
+       echo "$i not yet finished ..."
+fi
+
diff --git a/vasp_tools/e_fc_tersoff b/vasp_tools/e_fc_tersoff
new file mode 100755 (executable)
index 0000000..4e8b74c
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+ready=`grep General\ timing $1/OUTCAR | awk '{ print $1 }'`
+
+if [ "$ready" = "General" ]; then
+       echo "$i seems to be finisched ..."
+
+e=`./e_form_tersoff plain_si_2333_nosym_sp plain_sic_2333_nosym_sp $1 | grep M2 | \
+       awk '{ print $4 }'`
+echo "E_f = $e"
+
+ec100=3.72027
+r=`echo $e $ec100 $ec100 | awk '{ print $1-$2-$3 }'`
+echo "C 100: $r"
+
+ec110=4.16327
+r=`echo $e $ec100 $ec110 | awk '{ print $1-$2-$3 }'`
+echo "C 110: $r"
+
+ecsub=1.9548
+r=`echo $e $ec100 $ecsub | awk '{ print $1-$2-$3 }'`
+echo "C sub: $r"
+
+ecbc=4.66227
+r=`echo $e $ec100 $ecbc | awk '{ print $1-$2-$3 }'`
+echo "C bc: $r"
+
+esvac=3.62905
+r=`echo $e $ec100 $esvac | awk '{ print $1-$2-$3 }'`
+echo "Si vac: $r"
+
+es110=3.38999
+r=`echo $e $ec100 $es110 | awk '{ print $1-$2-$3 }'`
+echo "Si 110: $r"
+
+estet=3.76899
+r=`echo $e $ec100 $estet | awk '{ print $1-$2-$3 }'`
+echo "Si tet: $r"
+
+eshex=3.41999
+r=`echo $e $ec100 $eshex | awk '{ print $1-$2-$3 }'`
+echo "Si hex: $r"
+
+r=`echo $e $es110 $ecsub | awk '{ print $1-$2-$3 }'`
+echo "Si 110 and C sub: $r"
+
+r=`echo $e $estet $ecsub | awk '{ print $1-$2-$3 }'`
+echo "Si tet and C sub: $r"
+
+else
+       echo "$i not yet finished ..."
+fi
+
diff --git a/vasp_tools/e_form b/vasp_tools/e_form
new file mode 100755 (executable)
index 0000000..7c9e490
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+
+if [ $# = 2 ]; then
+
+echo "Calculation of formation energy (Method 1, single species)"
+echo "  Result: `basename $2`, Initial conf: `basename $1`"
+echo
+
+e1only=`./e_coh $1 | grep cohesive | grep only | awk '{ print $5 }'`
+e2only=`./e_coh $2 | grep cohesive | grep only | awk '{ print $5 }'`
+e1and=`./e_coh $1 | grep cohesive | grep and | awk '{ print $6 }'`
+e2and=`./e_coh $2 | grep cohesive | grep and | awk '{ print $6 }'`
+count=`./e_coh $2 | grep ^\ \ Si: | awk '{ print $6 }'`
+
+echo "$e1only $e2only $count" | \
+       awk '{ print "  formation energy M1 (Si and C): "($2-$1)*$3 " eV" }'
+echo "$e1and $e2and $count" | \
+       awk '{ print "  formation energy M1 (C only): "($2-$1)*$3 " eV" }'
+echo
+
+fi
+
+if [ $# = 3 ]; then
+
+echo "Calculation of formation energy (Method 2, two species)"
+
+e3=`./e_coh $3 | grep cohesive | grep and | awk '{ print $6 }'`
+sicnt=`./e_coh $3 | grep ^\ \ Si: | awk '{ print $2 }' | sed 's/,//'`
+ccnt=`./e_coh $3 | grep ^\ \ Si: | awk '{ print $4 }' | sed 's/,//'`
+et=`echo $e3 $sicnt $ccnt | awk '{ print $1*($2+$3) }'`
+echo "  Interstitial configuration: `basename $3` -> $et"
+e1=`./e_coh $1 | grep cohesive | grep and | awk '{ print $6 }'`
+e2=`./e_coh $2 | grep cohesive | grep only | awk '{ print $5 }'`
+echo "  Cohesive energies:"
+echo "    `basename $1` -> $e1 ($sicnt)"
+echo "    `basename $2` -> $e2 ($ccnt)"
+
+((count = sicnt + ccnt))
+
+echo "$et $sicnt $e1 $ccnt $e2" | \
+       awk '{ print "  formation energy M2: "$1-$2*$3-$4*$5 " eV" }'
+echo
+
+fi
+
diff --git a/vasp_tools/e_form_tersoff b/vasp_tools/e_form_tersoff
new file mode 100755 (executable)
index 0000000..9cbb5d2
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+
+if [ $# = 2 ]; then
+
+echo "unsupported ..."
+
+fi
+
+if [ $# = 3 ]; then
+
+echo "Calculation of formation energy (Method 2, two species)"
+
+e3=`./e_coh $3 | grep cohesive | grep and | awk '{ print $6 }'`
+sicnt=`./e_coh $3 | grep ^\ \ Si: | awk '{ print $2 }' | sed 's/,//'`
+ccnt=`./e_coh $3 | grep ^\ \ Si: | awk '{ print $4 }' | sed 's/,//'`
+et=`echo $e3 $sicnt $ccnt | awk '{ print $1*($2+$3) }'`
+echo "  Interstitial configuration: `basename $3` -> $et"
+e1=`./e_coh $1 | grep cohesive | grep and | awk '{ print $6 }'`
+e2=`./e_coh $2 | grep cohesive | grep and | awk '{ print $6 }'`
+emuc=`echo $e2 $e1 | awk '{ print 2*$1-$2 }'`
+echo "  Cohesive energies:"
+echo "    `basename $1` -> $e1 ($sicnt)"
+echo "    `basename $2` -> $emuc / $e2 ($ccnt)"
+
+((count = sicnt + ccnt))
+
+#echo "$et $sicnt $e1 $ccnt $emuc" | \
+#      awk '{ print "  formation energy M2: "$1-$2*$3-$4*$5 " eV" }'
+echo "$et $sicnt $e1 $ccnt $e2" | \
+       awk '{ print "  formation energy M2: "$1-($2-$4)*$3-$4*$5*2 " eV" }'
+echo
+
+fi
+
diff --git a/vasp_tools/get_ks_levels b/vasp_tools/get_ks_levels
new file mode 100755 (executable)
index 0000000..8ef690e
--- /dev/null
@@ -0,0 +1,123 @@
+#!/bin/bash
+
+# get the kohn sham levels (plotted nicely)
+
+# spin component 1
+
+file=$1/OUTCAR
+
+WUP=1.2
+WDOWN=1.8
+PS=2
+OPT=7
+UPT=4
+
+if [ ! -f $file ]; then
+       echo "no OUTCAR file found ..."
+       exit
+fi
+
+rm -f $1/ks_levels_*
+
+center="0"
+
+cntup=0
+echo $cntup > $1/temp_cu
+fup=0
+echo $fup > $1/temp_fu
+cntdown=0
+echo $cntdown > $1/temp_cd
+fdown=0
+echo $fdown > $1/temp_fd
+
+# spin component 1
+startline=`grep -n spin\ component\ 1 $file | tail -1 | awk -F: '{ print $1 }'`
+echo -en "spin component 1 ($startline)... "
+sed -n "$startline,/spin component 2/p" $file | grep ^' '*[0-9] | \
+       while read number energy occu; do
+               if [ "$occu" = "1.00000" ]; then
+               echo "0.18 $energy 0.1" >> $1/ks_levels_o
+               cntup=`cat $1/temp_cu`
+               ((cntup+=1))
+               echo $cntup > $1/temp_cu
+               elif [ "$occu" = "0.00000" ]; then
+               echo "0.18 $energy 0.1" >> $1/ks_levels_u
+               else
+               echo "0.18 $energy 0.1" >> $1/ks_levels_p
+               fup=`cat $1/temp_fu`
+               fup=`echo $fup $occu | awk '{ print $1+$2 }'`
+               echo $fup > $1/temp_fu
+               fi
+       done
+echo "done"
+
+# spin component 2
+startline=`grep -n spin\ component\ 2 $file | tail -1 | awk -F: '{ print $1 }'`
+echo -en "spin component 2 ($startline) ... "
+sed -n "$startline,/---/p" $file | grep ^' '*[0-9] | \
+       while read number energy occu; do
+               if [ "$occu" = "1.00000" ]; then
+               echo "0.42 $energy 0.1" >> $1/ks_levels_o
+               cntdown=`cat $1/temp_cd`
+               ((cntdown+=1))
+               echo $cntdown > $1/temp_cd
+               elif [ "$occu" = "0.00000" ]; then
+                       if [ "$center" = "0" ]; then
+                               echo -en "setting mid value -> $energy ... "
+                               center=$energy
+                               echo "$energy" > $1/temp_e
+                       fi
+               echo "0.42 $energy 0.1" >> $1/ks_levels_u
+               else
+               echo "0.42 $energy 0.1" >> $1/ks_levels_p
+               fdown=`cat $1/temp_fd`
+               fdown=`echo $fdown $occu | awk '{ print $1+$2 }'`
+               echo $fdown > $1/temp_fd
+               fi
+       done
+echo "done"
+
+cntup=`cat $1/temp_cu`
+fup=`cat $1/temp_fu`
+cntdown=`cat $1/temp_cd`
+fdown=`cat $1/temp_fd`
+center=`cat $1/temp_e`
+yl=`echo $center $WDOWN | awk '{ print $1-$2 }'`
+yh=`echo $center $WUP | awk '{ print $1+$2 }'`
+fup=`awk -v var=$fup 'BEGIN{ printf"%0.f\n", var }'`
+fdown=`awk -v var=$fdown 'BEGIN{ printf"%0.f\n", var }'`
+((cntup+=fup))
+((cntdown+=fdown))
+((difference=cntup-cntdown))
+echo "generating gnuplot file ($center, $yl, $yh, $ly) ..."
+cat > $1/ksl_plot.gpi <<!
+plot "ks_levels_o" w xerrorbars pt $OPT ps $PS t "", "ks_levels_u" w xerrorbars pt $UPT ps $PS t "", "ks_levels_p" w xerrorbars pt $OPT ps $PS t ""
+unset bars
+set ylabel "Kohn-Sham levels [eV]"
+set xrange [0:0.6]
+set yrange [$yl:$yh]
+set xlabel "Spin up / down"
+set format x ""
+set x2label "$cntup / $cntdown (Delta: $difference)"
+unset xtics
+set mytics 5
+set size ratio 3.0
+replot
+set term epslatex standalone color solid size 3.5,7
+set out "ksl.tex"
+replot
+!
+
+cd $1
+
+echo "running gnuplot and latex ..."
+gnuplot ksl_plot.gpi
+latex ksl
+dvips ksl
+gv ksl
+
+cd ../..
+
+echo "done"
+echo "file: $1/ksl.ps"
+echo
diff --git a/vasp_tools/interPOS b/vasp_tools/interPOS
new file mode 100755 (executable)
index 0000000..0dec6a3
--- /dev/null
@@ -0,0 +1,97 @@
+#!/bin/bash
+
+((offset=8))
+
+images=4
+[ ! -z $1 ] && images=$1
+
+echo "doing interpolation for $images images"
+
+start=0
+((fin=images+1))
+
+nsi=`sed -n 6p 00/POSCAR | awk '{ print $1 }'`
+nc=`sed -n 6p 00/POSCAR | awk '{ print $2 }'`
+((tot=nsi+nc))
+
+echo "$tot atoms found"
+
+x1=`sed -n 3p 00/POSCAR | awk '{ print $1 }'`
+x2=`sed -n 3p 00/POSCAR | awk '{ print $2 }'`
+x3=`sed -n 3p 00/POSCAR | awk '{ print $3 }'`
+
+y1=`sed -n 4p 00/POSCAR | awk '{ print $1 }'`
+y2=`sed -n 4p 00/POSCAR | awk '{ print $2 }'`
+y3=`sed -n 4p 00/POSCAR | awk '{ print $3 }'`
+
+z1=`sed -n 5p 00/POSCAR | awk '{ print $1 }'`
+z2=`sed -n 5p 00/POSCAR | awk '{ print $2 }'`
+z3=`sed -n 5p 00/POSCAR | awk '{ print $3 }'`
+
+# final 
+
+dir=`printf "%02d" $fin`
+
+X1=`sed -n 3p $dir/POSCAR | awk '{ print $1 }'`
+X2=`sed -n 3p $dir/POSCAR | awk '{ print $2 }'`
+X3=`sed -n 3p $dir/POSCAR | awk '{ print $3 }'`
+
+Y1=`sed -n 4p $dir/POSCAR | awk '{ print $1 }'`
+Y2=`sed -n 4p $dir/POSCAR | awk '{ print $2 }'`
+Y3=`sed -n 4p $dir/POSCAR | awk '{ print $3 }'`
+
+Z1=`sed -n 5p $dir/POSCAR | awk '{ print $1 }'`
+Z2=`sed -n 5p $dir/POSCAR | awk '{ print $2 }'`
+Z3=`sed -n 5p $dir/POSCAR | awk '{ print $3 }'`
+
+fdir=$dir
+
+((cnt=1))
+while [ $cnt -lt $fin ]; do
+       dir=`printf "%02d" $cnt`
+       if [ ! -d $dir ]; then
+               echo "creating dir $dir ..."
+               mkdir $dir
+       fi
+       sed -n 1p 00/POSCAR > $dir/POSCAR
+       sed -n 2p 00/POSCAR >> $dir/POSCAR
+       echo $x1 $X1 $x2 $X2 $x3 $X3 $cnt $fin| awk '{
+               ratio=$7/$8
+               print "  " $1+($2-$1)*ratio " " $3+($4-$3)*ratio " " $5+($6-$5)*ratio
+       }' >> $dir/POSCAR
+       echo $y1 $Y1 $y2 $Y2 $y3 $Y3 $cnt $fin| awk '{
+               ratio=$7/$8
+               print "  " $1+($2-$1)*ratio " " $3+($4-$3)*ratio " " $5+($6-$5)*ratio
+       }' >> $dir/POSCAR
+       echo $z1 $Z1 $z2 $Z2 $z3 $Z3 $cnt $fin| awk '{
+               ratio=$7/$8
+               print "  " $1+($2-$1)*ratio " " $3+($4-$3)*ratio " " $5+($6-$5)*ratio
+       }' >> $dir/POSCAR
+       sed -n 6p 00/POSCAR >> $dir/POSCAR
+       sed -n 7p 00/POSCAR >> $dir/POSCAR
+       sed -n 8p 00/POSCAR >> $dir/POSCAR
+       ((cnt+=1))
+done
+
+((acnt=1))
+
+while [ $acnt -le $tot ]; do
+       ((cnt=1))
+       ((ltg=acnt+offset))
+       x=`sed -n ${ltg}p 00/POSCAR | awk '{ print $1 }'`
+       X=`sed -n ${ltg}p $fdir/POSCAR | awk '{ print $1 }'`
+       y=`sed -n ${ltg}p 00/POSCAR | awk '{ print $2 }'`
+       Y=`sed -n ${ltg}p $fdir/POSCAR | awk '{ print $2 }'`
+       z=`sed -n ${ltg}p 00/POSCAR | awk '{ print $3 }'`
+       Z=`sed -n ${ltg}p $fdir/POSCAR | awk '{ print $3 }'`
+       while [ $cnt -lt $fin ]; do
+               dir=`printf "%02d" $cnt`
+               echo $x $X $y $Y $z $Z $cnt $fin| awk '{
+                       ratio=$7/$8
+                       print "  " $1+($2-$1)*ratio " " $3+($4-$3)*ratio " " $5+($6-$5)*ratio " T T T"
+               }' >> $dir/POSCAR
+               ((cnt+=1))
+       done
+       ((acnt+=1))
+done
+
diff --git a/vasp_tools/lastxyz2video b/vasp_tools/lastxyz2video
new file mode 100755 (executable)
index 0000000..f2f3142
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+if [ -d video ]; then
+       echo "moving video directory ..."
+       mv -v video v_tmp
+fi
+
+mkdir video
+
+for i in video.??; do
+       cp -v `ls $i/atomic_conf*.xyz | tail -1` \
+               video/atomic_conf_`echo $i | awk -F. '{ print $2 }'`.xyz;
+done
+
+echo "done"
diff --git a/vasp_tools/mig_calc b/vasp_tools/mig_calc
new file mode 100755 (executable)
index 0000000..506fdae
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+if [ ! -d $1 ] ; then
+       echo "no valid dir"
+       exit
+fi
+
+last=""
+rc=0.0
+
+for i in $1/OUTCAR.*; do
+       index=`echo $i | awk -F. '{ print $2 }'`
+       if [ ! -f $1/CONTCAR.${index} ] ; then
+               echo "no such file: CONTCAR.${index}"
+               exit
+       else
+               cfile=$1/CONTCAR.${index}
+       fi
+       if [ -z $last ]; then
+               last=$cfile
+               lst=$index
+       fi
+
+       acnt=`sed -n 6p $cfile | awk '{ print $1 }'`
+       ((acnt+=9))
+       ((lcnt=9))
+
+       while [ $lcnt -le $acnt ]; do
+               line="`sed -n ${lcnt}p $cfile`"
+               x1=`echo $line | awk '{ print $1 }'`
+               x2=`echo $line | awk '{ print $2 }'`
+               x3=`echo $line | awk '{ print $3 }'`
+               line="`sed -n ${lcnt}p $last`"
+               y1=`echo $line | awk '{ print $1 }'`
+               y2=`echo $line | awk '{ print $2 }'`
+               y3=`echo $line | awk '{ print $3 }'`
+               rc=`echo $rc $x1 $x2 $x3 $y1 $y2 $y3 |\
+                       awk '{ print $1+sqrt(($2-$5)^2+($3-$6)^2+($4-$7)^2) }'`
+               ((lcnt+=1))
+       done
+
+       energy=`./e_coh $i | grep Si\ and\ C | awk '{ print $8 }'`
+       
+       echo "$rc $energy"
+
+       last=$cfile
+       lst=$index      
+done
diff --git a/vasp_tools/mig_fullct.sh b/vasp_tools/mig_fullct.sh
new file mode 100755 (executable)
index 0000000..43f2e82
--- /dev/null
@@ -0,0 +1,101 @@
+#!/bin/bash
+
+# migration
+
+if [ ! -f POSCAR.init ]; then
+       echo "no initial configuration file, aborting ..."
+       exit
+fi
+
+if [ ! -f POSCAR.final ]; then
+       echo "no final configuration file, aborting ..."
+       exit
+fi
+
+echo "Info:"
+echo $LANG
+bash --version
+echo
+echo
+
+((steps=10))
+((count=1))
+((offset=8))
+
+while [ $count -le $steps ]; do
+
+       cnt=`printf "%02d" $count`
+
+       # create the POSCAR file
+       if [ $count -eq 1 ]; then
+               cp -v POSCAR.init CONTCAR
+       fi
+
+       srcfile=CONTCAR
+       sed -n 1,6p $srcfile > POSCAR
+       echo "Transformed selective dynamics" >> POSCAR
+       echo "Direct" >> POSCAR
+       sicnt=`sed -n 6p $srcfile | awk '{ print $1 }'`
+       ccnt=`sed -n 6p $srcfile | awk '{ print $2 }'`
+       ((tot=sicnt+ccnt))
+
+       ((acnt=1))
+       while [ $acnt -le $tot ]; do
+               ((lcnt=acnt+offset))
+               line="`sed -n ${lcnt}p $srcfile`"
+               xo=`echo $line | awk '{ print $1 }'`
+               yo=`echo $line | awk '{ print $2 }'`
+               zo=`echo $line | awk '{ print $3 }'`
+               line="`sed -n ${lcnt}p POSCAR.final`"
+               xn=`echo $line | awk '{ print $1 }'`
+               yn=`echo $line | awk '{ print $2 }'`
+               zn=`echo $line | awk '{ print $3 }'`
+
+               echo "$xo $yo $zo $xn $yn $zn $count $steps" | awk '{
+                       if($1<0) xo=$1+1.0
+                       else xo=$1
+                       if($2<0) yo=$2+1.0
+                       else yo=$2
+                       if($3<0) zo=$3+1.0
+                       else zo=$3
+                       if($4<0) xn=$4+1.0
+                       else xn=$4
+                       if($5<0) yn=$5+1.0
+                       else yn=$5
+                       if($6<0) zn=$6+1.0
+                       else zn=$6
+                       dx=xn-xo
+                       if(dx>0.5) dx-=1.0;
+                       if(dx<-0.5) dx+=1.0;
+                       dy=yn-yo
+                       if(dy>0.5) dy-=1.0;
+                       if(dy<-0.5) dy+=1.0;
+                       dz=zn-zo
+                       if(dz>0.5) dz-=1.0;
+                       if(dz<-0.5) dz+=1.0;
+                       zrot=180.0*atan2(dx,dy)/3.14159265
+                       xrot=-180.0*atan2(dz,sqrt(dx^2+dy^2))/3.14159265
+                       frac=1.0/($8-$7+1)
+                       x=xo+dx*frac
+                       y=yo+dy*frac
+                       z=zo+dz*frac
+                       print " " x " " y " " z " T F T " zrot " " xrot
+               }' >> POSCAR
+
+               ((acnt+=1))
+       done
+
+       echo
+       echo
+       echo "run simulation $cnt ..."
+       echo
+       echo
+       ../vasp.4.6-gamma-fullct/vasp
+
+       cp -v POSCAR POSCAR.${cnt}
+       cp -v CONTCAR CONTCAR.${cnt}
+       cp -v OUTCAR OUTCAR.${cnt}
+
+       ((count+=1))
+done
+
diff --git a/vasp_tools/o_init2moldyn b/vasp_tools/o_init2moldyn
new file mode 100755 (executable)
index 0000000..837712e
--- /dev/null
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+for i in OUTCAR*; do
+       app=`echo $i | awk -F. '{ print $2 }'`
+       [ ! -z $app ] && app=".$app"
+
+rm -rf video$app
+mkdir -p video$app
+
+sicnt=`grep 'ions per' $i | awk '{ print $5 }'`
+ccnt=`grep 'ions per' $i | awk '{ print $6 }'`
+
+((total=sicnt+ccnt))
+
+echo "parsing file $PWD/$i ..."
+echo "  Si: $sicnt, C: $ccnt, total: $total"
+
+cnt=0
+tcnt=0
+
+cx=1.0
+cy=1.0
+cz=0.8
+
+sed -n -e '/ position of ions in cartesian/,/----/p' $i | \
+       grep -v POS | grep -v total | grep -v -- ^\ - | \
+       while read x y z; do
+
+       time=`printf "%05d" $tcnt`
+       #echo -en "$tcnt/$cnt "
+       [ "$cnt" = "0" ] && \
+               echo "# P $total $time <$cx,$cy,$cz>" > \
+                       video$app/atomic_conf_$time.xyz
+
+       type="Si"
+       color="Yellow"
+       force=0.0
+       if [ $cnt -ge $sicnt ]; then
+               type="C"
+               color="Gray"
+       fi
+       echo "$type $x $y $z $color $force" >> \
+               video$app/atomic_conf_$time.xyz
+       
+       ((cnt+=1))
+       if [ $cnt -eq $total ]; then
+               cnt=0
+               ((tcnt+=1))
+               echo -en "$tcnt "
+       fi
+done
+
+echo
+
+done
+
diff --git a/vasp_tools/outcar2moldyn b/vasp_tools/outcar2moldyn
new file mode 100755 (executable)
index 0000000..6950453
--- /dev/null
@@ -0,0 +1,64 @@
+#!/bin/bash
+
+for i in OUTCAR*; do
+       app=`echo $i | awk -F. '{ print $2 }'`
+       [ ! -z $app ] && app=".$app"
+
+if [ "$1" = "renew" ]; then
+       rm -rf video$app
+fi
+
+if [ -d video$app ]; then
+       echo "skipping $app ... (use $0 renew to force rebuild)"
+       continue
+fi
+
+mkdir -p video$app
+
+sicnt=`grep 'ions per' $i | awk '{ print $5 }'`
+ccnt=`grep 'ions per' $i | awk '{ print $6 }'`
+
+((total=sicnt+ccnt))
+
+echo "parsing file $PWD/$i ..."
+echo "  Si: $sicnt, C: $ccnt, total: $total"
+
+cnt=0
+tcnt=0
+
+cx=1.0
+cy=1.0
+cz=0.8
+
+sed -n -e '/POSITION/,/total/p' $i | \
+       grep -v POS | grep -v total | grep -v -- ^\ - | \
+       while read x y z fx fy fz; do
+
+       time=`printf "%05d" $tcnt`
+       #echo -en "$tcnt/$cnt "
+       [ "$cnt" = "0" ] && \
+               echo "# P $total $time <$cx,$cy,$cz>" > \
+                       video$app/atomic_conf_$time.xyz
+
+       type="Si"
+       color="Yellow"
+       force=`echo "sqrt($fx*$fx+$fy*$fy+$fz*$fz)" | bc`
+       if [ $cnt -ge $sicnt ]; then
+               type="C"
+               color="Gray"
+       fi
+       echo "$type $x $y $z $color $force" >> \
+               video$app/atomic_conf_$time.xyz
+       
+       ((cnt+=1))
+       if [ $cnt -eq $total ]; then
+               cnt=0
+               ((tcnt+=1))
+               echo -en "$tcnt "
+       fi
+done
+
+echo
+
+done
+
diff --git a/vasp_tools/pc_calc.c b/vasp_tools/pc_calc.c
new file mode 100644 (file)
index 0000000..db12f50
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * pc_calc.c - calculate the pc
+ *
+ * author: frank.zirkelbach@physik.uni-augsburg.de
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <math.h>
+
+
+#define MAXR   6.0
+#define DELTA  0.01
+
+typedef struct s_atom {
+       double x,y,z;
+       char type;
+} t_atom;
+
+int get_line(int fd,char *line,int max) {
+
+        int count,ret;
+
+        count=0;
+
+        while(1) {
+                if(count==max) return count;
+                ret=read(fd,line+count,1);
+                if(ret<=0) return ret;
+                if(line[count]=='\n') {
+                        memset(line+count,0,max-count-1);
+                        //line[count]='\0';
+                        return count+1;
+                }
+                count+=1;
+        }
+}
+
+int get_max3_vals(char *buf,int amount,double *v1, double *v2,double *v3) {
+
+       int i,j,k;
+       char temp[128];
+
+       i=0;
+
+       for(k=0;k<amount;k++) {
+               while(buf[i]==' ')
+                       i++;
+               j=0;
+               while((buf[i+j]!=' ')&&(buf[i+j]!=0))
+                       j++;
+               memcpy(temp,buf+i,j);
+               temp[j]=0;
+               if(k==0) *v1=atof(temp);
+               if(k==1) *v2=atof(temp);
+               if(k==2) *v3=atof(temp);
+               i+=j;
+       }
+
+       return 0;
+}
+
+int get_2_ints(char *buf,int *i1,int *i2) {
+
+       int i,j,k;
+       char temp[128];
+
+       i=0;
+
+       for(k=0;k<2;k++) {
+               while(buf[i]==' ')
+                       i++;
+               j=0;
+               while((buf[i+j]!=' ')&&(buf[i+j]!=0))
+                       j++;
+               memcpy(temp,buf+i,j);
+               temp[j]=0;
+               if(k==0) *i1=atoi(temp);
+               if(k==1) *i2=atoi(temp);
+               i+=j;
+       }
+
+       return 0;
+}
+
+int main(int argc,char **argv) {
+
+       t_atom *atom;
+       double *aslot,*bslot,*cslot;
+       int cnt,count,fcnt,slots;
+       int fd;
+       char buf[256];
+       int i,j,k;
+       int nsi,nc,ntot;
+       double dx,dy,dz,dist,norm;
+       double dxt,dyt,dzt;
+       double X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3;
+       double scale;
+
+       atom=NULL;
+
+       if(argc<1) {
+               printf("usage: %s file1 file2 ...\n",
+                      argv[0]);
+               return -1;
+       }
+
+       // prepare pc
+       slots=MAXR/DELTA;
+       aslot=malloc(slots*sizeof(double));
+       if(aslot==NULL) {
+               perror("slot a\n");
+               return -1;
+       }
+       memset(aslot,0,slots*sizeof(double));
+       bslot=malloc(slots*sizeof(double));
+       if(bslot==NULL) {
+               perror("slot a\n");
+               return -1;
+       }
+       memset(bslot,0,slots*sizeof(double));
+       cslot=malloc(slots*sizeof(double));
+       if(cslot==NULL) {
+               perror("slot a\n");
+               return -1;
+       }
+       memset(cslot,0,slots*sizeof(double));
+       printf("i: allocated 3 times %d slots ...\n",slots);
+
+       // use all given files ...
+       printf("using files:\n");
+       for(fcnt=1;fcnt<argc;fcnt++)
+               printf(" %d: %s\n",fcnt,argv[fcnt]);
+
+       for(fcnt=1;fcnt<argc;fcnt++) {
+
+       fd=open(argv[fcnt],O_RDONLY);
+       if(fd<0) {
+               perror("open file\n");
+               return fd;
+       }
+
+       // first line
+       cnt=get_line(fd,buf,256);
+
+       // second line -> scale
+       cnt=get_line(fd,buf,256);
+       get_max3_vals(buf,1,&scale,NULL,NULL);
+       printf("scale: %f\n",scale);
+
+       // third line -> X
+       cnt=get_line(fd,buf,256);
+       get_max3_vals(buf,3,&X1,&X2,&X3);
+       printf("X: %f %f %f\n",X1,X2,X3);
+       
+       // 4th line -> Y
+       cnt=get_line(fd,buf,256);
+       get_max3_vals(buf,3,&Y1,&Y2,&Y3);
+       printf("Y: %f %f %f\n",Y1,Y2,Y3);
+       
+       // 5th line -> Z
+       cnt=get_line(fd,buf,256);
+       get_max3_vals(buf,3,&Z1,&Z2,&Z3);
+       printf("Z: %f %f %f\n",Z1,Z2,Z3);
+       
+       // 6th line -> nsi + nc = ntot
+       cnt=get_line(fd,buf,256);
+       get_2_ints(buf,&nsi,&nc);
+       ntot=nsi+nc;
+       printf("Si: %d - C: %d - tot: %d\n",nsi,nc,ntot);
+       
+       // 7th line
+       cnt=get_line(fd,buf,256);
+
+       // 8th line
+       cnt=get_line(fd,buf,256);
+
+       // read in atoms
+       count=0;
+       while(count<ntot) {
+               cnt=get_line(fd,buf,256);
+               if(cnt<=0) {
+                       printf("Should never happen!\n");
+                       return cnt;
+               }
+
+               atom=realloc(atom,(count+1)*sizeof(t_atom));
+               if(count<nsi)
+                       atom[count].type='S';
+               else
+                       atom[count].type='C';
+
+               get_max3_vals(buf,3,
+                             &(atom[count].x),
+                             &(atom[count].y),
+                             &(atom[count].z));
+
+               count+=1;
+       }
+
+       printf("i: read in %d atoms ...\n",count);
+
+       // calc pc
+       for(i=0;i<count;i++) {
+               for(j=0;j<i;j++) {
+                       dx=atom[i].x-atom[j].x;
+                       if(dx>0.5)
+                               dx-=1;
+                       else if(dx<-0.5)
+                               dx+=1;
+
+                       dy=atom[i].y-atom[j].y;
+                       if(dy>0.5)
+                               dy-=1;
+                       else if(dy<-0.5)
+                               dy+=1;
+
+                       dz=atom[i].z-atom[j].z;
+                       if(dz>0.5)
+                               dz-=1;
+                       else if(dz<-0.5)
+                               dz+=1;
+
+                       dxt=dx*X1+dy*Y1+dz*Z1;
+                       dyt=dx*X2+dy*Y2+dz*Z2;
+                       dzt=dx*X3+dy*Y3+dz*Z3;
+
+                       dist=sqrt(dxt*dxt+dyt*dyt+dzt*dzt);
+                       dist*=scale;
+
+                       if(dist>=MAXR)
+                               continue;
+                       k=dist/DELTA;
+                       if((atom[i].type=='S')&&(atom[j].type=='S')) {
+                               aslot[k]+=1;
+                       }
+                       else if((atom[i].type=='C')&&(atom[j].type=='C')) {
+                               bslot[k]+=1;
+                       }
+                       else {
+                               cslot[k]+=1;
+                       }
+               }
+       }
+
+       close(fd);
+
+       }
+
+       // normalization and output
+       for(i=1;i<slots;i++) {
+               norm=4*M_PI*(i*DELTA)*(i*DELTA)*DELTA;
+               norm*=(argc-1);
+               printf("pc: %f %f %f %f\n",i*DELTA,
+                                          aslot[i]/norm,
+                                          bslot[i]/norm,
+                                          cslot[i]/norm);
+       }
+
+       free(aslot);
+       free(bslot);
+       free(cslot);
+
+       free(atom);
+
+       return 0;
+
+}
+
diff --git a/vasp_tools/pc_script b/vasp_tools/pc_script
new file mode 100755 (executable)
index 0000000..05ad174
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+if [ ! -d $1 ]; then
+       echo "not a valid directory ..."
+       exit
+fi
+
+app=""
+if [ ! -z $2 ]; then
+       app=".${2}"
+fi
+
+if [ ! -f $1/CONTCAR${app} ]; then
+       echo "no vasp data found in $1 ..."
+       exit
+fi
+
+files=`ls $1/CONTCAR${app}`
+
+echo "running on:"
+echo " $files"
+
+./pc_calc2 $files | grep ^pc | \
+       awk '{ print $2 " " $3 " " $4 " "$5 }' > $1/pc${app}.txt
+
+echo "done, pc stored in $1/pc_${app}.txt"
+
diff --git a/vasp_tools/poscar2moldyn b/vasp_tools/poscar2moldyn
new file mode 100755 (executable)
index 0000000..a4f2562
--- /dev/null
@@ -0,0 +1,73 @@
+#!/bin/bash
+
+mkdir -p video
+
+if [ -z $1 ]; then
+       file=POSCAR
+       app=""
+else
+       file=$1
+       app=".`echo $file | awk -F. '{ print $2 }'`"
+fi
+
+echo "parsing $file file ..."
+
+sicnt=`sed -n 6p $file | awk '{ print $1 }'`
+ccnt=`sed -n 6p $file | awk '{ print $2 }'`
+
+lc=`sed -n 2p $file | awk '{ print $1 }'`
+
+x1=`sed -n 3p $file | awk '{ print $1 }'`
+x2=`sed -n 3p $file | awk '{ print $2 }'`
+x3=`sed -n 3p $file | awk '{ print $3 }'`
+
+y1=`sed -n 4p $file | awk '{ print $1 }'`
+y2=`sed -n 4p $file | awk '{ print $2 }'`
+y3=`sed -n 4p $file | awk '{ print $3 }'`
+
+z1=`sed -n 5p $file | awk '{ print $1 }'`
+z2=`sed -n 5p $file | awk '{ print $2 }'`
+z3=`sed -n 5p $file | awk '{ print $3 }'`
+
+((total=sicnt+ccnt))
+((eoa=total+8))
+
+echo "  Si: $sicnt, C: $ccnt, total: $total"
+echo "  Lattice constant: $lc A"
+echo "  Basis:"
+echo "      $x1      $y1      $z1"
+echo "  x = $x2  y = $y2  z = $z2"
+echo "      $x3      $y3      $z3"
+
+cnt=0
+tcnt=0
+
+cx=1.0
+cy=1.0
+cz=0.8
+
+echo "# P $total init <$cx,$cy,$cz>" > video/atomic_conf_init${app}.xyz
+
+sed -n 9,${eoa}p $file | \
+       while read x y z fx fy fz; do
+               type="Si"
+               color="Yellow"
+               if [ $cnt -ge $sicnt ]; then
+                       type="C"
+                       color="Gray"
+               fi
+               X=`echo $x $y $z $x1 $y1 $z1 | \
+                       awk '{ print $1*$4+$2*$5+$3*$6 }'`
+               Y=`echo $x $y $z $x2 $y2 $z2 | \
+                       awk '{ print $1*$4+$2*$5+$3*$6 }'`
+               Z=`echo $x $y $z $x3 $y3 $z3 | \
+                       awk '{ print $1*$4+$2*$5+$3*$6 }'`
+               X=`echo $lc $X | awk '{ print $1*$2 }'`
+               Y=`echo $lc $Y | awk '{ print $1*$2 }'`
+               Z=`echo $lc $Z | awk '{ print $1*$2 }'`
+               echo "$type $X $Y $Z $color 0.0" >> video/atomic_conf_init${app}.xyz
+               ((cnt+=1))
+       done
+
+echo "done"
+
diff --git a/vasp_tools/ppm2avi b/vasp_tools/ppm2avi
new file mode 100755 (executable)
index 0000000..74c8370
--- /dev/null
@@ -0,0 +1,13 @@
+#for i in $1/*.ppm; do
+#      convert $i $1/$(basename $i ppm)png
+#done
+
+MFOPTS="-mf fps=13:type=png"
+#MFOPTS="-mf fps=25:type=png"
+
+OUTFILE=md.avi
+[ -n "$2" ] && OUTFILE=$2
+
+#mencoder mf://$1/*.png -ovc copy -o $1/$OUTFILE >/dev/null 2>&1
+mencoder $MFOPTS mf://$1/*.png -ovc xvid -xvidencopts bitrate=1000 \
+         -o $1/$OUTFILE >/dev/null 2>&1
diff --git a/vasp_tools/runvasp_rx200 b/vasp_tools/runvasp_rx200
new file mode 100755 (executable)
index 0000000..13d67bf
--- /dev/null
@@ -0,0 +1,20 @@
+# create run file
+NTH=1
+[ ! -z "$1" ] && NTH=$1
+WORKDIR=`pwd`
+rf=`basename $WORKDIR`
+cat > run_$rf <<-EOF
+#!/bin/bash
+#$ -S /bin/bash
+#$ -cwd
+#$ -pe smp $NTH
+
+export LD_LIBRARY_PATH=/opt/intel/mkl/9.1.021/lib/em64t
+../vasp.4.6/vasp
+
+EOF
+
+# submit job
+qsub -q all.q run_$rf
+
+
diff --git a/vasp_tools/runvasp_rx200_gamma b/vasp_tools/runvasp_rx200_gamma
new file mode 100755 (executable)
index 0000000..57ab562
--- /dev/null
@@ -0,0 +1,20 @@
+# create run file
+NTH=1
+[ ! -z "$1" ] && NTH=$1
+WORKDIR=`pwd`
+rf=`basename $WORKDIR`
+cat > run_$rf <<-EOF
+#!/bin/bash
+#$ -S /bin/bash
+#$ -cwd
+#$ -pe smp $NTH
+
+export LD_LIBRARY_PATH=/opt/intel/mkl/9.1.021/lib/em64t
+../vasp.4.6-gamma/vasp
+
+EOF
+
+# submit job
+qsub -q all.q run_$rf
+
+
diff --git a/vasp_tools/sd_rot.patch b/vasp_tools/sd_rot.patch
new file mode 100644 (file)
index 0000000..c0c15f2
--- /dev/null
@@ -0,0 +1,407 @@
+diff -Nur vasp.4.6/dyna.F vasp.4.6-ct/dyna.F
+--- vasp.4.6/dyna.F    2009-07-22 15:12:20.032980043 +0200
++++ vasp.4.6-ct/dyna.F 2009-09-18 08:32:08.666016928 +0200
+@@ -1164,6 +1164,83 @@
+ !*********************************************************************
+ !
++! subroutine to transform vectors into the rotated constraints system
++!
++!*********************************************************************
++
++      SUBROUTINE SD_ROT(T_INFO,VEC,DIR,NI)
++      USE poscar
++      IMPLICIT NONE
++
++      TYPE (type_info)   T_INFO
++      REAL(q)            VEC(3),TMP(3)
++      CHARACTER*1        DIR
++      
++      INTEGER            M,NI
++
++      IF((.NOT. T_INFO%LSFOR(1,NI)).OR. &
++     &   (.NOT. T_INFO%LSFOR(2,NI)).OR. &
++     &   (.NOT. T_INFO%LSFOR(3,NI))) THEN
++         IF (DIR=='F') THEN
++            IF (T_INFO%SD_ROT_Z/=0._q) THEN
++               DO M=1,3
++                  TMP(M)=VEC(M)
++               ENDDO
++               VEC(1)=COS(T_INFO%SD_ROT_Z)*TMP(1)- &
++     &                SIN(T_INFO%SD_ROT_Z)*TMP(2)
++               VEC(2)=SIN(T_INFO%SD_ROT_Z)*TMP(1)+ &
++     &                COS(T_INFO%SD_ROT_Z)*TMP(2)
++               WRITE(*,*) 'SD rotate DEBUG (Z^-1): ',NI
++               WRITE(*,*) '  F: ', TMP(1),' ',TMP(2),' ',TMP(3)
++               WRITE(*,*) ' to: ',VEC(1),' ',VEC(2),' ',VEC(3)
++            ENDIF
++            IF (T_INFO%SD_ROT_X/=0._q) THEN
++               DO M=1,3
++                  TMP(M)=VEC(M)
++               ENDDO
++               VEC(2)=COS(T_INFO%SD_ROT_X)*TMP(2)- &
++     &                SIN(T_INFO%SD_ROT_X)*TMP(3)
++               VEC(3)=SIN(T_INFO%SD_ROT_X)*TMP(2)+ &
++     &                COS(T_INFO%SD_ROT_X)*TMP(3)
++               WRITE(*,*) 'SD rotate DEBUG (X^-1): ',NI
++               WRITE(*,*) '  F: ', TMP(1),' ',TMP(2),' ',TMP(3)
++               WRITE(*,*) ' to: ',VEC(1),' ',VEC(2),' ',VEC(3)
++            ENDIF
++         ELSE
++            IF (T_INFO%SD_ROT_X/=0._q) THEN
++               DO M=1,3
++                  TMP(M)=VEC(M)
++               ENDDO
++               VEC(2)=COS(-T_INFO%SD_ROT_X)*TMP(2)- &
++     &                SIN(-T_INFO%SD_ROT_X)*TMP(3)
++               VEC(3)=SIN(-T_INFO%SD_ROT_X)*TMP(2)+ &
++     &                COS(-T_INFO%SD_ROT_X)*TMP(3)
++               WRITE(*,*) 'SD rotate DEBUG (X): ',NI
++               WRITE(*,*) '  B: ', TMP(1),' ',TMP(2),' ',TMP(3)
++               WRITE(*,*) ' to: ',VEC(1),' ',VEC(2),' ',VEC(3)
++            ENDIF
++            IF (T_INFO%SD_ROT_Z/=0._q) THEN
++               DO M=1,3
++                  TMP(M)=VEC(M)
++               ENDDO
++               VEC(1)=COS(-T_INFO%SD_ROT_Z)*TMP(1)- &
++     &                SIN(-T_INFO%SD_ROT_Z)*TMP(2)
++               VEC(2)=SIN(-T_INFO%SD_ROT_Z)*TMP(1)+ &
++     &                COS(-T_INFO%SD_ROT_Z)*TMP(2)
++               WRITE(*,*) 'SD rotate DEBUG (Z): ',NI
++               WRITE(*,*) '  B: ', TMP(1),' ',TMP(2),' ',TMP(3)
++               WRITE(*,*) ' to: ',VEC(1),' ',VEC(2),' ',VEC(3)
++            ENDIF
++         ENDIF
++      ENDIF
++
++      RETURN
++
++      END
++
++
++!*********************************************************************
++!
+ ! subroutine to set selected force components to zero
+ !
+ !*********************************************************************
+@@ -1184,19 +1261,44 @@
+       IF (T_INFO%LSDYN) THEN
+ !-----Selective dynamics here ... :
+          DO NI=1,T_INFO%NIONS
++!-----transformed selective dynamics
++            IF(T_INFO%SD_ROT) THEN
++               DO M=1,3
++                  VTMP(M)=VEL(M,NI)
++               ENDDO
++               CALL SD_ROT(T_INFO,VTMP,'F',NI)
++               DO M=1,3
++                  VEL(M,NI)=VTMP(M)
++               ENDDO
++            ENDIF
+ !-----reset the velocities of the selected coordinates ...
+             DO M=1,3
+                IF (.NOT.T_INFO%LSFOR(M,NI)) VEL(M,NI)=0._q
+             ENDDO
++!-----transform back to direct coordinates
++            IF(T_INFO%SD_ROT) THEN
++               DO M=1,3
++                  VTMP(M)=VEL(M,NI)
++               ENDDO
++               CALL SD_ROT(T_INFO,VTMP,'B',NI)
++               DO M=1,3
++                  VEL(M,NI)=VTMP(M)
++               ENDDO
++            ENDIF
+ !-----and reset the selected force coordinates (warning: forces are
+ !     given in cartesian, selection is made in direct coordinates!):
+             DO M=1,3
+               VTMP(M)=TIFOR(M,NI)
+             ENDDO
+             CALL KARDIR(1,VTMP,LATT_CUR%B)
++!-----transformed selective dynamics
++            IF(T_INFO%SD_ROT) CALL SD_ROT(T_INFO,VTMP,'F',NI)
++!-----the actual reset
+             DO M=1,3
+               IF (.NOT.T_INFO%LSFOR(M,NI)) VTMP(M)=0._q
+             ENDDO
++!-----transform back to direct coordinates
++            IF(T_INFO%SD_ROT) CALL SD_ROT(T_INFO,VTMP,'B',NI)
+             CALL DIRKAR(1,VTMP,LATT_CUR%A)
+             DO M=1,3
+               TIFOR(M,NI)=VTMP(M)
+@@ -1222,10 +1324,30 @@
+       IF (T_INFO%LSDYN) THEN
+ !-----Selective dynamics here ... :
+          DO NI=1,T_INFO%NIONS
++!-----transformed selective dynamics
++            IF(T_INFO%SD_ROT) THEN
++               DO M=1,3
++                  VTMP(M)=VEL(M,NI)
++               ENDDO
++               CALL SD_ROT(T_INFO,VTMP,'F',NI)
++               DO M=1,3
++                  VEL(M,NI)=VTMP(M)
++               ENDDO
++            ENDIF
+ !-----reset the velocities of the selected coordinates ...
+             DO M=1,3
+                IF (.NOT.T_INFO%LSFOR(M,NI)) VEL(M,NI)=0._q
+             ENDDO
++!-----transform back to direct coordinates
++            IF(T_INFO%SD_ROT) THEN
++               DO M=1,3
++                  VTMP(M)=VEL(M,NI)
++               ENDDO
++               CALL SD_ROT(T_INFO,VTMP,'B',NI)
++               DO M=1,3
++                  VEL(M,NI)=VTMP(M)
++               ENDDO
++            ENDIF
+          ENDDO
+       ENDIF
+       END SUBROUTINE
+diff -Nur vasp.4.6/main.F vasp.4.6-ct/main.F
+--- vasp.4.6/main.F    2009-07-22 15:12:20.044978904 +0200
++++ vasp.4.6-ct/main.F 2009-09-18 08:55:20.595465366 +0200
+@@ -1929,7 +1929,8 @@
+          ! write header
+          CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, &
+         &             T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, &
++        &              T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          io_end
+          ! write AE charge density
+          CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT)
+@@ -1951,7 +1952,8 @@
+          ! write header
+          CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, &
+         &             T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, &
++        &              T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          io_end
+          ! write AE core charge density
+          CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT)
+@@ -3478,7 +3480,7 @@
+      io_begin
+       CALL OUTPOS(13,.TRUE.,T_INFO%SZNAM2,LATT_CUR%SCALE,DYN%AC,T_INFO%NTYP,T_INFO%NITYP,T_INFO%LSDYN, &
+-     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR )
++     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+       CALL OUTPOS_TRAIL(13,IO%LOPEN, LATT_CUR, T_INFO, DYN)
+      io_end
+@@ -3489,7 +3491,7 @@
+       io_begin
+       CALL OUTPOS(70,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+       io_end
+       DO ISP=1,WDES%NCDIJ
+@@ -3828,7 +3830,7 @@
+          REWIND 18
+          ! since t
+          CALL OUTPOS(18,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          io_end
+ ! if you uncomment the following lines the pseudo core charge density
+ ! is added to the pseudo charge density         
+@@ -3855,7 +3857,7 @@
+          IF (IO%LOPEN) OPEN(IO%IUVTOT,FILE='LOCPOT',STATUS='UNKNOWN')
+          REWIND IO%IUVTOT
+          CALL OUTPOS(IO%IUVTOT,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          io_end
+ ! comment out the following line to add  exchange correlation
+          INFO%LEXCHG=-1
+@@ -3936,7 +3938,8 @@
+          ! write header
+          CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, &
+         &             T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, &
++        &              T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          io_end
+          ! write AE charge density
+          CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT)
+@@ -3959,7 +3962,7 @@
+       io_begin
+       OPEN(UNIT=53,FILE='ELFCAR',STATUS='UNKNOWN')
+       CALL OUTPOS(53,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+       io_end
+       DO ISP=1,WDES%NCDIJ
+diff -Nur vasp.4.6/main.f90 vasp.4.6-ct/main.f90
+--- vasp.4.6/main.f90  2009-07-22 15:14:38.603841627 +0200
++++ vasp.4.6-ct/main.f90       2009-09-18 08:55:22.638156662 +0200
+@@ -1830,7 +1830,8 @@
+          ! write header
+          CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, &
+         &             T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, &
++        &              T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          
+          ! write AE charge density
+          CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT)
+@@ -1852,7 +1853,8 @@
+          ! write header
+          CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, &
+         &             T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, &
++        &              T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          
+          ! write AE core charge density
+          CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT)
+@@ -3369,7 +3371,7 @@
+      
+       CALL OUTPOS(13,.TRUE.,T_INFO%SZNAM2,LATT_CUR%SCALE,DYN%AC,T_INFO%NTYP,T_INFO%NITYP,T_INFO%LSDYN, &
+-     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR )
++     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+       CALL OUTPOS_TRAIL(13,IO%LOPEN, LATT_CUR, T_INFO, DYN)
+      
+@@ -3380,7 +3382,7 @@
+       
+       CALL OUTPOS(70,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+       
+       DO ISP=1,WDES%NCDIJ
+@@ -3712,7 +3714,7 @@
+          REWIND 18
+          ! since t
+          CALL OUTPOS(18,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          
+ ! if you uncomment the following lines the pseudo core charge density
+ ! is added to the pseudo charge density         
+@@ -3739,7 +3741,7 @@
+          IF (IO%LOPEN) OPEN(IO%IUVTOT,FILE='LOCPOT',STATUS='UNKNOWN')
+          REWIND IO%IUVTOT
+          CALL OUTPOS(IO%IUVTOT,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          
+ ! comment out the following line to add  exchange correlation
+          INFO%LEXCHG=-1
+@@ -3820,7 +3822,8 @@
+          ! write header
+          CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, &
+         &             T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, &
++        &              T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          
+          ! write AE charge density
+          CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT)
+@@ -3843,7 +3846,7 @@
+       
+       OPEN(UNIT=53,FILE='ELFCAR',STATUS='UNKNOWN')
+       CALL OUTPOS(53,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+       
+       DO ISP=1,WDES%NCDIJ
+diff -Nur vasp.4.6/poscar.F vasp.4.6-ct/poscar.F
+--- vasp.4.6/poscar.F  2009-07-22 15:12:20.052978145 +0200
++++ vasp.4.6-ct/poscar.F       2009-09-18 09:17:37.370283715 +0200
+@@ -181,6 +181,7 @@
+       INTEGER I,NT,NI,NSCALE
+       REAL(q) SCALEX,SCALEY,SCALEZ
+       REAL(q) POTIMR
++      REAL(q),PARAMETER :: PI=3.1415926536_q
+       OPEN(UNIT=15,FILE=DIR_APP(1:DIR_LEN)//'POSCAR',STATUS='OLD')
+@@ -269,6 +270,25 @@
+       ENDIF
+       READ(15,'(A1)') CSEL
++      T_INFO%SD_ROT=.FALSE.
++      IF ((CSEL=='T').OR.(CSEL=='t').OR. &
++     &    (CSEL=='R').OR.(CSEL=='r')) THEN
++!-----transformed/rotated selective dynamics switched on
++!-----read in rotation angles
++         T_INFO%SD_ROT=.TRUE.
++         T_INFO%SD_ROT_Z=0._q
++         T_INFO%SD_ROT_X=0._q
++         READ(15,*,ERR=400,END=400) T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X
++!-----print some info and convert to rad
++         WRITE(IU6,*) ' rotated selective dynamics:'
++         WRITE(IU6,*) '   Z: ', T_INFO%SD_ROT_Z
++         WRITE(IU6,*) '  rX: ', T_INFO%SD_ROT_X
++         T_INFO%SD_ROT_Z=PI*T_INFO%SD_ROT_Z/180.0
++         T_INFO%SD_ROT_X=PI*T_INFO%SD_ROT_X/180.0
++!-----switch on selective dynamics for further processing
++         CSEL='s'
++      ENDIF
++
+       T_INFO%LSDYN=((CSEL=='S').OR.(CSEL=='s'))
+       IF (T_INFO%LSDYN) READ(15,'(A1)') CSEL
+       IF (CSEL=='K'.OR.CSEL=='k'.OR. &
+@@ -538,17 +558,19 @@
+ !***********************************************************************
+       SUBROUTINE OUTPOS(IU,LLONG,SZNAM,SCALE,A,NTYP,NITYP,LSDYN, &
+-     &                  NIONS,POSION,LSFOR )
++     &                  NIONS,POSION,LSFOR,SD_ROT,SD_ROT_Z,SD_ROT_X)
+       USE prec
+       IMPLICIT REAL(q) (A-H,O-Z)
+-      LOGICAL LLONG,LSDYN,LSFOR
++      LOGICAL LLONG,LSDYN,LSFOR,SD_ROT
++      REAL(q) SD_ROT_Z,SD_ROT_X
+       DIMENSION A(3,3)
+       DIMENSION POSION(3,NIONS)
+       DIMENSION LSFOR (3,NIONS)
+       DIMENSION NITYP(NTYP)
+       CHARACTER*40 FORM
+       CHARACTER*40 SZNAM
++      REAL(q),PARAMETER :: PI=3.1415926536_q
+ !-----direct lattice
+       WRITE(IU,'(A40)') SZNAM
+@@ -562,7 +584,14 @@
+       WRITE(IU,FORM) (A(1,I)/SCALE,A(2,I)/SCALE,A(3,I)/SCALE,I=1,3)
+       WRITE(IU,'(20I4)') (NITYP(NT),NT=1,NTYP)
+-      IF (LSDYN) WRITE(13,'(A18)') 'Selective dynamics'
++      IF (LSDYN) THEN
++         IF (SD_ROT) THEN
++            WRITE(13,'(A30)') 'Transformed selective dynamics'
++            WRITE(13,'(2F)') SD_ROT_Z*180.0/PI,SD_ROT_X*180.0/PI
++         ELSE
++            WRITE(13,'(A18)') 'Selective dynamics'
++         ENDIF
++      ENDIF
+       WRITE(IU,'(A6)')'Direct'
+       IF (LSDYN) THEN
+diff -Nur vasp.4.6/poscar.inc vasp.4.6-ct/poscar.inc
+--- vasp.4.6/poscar.inc        2009-07-22 15:05:24.076290013 +0200
++++ vasp.4.6-ct/poscar.inc     2009-09-18 08:01:29.234012116 +0200
+@@ -14,6 +14,9 @@
+         INTEGER NIONS                 ! actual number of ions
+         INTEGER NIONP                 ! actual number of ions inc. empty spheres
+         LOGICAL LSDYN                 ! selective dynamics (yes/ no)
++        LOGICAL SD_ROT                ! rotated selective dynamics (yes/ no)
++        REAL(q) SD_ROT_Z              ! constraints rotation (z-axis, 1st rot)
++        REAL(q) SD_ROT_X              ! constraints rotation (x-axis, 2nd rot)
+         LOGICAL LDIRCO                ! positions in direct/recproc. lattice
+         REAL(q), POINTER :: POSION(:,:)  ! positions usually same as DYN%POSION
+         LOGICAL,POINTER ::  LSFOR(:,:) ! selective dynamics
diff --git a/vasp_tools/sd_rot_all-atoms.patch b/vasp_tools/sd_rot_all-atoms.patch
new file mode 100644 (file)
index 0000000..548f3c6
--- /dev/null
@@ -0,0 +1,407 @@
+diff -Nur vasp.4.6.orig/dyna.F vasp.4.6-gamma-fullct/dyna.F
+--- vasp.4.6.orig/dyna.F       2009-09-16 10:45:06.050116866 +0200
++++ vasp.4.6-gamma-fullct/dyna.F       2009-11-05 15:09:26.435422082 +0100
+@@ -1164,6 +1164,71 @@
+ !*********************************************************************
+ !
++! subroutine to transform vectors into the rotated constraints system
++!
++!*********************************************************************
++
++      SUBROUTINE SD_ROT(T_INFO,VEC,DIR,NI)
++      USE poscar
++      IMPLICIT NONE
++
++      TYPE (type_info)   T_INFO
++      REAL(q)            VEC(3),TMP(3)
++      CHARACTER*1        DIR
++      
++      INTEGER            M,NI
++
++      IF((.NOT. T_INFO%LSFOR(1,NI)).OR. &
++     &   (.NOT. T_INFO%LSFOR(2,NI)).OR. &
++     &   (.NOT. T_INFO%LSFOR(3,NI))) THEN
++         IF (DIR=='F') THEN
++            IF (T_INFO%SD_ROT_Z(NI)/=0._q) THEN
++               DO M=1,3
++                  TMP(M)=VEC(M)
++               ENDDO
++               VEC(1)=COS(T_INFO%SD_ROT_Z(NI))*TMP(1)- &
++     &                SIN(T_INFO%SD_ROT_Z(NI))*TMP(2)
++               VEC(2)=SIN(T_INFO%SD_ROT_Z(NI))*TMP(1)+ &
++     &                COS(T_INFO%SD_ROT_Z(NI))*TMP(2)
++            ENDIF
++            IF (T_INFO%SD_ROT_X(NI)/=0._q) THEN
++               DO M=1,3
++                  TMP(M)=VEC(M)
++               ENDDO
++               VEC(2)=COS(T_INFO%SD_ROT_X(NI))*TMP(2)- &
++     &                SIN(T_INFO%SD_ROT_X(NI))*TMP(3)
++               VEC(3)=SIN(T_INFO%SD_ROT_X(NI))*TMP(2)+ &
++     &                COS(T_INFO%SD_ROT_X(NI))*TMP(3)
++            ENDIF
++         ELSE
++            IF (T_INFO%SD_ROT_X(NI)/=0._q) THEN
++               DO M=1,3
++                  TMP(M)=VEC(M)
++               ENDDO
++               VEC(2)=COS(-T_INFO%SD_ROT_X(NI))*TMP(2)- &
++     &                SIN(-T_INFO%SD_ROT_X(NI))*TMP(3)
++               VEC(3)=SIN(-T_INFO%SD_ROT_X(NI))*TMP(2)+ &
++     &                COS(-T_INFO%SD_ROT_X(NI))*TMP(3)
++            ENDIF
++            IF (T_INFO%SD_ROT_Z(NI)/=0._q) THEN
++               DO M=1,3
++                  TMP(M)=VEC(M)
++               ENDDO
++               VEC(1)=COS(-T_INFO%SD_ROT_Z(NI))*TMP(1)- &
++     &                SIN(-T_INFO%SD_ROT_Z(NI))*TMP(2)
++               VEC(2)=SIN(-T_INFO%SD_ROT_Z(NI))*TMP(1)+ &
++     &                COS(-T_INFO%SD_ROT_Z(NI))*TMP(2)
++            ENDIF
++         ENDIF
++      ENDIF
++
++      RETURN
++
++      END
++
++
++!*********************************************************************
++!
+ ! subroutine to set selected force components to zero
+ !
+ !*********************************************************************
+@@ -1184,19 +1249,44 @@
+       IF (T_INFO%LSDYN) THEN
+ !-----Selective dynamics here ... :
+          DO NI=1,T_INFO%NIONS
++!-----transformed selective dynamics
++            IF(T_INFO%SD_ROT) THEN
++               DO M=1,3
++                  VTMP(M)=VEL(M,NI)
++               ENDDO
++               CALL SD_ROT(T_INFO,VTMP,'F',NI)
++               DO M=1,3
++                  VEL(M,NI)=VTMP(M)
++               ENDDO
++            ENDIF
+ !-----reset the velocities of the selected coordinates ...
+             DO M=1,3
+                IF (.NOT.T_INFO%LSFOR(M,NI)) VEL(M,NI)=0._q
+             ENDDO
++!-----transform back to direct coordinates
++            IF(T_INFO%SD_ROT) THEN
++               DO M=1,3
++                  VTMP(M)=VEL(M,NI)
++               ENDDO
++               CALL SD_ROT(T_INFO,VTMP,'B',NI)
++               DO M=1,3
++                  VEL(M,NI)=VTMP(M)
++               ENDDO
++            ENDIF
+ !-----and reset the selected force coordinates (warning: forces are
+ !     given in cartesian, selection is made in direct coordinates!):
+             DO M=1,3
+               VTMP(M)=TIFOR(M,NI)
+             ENDDO
+             CALL KARDIR(1,VTMP,LATT_CUR%B)
++!-----transformed selective dynamics
++            IF(T_INFO%SD_ROT) CALL SD_ROT(T_INFO,VTMP,'F',NI)
++!-----the actual reset
+             DO M=1,3
+               IF (.NOT.T_INFO%LSFOR(M,NI)) VTMP(M)=0._q
+             ENDDO
++!-----transform back to direct coordinates
++            IF(T_INFO%SD_ROT) CALL SD_ROT(T_INFO,VTMP,'B',NI)
+             CALL DIRKAR(1,VTMP,LATT_CUR%A)
+             DO M=1,3
+               TIFOR(M,NI)=VTMP(M)
+@@ -1222,10 +1312,30 @@
+       IF (T_INFO%LSDYN) THEN
+ !-----Selective dynamics here ... :
+          DO NI=1,T_INFO%NIONS
++!-----transformed selective dynamics
++            IF(T_INFO%SD_ROT) THEN
++               DO M=1,3
++                  VTMP(M)=VEL(M,NI)
++               ENDDO
++               CALL SD_ROT(T_INFO,VTMP,'F',NI)
++               DO M=1,3
++                  VEL(M,NI)=VTMP(M)
++               ENDDO
++            ENDIF
+ !-----reset the velocities of the selected coordinates ...
+             DO M=1,3
+                IF (.NOT.T_INFO%LSFOR(M,NI)) VEL(M,NI)=0._q
+             ENDDO
++!-----transform back to direct coordinates
++            IF(T_INFO%SD_ROT) THEN
++               DO M=1,3
++                  VTMP(M)=VEL(M,NI)
++               ENDDO
++               CALL SD_ROT(T_INFO,VTMP,'B',NI)
++               DO M=1,3
++                  VEL(M,NI)=VTMP(M)
++               ENDDO
++            ENDIF
+          ENDDO
+       ENDIF
+       END SUBROUTINE
+diff -Nur vasp.4.6.orig/main.F vasp.4.6-gamma-fullct/main.F
+--- vasp.4.6.orig/main.F       2009-09-16 10:45:05.747597375 +0200
++++ vasp.4.6-gamma-fullct/main.F       2009-11-05 15:09:26.449951618 +0100
+@@ -1929,7 +1929,8 @@
+          ! write header
+          CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, &
+         &             T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, &
++        &              T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          io_end
+          ! write AE charge density
+          CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT)
+@@ -1951,7 +1952,8 @@
+          ! write header
+          CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, &
+         &             T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, &
++        &              T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          io_end
+          ! write AE core charge density
+          CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT)
+@@ -3478,7 +3480,7 @@
+      io_begin
+       CALL OUTPOS(13,.TRUE.,T_INFO%SZNAM2,LATT_CUR%SCALE,DYN%AC,T_INFO%NTYP,T_INFO%NITYP,T_INFO%LSDYN, &
+-     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR )
++     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+       CALL OUTPOS_TRAIL(13,IO%LOPEN, LATT_CUR, T_INFO, DYN)
+      io_end
+@@ -3489,7 +3491,7 @@
+       io_begin
+       CALL OUTPOS(70,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+       io_end
+       DO ISP=1,WDES%NCDIJ
+@@ -3828,7 +3830,7 @@
+          REWIND 18
+          ! since t
+          CALL OUTPOS(18,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          io_end
+ ! if you uncomment the following lines the pseudo core charge density
+ ! is added to the pseudo charge density         
+@@ -3855,7 +3857,7 @@
+          IF (IO%LOPEN) OPEN(IO%IUVTOT,FILE='LOCPOT',STATUS='UNKNOWN')
+          REWIND IO%IUVTOT
+          CALL OUTPOS(IO%IUVTOT,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          io_end
+ ! comment out the following line to add  exchange correlation
+          INFO%LEXCHG=-1
+@@ -3936,7 +3938,8 @@
+          ! write header
+          CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, &
+         &             T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++        &              T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, &
++        &              T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+          io_end
+          ! write AE charge density
+          CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT)
+@@ -3959,7 +3962,7 @@
+       io_begin
+       OPEN(UNIT=53,FILE='ELFCAR',STATUS='UNKNOWN')
+       CALL OUTPOS(53,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., &
+-     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++     &                  T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+       io_end
+       DO ISP=1,WDES%NCDIJ
+diff -Nur vasp.4.6.orig/pardens.F vasp.4.6-gamma-fullct/pardens.F
+--- vasp.4.6.orig/pardens.F    2009-09-16 10:45:06.294577287 +0200
++++ vasp.4.6-gamma-fullct/pardens.F    2009-11-05 15:09:26.453773187 +0100
+@@ -308,7 +308,7 @@
+ ! I do not call <<write_pard>> here, because I handle the total charge a little bit
+ ! differnt, and the output to <<CHG>> is also differnt
+        do_io CALL OUTPOS(iuchgcar,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP, &
+-            T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++            T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+        CALL OUTCHG(GRIDC,iuchgcar,.TRUE.,CHTOT)
+@@ -320,7 +320,7 @@
+        do_io CLOSE(iuchgcar)
+        do_io CALL OUTPOS(iuchg,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP, &
+-            T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++            T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+        CALL OUTCHG(GRIDC,iuchg,.FALSE.,CHTOT)
+@@ -1154,7 +1154,7 @@
+       ! and use the usual output routines
+       CALL OUTPOS(iunit,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP, &
+-            T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR)
++            T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X)
+       io_end
+       CALL OUTCHG(GRIDC,iunit,.FALSE.,CHTOT)
+diff -Nur vasp.4.6.orig/poscar.F vasp.4.6-gamma-fullct/poscar.F
+--- vasp.4.6.orig/poscar.F     2009-09-16 10:45:06.074097686 +0200
++++ vasp.4.6-gamma-fullct/poscar.F     2009-11-05 15:19:56.505775347 +0100
+@@ -181,6 +181,7 @@
+       INTEGER I,NT,NI,NSCALE
+       REAL(q) SCALEX,SCALEY,SCALEZ
+       REAL(q) POTIMR
++      REAL(q),PARAMETER :: PI=3.1415926536_q
+       OPEN(UNIT=15,FILE=DIR_APP(1:DIR_LEN)//'POSCAR',STATUS='OLD')
+@@ -269,6 +270,17 @@
+       ENDIF
+       READ(15,'(A1)') CSEL
++      T_INFO%SD_ROT=.FALSE.
++      IF ((CSEL=='T').OR.(CSEL=='t').OR. &
++     &    (CSEL=='R').OR.(CSEL=='r')) THEN
++!-----transformed/rotated selective dynamics switched on
++         T_INFO%SD_ROT=.TRUE.
++!-----print some info and convert to rad
++         WRITE(IU6,*) ' rotated selective dynamics switched on'
++!-----switch on selective dynamics for further processing
++         CSEL='s'
++      ENDIF
++
+       T_INFO%LSDYN=((CSEL=='S').OR.(CSEL=='s'))
+       IF (T_INFO%LSDYN) READ(15,'(A1)') CSEL
+       IF (CSEL=='K'.OR.CSEL=='k'.OR. &
+@@ -288,6 +300,12 @@
+      &         DYN%D2C(3,NIOND), &
+      &         DYN%VEL(3,NIOND),DYN%D2(3,NIOND),DYN%D3(3,NIOND))
++      ALLOCATE(T_INFO%SD_ROT_Z(NIOND))
++      ALLOCATE(T_INFO%SD_ROT_X(NIOND))
++
++      T_INFO%SD_ROT_Z=0._q
++      T_INFO%SD_ROT_X=0._q
++
+ ! alias T_INFO%POSION
+       T_INFO%POSION => DYN%POSION
+@@ -298,12 +316,21 @@
+       DYN%D3    =0
+       DO NI=1,T_INFO%NIONS
++      IF (T_INFO%SD_ROT) THEN
++      READ(15,*,ERR=400,END=400) DYN%POSION(1,NI),DYN%POSION(2,NI),DYN%POSION(3,NI), &
++     &      T_INFO%LSFOR(1,NI),T_INFO%LSFOR(2,NI),T_INFO%LSFOR(3,NI), &
++     &      T_INFO%SD_ROT_Z(NI), T_INFO%SD_ROT_X(NI)
++!-----convert to rad
++      T_INFO%SD_ROT_Z(NI)=PI*T_INFO%SD_ROT_Z(NI)/180.0
++      T_INFO%SD_ROT_X(NI)=PI*T_INFO%SD_ROT_X(NI)/180.0
++      ELSE
+       IF (T_INFO%LSDYN) THEN
+       READ(15,*,ERR=400,END=400) DYN%POSION(1,NI),DYN%POSION(2,NI),DYN%POSION(3,NI), &
+      &      T_INFO%LSFOR(1,NI),T_INFO%LSFOR(2,NI),T_INFO%LSFOR(3,NI)
+       ELSE
+       READ(15,*,ERR=400,END=400) DYN%POSION(1,NI),DYN%POSION(2,NI),DYN%POSION(3,NI)
+       ENDIF
++      ENDIF
+       ENDDO
+       IF (CSEL=='K') THEN
+@@ -538,17 +565,19 @@
+ !***********************************************************************
+       SUBROUTINE OUTPOS(IU,LLONG,SZNAM,SCALE,A,NTYP,NITYP,LSDYN, &
+-     &                  NIONS,POSION,LSFOR )
++     &                  NIONS,POSION,LSFOR,SD_ROT,SD_ROT_Z,SD_ROT_X)
+       USE prec
+       IMPLICIT REAL(q) (A-H,O-Z)
+-      LOGICAL LLONG,LSDYN,LSFOR
++      LOGICAL LLONG,LSDYN,LSFOR,SD_ROT
++      REAL(q), POINTER :: SD_ROT_Z(:), SD_ROT_X(:)
+       DIMENSION A(3,3)
+       DIMENSION POSION(3,NIONS)
+       DIMENSION LSFOR (3,NIONS)
+       DIMENSION NITYP(NTYP)
+       CHARACTER*40 FORM
+       CHARACTER*40 SZNAM
++      REAL(q),PARAMETER :: PI=3.1415926536_q
+ !-----direct lattice
+       WRITE(IU,'(A40)') SZNAM
+@@ -562,14 +591,26 @@
+       WRITE(IU,FORM) (A(1,I)/SCALE,A(2,I)/SCALE,A(3,I)/SCALE,I=1,3)
+       WRITE(IU,'(20I4)') (NITYP(NT),NT=1,NTYP)
+-      IF (LSDYN) WRITE(13,'(A18)') 'Selective dynamics'
++      IF (LSDYN) THEN
++         IF (SD_ROT) THEN
++            WRITE(13,'(A30)') 'Transformed selective dynamics'
++         ELSE
++            WRITE(13,'(A18)') 'Selective dynamics'
++         ENDIF
++      ENDIF
+       WRITE(IU,'(A6)')'Direct'
+       IF (LSDYN) THEN
+       IF (LLONG) THEN
+         FORM='(3F20.16,3L4)'
++        IF (SD_ROT) THEN
++           FORM='(3F20.16,3L4,2F20.12)'
++        ENDIF
+       ELSE
+         FORM='(3F10.6,3L2)'
++        IF (SD_ROT) THEN
++           FORM='(3F10.6,3L2,2F10.2)'
++        ENDIF
+       ENDIF
+       ELSE
+       IF (LLONG) THEN
+@@ -579,6 +620,12 @@
+       ENDIF
+       ENDIF
++      IF(SD_ROT) THEN
++          WRITE(IU,FORM) &
++     &      (POSION(1,NI),POSION(2,NI),POSION(3,NI), &
++     &       LSFOR(1,NI),LSFOR(2,NI),LSFOR(3,NI), &
++     &       SD_ROT_Z(NI)*180.0/PI, SD_ROT_X(NI)*180.0/PI,NI=1,NIONS)
++      ELSE
+       IF (LSDYN) THEN
+           WRITE(IU,FORM) &
+      &      (POSION(1,NI),POSION(2,NI),POSION(3,NI), &
+@@ -587,6 +634,7 @@
+           WRITE(IU,FORM) &
+      &      (POSION(1,NI),POSION(2,NI),POSION(3,NI),NI=1,NIONS)
+       ENDIF
++      ENDIF
+       IF (.NOT.LLONG) WRITE(IU,*)
+       RETURN
+       END SUBROUTINE
+diff -Nur vasp.4.6.orig/poscar.inc vasp.4.6-gamma-fullct/poscar.inc
+--- vasp.4.6.orig/poscar.inc   2009-09-16 10:45:06.791087379 +0200
++++ vasp.4.6-gamma-fullct/poscar.inc   2009-11-03 11:58:39.388412198 +0100
+@@ -14,6 +14,9 @@
+         INTEGER NIONS                 ! actual number of ions
+         INTEGER NIONP                 ! actual number of ions inc. empty spheres
+         LOGICAL LSDYN                 ! selective dynamics (yes/ no)
++        LOGICAL SD_ROT                ! rotated selective dynamics (yes/ no)
++        REAL(q), POINTER :: SD_ROT_Z(:) ! constraints rotation (z-axis, 1st rot)
++        REAL(q), POINTER :: SD_ROT_X(:) ! constraints rotation (x-axis, 2nd rot)
+         LOGICAL LDIRCO                ! positions in direct/recproc. lattice
+         REAL(q), POINTER :: POSION(:,:)  ! positions usually same as DYN%POSION
+         LOGICAL,POINTER ::  LSFOR(:,:) ! selective dynamics
diff --git a/vasp_tools/search_bonds b/vasp_tools/search_bonds
new file mode 100755 (executable)
index 0000000..29b6d1c
--- /dev/null
@@ -0,0 +1,144 @@
+#!/bin/bash
+
+file=$1
+len=$2
+delta=$3
+tA=$4
+tB=$5
+
+echo
+echo "usage:"
+echo "$0 <contcar file> <len> <delta> <type a> <type b>"
+echo
+echo "args: $@"
+echo
+
+scale=`sed -n 2p $1`
+
+X1=`sed -n 3p $file | awk '{ print $1 }'`
+X2=`sed -n 3p $file | awk '{ print $2 }'`
+X3=`sed -n 3p $file | awk '{ print $3 }'`
+
+Y1=`sed -n 4p $file | awk '{ print $1 }'`
+Y2=`sed -n 4p $file | awk '{ print $2 }'`
+Y3=`sed -n 4p $file | awk '{ print $3 }'`
+
+Z1=`sed -n 5p $file | awk '{ print $1 }'`
+Z2=`sed -n 5p $file | awk '{ print $2 }'`
+Z3=`sed -n 5p $file | awk '{ print $3 }'`
+
+export X1 X2 X3
+export Y1 Y2 Y3
+export Z1 Z2 Z3
+
+nsi=`sed -n 6p $file | awk '{ print $1 }'`
+nc=`sed -n 6p $file | awk '{ print $2 }'`
+
+((nt=nsi+nc))
+
+((offset=8))
+((count=1))
+
+echo "found $nt atoms: Si = $nsi / C = $nc"
+echo "scale: $scale"
+echo "X: $X1 $X2 $X3"
+echo "Y: $Y1 $Y2 $Y3"
+echo "Z: $Z1 $Z2 $Z3"
+echo
+
+while [ "1" ]; do
+
+       if [ $count -le $nsi ]; then
+               typea=S
+       else
+               typea=C
+       fi
+
+       if [ "$tA" != "$typea" ]; then
+               ((count+=1))
+               [ $count -gt $nt ] && break
+               continue
+       fi
+
+       ((line=count+offset))
+
+       temp="`sed -n ${line}p $1`"
+       xa=`echo $temp | awk '{ print $1 }'`
+       ya=`echo $temp | awk '{ print $2 }'`
+       za=`echo $temp | awk '{ print $3 }'`
+
+       ((ic=1))
+       while [ "1" ]; do
+               ((il=ic+offset))
+               if [ $line != $il ]; then
+                       if [ $ic -le $nsi ] ; then
+                               typeb=S
+                       else
+                               typeb=C
+                       fi
+                       if [ "$typeb" != "$tB" ]; then
+                               ((ic+=1))
+                               [ $ic -gt $nt ] && break
+                               continue
+                       fi
+                       tmpb="`sed -n ${il}p $1`"
+                       xb=`echo $tmpb | awk '{ print $1 }'`
+                       yb=`echo $tmpb | awk '{ print $2 }'`
+                       zb=`echo $tmpb | awk '{ print $3 }'`
+
+                       echo "$xa $ya $za $xb $yb $zb $scale $len $delta $count $ic" | \
+                       awk ' \
+                       BEGIN {
+                       dxt=0; dyt=0; dzt=0
+                       dx=0; dy=0; dz=0; dist=0
+                       X=0; Y=0; Z=0
+                       X1=ENVIRON["X1"]; X2=ENVIRON["X2"]; X3=ENVIRON["X3"]
+                       Y1=ENVIRON["Y1"]; Y2=ENVIRON["Y2"]; Y3=ENVIRON["Y3"]
+                       Z1=ENVIRON["Z1"]; Z2=ENVIRON["Z2"]; Z3=ENVIRON["Z3"]
+                       }       
+                       {
+                       X=sqrt(X1^2+X2^2+X3^2)
+                       Y=sqrt(Y1^2+Y2^2+Y3^2)
+                       Z=sqrt(Z1^2+Z2^2+Z3^2)
+                       dx=$1-$4
+                       dy=$2-$5
+                       dz=$3-$6
+                       if(dx>1/2)
+                               dx-=1
+                       if(dx<-1/2)
+                               dx+=1
+                       if(dy>1/2)
+                               dy-=1
+                       if(dy<-1/2)
+                               dy+=1
+                       if(dz>1/2)
+                               dz-=1
+                       if(dz<-1/2)
+                               dz+=1
+                       dxt=dx*X1+dy*Y1+dz*Z1
+                       dyt=dx*X2+dy*Y2+dz*Z2
+                       dzt=dx*X3+dy*Y3+dz*Z3
+                       dist=sqrt(dxt^2+dyt^2+dzt^2)
+                       dist*=$7
+                       if((dist>=($8-$9))&&(dist<=($8+$9))) {
+                               print ""
+                               print "atoms: " $10 " - " $11
+                               print $1 " " $2 " " $3
+                               print $4 " " $5 " " $6 " (" dist " - " $8 ")"
+                               print "displace: " dx*X " " dy*Y " " dz*Z
+                       }
+                       }'
+               fi
+
+               ((ic+=1))
+               [ $ic -gt $nt ] && break
+
+       done
+
+       ((count+=1))
+       [ $count -gt $nt ] && break
+
+done
+
+echo "done"
+
diff --git a/vasp_tools/stdvis b/vasp_tools/stdvis
new file mode 100755 (executable)
index 0000000..4592d5a
--- /dev/null
@@ -0,0 +1,180 @@
+#!/bin/bash
+
+if [ -z "$1" ]; then
+       echo "specify a directory ..."
+       exit
+fi
+
+if [ -z "$2" ]; then
+       type="default"
+else
+       type=$2
+fi
+
+if [ -z "$3" ]; then
+       trg="video"
+else
+       trg="video.*"
+fi
+
+if [ "$type" != "disp" ]; then
+
+for i in $1/$trg; do
+
+       if [ -f $i/stdvis ]; then
+               echo "$i already visualized ..."
+               continue
+       else
+               touch $i/stdvis
+       fi
+
+# first unit cell in each direction without rotation
+if [ "$type" = "default" -o "$type" = "1" ]; then
+echo "type: 1 no rotation"
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 -0.20 -0.50 -fur 1.20 1.20 1.20 \
+       -b 0.0 0.0 0.0 1.0 1.0 1.0 \
+       -c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \
+       -r 0.6 -A 1 217 1.9
+fi
+
+# first unit cell in each direction without rotation displaying mirrored atoms
+if [ "$type" = "1m" ]; then
+echo "type: 1 no rotation, mirrored"
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 -0.20 -0.20 -fur 1.20 1.20 1.20 \
+       -b 0.0 0.0 0.0 1.0 1.0 1.0 \
+       -c 0.3 -1.7 0.9 -L 0.5 -1.0 0.5 \
+       -r 0.6 -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 \
+       -A 1 216 2.6
+       #-A 1 217 2.6
+       #-c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \
+fi
+
+# defect combination view 1
+if [ "$type" = "dc1" ]; then
+echo "type: defect combination 1, mirrored"
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 -0.20 -0.80 -fur 1.20 1.20 1.20 \
+       -b 0.0 0.0 0.0 1.0 1.0 1.0 \
+       -c 0.3 -1.7 0.9 -L 0.5 -1.0 0.5 \
+       -r 0.6 -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 \
+       -A 2 217 218 2.6
+fi
+
+# first unit cell in each direction without rotation displaying mirrored atoms
+if [ "$type" = "x1y1z13" ]; then
+echo "type: x1y1z13, mirrored"
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 -0.20 -1.20 -fur 1.20 1.20 1.20 \
+       -b 0.0 0.0 0.0 1.0 1.0 1.0 \
+       -c 0.3 -1.7 0.4 -L 0.5 -1.0 0 \
+       -r 0.6 -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 \
+       -A 1 217 2.6
+       #-A 2 109 217 2.6
+fi
+
+# first unit cell in each direction without rotation displaying mirrored atoms
+if [ "$type" = "1m2" ]; then
+echo "type: 1 no rotation, mirrored, displaying bonds of the 2 C atoms"
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 -0.20 -0.20 -fur 1.20 1.20 1.20 \
+       -b 0.0 0.0 0.0 1.0 1.0 1.0 \
+       -c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \
+       -r 0.6 -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 \
+       -A 2 217 218 2.6
+fi
+
+if [ "$type" = "1m2dv" ]; then
+echo "type: 1 no rotation, mirrored, displaying bonds of db and vac"
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 -0.20 -0.20 -fur 1.20 1.20 1.20 \
+       -b 0.0 0.0 0.0 1.0 1.0 1.0 \
+       -c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \
+       -r 0.6 -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 \
+       -A 2 215 216 2.6
+fi
+
+# three unit cells in each direction without rotation
+if [ "$type" = "3" ]; then
+echo "type: 3 no rotation"
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 -0.20 -0.20 -fur 3.20 3.20 3.20 \
+       -b 0.0 0.0 0.0 3.0 3.0 3.0 \
+       -c 2.3 -3.7 2.4 -L 1.5 -1.0 1.5 \
+       -r 0.6 -A 1 217 2.6
+fi
+
+# unti cell 3,0,2
+if [ "$type" = "3x2z" ]; then
+echo "type: 3x2z no rotation"
+./visualize -w 640 -h 480 -d $i \
+       -nll 1.8 -0.2 0.8 -fur 3.20 1.20 2.20 \
+       -b 2.0 0.0 1.0 3.0 1.0 2.0 \
+       -c 2.3 -3.7 2.4 -L 1.5 -1.0 1.5 \
+       -r 0.6
+fi
+
+# first unit cell rotated by 45 degrees about z-axis
+if [ "$type" = "1r" ]; then
+echo "type: 1 rotated"
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 -0.70 -0.20 -fur 2.00 0.70 1.20 \
+       -c -0.5 -1.5 0.9 -L 1.0 0.0 0.5 \
+       -r 0.6
+       #-b 0.0 0.0 0.0 0.0 0.0 1.0 \
+fi
+
+# first unit cell rotated by 45 degrees displaying mirrored atoms
+if [ "$type" = "1rm" ]; then
+echo "type: 1 rotated, mirrored"
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 -0.20 -0.50 -fur 1.20 1.20 1.20 \
+       -b 0.0 0.0 0.0 1.0 1.0 1.0 \
+       -c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \
+       -r 0.6 -m 2.0 -2.0 0.0 2.0 2.0 0.0 0.0 0.0 3.0 \
+       -A 1 193 1.9
+fi
+
+# three unit cells (rotated) in each direction displaying mirrored atoms
+if [ "$type" = "3rm" ]; then
+echo "type: 3 roted, mirrored"
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 -0.20 -0.20 -fur 3.20 3.20 3.20 \
+       -b 0.0 0.0 0.0 3.0 3.0 3.0 \
+       -c 1.3 -3.7 2.4 -L 1.5 -1.0 1.5 \
+       -r 0.6 -m 2.0 -2.0 0.0 2.0 2.0 0.0 0.0 0.0 3.0
+fi
+
+# x: 2,3 y 3 z 1,2
+if [ "$type" = "x123y3z123" ]; then
+echo "type: x: 1,2,3 y 3 z 1,2,3"
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 1.80 -0.20 -fur 3.20 3.20 3.20 \
+       -b 1.0 2.0 1.0 2.0 3.0 2.0 \
+       -c 1.8 -1.7 2.2 -L 1.6 2.5 1.7 \
+       -r 0.6 -A 1 217 2.6 \
+        -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0
+fi
+
+./ppm2avi $i
+
+done
+
+else
+
+# 100 db in type 1 sc (insdide sc)
+for i in $1/video/atomic_conf_*.xyz; do
+       displace=`echo $i | awk -F_ '{ print $7 }' | sed 's/\.xyz//'`
+       echo "$i $displace ..."
+./visualize -w 640 -h 480 -d $i \
+       -nll -0.20 -0.20 -0.50 -fur 1.20 1.20 1.20 \
+       -b 0.0 0.0 0.0 1.0 1.0 1.0 \
+       -c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \
+       -r 0.6 -B 0.1 -D $displace -m 2.0 -2.0 0.0 2.0 2.0 0.0 0.0 0.0 3.0
+done
+
+fi
+
+#mplayer $1/video/md.avi
+
diff --git a/vasp_tools/tXYZp.c b/vasp_tools/tXYZp.c
new file mode 100644 (file)
index 0000000..cd96040
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * tXYZp.c
+ *
+ * author: frank.zirkelbach@physik.uni-augsburg.de
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+
+int get_line(int fd,char *line,int max) {
+
+        int count,ret;
+
+        count=0;
+
+        while(1) {
+                if(count==max) return count;
+                ret=read(fd,line+count,1);
+                if(ret<=0) return ret;
+                if(line[count]=='\n') {
+                        memset(line+count,0,max-count-1);
+                        //line[count]='\0';
+                        return count+1;
+                }
+                count+=1;
+        }
+}
+
+void usage(void) {
+       printf("usage: tXYZp -X,Y,Z <angle> -X,Y,Z <angle> ...\n");
+}
+
+int b_transform(char rtype,double angle,double cosangle,double sinangle,
+                double o[3][3],double t[3][3]) {
+
+       int i;
+
+       switch(rtype) {
+               case 'X':
+                       for(i=0;i<3;i++) {
+                               t[i][0]=o[i][0];
+                               t[i][1]=cosangle*o[i][1]+sinangle*o[i][2];
+                               t[i][2]=cosangle*o[i][2]-sinangle*o[i][1];
+                       }
+                       break;
+               case 'Y':
+                       for(i=0;i<3;i++) {
+                               t[i][0]=cosangle*o[i][0]+sinangle*o[i][2];
+                               t[i][1]=o[i][1];
+                               t[i][2]=cosangle*o[i][2]-sinangle*o[i][0];
+                       }
+                       break;
+               case 'Z':
+                       for(i=0;i<3;i++) {
+                               t[i][0]=cosangle*o[i][0]+sinangle*o[i][1];
+                               t[i][1]=cosangle*o[i][1]-sinangle*o[i][0];
+                               t[i][2]=o[i][2];
+                       }
+                       break;
+               default:
+                       break;
+       }
+
+       printf("Transformed (%c - %f) basis:\n",rtype,angle);
+       printf(" b1: (%f, %f, %f)\n",t[0][0],t[0][1],t[0][2]);
+       printf(" b2: (%f, %f, %f)\n",t[1][0],t[1][1],t[1][2]);
+       printf(" b3: (%f, %f, %f)\n",t[2][0],t[2][1],t[2][2]);
+
+       return 1;
+}
+
+int a_transform(char rtype,double angle,double cosangle,double sinangle,
+                double o[3],double t[3]) {
+
+       switch(rtype) {
+               case 'X':
+                       t[0]=o[0];
+                       t[1]=cosangle*o[1]-sinangle*o[2];
+                       t[2]=cosangle*o[2]+sinangle*o[1];
+                       break;
+               case 'Y':
+                       t[0]=cosangle*o[0]-sinangle*o[2];
+                       t[1]=o[1];
+                       t[2]=cosangle*o[2]+sinangle*o[0];
+                       break;
+               case 'Z':
+                       t[0]=cosangle*o[0]-sinangle*o[1];
+                       t[1]=cosangle*o[1]+sinangle*o[0];
+                       t[2]=o[2];
+                       break;
+               default:
+                       break;
+       }
+
+       return 1;
+}
+
+int main(int argc,char **argv) {
+
+       int i,j;
+       double angle[3];
+       char rtype[3];
+       double cosangle[3];
+       double sinangle[3];
+       int posr,poso;
+       char file[128];
+       int cnt,count;
+       char buf[256];
+       char *wptr;
+
+       /* basis in cartesian coordinates */
+       double b[3][3];
+
+       /* transformed basis */ 
+       double tb[3][3][3];
+
+       double x[3],X[3];
+       char t1,t2,t3;
+
+       memset(angle,0,sizeof(double)*3);
+       memset(rtype,0,sizeof(char)*3);
+
+       count=0;
+       for(i=1;i<argc;i++) {
+               if(argv[i][0]=='-') {
+                       switch(argv[i][1]) {
+                               case 'X':
+                               case 'Y':
+                               case 'Z':
+                                       rtype[count]=argv[i][1];
+                                       angle[count]=atof(argv[++i])/180.0*M_PI;
+                                       count+=1;
+                                       break;
+                               default:
+                                       usage();
+                                       return -1;
+                       }
+               }
+               else {
+                       usage();
+                       return -1;
+               }
+       }
+
+       printf("\nOperations: ");
+       for(i=0;i<3;i++) {
+               if(rtype[i]) {
+                       cosangle[i]=cos(angle[i]);
+                       sinangle[i]=sin(angle[i]);
+                       printf("%c %f (%d) | ",rtype[i],angle[i]/M_PI*180.0,i);
+               }
+       }
+       printf("\n\n");
+
+       posr=open("POSCAR",O_RDONLY);
+       if(posr<0) {
+               perror("open POSCAR (read) file\n");
+               return posr;
+       }
+
+       snprintf(file,255,"POSCAR.");
+       for(i=0;i<3;i++) {
+               if(rtype[i]) 
+                       snprintf(file,255,"%s%c%f",file,rtype[i],angle[i]);
+       }
+       poso=open(file,O_WRONLY|O_CREAT);
+       if(poso<0) {
+               perror("open POSCAR (write) file\n");
+               return poso;
+       }
+       
+       // first line
+       cnt=get_line(posr,buf,256);
+       buf[cnt-1]='\n';
+       write(poso,buf,cnt);
+
+       // second line
+       cnt=get_line(posr,buf,256);
+       buf[cnt-1]='\n';
+       write(poso,buf,cnt);
+
+       // basis in cartesian coordinates
+       for(j=0;j<3;j++) {
+               cnt=get_line(posr,buf,256);
+               for(i=0;i<3;i++) {
+                       if(i==0)
+                               wptr=strtok(buf," ");
+                       else
+                               wptr=strtok(NULL," ");
+                       b[j][i]=atof(wptr);
+               }
+       }
+
+       printf("Basis:\n");
+       printf(" b1: (%f, %f, %f)\n",b[0][0],b[0][1],b[0][2]);
+       printf(" b2: (%f, %f, %f)\n",b[1][0],b[1][1],b[1][2]);
+       printf(" b3: (%f, %f, %f)\n",b[2][0],b[2][1],b[2][2]);
+
+       /* transformation */
+       // remember:
+       // first rotation A
+       // second rotation B
+       // B needs to get transformed into B' = ABA^-1
+       // => total: ABA^-1A = AB
+       // => reverse sequence of transformations!
+       for(i=count-1;i>-1;i--) {
+               if(rtype[i]) {
+                       if(i==count-1)
+                               b_transform(rtype[i],angle[i],
+                                           cosangle[i],sinangle[i],
+                                           b,tb[i]);
+                       else
+                               b_transform(rtype[i],angle[i],
+                                           cosangle[i],sinangle[i],
+                                           tb[i+1],tb[i]);
+               }
+       }
+
+       for(i=0;i<3;i++)
+               dprintf(poso," %f %f %f\n",
+                       tb[0][i][0],tb[0][i][1],tb[0][i][2]);
+                       
+       // 6th line
+       cnt=get_line(posr,buf,256);
+       buf[cnt-1]='\n';
+       write(poso,buf,cnt);
+
+       // 7th line
+       cnt=get_line(posr,buf,256);
+       buf[cnt-1]='\n';
+       write(poso,buf,cnt);
+
+       // 8th line
+       cnt=get_line(posr,buf,256);
+       buf[cnt-1]='\n';
+       write(poso,buf,cnt);
+
+       while(1) {
+               cnt=get_line(posr,buf,256);
+               if(cnt<=0)
+                       break;
+               wptr=strtok(buf," ");
+               x[0]=atof(wptr);
+               wptr=strtok(NULL," ");
+               x[1]=atof(wptr);
+               wptr=strtok(NULL," ");
+               x[2]=atof(wptr);
+
+               wptr=strtok(NULL," ");
+               t1=wptr[0];
+               wptr=strtok(NULL," ");
+               t2=wptr[0];
+               wptr=strtok(NULL," ");
+               t3=wptr[0];
+
+               for(i=0;i<3;i++)  {
+                       if(rtype[i]) {
+                               X[0]=x[0];
+                               X[1]=x[1];
+                               X[2]=x[2];
+                               a_transform(rtype[i],angle[i],
+                                           cosangle[i],sinangle[i],
+                                           X,x);
+                       }
+               }
+
+               dprintf(poso," %f %f %f %c %c %c\n",x[0],x[1],x[2],t1,t2,t3);
+       }
+
+       close(posr);
+       close(poso);
+
+       printf("done!\n");
+
+       return 0;
+}
+
diff --git a/vasp_tools/tXp.c b/vasp_tools/tXp.c
new file mode 100644 (file)
index 0000000..6b6e6a1
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * tXp.c
+ *
+ * author: frank.zirkelbach@physik.uni-augsburg.de
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+
+int get_line(int fd,char *line,int max) {
+
+        int count,ret;
+
+        count=0;
+
+        while(1) {
+                if(count==max) return count;
+                ret=read(fd,line+count,1);
+                if(ret<=0) return ret;
+                if(line[count]=='\n') {
+                        memset(line+count,0,max-count-1);
+                        //line[count]='\0';
+                        return count+1;
+                }
+                count+=1;
+        }
+}
+
+
+int main(int argc,char **argv) {
+
+       double x1,x2,x3,y1,y2,y3,z1,z2,z3;
+       double x_1,x_2,x_3,y_1,y_2,y_3,z_1,z_2,z_3;
+       double X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3;
+       double theta;
+       double costheta,sintheta;
+       double normx,normy,normz;
+       int posr,poso;
+       char file[128],buf[256];
+       char *wptr;
+       char t1,t2,t3;
+       int cnt;
+
+       posr=open("POSCAR",O_RDONLY);
+       if(posr<0) {
+               perror("open POSCAR (read) file\n");
+               return posr;
+       }
+
+       theta=(atof(argv[1])/180.0*M_PI);
+       costheta=cos(theta);
+       sintheta=sin(theta);
+
+       snprintf(file,127,"POSCAR.X%f",theta);
+       poso=open(file,O_WRONLY|O_CREAT);
+       if(poso<0) {
+               perror("open POSCAR (write) file\n");
+               return poso;
+       }
+       
+       // first line
+       cnt=get_line(posr,buf,256);
+       buf[cnt-1]='\n';
+       write(poso,buf,cnt);
+
+       // second line
+       cnt=get_line(posr,buf,256);
+       buf[cnt-1]='\n';
+       write(poso,buf,cnt);
+
+       // basis
+       cnt=get_line(posr,buf,256);
+       wptr=strtok(buf," ");
+       x1=atof(wptr);
+       wptr=strtok(NULL," ");
+       x2=atof(wptr);
+       wptr=strtok(NULL," ");
+       x3=atof(wptr);
+
+       cnt=get_line(posr,buf,256);
+       wptr=strtok(buf," ");
+       y1=atof(wptr);
+       wptr=strtok(NULL," ");
+       y2=atof(wptr);
+       wptr=strtok(NULL," ");
+       y3=atof(wptr);
+
+       cnt=get_line(posr,buf,256);
+       wptr=strtok(buf," ");
+       z1=atof(wptr);
+       wptr=strtok(NULL," ");
+       z2=atof(wptr);
+       wptr=strtok(NULL," ");
+       z3=atof(wptr);
+
+       /* norm */
+       normx=sqrt(x1*x1+x2*x2+x3*x3);
+       normy=sqrt(y1*y1+y2*y2+y3*y3);
+       normz=sqrt(z1*z1+z2*z2+z3*z3);
+
+       /* basis in given basis */
+       X1=(x1*x1+x2*x2+x3*x3)/normx;
+       X2=(y1*x1+y2*x2+y3*x3)/normy;
+       X3=(z1*x1+z2*x2+z3*x3)/normz;
+
+       Y1=(x1*y1+x2*y2+x3*y3)/normx;
+       Y2=(y1*y1+y2*y2+y3*y3)/normy;
+       Y3=(z1*y1+z2*y2+z3*y3)/normz;
+
+       Z1=(x1*z1+x2*z2+x3*z3)/normx;
+       Z2=(y1*z1+y2*z2+y3*z3)/normy;
+       Z3=(z1*z1+z2*z2+z3*z3)/normz;
+
+       printf("Basis expressed by itself:\n");
+       printf("     %f     %f     %f\n",X1,Y1,Z1);
+       printf(" x = %f y = %f z = %f\n",X2,Y2,Z2);
+       printf("     %f     %f     %f\n",X3,Y3,Z3);
+
+       /* transformed basis */
+       x_1=X1;
+       x_2=costheta*X2-sintheta*X3;
+       x_3=sintheta*X2+costheta*X3;
+
+       y_1=Y1;
+       y_2=costheta*Y2-sintheta*Y3;
+       y_3=sintheta*Y2+costheta*Y3;
+
+       z_1=Z1;
+       z_2=costheta*Z2-sintheta*Z3;
+       z_3=sintheta*Z2+costheta*Z3;
+
+       printf("Transformed basis in the given basis:\n");
+       printf("     %f     %f     %f\n",x_1,y_1,z_1);
+       printf(" x = %f y = %f z = %f\n",x_2,y_2,z_2);
+       printf("     %f     %f     %f\n",x_3,y_3,z_3);
+
+       /* transformed basis in cartesian coordinates */
+       X1=(x1/normx*x_1+y1/normy*x_2+z1/normz*x_3);
+       X2=(x2/normx*x_1+y2/normy*x_2+z2/normz*x_3);
+       X3=(x3/normx*x_1+y3/normy*x_2+z3/normz*x_3);
+
+       Y1=(x1/normx*y_1+y1/normy*y_2+z1/normz*y_3);
+       Y2=(x2/normx*y_1+y2/normy*y_2+z2/normz*y_3);
+       Y3=(x3/normx*y_1+y3/normy*y_2+z3/normz*y_3);
+
+       Z1=(x1/normx*z_1+y1/normy*z_2+z1/normz*z_3);
+       Z2=(x2/normx*z_1+y2/normy*z_2+z2/normz*z_3);
+       Z3=(x3/normx*z_1+y3/normy*z_2+z3/normz*z_3);
+
+       printf("Transformed basis in cartesian coordinates:\n");
+       printf("     %f     %f     %f\n",X1,Y1,Z1);
+       printf(" x = %f y = %f z = %f\n",X2,Y2,Z2);
+       printf("     %f     %f     %f\n",X3,Y3,Z3);
+
+       dprintf(poso," %f %f %f\n",X1,X2,X3);
+       dprintf(poso," %f %f %f\n",Y1,Y2,Y3);
+       dprintf(poso," %f %f %f\n",Z1,Z2,Z3);
+
+       // 6th line
+       cnt=get_line(posr,buf,256);
+       buf[cnt-1]='\n';
+       write(poso,buf,cnt);
+
+       // 7th line
+       cnt=get_line(posr,buf,256);
+       buf[cnt-1]='\n';
+       write(poso,buf,cnt);
+
+       // 8th line
+       cnt=get_line(posr,buf,256);
+       buf[cnt-1]='\n';
+       write(poso,buf,cnt);
+
+       while(1) {
+               cnt=get_line(posr,buf,256);
+               if(cnt<=0)
+                       break;
+               wptr=strtok(buf," ");
+               x1=atof(wptr);
+               wptr=strtok(NULL," ");
+               x2=atof(wptr);
+               wptr=strtok(NULL," ");
+               x3=atof(wptr);
+
+               wptr=strtok(NULL," ");
+               t1=wptr[0];
+               wptr=strtok(NULL," ");
+               t2=wptr[0];
+               wptr=strtok(NULL," ");
+               t3=wptr[0];
+
+               X1=x1;
+               X2=costheta*x2+sintheta*x3;
+               X3=costheta*x3-sintheta*x2;
+
+               /* check! */
+               double tmp1,tmp2,tmp3;
+               tmp1=(X1*x_1+X2*y_1+X3*z_1)/normx;
+               tmp2=(X1*x_2+X2*y_2+X3*z_2)/normy;
+               tmp3=(X1*x_3+X2*y_3+X3*z_3)/normz;
+               printf("%f %f %f - %f %f %f | %f %f %f\n",
+                      x1,x2,x3,tmp1,tmp2,tmp3,x1-tmp1,x2-tmp2,x3-tmp3);
+
+               dprintf(poso," %f %f %f %c %c %c\n",X1,X2,X3,t1,t2,t3);
+       }
+
+       close(posr);
+       close(poso);
+
+       printf("done!\n");
+
+       return 0;
+}
+
diff --git a/vasp_tools/trafoXposcar b/vasp_tools/trafoXposcar
new file mode 100755 (executable)
index 0000000..1cd5286
--- /dev/null
@@ -0,0 +1,177 @@
+#!/bin/bash
+
+echo "parsing POSCAR file ..."
+
+theta=$1
+
+trg=POSCAR.Xtrafo$theta
+
+sicnt=`sed -n 6p POSCAR | awk '{ print $1 }'`
+ccnt=`sed -n 6p POSCAR | awk '{ print $2 }'`
+
+lc=`sed -n 2p POSCAR | awk '{ print $1 }'`
+
+x1=`sed -n 3p POSCAR | awk '{ print $1 }'`
+x2=`sed -n 3p POSCAR | awk '{ print $2 }'`
+x3=`sed -n 3p POSCAR | awk '{ print $3 }'`
+
+y1=`sed -n 4p POSCAR | awk '{ print $1 }'`
+y2=`sed -n 4p POSCAR | awk '{ print $2 }'`
+y3=`sed -n 4p POSCAR | awk '{ print $3 }'`
+
+z1=`sed -n 5p POSCAR | awk '{ print $1 }'`
+z2=`sed -n 5p POSCAR | awk '{ print $2 }'`
+z3=`sed -n 5p POSCAR | awk '{ print $3 }'`
+
+((total=sicnt+ccnt))
+
+echo "  Si: $sicnt, C: $ccnt, total: $total"
+echo "  Lattice constant: $lc A"
+echo "  Basis:"
+echo "      $x1      $y1      $z1"
+echo "  x = $x2  y = $y2  z = $z2"
+echo "      $x3      $y3      $z3"
+echo
+echo "  -----"
+echo "  Trafo: x axis, $theta degree"
+echo "  -----"
+echo
+
+# determine trafo of cartesian coordinates to this one
+normx=`echo $x1 $x2 $x3 | awk '{ print sqrt($1*$1+$2*$2+$3*$3) }'`
+normy=`echo $y1 $y2 $y3 | awk '{ print sqrt($1*$1+$2*$2+$3*$3) }'`
+normz=`echo $z1 $z2 $z3 | awk '{ print sqrt($1*$1+$2*$2+$3*$3) }'`
+echo $normx $normz $normy
+t11=`echo $x1 $normx | awk '{ print $1/$2 }'`
+t12=`echo $x2 $normx | awk '{ print $1/$2 }'`
+t13=`echo $x3 $normx | awk '{ print $1/$2 }'`
+t21=`echo $y1 $normy | awk '{ print $1/$2 }'`
+t22=`echo $y2 $normy | awk '{ print $1/$2 }'`
+t23=`echo $y3 $normy | awk '{ print $1/$2 }'`
+t31=`echo $z1 $normz | awk '{ print $1/$2 }'`
+t32=`echo $z2 $normz | awk '{ print $1/$2 }'`
+t33=`echo $z3 $normz | awk '{ print $1/$2 }'`
+echo "  Matrix from cartesian to used coordinates:"
+echo "  | $t11 $t21 $t31 |"
+echo "  | $t12 $t22 $t32 |"
+echo "  | $t13 $t23 $t33 |"
+echo
+i11=$t11
+i12=$t21
+i13=$t31
+i21=$t12
+i22=$t22
+i23=$t32
+i31=$t13
+i32=$t23
+i33=$t33
+echo "  Inverse matrix (i=t^T):"
+echo "  | $i11 $i21 $i31 |"
+echo "  | $i12 $i22 $i32 |"
+echo "  | $i13 $i23 $i33 |"
+echo
+# i * basis
+X1=`echo $i11 $i21 $i31 $x1 $x2 $x3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+X2=`echo $i12 $i22 $i32 $x1 $x2 $x3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+X3=`echo $i13 $i23 $i33 $x1 $x2 $x3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+
+Y1=`echo $i11 $i21 $i31 $y1 $y2 $y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+Y2=`echo $i12 $i22 $i32 $y1 $y2 $y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+Y3=`echo $i13 $i23 $i33 $y1 $y2 $y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+
+Z1=`echo $i11 $i21 $i31 $z1 $z2 $z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+Z2=`echo $i12 $i22 $i32 $z1 $z2 $z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+Z3=`echo $i13 $i23 $i33 $z1 $z2 $z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+echo "  Basis (in rotation system):"
+echo "      $X1      $Y1      $Z1"
+echo "  x = $X2  y = $Y2  z = $Z2"
+echo "      $X3      $Y3      $Z3"
+echo
+
+costheta=`echo $theta | awk '{ print cos($1*3.1415927/180.0) }'`
+sintheta=`echo $theta | awk '{ print sin($1*3.1415927/180.0) }'`
+
+x1=$X1
+x2=$X2
+x3=$X3
+X1=$x1
+X2=`echo $x2 $x3 $costheta $sintheta | awk '{ print $3*$1-$4*$2 }'`
+X3=`echo $x2 $x3 $costheta $sintheta | awk '{ print $4*$1+$3*$2 }'`
+
+y1=$Y1
+y2=$Y2
+y3=$Y3
+Y1=$y1
+Y2=`echo $y2 $y3 $costheta $sintheta | awk '{ print $3*$1-$4*$2 }'`
+Y3=`echo $y2 $y3 $costheta $sintheta | awk '{ print $4*$1+$3*$2 }'`
+
+z1=$Z1
+z2=$Z2
+z3=$Z3
+Z1=$z1
+Z2=`echo $z2 $z3 $costheta $sintheta | awk '{ print $3*$1-$4*$2 }'`
+Z3=`echo $z2 $z3 $costheta $sintheta | awk '{ print $4*$1+$3*$2 }'`
+
+echo "  Transformed basis (in rotation system):"
+echo "       $X1       $Y1       $Z1"
+echo "  x' = $X2  y' = $Y2  z' = $Z2"
+echo "       $X3       $Y3       $Z3"
+echo
+
+# t * basis
+x1=`echo $t11 $t21 $t31 $X1 $X2 $X3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+x2=`echo $t12 $t22 $t32 $X1 $X2 $X3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+x3=`echo $t13 $t23 $t33 $X1 $X2 $X3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+X1=$x1
+X2=$x2
+X3=$x3
+
+y1=`echo $t11 $t21 $t31 $Y1 $Y2 $Y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+y2=`echo $t12 $t22 $t32 $Y1 $Y2 $Y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+y3=`echo $t13 $t23 $t33 $Y1 $Y2 $Y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+Y1=$y1
+Y2=$y2
+Y3=$y3
+
+z1=`echo $t11 $t21 $t31 $Z1 $Z2 $Z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+z2=`echo $t12 $t22 $t32 $Z1 $Z2 $Z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+z3=`echo $t13 $t23 $t33 $Z1 $Z2 $Z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'`
+Z1=$z1
+Z2=$z2
+Z3=$z3
+
+
+echo "  Transformed basis (cartesian coordinates):"
+echo "       $X1       $Y1       $Z1"
+echo "  x' = $X2  y' = $Y2  z' = $Z2"
+echo "       $X3       $Y3       $Z3"
+echo
+
+cnt=0
+tcnt=0
+
+cx=1.0
+cy=1.0
+cz=0.8
+
+# header
+sed -n 1p POSCAR > $trg
+echo " $lc" >> $trg
+echo " $X1 $X2 $X3" >> $trg
+echo " $Y1 $Y2 $Y3" >> $trg
+echo " $Z1 $Z2 $Z3" >> $trg
+echo " $sicnt $ccnt" >> $trg
+echo "selective dynamics" >> $trg
+echo "direct" >> $trg
+
+tail -${total} POSCAR | \
+       while read x y z fx fy fz; do
+               Y=`echo $y $z $costheta $sintheta | \
+                       awk '{ print $3*$1+$4*$2 }'`
+               Z=`echo $y $z $costheta $sintheta | \
+                       awk '{ print $3*$2-$4*$1 }'`
+               echo " $x $Y $Z $fx $fy $fz" >> $trg
+       done
+
+echo "done"
+
diff --git a/vasp_tools/visualize b/vasp_tools/visualize
new file mode 100755 (executable)
index 0000000..1ed430c
--- /dev/null
@@ -0,0 +1,453 @@
+#!/bin/sh
+
+#
+# visualization script
+# author: frank.zirkelbach@physik.uni-augsburg.de
+#
+
+# help function
+draw_cyl() {
+       cat >> temp.pov <<-EOF
+cylinder {
+<$1, $3, $2>, <$4, $6, $5>, 0.05
+pigment { color White }
+}
+EOF
+}
+draw_bond() {
+       cat >> temp.pov <<-EOF
+cylinder {
+<$1, $3, $2>, <$4, $6, $5>, $7
+pigment { color Blue }
+}
+EOF
+}
+
+# defaults
+
+lc=5.429
+directory="doesnt_exist____for_sure"
+width="640"
+height="480"
+radius="0.6"
+x0="-0.6"; y0="-0.6"; z0="-0.6";
+x1="0.6"; y1="0.6"; z1="0.6";
+cx=""; cy=""; cz="";
+lx="0"; ly="-100"; lz="100";
+ortographic=""
+bx0=""; by0=""; bz0="";
+bx1=""; by1=""; bz1="";
+bcr="0.1";
+clx="0"; cly="0"; clz="0";
+extra=0
+displace=""
+mirror=0
+mx1=0; mx2=0; mx3=0;
+my1=0; my2=0; my3=0;
+mz1=0; mz2=0; mz3=0;
+ab=0
+
+# parse argv
+
+while [ "$1" ]; do
+       case "$1" in
+               -d)             directory=$2;           shift 2;;
+               -w)             width=$2;               shift 2;;
+               -h)             height=$2;              shift 2;;
+               -r)             radius=$2;              shift 2;;
+               -nll)           x0=$2; y0=$3; z0=$4;    shift 4;;
+               -fur)           x1=$2; y1=$3; z1=$4;    shift 4;;
+               -c)             cx=$2; cy=$3; cz=$4;    shift 4;;
+               -L)             clx=$2; cly=$3; clz=$4; shift 4;;
+               -l)             lx=$2; ly=$3; lz=$4;    shift 4;;
+               -o)             ortographic=1;          shift 1;;
+               -b)             bx0=$2; by0=$3; bz0=$4;
+                               bx1=$5; by1=$6; bz1=$7; shift 7;;
+               -B)             bcr=$2;                 shift 2;;
+               -C)             lc=$2;                  shift 2;;
+               -e)             extra=1;                shift 1;;
+               -D)             displace=$2;            shift 2;;
+               -m)             mx1=$2; mx2=$3; mx3=$4;
+                               my1=$5; my2=$6; my3=$7;
+                               mz1=$8; mz2=$9; mz3=${10};
+                               mirror=1;               shift 10;;
+               -A)             ab=$2;                  shift 2;
+                               ((cnt=1))
+                               while [ $cnt -le $ab ]; do
+                                       anr[$cnt]=$1;   shift 1;
+                                       ((cnt+=1))
+                               done
+                               cutoff=$1;              shift 1;;
+               *)
+                               echo "options:"
+                               echo "########"
+                               echo "directory to progress:"
+                               echo "  -d <directory> (mandatory)"
+                               echo "png dim:"
+                               echo "  -w <width>"
+                               echo "  -h <height>"
+                               echo "atom size:"
+                               echo "  -r <radius>"
+                               echo "  -B <bond cylinder radius>"
+                               echo "unit cell:"
+                               echo "  -C <lattice constant>"
+                               echo "  -m <dimX> <dimY> <dimZ> (mirror atoms)"
+                               echo "visualization volume:"
+                               echo "  -nll <x> <y> <z> (near lower left)"
+                               echo "  -fur <x> <y> <z> (far upper right)"
+                               echo "  -o (ortographic)"
+                               echo "bounding box:"
+                               echo "  -b <x0> <y0> <z0> <x1> <y1> <z1>"
+                               echo "povray:"
+                               echo "  -c <x> <y> <z> (camera position)"
+                               echo "  -L <x> <y> <z> (camera look)"
+                               echo "  -l <x> <y> <z> (light source)"
+                               echo "bonds:"
+                               echo "  -ab <atom number> <cutoff> (auto bonds)"
+                               exit 1;;
+       esac
+done
+
+# calculation from lattic eunits to angstroms
+
+[ "$lc" = "sic" ] && lc=4.359
+[ "$lc" = "si" ] && lc=5.480
+[ "$lc" = "c" ] && lc=3.566
+
+#offset=`echo 0.125 \* $lc | bc`
+offset=0.0
+
+x0=`echo $x0 \* $lc + $offset | bc`
+y0=`echo $y0 \* $lc + $offset | bc`
+z0=`echo $z0 \* $lc + $offset | bc`
+x1=`echo $x1 \* $lc + $offset | bc`
+y1=`echo $y1 \* $lc + $offset | bc`
+z1=`echo $z1 \* $lc + $offset | bc`
+
+mx1=`echo $mx1 \* $lc + $offset | bc`
+my1=`echo $my1 \* $lc + $offset | bc`
+mz1=`echo $mz1 \* $lc + $offset | bc`
+mx2=`echo $mx2 \* $lc + $offset | bc`
+my2=`echo $my2 \* $lc + $offset | bc`
+mz2=`echo $mz2 \* $lc + $offset | bc`
+mx3=`echo $mx3 \* $lc + $offset | bc`
+my3=`echo $my3 \* $lc + $offset | bc`
+mz3=`echo $mz3 \* $lc + $offset | bc`
+
+clx=`echo $clx \* $lc + $offset | bc`
+cly=`echo $cly \* $lc + $offset | bc`
+clz=`echo $clz \* $lc + $offset | bc`
+
+if [ -n "$cx" -a -n "$cy" -a -n "$cz" ]; then
+       cx=`echo $cx \* $lc + $offset | bc`
+       cy=`echo $cy \* $lc + $offset | bc`
+       cz=`echo $cz \* $lc + $offset | bc`
+fi
+
+if [ -n "$bx0" ]; then
+       bx0=`echo $bx0 \* $lc + $offset | bc`
+       by0=`echo $by0 \* $lc + $offset | bc`
+       bz0=`echo $bz0 \* $lc + $offset | bc`
+       bx1=`echo $bx1 \* $lc + $offset | bc`
+       by1=`echo $by1 \* $lc + $offset | bc`
+       bz1=`echo $bz1 \* $lc + $offset | bc`
+fi
+
+# povray command
+
+POVRAY="povray -W${width} -H${height} -d" 
+
+# convert options
+
+COPTS="-font /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"
+COPTS="$COPTS -depth 8 -fill white -stroke blue -pointsize 24"
+
+# do it ...
+
+if [ -d $directory ]; then
+       filesource=$directory/atomic_conf_*.xyz
+fi
+
+if [ -f $directory ]; then
+       filesource=$directory
+fi
+
+for file in $filesource; do
+
+       cat > temp.pov <<-EOF
+#include "colors.inc"
+#include "textures.inc"
+#include "shapes.inc"
+#include "glass.inc"
+#include "metals.inc"
+#include "woods.inc"
+#include "stones.inc"
+EOF
+
+       # meta info
+       count=`grep '# \[P\]' $file | awk '{ print $3 }'`
+       time=`grep '# \[P\]' $file | awk '{ print $4 }'`
+       camloc=`grep '# \[P\]' $file | awk '{ print $5 }'`
+       [ -n "$cx" -a -n "$cy" -a -n "$cz" ] && camloc="<$cx,$cz,$cy>"
+
+       # atoms
+#echo "-----> $x0 $y0 $z0 $x1 $y1 $z1 <-----"
+       if [ -n "$x0" ]; then
+               export x0 y0 z0 x1 y1 z1 radius extra
+               export mx1 mx2 mx3
+               export my1 my2 my3
+               export mz1 mz2 mz3
+               export mirror
+               cat $file | grep -v '#' | awk '\
+               BEGIN {
+                       x0=ENVIRON["x0"]; y0=ENVIRON["y0"]; z0=ENVIRON["z0"];
+                       x1=ENVIRON["x1"]; y1=ENVIRON["y1"]; z1=ENVIRON["z1"];
+                       mx1=ENVIRON["mx1"]; my1=ENVIRON["my1"];
+                       mz1=ENVIRON["mz1"]; mx2=ENVIRON["mx2"];
+                       my2=ENVIRON["my2"]; mz2=ENVIRON["mz2"];
+                       mx3=ENVIRON["mx3"]; my3=ENVIRON["my3"];
+                       mz3=ENVIRON["mz3"]; mirror=ENVIRON["mirror"];
+                       radius=ENVIRON["radius"]; extra=ENVIRON["extra"];
+                       nx=0; ny=0; nz=0;
+               }
+               {
+                       if(($2>=x0)&&($3>=y0)&&($4>=z0)&&\
+                          ($2<=x1)&&($3<=y1)&&($4<=z1)) {
+                               print "sphere { <"$2","$4","$3">, "radius" ";
+                               if(extra)
+               print "texture { pigment { color rgb<"$6/4.4",0,"1-$6/4.4"> } ";
+                               else
+               print "texture { pigment { color "$5" } ";
+                               print "finish { phong 1 metallic } } }";
+                       }
+
+                       if(mirror) {
+
+                       nx=$2-mx1; ny=$3-mx2; nz=$4-mx3;
+                       if((nx>=x0)&&(ny>=y0)&&(nz>=z0)&&\
+                          (nx<=x1)&&(ny<=y1)&&(nz<=z1)) {
+print "// translation: "$2/5.480" "$3/5.480" "$4/5.480" -> "nx/5.480" "ny/5.480" "nz/5.480" ...";
+                               print "sphere { <"nx","nz","ny">, "radius" ";
+                               if(extra)
+               print "texture { pigment { color rgb<"$6/4.4",0,"1-$6/4.4"> } ";
+                               else
+               print "texture { pigment { color "$5" } ";
+                               print "finish { phong 1 metallic } } }";
+                       }
+                       nx=$2-my1; ny=$3-my2; nz=$4-my3;
+                       if((nx>=x0)&&(ny>=y0)&&(nz>=z0)&&\
+                          (nx<=x1)&&(ny<=y1)&&(nz<=z1)) {
+                               print "sphere { <"nx","nz","ny">, "radius" ";
+                               if(extra)
+               print "texture { pigment { color rgb<"$6/4.4",0,"1-$6/4.4"> } ";
+                               else
+               print "texture { pigment { color "$5" } ";
+                               print "finish { phong 1 metallic } } }";
+                       }
+                       nx=$2-mz1; ny=$3-mz2; nz=$4-mz3;
+                       if((nx>=x0)&&(ny>=y0)&&(nz>=z0)&&\
+                          (nx<=x1)&&(ny<=y1)&&(nz<=z1)) {
+                               print "sphere { <"nx","nz","ny">, "radius" ";
+                               if(extra)
+               print "texture { pigment { color rgb<"$6/4.4",0,"1-$6/4.4"> } ";
+                               else
+               print "texture { pigment { color "$5" } ";
+                               print "finish { phong 1 metallic } } }";
+                       }
+
+                       }
+
+               }' >> temp.pov
+       else
+               cat $file | grep -v '#' | while read name x y z color temp; do
+                       cat >> temp.pov <<-EOF
+sphere {
+<$x, $z, $y>, $radius
+texture {
+pigment { color $color }
+finish {
+phong 1
+metallic
+}
+}
+}
+EOF
+               done
+       fi
+
+       # boundaries
+       if [ -z "$bx0" ]; then
+
+       #if [ -z "$x0" ]; then
+
+       cat $file | grep '# \[D\]' | while read foo bar x1 y1 z1 x2 y2 z2 ; do
+               draw_cyl $x1 $y1 $z1 $x2 $y2 $z2 0.05
+       done
+
+       #else
+
+               # manually drawing the 3x4 boundaries ...
+#              draw_cyl $x0 $y0 $z0 $x1 $y0 $z0
+#              draw_cyl $x0 $y0 $z0 $x0 $y1 $z0
+#              draw_cyl $x1 $y1 $z0 $x1 $y0 $z0
+#              draw_cyl $x0 $y1 $z0 $x1 $y1 $z0
+
+#              draw_cyl $x0 $y0 $z1 $x1 $y0 $z1
+#              draw_cyl $x0 $y0 $z1 $x0 $y1 $z1
+#              draw_cyl $x1 $y1 $z1 $x1 $y0 $z1
+#              draw_cyl $x0 $y1 $z1 $x1 $y1 $z1
+
+#              draw_cyl $x0 $y0 $z1 $x0 $y0 $z0
+#              draw_cyl $x0 $y1 $z1 $x0 $y1 $z0
+#              draw_cyl $x1 $y0 $z1 $x1 $y0 $z0
+#              draw_cyl $x1 $y1 $z1 $x1 $y1 $z0
+#      fi
+
+       else
+
+               # manually drawing the 3x4 boundaries specified by argv ...
+               draw_cyl $bx0 $by0 $bz0 $bx1 $by0 $bz0
+               draw_cyl $bx0 $by0 $bz0 $bx0 $by1 $bz0
+               draw_cyl $bx1 $by1 $bz0 $bx1 $by0 $bz0
+               draw_cyl $bx0 $by1 $bz0 $bx1 $by1 $bz0
+
+               draw_cyl $bx0 $by0 $bz1 $bx1 $by0 $bz1
+               draw_cyl $bx0 $by0 $bz1 $bx0 $by1 $bz1
+               draw_cyl $bx1 $by1 $bz1 $bx1 $by0 $bz1
+               draw_cyl $bx0 $by1 $bz1 $bx1 $by1 $bz1
+
+               draw_cyl $bx0 $by0 $bz1 $bx0 $by0 $bz0
+               draw_cyl $bx0 $by1 $bz1 $bx0 $by1 $bz0
+               draw_cyl $bx1 $by0 $bz1 $bx1 $by0 $bz0
+               draw_cyl $bx1 $by1 $bz1 $bx1 $by1 $bz0
+
+       fi      
+
+       # bonds
+       if [ -n "$bcr" ]; then
+
+               if [ -z "$x0" ]; then
+
+       cat $file | grep '# \[B\]' | while read foo bar x1 y1 z1 x2 y2 z2 ; do
+               draw_bond $x1 $z1 $y1 $x2 $z2 $y2 $bcr
+       done
+
+               else
+
+               export x0 y0 z0 x1 y1 z1 bcr
+               cat $file | grep '# \[B\]' | awk '\
+               BEGIN {
+                       x0=ENVIRON["x0"]; y0=ENVIRON["y0"]; z0=ENVIRON["z0"];
+                       x1=ENVIRON["x1"]; y1=ENVIRON["y1"]; z1=ENVIRON["z1"];
+                       bcr=ENVIRON["bcr"];
+               }
+               {
+                       if(($3>=x0)&&($4>=y0)&&($5>=z0)&&\
+                          ($3<=x1)&&($4<=y1)&&($5<=z1)) {
+                               print "cylinder {";
+                               print "<"$3","$5","$4">,";
+                               print "<"$6","$8","$7">, "bcr;
+                               print "pigment { color Blue }";
+                               print "}";
+                       }
+               }' >> temp.pov
+
+               fi
+       fi
+
+       # auto bonds
+       if [ "$ab" != "0" ]; then
+               ((cnt=1))
+               while [ $cnt -le $ab ]; do
+                       anr=${anr[$cnt]}
+
+               ((tmp=anr+1))
+               line="`sed -n ${tmp}p $file`"
+               aX=`echo $line | awk '{ print $2 }'`
+               aY=`echo $line | awk '{ print $3 }'`
+               aZ=`echo $line | awk '{ print $4 }'`
+               export aX aY aZ cutoff mirror
+               cat $file | grep -v '#' | awk '\
+               BEGIN {
+                       x=ENVIRON["aX"]; y=ENVIRON["aY"]; z=ENVIRON["aZ"];
+                       co=ENVIRON["cutoff"]; dist=0; bcr=ENVIRON["bcr"];
+                       mx1=ENVIRON["mx1"]; my1=ENVIRON["my1"];
+                       mz1=ENVIRON["mz1"]; mx2=ENVIRON["mx2"];
+                       my2=ENVIRON["my2"]; mz2=ENVIRON["mz2"];
+                       mx3=ENVIRON["mx3"]; my3=ENVIRON["my3"];
+                       mz3=ENVIRON["mz3"]; mirror=ENVIRON["mirror"];
+               }
+               {
+                       dist=sqrt((x-$2)^2+(y-$3)^2+(z-$4)^2);
+                       if((dist<=co)&&(dist>0.01)) {
+                               print "cylinder {";
+                               print "<"x","z","y">,";
+                               print "<"$2","$4","$3">, "bcr;
+                               print "pigment { color Blue }";
+                               print "}";
+                       }
+
+                       if(mirror) {
+                               nx=$2-mx1; ny=$3-mx2; nz=$4-mx3;
+                               dist=sqrt((x-nx)^2+(y-ny)^2+(z-nz)^2)
+                               if((dist<=co)&&(dist>0.01)) {
+                                       print "cylinder {";
+                                       print "<"x","z","y">,";
+                                       print "<"nx","nz","ny">, "bcr;
+                                       print "pigment { color Blue }";
+                                       print "}";
+                               }
+                               nx=$2-my1; ny=$3-my2; nz=$4-my3;
+                               dist=sqrt((x-nx)^2+(y-ny)^2+(z-nz)^2)
+                               if((dist<=co)&&(dist>0.01)) {
+                                       print "cylinder {";
+                                       print "<"x","z","y">,";
+                                       print "<"nx","nz","ny">, "bcr;
+                                       print "pigment { color Blue }";
+                                       print "}";
+                               }
+                               nx=$2-mz1; ny=$3-mz2; nz=$4-mz3;
+                               dist=sqrt((x-nx)^2+(y-ny)^2+(z-nz)^2)
+                               if((dist<=co)&&(dist>0.01)) {
+                                       print "cylinder {";
+                                       print "<"x","z","y">,";
+                                       print "<"nx","nz","ny">, "bcr;
+                                       print "pigment { color Blue }";
+                                       print "}";
+                               }
+                       }
+
+               }' >> temp.pov
+
+                       ((cnt+=1))
+               done
+       fi
+
+       # add camera and light source
+       cat >> temp.pov <<-EOF
+camera {
+EOF
+       if [ -n "$ortographic" ]; then  cat >> temp.pov <<-EOF
+orthographic
+EOF
+       fi
+       cat >> temp.pov <<-EOF
+location $camloc
+look_at <$clx,$clz,$clz>
+}
+light_source { <0,100,-100> color White shadowless }
+EOF
+
+       # mv png
+       $POVRAY temp.pov > /dev/null 2>&1
+       time=`basename $file | awk -F. '{ print $1 }' | awk -F_ '{ print $3 }'`
+       if [ ! -z $displace ]; then
+       convert $COPTS -draw "text 5,20 'd = $displace %'" temp.png temp.png
+       else
+       convert $COPTS -draw "text 5,20 't = $time fs'" temp.png temp.png
+       fi
+       mv temp.png `echo $file | sed 's/\.xyz/\.png/'`
+
+done
+
+echo "done"
diff --git a/vasp_tools/visualize_contcar b/vasp_tools/visualize_contcar
new file mode 100755 (executable)
index 0000000..61ed143
--- /dev/null
@@ -0,0 +1,497 @@
+#!/bin/sh
+
+#
+# visualization script
+# author: frank.zirkelbach@physik.uni-augsburg.de
+#
+
+# help function
+draw_cyl() {
+       cat >> temp.pov <<-EOF
+cylinder {
+<$1, $3, $2>, <$4, $6, $5>, 0.05
+pigment { color White }
+}
+EOF
+}
+draw_bond() {
+       cat >> temp.pov <<-EOF
+cylinder {
+<$1, $3, $2>, <$4, $6, $5>, $7
+pigment {
+       color rgbf <0, 0, 1.0, 0.8>
+       finish { phong 1 metallic }
+}
+}
+EOF
+}
+
+# defaults
+
+lc=5.429
+directory="doesnt_exist____for_sure"
+width="640"
+height="480"
+radius="0.6"
+x0="-0.6"; y0="-0.6"; z0="-0.6";
+x1="0.6"; y1="0.6"; z1="0.6";
+cx=""; cy=""; cz="";
+lx="0"; ly="-100"; lz="100";
+ortographic=""
+bx0=""; by0=""; bz0="";
+bx1=""; by1=""; bz1="";
+bcr="0.1";
+clx="0"; cly="0"; clz="0";
+extra=0
+displace=""
+mirror=0
+mx1=0; mx2=0; mx3=0;
+my1=0; my2=0; my3=0;
+mz1=0; mz2=0; mz3=0;
+ab=0
+sym=0
+
+# parse argv
+
+while [ "$1" ]; do
+       case "$1" in
+               -d)             directory=$2;           shift 2;;
+               -w)             width=$2;               shift 2;;
+               -h)             height=$2;              shift 2;;
+               -r)             radius=$2;              shift 2;;
+               -nll)           x0=$2; y0=$3; z0=$4;    shift 4;;
+               -fur)           x1=$2; y1=$3; z1=$4;    shift 4;;
+               -c)             cx=$2; cy=$3; cz=$4;    shift 4;;
+               -L)             clx=$2; cly=$3; clz=$4; shift 4;;
+               -l)             lx=$2; ly=$3; lz=$4;    shift 4;;
+               -o)             ortographic=1;          shift 1;;
+               -b)             bx0=$2; by0=$3; bz0=$4;
+                               bx1=$5; by1=$6; bz1=$7; shift 7;;
+               -B)             bcr=$2;                 shift 2;;
+               -C)             lc=$2;                  shift 2;;
+               -e)             extra=1;                shift 1;;
+               -D)             displace=$2;            shift 2;;
+               -m)             mx1=$2; mx2=$3; mx3=$4;
+                               my1=$5; my2=$6; my3=$7;
+                               mz1=$8; mz2=$9; mz3=${10};
+                               mirror=1;               shift 10;;
+               -A)             ab=$2;                  shift 2;
+                               ((cnt=1))
+                               while [ $cnt -le $ab ]; do
+                                       anr[$cnt]=$1;   shift 1;
+                                       ((cnt+=1))
+                               done
+                               cutoff=$1;              shift 1;;
+               -s)             sym=$2;                 shift 2;;
+               *)
+                               echo "options:"
+                               echo "########"
+                               echo "directory to progress:"
+                               echo "  -d <directory> (mandatory)"
+                               echo "png dim:"
+                               echo "  -w <width>"
+                               echo "  -h <height>"
+                               echo "atom size:"
+                               echo "  -r <radius>"
+                               echo "  -B <bond cylinder radius>"
+                               echo "unit cell:"
+                               echo "  -C <lattice constant>"
+                               echo "  -m <dimX> <dimY> <dimZ> (mirror atoms)"
+                               echo "visualization volume:"
+                               echo "  -nll <x> <y> <z> (near lower left)"
+                               echo "  -fur <x> <y> <z> (far upper right)"
+                               echo "  -o (ortographic)"
+                               echo "bounding box:"
+                               echo "  -b <x0> <y0> <z0> <x1> <y1> <z1>"
+                               echo "povray:"
+                               echo "  -c <x> <y> <z> (camera position)"
+                               echo "  -L <x> <y> <z> (camera look)"
+                               echo "  -l <x> <y> <z> (light source)"
+                               echo "bonds:"
+                               echo "  -ab <atom number> <cutoff> (auto bonds)"
+                               echo "symmetry:"
+                               echo "  -s <sym nr>"
+                               echo "     1: sym by <1 -1 0> at 1/4 <1 1 0>"
+                               exit 1;;
+       esac
+done
+
+# calculation from lattic eunits to angstroms
+
+[ "$lc" = "sic" ] && lc=4.359
+[ "$lc" = "si" ] && lc=5.480
+[ "$lc" = "c" ] && lc=3.566
+
+#offset=`echo 0.125 \* $lc | bc`
+offset=0.0
+
+x0=`echo $x0 \* $lc + $offset | bc`
+y0=`echo $y0 \* $lc + $offset | bc`
+z0=`echo $z0 \* $lc + $offset | bc`
+x1=`echo $x1 \* $lc + $offset | bc`
+y1=`echo $y1 \* $lc + $offset | bc`
+z1=`echo $z1 \* $lc + $offset | bc`
+
+mx1=`echo $mx1 \* $lc + $offset | bc`
+my1=`echo $my1 \* $lc + $offset | bc`
+mz1=`echo $mz1 \* $lc + $offset | bc`
+mx2=`echo $mx2 \* $lc + $offset | bc`
+my2=`echo $my2 \* $lc + $offset | bc`
+mz2=`echo $mz2 \* $lc + $offset | bc`
+mx3=`echo $mx3 \* $lc + $offset | bc`
+my3=`echo $my3 \* $lc + $offset | bc`
+mz3=`echo $mz3 \* $lc + $offset | bc`
+
+clx=`echo $clx \* $lc + $offset | bc`
+cly=`echo $cly \* $lc + $offset | bc`
+clz=`echo $clz \* $lc + $offset | bc`
+
+if [ -n "$cx" -a -n "$cy" -a -n "$cz" ]; then
+       cx=`echo $cx \* $lc + $offset | bc`
+       cy=`echo $cy \* $lc + $offset | bc`
+       cz=`echo $cz \* $lc + $offset | bc`
+fi
+
+if [ -n "$bx0" ]; then
+       bx0=`echo $bx0 \* $lc + $offset | bc`
+       by0=`echo $by0 \* $lc + $offset | bc`
+       bz0=`echo $bz0 \* $lc + $offset | bc`
+       bx1=`echo $bx1 \* $lc + $offset | bc`
+       by1=`echo $by1 \* $lc + $offset | bc`
+       bz1=`echo $bz1 \* $lc + $offset | bc`
+fi
+
+# povray command
+POVRAY="povray -W${width} -H${height} -d" 
+
+# camera location
+[ -n "$cx" -a -n "$cy" -a -n "$cz" ] && camloc="<$cx,$cz,$cy>"
+
+# convert options
+COPTS="-font /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"
+COPTS="$COPTS -depth 8 -fill white -stroke blue -pointsize 24"
+
+# do it ...
+
+if [ -d $directory ]; then
+       filesource=$directory/CONTCAR*
+fi
+
+if [ -f $directory ]; then
+       filesource=$directory
+fi
+
+for file in $filesource; do
+
+       echo "working on $file ..."
+
+       cat > temp.pov <<-EOF
+#include "colors.inc"
+#include "textures.inc"
+#include "shapes.inc"
+#include "glass.inc"
+#include "metals.inc"
+#include "woods.inc"
+#include "stones.inc"
+EOF
+
+       # meta info
+       scale=`sed -n 2p $file | awk '{ print $1 }'`
+       line="`sed -n 3p $file`"
+       X1=`echo $line | awk '{ print $1 }'`
+       X2=`echo $line | awk '{ print $2 }'`
+       X3=`echo $line | awk '{ print $3 }'`
+       line="`sed -n 4p $file`"
+       Y1=`echo $line | awk '{ print $1 }'`
+       Y2=`echo $line | awk '{ print $2 }'`
+       Y3=`echo $line | awk '{ print $3 }'`
+       line="`sed -n 5p $file`"
+       Z1=`echo $line | awk '{ print $1 }'`
+       Z2=`echo $line | awk '{ print $2 }'`
+       Z3=`echo $line | awk '{ print $3 }'`
+       line="`sed -n 6p $file`"
+       nsi=`echo $line | awk '{ print $1 }'`
+       nc=`echo $line | awk '{ print $2 }'`
+       ((ntot=nsi+nc))
+
+       echo "Si : $nsi"
+       echo "C  : $nc"
+       echo "tot: $ntot"
+       echo "cutoff: $cutoff"
+
+       export scale
+       export X1 X2 X3
+       export Y1 Y2 Y3
+       export Z1 Z2 Z3
+       
+       export x0 y0 z0 x1 y1 z1 radius
+
+       export sym
+
+       # atoms
+       ((count=1))
+       checktsd=`sed -n 7p $file | awk '{ print $1 }'`
+       if [ "$checktsd" = "Transformed" ]; then
+               ((offset=9))
+               echo "tsd: yes, offset = $offset"
+               # but maybe not
+               checkmore=`sed -n 8p $file | awk '{ print $1 }'`
+               if [ "$checkmore" = "Direct" ]; then
+                       ((offset=8))
+                       echo "tsd: yes, but anyways using offset $offset"
+               fi
+       else
+               ((offset=8))
+               echo "tsd: no, offset = $offset"
+       fi
+       while [ "1" ]; do
+
+               [ $count -gt $ntot ] && break
+
+               if [ $count -le $nsi ]; then
+                       color="Yellow"
+               else
+                       color="Gray"
+               fi
+               export color
+
+               ((gl=offset+count))
+               line="`sed -n ${gl}p $file`"
+               x=`echo $line | awk '{ print $1 }'`
+               y=`echo $line | awk '{ print $2 }'`
+               z=`echo $line | awk '{ print $3 }'`
+
+               echo $x $y $z $count | awk '\
+               BEGIN {
+                       x0=ENVIRON["x0"]; y0=ENVIRON["y0"]; z0=ENVIRON["z0"];
+                       x1=ENVIRON["x1"]; y1=ENVIRON["y1"]; z1=ENVIRON["z1"];
+                       X1=ENVIRON["X1"]; X2=ENVIRON["X2"]; X3=ENVIRON["X3"];
+                       Y1=ENVIRON["Y1"]; Y2=ENVIRON["Y2"]; Y3=ENVIRON["Y3"];
+                       Z1=ENVIRON["Z1"]; Z2=ENVIRON["Z2"]; Z3=ENVIRON["Z3"];
+                       radius=ENVIRON["radius"]; scale=ENVIRON["scale"];
+                       color=ENVIRON["color"]
+                       sym=ENVIRON["sym"]
+                       x=0; y=0; z=0;
+                       xt=0; yt=0; zt=0;
+                       i=0; j=0; k=0;
+               }
+               {
+                       for(i=-1;i<=1;i++) {
+                               for(j=-1;j<=1;j++) {
+                                       for(k=-1;k<=1;k++) {
+
+                       nx=$1+i; ny=$2+j; nz=$3+k;
+
+                       if(sym==1) {
+                               xt=nx-1.0/12.0;
+                               yt=ny-1.0/12.0;
+                               nx=-yt;
+                               ny=-xt;
+                               nx+=1.0/12.0;
+                               ny+=1.0/12.0;
+                       }
+
+                       xt=nx*X1+ny*Y1+nz*Z1;
+                       yt=nx*X2+ny*Y2+nz*Z2;
+                       zt=nx*X3+ny*Y3+nz*Z3;
+
+                       xt*=scale;
+                       yt*=scale;
+                       zt*=scale;
+
+                       if((xt>=x0)&&(yt>=y0)&&(zt>=z0)&&\
+                          (xt<=x1)&&(yt<=y1)&&(zt<=z1)) {
+                               print "// atom " $4;
+                               print "sphere { <"xt","zt","yt">, "radius" ";
+                               print "texture { pigment { color " color " } ";
+                               print "finish { phong 1 metallic } } }";
+                       }
+
+                                       }
+                               }
+                       }
+               }' >> temp.pov
+
+               # see, whether there are bonds to draw
+               if [ "$ab" = "0" ]; then
+                       echo -en "$count "
+                       ((count+=1))
+                       continue
+               fi
+               ((cnt=1))
+               dobond=no
+               while [ $cnt -le $ab ]; do
+                       anr=${anr[$cnt]}
+                       if [ $anr -eq $count ]; then
+                               dobond=yes
+                               break
+                       fi
+                       ((cnt+=1))
+               done
+               if [ "$ab" = "-1" ]; then
+                       if [ -n "`grep \/\/\ atom\ $count temp.pov`" ]; then
+                               dobond=yes
+                       fi
+               fi
+               if [ "$dobond" = "no" ]; then
+                       echo -en "$count "
+                       ((count+=1))
+                       continue;
+               fi
+
+               # draw bonds
+               ((ic=1))
+               while [ "1" ]; do
+
+                       [ $ic -gt $count ] && break
+
+                       if [ $ic -eq $count ]; then
+                               ((ic+=1))
+                               continue
+                       fi
+
+                       ((il=ic+offset))
+                       line="`sed -n ${il}p $file`"
+                       xb=`echo $line | awk '{ print $1 }'`
+                       yb=`echo $line | awk '{ print $2 }'`
+                       zb=`echo $line | awk '{ print $3 }'`
+
+                       echo $x $y $z $xb $yb $zb $cutoff | awk '\
+                       BEGIN {
+                       x0=ENVIRON["x0"]; y0=ENVIRON["y0"]; z0=ENVIRON["z0"];
+                       x1=ENVIRON["x1"]; y1=ENVIRON["y1"]; z1=ENVIRON["z1"];
+                       X1=ENVIRON["X1"]; X2=ENVIRON["X2"]; X3=ENVIRON["X3"];
+                       Y1=ENVIRON["Y1"]; Y2=ENVIRON["Y2"]; Y3=ENVIRON["Y3"];
+                       Z1=ENVIRON["Z1"]; Z2=ENVIRON["Z2"]; Z3=ENVIRON["Z3"];
+                       bcr=ENVIRON["bcr"]; scale=ENVIRON["scale"];
+                       sym=ENVIRON["sym"];
+                       }
+                       {
+                               for(i=-1;i<=1;i++) {
+                                       for(j=-1;j<=1;j++) {
+                                               for(k=-1;k<=1;k++) {
+
+                               for(ii=-1;ii<=1;ii++) {
+                                       for(ij=-1;ij<=1;ij++) {
+                                               for(ik=-1;ik<=1;ik++) {
+       
+                               nx=$1+i; ny=$2+j; nz=$3+k;
+
+                               if(sym==1) {
+                                       xt=nx-1.0/12.0;
+                                       yt=ny-1.0/12.0;
+                                       nx=-yt;
+                                       ny=-xt;
+                                       nx+=1.0/12.0;
+                                       ny+=1.0/12.0;
+                               }
+
+                               xt=nx*X1+ny*Y1+nz*Z1;
+                               yt=nx*X2+ny*Y2+nz*Z2;
+                               zt=nx*X3+ny*Y3+nz*Z3;
+                               xt*=scale;
+                               yt*=scale;
+                               zt*=scale;
+
+                               if((xt>=x0)&&(yt>=y0)&&(zt>=z0)&&\
+                                  (xt<=x1)&&(yt<=y1)&&(zt<=z1)) {
+
+                               inx=$4+ii; iny=$5+ij; inz=$6+ik;
+
+                               if(sym==1) {
+                                       ixt=inx-1.0/12.0;
+                                       iyt=iny-1.0/12.0;
+                                       inx=-iyt;
+                                       iny=-ixt;
+                                       inx+=1.0/12.0;
+                                       iny+=1.0/12.0;
+                               }
+
+                               ixt=inx*X1+iny*Y1+inz*Z1;
+                               iyt=inx*X2+iny*Y2+inz*Z2;
+                               izt=inx*X3+iny*Y3+inz*Z3;
+                               ixt*=scale;
+                               iyt*=scale;
+                               izt*=scale;
+
+                               dist=sqrt((xt-ixt)^2+(yt-iyt)^2+(zt-izt)^2);
+
+                               if((ixt>=x0)&&(iyt>=y0)&&(izt>=z0)&&\
+                                  (ixt<=x1)&&(iyt<=y1)&&(izt<=z1)) {
+
+                               #if((xt>=x0)&&(yt>=y0)&&(zt>=z0)&&\
+                               #   (xt<=x1)&&(yt<=y1)&&(zt<=z1)) {
+                                       if(dist<=$7) {
+                                               print "cylinder {";
+                                               print "<"xt","zt","yt">,";
+                                               print "<"ixt","izt","iyt">,0.1";
+                                               print "pigment { color Blue }";
+                                               print "}";
+                                       }
+                               #}
+
+                               }
+
+                               }
+       
+                                               }
+                                       }
+                               }
+                                               }
+                                       }
+                               }
+                       }' >> temp.pov
+
+                       ((ic+=1))
+                       [ $ic -gt $ntot ] && break;
+
+               done
+
+               echo -en "[$count] "
+               ((count+=1))
+               [ $count -gt $ntot ] && break;
+
+       done
+
+       echo
+
+       # manually drawing the 3x4 boundaries specified by argv ...
+       if [ -n "$bx0" ]; then
+       draw_cyl $bx0 $by0 $bz0 $bx1 $by0 $bz0
+       draw_cyl $bx0 $by0 $bz0 $bx0 $by1 $bz0
+       draw_cyl $bx1 $by1 $bz0 $bx1 $by0 $bz0
+       draw_cyl $bx0 $by1 $bz0 $bx1 $by1 $bz0
+
+       draw_cyl $bx0 $by0 $bz1 $bx1 $by0 $bz1
+       draw_cyl $bx0 $by0 $bz1 $bx0 $by1 $bz1
+       draw_cyl $bx1 $by1 $bz1 $bx1 $by0 $bz1
+       draw_cyl $bx0 $by1 $bz1 $bx1 $by1 $bz1
+
+       draw_cyl $bx0 $by0 $bz1 $bx0 $by0 $bz0
+       draw_cyl $bx0 $by1 $bz1 $bx0 $by1 $bz0
+       draw_cyl $bx1 $by0 $bz1 $bx1 $by0 $bz0
+       draw_cyl $bx1 $by1 $bz1 $bx1 $by1 $bz0
+       fi
+
+       # add camera and light source
+       cat >> temp.pov <<-EOF
+camera {
+EOF
+       if [ -n "$ortographic" ]; then  cat >> temp.pov <<-EOF
+orthographic
+EOF
+       fi
+       cat >> temp.pov <<-EOF
+location $camloc
+look_at <$clx,$clz,$clz>
+}
+light_source { <0,100,-100> color White shadowless }
+EOF
+
+       # mv png
+       $POVRAY temp.pov > /dev/null 2>&1
+       mv temp.png `dirname $file`/
+
+done
+
+echo "done"
index 50507db..68901ec 100644 (file)
 
 #include "moldyn.h"
 
+/* pse */
+#define PSE_NAME
+#define PSE_COL
+#include "pse.h"
+#undef PSE_NAME
+#undef PSE_COL
+
+typedef struct s_data {
+       int ca;
+       double radius;
+       double lc;
+       int ma;
+       double ox,oy,oz;
+} t_data;
+
 int usage(char *prog) {
 
        printf("\nusage:\n");
@@ -25,33 +40,47 @@ int usage(char *prog) {
        return -1;
 }
 
+int process(t_moldyn *moldyn,t_atom *itom,t_atom *jtom,void *ptr,u8 bc) {
+
+       t_3dvec dist;
+       double d;
+       t_data *data;
+
+       data=ptr;
+
+       v3_sub(&dist,&(itom->r),&(jtom->r));
+       if(bc) check_per_bound(moldyn,&dist);
+       d=v3_norm(&dist);
+
+       if(d<=data->radius) {
+               printf("%s %f %f %f %s %f\n",
+                      pse_name[jtom->element],
+                      jtom->r.x+data->ox,jtom->r.y+data->oy,jtom->r.z+data->oz,
+                      (jtom->tag==data->ma)?"Red":pse_col[jtom->element],
+                      jtom->ekin);
+       }
+
+       return 0;
+}
+
 int main(int argc,char **argv) {
 
        t_moldyn moldyn;
-       t_atom *itom,*jtom;
-       int j;
+       t_data data;
        int ret;
-       t_list n[27];
-       t_list *this;
-       t_linkcell *lc;
-       t_3dvec dist;
-       double d,radius;
-       double ox,oy,oz;
-       int ma,ca;
-       double lac;
+       t_atom *atom;
 
        if(argc<4) {
                usage(argv[0]);
                return -1;
        }
-
-       ca=atoi(argv[2]);
-       radius=atof(argv[3]);
-       lac=atof(argv[4]);
-
-       ma=-1;
+       
+       data.ca=atoi(argv[2]);
+       data.radius=atof(argv[3]);
+       data.lc=atof(argv[4]);
+       data.ma=-1;
        if(argc==6)
-               ma=atoi(argv[5]);
+               data.ma=atoi(argv[5]);
 
        memset(&moldyn,0,sizeof(t_moldyn));
 
@@ -63,87 +92,52 @@ int main(int argc,char **argv) {
        }
 
        /* link cell init */
-       moldyn.cutoff=radius;
+       moldyn.cutoff=data.radius;
        link_cell_init(&moldyn,VERBOSE);
-       lc=&(moldyn.lc);
-
-       /* serach atoms */
-       itom=&(moldyn.atom[ca]);
-       link_cell_neighbour_index(&moldyn,
-                                 (itom->r.x+moldyn.dim.x/2)/lc->x,
-                                 (itom->r.y+moldyn.dim.y/2)/lc->y,
-                                 (itom->r.z+moldyn.dim.z/2)/lc->z,
-                                 n);
 
+       atom=&(moldyn.atom[data.ca]);
 
        /* prepare offset */
-       ox=0.0;
-       if(itom->r.x<0) {
-               while((itom->r.x+ox)<(-lac/2.0))
-                       ox+=lac;
+       data.ox=0.0;
+       if(atom->r.x<0) {
+               while((atom->r.x+data.ox)<(-data.lc/2.0))
+                       data.ox+=data.lc;
        }
        else {
-               while((itom->r.x+ox)>(lac/2.0))
-                       ox-=lac;
+               while((atom->r.x+data.ox)>(data.lc/2.0))
+                       data.ox-=data.lc;
        }
 
-       oy=0.0;
-       if(itom->r.y<0) {
-               while((itom->r.y+oy)<(-lac/2.0))
-                       oy+=lac;
+       data.oy=0.0;
+       if(atom->r.y<0) {
+               while((atom->r.y+data.oy)<(-data.lc/2.0))
+                       data.oy+=data.lc;
        }
        else {
-               while((itom->r.y+oy)>(lac/2.0))
-                       oy-=lac;
+               while((atom->r.y+data.oy)>(data.lc/2.0))
+                       data.oy-=data.lc;
        }
 
-       oz=0.0;
-       if(itom->r.z<0) {
-               while((itom->r.z+oz)<(-lac/2.0))
-                       oz+=lac;
+       data.oz=0.0;
+       if(atom->r.z<0) {
+               while((atom->r.z+data.oz)<(-data.lc/2.0))
+                       data.oz+=data.lc;
        }
        else {
-               while((itom->r.z+oz)>(lac/2.0))
-                       oz-=lac;
+               while((atom->r.z+data.oz)>(data.lc/2.0))
+                       data.oz-=data.lc;
        }
 
-
+       /* print the centered atom */
        printf("%s %f %f %f %s %f\n",
-              pse_name[itom->element],itom->r.x+ox,itom->r.y+oy,itom->r.z+oz,
-              "Green",itom->ekin);
-
-       for(j=0;j<27;j++) {
-               this=&(n[j]);
-               list_reset_f(this);
-
-               if(this->start==NULL)
-                       continue;
-
-               do {
-
-                       jtom=this->current->data;
-
-                       if(jtom==itom)
-                               continue;
-
-                       v3_sub(&dist,&(itom->r),&(jtom->r));
-                       check_per_bound(&moldyn,&dist);
-                       d=v3_norm(&dist);
-
-                       if(d<=radius) {
-                               printf("%s %f %f %f %s %f\n",
-                                      pse_name[jtom->element],
-                                      jtom->r.x+ox,jtom->r.y+oy,jtom->r.z+oz,
-                                      (jtom->tag==ma)?"Red":pse_col[jtom->element],
-                                      jtom->ekin);
-                       }
-
-               } while(list_next_f(this)!=L_NO_NEXT_ELEMENT);
-       }
+              pse_name[atom->element],atom->r.x+data.ox,atom->r.y+data.oy,
+               atom->r.z+data.oz,"Green",atom->ekin);
 
+       process_neighbours(&moldyn,&data,atom,process);
+       
        link_cell_shutdown(&moldyn);
-
        moldyn_free_save_file(&moldyn);
 
        return 0;
 }
+
diff --git a/visual_atoms_script b/visual_atoms_script
new file mode 100755 (executable)
index 0000000..2b7f55f
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+rm -f $5/va_*.*
+
+((count=0))
+
+./search_bonds $1 $2 $3 $4 | grep ' # atoms' | while read a b c d e f; do
+
+       ca=`echo $c | awk -F/ '{ print $1}'`
+       ma=`echo $d | awk -F/ '{ print $1}'`
+
+       ./visual_atoms $1 $ca 12.0 5.429 $ma | \
+               grep ^[A-Z] > $5/va_${count}.xyz
+
+       which povray
+       ret=$?
+       if [ "$ret" = "0" ]; then
+               ./visualize -w 640 -h 480 -d $5/va_${count}.xyz \
+                            -nll -0.76 -0.76 -0.76 -fur 0.76 0.76 0.76 \
+                            -b -0.5 -0.5 -0.5 0.5 0.5 0.5 \
+                            -c -0.2 -2.0 0.6 -L 0 0 -0.1 \
+                            -r 0.6 -B 0.1
+       fi
+
+       echo -en "$count "
+
+       ((count+=1))
+done
+
+echo "done"
+
+qiv $5/va_*.png
+
index 7dc964e..0b8fc61 100755 (executable)
--- a/visualize
+++ b/visualize
@@ -31,7 +31,7 @@ width="640"
 height="480"
 radius="0.6"
 x0="-0.6"; y0="-0.6"; z0="-0.6";
-x1="+0.6"; y1="+0.6"; z1="+0.6";
+x1="0.6"; y1="0.6"; z1="0.6";
 cx=""; cy=""; cz="";
 lx="0"; ly="-100"; lz="100";
 ortographic=""
@@ -39,6 +39,7 @@ bx0=""; by0=""; bz0="";
 bx1=""; by1=""; bz1="";
 bcr="";
 clx="0"; cly="0"; clz="0";
+extra=0
 
 # parse argv
 
@@ -58,6 +59,7 @@ while [ "$1" ]; do
                                bx1=$5; by1=$6; bz1=$7; shift 7;;
                -B)             bcr=$2;                 shift 2;;
                -C)             lc=$2;                  shift 2;;
+               -e)             extra=1;                shift 1;;
                *)
                                echo "options:"
                                echo "########"
@@ -92,6 +94,7 @@ done
 [ "$lc" = "c" ] && lc=3.566
 
 offset=`echo 0.125 \* $lc | bc`
+#offset=0.0
 
 x0=`echo $x0 \* $lc + $offset | bc`
 y0=`echo $y0 \* $lc + $offset | bc`
@@ -123,6 +126,11 @@ fi
 
 POVRAY="povray -W${width} -H${height} -d" 
 
+# convert options
+
+COPTS="-font /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"
+COPTS="$COPTS -depth 8 -fill white -stroke blue -pointsize 24"
+
 # do it ...
 
 if [ -d $directory ]; then
@@ -153,18 +161,21 @@ EOF
 
        # atoms
        if [ -n "$x0" ]; then
-               export x0 y0 z0 x1 y1 z1 radius
+               export x0 y0 z0 x1 y1 z1 radius extra
                cat $file | grep -v '#' | awk '\
                BEGIN {
                        x0=ENVIRON["x0"]; y0=ENVIRON["y0"]; z0=ENVIRON["z0"];
                        x1=ENVIRON["x1"]; y1=ENVIRON["y1"]; z1=ENVIRON["z1"];
-                       radius=ENVIRON["radius"];
+                       radius=ENVIRON["radius"]; extra=ENVIRON["extra"];
                }
                {
                        if(($2>=x0)&&($3>=y0)&&($4>=z0)&&\
                           ($2<=x1)&&($3<=y1)&&($4<=z1)) {
                                print "sphere { <"$2","$4","$3">, "radius" ";
-                               print "texture { pigment { color "$5" } ";
+                               if(extra)
+               print "texture { pigment { color rgb<"$6/4.4",0,"1-$6/4.4"> } ";
+                               else
+               print "texture { pigment { color "$5" } ";
                                print "finish { phong 1 metallic } } }";
                        }
                }' >> temp.pov
@@ -188,29 +199,30 @@ EOF
        # boundaries
        if [ -z "$bx0" ]; then
 
-       if [ -z "$x0" ]; then
+       #if [ -z "$x0" ]; then
 
        cat $file | grep '# \[D\]' | while read foo bar x1 y1 z1 x2 y2 z2 ; do
-               draw_cyl $x1 $z1 $y1 $x2 $z2 $y2 0.05
+               draw_cyl $x1 $y1 $z1 $x2 $y2 $z2 0.05
        done
 
-       else
+       #else
+
                # manually drawing the 3x4 boundaries ...
-               draw_cyl $x0 $y0 $z0 $x1 $y0 $z0
-               draw_cyl $x0 $y0 $z0 $x0 $y1 $z0
-               draw_cyl $x1 $y1 $z0 $x1 $y0 $z0
-               draw_cyl $x0 $y1 $z0 $x1 $y1 $z0
-
-               draw_cyl $x0 $y0 $z1 $x1 $y0 $z1
-               draw_cyl $x0 $y0 $z1 $x0 $y1 $z1
-               draw_cyl $x1 $y1 $z1 $x1 $y0 $z1
-               draw_cyl $x0 $y1 $z1 $x1 $y1 $z1
-
-               draw_cyl $x0 $y0 $z1 $x0 $y0 $z0
-               draw_cyl $x0 $y1 $z1 $x0 $y1 $z0
-               draw_cyl $x1 $y0 $z1 $x1 $y0 $z0
-               draw_cyl $x1 $y1 $z1 $x1 $y1 $z0
-       fi
+#              draw_cyl $x0 $y0 $z0 $x1 $y0 $z0
+#              draw_cyl $x0 $y0 $z0 $x0 $y1 $z0
+#              draw_cyl $x1 $y1 $z0 $x1 $y0 $z0
+#              draw_cyl $x0 $y1 $z0 $x1 $y1 $z0
+
+#              draw_cyl $x0 $y0 $z1 $x1 $y0 $z1
+#              draw_cyl $x0 $y0 $z1 $x0 $y1 $z1
+#              draw_cyl $x1 $y1 $z1 $x1 $y0 $z1
+#              draw_cyl $x0 $y1 $z1 $x1 $y1 $z1
+
+#              draw_cyl $x0 $y0 $z1 $x0 $y0 $z0
+#              draw_cyl $x0 $y1 $z1 $x0 $y1 $z0
+#              draw_cyl $x1 $y0 $z1 $x1 $y0 $z0
+#              draw_cyl $x1 $y1 $z1 $x1 $y1 $z0
+#      fi
 
        else
 
@@ -281,6 +293,8 @@ EOF
 
        # mv png
        $POVRAY temp.pov > /dev/null 2>&1
+       time=`basename $file | awk -F. '{ print $1 }' | awk -F_ '{ print $3 }'`
+       convert $COPTS -draw "text 5,20 't = $time fs'" temp.png temp.png
        mv temp.png `echo $file | sed 's/\.xyz/\.png/'`
 
 done