-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
diffusion_calc: $(DEPS)
+diffusion_calc_ver2: $(DEPS)
+
bond_analyze: $(DEPS)
search_bonds: $(DEPS)
display_atom_data: $(DEPS)
+atom_match: $(DEPS)
+
+msd_calc: $(DEPS)
+
+s2xyz: $(DEPS)
+
.PHONY:clean
clean:
rm -vf $(ALL) *.o */*.o
--- /dev/null
+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!
+
--- /dev/null
+/*
+ * 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;
+}
/* 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);
--- /dev/null
+#!/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"
#!/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" }'
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+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)
+
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;
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;
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);
// 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;
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
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':
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)) {
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]);
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);
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]);
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;
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;
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;
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;
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;
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;
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;
}
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)
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)
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;
/* 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)&\
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;
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) {
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;
return 0;
}
steps=0;
- tau=mdrun->timestep;
}
}
}
/* continue simulation */
- moldyn_add_schedule(moldyn,steps,tau);
+ moldyn_add_schedule(moldyn,steps,mdrun->timestep);
return 0;
}
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;
/* 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",
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 */
#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
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
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;
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;
int runs;
int count;
double dt;
+ int interval;
} t_anneal_params;
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;
#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
#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
*/
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;
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));
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:
* 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;
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) {
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;
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:
/* 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);
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;
}
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 */
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;
t_atom *new,*old;
int cnt;
+#if defined LOWMEM_LISTS || defined PTHREADS
+ void *ptr;
+#endif
old=moldyn->atom;
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)
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;
}
/* 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)
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++) {
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;
}
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;
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;
}
/* 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;
}
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 */
}
/* 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;
}
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;
}
/* 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;
/* 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;
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);
/* 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) {
lc->x*=scale;
lc->y*=scale;
lc->z*=scale;
+ //lc->x*=sx;
+ //lc->y*=sx;
+ //lc->z*=sy;
}
return 0;
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;
int link_cell_init(t_moldyn *moldyn,u8 vol) {
t_linkcell *lc;
+#ifndef LOWMEM_LISTS
int i;
+#endif
lc=&(moldyn->lc);
#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
}
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);
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]));
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
#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) {
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)
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
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;
}
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
}
}
}
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]);
list_destroy_f(&(lc->subcell[i]));
#endif
}
+#endif
free(lc->subcell);
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;
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!
/* 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");
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);
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)) {
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);
}
}
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);
}
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));
/* copy over time */
t1=t2;
- //}
+#ifndef PDEBUG
+ }
+#endif
/* increase absolute time */
moldyn->time+=moldyn->tau;
}
+ /* 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;
}
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)] */
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);
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];
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 */
#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);
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
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++) {
#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);
#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);
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);
#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);
#ifdef STATIC_LISTS
}
+#elif LOWMEM_LISTS
+ }
#else
} while(list_next_f(that)!=\
L_NO_NEXT_ELEMENT);
}
#ifdef STATIC_LISTS
}
+#elif LOWMEM_LISTS
+ }
#else
} while(list_next_f(this)!=L_NO_NEXT_ELEMENT);
#endif
#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;
/* 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);
}
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
*/
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);
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;
#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;
#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);
#ifdef STATIC_LISTS
}
+#elif LOWMEM_LISTS
+ }
#else
} while(list_next_f(this)!=L_NO_NEXT_ELEMENT);
#endif
}
+/*
+ * 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
*/
int i;
t_atom *atom;
t_3dvec dist;
+ t_3dvec final_r;
double d2;
int a_cnt;
int b_cnt;
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) {
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;
ba=data;
/* increase total bond counter
- * ... double counting!
*/
- ba->tcnt+=2;
+ ba->tcnt+=1;
if(itom->brand==0)
ba->acnt[jtom->tag]+=1;
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;
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;
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;
return 0;
}
+#ifdef VISUAL_THREAD
+void *visual_atoms(void *ptr) {
+#else
int visual_atoms(t_moldyn *moldyn) {
+#endif
int i;
char file[128+64];
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;
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) {
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;
}
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) */
#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 */
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
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;
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
#define FCC 0x02
#define DIAMOND 0x04
#define ZINCBLENDE 0x08
+#define NONE 0x80
/*
* more includes
*/
-#include "pse.h"
+//#include "pse.h"
/*
*
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);
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
//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));
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);
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
--- /dev/null
+/*
+ * 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;
+}
+
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"
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;
}
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);
--- /dev/null
+#!/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
+
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);
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;
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 */
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;
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 */
#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
--- /dev/null
+/*
+ * 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
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);
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) {
#endif
/* virial */
- virial_calc(aj,&force,&dist_ij);
+ virial_calc(ai,&force,&dist_ij);
/* energy 2bp contribution */
energy=f_r*f_c;
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 */
}
#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 */
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];
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;
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);
#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;
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;
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);
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);
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;
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;
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,
# 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 }'`
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
#include "moldyn.h"
+#ifdef PSE_MASS
static double pse_mass[]={
0,
0,
0,
0,
};
+#endif
+#ifdef PSE_LC
static double pse_lc[]={
0,
0,
0,
0,
};
+#endif
+#ifdef PSE_NAME
static char *pse_name[]={
"*",
"H",
"Cl",
"Ar",
};
+#endif
+#ifdef PSE_COL
static char *pse_col[]={
"*",
"White",
"Cl",
"Ar",
};
+#endif
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;
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
+
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
# 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
# old rasmol
#rasmol -32 -nodisplay < $1/visualize.scr > /dev/null 2>&1
./ppm2avi $1
+
fi
fi
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+#!/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
+
+
+
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);
// 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
#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
--- /dev/null
+CC = gcc-4.3
+
+CFLAGS = -Wall -Winline
+CFLAGS += -O3 -march=native -msse2 -mfpmath=sse
+CFLAGS += -g
+
+LDFLAGS = -lm
+
+ALL = create_lattice
+
+all: $(ALL)
+
--- /dev/null
+/* 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;
+}
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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) }'
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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"
--- /dev/null
+#!/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
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+/*
+ * 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;
+
+}
+
--- /dev/null
+#!/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"
+
--- /dev/null
+#!/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"
+
--- /dev/null
+#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
--- /dev/null
+# 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
+
+
--- /dev/null
+# 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
+
+
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+#!/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"
+
--- /dev/null
+#!/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
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+#!/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"
+
--- /dev/null
+#!/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"
--- /dev/null
+#!/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"
#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");
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));
}
/* 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;
}
+
--- /dev/null
+#!/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
+
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=""
bx1=""; by1=""; bz1="";
bcr="";
clx="0"; cly="0"; clz="0";
+extra=0
# parse argv
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 "########"
[ "$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`
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
# 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
# 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
# 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