From: hackbard Date: Mon, 20 Feb 2012 15:55:56 +0000 (+0100) Subject: Merge branch 'leadoff' X-Git-Url: https://hackdaworld.org/gitweb/?p=physik%2Fposic.git;a=commitdiff_plain;h=6e6d7126ea9a845f11637d8e1b8eb2b570ac4dc9;hp=97dc63eb6a519b8e1f4fbfaa9760dd94539436b0 Merge branch 'leadoff' Conflicts: Makefile moldyn.c potentials/albe.c potentials/albe.h runmd ... hopefully fixed! Just a test to merge leadoff back to master! :) --- diff --git a/Makefile b/Makefile index 1b19d50..fa40909 100644 --- a/Makefile +++ b/Makefile @@ -1,34 +1,60 @@ -CC = gcc +CC = gcc-4.3 +#CC = gcc-3.4 -CFLAGS = -Wall +CFLAGS = -Wall -Winline #CFLAGS += -Wextra -pedantic -CFLAGS += -O3 + +CFLAGS += -O3 -march=native -msse2 -mfpmath=sse +#CFLAGS += -O3 -march=athlon64 + CFLAGS += -g -CFLAGS += -ffloat-store +#CFLAGS += -pg +#CFLAGS += -ffloat-store + +#CFLAGS += -DPARALLEL -fopenmp +#CFLAGS += -DPTHREADS -lpthread +#CFLAGS += -DVISUAL_THREAD -lpthread +#CFLAGS += -DPTHREADS -DVISUAL_THREAD -lpthread -CFLAGS += -DALBE +#CFLAGS += -DALBE +CFLAGS += -DALBE_FAST #CFLAGS += -DTERSOFF_ORIG #CFLAGS += -DSTATIC_LISTS +CFLAGS += -DLOWMEM_LISTS -#CFLAGS += -DNDEBUG +#CFLAGS += -DPDEBUG #CFLAGS += -DDEBUG -#CFLAGS += -DDSTART=-1 -DDEND=3 -DDATOM=0 +#CFLAGS += -DDSTART=50 -DDEND=60 -DDATOM=0 #CFLAGS += -DVDEBUG +#CFLAGS += -DQUENCH + LDFLAGS = -lm + +#LDFLAGS += -lc_p #LDFLAGS += -lefence DEPS = moldyn.o random/random.o list/list.o DEPS += potentials/lennard_jones.o potentials/harmonic_oscillator.o -DEPS += potentials/tersoff.o potentials/albe.o potentials/albe_orig.o +DEPS += potentials/tersoff.o potentials/albe.o +DEPS += potentials/albe_fast.o -ALL = mdrun sic fluctuation_calc postproc pair_correlation_calc diffusion_calc -ALL += bond_analyze search_bonds visual_atoms display_atom_data +SRC = moldyn.c random/random.c list/list.c +SRC += potentials/lennard_jones.c potentials/harmonic_oscillator.c +SRC += potentials/tersoff.c potentials/albe.c +SRC += potentials/albe_fast.c + +#ALL = mdrun sic fluctuation_calc postproc pair_correlation_calc diffusion_calc +ALL = mdrun fluctuation_calc postproc pair_correlation_calc diffusion_calc +ALL += diffusion_calc_ver2 bond_analyze search_bonds visual_atoms +ALL += display_atom_data atom_match msd_calc s2xyz all: $(ALL) -mdrun: $(DEPS) +# main code. using SRC, much more efficient code is produced! +mdrun: $(SRC) +#mdrun: $(DEPS) sic: $(DEPS) config.h @@ -38,6 +64,8 @@ pair_correlation_calc: $(DEPS) diffusion_calc: $(DEPS) +diffusion_calc_ver2: $(DEPS) + bond_analyze: $(DEPS) search_bonds: $(DEPS) @@ -46,6 +74,12 @@ visual_atoms: $(DEPS) display_atom_data: $(DEPS) +atom_match: $(DEPS) + +msd_calc: $(DEPS) + +s2xyz: $(DEPS) + .PHONY:clean clean: rm -vf $(ALL) *.o */*.o diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..d10b149 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,93 @@ +parcas +****** +more DOUBLECHECKs with PARCAS !!!! + + * E_kin + * x/y/z(t) of both + * video of hex -> 100db + +implement +********* + + - improve ins_m_atoms (merge to general ins_atoms function maybe) + + * modified first: try rules to better distribute Si and C *** + * general cleanup + * type 1 square, type 2 radius! + + - clean up mdrun + - config sanity checks + + - anneal -> from current to T with rate R + + - check virial calc, where does the - come from? + + - angular distribution + - structurfactoranalyze (see nordlund paper) + + - filled atoms need atom attrib?!?!? or aattr pre prerun + + - bond_analyze to dump xyz file of atoms + + - improve diff calc + + - pthreads: + + * threads nur einmal oeffnen + * verteilung auf laufende threads + + - potentials: + + * tersoff fast + * meam + + - optimize code! + + * 6.56 + * -> 6.16 (albe_potential_force_calc) unoptimized + * -> 7.05 first variable optimization + * -> 5.53 2nd variable mod (moving out of blocks) + * -> 5.12 source c files (orig albe) /wo float-store (otherwise 9.x) + * -> 5.00 source c, fpu_set() (orig albe) + * -> 5.04 source c, fpu_set() (albe fast) (same w -finline-functions) + * -> 4.55 source c, fpu(), albe orig, fast-math ;) + * -> 4.12 source c, fpu(), albe fast + * -> 4.06 source c, fpu(), albe fast, arch opts + * -> 3.54 ^ + c,d,h,gamma opts + * -> 3.50 ^ + static lists + * -> 3.37 source c, albe f, arch opts, c,d,h,gamma + + lowmem lists (test for bigger + atoms!) + * -> 3.31(36) ^ + inline v_calc + + * -> 4.44 orig albe, lowmem, source c, arch opts + + todo: + - listen ! estimate time + - more in fast (also think about -> 'type') + - inline + +simulation runs +*************** + +- start with small nuclei and amorphous surrounding +- tctrl only in outer regions +- only 1 atom per timestep +- melting exps (both, anneal + interface method) +- interstitials: + - sic ints (compare!) + - more interstitial combinations + - characterize interstitials by PCF, then inc temperature + +learn +***** + +- ab initio / dft itself (find good docs) +- checkout abinit in the same time +- checkout thight binding +- of course md theory! + +write +***** + +- results >> thesis! + diff --git a/atom_match.c b/atom_match.c new file mode 100644 index 0000000..7eb5556 --- /dev/null +++ b/atom_match.c @@ -0,0 +1,228 @@ +/* + * atom_match.c - match atoms and process + * + * author: frank.zirkelbach@physik.uni-augsburg.de + * + */ + +#define _GNU_SOURCE +#include + +#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;iinfile,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 skipped.\n", + ME,am.rule[i].type); + break; + } + } + + /* process data */ + for(i=0;i> $1/bond_analyze.txt +done + +echo "done" diff --git a/calc_delta_e b/calc_delta_e index 4ff46fb..eff07c9 100755 --- a/calc_delta_e +++ b/calc_delta_e @@ -1,9 +1,40 @@ #!/bin/bash +# guess potential +pot=`grep ^potential $1/config | awk '{ print $2 }'` + +echo +if [ "$pot" = "tersoff" ]; then +echo "potential: $pot" +musi=-4.629595 +muc=-7.421824 +music=-12.37363 +else +echo "potential: $pot" +musi=-4.628414 +muc=-7.373091 +music=-12.679618 +fi +echo + file=`ls $1/atomic_conf_* | tail -1` atom_cnt=`grep '# \[P\]' $file | awk '{ print $3 }'` -e0=`grep ^0 $1/energy | awk '{ print $4 }'` -e1=`tail -n 1 $1/energy | awk '{ print $4 }'` +e0=`awk 'NR==2' $1/energy | awk '{ print $3 }'` +e1=`tail -n 1 $1/energy | awk '{ print $3 }'` +ed0=`awk 'NR==2' $1/energy | awk '{ print $6 }'` +ed1=`tail -n 1 $1/energy | awk '{ print $6 }'` +si_cnt=`grep ^Si $file | wc -l` +c_cnt=`grep ^C $file | wc -l` + +echo "-------------------------------------------------------------------------" +echo " Formation energy [eV]: #Si=$si_cnt, #C=$c_cnt, #tot=$atom_cnt" +echo "-------------------------------------------------------------------------" + +echo "$si_cnt $c_cnt $e1 $e0" | \ + awk '{ print " Gao: "($3-$4)*($1+$2) }' +echo "$si_cnt $c_cnt $musi $muc $e1 $music" | \ + #awk '{ print " Posselt: "$5*($1+$2)-0.5*($1+$2)*$6-0.5*($1-$2)*($3-$4) }' + awk '{ print " Posselt: "$5*($1+$2)-$1*$3-$2*$4 }' +echo "$si_cnt $c_cnt $musi $music $e1 $music" | \ + awk '{ print " Tersoff: "$5*($1+$2)-$1*$3-$2*($4-$3) }' -echo "$e0 $e1 $atom_cnt" | \ - awk '{ print ($2-$1)*$3" eV" }' diff --git a/diffusion_calc_ver2.c b/diffusion_calc_ver2.c new file mode 100644 index 0000000..ef071a0 --- /dev/null +++ b/diffusion_calc_ver2.c @@ -0,0 +1,113 @@ +/* + * calculation of diffusion coefficient (version 2) + * + * author: frank.zirkelbach@physik.uni-augsburg.de + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#include "moldyn.h" + +#define CM 1.0e8 + +int usage(char *prog) { + + printf("\nusage:\n"); + printf(" %s \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;i0.5) + dx-=0.5; + if(dx<-0.5) + dx+=0.5; + if(dy>0.5) + dy-=0.5; + if(dy<-0.5) + dy+=0.5; + if(dz>0.5) + dz-=0.5; + if(dz<-0.5) + dz+=0.5; + dx*=moldyn_1.dim.x; + dy*=moldyn_1.dim.y; + dz*=moldyn_1.dim.z; + if(moldyn_0.atom[i].brand) { + b_cnt+=1; + dc[1]+=dx*dx+dy*dy+dz*dz; + } + else { + a_cnt+=1; + dc[0]+=dx*dx+dy*dy+dz*dz; + } + dc[2]+=dx*dx+dy*dy+dz*dz; + } + + dc[0]*=(1.0/(6.0*(moldyn_1.time-moldyn_0.time)*a_cnt)); + dc[1]*=(1.0/(6.0*(moldyn_1.time-moldyn_0.time)*b_cnt)); + dc[2]*=(1.0/(6.0*(moldyn_1.time-moldyn_0.time)*moldyn_0.count)); + + dc[0]*=(SECOND/(CM*CM)); + dc[1]*=(SECOND/(CM*CM)); + dc[2]*=(SECOND/(CM*CM)); + + printf("diffusion coefficients: %.10f %.10f %.10f [cm^2/s]\n", + dc[0],dc[1],dc[2]); + + return 0; +} + diff --git a/logfile b/logfile new file mode 100644 index 0000000..150c159 --- /dev/null +++ b/logfile @@ -0,0 +1,125 @@ +it's never too late to start a logfile ... + ####### + + +05.06.2009: +----------- + +local: c_in_si_mig_01 + +migratin of defects tests + +06.05.2009: +----------- + +local: si_0k, si_20, si_1250, si_2050 + c_0k, c_20, c_1250, c_2050 + sic_0k, sic_20, sic_1250, sic_2050 + + fully relaxed si, c or sic at given temperature, using albe pot + + ... _tersoff + + same, using tersoff pot + + ... _check + + same, without tp-ctrl, to check conservation of energy (both, tersoff an albe) + +04.05.2009: +----------- + +local: c_in_si_prec_01 + + 3x3 lattice si, insertion of same amount of carbon at 2050 celsius, relax 1 ns + +06.04.2009: +----------- + +./posic_2009_02/saves/c_in_si_prec_10 <- 2050 +./posic_2009_02/saves/c_in_si_prec_11 <- 1650 +./posic_2009_02/saves/c_in_si_prec_12 <- 1250 + + like 07, 08, 09 but using tersoff = tersoff + total volume + +./posic_2009_02/saves/c_in_si_prec_12_cnt0k + + continued, cooling down to 0k + +./posic_2009_02/saves/c_in_si_prec_07_cnt0k +./posic_2009_02/saves/c_in_si_prec_09_cnt0k + + continued (from 23.02.09), cooling down to 0K + +23.02.2009: +----------- + +./posic_2009_02/saves/c_in_si_prec_2050_01 +./posic_2009_02/saves/c_in_si_prec_2050_02 WARNING: bullshit notation! see below +./posic_2009_02/saves/c_in_si_prec_2050_03 + + c in sphere of r = 2.5 nm at 01 = 2050 02 = 1650 03 = 1250 celsius + +local: sic_prec_08-tup1250 / 1650 / 2050 + + sic prec at 1250 / 1650 / 2050 celsius + +./posic_2009_02/saves/c_in_si_prec_04 +./posic_2009_02/saves/c_in_si_prec_05 +./posic_2009_02/saves/c_in_si_prec_06 + + like first three, using tersoff <- TODO + +./posic_2009_02/saves/c_in_si_prec_07 <- 2050 +./posic_2009_02/saves/c_in_si_prec_08 <- 1650 +./posic_2009_02/saves/c_in_si_prec_09 <- 1250 + + like first three (albe!) into total volume + +TODO: - kleine si mit genausoviel c ins + - c in groesseres gebiet (tot oder so?) + - c in grosses gebiet + 'mehr' c + +19.02.2009: +----------- + +local: sic_prec_08* + + - sic in si, free run for 2ps, tctrl to 23 celsius + - more tctrl and annealing + +09.02.2009: +----------- + +./posic_2009_01/saves/c_in_si_prec_1650-2150_v2_04 + + tersoff instead of albe, cr = 1.5 angstrom, insertion into sphere r=2.5 + +06.02.2009: +----------- + +adapted parcas albe sic parameters, dcut of si-1 unmodified! + +13.01.2009: +----------- + +./posic_2009_01/saves/c_in_si_prec_1650-2150_v2_03 + + as 02, but cr of Si-C increased to 1.9 + +12.01.2009: +----------- + +./posic_2009_01/saves/c_in_si_prec_1650-2150_v2_02 + + as 01, but: c insertion cr check for another c atom increased to 2.7 angstrom + +08.01.2009: +----------- + +INS_SPHERE implemented + +./posic_2009_01/saves/c_in_si_prec_1650-2150_v2_01 + + 316 x 10 C -> Si, v2: sphere r=2.5 nm, t=1650(+500) + diff --git a/mdrun.c b/mdrun.c index 907388a..26fbc87 100644 --- a/mdrun.c +++ b/mdrun.c @@ -94,9 +94,18 @@ int add_stage(t_mdrun *mdrun,u8 type,void *params) { case STAGE_DISPLACE_ATOM: psize=sizeof(t_displace_atom_params); break; + case STAGE_DEL_ATOMS: + psize=sizeof(t_del_atoms_params); + break; + case STAGE_MODIFY_ATOMS: + psize=sizeof(t_modify_atoms_params); + break; case STAGE_INSERT_ATOMS: psize=sizeof(t_insert_atoms_params); break; + case STAGE_INSERT_MIXED_ATOMS: + psize=sizeof(t_insert_mixed_atoms_params); + break; case STAGE_CONTINUE: psize=sizeof(t_continue_params); break; @@ -109,6 +118,21 @@ int add_stage(t_mdrun *mdrun,u8 type,void *params) { case STAGE_CHSATTR: psize=sizeof(t_chsattr_params); break; + case STAGE_SET_TEMP: + psize=sizeof(t_set_temp_params); + break; + case STAGE_SET_TIMESTEP: + psize=sizeof(t_set_timestep_params); + break; + case STAGE_FILL: + psize=sizeof(t_fill_params); + break; + case STAGE_THERMAL_INIT: + psize=0; + break; + case STAGE_CRT: + psize=sizeof(t_crt_params); + break; default: printf("%s unknown stage type: %02x\n",ME,type); return -1; @@ -142,16 +166,23 @@ int mdrun_parse_config(t_mdrun *mdrun) { char error[128]; char line[128]; char *wptr; - char word[16][64]; + char word[32][64]; int wcnt; int i,o; t_displace_atom_params dap; + t_modify_atoms_params map; t_insert_atoms_params iap; + t_insert_mixed_atoms_params imp; t_continue_params cp; t_anneal_params ap; t_chaattr_params cap; t_chsattr_params csp; + t_set_temp_params stp; + t_set_timestep_params stsp; + t_fill_params fp; + t_del_atoms_params delp; + t_crt_params crtp; /* open config file */ fd=open(mdrun->cfile,O_RDONLY); @@ -176,10 +207,17 @@ int mdrun_parse_config(t_mdrun *mdrun) { // reset memset(&iap,0,sizeof(t_insert_atoms_params)); + memset(&map,0,sizeof(t_modify_atoms_params)); + memset(&imp,0,sizeof(t_insert_mixed_atoms_params)); memset(&cp,0,sizeof(t_continue_params)); memset(&ap,0,sizeof(t_anneal_params)); memset(&cap,0,sizeof(t_chaattr_params)); memset(&csp,0,sizeof(t_chsattr_params)); + memset(&stp,0,sizeof(t_set_temp_params)); + memset(&stsp,0,sizeof(t_set_timestep_params)); + memset(&fp,0,sizeof(t_fill_params)); + memset(&delp,0,sizeof(t_del_atoms_params)); + memset(&crtp,0,sizeof(t_crt_params)); // get command + args wcnt=0; @@ -250,21 +288,133 @@ int mdrun_parse_config(t_mdrun *mdrun) { mdrun->lattice=FCC; if(!strncmp(word[1],"diamond",7)) mdrun->lattice=DIAMOND; + if(!strncmp(word[1],"none",4)) + mdrun->lattice=NONE; + if(wcnt==3) + mdrun->lc=atof(word[2]); } else if(!strncmp(word[0],"element1",8)) { mdrun->element1=atoi(word[1]); - mdrun->m1=pse_mass[mdrun->element1]; } else if(!strncmp(word[0],"element2",8)) { mdrun->element2=atoi(word[1]); - mdrun->m2=pse_mass[mdrun->element2]; } else if(!strncmp(word[0],"fill",6)) { - // only lc mode by now - mdrun->lx=atoi(word[2]); - mdrun->ly=atoi(word[3]); - mdrun->lz=atoi(word[4]); - mdrun->lc=atof(word[5]); + // default values + fp.fill_element=mdrun->element1; + fp.fill_brand=0; + fp.lattice=mdrun->lattice; + fp.p_params.type=0; + fp.d_params.type=0; + fp.d_params.stype=0; + // parse fill command + i=1; + while(ilc=fp.lc; + continue; + } + if(!strncmp(word[i],"eb",2)) { + fp.fill_element=atoi(word[++i]); + fp.fill_brand=atoi(word[++i]); + continue; + } + if(word[i][0]=='p') { + i+=1; + switch(word[i][0]) { + case 'i': + if(word[i][1]=='r') + fp.p_params.type=PART_INSIDE_R; + else + fp.p_params.type=PART_INSIDE_D; + break; + case 'o': + if(word[i][1]=='r') + fp.p_params.type=PART_OUTSIDE_R; + else + fp.p_params.type=PART_OUTSIDE_D; + break; + default: + break; + } + if((fp.p_params.type==PART_INSIDE_R)|| + (fp.p_params.type==PART_OUTSIDE_R)) { + fp.p_params.r=atof(word[++i]); + fp.p_params.p.x=atof(word[++i]); + fp.p_params.p.y=atof(word[++i]); + fp.p_params.p.z=atof(word[++i]); + } + if((fp.p_params.type==PART_INSIDE_D)|| + (fp.p_params.type==PART_OUTSIDE_D)) { + fp.p_params.p.x=atof(word[++i]); + fp.p_params.p.y=atof(word[++i]); + fp.p_params.p.z=atof(word[++i]); + fp.p_params.d.x=atof(word[++i]); + fp.p_params.d.y=atof(word[++i]); + fp.p_params.d.z=atof(word[++i]); + } + continue; + } + if(word[i][0]=='d') { + switch(word[++i][0]) { + case '0': + + fp.d_params.type=DEFECT_TYPE_0D; + if(!strncmp(word[i+1],"dbx",3)) { + fp.d_params.stype=DEFECT_STYPE_DB_X; + } + if(!strncmp(word[i+1],"dby",3)) { + fp.d_params.stype=DEFECT_STYPE_DB_Y; + } + if(!strncmp(word[i+1],"dbz",3)) { + fp.d_params.stype=DEFECT_STYPE_DB_Z; + } + if(!strncmp(word[i+1],"dbr",3)) { + fp.d_params.stype=DEFECT_STYPE_DB_R; + } + i+=1; + fp.d_params.od=atof(word[++i]); + fp.d_params.dd=atof(word[++i]); + fp.d_params.element=atoi(word[++i]); + fp.d_params.brand=atoi(word[++i]); + // parsed in future + fp.d_params.attr=ATOM_ATTR_HB|ATOM_ATTR_VA; + fp.d_params.attr|=ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP; + break; + + case '1': + fp.d_params.type=DEFECT_TYPE_1D; + break; + case '2': + fp.d_params.type=DEFECT_TYPE_2D; + break; + case '3': + fp.d_params.type=DEFECT_TYPE_3D; + break; + default: + break; + } + continue; + + } + // offset + if(word[i][0]=='o') { + fp.o_params.o.x=atof(word[++i])*fp.lc; + fp.o_params.o.y=atof(word[++i])*fp.lc; + fp.o_params.o.z=atof(word[++i])*fp.lc; + fp.o_params.use=1; + continue; + } + i+=1; + } + add_stage(mdrun,STAGE_FILL,&fp); + } + else if(!strncmp(word[0],"thermal_init",12)) { + add_stage(mdrun,STAGE_THERMAL_INIT,NULL); } else if(!strncmp(word[0],"aattr",5)) { // for aatrib line we need a special stage @@ -280,24 +430,30 @@ int mdrun_parse_config(t_mdrun *mdrun) { case 'e': cap.type|=CHAATTR_ELEMENT; break; + case 'n': + cap.type|=CHAATTR_NUMBER; default: break; } } i=2; if(cap.type&CHAATTR_REGION) { - cap.x0=atof(word[1]); - cap.y0=atof(word[2]); - cap.z0=atof(word[3]); - cap.x1=atof(word[4]); - cap.y1=atof(word[5]); - cap.z1=atof(word[6]); + cap.x0=atof(word[2]); + cap.y0=atof(word[3]); + cap.z0=atof(word[4]); + cap.x1=atof(word[5]); + cap.y1=atof(word[6]); + cap.z1=atof(word[7]); i+=6; } if(cap.type&CHAATTR_ELEMENT) { cap.element=atoi(word[i]); i+=1; } + if(cap.type&CHAATTR_NUMBER) { + cap.element=atoi(word[i]); + i+=1; + } for(o=0;o0) + csp.ptau=0.01/(csp.ptau*GPA); csp.type|=CHSATTR_PCTRL; } if(!strncmp(word[i],"tctrl",5)) { @@ -384,6 +542,29 @@ int mdrun_parse_config(t_mdrun *mdrun) { dap.dz=atof(word[5]); add_stage(mdrun,STAGE_DISPLACE_ATOM,&dap); } + else if(!strncmp(word[1],"del_atoms",9)) { + delp.o.x=atof(word[2]); + delp.o.y=atof(word[3]); + delp.o.z=atof(word[4]); + delp.r=atof(word[5]); + add_stage(mdrun,STAGE_DEL_ATOMS,&delp); + } + else if(!strncmp(word[1],"mod_atoms",8)) { + i=2; + while(istage.current->data; + delp=stage->params; + + if(delp->r<0) + outer=1; + + for(i=0;icount;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;icount;i++) { + if(atom[i].tag==map->tag) { + v.x=sqrt(2.0*fabs(map->ekin.x)/atom[i].mass); + if(map->ekin.x<0.0) + v.x=-v.x; + v.y=sqrt(2.0*fabs(map->ekin.y)/atom[i].mass); + if(map->ekin.y<0.0) + v.y=-v.y; + v.z=sqrt(2.0*fabs(map->ekin.z)/atom[i].mass); + if(map->ekin.z<0.0) + v.z=-v.z; + v3_copy(&(atom[i].v),&v); + printf("%s atom modified: v = (%f %f %f)\n", + ME,v.x,v.y,v.z); + } + } + + return 0; +} + int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) { t_insert_atoms_params *iap; @@ -573,7 +920,7 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) { z0=-z/2.0; cr_check=TRUE; break; - case INS_REGION: + case INS_RECT: x=iap->x1-iap->x0; x0=iap->x0; y=iap->y1-iap->y0; @@ -582,7 +929,17 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) { z0=iap->z0; cr_check=TRUE; break; + case INS_SPHERE: + x=2.0*iap->x1; + x0=iap->x0-iap->x1; + y=x; + y0=iap->y0-iap->x1; + z=x; + z0=iap->z0-iap->x1; + cr_check=TRUE; + break; case INS_POS: + case INS_RELPOS: x0=iap->x0; y0=iap->y0; z0=iap->z0; @@ -598,7 +955,7 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) { while(cntins_atoms) { run=1; while(run) { - if(iap->type!=INS_POS) { + if((iap->type!=INS_POS)&&(iap->type!=INS_RELPOS)) { r.x=rand_get_double(&(moldyn->random))*x; r.y=rand_get_double(&(moldyn->random))*y; r.z=rand_get_double(&(moldyn->random))*z; @@ -608,9 +965,16 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) { r.y=0.0; r.z=0.0; } - r.x+=x0; - r.y+=y0; - r.z+=z0; + if(iap->type==INS_RELPOS) { + r.x+=x0*mdrun->lc; + r.y+=y0*mdrun->lc; + r.z+=z0*mdrun->lc; + } + else { + r.x+=x0; + r.y+=y0; + r.z+=z0; + } // offset if(iap->type!=INS_TOTAL) { r.x+=o; @@ -633,19 +997,146 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) { dmin=d; } } + if(iap->type==INS_SPHERE) { + if((r.x-iap->x0)*(r.x-iap->x0)+ + (r.y-iap->y0)*(r.y-iap->y0)+ + (r.z-iap->z0)*(r.z-iap->z0)> + (iap->x1*iap->x1)) { + run=1; + } + } } - add_atom(moldyn,iap->element,pse_mass[iap->element], + add_atom(moldyn,iap->element, iap->brand,iap->attr,&r,&v); printf("%s atom inserted (%d/%d): %f %f %f\n", ME,(iap->cnt_steps+1)*iap->ins_atoms, iap->ins_steps*iap->ins_atoms,r.x,r.y,r.z); - printf(" -> d2 = %f/%f\n",dmin,iap->cr*iap->cr); + printf(" attributes: "); + if(iap->attr&ATOM_ATTR_VB) + printf("b "); + if(iap->attr&ATOM_ATTR_HB) + printf("h "); + if(iap->attr&ATOM_ATTR_VA) + printf("v "); + if(iap->attr&ATOM_ATTR_FP) + printf("f "); + if(iap->attr&ATOM_ATTR_1BP) + printf("1 "); + if(iap->attr&ATOM_ATTR_2BP) + printf("2 "); + if(iap->attr&ATOM_ATTR_3BP) + printf("3 "); + printf("\n"); + printf(" d2 = %f/%f\n",dmin,iap->cr*iap->cr); cnt+=1; } return 0; } +int insert_mixed_atoms(t_moldyn *moldyn,t_mdrun *mdrun) { + + t_stage *stage; + t_insert_mixed_atoms_params *imp; + t_atom *atom; + double x,x0,y,y0,z,z0; + double dmin,d,cmin,cmax; + u8 retry; + t_3dvec r,v,dist; + int i; + + + stage=mdrun->stage.current->data; + imp=stage->params; + + x=moldyn->dim.x; + x0=-x/2.0; + y=moldyn->dim.y; + y0=-y/2.0; + z=moldyn->dim.z; + z0=-z/2.0; + + v.x=0.0; + v.y=0.0; + v.z=0.0; + + cmin=imp->crmin*imp->crmin; + cmax=imp->crmax*imp->crmax; + + while(imp->amount1|imp->amount2) { + if(imp->amount1) { + retry=1; + while(retry) { + retry=0; + r.x=rand_get_double(&(moldyn->random))*x; + r.y=rand_get_double(&(moldyn->random))*y; + r.z=rand_get_double(&(moldyn->random))*z; + r.x+=x0; + r.y+=y0; + r.z+=z0; + dmin=1000.0; // for sure too high! + for(i=0;icount;i++) { + atom=&(moldyn->atom[i]); + v3_sub(&dist,&(atom->r),&r); + check_per_bound(moldyn,&dist); + d=v3_absolute_square(&dist); + if(dcmax) + 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;icount;i++) { + atom=&(moldyn->atom[i]); + v3_sub(&dist,&(atom->r),&r); + check_per_bound(moldyn,&dist); + d=v3_absolute_square(&dist); + if(dcmax) + retry=1; + } + add_atom(moldyn,imp->element2, + imp->brand2,imp->attr2,&r,&v); + printf("%s (mixed) atom inserted (%d): %f %f %f\n", + ME,imp->amount2,r.x,r.y,r.z); + printf(" -> d2 = %f/%f/%f\n",dmin,cmin,cmax); + imp->amount2-=1; + } + } + + return 0; +} + int chaatr(t_moldyn *moldyn,t_mdrun *mdrun) { t_stage *stage; @@ -662,23 +1153,32 @@ int chaatr(t_moldyn *moldyn,t_mdrun *mdrun) { if(cap->element!=atom->element) continue; } + if(cap->type&CHAATTR_NUMBER) { + if(cap->element!=atom->tag) + continue; + } if(cap->type&CHAATTR_REGION) { - if(cap->x0r.x) + if(cap->x0>atom->r.x) continue; - if(cap->y0r.y) + if(cap->y0>atom->r.y) continue; - if(cap->z0r.z) + if(cap->z0>atom->r.z) continue; - if(cap->x1>atom->r.x) + if(cap->x1r.x) continue; - if(cap->y1>atom->r.y) + if(cap->y1r.y) continue; - if(cap->z1>atom->r.z) + if(cap->z1r.z) continue; } + if(!(cap->type&CHAATTR_TOTALV)) + printf(" changing attributes of atom %d (0x%x)\n", + i,cap->attr); atom->attr=cap->attr; } + printf("\n\n"); + return 0; } @@ -694,13 +1194,13 @@ int chsattr(t_moldyn *moldyn,t_mdrun *mdrun) { if(csp->ptau>0) set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau); else - set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau); + set_p_scale(moldyn,P_SCALE_NONE,1.0); } if(csp->type&CHSATTR_TCTRL) { if(csp->ttau>0) set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau); else - set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau); + set_t_scale(moldyn,T_SCALE_NONE,1.0); } if(csp->type&CHSATTR_PRELAX) { if(csp->dp<0) @@ -729,6 +1229,138 @@ int chsattr(t_moldyn *moldyn,t_mdrun *mdrun) { return 0; } +int crt(t_moldyn *moldyn,t_mdrun *mdrun) { + + t_stage *stage; + t_crt_params *crtp; + + int fd; + char line[128]; + char *wptr; + int acount; + int ret; + void *ptr; + + t_atom *atom; + t_3dvec disp; + double frac; + int i; + + stage=mdrun->stage.current->data; + crtp=stage->params; + + acount=0; + + /* initial stuff */ + + if(crtp->count==0) { + printf(" crt init\n"); + // read final positions, constraints and do the alloc + fd=open(crtp->file,O_RDONLY); + if(fd<0) { + perror("[mdrun] FATAL reading constraints file"); + return fd; + } + while(1) { + ret=get_line(fd,line,128); + // check for end of file + if(ret<=0) { + printf(" read %d atom positions\n",acount); + if(acount!=moldyn->count) + printf(" atom count mismatch!!!\n"); + printf("\n"); + break; + } + // ignore # lines and \n + if((line[0]=='#')|(ret==1)) + continue; + // allocate new memory + ptr=realloc(crtp->r_fin,(acount+1)*sizeof(t_3dvec)); + if(ptr==NULL) { + perror("[mdrun] FATAL realloc crt positions"); + return -1; + } + crtp->r_fin=ptr; + ptr=realloc(constraints,(acount+1)*3*sizeof(u8)); + if(ptr==NULL) { + perror("[mdrun] FATAL realloc crt constraints"); + return -1; + } + constraints=ptr; + // ignore type + wptr=strtok(line," \t"); + // read x y z + wptr=strtok(NULL," \t"); + crtp->r_fin[acount].x=atof(wptr); + wptr=strtok(NULL," \t"); + crtp->r_fin[acount].y=atof(wptr); + wptr=strtok(NULL," \t"); + crtp->r_fin[acount].z=atof(wptr); + // read constraints + wptr=strtok(NULL," \t"); + constraints[3*acount]=atoi(wptr); + wptr=strtok(NULL," \t"); + constraints[3*acount+1]=atoi(wptr); + wptr=strtok(NULL," \t"); + constraints[3*acount+2]=atoi(wptr); + // done reading + acount+=1; + } + close(fd); + // allocate trafo angles + trafo_angle=malloc(acount*2*sizeof(double)); + if(trafo_angle==NULL) { + perror("[mdrun] FATAL alloc trafo angles"); + return -1; + } + // set crt mode + crtt=crtp->type; + } + + /* write a save file s-crt_xofy.save */ + snprintf(line,128,"%s/s-crt_%03dof%03d.save", + moldyn->vlsdir,crtp->count,crtp->steps); + fd=open(line,O_WRONLY|O_TRUNC|O_CREAT,S_IRUSR|S_IWUSR); + if(fd<0) perror("[mdrun] crt save fd open"); + else { + write(fd,moldyn,sizeof(t_moldyn)); + write(fd,moldyn->atom, + moldyn->count*sizeof(t_atom)); + } + close(fd); + /* visualize atoms */ + visual_atoms(moldyn); + + /* output energy */ + printf(" crt energy: %d - %f\n\n", + crtp->count,(moldyn->ekin+moldyn->energy)/EV); + + /* crt routines: calculate displacement + set individual constraints */ + + printf(" crt step %d of %d in total\n\n",crtp->count+1,crtp->steps); + + if((crtp->type==1)|(crtp->count==0)) + printf(" crt angle update\n\n"); + + for(i=0;icount;i++) { + // calc displacements + atom=moldyn->atom; + v3_sub(&disp,&(crtp->r_fin[i]),&(atom[i].r)); + // angles + if((crtp->type==1)|(crtp->count==0)) { + trafo_angle[2*i]=atan2(disp.x,disp.y); + trafo_angle[2*i+1]=-atan2(disp.z, + sqrt(disp.x*disp.x+disp.y*disp.y)); + } + // move atoms + frac=1.0/(crtp->steps-crtp->count); + v3_scale(&disp,&disp,frac); + v3_add(&(atom[i].r),&(atom[i].r),&disp); + } + + return 0; +} + #define stage_print(m) if(!(stage->executed)) \ printf("%s",m) @@ -739,12 +1371,17 @@ int mdrun_hook(void *ptr1,void *ptr2) { t_stage *stage; t_list *sl; int steps; - double tau; u8 change_stage; + t_3dvec o; t_insert_atoms_params *iap; + t_insert_mixed_atoms_params *imp; t_continue_params *cp; t_anneal_params *ap; + t_set_temp_params *stp; + t_set_timestep_params *stsp; + t_fill_params *fp; + t_crt_params *crtp; moldyn=ptr1; mdrun=ptr2; @@ -760,9 +1397,8 @@ int mdrun_hook(void *ptr1,void *ptr2) { /* get stage description */ stage=sl->current->data; - /* default steps and tau values */ + /* steps in next schedule */ steps=mdrun->relax_steps; - tau=mdrun->timestep; /* check whether relaxation steps are necessary */ if((check_pressure(moldyn,mdrun)==TRUE)&\ @@ -780,6 +1416,16 @@ int mdrun_hook(void *ptr1,void *ptr2) { displace_atom(moldyn,mdrun); change_stage=TRUE; break; + case STAGE_DEL_ATOMS: + stage_print(" -> del atoms\n\n"); + del_atoms(moldyn,mdrun); + change_stage=TRUE; + break; + case STAGE_MODIFY_ATOMS: + stage_print(" -> modify atoms\n\n"); + modify_atoms(moldyn,mdrun); + change_stage=TRUE; + break; case STAGE_INSERT_ATOMS: stage_print(" -> insert atoms\n\n"); iap=stage->params; @@ -790,6 +1436,18 @@ int mdrun_hook(void *ptr1,void *ptr2) { insert_atoms(moldyn,mdrun); iap->cnt_steps+=1; break; + + + + case STAGE_INSERT_MIXED_ATOMS: + stage_print(" -> insert mixed atoms\n\n"); + imp=stage->params; + insert_mixed_atoms(moldyn,mdrun); + change_stage=TRUE; + break; + + + case STAGE_CONTINUE: stage_print(" -> continue\n\n"); if(stage->executed==TRUE) { @@ -810,17 +1468,103 @@ int mdrun_hook(void *ptr1,void *ptr2) { set_temperature(moldyn, moldyn->t_ref+ap->dt); ap->count+=1; + steps=ap->interval; break; case STAGE_CHAATTR: - stage_print(" -> chaattr\n\n"); + stage_print(" -> change atom attributes\n\n"); chaatr(moldyn,mdrun); change_stage=TRUE; break; case STAGE_CHSATTR: - stage_print(" -> chsattr\n\n"); + stage_print(" -> change sys attributes\n\n"); chsattr(moldyn,mdrun); change_stage=TRUE; break; + case STAGE_SET_TEMP: + stage_print(" -> set temperature\n\n"); + stp=stage->params; + if(stp->type&SET_TEMP_CURRENT) { + set_temperature(moldyn,moldyn->t_avg); + } + else { + set_temperature(moldyn,stp->val); + } + change_stage=TRUE; + break; + case STAGE_SET_TIMESTEP: + stage_print(" -> set timestep\n\n"); + stsp=stage->params; + mdrun->timestep=stsp->tau; + change_stage=TRUE; + break; + case STAGE_FILL: + stage_print(" -> fill lattice\n\n"); + fp=stage->params; + switch(fp->lattice) { + case ZINCBLENDE: + + o.x=0.5*0.25*fp->lc; + o.y=o.x; + o.z=o.x; + create_lattice(moldyn, + FCC,fp->lc, + mdrun->element1, + DEFAULT_ATOM_ATTR,0, + fp->lx,fp->ly,fp->lz, + &o, + &(fp->p_params), + &(fp->d_params), + &(fp->o_params)); + o.x+=0.25*fp->lc; + o.y=o.x; + o.z=o.x; + create_lattice(moldyn, + FCC,fp->lc, + mdrun->element2, + DEFAULT_ATOM_ATTR,1, + fp->lx,fp->ly,fp->lz, + &o, + &(fp->p_params), + &(fp->d_params), + &(fp->o_params)); + break; + + default: + + create_lattice(moldyn, + fp->lattice,fp->lc, + fp->fill_element, + DEFAULT_ATOM_ATTR, + fp->fill_brand, + fp->lx,fp->ly,fp->lz, + NULL, + &(fp->p_params), + &(fp->d_params), + &(fp->o_params)); + break; + } + moldyn_bc_check(moldyn); + change_stage=TRUE; + break; + case STAGE_THERMAL_INIT: + stage_print(" -> thermal init\n\n"); + thermal_init(moldyn,TRUE); + change_stage=TRUE; + break; + case STAGE_CRT: + stage_print(" -> constraint relaxation"); + stage_print(" technique\n\n"); + crtp=stage->params; + if(crtp->count==crtp->steps) { + free(constraints); + free(trafo_angle); + free(crtp->r_fin); + change_stage=TRUE; + break; + } + crt(moldyn,mdrun); + crtp->count+=1; + break; default: printf("%s unknwon stage type\n",ME); break; @@ -837,7 +1581,6 @@ int mdrun_hook(void *ptr1,void *ptr2) { return 0; } steps=0; - tau=mdrun->timestep; } } @@ -850,7 +1593,7 @@ int mdrun_hook(void *ptr1,void *ptr2) { } /* continue simulation */ - moldyn_add_schedule(moldyn,steps,tau); + moldyn_add_schedule(moldyn,steps,mdrun->timestep); return 0; } @@ -859,12 +1602,17 @@ int main(int argc,char **argv) { t_mdrun mdrun; t_moldyn moldyn; - t_3dvec o; + //t_3dvec o; /* clear structs */ memset(&mdrun,0,sizeof(t_mdrun)); memset(&moldyn,0,sizeof(t_moldyn)); + /* init crt variables */ + crtt=0; + constraints=NULL; + trafo_angle=NULL; + /* parse arguments */ if(mdrun_parse_argv(&mdrun,argc,argv)<0) return -1; @@ -939,26 +1687,33 @@ int main(int argc,char **argv) { /* initial lattice and dimensions */ set_dim(&moldyn,mdrun.dim.x,mdrun.dim.y,mdrun.dim.z,mdrun.vis); set_pbc(&moldyn,mdrun.pbcx,mdrun.pbcy,mdrun.pbcz); + /* replaced by fill stage !! switch(mdrun.lattice) { case FCC: - create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element1, - mdrun.m1,DEFAULT_ATOM_ATTR,0,mdrun.lx, - mdrun.ly,mdrun.lz,NULL); + create_lattice(&moldyn,FCC,mdrun.lc,mdrun.fill_element, + mdrun.m1,DEFAULT_ATOM_ATTR, + mdrun.fill_brand,mdrun.lx, + mdrun.ly,mdrun.lz,NULL,0,NULL); break; case DIAMOND: - create_lattice(&moldyn,DIAMOND,mdrun.lc,mdrun.element1, - mdrun.m1,DEFAULT_ATOM_ATTR,0,mdrun.lx, - mdrun.ly,mdrun.lz,NULL); + create_lattice(&moldyn,DIAMOND,mdrun.lc, + mdrun.fill_element, + mdrun.m1,DEFAULT_ATOM_ATTR, + mdrun.fill_brand,mdrun.lx, + mdrun.ly,mdrun.lz,NULL,0,NULL); break; case ZINCBLENDE: o.x=0.5*0.25*mdrun.lc; o.y=o.x; o.z=o.x; create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element1, mdrun.m1,DEFAULT_ATOM_ATTR,0,mdrun.lx, - mdrun.ly,mdrun.lz,&o); + mdrun.ly,mdrun.lz,&o,0,NULL); o.x+=0.25*mdrun.lc; o.y=o.x; o.z=o.x; create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element2, mdrun.m2,DEFAULT_ATOM_ATTR,1,mdrun.lx, - mdrun.ly,mdrun.lz,&o); + mdrun.ly,mdrun.lz,&o,0,NULL); + break; + case NONE: + set_nn_dist(&moldyn,mdrun.nnd); break; default: printf("%s unknown lattice type: %02x\n", @@ -966,11 +1721,14 @@ int main(int argc,char **argv) { return -1; } moldyn_bc_check(&moldyn); + replaced by fill stage !! */ /* temperature and pressure */ set_temperature(&moldyn,mdrun.temperature); set_pressure(&moldyn,mdrun.pressure); + /* replaced thermal_init stage thermal_init(&moldyn,TRUE); + */ addsched: /* first schedule */ diff --git a/mdrun.h b/mdrun.h index d065d57..b8ed70c 100644 --- a/mdrun.h +++ b/mdrun.h @@ -43,10 +43,18 @@ typedef struct s_stage { #define STAGE_DISPLACE_ATOM 0x00 #define STAGE_INSERT_ATOMS 0x01 -#define STAGE_CONTINUE 0x02 -#define STAGE_ANNEAL 0x03 -#define STAGE_CHAATTR 0x04 -#define STAGE_CHSATTR 0x05 +#define STAGE_INSERT_MIXED_ATOMS 0x02 +#define STAGE_CONTINUE 0x03 +#define STAGE_ANNEAL 0x04 +#define STAGE_CHAATTR 0x05 +#define STAGE_CHSATTR 0x06 +#define STAGE_SET_TEMP 0x07 +#define STAGE_SET_TIMESTEP 0x08 +#define STAGE_FILL 0x09 +#define STAGE_THERMAL_INIT 0x10 +#define STAGE_DEL_ATOMS 0x11 +#define STAGE_MODIFY_ATOMS 0x12 +#define STAGE_CRT 0x13 typedef struct s_mdrun { char cfile[128]; // config file @@ -66,13 +74,9 @@ typedef struct s_mdrun { u8 pbcz; int element1; // element 1 - double m1; int element2; // element 2 - double m2; + double lc; // lattice constant - int lx; // amount of lc units - int ly; - int lz; u8 lattice; // type of lattice u8 sattr; // system attributes @@ -107,6 +111,17 @@ typedef struct s_displace_atom_params { double dx,dy,dz; } t_displace_atom_params; +typedef struct s_del_atoms_params { + double r; + t_3dvec o; +} t_del_atoms_params; + +typedef struct s_modify_aoms_params { + u8 type; + int tag; + t_3dvec ekin; +} t_modify_atoms_params; + typedef struct s_insert_atoms_params { u8 type; double x0,y0,z0,x1,y1,z1; @@ -119,9 +134,24 @@ typedef struct s_insert_atoms_params { u8 attr; } t_insert_atoms_params; +typedef struct s_insert_mixed_atoms_params { + int element1; + int element2; + int amount1; + int amount2; + u8 brand1; + u8 brand2; + u8 attr1; + u8 attr2; + double crmin; + double crmax; +} t_insert_mixed_atoms_params; + #define INS_TOTAL 0x01 -#define INS_REGION 0x02 -#define INS_POS 0x03 +#define INS_RECT 0x02 +#define INS_SPHERE 0x03 +#define INS_POS 0x04 +#define INS_RELPOS 0x05 typedef struct s_continue_params { int runs; @@ -131,6 +161,7 @@ typedef struct s_anneal_params { int runs; int count; double dt; + int interval; } t_anneal_params; typedef struct s_chaattr_params { @@ -144,6 +175,7 @@ typedef struct s_chaattr_params { #define CHAATTR_TOTALV 0x01 #define CHAATTR_REGION 0x02 #define CHAATTR_ELEMENT 0x04 +#define CHAATTR_NUMBER 0x08 typedef struct s_chsattr_params { u8 type; @@ -162,9 +194,51 @@ typedef struct s_chsattr_params { #define CHSATTR_AVGRST 0x10 #define CHSATTR_RSTEPS 0x20 +typedef struct s_set_temp_params { + u8 type; + double val; +} t_set_temp_params; + +#define SET_TEMP_CURRENT 0x01 +#define SET_TEMP_VALUE 0x02 + +typedef struct s_set_timestep_params { + double tau; +} t_set_timestep_params; + +typedef struct s_fill_params { + double lc; // lattice constant + int lx; // amount of lc units + int ly; + int lz; + u8 lattice; + int fill_element; + u8 fill_brand; + t_part_params p_params; + t_defect_params d_params; + t_offset_params o_params; +} t_fill_params; + +typedef struct s_crt_params { + u8 type; + char file[128]; + t_3dvec *r_fin; + u8 *constraints; + int steps; + int count; +} t_crt_params; + /* - * function prototypes + * extern variables */ +// constraint relaxation technique +extern u8 crtt; +extern u8 *constraints; +extern double *trafo_angle; + +/* + * function prototypes + */ #endif diff --git a/moldyn.c b/moldyn.c index 010b8ed..1d6e0b7 100644 --- a/moldyn.c +++ b/moldyn.c @@ -17,6 +17,16 @@ #include #include +#include + +#ifdef PARALLEL +#include +#endif + +#if defined PTHREADS || defined VISUAL_THREAD +#include +#endif + #include "moldyn.h" #include "report/report.h" @@ -31,6 +41,26 @@ #include "potentials/tersoff.h" #endif +/* pse */ +#define PSE_MASS +#define PSE_NAME +#define PSE_COL +#include "pse.h" +#undef PSE_MASS +#undef PSE_NAME +#undef PSE_COL + +#ifdef PTHREADS +/* global mutexes */ +pthread_mutex_t *amutex; +pthread_mutex_t emutex; +#endif + +/* fully constrained relaxation technique - global pointers */ +u8 crtt; +u8 *constraints; +double *trafo_angle; + /* * the moldyn functions */ @@ -39,6 +69,9 @@ int moldyn_init(t_moldyn *moldyn,int argc,char **argv) { printf("[moldyn] init\n"); + /* only needed if compiled without -msse2 (float-store prob!) */ + //fpu_set_rtd(); + memset(moldyn,0,sizeof(t_moldyn)); moldyn->argc=argc; @@ -47,13 +80,28 @@ int moldyn_init(t_moldyn *moldyn,int argc,char **argv) { rand_init(&(moldyn->random),NULL,1); moldyn->random.status|=RAND_STAT_VERBOSE; +#ifdef PTHREADS + pthread_mutex_init(&emutex,NULL); +#endif + return 0; } int moldyn_shutdown(t_moldyn *moldyn) { +#ifdef PTHREADS + int i; +#endif + printf("[moldyn] shutdown\n"); +#ifdef PTHREADS + for(i=0;icount;i++) + pthread_mutex_destroy(&(amutex[i])); + free(amutex); + pthread_mutex_destroy(&emutex); +#endif + moldyn_log_shutdown(moldyn); link_cell_shutdown(moldyn); rand_close(&(moldyn->random)); @@ -216,11 +264,11 @@ int set_potential(t_moldyn *moldyn,u8 type) { switch(type) { case MOLDYN_POTENTIAL_TM: - moldyn->func_i0=tersoff_mult_1bp; - moldyn->func_j1=tersoff_mult_3bp_j1; - moldyn->func_j1_k0=tersoff_mult_3bp_k1; - moldyn->func_j1c=tersoff_mult_3bp_j2; - moldyn->func_j1_k1=tersoff_mult_3bp_k2; + //moldyn->func1b=tersoff_mult_1bp; + moldyn->func3b_j1=tersoff_mult_3bp_j1; + moldyn->func3b_k1=tersoff_mult_3bp_k1; + moldyn->func3b_j2=tersoff_mult_3bp_j2; + moldyn->func3b_k2=tersoff_mult_3bp_k2; moldyn->check_2b_bond=tersoff_mult_check_2b_bond; break; case MOLDYN_POTENTIAL_AO: @@ -482,8 +530,10 @@ int moldyn_log_shutdown(t_moldyn *moldyn) { * creating lattice functions */ -int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, - u8 attr,u8 brand,int a,int b,int c,t_3dvec *origin) { +int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element, + u8 attr,u8 brand,int a,int b,int c,t_3dvec *origin, + t_part_params *p_params,t_defect_params *d_params, + t_offset_params *o_params) { int new,count; int ret; @@ -491,15 +541,37 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, void *ptr; t_atom *atom; char name[16]; +#ifdef PTHREADS + pthread_mutex_t *mutex; +#endif new=a*b*c; count=moldyn->count; /* how many atoms do we expect */ + if(type==NONE) { + new*=1; + printf("[moldyn] WARNING: create 'none' lattice called"); + } if(type==CUBIC) new*=1; if(type==FCC) new*=4; if(type==DIAMOND) new*=8; + /* defects */ + if(d_params->type) { + switch(d_params->stype) { + case DEFECT_STYPE_DB_X: + case DEFECT_STYPE_DB_Y: + case DEFECT_STYPE_DB_Z: + case DEFECT_STYPE_DB_R: + new*=2; + break; + default: + printf("[moldyn] WARNING: cl unknown defect\n"); + break; + } + } + /* allocate space for atoms */ ptr=realloc(moldyn->atom,(count+new)*sizeof(t_atom)); if(!ptr) { @@ -509,6 +581,16 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, moldyn->atom=ptr; atom=&(moldyn->atom[count]); +#ifdef PTHREADS + ptr=realloc(amutex,(count+new)*sizeof(pthread_mutex_t)); + if(!ptr) { + perror("[moldyn] mutex realloc (add atom)"); + return -1; + } + amutex=ptr; + mutex=&(amutex[count]); +#endif + /* no atoms on the boundaries (only reason: it looks better!) */ if(!origin) { orig.x=0.5*lc; @@ -523,22 +605,28 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, switch(type) { case CUBIC: + if(o_params->use) + v3_add(&orig,&orig,&(o_params->o)); set_nn_dist(moldyn,lc); - ret=cubic_init(a,b,c,lc,atom,&orig); + ret=cubic_init(a,b,c,lc,atom,&orig,p_params,d_params); strcpy(name,"cubic"); break; case FCC: if(!origin) v3_scale(&orig,&orig,0.5); + if(o_params->use) + v3_add(&orig,&orig,&(o_params->o)); set_nn_dist(moldyn,0.5*sqrt(2.0)*lc); - ret=fcc_init(a,b,c,lc,atom,&orig); + ret=fcc_init(a,b,c,lc,atom,&orig,p_params,d_params); strcpy(name,"fcc"); break; case DIAMOND: if(!origin) v3_scale(&orig,&orig,0.25); + if(o_params->use) + v3_add(&orig,&orig,&(o_params->o)); set_nn_dist(moldyn,0.25*sqrt(3.0)*lc); - ret=diamond_init(a,b,c,lc,atom,&orig); + ret=diamond_init(a,b,c,lc,atom,&orig,p_params,d_params); strcpy(name,"diamond"); break; default: @@ -548,25 +636,62 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, /* debug */ if(ret!=new) { - printf("[moldyn] creating lattice failed\n"); + printf("[moldyn] creating %s lattice (lc=%f) incomplete\n", + name,lc); + printf(" (ignore for partial lattice creation)\n"); printf(" amount of atoms\n"); printf(" - expected: %d\n",new); printf(" - created: %d\n",ret); + } + + moldyn->count+=ret; + if(ret==new) + printf("[moldyn] created %s lattice with %d atoms\n",name,ret); + + for(new=0;newtype) { + 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;retlc.subcell->list,moldyn->count*sizeof(int)); + if(!ptr) { + perror("[moldyn] list realloc (create lattice)"); + return -1; } + moldyn->lc.subcell->list=ptr; +#endif /* update total system mass */ total_mass_calc(moldyn); @@ -574,7 +699,7 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, return ret; } -int add_atom(t_moldyn *moldyn,int element,double mass,u8 brand,u8 attr, +int add_atom(t_moldyn *moldyn,int element,u8 brand,u8 attr, t_3dvec *r,t_3dvec *v) { t_atom *atom; @@ -591,6 +716,25 @@ int add_atom(t_moldyn *moldyn,int element,double mass,u8 brand,u8 attr, } moldyn->atom=ptr; +#ifdef LOWMEM_LISTS + ptr=realloc(moldyn->lc.subcell->list,(count+1)*sizeof(int)); + if(!ptr) { + perror("[moldyn] list realloc (add atom)"); + return -1; + } + moldyn->lc.subcell->list=ptr; +#endif + +#ifdef PTHREADS + ptr=realloc(amutex,(count+1)*sizeof(pthread_mutex_t)); + if(!ptr) { + perror("[moldyn] mutex realloc (add atom)"); + return -1; + } + amutex=ptr; + pthread_mutex_init(&(amutex[count]),NULL); +#endif + atom=moldyn->atom; /* initialize new atom */ @@ -598,7 +742,7 @@ int add_atom(t_moldyn *moldyn,int element,double mass,u8 brand,u8 attr, atom[count].r=*r; atom[count].v=*v; atom[count].element=element; - atom[count].mass=mass; + atom[count].mass=pse_mass[element]; atom[count].brand=brand; atom[count].tag=count; atom[count].attr=attr; @@ -615,6 +759,9 @@ int del_atom(t_moldyn *moldyn,int tag) { t_atom *new,*old; int cnt; +#if defined LOWMEM_LISTS || defined PTHREADS + void *ptr; +#endif old=moldyn->atom; @@ -637,16 +784,81 @@ int del_atom(t_moldyn *moldyn,int tag) { free(old); +#ifdef LOWMEM_LISTS + ptr=realloc(moldyn->lc.subcell->list,moldyn->count*sizeof(int)); + if(!ptr) { + perror("[moldyn] list realloc (del atom)"); + return -1; + } + moldyn->lc.subcell->list=ptr; + // update lists + link_cell_update(moldyn); +#endif + +#ifdef PTHREADS + ptr=realloc(amutex,moldyn->count*sizeof(pthread_mutex_t)); + if(!ptr) { + perror("[moldyn] mutex realloc (add atom)"); + return -1; + } + amutex=ptr; + pthread_mutex_destroy(&(amutex[moldyn->count+1])); +#endif + + return 0; } +#define set_atom_positions(pos) \ + if(d_params->type) {\ + d_o.x=0; d_o.y=0; d_o.z=0;\ + d_d.x=0; d_d.y=0; d_d.z=0;\ + switch(d_params->stype) {\ + case DEFECT_STYPE_DB_X:\ + d_o.x=d_params->od;\ + d_d.x=d_params->dd;\ + break;\ + case DEFECT_STYPE_DB_Y:\ + d_o.y=d_params->od;\ + d_d.y=d_params->dd;\ + break;\ + case DEFECT_STYPE_DB_Z:\ + d_o.z=d_params->od;\ + d_d.z=d_params->dd;\ + break;\ + case DEFECT_STYPE_DB_R:\ + break;\ + default:\ + printf("[moldyn] WARNING: unknown defect\n");\ + break;\ + }\ + v3_add(&dr,&pos,&d_o);\ + v3_copy(&(atom[count].r),&dr);\ + count+=1;\ + v3_add(&dr,&pos,&d_d);\ + v3_copy(&(atom[count].r),&dr);\ + count+=1;\ + }\ + else {\ + v3_copy(&(atom[count].r),&pos);\ + count+=1;\ + } + /* cubic init */ -int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { +int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin, + t_part_params *p_params,t_defect_params *d_params) { int count; t_3dvec r; int i,j,k; t_3dvec o; + t_3dvec dist; + t_3dvec p; + t_3dvec d_o; + t_3dvec d_d; + t_3dvec dr; + + p.x=0; p.y=0; p.z=0; count=0; if(origin) @@ -654,14 +866,54 @@ int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { else v3_zero(&o); + /* shift partition values */ + if(p_params->type) { + p.x=p_params->p.x+(a*lc)/2.0; + p.y=p_params->p.y+(b*lc)/2.0; + p.z=p_params->p.z+(c*lc)/2.0; + } + r.x=o.x; for(i=0;itype) { + 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)d.x)&& + (fabs(dist.y)d.y)&& + (fabs(dist.z)d.z)) { + set_atom_positions(r); + } + break; + case PART_OUTSIDE_D: + v3_sub(&dist,&r,&p); + if((fabs(dist.x)>=p_params->d.x)|| + (fabs(dist.y)>=p_params->d.y)|| + (fabs(dist.z)>=p_params->d.z)) { + set_atom_positions(r); + } + break; + default: + set_atom_positions(r); + break; + } r.z+=lc; } r.y+=lc; @@ -679,12 +931,18 @@ int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { } /* fcc lattice init */ -int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { +int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin, + t_part_params *p_params,t_defect_params *d_params) { int count; int i,j,k,l; t_3dvec o,r,n; t_3dvec basis[3]; + t_3dvec dist; + t_3dvec p; + t_3dvec d_d,d_o,dr; + + p.x=0; p.y=0; p.z=0; count=0; if(origin) @@ -701,6 +959,13 @@ int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { basis[2].y=0.5*lc; basis[2].z=0.5*lc; + /* shift partition values */ + if(p_params->type) { + p.x=p_params->p.x+(a*lc)/2.0; + p.y=p_params->p.y+(b*lc)/2.0; + p.z=p_params->p.z+(c*lc)/2.0; + } + /* fill up the room */ r.x=o.x; for(i=0;itype) { + 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)d.x)&& + (fabs(dist.y)d.y)&& + (fabs(dist.z)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)d.x)&& + (fabs(dist.y)d.y)&& + (fabs(dist.z)d.z)) { + set_atom_positions(n); + } + break; + case PART_OUTSIDE_D: + v3_sub(&dist,&n,&p); + if((fabs(dist.x)>=p_params->d.x)|| + (fabs(dist.y)>=p_params->d.y)|| + (fabs(dist.z)>=p_params->d.z)) { + set_atom_positions(n); + } + break; + default: + set_atom_positions(n); + break; + } } + r.z+=lc; } r.y+=lc; } @@ -734,12 +1065,13 @@ int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { return count; } -int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { +int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin, + t_part_params *p_params,t_defect_params *d_params) { int count; t_3dvec o; - count=fcc_init(a,b,c,lc,atom,origin); + count=fcc_init(a,b,c,lc,atom,origin,p_params,d_params); o.x=0.25*lc; o.y=0.25*lc; @@ -747,7 +1079,7 @@ int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { if(origin) v3_add(&o,&o,origin); - count+=fcc_init(a,b,c,lc,&atom[count],&o); + count+=fcc_init(a,b,c,lc,&atom[count],&o,p_params,d_params); return count; } @@ -825,7 +1157,9 @@ double temperature_calc(t_moldyn *moldyn) { /* assume up to date kinetic energy, which is 3/2 N k_B T */ - moldyn->t=(2.0*moldyn->ekin)/(3.0*K_BOLTZMANN*moldyn->count); + if(moldyn->count) + moldyn->t=(2.0*moldyn->ekin)/(3.0*K_BOLTZMANN*moldyn->count); + else moldyn->t=0.0; return moldyn->t; } @@ -879,7 +1213,7 @@ int scale_velocity(t_moldyn *moldyn,u8 equi_init) { scale*=2.0; else if(moldyn->pt_scale&T_SCALE_BERENDSEN) - scale=1.0+(scale-1.0)/moldyn->t_tc; + scale=1.0+(scale-1.0)*moldyn->tau/moldyn->t_tc; scale=sqrt(scale); /* velocity scaling */ @@ -925,8 +1259,8 @@ double virial_sum(t_moldyn *moldyn) { } /* global virial (absolute coordinates) */ - virial=&(moldyn->gvir); - moldyn->gv=virial->xx+virial->yy+virial->zz; + //virial=&(moldyn->gvir); + //moldyn->gv=virial->xx+virial->yy+virial->zz; return moldyn->virial; } @@ -947,9 +1281,16 @@ double pressure_calc(t_moldyn *moldyn) { moldyn->p=2.0*moldyn->ekin+moldyn->virial; moldyn->p/=(3.0*moldyn->volume); + //moldyn->px=2.0*moldyn->ekinx+moldyn->vir.xx; + //moldyn->px/=moldyn->volume; + //moldyn->py=2.0*moldyn->ekiny+moldyn->vir.yy; + //moldyn->py/=moldyn->volume; + //moldyn->pz=2.0*moldyn->ekinz+moldyn->vir.zz; + //moldyn->pz/=moldyn->volume; + /* pressure (absolute coordinates) */ - moldyn->gp=2.0*moldyn->ekin+moldyn->gv; - moldyn->gp/=(3.0*moldyn->volume); + //moldyn->gp=2.0*moldyn->ekin+moldyn->gv; + //moldyn->gp/=(3.0*moldyn->volume); return moldyn->p; } @@ -974,11 +1315,11 @@ int average_reset(t_moldyn *moldyn) { /* virial */ moldyn->virial_sum=0.0; - moldyn->gv_sum=0.0; + //moldyn->gv_sum=0.0; /* pressure */ moldyn->p_sum=0.0; - moldyn->gp_sum=0.0; + //moldyn->gp_sum=0.0; moldyn->tp_sum=0.0; return 0; @@ -1016,14 +1357,14 @@ int average_and_fluctuation_calc(t_moldyn *moldyn) { /* virial */ moldyn->virial_sum+=moldyn->virial; moldyn->virial_avg=moldyn->virial_sum/denom; - moldyn->gv_sum+=moldyn->gv; - moldyn->gv_avg=moldyn->gv_sum/denom; + //moldyn->gv_sum+=moldyn->gv; + //moldyn->gv_avg=moldyn->gv_sum/denom; /* pressure */ moldyn->p_sum+=moldyn->p; moldyn->p_avg=moldyn->p_sum/denom; - moldyn->gp_sum+=moldyn->gp; - moldyn->gp_avg=moldyn->gp_sum/denom; + //moldyn->gp_sum+=moldyn->gp; + //moldyn->gp_avg=moldyn->gp_sum/denom; moldyn->tp_sum+=moldyn->tp; moldyn->tp_avg=moldyn->tp_sum/denom; @@ -1177,11 +1518,40 @@ int scale_atoms(t_moldyn *moldyn,u8 dir,double scale,u8 x,u8 y,u8 z) { return 0; } +int scale_atoms_ind(t_moldyn *moldyn,double x,double y,double z) { + + int i; + t_3dvec *r; + + for(i=0;icount;i++) { + r=&(moldyn->atom[i].r); + r->x*=x; + r->y*=y; + r->z*=z; + } + + return 0; +} + +int scale_dim_ind(t_moldyn *moldyn,double x,double y,double z) { + + t_3dvec *dim; + + dim=&(moldyn->dim); + + dim->x*=x; + dim->y*=y; + dim->z*=z; + + return 0; +} + int scale_volume(t_moldyn *moldyn) { t_3dvec *dim,*vdim; double scale; t_linkcell *lc; + //double sx,sy,sz; vdim=&(moldyn->vis.dim); dim=&(moldyn->dim); @@ -1189,16 +1559,28 @@ int scale_volume(t_moldyn *moldyn) { /* scaling factor */ if(moldyn->pt_scale&P_SCALE_BERENDSEN) { - scale=1.0-(moldyn->p_ref-moldyn->p)*moldyn->p_tc; + scale=1.0-(moldyn->p_ref-moldyn->p)*moldyn->p_tc*moldyn->tau; scale=pow(scale,ONE_THIRD); } else { scale=pow(moldyn->p/moldyn->p_ref,ONE_THIRD); } + + /* + sx=1.0-(moldyn->p_ref-moldyn->px)*moldyn->p_tc*moldyn->tau; + sy=1.0-(moldyn->p_ref-moldyn->py)*moldyn->p_tc*moldyn->tau; + sz=1.0-(moldyn->p_ref-moldyn->pz)*moldyn->p_tc*moldyn->tau; + sx=pow(sx,ONE_THIRD); + sy=pow(sy,ONE_THIRD); + sz=pow(sz,ONE_THIRD); + */ + /* scale the atoms and dimensions */ scale_atoms(moldyn,SCALE_DIRECT,scale,TRUE,TRUE,TRUE); scale_dim(moldyn,SCALE_DIRECT,scale,TRUE,TRUE,TRUE); + //scale_atoms_ind(moldyn,sx,sy,sz); + //scale_dim_ind(moldyn,sx,sy,sz); /* visualize dimensions */ if(vdim->x!=0) { @@ -1220,6 +1602,9 @@ int scale_volume(t_moldyn *moldyn) { lc->x*=scale; lc->y*=scale; lc->z*=scale; + //lc->x*=sx; + //lc->y*=sx; + //lc->z*=sy; } return 0; @@ -1233,10 +1618,16 @@ double e_kin_calc(t_moldyn *moldyn) { atom=moldyn->atom; moldyn->ekin=0.0; + //moldyn->ekinx=0.0; + //moldyn->ekiny=0.0; + //moldyn->ekinz=0.0; for(i=0;icount;i++) { atom[i].ekin=0.5*atom[i].mass*v3_absolute_square(&(atom[i].v)); moldyn->ekin+=atom[i].ekin; + //moldyn->ekinx+=0.5*atom[i].mass*atom[i].v.x*atom[i].v.x; + //moldyn->ekiny+=0.5*atom[i].mass*atom[i].v.y*atom[i].v.y; + //moldyn->ekinz+=0.5*atom[i].mass*atom[i].v.z*atom[i].v.z; } return moldyn->ekin; @@ -1284,7 +1675,9 @@ double estimate_time_step(t_moldyn *moldyn,double nn_dist) { int link_cell_init(t_moldyn *moldyn,u8 vol) { t_linkcell *lc; +#ifndef LOWMEM_LISTS int i; +#endif lc=&(moldyn->lc); @@ -1299,6 +1692,8 @@ int link_cell_init(t_moldyn *moldyn,u8 vol) { #ifdef STATIC_LISTS lc->subcell=malloc(lc->cells*sizeof(int*)); +#elif LOWMEM_LISTS + lc->subcell=malloc(sizeof(t_lowmem_list)); #else lc->subcell=malloc(lc->cells*sizeof(t_list)); #endif @@ -1309,12 +1704,16 @@ int link_cell_init(t_moldyn *moldyn,u8 vol) { } if(lc->cells<27) - printf("[moldyn] FATAL: less then 27 subcells!\n"); + printf("[moldyn] FATAL: less then 27 subcells! (%d)\n", + lc->cells); if(vol) { #ifdef STATIC_LISTS printf("[moldyn] initializing 'static' linked cells (%d)\n", lc->cells); +#elif LOWMEM_LISTS + printf("[moldyn] initializing 'lowmem' linked cells (%d)\n", + lc->cells); #else printf("[moldyn] initializing 'dynamic' linked cells (%d)\n", lc->cells); @@ -1338,6 +1737,17 @@ int link_cell_init(t_moldyn *moldyn,u8 vol) { i,lc->subcell[0],lc->subcell); */ } +#elif LOWMEM_LISTS + lc->subcell->head=malloc(lc->cells*sizeof(int)); + if(lc->subcell->head==NULL) { + perror("[moldyn] head init (malloc)"); + return -1; + } + lc->subcell->list=malloc(moldyn->count*sizeof(int)); + if(lc->subcell->list==NULL) { + perror("[moldyn] list init (malloc)"); + return -1; + } #else for(i=0;icells;i++) list_init_f(&(lc->subcell[i])); @@ -1352,22 +1762,26 @@ int link_cell_init(t_moldyn *moldyn,u8 vol) { int link_cell_update(t_moldyn *moldyn) { int count,i,j,k; - int nx,ny; + int nx,nxy; t_atom *atom; t_linkcell *lc; #ifdef STATIC_LISTS int p; +#elif LOWMEM_LISTS + int p; #endif atom=moldyn->atom; lc=&(moldyn->lc); nx=lc->nx; - ny=lc->ny; + nxy=nx*lc->ny; for(i=0;icells;i++) #ifdef STATIC_LISTS - memset(lc->subcell[i],0,(MAX_ATOMS_PER_LIST+1)*sizeof(int)); + memset(lc->subcell[i],-1,(MAX_ATOMS_PER_LIST+1)*sizeof(int)); +#elif LOWMEM_LISTS + lc->subcell->head[i]=-1; #else list_destroy_f(&(lc->subcell[i])); #endif @@ -1379,7 +1793,7 @@ int link_cell_update(t_moldyn *moldyn) { #ifdef STATIC_LISTS p=0; - while(lc->subcell[i+j*nx+k*nx*ny][p]!=0) + while(lc->subcell[i+j*nx+k*nxy][p]!=-1) p++; if(p>=MAX_ATOMS_PER_LIST) { @@ -1387,9 +1801,13 @@ int link_cell_update(t_moldyn *moldyn) { return -1; } - lc->subcell[i+j*nx+k*nx*ny][p]=count; + lc->subcell[i+j*nx+k*nxy][p]=count; +#elif LOWMEM_LISTS + p=i+j*nx+k*nxy; + lc->subcell->list[count]=lc->subcell->head[p]; + lc->subcell->head[p]=count; #else - list_add_immediate_f(&(lc->subcell[i+j*nx+k*nx*ny]), + list_add_immediate_f(&(lc->subcell[i+j*nx+k*nxy]), &(atom[count])); /* if(j==0&&k==0) @@ -1405,6 +1823,8 @@ int link_cell_update(t_moldyn *moldyn) { int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k, #ifdef STATIC_LISTS int **cell +#elif LOWMEM_LISTS + int *cell #else t_list *cell #endif @@ -1430,7 +1850,11 @@ int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k, printf("[moldyn] WARNING: lcni %d/%d %d/%d %d/%d\n", i,nx,j,ny,k,nz); +#ifndef LOWMEM_LISTS cell[0]=lc->subcell[i+j*nx+k*a]; +#else + cell[0]=lc->subcell->head[i+j*nx+k*a]; +#endif for(ci=-1;ci<=1;ci++) { bx=0; x=i+ci; @@ -1454,10 +1878,19 @@ int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k, } if(!(ci|cj|ck)) continue; if(bx|by|bz) { +#ifndef LOWMEM_LISTS cell[--count2]=lc->subcell[x+y*nx+z*a]; +#else + cell[--count2]=lc->subcell->head[x+y*nx+z*a]; +#endif + } else { +#ifndef LOWMEM_LISTS cell[count1++]=lc->subcell[x+y*nx+z*a]; +#else + cell[count1++]=lc->subcell->head[x+y*nx+z*a]; +#endif } } } @@ -1470,11 +1903,19 @@ int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k, int link_cell_shutdown(t_moldyn *moldyn) { +#ifndef LOWMEM_LISTS int i; +#endif t_linkcell *lc; lc=&(moldyn->lc); +#if LOWMEM_LISTS + free(lc->subcell->head); + free(lc->subcell->list); + +#else + for(i=0;icells;i++) { #ifdef STATIC_LISTS free(lc->subcell[i]); @@ -1483,6 +1924,7 @@ int link_cell_shutdown(t_moldyn *moldyn) { list_destroy_f(&(lc->subcell[i])); #endif } +#endif free(lc->subcell); @@ -1551,6 +1993,17 @@ int moldyn_integrate(t_moldyn *moldyn) { struct timeval t1,t2; //double tp; +#ifdef VISUAL_THREAD + u8 first,change; + pthread_t io_thread; + int ret; + t_moldyn md_copy; + t_atom *atom_copy; + + first=1; + change=0; +#endif + sched=&(moldyn->schedule); atom=moldyn->atom; @@ -1585,9 +2038,11 @@ int moldyn_integrate(t_moldyn *moldyn) { printf("[moldyn] WARNING: cutoff > 0.5 x dim.y\n"); if(moldyn->cutoff>0.5*moldyn->dim.z) printf("[moldyn] WARNING: cutoff > 0.5 x dim.z\n"); - ds=0.5*atom[0].f.x*moldyn->tau_square/atom[0].mass; - if(ds>0.05*moldyn->nnd) + if(moldyn->count) { + ds=0.5*atom[0].f.x*moldyn->tau_square/atom[0].mass; + if(ds>0.05*moldyn->nnd) printf("[moldyn] WARNING: forces too high / tau too small!\n"); + } /* zero absolute time */ // should have right values! @@ -1597,6 +2052,21 @@ int moldyn_integrate(t_moldyn *moldyn) { /* debugging, ignore */ moldyn->debug=0; + /* zero & init moldyn copy */ +#ifdef VISUAL_THREAD + memset(&md_copy,0,sizeof(t_moldyn)); + atom_copy=malloc(moldyn->count*sizeof(t_atom)); + if(atom_copy==NULL) { + perror("[moldyn] malloc atom copy (init)"); + return -1; + } +#endif + +#ifdef PTHREADS + printf("##################\n"); + printf("# USING PTHREADS #\n"); + printf("##################\n"); +#endif /* tell the world */ printf("[moldyn] integration start, go get a coffee ...\n"); @@ -1624,11 +2094,11 @@ int moldyn_integrate(t_moldyn *moldyn) { temperature_calc(moldyn); virial_sum(moldyn); pressure_calc(moldyn); - /* +#ifdef PDEBUG thermodynamic_pressure_calc(moldyn); printf("\n\nDEBUG: numeric pressure calc: %f\n\n", moldyn->tp/BAR); - */ +#endif /* calculate fluctuations + averages */ average_and_fluctuation_calc(moldyn); @@ -1643,10 +2113,11 @@ int moldyn_integrate(t_moldyn *moldyn) { if(e) { if(!(moldyn->total_steps%e)) dprintf(moldyn->efd, - "%f %f %f %f\n", + "%f %f %f %f %f %f\n", moldyn->time,moldyn->ekin/energy_scale, moldyn->energy/energy_scale, - get_total_energy(moldyn)/energy_scale); + get_total_energy(moldyn)/energy_scale, + moldyn->ekin/EV,moldyn->energy/EV); } if(m) { if(!(moldyn->total_steps%m)) { @@ -1662,7 +2133,7 @@ int moldyn_integrate(t_moldyn *moldyn) { dprintf(moldyn->pfd, "%f %f %f %f %f %f %f\n",moldyn->time, moldyn->p/BAR,moldyn->p_avg/BAR, - moldyn->gp/BAR,moldyn->gp_avg/BAR, + moldyn->p/BAR,moldyn->p_avg/BAR, moldyn->tp/BAR,moldyn->tp_avg/BAR); } } @@ -1676,12 +2147,16 @@ int moldyn_integrate(t_moldyn *moldyn) { if(v) { if(!(moldyn->total_steps%v)) { dprintf(moldyn->vfd, - "%f %f\n",moldyn->time,moldyn->volume); + "%f %f %f %f %f\n",moldyn->time, + moldyn->volume, + moldyn->dim.x, + moldyn->dim.y, + moldyn->dim.z); } } if(s) { if(!(moldyn->total_steps%s)) { - snprintf(dir,128,"%s/s-%07.f.save", + snprintf(dir,128,"%s/s-%08.f.save", moldyn->vlsdir,moldyn->time); fd=open(dir,O_WRONLY|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR); @@ -1696,20 +2171,54 @@ int moldyn_integrate(t_moldyn *moldyn) { } if(a) { if(!(moldyn->total_steps%a)) { +#ifdef VISUAL_THREAD + /* check whether thread has not terminated yet */ + if(!first) { + ret=pthread_join(io_thread,NULL); + } + first=0; + /* prepare and start thread */ + if(moldyn->count!=md_copy.count) { + free(atom_copy); + change=1; + } + memcpy(&md_copy,moldyn,sizeof(t_moldyn)); + if(change) { + atom_copy=malloc(moldyn->count*sizeof(t_atom)); + if(atom_copy==NULL) { + perror("[moldyn] malloc atom copy (change)"); + return -1; + } + } + md_copy.atom=atom_copy; + memcpy(atom_copy,moldyn->atom,moldyn->count*sizeof(t_atom)); + change=0; + ret=pthread_create(&io_thread,NULL,visual_atoms,&md_copy); + if(ret) { + perror("[moldyn] create visual atoms thread\n"); + return -1; + } +#else visual_atoms(moldyn); +#endif } } /* display progress */ - //if(!(moldyn->total_steps%10)) { +#ifndef PDEBUG + if(!(i%10)) { +#endif /* get current time */ gettimeofday(&t2,NULL); -printf("\rsched:%d, steps:%d/%d, T:%4.1f/%4.1f P:%4.1f/%4.1f V:%6.1f (%d)", +printf("sched:%d, steps:%d/%d, T:%4.1f/%4.1f P:%4.1f/%4.1f V:%6.1f (%d)\n", sched->count,i,moldyn->total_steps, moldyn->t,moldyn->t_avg, +#ifndef PDEBUG moldyn->p/BAR,moldyn->p_avg/BAR, - //moldyn->p/BAR,(moldyn->p-2.0*moldyn->ekin/(3.0*moldyn->volume))/BAR, +#else + moldyn->p/BAR,(moldyn->p-2.0*moldyn->ekin/(3.0*moldyn->volume))/BAR, +#endif moldyn->volume, (int)(t2.tv_sec-t1.tv_sec)); @@ -1717,7 +2226,9 @@ printf("\rsched:%d, steps:%d/%d, T:%4.1f/%4.1f P:%4.1f/%4.1f V:%6.1f (%d)", /* copy over time */ t1=t2; - //} +#ifndef PDEBUG + } +#endif /* increase absolute time */ moldyn->time+=moldyn->tau; @@ -1738,6 +2249,59 @@ printf("\rsched:%d, steps:%d/%d, T:%4.1f/%4.1f P:%4.1f/%4.1f V:%6.1f (%d)", } + /* writing a final save file! */ + if(s) { + snprintf(dir,128,"%s/s-final.save",moldyn->vlsdir); + fd=open(dir,O_WRONLY|O_TRUNC|O_CREAT,S_IRUSR|S_IWUSR); + if(fd<0) perror("[moldyn] save fd open"); + else { + write(fd,moldyn,sizeof(t_moldyn)); + write(fd,moldyn->atom, + moldyn->count*sizeof(t_atom)); + } + close(fd); + } + /* writing a final visual file! */ + if(a) + visual_atoms(moldyn); + + return 0; +} + +/* basis trafo */ + +#define FORWARD 0 +#define BACKWARD 1 + +int basis_trafo(t_3dvec *r,u8 dir,double z,double x) { + + t_3dvec tmp; + + if(dir==FORWARD) { + if(z!=0.0) { + v3_copy(&tmp,r); + r->x=cos(z)*tmp.x-sin(z)*tmp.y; + r->y=sin(z)*tmp.x+cos(z)*tmp.y; + } + if(x!=0.0) { + v3_copy(&tmp,r); + r->y=cos(x)*tmp.y-sin(x)*tmp.z; + r->z=sin(x)*tmp.y+cos(x)*tmp.z; + } + } + else { + if(x!=0.0) { + v3_copy(&tmp,r); + r->y=cos(-x)*tmp.y-sin(-x)*tmp.z; + r->z=sin(-x)*tmp.y+cos(-x)*tmp.z; + } + if(z!=0.0) { + v3_copy(&tmp,r); + r->x=cos(-z)*tmp.x-sin(-z)*tmp.y; + r->y=sin(-z)*tmp.x+cos(-z)*tmp.y; + } + } + return 0; } @@ -1756,15 +2320,47 @@ int velocity_verlet(t_moldyn *moldyn) { tau_square=moldyn->tau_square; for(i=0;ifunc3b_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;igvir),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;isubcell->list[p]; #else this=&(neighbour_i[j]); list_reset_f(this); @@ -1972,22 +2617,10 @@ int potential_force_calc(t_moldyn *moldyn) { bc_ik|bc_ij); #ifdef STATIC_LISTS } -#else - } while(list_next_f(that)!=\ - L_NO_NEXT_ELEMENT); -#endif - - } - - /* finish of first j loop after first k loop */ - if(moldyn->func_j0e) - moldyn->func_j0e(moldyn, - &(itom[i]), - jtom, - bc_ij); - #ifdef STATIC_LISTS } +#elif LOWMEM_LISTS + } #else } while(list_next_f(this)!=L_NO_NEXT_ELEMENT); #endif @@ -2000,6 +2633,15 @@ int potential_force_calc(t_moldyn *moldyn) { if(!(itom[i].attr&ATOM_ATTR_3BP)) continue; + /* copy the neighbour lists */ +#ifdef STATIC_LISTS + /* no copy needed for static lists */ +#elif LOWMEM_LISTS + /* no copy needed for lowmem lists */ +#else + memcpy(neighbour_i2,neighbour_i,27*sizeof(t_list)); +#endif + /* second loop over atoms j */ for(j=0;j<27;j++) { @@ -2007,10 +2649,17 @@ int potential_force_calc(t_moldyn *moldyn) { #ifdef STATIC_LISTS p=0; - while(neighbour_i[j][p]!=0) { + while(neighbour_i[j][p]!=-1) { jtom=&(atom[neighbour_i[j][p]]); p++; +#elif LOWMEM_LISTS + p=neighbour_i[j]; + + while(p!=-1) { + + jtom=&(itom[p]); + p=lc->subcell->list[p]; #else this=&(neighbour_i[j]); list_reset_f(this); @@ -2051,10 +2700,17 @@ int potential_force_calc(t_moldyn *moldyn) { #ifdef STATIC_LISTS q=0; - while(neighbour_i[j][q]!=0) { + while(neighbour_i[k][q]!=-1) { ktom=&(atom[neighbour_i[k][q]]); q++; +#elif LOWMEM_LISTS + q=neighbour_i[k]; + + while(q!=-1) { + + ktom=&(itom[q]); + q=lc->subcell->list[q]; #else that=&(neighbour_i2[k]); list_reset_f(that); @@ -2075,13 +2731,16 @@ int potential_force_calc(t_moldyn *moldyn) { if(ktom==&(itom[i])) continue; - moldyn->func_j1_k0(moldyn, - &(itom[i]), - jtom, - ktom, - bc_ik|bc_ij); + moldyn->func3b_k1(moldyn, + &(itom[i]), + jtom, + ktom, + bc_ik|bc_ij); + #ifdef STATIC_LISTS } +#elif LOWMEM_LISTS + } #else } while(list_next_f(that)!=\ L_NO_NEXT_ELEMENT); @@ -2107,10 +2766,17 @@ int potential_force_calc(t_moldyn *moldyn) { #ifdef STATIC_LISTS q=0; - while(neighbour_i[j][q]!=0) { + while(neighbour_i[k][q]!=-1) { ktom=&(atom[neighbour_i[k][q]]); q++; +#elif LOWMEM_LISTS + q=neighbour_i[k]; + + while(q!=-1) { + + ktom=&(itom[q]); + q=lc->subcell->list[q]; #else that=&(neighbour_i2[k]); list_reset_f(that); @@ -2139,6 +2805,8 @@ int potential_force_calc(t_moldyn *moldyn) { #ifdef STATIC_LISTS } +#elif LOWMEM_LISTS + } #else } while(list_next_f(that)!=\ L_NO_NEXT_ELEMENT); @@ -2156,6 +2824,8 @@ int potential_force_calc(t_moldyn *moldyn) { } #ifdef STATIC_LISTS } +#elif LOWMEM_LISTS + } #else } while(list_next_f(this)!=L_NO_NEXT_ELEMENT); #endif @@ -2182,6 +2852,9 @@ int potential_force_calc(t_moldyn *moldyn) { #endif /* some postprocessing */ +#ifdef PARALLEL + #pragma omp parallel for +#endif for(i=0;igvir.xx+=itom[i].r.x*itom[i].f.x; @@ -2193,7 +2866,7 @@ int potential_force_calc(t_moldyn *moldyn) { /* check forces regarding the given timestep */ if(v3_norm(&(itom[i].f))>\ - 0.1*moldyn->nnd*itom[i].mass/moldyn->tau_square) + 0.1*moldyn->nnd*itom[i].mass/moldyn->tau_square) printf("[moldyn] WARNING: pfc (high force: atom %d)\n", i); } @@ -2250,6 +2923,51 @@ int check_per_bound(t_moldyn *moldyn,t_3dvec *a) { return 0; } +int check_per_bound_and_care_for_pbc(t_moldyn *moldyn,t_atom *a) { + + double x,y,z; + t_3dvec *dim; + + dim=&(moldyn->dim); + + x=dim->x/2; + y=dim->y/2; + z=dim->z/2; + + if(moldyn->status&MOLDYN_STAT_PBX) { + if(a->r.x>=x) { + a->pbc[0]+=1; + a->r.x-=dim->x; + } + else if(-a->r.x>x) { + a->pbc[0]-=1; + a->r.x+=dim->x; + } + } + if(moldyn->status&MOLDYN_STAT_PBY) { + if(a->r.y>=y) { + a->pbc[1]+=1; + a->r.y-=dim->y; + } + else if(-a->r.y>y) { + a->pbc[1]-=1; + a->r.y+=dim->y; + } + } + if(moldyn->status&MOLDYN_STAT_PBZ) { + if(a->r.z>=z) { + a->pbc[2]+=1; + a->r.z-=dim->z; + } + else if(-a->r.z>z) { + a->pbc[2]-=1; + a->r.z+=dim->z; + } + } + + return 0; +} + /* * debugging / critical check functions */ @@ -2340,7 +3058,7 @@ int moldyn_read_save_file(t_moldyn *moldyn,char *file) { if(fsize!=sizeof(t_moldyn)+size) { corr=fsize-sizeof(t_moldyn)-size; printf("[moldyn] WARNING: lsf (illegal file size)\n"); - printf(" moifying offset:\n"); + printf(" modifying offset:\n"); printf(" - current pos: %d\n",sizeof(t_moldyn)); printf(" - atom size: %d\n",size); printf(" - file size: %d\n",fsize); @@ -2363,6 +3081,16 @@ int moldyn_read_save_file(t_moldyn *moldyn,char *file) { size-=cnt; } +#ifdef PTHREADS + amutex=malloc(moldyn->count*sizeof(pthread_mutex_t)); + if(amutex==NULL) { + perror("[moldyn] load save file (mutexes)"); + return -1; + } + for(cnt=0;cntcount;cnt++) + pthread_mutex_init(&(amutex[cnt]),NULL); +#endif + // hooks etc ... return 0; @@ -2394,13 +3122,16 @@ int process_2b_bonds(t_moldyn *moldyn,void *data, #ifdef STATIC_LISTS int *neighbour[27]; int p; +#elif LOWMEM_LISTS + int neighbour[27]; + int p; #else t_list neighbour[27]; + t_list *this; #endif u8 bc; t_atom *itom,*jtom; int i,j; - t_list *this; lc=&(moldyn->lc); itom=moldyn->atom; @@ -2420,10 +3151,17 @@ int process_2b_bonds(t_moldyn *moldyn,void *data, #ifdef STATIC_LISTS p=0; - while(neighbour[j][p]!=0) { + while(neighbour[j][p]!=-1) { jtom=&(moldyn->atom[neighbour[j][p]]); p++; +#elif LOWMEM_LISTS + p=neighbour[j]; + + while(p!=-1) { + + jtom=&(itom[p]); + p=lc->subcell->list[p]; #else this=&(neighbour[j]); list_reset_f(this); @@ -2441,6 +3179,8 @@ int process_2b_bonds(t_moldyn *moldyn,void *data, #ifdef STATIC_LISTS } +#elif LOWMEM_LISTS + } #else } while(list_next_f(this)!=L_NO_NEXT_ELEMENT); #endif @@ -2451,6 +3191,84 @@ int process_2b_bonds(t_moldyn *moldyn,void *data, } +/* + * function to find neighboured atoms + */ + +int process_neighbours(t_moldyn *moldyn,void *data,t_atom *atom, + int (*process)(t_moldyn *moldyn,t_atom *atom,t_atom *natom, + void *data,u8 bc)) { + + t_linkcell *lc; +#ifdef STATIC_LISTS + int *neighbour[27]; + int p; +#elif LOWMEM_LISTS + int neighbour[27]; + int p; +#else + t_list neighbour[27]; + t_list *this; +#endif + u8 bc; + t_atom *natom; + int j; + + lc=&(moldyn->lc); + + /* neighbour indexing */ + link_cell_neighbour_index(moldyn, + (atom->r.x+moldyn->dim.x/2)/lc->x, + (atom->r.y+moldyn->dim.y/2)/lc->x, + (atom->r.z+moldyn->dim.z/2)/lc->x, + neighbour); + + for(j=0;j<27;j++) { + + bc=(jdnlc)?0:1; + +#ifdef STATIC_LISTS + p=0; + + while(neighbour[j][p]!=-1) { + + natom=&(moldyn->atom[neighbour[j][p]]); + p++; +#elif LOWMEM_LISTS + p=neighbour[j]; + + while(p!=-1) { + + natom=&(moldyn->atom[p]); + p=lc->subcell->list[p]; +#else + this=&(neighbour[j]); + list_reset_f(this); + + if(this->start==NULL) + continue; + + do { + + natom=this->current->data; +#endif + + /* process bond */ + process(moldyn,atom,natom,data,bc); + +#ifdef STATIC_LISTS + } +#elif LOWMEM_LISTS + } +#else + } while(list_next_f(this)!=L_NO_NEXT_ELEMENT); +#endif + } + + return 0; + +} + /* * post processing functions */ @@ -2485,6 +3303,7 @@ int calculate_diffusion_coefficient(t_moldyn *moldyn,double *dc) { int i; t_atom *atom; t_3dvec dist; + t_3dvec final_r; double d2; int a_cnt; int b_cnt; @@ -2498,8 +3317,12 @@ int calculate_diffusion_coefficient(t_moldyn *moldyn,double *dc) { for(i=0;icount;i++) { - v3_sub(&dist,&(atom[i].r),&(atom[i].r_0)); - check_per_bound(moldyn,&dist); + /* care for pb crossing */ + final_r.x=atom[i].r.x+atom[i].pbc[0]*moldyn->dim.x; + final_r.y=atom[i].r.y+atom[i].pbc[1]*moldyn->dim.y; + final_r.z=atom[i].r.z+atom[i].pbc[2]*moldyn->dim.z; + /* calculate distance */ + v3_sub(&dist,&final_r,&(atom[i].r_0)); d2=v3_absolute_square(&dist); if(atom[i].brand) { @@ -2521,6 +3344,57 @@ int calculate_diffusion_coefficient(t_moldyn *moldyn,double *dc) { return 0; } +int calculate_msd(t_moldyn *moldyn,double *msd) { + + int i; + t_atom *atom; + t_3dvec dist; + t_3dvec final_r; + double d2; + int a_cnt; + int b_cnt; + + atom=moldyn->atom; + msd[0]=0; + msd[1]=0; + msd[2]=0; + a_cnt=0; + b_cnt=0; + + for(i=0;icount;i++) { + + /* care for pb crossing */ + if(atom[i].pbc[0]|atom[i].pbc[1]|atom[i].pbc[2]) { + printf("[moldyn] msd pb crossings for atom %d\n",i); + printf(" x: %d y: %d z: %d\n", + atom[i].pbc[0],atom[i].pbc[1],atom[i].pbc[2]); + } + final_r.x=atom[i].r.x+atom[i].pbc[0]*moldyn->dim.x; + final_r.y=atom[i].r.y+atom[i].pbc[1]*moldyn->dim.y; + final_r.z=atom[i].r.z+atom[i].pbc[2]*moldyn->dim.z; + /* calculate distance */ + v3_sub(&dist,&final_r,&(atom[i].r_0)); + d2=v3_absolute_square(&dist); + + if(atom[i].brand) { + b_cnt+=1; + msd[1]+=d2; + } + else { + a_cnt+=1; + msd[0]+=d2; + } + + msd[2]+=d2; + } + + msd[0]/=a_cnt; + msd[1]/=b_cnt; + msd[2]/=moldyn->count; + + return 0; +} + int bonding_analyze(t_moldyn *moldyn,double *cnt) { return 0; @@ -2666,9 +3540,8 @@ int bond_analyze_process(t_moldyn *moldyn,t_atom *itom,t_atom *jtom, ba=data; /* increase total bond counter - * ... double counting! */ - ba->tcnt+=2; + ba->tcnt+=1; if(itom->brand==0) ba->acnt[jtom->tag]+=1; @@ -2685,10 +3558,11 @@ int bond_analyze_process(t_moldyn *moldyn,t_atom *itom,t_atom *jtom, int bond_analyze(t_moldyn *moldyn,double *quality) { - // by now: # bonds of type 'a-4b' and 'b-4a' / # bonds total - - int qcnt; - int ccnt,cset; + int qcnt4; + int qcnt3; + int ccnt4; + int ccnt3; + int bcnt; t_ba ba; int i; t_atom *atom; @@ -2708,9 +3582,9 @@ int bond_analyze(t_moldyn *moldyn,double *quality) { memset(ba.bcnt,0,moldyn->count*sizeof(int)); ba.tcnt=0; - qcnt=0; - ccnt=0; - cset=0; + qcnt4=0; qcnt3=0; + ccnt4=0; ccnt3=0; + bcnt=0; atom=moldyn->atom; @@ -2719,27 +3593,30 @@ int bond_analyze(t_moldyn *moldyn,double *quality) { for(i=0;icount;i++) { if(atom[i].brand==0) { if((ba.acnt[i]==0)&(ba.bcnt[i]==4)) - qcnt+=4; + qcnt4+=4; + if((ba.acnt[i]==0)&(ba.bcnt[i]==3)) + qcnt3+=3; } else { if((ba.acnt[i]==4)&(ba.bcnt[i]==0)) { - qcnt+=4; - ccnt+=1; + qcnt4+=4; + ccnt4+=1; + } + if((ba.acnt[i]==3)&(ba.bcnt[i]==0)) { + qcnt3+=4; + ccnt3+=1; } - cset+=1; + bcnt+=1; } } - printf("[moldyn] bond analyze: c_cnt=%d | set=%d\n",ccnt,cset); - printf("[moldyn] bond analyze: q_cnt=%d | tot=%d\n",qcnt,ba.tcnt); - if(quality) { - quality[0]=1.0*ccnt/cset; - quality[1]=1.0*qcnt/ba.tcnt; + quality[0]=1.0*ccnt4/bcnt; + quality[1]=1.0*ccnt3/bcnt; } else { - printf("[moldyn] bond analyze: c_bnd_q=%f\n",1.0*qcnt/ba.tcnt); - printf("[moldyn] bond analyze: tot_q=%f\n",1.0*qcnt/ba.tcnt); + printf("[moldyn] bond analyze: %f %f\n", + 1.0*ccnt4/bcnt,1.0*ccnt3/bcnt); } return 0; @@ -2777,7 +3654,11 @@ int visual_bonds_process(t_moldyn *moldyn,t_atom *itom,t_atom *jtom, return 0; } +#ifdef VISUAL_THREAD +void *visual_atoms(void *ptr) { +#else int visual_atoms(t_moldyn *moldyn) { +#endif int i; char file[128+64]; @@ -2786,6 +3667,12 @@ int visual_atoms(t_moldyn *moldyn) { t_visual *v; t_atom *atom; t_vb vb; + t_3dvec strain; +#ifdef VISUAL_THREAD + t_moldyn *moldyn; + + moldyn=ptr; +#endif v=&(moldyn->vis); dim.x=v->dim.x; @@ -2795,31 +3682,39 @@ int visual_atoms(t_moldyn *moldyn) { help=(dim.x+dim.y); - sprintf(file,"%s/atomic_conf_%07.f.xyz",v->fb,moldyn->time); + sprintf(file,"%s/atomic_conf_%08.f.xyz",v->fb,moldyn->time); vb.fd=open(file,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR); if(vb.fd<0) { perror("open visual save file fd"); +#ifndef VISUAL_THREAD return -1; +#endif } /* write the actual data file */ // povray header - dprintf(vb.fd,"# [P] %d %07.f <%f,%f,%f>\n", + dprintf(vb.fd,"# [P] %d %08.f <%f,%f,%f>\n", moldyn->count,moldyn->time,help/40.0,help/40.0,-0.8*help); // atomic configuration - for(i=0;icount;i++) + for(i=0;icount;i++) { + v3_sub(&strain,&(atom[i].r),&(atom[i].r_0)); + check_per_bound(moldyn,&strain); // atom type, positions, color and kinetic energy dprintf(vb.fd,"%s %f %f %f %s %f\n",pse_name[atom[i].element], atom[i].r.x, atom[i].r.y, atom[i].r.z, pse_col[atom[i].element], - atom[i].ekin); + //atom[i].ekin); + sqrt(v3_absolute_square(&strain))); + } // bonds between atoms +#ifndef VISUAL_THREAD process_2b_bonds(moldyn,&vb,visual_bonds_process); +#endif // boundaries if(dim.x) { @@ -2865,6 +3760,32 @@ int visual_atoms(t_moldyn *moldyn) { close(vb.fd); +#ifdef VISUAL_THREAD + pthread_exit(NULL); + +} +#else + + return 0; +} +#endif + +/* + * fpu cntrol functions + */ + +// set rounding to double (eliminates -ffloat-store!) +int fpu_set_rtd(void) { + + fpu_control_t ctrl; + + _FPU_GETCW(ctrl); + + ctrl&=~_FPU_EXTENDED; + ctrl|=_FPU_DOUBLE; + + _FPU_SETCW(ctrl); + return 0; } diff --git a/moldyn.h b/moldyn.h index b2d6a34..0670f3d 100644 --- a/moldyn.h +++ b/moldyn.h @@ -45,6 +45,7 @@ typedef struct s_atom { u8 brand; /* brand id */ int tag; /* atom unique id (number of atom) */ u8 attr; /* attributes */ + int pbc[3]; /* pb crossing in x, y and z direction */ } t_atom; #define ATOM_ATTR_FP 0x01 /* fixed position (bulk material) */ @@ -58,6 +59,12 @@ typedef struct s_atom { #define DEFAULT_ATOM_ATTR 0x74 // 1,2,3 body interaction + visualize +/* special list structure for low mem approach */ +typedef struct s_lowmem_list { + int *head; + int *list; +} t_lowmem_list; + /* cell lists */ typedef struct s_linkcell { int nx,ny,nz; /* amount of cells in x, y and z direction */ @@ -66,6 +73,8 @@ typedef struct s_linkcell { double x,y,z; /* the actual cell lengthes */ #ifdef STATIC_LISTS int **subcell; /* pointer to the cell lists */ +#elif LOWMEM_LISTS + t_lowmem_list *subcell; /* low mem approach list */ #else t_list *subcell; /* pointer to the cell lists */ #endif @@ -132,14 +141,22 @@ typedef struct s_moldyn { double t_sum; /* sum over all t */ double t_avg; /* average value of t */ + /* for sale! */ t_virial gvir; /* global virial (absolute coordinates) */ - double gv; - double gv_sum; - double gv_avg; - - double gp; /* pressure computed from global virial */ - double gp_sum; /* sum over all gp */ - double gp_avg; /* average value of gp */ + //double gv; + //double gv_sum; + //double gv_avg; + double sale1; + double sale2; + double sale3; + + // gp stuff exchanged by kinetic energies + //double gp; /* pressure computed from global virial */ + //double gp_sum; /* sum over all gp */ + //double gp_avg; /* average value of gp */ + double ekinx; + double ekiny; + double ekinz; t_virial vir; /* actual virial */ double virial; @@ -245,6 +262,43 @@ typedef struct s_vb { int fd; } t_vb; +typedef struct s_part_params { + u8 type; + double r; + t_3dvec p; + t_3dvec d; +} t_part_params; + +#define PART_INSIDE_R 1 +#define PART_OUTSIDE_R 2 +#define PART_INSIDE_D 3 +#define PART_OUTSIDE_D 4 + +typedef struct s_defect_params { + u8 type; + u8 stype; + double od; + double dd; + int element; + u8 brand; + u8 attr; +} t_defect_params; + +#define DEFECT_TYPE_0D 1 +#define DEFECT_TYPE_1D 2 +#define DEFECT_TYPE_2D 3 +#define DEFECT_TYPE_3D 4 + +#define DEFECT_STYPE_DB_X 1 +#define DEFECT_STYPE_DB_Y 2 +#define DEFECT_STYPE_DB_Z 3 +#define DEFECT_STYPE_DB_R 4 + +typedef struct s_offset_params { + t_3dvec o; + u8 use; +} t_offset_params; + /* * * defines @@ -356,12 +410,13 @@ typedef struct s_vb { #define FCC 0x02 #define DIAMOND 0x04 #define ZINCBLENDE 0x08 +#define NONE 0x80 /* * more includes */ -#include "pse.h" +//#include "pse.h" /* * @@ -391,14 +446,19 @@ int moldyn_set_report(t_moldyn *moldyn,char *author,char *title); int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer); int moldyn_log_shutdown(t_moldyn *moldyn); -int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, - u8 attr,u8 brand,int a,int b,int c,t_3dvec *origin); -int add_atom(t_moldyn *moldyn,int element,double mass,u8 brand,u8 attr, +int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element, + u8 attr,u8 brand,int a,int b,int c,t_3dvec *origin, + t_part_params *p_params,t_defect_params *d_params, + t_offset_params *o_params); +int add_atom(t_moldyn *moldyn,int element,u8 brand,u8 attr, t_3dvec *r,t_3dvec *v); int del_atom(t_moldyn *moldyn,int tag); -int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin); -int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin); -int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin); +int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin, + t_part_params *p_params,t_defect_params *d_params); +int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin, + t_part_params *p_params,t_defect_params *d_params); +int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin, + t_part_params *p_params,t_defect_params *d_params); int destroy_atoms(t_moldyn *moldyn); int thermal_init(t_moldyn *moldyn,u8 equi_init); @@ -427,6 +487,8 @@ int link_cell_init(t_moldyn *moldyn,u8 vol); int link_cell_update(t_moldyn *moldyn); #ifdef STATIC_LISTS int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,int **cell); +#elif LOWMEM_LISTS +int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,int *cell); #else int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,t_list *cell); #endif @@ -445,6 +507,7 @@ int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d); //inline int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d) // __attribute__((always_inline)); int check_per_bound(t_moldyn *moldyn,t_3dvec *a); +int check_per_bound_and_care_for_pbc(t_moldyn *moldyn,t_atom *a); //inline int check_per_bound(t_moldyn *moldyn,t_3dvec *a) // __attribute__((always_inline)); @@ -456,10 +519,15 @@ int moldyn_load(t_moldyn *moldyn); int process_2b_bonds(t_moldyn *moldyn,void *data, int (*process)(t_moldyn *moldyn,t_atom *itom,t_atom *jtom, void *data,u8 bc)); +int process_neighbours(t_moldyn *moldyn,void *data,t_atom *atom, + int (*process)(t_moldyn *moldyn,t_atom *atom,t_atom *natom, + void *data,u8 bc)); + int get_line(int fd,char *line,int max); int pair_correlation_init(t_moldyn *moldyn,double dr); int calculate_diffusion_coefficient(t_moldyn *moldyn,double *dc); +int calculate_msd(t_moldyn *moldyn,double *msd); int calculate_pair_correlation_process(t_moldyn *moldyn,t_atom *itom, t_atom *jtom,void *data,u8 bc); int calculate_pair_correlation(t_moldyn *moldyn,double dr,void *ptr); @@ -470,7 +538,13 @@ int bond_analyze(t_moldyn *moldyn,double *quality); int visual_init(t_moldyn *moldyn,char *filebase); int visual_bonds_process(t_moldyn *moldyn,t_atom *itom,t_atom *jtom, void *data,u8 bc); +#ifdef VISUAL_THREAD +void *visual_atoms(void *ptr); +#else int visual_atoms(t_moldyn *moldyn); +#endif + +int fpu_set_rtd(void); #endif diff --git a/msd_calc.c b/msd_calc.c new file mode 100644 index 0000000..80388d8 --- /dev/null +++ b/msd_calc.c @@ -0,0 +1,54 @@ +/* + * calculation of mean square displacement + * + * author: frank.zirkelbach@physik.uni-augsburg.de + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#include "moldyn.h" + +int usage(char *prog) { + + printf("\nusage:\n"); + printf(" %s \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; +} + diff --git a/pair_corr_calc_script b/pair_corr_calc_script index 67ba32c..8006e1f 100755 --- a/pair_corr_calc_script +++ b/pair_corr_calc_script @@ -7,7 +7,7 @@ do_it() { echo "processing $1 ..." - ./pair_correlation_calc $1 $2 + ./pair_correlation_calc $2 $1 trg=`echo $1 | sed 's%s-%pair_corr-%' | sed 's%.save%%'` mv pair_corr_func.txt $trg echo "done" diff --git a/pair_correlation_calc.c b/pair_correlation_calc.c index efe81ad..26db76b 100644 --- a/pair_correlation_calc.c +++ b/pair_correlation_calc.c @@ -19,7 +19,7 @@ int usage(char *prog) { printf("\nusage:\n"); - printf(" %s \n\n",prog); + printf(" %s [ ...]\n\n",prog); return -1; } @@ -28,56 +28,81 @@ int main(int argc,char **argv) { t_moldyn moldyn; int ret; - double *stat; + double *stat,*total; int slots; - int i; + int i,j; double dr; int fd; + unsigned char first; - if(argc!=3) { + if(argc<3) { usage(argv[0]); return -1; } - memset(&moldyn,0,sizeof(t_moldyn)); + dr=atof(argv[1]); + + first=1; + stat=NULL; + total=NULL; + + for(j=2;j" > $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 + diff --git a/potentials/albe.c b/potentials/albe.c index 9d8336e..9f98282 100644 --- a/potentials/albe.c +++ b/potentials/albe.c @@ -105,6 +105,15 @@ int albe_mult_set_params(t_moldyn *moldyn,int element1,int element2) { p->S2[0]=p->S[0]*p->S[0]; p->S2[1]=p->S[1]*p->S[1]; p->S2mixed=p->Smixed*p->Smixed; + p->c2[0]=p->c[0]*p->c[0]; + p->c2[1]=p->c[1]*p->c[1]; + p->c2_mixed=p->c_mixed*p->c_mixed; + p->d2[0]=p->d[0]*p->d[0]; + p->d2[1]=p->d[1]*p->d[1]; + p->d2_mixed=p->d_mixed*p->d_mixed; + p->c2d2[0]=p->c2[0]/p->d2[0]; + p->c2d2[1]=p->c2[1]/p->d2[1]; + p->c2d2_m=p->c2_mixed/p->d2_mixed; printf("[albe] mult parameter info:\n"); printf(" S (A) | %f | %f | %f\n",p->S[0],p->S[1],p->Smixed); @@ -301,40 +310,18 @@ int albe_mult_i0_j0_k0(t_moldyn *moldyn, dgk=*(exchange->gamma_[k])*2.0*frac_k*h_cos_k/d2_h_cos2_k; } - /* zeta - for albe: ik depending g function */ -//if(ai->tag==0) { -// printf("------> %.15f %.15f\n",dj,dk); -// printf("------> %.15f %.15f\n",dj,dk); -//} - - exchange->zeta[j]+=(exchange->f_c[k]*gk); - exchange->zeta[k]+=(exchange->f_c[j]*gj); - - /* cos theta derivatives */ - v3_scale(&dcosdrj,&distk,djdk_inv); // j - v3_scale(&tmp,&distj,-cos_theta/exchange->d2[j]); - v3_add(&dcosdrj,&dcosdrj,&tmp); - v3_scale(&dcosdrk,&distj,djdk_inv); // k - v3_scale(&tmp,&distk,-cos_theta/exchange->d2[k]); - v3_add(&dcosdrk,&dcosdrk,&tmp); +#ifdef DEBUG + if(ai==&(moldyn->atom[DATOM])) + printf("zeta_ij: %f %f %f %f\n",f_c_ik*g,f_c_ik,g,d_ik); +#endif - /* zeta derivatives */ - dzjj=&(exchange->dzeta[j][j]); - dzkk=&(exchange->dzeta[k][k]); - dzjk=&(exchange->dzeta[j][k]); - dzkj=&(exchange->dzeta[k][j]); - v3_scale(&tmp,&dcosdrj,exchange->f_c[k]*dgk); - v3_add(dzjj,dzjj,&tmp); // j j - v3_scale(&tmp,&dcosdrk,exchange->f_c[j]*dgj); - v3_add(dzkk,dzkk,&tmp); // k k - v3_scale(&tmp,&distk,-exchange->df_c[k]*gk); // dk rik = - di rik - v3_add(dzjk,dzjk,&tmp); - v3_scale(&tmp,&dcosdrk,exchange->f_c[k]*dgk); - v3_add(dzjk,dzjk,&tmp); // j k - v3_scale(&tmp,&distj,-exchange->df_c[j]*gj); // dj rij = - di rij - v3_add(dzkj,dzkj,&tmp); - v3_scale(&tmp,&dcosdrj,exchange->f_c[j]*dgj); - v3_add(dzkj,dzkj,&tmp); // k j + /* store even more data for second k loop */ + exchange->g[kcount]=g; + exchange->dg[kcount]=dg; + exchange->d_ik[kcount]=d_ik; + exchange->cos_theta[kcount]=cos_theta; + exchange->f_c_ik[kcount]=f_c_ik; + exchange->df_c_ik[kcount]=df_c_ik; /* increase k counter */ exchange->kcnt+=1; @@ -440,11 +427,21 @@ printf(" t: %.15f %.15f %.15f\n",ai->f.x,ai->f.y,ai->f.z); v3_scale(&force,&force,-1.0); // dri rij = - drj rij v3_add(&(aj->f),&(aj->f),&force); -#ifdef NDEBUG -if(aj->tag==0) { -printf("force: %.15f %.15f %.15f | %d %d (ji) %.15f\n",force.x,force.y,force.z,aj->tag,ai->tag,exchange->zeta[j]); -printf(" t: %.15f %.15f %.15f\n",aj->f.x,aj->f.y,aj->f.z); -} + /* virial */ + virial_calc(ai,&force,&(exchange->dist_ij)); + +#ifdef DEBUG + if((ai==&(moldyn->atom[DATOM]))|(aj==&(moldyn->atom[DATOM]))) { + printf("force 3bp (j2): [%d %d sum]\n",ai->tag,aj->tag); + printf(" adding %f %f %f\n",force.x,force.y,force.z); + if(ai==&(moldyn->atom[DATOM])) + printf(" total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z); + if(aj==&(moldyn->atom[DATOM])) + printf(" total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z); + printf(" energy: %f = %f %f %f %f\n",0.5*f_c*(b*f_a+f_r), + f_c,b,f_a,f_r); + printf(" %f %f %f\n",exchange->zeta_ij,.0,.0); + } #endif /* virial */ @@ -501,39 +498,89 @@ int albe_mult_i0_j2_k0(t_moldyn *moldyn, return 0; } - /* k!=j & check whether to run k */ - k=exchange->kcnt; - j=exchange->j2cnt; - if((k==j)|(exchange->skip[k])) { - exchange->kcnt+=1; - return 0; - } - - /* force contribution (drk derivative) */ - v3_scale(&force,&(exchange->dzeta[j][k]),exchange->pre_dzeta); - v3_add(&(ak->f),&(ak->f),&force); + /* prefactor dzeta */ + pre_dzeta=exchange->pre_dzeta; -#ifdef NDEBUG -if(ak->tag==0) { -printf("force: %.15f %.15f %.15f | %d %d %d (k der)\n",force.x,force.y,force.z,ai->tag,aj->tag,ak->tag); -printf(" t: %.15f %.15f %.15f\n",ak->f.x,ak->f.y,ak->f.z); -} + /* dist_ik, d_ik */ + dist_ik=exchange->dist_ik[kcount]; + d_ik=exchange->d_ik[kcount]; + + /* f_c_ik, df_c_ik */ + f_c_ik=exchange->f_c_ik[kcount]; + df_c_ik=exchange->df_c_ik[kcount]; + + /* dist_ij, d_ij2, d_ij */ + dist_ij=exchange->dist_ij; + d_ij2=exchange->d_ij2; + d_ij=exchange->d_ij; + + /* g, dg, cos_theta */ + g=exchange->g[kcount]; + dg=exchange->dg[kcount]; + cos_theta=exchange->cos_theta[kcount]; + + /* cos_theta derivatives wrt j,k */ + dijdik_inv=1.0/(d_ij*d_ik); + v3_scale(&dcosdrj,&dist_ik,dijdik_inv); // j + v3_scale(&tmp,&dist_ij,-cos_theta/d_ij2); + v3_add(&dcosdrj,&dcosdrj,&tmp); + v3_scale(&dcosdrk,&dist_ij,dijdik_inv); // k + v3_scale(&tmp,&dist_ik,-cos_theta/d_ik2); + v3_add(&dcosdrk,&dcosdrk,&tmp); + + /* f_c_ik * dg, df_c_ik * g */ + fcdg=f_c_ik*dg; + dfcg=df_c_ik*g; + + /* derivative wrt j */ + v3_scale(&force,&dcosdrj,fcdg*pre_dzeta); + + /* force contribution */ + v3_add(&(aj->f),&(aj->f),&force); + +#ifdef DEBUG + if(aj==&(moldyn->atom[DATOM])) { + printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag); + printf(" adding %f %f %f\n",force.x,force.y,force.z); + printf(" total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z); + printf(" angle: %f\n",acos(cos_theta)*360.0/(2*M_PI)); + printf(" d ij ik = %f %f\n",d_ij,d_ik); + } #endif /* virial */ - virial_calc(ai,&force,&(exchange->dist[k])); + virial_calc(ai,&force,&dist_ij); + /* force contribution to atom i */ v3_scale(&force,&force,-1.0); v3_add(&(ai->f),&(ai->f),&force); -#ifdef NDEBUG -if(ai->tag==0) { -printf("force: %.15f %.15f %.15f | %d %d %d -- %d(i contr k der)\n",force.x,force.y,force.z,ai->tag,aj->tag,ak->tag,k); -printf(" t: %.15f %.15f %.15f\n",ai->f.x,ai->f.y,ai->f.z); -printf(" ## %f\n",exchange->d[k]); -} + /* derivative wrt k */ + v3_scale(&force,&dist_ik,-1.0*dfcg); // dri rik = - drk rik + v3_scale(&tmp,&dcosdrk,fcdg); + v3_add(&force,&force,&tmp); + v3_scale(&force,&force,pre_dzeta); + + v3_scale(&force,&force,-1.0); + v3_add(&(ai->f),&(ai->f),&force); + +#ifdef DEBUG + if(ak==&(moldyn->atom[DATOM])) { + printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag); + printf(" adding %f %f %f\n",force.x,force.y,force.z); + printf(" total k: %f %f %f\n",ak->f.x,ak->f.y,ak->f.z); + printf(" angle: %f\n",acos(cos_theta)*360.0/(2*M_PI)); + printf(" d ij ik = %f %f\n",d_ij,d_ik); + } #endif + /* virial */ + virial_calc(ai,&force,&dist_ik); + + /* force contribution to atom i */ + v3_scale(&force,&force,-1.0); + v3_add(&(ai->f),&(ai->f),&force); + /* increase k counter */ exchange->kcnt+=1; diff --git a/potentials/albe.h b/potentials/albe.h index 39c4df8..9687655 100644 --- a/potentials/albe.h +++ b/potentials/albe.h @@ -64,31 +64,32 @@ typedef struct s_albe_mult_params { double c[2]; double c2[2]; double c_mixed; + double c2[2]; double c2_mixed; double d[2]; double d2[2]; double d_mixed; + double d2[2]; double d2_mixed; - double c2d2[2]; - double c2d2_m; double h[2]; double h_mixed; + double c2d2[2]; + double c2d2_m; t_albe_exchange exchange; /* exchange between 2bp and 3bp calc */ } t_albe_mult_params; /* function prototypes */ int albe_mult_set_params(t_moldyn *moldyn,int element1,int elemnt2); -int albe_mult_i0(t_moldyn *moldyn,t_atom *ai); -int albe_mult_i0_j0(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); -int albe_mult_i0_j0_k0(t_moldyn *moldyn, - t_atom *ai,t_atom *aj,t_atom *ak,u8 bc); -int albe_mult_i0_j1(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); -int albe_mult_i0_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); -int albe_mult_i0_j2_k0(t_moldyn *moldyn, - t_atom *ai,t_atom *aj,t_atom *ak,u8 bc); -int albe_mult_i0_j3(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); +int albe_mult_3bp_j1(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); +int albe_mult_3bp_k1(t_moldyn *moldyn, + t_atom *ai,t_atom *aj,t_atom *ak,u8 bc); +int albe_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); +int albe_mult_3bp_k2(t_moldyn *moldyn, + t_atom *ai,t_atom *aj,t_atom *ak,u8 bc); int albe_mult_check_2b_bond(t_moldyn *moldyn,t_atom *itom,t_atom *jtom,u8 bc); +/* fast */ +int albe_potential_force_calc(t_moldyn *moldyn); /* albe potential parameter defines */ @@ -102,35 +103,35 @@ int albe_mult_check_2b_bond(t_moldyn *moldyn,t_atom *itom,t_atom *jtom,u8 bc); #define ALBE_MU_SI (1.4761*sqrt(2.0/1.842)) #define ALBE_GAMMA_SI 0.114354 #define ALBE_C_SI 2.00494 -#define ALBE_D_SI 0.81472 +#define ALBE_D_SI 0.814719 #define ALBE_H_SI 0.259 #define ALBE_LC_SI 5.429 // carbon #define ALBE_R_C (2.00-0.15) #define ALBE_S_C (2.00+0.15) -#define ALBE_A_C (6.00*EV/1.167) -#define ALBE_B_C (-2.167*6.00*EV/1.167) -#define ALBE_R0_C 1.4276 -#define ALBE_LAMBDA_C (2.0099*sqrt(2.0*2.167)) -#define ALBE_MU_C (2.0099*sqrt(2.0/2.167)) -#define ALBE_GAMMA_C 0.11233 -#define ALBE_C_C 181.910 -#define ALBE_D_C 6.28433 -#define ALBE_H_C 0.5556 +#define ALBE_A_C (6.00*EV/1.1671419) +#define ALBE_B_C (-2.1671419*6.00*EV/1.1671419) +#define ALBE_R0_C 1.4276442 +#define ALBE_LAMBDA_C (2.0099457*sqrt(2.0*2.1671419)) +#define ALBE_MU_C (2.0099457*sqrt(2.0/2.1671419)) +#define ALBE_GAMMA_C 0.1123327 +#define ALBE_C_C 181.9100526 +#define ALBE_D_C 6.2843249 +#define ALBE_H_C 0.5556181 #define ALBE_LC_C 3.566 // mixed: silicon carbide #define ALBE_R_SIC (2.40-0.20) #define ALBE_S_SIC (2.40+0.20) -#define ALBE_A_SIC (4.36*EV/0.847) -#define ALBE_B_SIC (-1.847*4.36*EV/0.847) +#define ALBE_A_SIC (4.36*EV/0.8474739) +#define ALBE_B_SIC (-1.8474739*4.36*EV/0.8474739) #define ALBE_R0_SIC 1.79 -#define ALBE_LAMBDA_SIC (1.6991*sqrt(2.0*1.847)) -#define ALBE_MU_SIC (1.6991*sqrt(2.0/1.847)) -#define ALBE_GAMMA_SIC 0.011877 -#define ALBE_C_SIC 273987 -#define ALBE_D_SIC 180.314 +#define ALBE_LAMBDA_SIC (1.6990751*sqrt(2.0*1.8474739)) +#define ALBE_MU_SIC (1.6990751*sqrt(2.0/1.8474739)) +#define ALBE_GAMMA_SIC 0.0118769 +#define ALBE_C_SIC 273986.61 +#define ALBE_D_SIC 180.31411 #define ALBE_H_SIC 0.68 #define ALBE_LC_SIC 4.359 diff --git a/potentials/albe_fast.c b/potentials/albe_fast.c new file mode 100644 index 0000000..79162b1 --- /dev/null +++ b/potentials/albe_fast.c @@ -0,0 +1,1460 @@ +/* + * test: albe_new.c + * + * author: Frank Zirkelbach + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef PARALLEL +#include +#endif + +#ifdef PTHREADS +#include +#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;ixx=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;idim.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=(jsubcell->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=(ksubcell->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_ijf),&(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->timeatom[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=(ksubcell->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->timeatom[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->timeatom[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->timeatom[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;igvir.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;iend;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=(jsubcell->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=(ksubcell->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_ijtag]))) + 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->timeatom[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=(ksubcell->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->timeatom[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->timeatom[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->timeatom[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;ixx=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;jgvir.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 diff --git a/potentials/tersoff.c b/potentials/tersoff.c index 5039ff7..4ca7141 100644 --- a/potentials/tersoff.c +++ b/potentials/tersoff.c @@ -85,20 +85,28 @@ int tersoff_mult_set_params(t_moldyn *moldyn,int element1,int element2) { p->h[1]=TM_H_C; break; default: - printf("[tersoff] WARNING: element1\n"); + printf("[tersoff] WARNING: element2\n"); return -1; } printf("[tersoff] parameter completion\n"); p->S2[0]=p->S[0]*p->S[0]; p->S2[1]=p->S[1]*p->S[1]; - p->Smixed=sqrt(p->S[0]*p->S[1]); - p->S2mixed=p->Smixed*p->Smixed; + p->S2mixed=p->S[0]*p->S[1]; + p->Smixed=sqrt(p->S2mixed); p->Rmixed=sqrt(p->R[0]*p->R[1]); p->Amixed=sqrt(p->A[0]*p->A[1]); p->Bmixed=sqrt(p->B[0]*p->B[1]); p->lambda_m=0.5*(p->lambda[0]+p->lambda[1]); p->mu_m=0.5*(p->mu[0]+p->mu[1]); + p->betaini[0]=pow(p->beta[0],p->n[0]); + p->betaini[1]=pow(p->beta[1],p->n[1]); + p->ci2[0]=p->c[0]*p->c[0]; + p->ci2[1]=p->c[1]*p->c[1]; + p->di2[0]=p->d[0]*p->d[0]; + p->di2[1]=p->d[1]*p->d[1]; + p->ci2di2[0]=p->ci2[0]/p->di2[0]; + p->ci2di2[1]=p->ci2[1]/p->di2[1]; printf("[tersoff] mult parameter info:\n"); printf(" S (A) | %f | %f | %f\n",p->S[0],p->S[1],p->Smixed); @@ -118,36 +126,6 @@ int tersoff_mult_set_params(t_moldyn *moldyn,int element1,int element2) { return 0; } -/* tersoff 1 body part */ -int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai) { - - int brand; - t_tersoff_mult_params *params; - t_tersoff_exchange *exchange; - - brand=ai->brand; - params=moldyn->pot_params; - exchange=&(params->exchange); - - /* - * simple: point constant parameters only depending on atom i to - * their right values - */ - - exchange->beta_i=&(params->beta[brand]); - exchange->n_i=&(params->n[brand]); - exchange->c_i=&(params->c[brand]); - exchange->d_i=&(params->d[brand]); - exchange->h_i=&(params->h[brand]); - - exchange->betaini=pow(*(exchange->beta_i),*(exchange->n_i)); - exchange->ci2=params->c[brand]*params->c[brand]; - exchange->di2=params->d[brand]*params->d[brand]; - exchange->ci2di2=exchange->ci2/exchange->di2; - - return 0; -} - /* tersoff 2 body part */ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { @@ -239,7 +217,7 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { #endif /* virial */ - virial_calc(aj,&force,&dist_ij); + virial_calc(ai,&force,&dist_ij); /* energy 2bp contribution */ energy=f_r*f_c; @@ -364,10 +342,10 @@ int tersoff_mult_3bp_k1(t_moldyn *moldyn, cos_theta=v3_scalar_product(&dist_ij,&dist_ik)/(d_ij*d_ik); /* g_ijk */ - h_cos=*(exchange->h_i)-cos_theta; - d2_h_cos2=exchange->di2+(h_cos*h_cos); - frac=exchange->ci2/d2_h_cos2; - g=1.0+exchange->ci2di2-frac; + h_cos=params->h[brand]-cos_theta; + d2_h_cos2=params->di2[brand]+(h_cos*h_cos); + frac=params->ci2[brand]/d2_h_cos2; + g=1.0+params->ci2di2[brand]-frac; dg=-2.0*frac*h_cos/d2_h_cos2; /* zeta sum += f_c_ik * g_ijk */ @@ -385,11 +363,8 @@ int tersoff_mult_3bp_k1(t_moldyn *moldyn, } #ifdef DEBUG - if((ai==&(moldyn->atom[0]))| - (aj==&(moldyn->atom[864]))| - (ak==&(moldyn->atom[1003]))) { - printf(" -> %f %f %f\n",exchange->ci2di2,frac,h_cos); - } + if(ai==&(moldyn->atom[DATOM])) + printf("zeta_ij: %f %f %f %f\n",f_c_ik*g,f_c_ik,g,d_ik); #endif /* store even more data for second k loop */ @@ -425,8 +400,8 @@ int tersoff_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { params=moldyn->pot_params; exchange=&(params->exchange); - brand=aj->brand; - if(brand==ai->brand) { + brand=ai->brand; + if(brand==aj->brand) { S=params->S[brand]; R=params->R[brand]; B=params->B[brand]; @@ -473,8 +448,8 @@ int tersoff_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { db=0.0; } else { - ni=*(exchange->n_i); - tmp=exchange->betaini*pow(exchange->zeta_ij,ni-1.0); + ni=params->n[brand]; + tmp=params->betaini[brand]*pow(exchange->zeta_ij,ni-1.0); b=(1.0+exchange->zeta_ij*tmp); db=chi*pow(b,-1.0/(2.0*ni)-1.0); b=db*b; @@ -489,12 +464,12 @@ int tersoff_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { v3_add(&(aj->f),&(aj->f),&force); #ifdef DEBUG - if((ai==&(moldyn->atom[0]))|(aj==&(moldyn->atom[0]))) { + if((ai==&(moldyn->atom[DATOM]))|(aj==&(moldyn->atom[DATOM]))) { printf("force 3bp (j2): [%d %d sum]\n",ai->tag,aj->tag); printf("adding %f %f %f\n",force.x,force.y,force.z); - if(ai==&(moldyn->atom[0])) + if(ai==&(moldyn->atom[DATOM])) printf("total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z); - if(aj==&(moldyn->atom[0])) + if(aj==&(moldyn->atom[DATOM])) printf("total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z); printf("energy: %f = %f %f %f %f\n",0.5*f_c*(b*f_a+f_r), f_c,b,f_a,f_r); @@ -503,7 +478,7 @@ int tersoff_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { #endif /* virial */ - virial_calc(aj,&force,&(exchange->dist_ij)); + virial_calc(ai,&force,&(exchange->dist_ij)); /* dzeta prefactor = - 0.5 f_c f_a db */ exchange->pre_dzeta=-0.5*f_a*f_c*db; @@ -534,7 +509,7 @@ int tersoff_mult_3bp_k2(t_moldyn *moldyn, double pre_dzeta; double f_c_ik,df_c_ik; double dijdik_inv,fcdg,dfcg; - t_3dvec dcosdri,dcosdrj,dcosdrk; + t_3dvec dcosdrj,dcosdrk; t_3dvec force,tmp; params=moldyn->pot_params; @@ -588,30 +563,11 @@ int tersoff_mult_3bp_k2(t_moldyn *moldyn, v3_scale(&dcosdrk,&dist_ij,dijdik_inv); v3_scale(&tmp,&dist_ik,-cos_theta/d_ik2); v3_add(&dcosdrk,&dcosdrk,&tmp); - v3_add(&dcosdri,&dcosdrj,&dcosdrk); - v3_scale(&dcosdri,&dcosdri,-1.0); /* f_c_ik * dg, df_c_ik * g */ fcdg=f_c_ik*dg; dfcg=df_c_ik*g; - /* derivative wrt i */ - v3_scale(&force,&dist_ik,dfcg); - v3_scale(&tmp,&dcosdri,fcdg); - v3_add(&force,&force,&tmp); - v3_scale(&force,&force,pre_dzeta); - - /* force contribution */ - v3_add(&(ai->f),&(ai->f),&force); - -#ifdef DEBUG - if(ai==&(moldyn->atom[0])) { - printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag); - printf("adding %f %f %f\n",force.x,force.y,force.z); - printf("total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z); - } -#endif - /* derivative wrt j */ v3_scale(&force,&dcosdrj,fcdg*pre_dzeta); @@ -619,17 +575,22 @@ int tersoff_mult_3bp_k2(t_moldyn *moldyn, v3_add(&(aj->f),&(aj->f),&force); #ifdef DEBUG - if(aj==&(moldyn->atom[0])) { + if(aj==&(moldyn->atom[DATOM])) { printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag); - printf("adding %f %f %f\n",force.x,force.y,force.z); - printf("total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z); + printf(" adding %f %f %f\n",force.x,force.y,force.z); + printf(" total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z); + printf(" angle: %f\n",acos(cos_theta)*360.0/(2*M_PI)); + printf(" d ij ik = %f %f\n",d_ij,d_ik); } #endif /* virial */ - v3_scale(&force,&force,-1.0); virial_calc(ai,&force,&dist_ij); + /* force contribution to atom i */ + v3_scale(&force,&force,-1.0); + v3_add(&(ai->f),&(ai->f),&force); + /* derivative wrt k */ v3_scale(&force,&dist_ik,-1.0*dfcg); // dri rik = - drk rik v3_scale(&tmp,&dcosdrk,fcdg); @@ -640,19 +601,24 @@ int tersoff_mult_3bp_k2(t_moldyn *moldyn, v3_add(&(ak->f),&(ak->f),&force); #ifdef DEBUG - if(ak==&(moldyn->atom[0])) { + if(ak==&(moldyn->atom[DATOM])) { printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag); - printf("adding %f %f %f\n",force.x,force.y,force.z); - printf("total k: %f %f %f\n",ak->f.x,ak->f.y,ak->f.z); + printf(" adding %f %f %f\n",force.x,force.y,force.z); + printf(" total k: %f %f %f\n",ak->f.x,ak->f.y,ak->f.z); + printf(" angle: %f\n",acos(cos_theta)*360.0/(2*M_PI)); + printf(" d ij ik = %f %f\n",d_ij,d_ik); } #endif /* virial */ - v3_scale(&force,&force,-1.0); virial_calc(ai,&force,&dist_ik); + + /* force contribution to atom i */ + v3_scale(&force,&force,-1.0); + v3_add(&(ai->f),&(ai->f),&force); /* increase k counter */ - exchange->kcount++; + exchange->kcount++; return 0; diff --git a/potentials/tersoff.h b/potentials/tersoff.h index a23503a..2e4f242 100644 --- a/potentials/tersoff.h +++ b/potentials/tersoff.h @@ -28,17 +28,6 @@ typedef struct s_tersoff_echange { double dg[TERSOFF_MAXN]; double cos_theta[TERSOFF_MAXN]; - double *beta_i; - double *n_i; - double *c_i; - double *d_i; - double *h_i; - - double ci2; - double di2; - double ci2di2; - double betaini; - double zeta_ij; double pre_dzeta; @@ -70,12 +59,17 @@ typedef struct s_tersoff_mult_params { double d[2]; double h[2]; + double ci2[2]; + double di2[2]; + double ci2di2[2]; + double betaini[2]; + t_tersoff_exchange exchange; /* exchange between 2bp and 3bp calc */ } t_tersoff_mult_params; /* function prototypes */ int tersoff_mult_set_params(t_moldyn *moldyn,int element1,int element2); -int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai); +//int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai); int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); int tersoff_mult_3bp_j1(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); int tersoff_mult_3bp_k1(t_moldyn *moldyn, diff --git a/povconv b/povconv index 122b3e8..0983b8e 100755 --- a/povconv +++ b/povconv @@ -5,18 +5,20 @@ # frank.zirkelbach@physik.uni-augsburg.de # -if [ ! -d $1 ]; then - echo "no valid directory" - exit 1 -fi +#if [ ! -d $1 ]; then +# echo "no valid directory" +# exit 1 +#fi -TRG=$1/md.movie +TRG="mdlat.in.xyz" rm -f $TRG ((frame=1)) -for file in $1/atomic_conf_*.xyz; do +#for file in $1/atomic_conf_*.xyz; do + +file=$1 count=`grep '# \[P\]' $file | awk '{ print $3 }'` time=`grep '# \[P\]' $file | awk '{ print $4 }'` @@ -37,13 +39,14 @@ for file in $1/atomic_conf_*.xyz; do cat $file | grep -v '^#' | while read name x y z color temp; do # well, i only use Si and C - [ "$name" = "Si" ] && type=1 - [ "$name" = "C" ] && type=2 - echo "$name $x $y $z $type ${ac}" >> $TRG + [ "$name" = "Si" ] && type=0 + [ "$name" = "C" ] && type=1 + #echo "$name $x $y $z $type ${ac}" >> $TRG + echo "$name $x $y $z $type" >> $TRG ((ac+=1)) done ((frame+=1)) -done +#done diff --git a/pse.h b/pse.h index 3391d26..c746f2d 100644 --- a/pse.h +++ b/pse.h @@ -7,6 +7,7 @@ #include "moldyn.h" +#ifdef PSE_MASS static double pse_mass[]={ 0, 0, @@ -28,7 +29,9 @@ static double pse_mass[]={ 0, 0, }; +#endif +#ifdef PSE_LC static double pse_lc[]={ 0, 0, @@ -50,7 +53,9 @@ static double pse_lc[]={ 0, 0, }; +#endif +#ifdef PSE_NAME static char *pse_name[]={ "*", "H", @@ -72,7 +77,9 @@ static char *pse_name[]={ "Cl", "Ar", }; +#endif +#ifdef PSE_COL static char *pse_col[]={ "*", "White", @@ -94,4 +101,5 @@ static char *pse_col[]={ "Cl", "Ar", }; +#endif diff --git a/random/random.c b/random/random.c index 902cdef..292bc69 100644 --- a/random/random.c +++ b/random/random.c @@ -109,6 +109,7 @@ double rand_get_gauss(t_random *random) { return random->gauss; } + a=0; b=0; w=0; while((w>=1.0)||(w==0.0)) { a=-2.0*rand_get_double(random)+1.0; diff --git a/remember_me.txt b/remember_me.txt index 7247fbb..3ae541e 100644 --- a/remember_me.txt +++ b/remember_me.txt @@ -11,3 +11,13 @@ c-c 3.1: saves/c_in_si_prec_450_01/s-0566000.save 239458 240660 110 - 100 239703 241605 100 - 100 + + +concatenated, differently oriented 100 dumbbells +################################################ + +posic_new/saves/c_in_si_prec_450_tot_02/s-0272000.save b 3.08 0.01 + + atoms 238338/1 238631/1 - 3.078045 + atoms 238461/1 244278/1 - 3.085715 + diff --git a/runmd b/runmd index d50d9ae..609bcf3 100755 --- a/runmd +++ b/runmd @@ -8,13 +8,15 @@ if [ ! -f ./config ]; then exit fi -[ ! -d $1 ] && mkdir $1 +[ ! -d $1 ] && mkdir -p $1 ./clean $1 cp -v config $1/config -time ./mdrun -c ./config -s $1 +mkdir -p logs +logfile=logs/run_`basename $1`.log +time ./mdrun -c ./config -s $1 | tee $logfile if [ "$?" == "0" ]; then #./perms @@ -22,9 +24,28 @@ if [ "$?" == "0" ]; then # whole simulation cell #./visualize -w 640 -h 480 -d $1 - # center unit cell + # crt + mkdir -p $1/crt + check=`grep crt\ init $logfile` + if [ "$check" = " crt init" ]; then + grep crt\ energy $logfile | \ + awk -F: '{ print $2 }' | \ + awk -F\ -\ '{ print $1 " " $2 }' > \ + $1/crt/energy + for i in $1/s-crt_*.save; do + nr=`basename $i | awk -F_ '{ print $2 }' | \ + awk -F. '{ print $1 }'` + ./s2xyz $i > $1/crt/atomic_conf_${nr}.xyz + done + ./visualize -w 640 -h 480 -d $1/crt \ + -nll -0.56 -0.56 -0.76 -fur 0.56 0.56 0.56 \ + -b -0.5 -0.5 -0.5 0.5 0.5 0.5 \ + -c -0.2 -2.0 0.6 -L 0 0 -0.1 \ + -r 0.6 -B 0.1 + fi + ./visualize -w 640 -h 480 -d $1 \ - -nll -0.56 -0.56 -0.56 -fur 0.56 0.56 0.56 \ + -nll -0.56 -0.56 -0.76 -fur 0.56 0.56 0.56 \ -b -0.5 -0.5 -0.5 0.5 0.5 0.5 \ -c -0.2 -2.0 0.6 -L 0 0 -0.1 \ -r 0.6 -B 0.1 @@ -32,5 +53,7 @@ if [ "$?" == "0" ]; then # old rasmol #rasmol -32 -nodisplay < $1/visualize.scr > /dev/null 2>&1 ./ppm2avi $1 + fi fi + diff --git a/s2xyz.c b/s2xyz.c new file mode 100644 index 0000000..5163e41 --- /dev/null +++ b/s2xyz.c @@ -0,0 +1,55 @@ +/* + * calcultae pair correlation function + * + * author: frank.zirkelbach@physik.uni-augsburg.de + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#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 $TRG" + ./s2xyz $i > $TRG +done + + + diff --git a/sic.c b/sic.c index e33d934..375c6d5 100644 --- a/sic.c +++ b/sic.c @@ -121,7 +121,7 @@ int insert_atoms(t_moldyn *moldyn) { dmin=d; } } - add_atom(moldyn,INS_TYPE,INS_MASS,INS_BRAND, + add_atom(moldyn,INS_TYPE,INS_BRAND, ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|\ INS_ATTR, &r,&v); @@ -325,25 +325,25 @@ int main(int argc,char **argv) { // diamond #ifdef ALBE #ifdef INIT_SI - create_lattice(&md,DIAMOND,ALBE_LC_SI,SI,M_SI, + create_lattice(&md,DIAMOND,ALBE_LC_SI,SI, ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - 0,LCNTX,LCNTY,LCNTZ,NULL); + 0,LCNTX,LCNTY,LCNTZ,NULL,0,NULL); #endif #ifdef INIT_C - create_lattice(&md,DIAMOND,ALBE_LC_C,C,M_C, + create_lattice(&md,DIAMOND,ALBE_LC_C,C, ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - 1,LCNTX,LCNTY,LCNTZ,NULL); + 1,LCNTX,LCNTY,LCNTZ,NULL,0,NULL); #endif #else #ifdef INIT_SI - create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, + create_lattice(&md,DIAMOND,LC_SI,SI, ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - 0,LCNTX,LCNTY,LCNTZ,NULL); + 0,LCNTX,LCNTY,LCNTZ,NULL,0,NULL); #endif #ifdef INIT_C - create_lattice(&md,DIAMOND,LC_C,SI,M_SI, + create_lattice(&md,DIAMOND,LC_C,SI, ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - 1,LCNTX,LCNTY,LCNTZ,NULL); + 1,LCNTX,LCNTY,LCNTZ,NULL,0,NULL); #endif #endif @@ -351,22 +351,22 @@ int main(int argc,char **argv) { #ifdef INIT_3CSIC #ifdef ALBE r.x=0.5*0.25*ALBE_LC_SIC; r.y=r.x; r.z=r.x; - create_lattice(&md,FCC,ALBE_LC_SIC,SI,M_SI, + create_lattice(&md,FCC,ALBE_LC_SIC,SI, ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - 0,LCNTX,LCNTY,LCNTZ,&r); + 0,LCNTX,LCNTY,LCNTZ,&r,0,NULL); r.x+=0.25*ALBE_LC_SIC; r.y=r.x; r.z=r.x; - create_lattice(&md,FCC,ALBE_LC_SIC,C,M_C, + create_lattice(&md,FCC,ALBE_LC_SIC,C, ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB|ATOM_ATTR_VB, - 1,LCNTX,LCNTY,LCNTZ,&r); + 1,LCNTX,LCNTY,LCNTZ,&r,0,NULL); #else r.x=0.5*0.25*TM_LC_SIC; r.y=r.x; r.z=r.x; - create_lattice(&md,FCC,TM_LC_SIC,SI,M_SI, + create_lattice(&md,FCC,TM_LC_SIC,SI, ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - 0,LCNTX,LCNTY,LCNTZ,&r); + 0,LCNTX,LCNTY,LCNTZ,&r,0,NULL); r.x+=0.25*TM_LC_SIC; r.y=r.x; r.z=r.x; - create_lattice(&md,FCC,TM_LC_SIC,C,M_C, + create_lattice(&md,FCC,TM_LC_SIC,C, ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - 1,LCNTX,LCNTY,LCNTZ,&r); + 1,LCNTX,LCNTY,LCNTZ,&r,0,NULL); #endif #endif diff --git a/vasp_tools/Makefile b/vasp_tools/Makefile new file mode 100644 index 0000000..177b5e9 --- /dev/null +++ b/vasp_tools/Makefile @@ -0,0 +1,12 @@ +CC = gcc-4.3 + +CFLAGS = -Wall -Winline +CFLAGS += -O3 -march=native -msse2 -mfpmath=sse +CFLAGS += -g + +LDFLAGS = -lm + +ALL = create_lattice + +all: $(ALL) + diff --git a/vasp_tools/acos.c b/vasp_tools/acos.c new file mode 100644 index 0000000..609a6dc --- /dev/null +++ b/vasp_tools/acos.c @@ -0,0 +1,11 @@ +/* acos */ + +#include +#include +#include + +int main(int argc,char **argv) { + printf("%f\n",180.0/M_PI*acos(atof(argv[1]))); + return 0; +} + diff --git a/vasp_tools/angle_calc b/vasp_tools/angle_calc new file mode 100755 index 0000000..b23d51d --- /dev/null +++ b/vasp_tools/angle_calc @@ -0,0 +1,101 @@ +#!/bin/bash + +file=$1 +atom=$2 +btom=$3 +ctom=$4 + +((offset=8)) + +scale=`sed -n 2p $file` +X1=`sed -n 3p $file | awk '{ print $1 }'` +X2=`sed -n 3p $file | awk '{ print $2 }'` +X3=`sed -n 3p $file | awk '{ print $3 }'` +Y1=`sed -n 4p $file | awk '{ print $1 }'` +Y2=`sed -n 4p $file | awk '{ print $2 }'` +Y3=`sed -n 4p $file | awk '{ print $3 }'` +Z1=`sed -n 5p $file | awk '{ print $1 }'` +Z2=`sed -n 5p $file | awk '{ print $2 }'` +Z3=`sed -n 5p $file | awk '{ print $3 }'` +export X1 X2 X3 +export Y1 Y2 Y3 +export Z1 Z2 Z3 + +((line1=atom+offset)) +((line2=btom+offset)) +((line3=ctom+offset)) + +temp="`sed -n ${line1}p $1`" +xa=`echo $temp | awk '{ print $1 }'` +ya=`echo $temp | awk '{ print $2 }'` +za=`echo $temp | awk '{ print $3 }'` + +temp="`sed -n ${line2}p $1`" +xb=`echo $temp | awk '{ print $1 }'` +yb=`echo $temp | awk '{ print $2 }'` +zb=`echo $temp | awk '{ print $3 }'` + +temp="`sed -n ${line3}p $1`" +xc=`echo $temp | awk '{ print $1 }'` +yc=`echo $temp | awk '{ print $2 }'` +zc=`echo $temp | awk '{ print $3 }'` + +echo -en "angle: " +foo=`echo "$xa $ya $za $xb $yb $zb $xc $yc $zc $scale" | \ + awk ' \ + BEGIN { + X1=ENVIRON["X1"]; X2=ENVIRON["X2"]; X3=ENVIRON["X3"] + Y1=ENVIRON["Y1"]; Y2=ENVIRON["Y2"]; Y3=ENVIRON["Y3"] + Z1=ENVIRON["Z1"]; Z2=ENVIRON["Z2"]; Z3=ENVIRON["Z3"] + pi=3.14159265 + } + { + X=sqrt(X1^2+X2^2+X3^2) + Y=sqrt(Y1^2+Y2^2+Y3^2) + Z=sqrt(Z1^2+Z2^2+Z3^2) + dx=$1-$4 + dy=$2-$5 + dz=$3-$6 + if(dx>1/2) + dx-=1 + if(dx<-1/2) + dx+=1 + if(dy>1/2) + dy-=1 + if(dy<-1/2) + dy+=1 + if(dz>1/2) + dz-=1 + if(dz<-1/2) + dz+=1 + Dx=$1-$7 + Dy=$2-$8 + Dz=$3-$9 + if(Dx>1/2) + Dx-=1 + if(Dx<-1/2) + Dx+=1 + if(Dy>1/2) + Dy-=1 + if(Dy<-1/2) + Dy+=1 + if(Dz>1/2) + Dz-=1 + if(Dz<-1/2) + Dz+=1 + dxt=dx*X1+dy*Y1+dz*Z1 + dyt=dx*X2+dy*Y2+dz*Z2 + dzt=dx*X3+dy*Y3+dz*Z3 + Dxt=Dx*X1+Dy*Y1+Dz*Z1 + Dyt=Dx*X2+Dy*Y2+Dz*Z2 + Dzt=Dx*X3+Dy*Y3+Dz*Z3 + sp=dxt*Dxt+dyt*Dyt+dzt*Dzt + d=sqrt(dxt^2+dyt^2+dzt^2) + D=sqrt(Dxt^2+Dyt^2+Dzt^2) + print sp/(d*D) + }'` + +./acos $foo + +echo + diff --git a/vasp_tools/avg_disp b/vasp_tools/avg_disp new file mode 100755 index 0000000..bd0a3d2 --- /dev/null +++ b/vasp_tools/avg_disp @@ -0,0 +1,99 @@ +#!/bin/bash + +file=$1 +init=$2 + +sicnt=`sed -n 6p $file | awk '{ print $1 }'` +ccnt=`sed -n 6p $file | awk '{ print $2 }'` +((cnt=sicnt+ccnt)) + +((offset=8)) + +((count=1)) + +x=0 +y=0 +z=0 + +while [ $count -le $cnt ]; do + + ((ln=count+offset)) + + temp="`sed -n ${ln}p $file`" + xa=`echo $temp | awk '{ print $1 }'` + ya=`echo $temp | awk '{ print $2 }'` + za=`echo $temp | awk '{ print $3 }'` + + temp="`sed -n ${ln}p $init`" + xi=`echo $temp | awk '{ print $1 }'` + yi=`echo $temp | awk '{ print $2 }'` + zi=`echo $temp | awk '{ print $3 }'` + + results=`echo $xa $ya $za $xi $yi $zi | awk '{ + xa=$1 + if($1<0.0) + xa=$1+1.0 + if($1>1.0) + xa=$1-1.0 + ya=$2 + if($2<0.0) + ya=$2+1.0 + if($2>1.0) + ya=$2-1.0 + za=$3 + if($3<0.0) + za=$3+1.0 + if($3>1.0) + za=$3-1.0 + + xi=$4 + if($4<0.0) + xi=$4+1.0 + if($4>1.0) + xi=$4-1.0 + yi=$5 + if($5<0.0) + yi=$5+1.0 + if($5>1.0) + yi=$5-1.0 + zi=$6 + if($6<0.0) + zi=$6+1.0 + if($6>1.0) + zi=$6-1.0 + + dx=xa-xi + dy=ya-yi + dz=za-zi + + if(dx>0.5) + dx-=1 + else if(dx<-0.5) + dx+=1 + if(dy>0.5) + dy-=1 + else if(dy<-0.5) + dy+=1 + if(dz>0.5) + dz-=1 + else if(dz<-0.5) + dz+=1 + + print dx " " dy " " dz + }'` + + dx=`echo $results | awk '{ print $1 }'` + dy=`echo $results | awk '{ print $2 }'` + dz=`echo $results | awk '{ print $3 }'` + + x=`echo $x $dx | awk '{ print $1+$2 }'` + y=`echo $y $dy | awk '{ print $1+$2 }'` + z=`echo $z $dz | awk '{ print $1+$2 }'` + + ((count+=1)) + +done + +((count-=1)) +echo $x $y $z $count | awk '{ print $1/($4*3) " " $2/($4*3) " " $3/($4*3) }' + diff --git a/vasp_tools/constraint_mig_script b/vasp_tools/constraint_mig_script new file mode 100755 index 0000000..ca74b78 --- /dev/null +++ b/vasp_tools/constraint_mig_script @@ -0,0 +1,74 @@ +#!/bin/bash + +# migration + +fx=0.1667178996794456 +fy=0.1667178996794456 +fz=0.0655951877086257 + +((steps=20)) +((count=0)) + +while [ $count -lt $steps ]; do + + cnt=`printf "%02d" $count` + + echo + echo + echo "run simulation $cnt ..." + [ $count != 0 ] && + echo " c atom at: `sed -n 226p CONTCAR`" + echo + echo + ../vasp.4.6-gamma-ct/vasp + + cp POSCAR POSCAR.${cnt} + cp CONTCAR CONTCAR.${cnt} + cp OUTCAR OUTCAR.${cnt} + + ltm="`sed -n 226p CONTCAR`" + val1=`echo $ltm | awk '{ print $1 }'` + val2=`echo $ltm | awk '{ print $2 }'` + val3=`echo $ltm | awk '{ print $3 }'` + val4=`echo $ltm | awk '{ print $4 }'` + val5=`echo $ltm | awk '{ print $5 }'` + val6=`echo $ltm | awk '{ print $6 }'` + + ((rest=steps-count)) + + nx=`echo $val1 $fx $rest | awk '{ print $1+($2-$1)/$3 }'` + ny=`echo $val2 $fy $rest | awk '{ print $1+($2-$1)/$3 }'` + nz=`echo $val3 $fz $rest | awk '{ print $1+($2-$1)/$3 }'` + + sed "s%$ltm% $nx $ny $nz $val4 $val5 $val6%" CONTCAR > POSCAR + + echo + echo "simulation $cnt end" + echo " c atom now at: `sed -n 226p CONTCAR`" + echo " dis x: `echo $val1 $fx $rest | awk '{ print ($2-$1)/$3 }'`" + echo " dis y: `echo $val2 $fy $rest | awk '{ print ($2-$1)/$3 }'`" + echo " dis z: `echo $val3 $fz $rest | awk '{ print ($2-$1)/$3 }'`" + echo + + newline="`echo $val1 $fx $val2 $fy $val3 $fz | awk '\ + BEGIN { + zrot=0; xrot=0; xyd=0; x=0; y=0; z=0; + } + { + x=$2-$1; y=$4-$3; z=$6-$5; + zrot=180.0*atan2(x,y)/3.14159265; + xyd=sqrt(x^2+y^2); + xrot=-180.0*atan2(z,xyd)/3.14159265; + print zrot " " xrot + }'`" + + ltm="`sed -n 8p POSCAR`" + echo "info:" + echo "$ltm" + echo "->" + echo "$newline" + sed -i "s%$ltm%$newline%" POSCAR + + ((count+=1)) +done + diff --git a/vasp_tools/create_dbc b/vasp_tools/create_dbc new file mode 100755 index 0000000..4b40c44 --- /dev/null +++ b/vasp_tools/create_dbc @@ -0,0 +1,141 @@ +#!/bin/bash + +# create POSCAR files for db combinations + +deltaC=0.1969 +deltaSi=0.1211 + +clen=3 + +file=$1/CONTCAR +if [ ! -f $file ]; then + echo "no CONTCAR file in $1 ..." + exit +fi + +lnumber=$2 +if [ -z $lnumber ]; then + echo "no line number specified ..." + exit +fi + +gline="`sed -n 6p $file`" +sic=`echo $gline | awk '{ print $1 }'` +cc=`echo $gline | awk '{ print $2 }'` +((tot=sic+cc)) +((addline=tot+8)) + +ltm=`sed -n ${lnumber}p $file` + +echo "line to modify:" +echo $ltm + +x=`echo $ltm | awk '{ print $1 }'` +y=`echo $ltm | awk '{ print $2 }'` +z=`echo $ltm | awk '{ print $3 }'` +s1=`echo $ltm | awk '{ print $4 }'` +s2=`echo $ltm | awk '{ print $5 }'` +s3=`echo $ltm | awk '{ print $6 }'` + +echo "00-1:" +nz=`echo $z $deltaSi $clen | awk '{ + res=$1+($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed "s%$ltm%$x $y $nz $s1 $s2 $s3%" $file > POSCAR.00-1 +nz=`echo $z $deltaC $clen | awk '{ + res=$1-($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed -i "$addline a\ +$x $y $nz T T T" POSCAR.00-1 + +echo "001:" +nz=`echo $z $deltaSi $clen | awk '{ + res=$1-($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed "s%$ltm%$x $y $nz $s1 $s2 $s3%" $file > POSCAR.001 +nz=`echo $z $deltaC $clen | awk '{ + res=$1+($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed -i "$addline a\ +$x $y $nz T T T" POSCAR.001 + +echo "0-10:" +ny=`echo $y $deltaSi $clen | awk '{ + res=$1+($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed "s%$ltm%$x $ny $z $s1 $s2 $s3%" $file > POSCAR.0-10 +ny=`echo $y $deltaC $clen | awk '{ + res=$1-($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed -i "$addline a\ +$x $ny $z T T T" POSCAR.0-10 + +echo "010:" +ny=`echo $y $deltaSi $clen | awk '{ + res=$1-($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed "s%$ltm%$x $ny $z $s1 $s2 $s3%" $file > POSCAR.010 +ny=`echo $y $deltaC $clen | awk '{ + res=$1+($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed -i "$addline a\ +$x $ny $z T T T" POSCAR.010 + +echo "-100:" +nx=`echo $x $deltaSi $clen | awk '{ + res=$1+($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed "s%$ltm%$nx $y $z $s1 $s2 $s3%" $file > POSCAR.-100 +nx=`echo $x $deltaC $clen | awk '{ + res=$1-($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed -i "$addline a\ +$nx $y $z T T T" POSCAR.-100 + +echo "100:" +nx=`echo $x $deltaSi $clen | awk '{ + res=$1-($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed "s%$ltm%$nx $y $z $s1 $s2 $s3%" $file > POSCAR.100 +nx=`echo $x $deltaC $clen | awk '{ + res=$1+($2/$3) + if(res>1.0) print res-1.0 + else if(res<0.0) print res+1.0 + else print res +}'` +sed -i "$addline a\ +$nx $y $z T T T" POSCAR.100 + diff --git a/vasp_tools/create_intf_crude b/vasp_tools/create_intf_crude new file mode 100755 index 0000000..f5e0c3d --- /dev/null +++ b/vasp_tools/create_intf_crude @@ -0,0 +1,69 @@ +#!/bin/bash + +si_file=$1 +sic_file=$2 + +cnt_si_si=`sed -n 6p $si_file` +cnt_si_sic=`sed -n 6p $sic_file | awk '{ print $1 }'` +cnt_c_sic=`sed -n 6p $sic_file | awk '{ print $2 }'` + +lc_si=`sed -n 2p $si_file` + +x_si=`sed -n 3p $si_file | awk '{ print $1 }'` +x_sic=`sed -n 3p $sic_file | awk '{ print $1 }'` + +h_si=`sed -n 5p $si_file | awk '{ print $3 }'` +h_sic=`sed -n 5p $sic_file | awk '{ print $3 }'` +h_sic=`echo $h_sic $x_si $x_sic | awk '{ print $1*$2/$3 }'` + +((tot_si=cnt_si_si+cnt_si_sic)) + +h_tot=`echo $h_si + $h_sic | bc` + +((offset=8)) + +# header: +sed -n 1,4p $si_file +echo " 0.00000 0.00000 $h_tot" +echo " $tot_si $cnt_c_sic" +sed -n 7,8p $si_file + +# silicon atoms of si lattice (bottom) +((cnt=1)) +while [ $cnt -le $cnt_si_si ]; do + ((gl=cnt+offset)) + line=`sed -n ${gl}p $si_file` + x=`echo $line | awk '{ print $1 }'` + y=`echo $line | awk '{ print $2 }'` + z=`echo $line | awk '{ print $3 }'` + nz=`echo $z $h_tot $h_si | awk '{ print $1*$3/$2 }'` + echo " $x $y $nz T T T" + ((cnt+=1)) +done + +# silicon atoms of sic lattice (top / 2nd fcc) +((cnt=1)) +while [ $cnt -le $cnt_si_sic ]; do + ((gl=cnt+offset+cnt_c_sic)) + line=`sed -n ${gl}p $sic_file` + x=`echo $line | awk '{ print $1 }'` + y=`echo $line | awk '{ print $2 }'` + z=`echo $line | awk '{ print $3 }'` + nz=`echo $z $h_tot $h_si $h_sic | awk '{ print $1*$4/$2 + $3/$2 }'` + echo " $x $y $nz T T T" + ((cnt+=1)) +done + +# carbon atoms of sic lattice (top / 1st fcc <- odd counts) +((cnt=1)) +while [ $cnt -le $cnt_c_sic ]; do + ((gl=cnt+offset)) + line=`sed -n ${gl}p $sic_file` + x=`echo $line | awk '{ print $1 }'` + y=`echo $line | awk '{ print $2 }'` + z=`echo $line | awk '{ print $3 }'` + nz=`echo $z $h_tot $h_si $h_sic | awk '{ print $1*$4/$2 + $3/$2 }'` + echo " $x $y $nz T T T" + ((cnt+=1)) +done + diff --git a/vasp_tools/create_lattice.c b/vasp_tools/create_lattice.c new file mode 100644 index 0000000..658fdb4 --- /dev/null +++ b/vasp_tools/create_lattice.c @@ -0,0 +1,243 @@ +/* + * create lattice (for usage in vasp POSCAR file) + * + * author: Frank Zirkelbach + * + */ + +#include +#include +#include +#include +#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;i1.0) + x-=1.0; + if(x<-1.0) + x+=1.0; + y=$2*Y + if(y>1.0) + y-=1.0; + if(y<-1.0) + y+=1.0; + z=$3*Z + if(z>1.0) + z-=1.0; + if(z<-1.0) + z+=1.0; + + print x*$4 " " y*$4 " " z*$4 + }'` + +xf=`echo $results | awk '{ print $1 }'` +yf=`echo $results | awk '{ print $2 }'` +zf=`echo $results | awk '{ print $3 }'` +echo "---> $xf $yf $zf" + +file=$init + +scale=`sed -n 2p $file` + +X1=`sed -n 3p $file | awk '{ print $1 }'` +X2=`sed -n 3p $file | awk '{ print $2 }'` +X3=`sed -n 3p $file | awk '{ print $3 }'` + +Y1=`sed -n 4p $file | awk '{ print $1 }'` +Y2=`sed -n 4p $file | awk '{ print $2 }'` +Y3=`sed -n 4p $file | awk '{ print $3 }'` + +Z1=`sed -n 5p $file | awk '{ print $1 }'` +Z2=`sed -n 5p $file | awk '{ print $2 }'` +Z3=`sed -n 5p $file | awk '{ print $3 }'` + +export X1 X2 X3 +export Y1 Y2 Y3 +export Z1 Z2 Z3 + +((offset=8)) + +echo +echo "initial:" +echo "scale: $scale" +echo "X: $X1 $X2 $X3" +echo "Y: $Y1 $Y2 $Y3" +echo "Z: $Z1 $Z2 $Z3" + +((line1=ref+offset)) + +temp="`sed -n ${line1}p $file`" +xa=`echo $temp | awk '{ print $1 }'` +ya=`echo $temp | awk '{ print $2 }'` +za=`echo $temp | awk '{ print $3 }'` +echo "(x,y,z) = $xa $ya $za $scale" + +results=`echo "$xa $ya $za $scale" | \ + awk ' \ + BEGIN { + X1=ENVIRON["X1"]; X2=ENVIRON["X2"]; X3=ENVIRON["X3"] + Y1=ENVIRON["Y1"]; Y2=ENVIRON["Y2"]; Y3=ENVIRON["Y3"] + Z1=ENVIRON["Z1"]; Z2=ENVIRON["Z2"]; Z3=ENVIRON["Z3"] + } + { + X=sqrt(X1^2+X2^2+X3^2) + Y=sqrt(Y1^2+Y2^2+Y3^2) + Z=sqrt(Z1^2+Z2^2+Z3^2) + x=$1*X + if(x>1.0) + x-=1.0; + if(x<-1.0) + x+=1.0; + y=$2*Y + if(y>1.0) + y-=1.0; + if(y<-1.0) + y+=1.0; + z=$3*Z + if(z>1.0) + z-=1.0; + if(z<-1.0) + z+=1.0; + + print x*$4 " " y*$4 " " z*$4 + }'` + +xi=`echo $results | awk '{ print $1 }'` +yi=`echo $results | awk '{ print $2 }'` +zi=`echo $results | awk '{ print $3 }'` +echo "---> $xi $yi $zi" + +echo +echo -en "displacement: " +echo $xf $yf $zf $xi $yi $zi | awk '{ print $1-$4 " " $2-$5 " " $3-$6 }' +echo + diff --git a/vasp_tools/dist_calc b/vasp_tools/dist_calc new file mode 100755 index 0000000..b397053 --- /dev/null +++ b/vasp_tools/dist_calc @@ -0,0 +1,88 @@ +#!/bin/bash + +file=$1 +atom=$2 +btom=$3 + +scale=`sed -n 2p $1` + +X1=`sed -n 3p $file | awk '{ print $1 }'` +X2=`sed -n 3p $file | awk '{ print $2 }'` +X3=`sed -n 3p $file | awk '{ print $3 }'` + +Y1=`sed -n 4p $file | awk '{ print $1 }'` +Y2=`sed -n 4p $file | awk '{ print $2 }'` +Y3=`sed -n 4p $file | awk '{ print $3 }'` + +Z1=`sed -n 5p $file | awk '{ print $1 }'` +Z2=`sed -n 5p $file | awk '{ print $2 }'` +Z3=`sed -n 5p $file | awk '{ print $3 }'` + +export X1 X2 X3 +export Y1 Y2 Y3 +export Z1 Z2 Z3 + +((offset=8)) + +echo "scale: $scale" +echo "X: $X1 $X2 $X3" +echo "Y: $Y1 $Y2 $Y3" +echo "Z: $Z1 $Z2 $Z3" +echo + +((line1=atom+offset)) +((line2=btom+offset)) + +temp="`sed -n ${line1}p $1`" +xa=`echo $temp | awk '{ print $1 }'` +ya=`echo $temp | awk '{ print $2 }'` +za=`echo $temp | awk '{ print $3 }'` + +echo "atom 1:" +echo $temp + +temp="`sed -n ${line2}p $1`" +xb=`echo $temp | awk '{ print $1 }'` +yb=`echo $temp | awk '{ print $2 }'` +zb=`echo $temp | awk '{ print $3 }'` + +echo "atom 2:" +echo $temp + +echo -en "distance: " +echo "$xa $ya $za $xb $yb $zb $scale" | \ + awk ' \ + BEGIN { + X1=ENVIRON["X1"]; X2=ENVIRON["X2"]; X3=ENVIRON["X3"] + Y1=ENVIRON["Y1"]; Y2=ENVIRON["Y2"]; Y3=ENVIRON["Y3"] + Z1=ENVIRON["Z1"]; Z2=ENVIRON["Z2"]; Z3=ENVIRON["Z3"] + } + { + X=sqrt(X1^2+X2^2+X3^2) + Y=sqrt(Y1^2+Y2^2+Y3^2) + Z=sqrt(Z1^2+Z2^2+Z3^2) + dx=$1-$4 + dy=$2-$5 + dz=$3-$6 + if(dx>1/2) + dx-=1 + if(dx<-1/2) + dx+=1 + if(dy>1/2) + dy-=1 + if(dy<-1/2) + dy+=1 + if(dz>1/2) + dz-=1 + if(dz<-1/2) + dz+=1 + dxt=dx*X1+dy*Y1+dz*Z1 + dyt=dx*X2+dy*Y2+dz*Z2 + dzt=dx*X3+dy*Y3+dz*Z3 + dist=sqrt(dxt^2+dyt^2+dzt^2) + dist*=$7 + print dist + }' + +echo + diff --git a/vasp_tools/e_coh b/vasp_tools/e_coh new file mode 100755 index 0000000..f32283f --- /dev/null +++ b/vasp_tools/e_coh @@ -0,0 +1,81 @@ +#!/bin/bash + +file=$1 + +[ -d $1 ] && file=$1/OUTCAR + +echo "parsing file $file ..." + +sicnt=`grep 'ions per' $file | awk '{ print $5 }'` +ccnt=`grep 'ions per' $file | awk '{ print $6 }'` +[ -z $ccnt ] && ccnt=0 +((total=sicnt+ccnt)) +echo " Si: $sicnt, C: $ccnt, total: $total" + +cutoff=`grep ENCUT $file | awk '{ print $3 }' | awk -F. '{ print $1 }'` +echo " cutoff: $cutoff eV" + +pawpp=`grep POTCAR $file | tail -1 | awk '{ print $2 }'` +if [ "$pawpp" = "PAW_GGA" ]; then + ext=_paw_gga + echo " GGA and PAW" +fi +if [ "$pawpp" = "PAW" ]; then + ext=_paw + echo " LDA and PAW" +fi +if [ "$pawpp" = "US" ]; then + help=`grep GGA $file | grep eV | tail -1 | awk '{ print $1i }'` + if [ -z $help ]; then + ext=_gga + echo " GGA and PP" + else + ext="" + echo " LDA and PP" + fi +fi + +cnt=0 +tcnt=0 + +energy=`grep energy\ without $file | tail -1 | awk '{ print $8 }'` + +sifile=free_atoms/si_free_${cutoff}${ext}/OUTCAR +cfile=free_atoms/c_free_${cutoff}${ext}/OUTCAR + +if [ ! -f $sifile ]; then + echo + echo "$sifile not found ..." + echo + exit +fi + +if [ ! -f $cfile ]; then + echo + echo "$cfile not found ..." + echo + exit +fi + +free_si=`grep energy\ without $sifile | tail -1 | awk '{ print $8 }'` +free_c=`grep energy\ without $cfile | tail -1 | awk '{ print $8 }'` +echo " Si correction: $free_si eV, C correction: $free_c eV" + +#echo "-> $energy | $total | $sicnt | $ccnt | $free_si | $free_c <-" +echo $energy $total | \ + awk '{ print " total e: " $1 " eV, per atom: " $1/$2 " eV"}' +echo "$energy $sicnt $ccnt $free_si $free_c" | \ + awk '{ print " cohesive energy (Si and C): " ($1-$2*$4-$3*$5)/($2+$3) " eV, " $1-$2*$4-$3*$5 " eV" }' +echo "$energy $sicnt $free_c" | \ + awk '{ print " cohesive energy (C only): " ($1-$2*$3)/$2 " eV, " $1-$2*$3 " eV" }' +#echo "$energy $total $free_si_250" | \ +# awk '{ print " cohesive energy (Si only 250): " ($1-$2*$3)/$2 " eV" }' +#echo "$energy $sicnt $free_c_650" | \ +# awk '{ print " cohesive energy (C only 650): " ($1-$2*$3)/($2) " eV" }' +#echo "$energy $sicnt $ccnt $free_si_650 $free_c_650" | \ +# awk '{ print " cohesive energy (Si and C 650): " ($1-$2*$4-$3*$5)/($2+$3) " eV" }' +#echo "$energy $total" | \ +# awk '{ print " Si:C -> cohesive energy: "$1/$2 " eV" }' + +echo + diff --git a/vasp_tools/e_f b/vasp_tools/e_f new file mode 100755 index 0000000..877f66c --- /dev/null +++ b/vasp_tools/e_f @@ -0,0 +1,11 @@ +#!/bin/bash + +ready=`grep General\ timing $1/OUTCAR | awk '{ print $1 }'` + +if [ "$ready" = "General" ]; then + echo "$i seems to be finisched ..." +./e_form plain_si_2333_nosym_sp plain_c_2333_nosym_sp $1 +else + echo "$i not yet finished ..." +fi + diff --git a/vasp_tools/e_f_tersoff b/vasp_tools/e_f_tersoff new file mode 100755 index 0000000..ef75640 --- /dev/null +++ b/vasp_tools/e_f_tersoff @@ -0,0 +1,22 @@ +#!/bin/bash + +ready=`grep General\ timing $1/OUTCAR | awk '{ print $1 }'` + +default="plain_si_2333_nosym_sp plain_sic_2333_nosym_sp" + +test=`echo $1 | awk -F_ '{ print $3 }'` + +if [ -d plain_si_${test}_nosym_sp ]; then + [ -d plain_sic_${test}_nosym_sp ] && \ + default="plain_si_${test}_nosym_sp plain_sic_${test}_nosym_sp" +fi + +if [ "$ready" = "General" ]; then + echo "$i seems to be finisched ..." + echo "reference: $default" +#./e_form_tersoff plain_si_2333_nosym_sp plain_sic_2333_nosym_sp $1 +./e_form_tersoff $default $1 +else + echo "$i not yet finished ..." +fi + diff --git a/vasp_tools/e_fc b/vasp_tools/e_fc new file mode 100755 index 0000000..af24d00 --- /dev/null +++ b/vasp_tools/e_fc @@ -0,0 +1,47 @@ +#!/bin/bash + +ready=`grep General\ timing $1/OUTCAR | awk '{ print $1 }'` + +if [ "$ready" = "General" ]; then + echo "$i seems to be finisched ..." + +e=`./e_form plain_si_2333_nosym_sp plain_c_2333_nosym_sp $1 | grep M2 | \ + awk '{ print $4 }'` +echo "E_f = $e" + +ec100=3.15438 +r=`echo $e $ec100 $ec100 | awk '{ print $1-$2-$3 }'` +echo "C 100: $r" + +ec110=3.59738 +r=`echo $e $ec100 $ec110 | awk '{ print $1-$2-$3 }'` +echo "C 110: $r" + +ecsub=1.38891 +r=`echo $e $ec100 $ecsub | awk '{ print $1-$2-$3 }'` +echo "C sub: $r" + +ecbc=4.09638 +r=`echo $e $ec100 $ecbc | awk '{ print $1-$2-$3 }'` +echo "C bc: $r" + +esvac=3.62905 +r=`echo $e $ec100 $esvac | awk '{ print $1-$2-$3 }'` +echo "Si vac: $r" + +es110=3.38999 +r=`echo $e $ec100 $es110 | awk '{ print $1-$2-$3 }'` +echo "Si 110: $r" + +estet=3.76899 +r=`echo $e $ec100 $estet | awk '{ print $1-$2-$3 }'` +echo "Si tet: $r" + +eshex=3.41999 +r=`echo $e $ec100 $eshex | awk '{ print $1-$2-$3 }'` +echo "Si hex: $r" + +else + echo "$i not yet finished ..." +fi + diff --git a/vasp_tools/e_fc_tersoff b/vasp_tools/e_fc_tersoff new file mode 100755 index 0000000..4e8b74c --- /dev/null +++ b/vasp_tools/e_fc_tersoff @@ -0,0 +1,53 @@ +#!/bin/bash + +ready=`grep General\ timing $1/OUTCAR | awk '{ print $1 }'` + +if [ "$ready" = "General" ]; then + echo "$i seems to be finisched ..." + +e=`./e_form_tersoff plain_si_2333_nosym_sp plain_sic_2333_nosym_sp $1 | grep M2 | \ + awk '{ print $4 }'` +echo "E_f = $e" + +ec100=3.72027 +r=`echo $e $ec100 $ec100 | awk '{ print $1-$2-$3 }'` +echo "C 100: $r" + +ec110=4.16327 +r=`echo $e $ec100 $ec110 | awk '{ print $1-$2-$3 }'` +echo "C 110: $r" + +ecsub=1.9548 +r=`echo $e $ec100 $ecsub | awk '{ print $1-$2-$3 }'` +echo "C sub: $r" + +ecbc=4.66227 +r=`echo $e $ec100 $ecbc | awk '{ print $1-$2-$3 }'` +echo "C bc: $r" + +esvac=3.62905 +r=`echo $e $ec100 $esvac | awk '{ print $1-$2-$3 }'` +echo "Si vac: $r" + +es110=3.38999 +r=`echo $e $ec100 $es110 | awk '{ print $1-$2-$3 }'` +echo "Si 110: $r" + +estet=3.76899 +r=`echo $e $ec100 $estet | awk '{ print $1-$2-$3 }'` +echo "Si tet: $r" + +eshex=3.41999 +r=`echo $e $ec100 $eshex | awk '{ print $1-$2-$3 }'` +echo "Si hex: $r" + +r=`echo $e $es110 $ecsub | awk '{ print $1-$2-$3 }'` +echo "Si 110 and C sub: $r" + +r=`echo $e $estet $ecsub | awk '{ print $1-$2-$3 }'` +echo "Si tet and C sub: $r" + +else + echo "$i not yet finished ..." +fi + diff --git a/vasp_tools/e_form b/vasp_tools/e_form new file mode 100755 index 0000000..7c9e490 --- /dev/null +++ b/vasp_tools/e_form @@ -0,0 +1,46 @@ +#!/bin/bash + + +if [ $# = 2 ]; then + +echo "Calculation of formation energy (Method 1, single species)" +echo " Result: `basename $2`, Initial conf: `basename $1`" +echo + +e1only=`./e_coh $1 | grep cohesive | grep only | awk '{ print $5 }'` +e2only=`./e_coh $2 | grep cohesive | grep only | awk '{ print $5 }'` +e1and=`./e_coh $1 | grep cohesive | grep and | awk '{ print $6 }'` +e2and=`./e_coh $2 | grep cohesive | grep and | awk '{ print $6 }'` +count=`./e_coh $2 | grep ^\ \ Si: | awk '{ print $6 }'` + +echo "$e1only $e2only $count" | \ + awk '{ print " formation energy M1 (Si and C): "($2-$1)*$3 " eV" }' +echo "$e1and $e2and $count" | \ + awk '{ print " formation energy M1 (C only): "($2-$1)*$3 " eV" }' +echo + +fi + +if [ $# = 3 ]; then + +echo "Calculation of formation energy (Method 2, two species)" + +e3=`./e_coh $3 | grep cohesive | grep and | awk '{ print $6 }'` +sicnt=`./e_coh $3 | grep ^\ \ Si: | awk '{ print $2 }' | sed 's/,//'` +ccnt=`./e_coh $3 | grep ^\ \ Si: | awk '{ print $4 }' | sed 's/,//'` +et=`echo $e3 $sicnt $ccnt | awk '{ print $1*($2+$3) }'` +echo " Interstitial configuration: `basename $3` -> $et" +e1=`./e_coh $1 | grep cohesive | grep and | awk '{ print $6 }'` +e2=`./e_coh $2 | grep cohesive | grep only | awk '{ print $5 }'` +echo " Cohesive energies:" +echo " `basename $1` -> $e1 ($sicnt)" +echo " `basename $2` -> $e2 ($ccnt)" + +((count = sicnt + ccnt)) + +echo "$et $sicnt $e1 $ccnt $e2" | \ + awk '{ print " formation energy M2: "$1-$2*$3-$4*$5 " eV" }' +echo + +fi + diff --git a/vasp_tools/e_form_tersoff b/vasp_tools/e_form_tersoff new file mode 100755 index 0000000..9cbb5d2 --- /dev/null +++ b/vasp_tools/e_form_tersoff @@ -0,0 +1,35 @@ +#!/bin/bash + + +if [ $# = 2 ]; then + +echo "unsupported ..." + +fi + +if [ $# = 3 ]; then + +echo "Calculation of formation energy (Method 2, two species)" + +e3=`./e_coh $3 | grep cohesive | grep and | awk '{ print $6 }'` +sicnt=`./e_coh $3 | grep ^\ \ Si: | awk '{ print $2 }' | sed 's/,//'` +ccnt=`./e_coh $3 | grep ^\ \ Si: | awk '{ print $4 }' | sed 's/,//'` +et=`echo $e3 $sicnt $ccnt | awk '{ print $1*($2+$3) }'` +echo " Interstitial configuration: `basename $3` -> $et" +e1=`./e_coh $1 | grep cohesive | grep and | awk '{ print $6 }'` +e2=`./e_coh $2 | grep cohesive | grep and | awk '{ print $6 }'` +emuc=`echo $e2 $e1 | awk '{ print 2*$1-$2 }'` +echo " Cohesive energies:" +echo " `basename $1` -> $e1 ($sicnt)" +echo " `basename $2` -> $emuc / $e2 ($ccnt)" + +((count = sicnt + ccnt)) + +#echo "$et $sicnt $e1 $ccnt $emuc" | \ +# awk '{ print " formation energy M2: "$1-$2*$3-$4*$5 " eV" }' +echo "$et $sicnt $e1 $ccnt $e2" | \ + awk '{ print " formation energy M2: "$1-($2-$4)*$3-$4*$5*2 " eV" }' +echo + +fi + diff --git a/vasp_tools/get_ks_levels b/vasp_tools/get_ks_levels new file mode 100755 index 0000000..8ef690e --- /dev/null +++ b/vasp_tools/get_ks_levels @@ -0,0 +1,123 @@ +#!/bin/bash + +# get the kohn sham levels (plotted nicely) + +# spin component 1 + +file=$1/OUTCAR + +WUP=1.2 +WDOWN=1.8 +PS=2 +OPT=7 +UPT=4 + +if [ ! -f $file ]; then + echo "no OUTCAR file found ..." + exit +fi + +rm -f $1/ks_levels_* + +center="0" + +cntup=0 +echo $cntup > $1/temp_cu +fup=0 +echo $fup > $1/temp_fu +cntdown=0 +echo $cntdown > $1/temp_cd +fdown=0 +echo $fdown > $1/temp_fd + +# spin component 1 +startline=`grep -n spin\ component\ 1 $file | tail -1 | awk -F: '{ print $1 }'` +echo -en "spin component 1 ($startline)... " +sed -n "$startline,/spin component 2/p" $file | grep ^' '*[0-9] | \ + while read number energy occu; do + if [ "$occu" = "1.00000" ]; then + echo "0.18 $energy 0.1" >> $1/ks_levels_o + cntup=`cat $1/temp_cu` + ((cntup+=1)) + echo $cntup > $1/temp_cu + elif [ "$occu" = "0.00000" ]; then + echo "0.18 $energy 0.1" >> $1/ks_levels_u + else + echo "0.18 $energy 0.1" >> $1/ks_levels_p + fup=`cat $1/temp_fu` + fup=`echo $fup $occu | awk '{ print $1+$2 }'` + echo $fup > $1/temp_fu + fi + done +echo "done" + +# spin component 2 +startline=`grep -n spin\ component\ 2 $file | tail -1 | awk -F: '{ print $1 }'` +echo -en "spin component 2 ($startline) ... " +sed -n "$startline,/---/p" $file | grep ^' '*[0-9] | \ + while read number energy occu; do + if [ "$occu" = "1.00000" ]; then + echo "0.42 $energy 0.1" >> $1/ks_levels_o + cntdown=`cat $1/temp_cd` + ((cntdown+=1)) + echo $cntdown > $1/temp_cd + elif [ "$occu" = "0.00000" ]; then + if [ "$center" = "0" ]; then + echo -en "setting mid value -> $energy ... " + center=$energy + echo "$energy" > $1/temp_e + fi + echo "0.42 $energy 0.1" >> $1/ks_levels_u + else + echo "0.42 $energy 0.1" >> $1/ks_levels_p + fdown=`cat $1/temp_fd` + fdown=`echo $fdown $occu | awk '{ print $1+$2 }'` + echo $fdown > $1/temp_fd + fi + done +echo "done" + +cntup=`cat $1/temp_cu` +fup=`cat $1/temp_fu` +cntdown=`cat $1/temp_cd` +fdown=`cat $1/temp_fd` +center=`cat $1/temp_e` +yl=`echo $center $WDOWN | awk '{ print $1-$2 }'` +yh=`echo $center $WUP | awk '{ print $1+$2 }'` +fup=`awk -v var=$fup 'BEGIN{ printf"%0.f\n", var }'` +fdown=`awk -v var=$fdown 'BEGIN{ printf"%0.f\n", var }'` +((cntup+=fup)) +((cntdown+=fdown)) +((difference=cntup-cntdown)) +echo "generating gnuplot file ($center, $yl, $yh, $ly) ..." +cat > $1/ksl_plot.gpi < $dir/POSCAR + sed -n 2p 00/POSCAR >> $dir/POSCAR + echo $x1 $X1 $x2 $X2 $x3 $X3 $cnt $fin| awk '{ + ratio=$7/$8 + print " " $1+($2-$1)*ratio " " $3+($4-$3)*ratio " " $5+($6-$5)*ratio + }' >> $dir/POSCAR + echo $y1 $Y1 $y2 $Y2 $y3 $Y3 $cnt $fin| awk '{ + ratio=$7/$8 + print " " $1+($2-$1)*ratio " " $3+($4-$3)*ratio " " $5+($6-$5)*ratio + }' >> $dir/POSCAR + echo $z1 $Z1 $z2 $Z2 $z3 $Z3 $cnt $fin| awk '{ + ratio=$7/$8 + print " " $1+($2-$1)*ratio " " $3+($4-$3)*ratio " " $5+($6-$5)*ratio + }' >> $dir/POSCAR + sed -n 6p 00/POSCAR >> $dir/POSCAR + sed -n 7p 00/POSCAR >> $dir/POSCAR + sed -n 8p 00/POSCAR >> $dir/POSCAR + ((cnt+=1)) +done + +((acnt=1)) + +while [ $acnt -le $tot ]; do + ((cnt=1)) + ((ltg=acnt+offset)) + x=`sed -n ${ltg}p 00/POSCAR | awk '{ print $1 }'` + X=`sed -n ${ltg}p $fdir/POSCAR | awk '{ print $1 }'` + y=`sed -n ${ltg}p 00/POSCAR | awk '{ print $2 }'` + Y=`sed -n ${ltg}p $fdir/POSCAR | awk '{ print $2 }'` + z=`sed -n ${ltg}p 00/POSCAR | awk '{ print $3 }'` + Z=`sed -n ${ltg}p $fdir/POSCAR | awk '{ print $3 }'` + while [ $cnt -lt $fin ]; do + dir=`printf "%02d" $cnt` + echo $x $X $y $Y $z $Z $cnt $fin| awk '{ + ratio=$7/$8 + print " " $1+($2-$1)*ratio " " $3+($4-$3)*ratio " " $5+($6-$5)*ratio " T T T" + }' >> $dir/POSCAR + ((cnt+=1)) + done + ((acnt+=1)) +done + diff --git a/vasp_tools/lastxyz2video b/vasp_tools/lastxyz2video new file mode 100755 index 0000000..f2f3142 --- /dev/null +++ b/vasp_tools/lastxyz2video @@ -0,0 +1,15 @@ +#!/bin/bash + +if [ -d video ]; then + echo "moving video directory ..." + mv -v video v_tmp +fi + +mkdir video + +for i in video.??; do + cp -v `ls $i/atomic_conf*.xyz | tail -1` \ + video/atomic_conf_`echo $i | awk -F. '{ print $2 }'`.xyz; +done + +echo "done" diff --git a/vasp_tools/mig_calc b/vasp_tools/mig_calc new file mode 100755 index 0000000..506fdae --- /dev/null +++ b/vasp_tools/mig_calc @@ -0,0 +1,48 @@ +#!/bin/bash + +if [ ! -d $1 ] ; then + echo "no valid dir" + exit +fi + +last="" +rc=0.0 + +for i in $1/OUTCAR.*; do + index=`echo $i | awk -F. '{ print $2 }'` + if [ ! -f $1/CONTCAR.${index} ] ; then + echo "no such file: CONTCAR.${index}" + exit + else + cfile=$1/CONTCAR.${index} + fi + if [ -z $last ]; then + last=$cfile + lst=$index + fi + + acnt=`sed -n 6p $cfile | awk '{ print $1 }'` + ((acnt+=9)) + ((lcnt=9)) + + while [ $lcnt -le $acnt ]; do + line="`sed -n ${lcnt}p $cfile`" + x1=`echo $line | awk '{ print $1 }'` + x2=`echo $line | awk '{ print $2 }'` + x3=`echo $line | awk '{ print $3 }'` + line="`sed -n ${lcnt}p $last`" + y1=`echo $line | awk '{ print $1 }'` + y2=`echo $line | awk '{ print $2 }'` + y3=`echo $line | awk '{ print $3 }'` + rc=`echo $rc $x1 $x2 $x3 $y1 $y2 $y3 |\ + awk '{ print $1+sqrt(($2-$5)^2+($3-$6)^2+($4-$7)^2) }'` + ((lcnt+=1)) + done + + energy=`./e_coh $i | grep Si\ and\ C | awk '{ print $8 }'` + + echo "$rc $energy" + + last=$cfile + lst=$index +done diff --git a/vasp_tools/mig_fullct.sh b/vasp_tools/mig_fullct.sh new file mode 100755 index 0000000..43f2e82 --- /dev/null +++ b/vasp_tools/mig_fullct.sh @@ -0,0 +1,101 @@ +#!/bin/bash + +# migration + +if [ ! -f POSCAR.init ]; then + echo "no initial configuration file, aborting ..." + exit +fi + +if [ ! -f POSCAR.final ]; then + echo "no final configuration file, aborting ..." + exit +fi + +echo "Info:" +echo $LANG +bash --version +echo +echo + +((steps=10)) +((count=1)) +((offset=8)) + +while [ $count -le $steps ]; do + + cnt=`printf "%02d" $count` + + # create the POSCAR file + if [ $count -eq 1 ]; then + cp -v POSCAR.init CONTCAR + fi + + srcfile=CONTCAR + sed -n 1,6p $srcfile > POSCAR + echo "Transformed selective dynamics" >> POSCAR + echo "Direct" >> POSCAR + sicnt=`sed -n 6p $srcfile | awk '{ print $1 }'` + ccnt=`sed -n 6p $srcfile | awk '{ print $2 }'` + ((tot=sicnt+ccnt)) + + ((acnt=1)) + while [ $acnt -le $tot ]; do + ((lcnt=acnt+offset)) + line="`sed -n ${lcnt}p $srcfile`" + xo=`echo $line | awk '{ print $1 }'` + yo=`echo $line | awk '{ print $2 }'` + zo=`echo $line | awk '{ print $3 }'` + line="`sed -n ${lcnt}p POSCAR.final`" + xn=`echo $line | awk '{ print $1 }'` + yn=`echo $line | awk '{ print $2 }'` + zn=`echo $line | awk '{ print $3 }'` + + echo "$xo $yo $zo $xn $yn $zn $count $steps" | awk '{ + if($1<0) xo=$1+1.0 + else xo=$1 + if($2<0) yo=$2+1.0 + else yo=$2 + if($3<0) zo=$3+1.0 + else zo=$3 + if($4<0) xn=$4+1.0 + else xn=$4 + if($5<0) yn=$5+1.0 + else yn=$5 + if($6<0) zn=$6+1.0 + else zn=$6 + dx=xn-xo + if(dx>0.5) dx-=1.0; + if(dx<-0.5) dx+=1.0; + dy=yn-yo + if(dy>0.5) dy-=1.0; + if(dy<-0.5) dy+=1.0; + dz=zn-zo + if(dz>0.5) dz-=1.0; + if(dz<-0.5) dz+=1.0; + zrot=180.0*atan2(dx,dy)/3.14159265 + xrot=-180.0*atan2(dz,sqrt(dx^2+dy^2))/3.14159265 + frac=1.0/($8-$7+1) + x=xo+dx*frac + y=yo+dy*frac + z=zo+dz*frac + print " " x " " y " " z " T F T " zrot " " xrot + }' >> POSCAR + + ((acnt+=1)) + done + + echo + echo + echo "run simulation $cnt ..." + echo + echo + ../vasp.4.6-gamma-fullct/vasp + + cp -v POSCAR POSCAR.${cnt} + cp -v CONTCAR CONTCAR.${cnt} + cp -v OUTCAR OUTCAR.${cnt} + + ((count+=1)) +done + diff --git a/vasp_tools/o_init2moldyn b/vasp_tools/o_init2moldyn new file mode 100755 index 0000000..837712e --- /dev/null +++ b/vasp_tools/o_init2moldyn @@ -0,0 +1,56 @@ +#!/bin/bash + +for i in OUTCAR*; do + app=`echo $i | awk -F. '{ print $2 }'` + [ ! -z $app ] && app=".$app" + +rm -rf video$app +mkdir -p video$app + +sicnt=`grep 'ions per' $i | awk '{ print $5 }'` +ccnt=`grep 'ions per' $i | awk '{ print $6 }'` + +((total=sicnt+ccnt)) + +echo "parsing file $PWD/$i ..." +echo " Si: $sicnt, C: $ccnt, total: $total" + +cnt=0 +tcnt=0 + +cx=1.0 +cy=1.0 +cz=0.8 + +sed -n -e '/ position of ions in cartesian/,/----/p' $i | \ + grep -v POS | grep -v total | grep -v -- ^\ - | \ + while read x y z; do + + time=`printf "%05d" $tcnt` + #echo -en "$tcnt/$cnt " + [ "$cnt" = "0" ] && \ + echo "# P $total $time <$cx,$cy,$cz>" > \ + video$app/atomic_conf_$time.xyz + + type="Si" + color="Yellow" + force=0.0 + if [ $cnt -ge $sicnt ]; then + type="C" + color="Gray" + fi + echo "$type $x $y $z $color $force" >> \ + video$app/atomic_conf_$time.xyz + + ((cnt+=1)) + if [ $cnt -eq $total ]; then + cnt=0 + ((tcnt+=1)) + echo -en "$tcnt " + fi +done + +echo + +done + diff --git a/vasp_tools/outcar2moldyn b/vasp_tools/outcar2moldyn new file mode 100755 index 0000000..6950453 --- /dev/null +++ b/vasp_tools/outcar2moldyn @@ -0,0 +1,64 @@ +#!/bin/bash + +for i in OUTCAR*; do + app=`echo $i | awk -F. '{ print $2 }'` + [ ! -z $app ] && app=".$app" + +if [ "$1" = "renew" ]; then + rm -rf video$app +fi + +if [ -d video$app ]; then + echo "skipping $app ... (use $0 renew to force rebuild)" + continue +fi + +mkdir -p video$app + +sicnt=`grep 'ions per' $i | awk '{ print $5 }'` +ccnt=`grep 'ions per' $i | awk '{ print $6 }'` + +((total=sicnt+ccnt)) + +echo "parsing file $PWD/$i ..." +echo " Si: $sicnt, C: $ccnt, total: $total" + +cnt=0 +tcnt=0 + +cx=1.0 +cy=1.0 +cz=0.8 + +sed -n -e '/POSITION/,/total/p' $i | \ + grep -v POS | grep -v total | grep -v -- ^\ - | \ + while read x y z fx fy fz; do + + time=`printf "%05d" $tcnt` + #echo -en "$tcnt/$cnt " + [ "$cnt" = "0" ] && \ + echo "# P $total $time <$cx,$cy,$cz>" > \ + video$app/atomic_conf_$time.xyz + + type="Si" + color="Yellow" + force=`echo "sqrt($fx*$fx+$fy*$fy+$fz*$fz)" | bc` + if [ $cnt -ge $sicnt ]; then + type="C" + color="Gray" + fi + echo "$type $x $y $z $color $force" >> \ + video$app/atomic_conf_$time.xyz + + ((cnt+=1)) + if [ $cnt -eq $total ]; then + cnt=0 + ((tcnt+=1)) + echo -en "$tcnt " + fi +done + +echo + +done + diff --git a/vasp_tools/pc_calc.c b/vasp_tools/pc_calc.c new file mode 100644 index 0000000..db12f50 --- /dev/null +++ b/vasp_tools/pc_calc.c @@ -0,0 +1,276 @@ +/* + * pc_calc.c - calculate the pc + * + * author: frank.zirkelbach@physik.uni-augsburg.de + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + + +#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 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(count0.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 $1/pc${app}.txt + +echo "done, pc stored in $1/pc_${app}.txt" + diff --git a/vasp_tools/poscar2moldyn b/vasp_tools/poscar2moldyn new file mode 100755 index 0000000..a4f2562 --- /dev/null +++ b/vasp_tools/poscar2moldyn @@ -0,0 +1,73 @@ +#!/bin/bash + +mkdir -p video + +if [ -z $1 ]; then + file=POSCAR + app="" +else + file=$1 + app=".`echo $file | awk -F. '{ print $2 }'`" +fi + +echo "parsing $file file ..." + +sicnt=`sed -n 6p $file | awk '{ print $1 }'` +ccnt=`sed -n 6p $file | awk '{ print $2 }'` + +lc=`sed -n 2p $file | awk '{ print $1 }'` + +x1=`sed -n 3p $file | awk '{ print $1 }'` +x2=`sed -n 3p $file | awk '{ print $2 }'` +x3=`sed -n 3p $file | awk '{ print $3 }'` + +y1=`sed -n 4p $file | awk '{ print $1 }'` +y2=`sed -n 4p $file | awk '{ print $2 }'` +y3=`sed -n 4p $file | awk '{ print $3 }'` + +z1=`sed -n 5p $file | awk '{ print $1 }'` +z2=`sed -n 5p $file | awk '{ print $2 }'` +z3=`sed -n 5p $file | awk '{ print $3 }'` + +((total=sicnt+ccnt)) +((eoa=total+8)) + +echo " Si: $sicnt, C: $ccnt, total: $total" +echo " Lattice constant: $lc A" +echo " Basis:" +echo " $x1 $y1 $z1" +echo " x = $x2 y = $y2 z = $z2" +echo " $x3 $y3 $z3" + +cnt=0 +tcnt=0 + +cx=1.0 +cy=1.0 +cz=0.8 + +echo "# P $total init <$cx,$cy,$cz>" > video/atomic_conf_init${app}.xyz + +sed -n 9,${eoa}p $file | \ + while read x y z fx fy fz; do + type="Si" + color="Yellow" + if [ $cnt -ge $sicnt ]; then + type="C" + color="Gray" + fi + X=`echo $x $y $z $x1 $y1 $z1 | \ + awk '{ print $1*$4+$2*$5+$3*$6 }'` + Y=`echo $x $y $z $x2 $y2 $z2 | \ + awk '{ print $1*$4+$2*$5+$3*$6 }'` + Z=`echo $x $y $z $x3 $y3 $z3 | \ + awk '{ print $1*$4+$2*$5+$3*$6 }'` + X=`echo $lc $X | awk '{ print $1*$2 }'` + Y=`echo $lc $Y | awk '{ print $1*$2 }'` + Z=`echo $lc $Z | awk '{ print $1*$2 }'` + echo "$type $X $Y $Z $color 0.0" >> video/atomic_conf_init${app}.xyz + ((cnt+=1)) + done + +echo "done" + diff --git a/vasp_tools/ppm2avi b/vasp_tools/ppm2avi new file mode 100755 index 0000000..74c8370 --- /dev/null +++ b/vasp_tools/ppm2avi @@ -0,0 +1,13 @@ +#for i in $1/*.ppm; do +# convert $i $1/$(basename $i ppm)png +#done + +MFOPTS="-mf fps=13:type=png" +#MFOPTS="-mf fps=25:type=png" + +OUTFILE=md.avi +[ -n "$2" ] && OUTFILE=$2 + +#mencoder mf://$1/*.png -ovc copy -o $1/$OUTFILE >/dev/null 2>&1 +mencoder $MFOPTS mf://$1/*.png -ovc xvid -xvidencopts bitrate=1000 \ + -o $1/$OUTFILE >/dev/null 2>&1 diff --git a/vasp_tools/runvasp_rx200 b/vasp_tools/runvasp_rx200 new file mode 100755 index 0000000..13d67bf --- /dev/null +++ b/vasp_tools/runvasp_rx200 @@ -0,0 +1,20 @@ +# create run file +NTH=1 +[ ! -z "$1" ] && NTH=$1 +WORKDIR=`pwd` +rf=`basename $WORKDIR` +cat > run_$rf <<-EOF +#!/bin/bash +#$ -S /bin/bash +#$ -cwd +#$ -pe smp $NTH + +export LD_LIBRARY_PATH=/opt/intel/mkl/9.1.021/lib/em64t +../vasp.4.6/vasp + +EOF + +# submit job +qsub -q all.q run_$rf + + diff --git a/vasp_tools/runvasp_rx200_gamma b/vasp_tools/runvasp_rx200_gamma new file mode 100755 index 0000000..57ab562 --- /dev/null +++ b/vasp_tools/runvasp_rx200_gamma @@ -0,0 +1,20 @@ +# create run file +NTH=1 +[ ! -z "$1" ] && NTH=$1 +WORKDIR=`pwd` +rf=`basename $WORKDIR` +cat > run_$rf <<-EOF +#!/bin/bash +#$ -S /bin/bash +#$ -cwd +#$ -pe smp $NTH + +export LD_LIBRARY_PATH=/opt/intel/mkl/9.1.021/lib/em64t +../vasp.4.6-gamma/vasp + +EOF + +# submit job +qsub -q all.q run_$rf + + diff --git a/vasp_tools/sd_rot.patch b/vasp_tools/sd_rot.patch new file mode 100644 index 0000000..c0c15f2 --- /dev/null +++ b/vasp_tools/sd_rot.patch @@ -0,0 +1,407 @@ +diff -Nur vasp.4.6/dyna.F vasp.4.6-ct/dyna.F +--- vasp.4.6/dyna.F 2009-07-22 15:12:20.032980043 +0200 ++++ vasp.4.6-ct/dyna.F 2009-09-18 08:32:08.666016928 +0200 +@@ -1164,6 +1164,83 @@ + + !********************************************************************* + ! ++! subroutine to transform vectors into the rotated constraints system ++! ++!********************************************************************* ++ ++ SUBROUTINE SD_ROT(T_INFO,VEC,DIR,NI) ++ USE poscar ++ IMPLICIT NONE ++ ++ TYPE (type_info) T_INFO ++ REAL(q) VEC(3),TMP(3) ++ CHARACTER*1 DIR ++ ++ INTEGER M,NI ++ ++ IF((.NOT. T_INFO%LSFOR(1,NI)).OR. & ++ & (.NOT. T_INFO%LSFOR(2,NI)).OR. & ++ & (.NOT. T_INFO%LSFOR(3,NI))) THEN ++ IF (DIR=='F') THEN ++ IF (T_INFO%SD_ROT_Z/=0._q) THEN ++ DO M=1,3 ++ TMP(M)=VEC(M) ++ ENDDO ++ VEC(1)=COS(T_INFO%SD_ROT_Z)*TMP(1)- & ++ & SIN(T_INFO%SD_ROT_Z)*TMP(2) ++ VEC(2)=SIN(T_INFO%SD_ROT_Z)*TMP(1)+ & ++ & COS(T_INFO%SD_ROT_Z)*TMP(2) ++ WRITE(*,*) 'SD rotate DEBUG (Z^-1): ',NI ++ WRITE(*,*) ' F: ', TMP(1),' ',TMP(2),' ',TMP(3) ++ WRITE(*,*) ' to: ',VEC(1),' ',VEC(2),' ',VEC(3) ++ ENDIF ++ IF (T_INFO%SD_ROT_X/=0._q) THEN ++ DO M=1,3 ++ TMP(M)=VEC(M) ++ ENDDO ++ VEC(2)=COS(T_INFO%SD_ROT_X)*TMP(2)- & ++ & SIN(T_INFO%SD_ROT_X)*TMP(3) ++ VEC(3)=SIN(T_INFO%SD_ROT_X)*TMP(2)+ & ++ & COS(T_INFO%SD_ROT_X)*TMP(3) ++ WRITE(*,*) 'SD rotate DEBUG (X^-1): ',NI ++ WRITE(*,*) ' F: ', TMP(1),' ',TMP(2),' ',TMP(3) ++ WRITE(*,*) ' to: ',VEC(1),' ',VEC(2),' ',VEC(3) ++ ENDIF ++ ELSE ++ IF (T_INFO%SD_ROT_X/=0._q) THEN ++ DO M=1,3 ++ TMP(M)=VEC(M) ++ ENDDO ++ VEC(2)=COS(-T_INFO%SD_ROT_X)*TMP(2)- & ++ & SIN(-T_INFO%SD_ROT_X)*TMP(3) ++ VEC(3)=SIN(-T_INFO%SD_ROT_X)*TMP(2)+ & ++ & COS(-T_INFO%SD_ROT_X)*TMP(3) ++ WRITE(*,*) 'SD rotate DEBUG (X): ',NI ++ WRITE(*,*) ' B: ', TMP(1),' ',TMP(2),' ',TMP(3) ++ WRITE(*,*) ' to: ',VEC(1),' ',VEC(2),' ',VEC(3) ++ ENDIF ++ IF (T_INFO%SD_ROT_Z/=0._q) THEN ++ DO M=1,3 ++ TMP(M)=VEC(M) ++ ENDDO ++ VEC(1)=COS(-T_INFO%SD_ROT_Z)*TMP(1)- & ++ & SIN(-T_INFO%SD_ROT_Z)*TMP(2) ++ VEC(2)=SIN(-T_INFO%SD_ROT_Z)*TMP(1)+ & ++ & COS(-T_INFO%SD_ROT_Z)*TMP(2) ++ WRITE(*,*) 'SD rotate DEBUG (Z): ',NI ++ WRITE(*,*) ' B: ', TMP(1),' ',TMP(2),' ',TMP(3) ++ WRITE(*,*) ' to: ',VEC(1),' ',VEC(2),' ',VEC(3) ++ ENDIF ++ ENDIF ++ ENDIF ++ ++ RETURN ++ ++ END ++ ++ ++!********************************************************************* ++! + ! subroutine to set selected force components to zero + ! + !********************************************************************* +@@ -1184,19 +1261,44 @@ + IF (T_INFO%LSDYN) THEN + !-----Selective dynamics here ... : + DO NI=1,T_INFO%NIONS ++!-----transformed selective dynamics ++ IF(T_INFO%SD_ROT) THEN ++ DO M=1,3 ++ VTMP(M)=VEL(M,NI) ++ ENDDO ++ CALL SD_ROT(T_INFO,VTMP,'F',NI) ++ DO M=1,3 ++ VEL(M,NI)=VTMP(M) ++ ENDDO ++ ENDIF + !-----reset the velocities of the selected coordinates ... + DO M=1,3 + IF (.NOT.T_INFO%LSFOR(M,NI)) VEL(M,NI)=0._q + ENDDO ++!-----transform back to direct coordinates ++ IF(T_INFO%SD_ROT) THEN ++ DO M=1,3 ++ VTMP(M)=VEL(M,NI) ++ ENDDO ++ CALL SD_ROT(T_INFO,VTMP,'B',NI) ++ DO M=1,3 ++ VEL(M,NI)=VTMP(M) ++ ENDDO ++ ENDIF + !-----and reset the selected force coordinates (warning: forces are + ! given in cartesian, selection is made in direct coordinates!): + DO M=1,3 + VTMP(M)=TIFOR(M,NI) + ENDDO + CALL KARDIR(1,VTMP,LATT_CUR%B) ++!-----transformed selective dynamics ++ IF(T_INFO%SD_ROT) CALL SD_ROT(T_INFO,VTMP,'F',NI) ++!-----the actual reset + DO M=1,3 + IF (.NOT.T_INFO%LSFOR(M,NI)) VTMP(M)=0._q + ENDDO ++!-----transform back to direct coordinates ++ IF(T_INFO%SD_ROT) CALL SD_ROT(T_INFO,VTMP,'B',NI) + CALL DIRKAR(1,VTMP,LATT_CUR%A) + DO M=1,3 + TIFOR(M,NI)=VTMP(M) +@@ -1222,10 +1324,30 @@ + IF (T_INFO%LSDYN) THEN + !-----Selective dynamics here ... : + DO NI=1,T_INFO%NIONS ++!-----transformed selective dynamics ++ IF(T_INFO%SD_ROT) THEN ++ DO M=1,3 ++ VTMP(M)=VEL(M,NI) ++ ENDDO ++ CALL SD_ROT(T_INFO,VTMP,'F',NI) ++ DO M=1,3 ++ VEL(M,NI)=VTMP(M) ++ ENDDO ++ ENDIF + !-----reset the velocities of the selected coordinates ... + DO M=1,3 + IF (.NOT.T_INFO%LSFOR(M,NI)) VEL(M,NI)=0._q + ENDDO ++!-----transform back to direct coordinates ++ IF(T_INFO%SD_ROT) THEN ++ DO M=1,3 ++ VTMP(M)=VEL(M,NI) ++ ENDDO ++ CALL SD_ROT(T_INFO,VTMP,'B',NI) ++ DO M=1,3 ++ VEL(M,NI)=VTMP(M) ++ ENDDO ++ ENDIF + ENDDO + ENDIF + END SUBROUTINE +diff -Nur vasp.4.6/main.F vasp.4.6-ct/main.F +--- vasp.4.6/main.F 2009-07-22 15:12:20.044978904 +0200 ++++ vasp.4.6-ct/main.F 2009-09-18 08:55:20.595465366 +0200 +@@ -1929,7 +1929,8 @@ + ! write header + CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, & + & T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, & ++ & T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + ! write AE charge density + CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT) +@@ -1951,7 +1952,8 @@ + ! write header + CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, & + & T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, & ++ & T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + ! write AE core charge density + CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT) +@@ -3478,7 +3480,7 @@ + io_begin + + CALL OUTPOS(13,.TRUE.,T_INFO%SZNAM2,LATT_CUR%SCALE,DYN%AC,T_INFO%NTYP,T_INFO%NITYP,T_INFO%LSDYN, & +- & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR ) ++ & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + CALL OUTPOS_TRAIL(13,IO%LOPEN, LATT_CUR, T_INFO, DYN) + + io_end +@@ -3489,7 +3491,7 @@ + + io_begin + CALL OUTPOS(70,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + + DO ISP=1,WDES%NCDIJ +@@ -3828,7 +3830,7 @@ + REWIND 18 + ! since t + CALL OUTPOS(18,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + ! if you uncomment the following lines the pseudo core charge density + ! is added to the pseudo charge density +@@ -3855,7 +3857,7 @@ + IF (IO%LOPEN) OPEN(IO%IUVTOT,FILE='LOCPOT',STATUS='UNKNOWN') + REWIND IO%IUVTOT + CALL OUTPOS(IO%IUVTOT,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + ! comment out the following line to add exchange correlation + INFO%LEXCHG=-1 +@@ -3936,7 +3938,8 @@ + ! write header + CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, & + & T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, & ++ & T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + ! write AE charge density + CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT) +@@ -3959,7 +3962,7 @@ + io_begin + OPEN(UNIT=53,FILE='ELFCAR',STATUS='UNKNOWN') + CALL OUTPOS(53,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + + DO ISP=1,WDES%NCDIJ +diff -Nur vasp.4.6/main.f90 vasp.4.6-ct/main.f90 +--- vasp.4.6/main.f90 2009-07-22 15:14:38.603841627 +0200 ++++ vasp.4.6-ct/main.f90 2009-09-18 08:55:22.638156662 +0200 +@@ -1830,7 +1830,8 @@ + ! write header + CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, & + & T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, & ++ & T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + + ! write AE charge density + CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT) +@@ -1852,7 +1853,8 @@ + ! write header + CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, & + & T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, & ++ & T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + + ! write AE core charge density + CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT) +@@ -3369,7 +3371,7 @@ + + + CALL OUTPOS(13,.TRUE.,T_INFO%SZNAM2,LATT_CUR%SCALE,DYN%AC,T_INFO%NTYP,T_INFO%NITYP,T_INFO%LSDYN, & +- & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR ) ++ & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + CALL OUTPOS_TRAIL(13,IO%LOPEN, LATT_CUR, T_INFO, DYN) + + +@@ -3380,7 +3382,7 @@ + + + CALL OUTPOS(70,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + + + DO ISP=1,WDES%NCDIJ +@@ -3712,7 +3714,7 @@ + REWIND 18 + ! since t + CALL OUTPOS(18,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + + ! if you uncomment the following lines the pseudo core charge density + ! is added to the pseudo charge density +@@ -3739,7 +3741,7 @@ + IF (IO%LOPEN) OPEN(IO%IUVTOT,FILE='LOCPOT',STATUS='UNKNOWN') + REWIND IO%IUVTOT + CALL OUTPOS(IO%IUVTOT,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + + ! comment out the following line to add exchange correlation + INFO%LEXCHG=-1 +@@ -3820,7 +3822,8 @@ + ! write header + CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, & + & T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, & ++ & T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + + ! write AE charge density + CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT) +@@ -3843,7 +3846,7 @@ + + OPEN(UNIT=53,FILE='ELFCAR',STATUS='UNKNOWN') + CALL OUTPOS(53,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + + + DO ISP=1,WDES%NCDIJ +diff -Nur vasp.4.6/poscar.F vasp.4.6-ct/poscar.F +--- vasp.4.6/poscar.F 2009-07-22 15:12:20.052978145 +0200 ++++ vasp.4.6-ct/poscar.F 2009-09-18 09:17:37.370283715 +0200 +@@ -181,6 +181,7 @@ + INTEGER I,NT,NI,NSCALE + REAL(q) SCALEX,SCALEY,SCALEZ + REAL(q) POTIMR ++ REAL(q),PARAMETER :: PI=3.1415926536_q + + OPEN(UNIT=15,FILE=DIR_APP(1:DIR_LEN)//'POSCAR',STATUS='OLD') + +@@ -269,6 +270,25 @@ + ENDIF + + READ(15,'(A1)') CSEL ++ T_INFO%SD_ROT=.FALSE. ++ IF ((CSEL=='T').OR.(CSEL=='t').OR. & ++ & (CSEL=='R').OR.(CSEL=='r')) THEN ++!-----transformed/rotated selective dynamics switched on ++!-----read in rotation angles ++ T_INFO%SD_ROT=.TRUE. ++ T_INFO%SD_ROT_Z=0._q ++ T_INFO%SD_ROT_X=0._q ++ READ(15,*,ERR=400,END=400) T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X ++!-----print some info and convert to rad ++ WRITE(IU6,*) ' rotated selective dynamics:' ++ WRITE(IU6,*) ' Z: ', T_INFO%SD_ROT_Z ++ WRITE(IU6,*) ' rX: ', T_INFO%SD_ROT_X ++ T_INFO%SD_ROT_Z=PI*T_INFO%SD_ROT_Z/180.0 ++ T_INFO%SD_ROT_X=PI*T_INFO%SD_ROT_X/180.0 ++!-----switch on selective dynamics for further processing ++ CSEL='s' ++ ENDIF ++ + T_INFO%LSDYN=((CSEL=='S').OR.(CSEL=='s')) + IF (T_INFO%LSDYN) READ(15,'(A1)') CSEL + IF (CSEL=='K'.OR.CSEL=='k'.OR. & +@@ -538,17 +558,19 @@ + !*********************************************************************** + + SUBROUTINE OUTPOS(IU,LLONG,SZNAM,SCALE,A,NTYP,NITYP,LSDYN, & +- & NIONS,POSION,LSFOR ) ++ & NIONS,POSION,LSFOR,SD_ROT,SD_ROT_Z,SD_ROT_X) + USE prec + IMPLICIT REAL(q) (A-H,O-Z) + +- LOGICAL LLONG,LSDYN,LSFOR ++ LOGICAL LLONG,LSDYN,LSFOR,SD_ROT ++ REAL(q) SD_ROT_Z,SD_ROT_X + DIMENSION A(3,3) + DIMENSION POSION(3,NIONS) + DIMENSION LSFOR (3,NIONS) + DIMENSION NITYP(NTYP) + CHARACTER*40 FORM + CHARACTER*40 SZNAM ++ REAL(q),PARAMETER :: PI=3.1415926536_q + + !-----direct lattice + WRITE(IU,'(A40)') SZNAM +@@ -562,7 +584,14 @@ + WRITE(IU,FORM) (A(1,I)/SCALE,A(2,I)/SCALE,A(3,I)/SCALE,I=1,3) + + WRITE(IU,'(20I4)') (NITYP(NT),NT=1,NTYP) +- IF (LSDYN) WRITE(13,'(A18)') 'Selective dynamics' ++ IF (LSDYN) THEN ++ IF (SD_ROT) THEN ++ WRITE(13,'(A30)') 'Transformed selective dynamics' ++ WRITE(13,'(2F)') SD_ROT_Z*180.0/PI,SD_ROT_X*180.0/PI ++ ELSE ++ WRITE(13,'(A18)') 'Selective dynamics' ++ ENDIF ++ ENDIF + WRITE(IU,'(A6)')'Direct' + + IF (LSDYN) THEN +diff -Nur vasp.4.6/poscar.inc vasp.4.6-ct/poscar.inc +--- vasp.4.6/poscar.inc 2009-07-22 15:05:24.076290013 +0200 ++++ vasp.4.6-ct/poscar.inc 2009-09-18 08:01:29.234012116 +0200 +@@ -14,6 +14,9 @@ + INTEGER NIONS ! actual number of ions + INTEGER NIONP ! actual number of ions inc. empty spheres + LOGICAL LSDYN ! selective dynamics (yes/ no) ++ LOGICAL SD_ROT ! rotated selective dynamics (yes/ no) ++ REAL(q) SD_ROT_Z ! constraints rotation (z-axis, 1st rot) ++ REAL(q) SD_ROT_X ! constraints rotation (x-axis, 2nd rot) + LOGICAL LDIRCO ! positions in direct/recproc. lattice + REAL(q), POINTER :: POSION(:,:) ! positions usually same as DYN%POSION + LOGICAL,POINTER :: LSFOR(:,:) ! selective dynamics diff --git a/vasp_tools/sd_rot_all-atoms.patch b/vasp_tools/sd_rot_all-atoms.patch new file mode 100644 index 0000000..548f3c6 --- /dev/null +++ b/vasp_tools/sd_rot_all-atoms.patch @@ -0,0 +1,407 @@ +diff -Nur vasp.4.6.orig/dyna.F vasp.4.6-gamma-fullct/dyna.F +--- vasp.4.6.orig/dyna.F 2009-09-16 10:45:06.050116866 +0200 ++++ vasp.4.6-gamma-fullct/dyna.F 2009-11-05 15:09:26.435422082 +0100 +@@ -1164,6 +1164,71 @@ + + !********************************************************************* + ! ++! subroutine to transform vectors into the rotated constraints system ++! ++!********************************************************************* ++ ++ SUBROUTINE SD_ROT(T_INFO,VEC,DIR,NI) ++ USE poscar ++ IMPLICIT NONE ++ ++ TYPE (type_info) T_INFO ++ REAL(q) VEC(3),TMP(3) ++ CHARACTER*1 DIR ++ ++ INTEGER M,NI ++ ++ IF((.NOT. T_INFO%LSFOR(1,NI)).OR. & ++ & (.NOT. T_INFO%LSFOR(2,NI)).OR. & ++ & (.NOT. T_INFO%LSFOR(3,NI))) THEN ++ IF (DIR=='F') THEN ++ IF (T_INFO%SD_ROT_Z(NI)/=0._q) THEN ++ DO M=1,3 ++ TMP(M)=VEC(M) ++ ENDDO ++ VEC(1)=COS(T_INFO%SD_ROT_Z(NI))*TMP(1)- & ++ & SIN(T_INFO%SD_ROT_Z(NI))*TMP(2) ++ VEC(2)=SIN(T_INFO%SD_ROT_Z(NI))*TMP(1)+ & ++ & COS(T_INFO%SD_ROT_Z(NI))*TMP(2) ++ ENDIF ++ IF (T_INFO%SD_ROT_X(NI)/=0._q) THEN ++ DO M=1,3 ++ TMP(M)=VEC(M) ++ ENDDO ++ VEC(2)=COS(T_INFO%SD_ROT_X(NI))*TMP(2)- & ++ & SIN(T_INFO%SD_ROT_X(NI))*TMP(3) ++ VEC(3)=SIN(T_INFO%SD_ROT_X(NI))*TMP(2)+ & ++ & COS(T_INFO%SD_ROT_X(NI))*TMP(3) ++ ENDIF ++ ELSE ++ IF (T_INFO%SD_ROT_X(NI)/=0._q) THEN ++ DO M=1,3 ++ TMP(M)=VEC(M) ++ ENDDO ++ VEC(2)=COS(-T_INFO%SD_ROT_X(NI))*TMP(2)- & ++ & SIN(-T_INFO%SD_ROT_X(NI))*TMP(3) ++ VEC(3)=SIN(-T_INFO%SD_ROT_X(NI))*TMP(2)+ & ++ & COS(-T_INFO%SD_ROT_X(NI))*TMP(3) ++ ENDIF ++ IF (T_INFO%SD_ROT_Z(NI)/=0._q) THEN ++ DO M=1,3 ++ TMP(M)=VEC(M) ++ ENDDO ++ VEC(1)=COS(-T_INFO%SD_ROT_Z(NI))*TMP(1)- & ++ & SIN(-T_INFO%SD_ROT_Z(NI))*TMP(2) ++ VEC(2)=SIN(-T_INFO%SD_ROT_Z(NI))*TMP(1)+ & ++ & COS(-T_INFO%SD_ROT_Z(NI))*TMP(2) ++ ENDIF ++ ENDIF ++ ENDIF ++ ++ RETURN ++ ++ END ++ ++ ++!********************************************************************* ++! + ! subroutine to set selected force components to zero + ! + !********************************************************************* +@@ -1184,19 +1249,44 @@ + IF (T_INFO%LSDYN) THEN + !-----Selective dynamics here ... : + DO NI=1,T_INFO%NIONS ++!-----transformed selective dynamics ++ IF(T_INFO%SD_ROT) THEN ++ DO M=1,3 ++ VTMP(M)=VEL(M,NI) ++ ENDDO ++ CALL SD_ROT(T_INFO,VTMP,'F',NI) ++ DO M=1,3 ++ VEL(M,NI)=VTMP(M) ++ ENDDO ++ ENDIF + !-----reset the velocities of the selected coordinates ... + DO M=1,3 + IF (.NOT.T_INFO%LSFOR(M,NI)) VEL(M,NI)=0._q + ENDDO ++!-----transform back to direct coordinates ++ IF(T_INFO%SD_ROT) THEN ++ DO M=1,3 ++ VTMP(M)=VEL(M,NI) ++ ENDDO ++ CALL SD_ROT(T_INFO,VTMP,'B',NI) ++ DO M=1,3 ++ VEL(M,NI)=VTMP(M) ++ ENDDO ++ ENDIF + !-----and reset the selected force coordinates (warning: forces are + ! given in cartesian, selection is made in direct coordinates!): + DO M=1,3 + VTMP(M)=TIFOR(M,NI) + ENDDO + CALL KARDIR(1,VTMP,LATT_CUR%B) ++!-----transformed selective dynamics ++ IF(T_INFO%SD_ROT) CALL SD_ROT(T_INFO,VTMP,'F',NI) ++!-----the actual reset + DO M=1,3 + IF (.NOT.T_INFO%LSFOR(M,NI)) VTMP(M)=0._q + ENDDO ++!-----transform back to direct coordinates ++ IF(T_INFO%SD_ROT) CALL SD_ROT(T_INFO,VTMP,'B',NI) + CALL DIRKAR(1,VTMP,LATT_CUR%A) + DO M=1,3 + TIFOR(M,NI)=VTMP(M) +@@ -1222,10 +1312,30 @@ + IF (T_INFO%LSDYN) THEN + !-----Selective dynamics here ... : + DO NI=1,T_INFO%NIONS ++!-----transformed selective dynamics ++ IF(T_INFO%SD_ROT) THEN ++ DO M=1,3 ++ VTMP(M)=VEL(M,NI) ++ ENDDO ++ CALL SD_ROT(T_INFO,VTMP,'F',NI) ++ DO M=1,3 ++ VEL(M,NI)=VTMP(M) ++ ENDDO ++ ENDIF + !-----reset the velocities of the selected coordinates ... + DO M=1,3 + IF (.NOT.T_INFO%LSFOR(M,NI)) VEL(M,NI)=0._q + ENDDO ++!-----transform back to direct coordinates ++ IF(T_INFO%SD_ROT) THEN ++ DO M=1,3 ++ VTMP(M)=VEL(M,NI) ++ ENDDO ++ CALL SD_ROT(T_INFO,VTMP,'B',NI) ++ DO M=1,3 ++ VEL(M,NI)=VTMP(M) ++ ENDDO ++ ENDIF + ENDDO + ENDIF + END SUBROUTINE +diff -Nur vasp.4.6.orig/main.F vasp.4.6-gamma-fullct/main.F +--- vasp.4.6.orig/main.F 2009-09-16 10:45:05.747597375 +0200 ++++ vasp.4.6-gamma-fullct/main.F 2009-11-05 15:09:26.449951618 +0100 +@@ -1929,7 +1929,8 @@ + ! write header + CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, & + & T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, & ++ & T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + ! write AE charge density + CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT) +@@ -1951,7 +1952,8 @@ + ! write header + CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, & + & T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, & ++ & T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + ! write AE core charge density + CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT) +@@ -3478,7 +3480,7 @@ + io_begin + + CALL OUTPOS(13,.TRUE.,T_INFO%SZNAM2,LATT_CUR%SCALE,DYN%AC,T_INFO%NTYP,T_INFO%NITYP,T_INFO%LSDYN, & +- & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR ) ++ & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + CALL OUTPOS_TRAIL(13,IO%LOPEN, LATT_CUR, T_INFO, DYN) + + io_end +@@ -3489,7 +3491,7 @@ + + io_begin + CALL OUTPOS(70,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSIOC,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + + DO ISP=1,WDES%NCDIJ +@@ -3828,7 +3830,7 @@ + REWIND 18 + ! since t + CALL OUTPOS(18,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + ! if you uncomment the following lines the pseudo core charge density + ! is added to the pseudo charge density +@@ -3855,7 +3857,7 @@ + IF (IO%LOPEN) OPEN(IO%IUVTOT,FILE='LOCPOT',STATUS='UNKNOWN') + REWIND IO%IUVTOT + CALL OUTPOS(IO%IUVTOT,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + ! comment out the following line to add exchange correlation + INFO%LEXCHG=-1 +@@ -3936,7 +3938,8 @@ + ! write header + CALL OUTPOS(99,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A, & + & T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR, & ++ & T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + ! write AE charge density + CALL OUTCHG(GRIDC,99,.TRUE.,CHTOT) +@@ -3959,7 +3962,7 @@ + io_begin + OPEN(UNIT=53,FILE='ELFCAR',STATUS='UNKNOWN') + CALL OUTPOS(53,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP,T_INFO%NITYP,.FALSE., & +- & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ & T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + + DO ISP=1,WDES%NCDIJ +diff -Nur vasp.4.6.orig/pardens.F vasp.4.6-gamma-fullct/pardens.F +--- vasp.4.6.orig/pardens.F 2009-09-16 10:45:06.294577287 +0200 ++++ vasp.4.6-gamma-fullct/pardens.F 2009-11-05 15:09:26.453773187 +0100 +@@ -308,7 +308,7 @@ + ! I do not call <> here, because I handle the total charge a little bit + ! differnt, and the output to <> is also differnt + do_io CALL OUTPOS(iuchgcar,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP, & +- T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + + CALL OUTCHG(GRIDC,iuchgcar,.TRUE.,CHTOT) + +@@ -320,7 +320,7 @@ + do_io CLOSE(iuchgcar) + + do_io CALL OUTPOS(iuchg,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP, & +- T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + + CALL OUTCHG(GRIDC,iuchg,.FALSE.,CHTOT) + +@@ -1154,7 +1154,7 @@ + + ! and use the usual output routines + CALL OUTPOS(iunit,.FALSE.,INFO%SZNAM1,LATT_CUR%SCALE,LATT_CUR%A,T_INFO%NTYP, & +- T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR) ++ T_INFO%NITYP,.FALSE.,T_INFO%NIONS,DYN%POSION,T_INFO%LSFOR,T_INFO%SD_ROT,T_INFO%SD_ROT_Z,T_INFO%SD_ROT_X) + io_end + + CALL OUTCHG(GRIDC,iunit,.FALSE.,CHTOT) +diff -Nur vasp.4.6.orig/poscar.F vasp.4.6-gamma-fullct/poscar.F +--- vasp.4.6.orig/poscar.F 2009-09-16 10:45:06.074097686 +0200 ++++ vasp.4.6-gamma-fullct/poscar.F 2009-11-05 15:19:56.505775347 +0100 +@@ -181,6 +181,7 @@ + INTEGER I,NT,NI,NSCALE + REAL(q) SCALEX,SCALEY,SCALEZ + REAL(q) POTIMR ++ REAL(q),PARAMETER :: PI=3.1415926536_q + + OPEN(UNIT=15,FILE=DIR_APP(1:DIR_LEN)//'POSCAR',STATUS='OLD') + +@@ -269,6 +270,17 @@ + ENDIF + + READ(15,'(A1)') CSEL ++ T_INFO%SD_ROT=.FALSE. ++ IF ((CSEL=='T').OR.(CSEL=='t').OR. & ++ & (CSEL=='R').OR.(CSEL=='r')) THEN ++!-----transformed/rotated selective dynamics switched on ++ T_INFO%SD_ROT=.TRUE. ++!-----print some info and convert to rad ++ WRITE(IU6,*) ' rotated selective dynamics switched on' ++!-----switch on selective dynamics for further processing ++ CSEL='s' ++ ENDIF ++ + T_INFO%LSDYN=((CSEL=='S').OR.(CSEL=='s')) + IF (T_INFO%LSDYN) READ(15,'(A1)') CSEL + IF (CSEL=='K'.OR.CSEL=='k'.OR. & +@@ -288,6 +300,12 @@ + & DYN%D2C(3,NIOND), & + & DYN%VEL(3,NIOND),DYN%D2(3,NIOND),DYN%D3(3,NIOND)) + ++ ALLOCATE(T_INFO%SD_ROT_Z(NIOND)) ++ ALLOCATE(T_INFO%SD_ROT_X(NIOND)) ++ ++ T_INFO%SD_ROT_Z=0._q ++ T_INFO%SD_ROT_X=0._q ++ + ! alias T_INFO%POSION + T_INFO%POSION => DYN%POSION + +@@ -298,12 +316,21 @@ + DYN%D3 =0 + + DO NI=1,T_INFO%NIONS ++ IF (T_INFO%SD_ROT) THEN ++ READ(15,*,ERR=400,END=400) DYN%POSION(1,NI),DYN%POSION(2,NI),DYN%POSION(3,NI), & ++ & T_INFO%LSFOR(1,NI),T_INFO%LSFOR(2,NI),T_INFO%LSFOR(3,NI), & ++ & T_INFO%SD_ROT_Z(NI), T_INFO%SD_ROT_X(NI) ++!-----convert to rad ++ T_INFO%SD_ROT_Z(NI)=PI*T_INFO%SD_ROT_Z(NI)/180.0 ++ T_INFO%SD_ROT_X(NI)=PI*T_INFO%SD_ROT_X(NI)/180.0 ++ ELSE + IF (T_INFO%LSDYN) THEN + READ(15,*,ERR=400,END=400) DYN%POSION(1,NI),DYN%POSION(2,NI),DYN%POSION(3,NI), & + & T_INFO%LSFOR(1,NI),T_INFO%LSFOR(2,NI),T_INFO%LSFOR(3,NI) + ELSE + READ(15,*,ERR=400,END=400) DYN%POSION(1,NI),DYN%POSION(2,NI),DYN%POSION(3,NI) + ENDIF ++ ENDIF + ENDDO + + IF (CSEL=='K') THEN +@@ -538,17 +565,19 @@ + !*********************************************************************** + + SUBROUTINE OUTPOS(IU,LLONG,SZNAM,SCALE,A,NTYP,NITYP,LSDYN, & +- & NIONS,POSION,LSFOR ) ++ & NIONS,POSION,LSFOR,SD_ROT,SD_ROT_Z,SD_ROT_X) + USE prec + IMPLICIT REAL(q) (A-H,O-Z) + +- LOGICAL LLONG,LSDYN,LSFOR ++ LOGICAL LLONG,LSDYN,LSFOR,SD_ROT ++ REAL(q), POINTER :: SD_ROT_Z(:), SD_ROT_X(:) + DIMENSION A(3,3) + DIMENSION POSION(3,NIONS) + DIMENSION LSFOR (3,NIONS) + DIMENSION NITYP(NTYP) + CHARACTER*40 FORM + CHARACTER*40 SZNAM ++ REAL(q),PARAMETER :: PI=3.1415926536_q + + !-----direct lattice + WRITE(IU,'(A40)') SZNAM +@@ -562,14 +591,26 @@ + WRITE(IU,FORM) (A(1,I)/SCALE,A(2,I)/SCALE,A(3,I)/SCALE,I=1,3) + + WRITE(IU,'(20I4)') (NITYP(NT),NT=1,NTYP) +- IF (LSDYN) WRITE(13,'(A18)') 'Selective dynamics' ++ IF (LSDYN) THEN ++ IF (SD_ROT) THEN ++ WRITE(13,'(A30)') 'Transformed selective dynamics' ++ ELSE ++ WRITE(13,'(A18)') 'Selective dynamics' ++ ENDIF ++ ENDIF + WRITE(IU,'(A6)')'Direct' + + IF (LSDYN) THEN + IF (LLONG) THEN + FORM='(3F20.16,3L4)' ++ IF (SD_ROT) THEN ++ FORM='(3F20.16,3L4,2F20.12)' ++ ENDIF + ELSE + FORM='(3F10.6,3L2)' ++ IF (SD_ROT) THEN ++ FORM='(3F10.6,3L2,2F10.2)' ++ ENDIF + ENDIF + ELSE + IF (LLONG) THEN +@@ -579,6 +620,12 @@ + ENDIF + ENDIF + ++ IF(SD_ROT) THEN ++ WRITE(IU,FORM) & ++ & (POSION(1,NI),POSION(2,NI),POSION(3,NI), & ++ & LSFOR(1,NI),LSFOR(2,NI),LSFOR(3,NI), & ++ & SD_ROT_Z(NI)*180.0/PI, SD_ROT_X(NI)*180.0/PI,NI=1,NIONS) ++ ELSE + IF (LSDYN) THEN + WRITE(IU,FORM) & + & (POSION(1,NI),POSION(2,NI),POSION(3,NI), & +@@ -587,6 +634,7 @@ + WRITE(IU,FORM) & + & (POSION(1,NI),POSION(2,NI),POSION(3,NI),NI=1,NIONS) + ENDIF ++ ENDIF + IF (.NOT.LLONG) WRITE(IU,*) + RETURN + END SUBROUTINE +diff -Nur vasp.4.6.orig/poscar.inc vasp.4.6-gamma-fullct/poscar.inc +--- vasp.4.6.orig/poscar.inc 2009-09-16 10:45:06.791087379 +0200 ++++ vasp.4.6-gamma-fullct/poscar.inc 2009-11-03 11:58:39.388412198 +0100 +@@ -14,6 +14,9 @@ + INTEGER NIONS ! actual number of ions + INTEGER NIONP ! actual number of ions inc. empty spheres + LOGICAL LSDYN ! selective dynamics (yes/ no) ++ LOGICAL SD_ROT ! rotated selective dynamics (yes/ no) ++ REAL(q), POINTER :: SD_ROT_Z(:) ! constraints rotation (z-axis, 1st rot) ++ REAL(q), POINTER :: SD_ROT_X(:) ! constraints rotation (x-axis, 2nd rot) + LOGICAL LDIRCO ! positions in direct/recproc. lattice + REAL(q), POINTER :: POSION(:,:) ! positions usually same as DYN%POSION + LOGICAL,POINTER :: LSFOR(:,:) ! selective dynamics diff --git a/vasp_tools/search_bonds b/vasp_tools/search_bonds new file mode 100755 index 0000000..29b6d1c --- /dev/null +++ b/vasp_tools/search_bonds @@ -0,0 +1,144 @@ +#!/bin/bash + +file=$1 +len=$2 +delta=$3 +tA=$4 +tB=$5 + +echo +echo "usage:" +echo "$0 " +echo +echo "args: $@" +echo + +scale=`sed -n 2p $1` + +X1=`sed -n 3p $file | awk '{ print $1 }'` +X2=`sed -n 3p $file | awk '{ print $2 }'` +X3=`sed -n 3p $file | awk '{ print $3 }'` + +Y1=`sed -n 4p $file | awk '{ print $1 }'` +Y2=`sed -n 4p $file | awk '{ print $2 }'` +Y3=`sed -n 4p $file | awk '{ print $3 }'` + +Z1=`sed -n 5p $file | awk '{ print $1 }'` +Z2=`sed -n 5p $file | awk '{ print $2 }'` +Z3=`sed -n 5p $file | awk '{ print $3 }'` + +export X1 X2 X3 +export Y1 Y2 Y3 +export Z1 Z2 Z3 + +nsi=`sed -n 6p $file | awk '{ print $1 }'` +nc=`sed -n 6p $file | awk '{ print $2 }'` + +((nt=nsi+nc)) + +((offset=8)) +((count=1)) + +echo "found $nt atoms: Si = $nsi / C = $nc" +echo "scale: $scale" +echo "X: $X1 $X2 $X3" +echo "Y: $Y1 $Y2 $Y3" +echo "Z: $Z1 $Z2 $Z3" +echo + +while [ "1" ]; do + + if [ $count -le $nsi ]; then + typea=S + else + typea=C + fi + + if [ "$tA" != "$typea" ]; then + ((count+=1)) + [ $count -gt $nt ] && break + continue + fi + + ((line=count+offset)) + + temp="`sed -n ${line}p $1`" + xa=`echo $temp | awk '{ print $1 }'` + ya=`echo $temp | awk '{ print $2 }'` + za=`echo $temp | awk '{ print $3 }'` + + ((ic=1)) + while [ "1" ]; do + ((il=ic+offset)) + if [ $line != $il ]; then + if [ $ic -le $nsi ] ; then + typeb=S + else + typeb=C + fi + if [ "$typeb" != "$tB" ]; then + ((ic+=1)) + [ $ic -gt $nt ] && break + continue + fi + tmpb="`sed -n ${il}p $1`" + xb=`echo $tmpb | awk '{ print $1 }'` + yb=`echo $tmpb | awk '{ print $2 }'` + zb=`echo $tmpb | awk '{ print $3 }'` + + echo "$xa $ya $za $xb $yb $zb $scale $len $delta $count $ic" | \ + awk ' \ + BEGIN { + dxt=0; dyt=0; dzt=0 + dx=0; dy=0; dz=0; dist=0 + X=0; Y=0; Z=0 + X1=ENVIRON["X1"]; X2=ENVIRON["X2"]; X3=ENVIRON["X3"] + Y1=ENVIRON["Y1"]; Y2=ENVIRON["Y2"]; Y3=ENVIRON["Y3"] + Z1=ENVIRON["Z1"]; Z2=ENVIRON["Z2"]; Z3=ENVIRON["Z3"] + } + { + X=sqrt(X1^2+X2^2+X3^2) + Y=sqrt(Y1^2+Y2^2+Y3^2) + Z=sqrt(Z1^2+Z2^2+Z3^2) + dx=$1-$4 + dy=$2-$5 + dz=$3-$6 + if(dx>1/2) + dx-=1 + if(dx<-1/2) + dx+=1 + if(dy>1/2) + dy-=1 + if(dy<-1/2) + dy+=1 + if(dz>1/2) + dz-=1 + if(dz<-1/2) + dz+=1 + dxt=dx*X1+dy*Y1+dz*Z1 + dyt=dx*X2+dy*Y2+dz*Z2 + dzt=dx*X3+dy*Y3+dz*Z3 + dist=sqrt(dxt^2+dyt^2+dzt^2) + dist*=$7 + if((dist>=($8-$9))&&(dist<=($8+$9))) { + print "" + print "atoms: " $10 " - " $11 + print $1 " " $2 " " $3 + print $4 " " $5 " " $6 " (" dist " - " $8 ")" + print "displace: " dx*X " " dy*Y " " dz*Z + } + }' + fi + + ((ic+=1)) + [ $ic -gt $nt ] && break + + done + + ((count+=1)) + [ $count -gt $nt ] && break + +done + +echo "done" + diff --git a/vasp_tools/stdvis b/vasp_tools/stdvis new file mode 100755 index 0000000..4592d5a --- /dev/null +++ b/vasp_tools/stdvis @@ -0,0 +1,180 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "specify a directory ..." + exit +fi + +if [ -z "$2" ]; then + type="default" +else + type=$2 +fi + +if [ -z "$3" ]; then + trg="video" +else + trg="video.*" +fi + +if [ "$type" != "disp" ]; then + +for i in $1/$trg; do + + if [ -f $i/stdvis ]; then + echo "$i already visualized ..." + continue + else + touch $i/stdvis + fi + +# first unit cell in each direction without rotation +if [ "$type" = "default" -o "$type" = "1" ]; then +echo "type: 1 no rotation" +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 -0.20 -0.50 -fur 1.20 1.20 1.20 \ + -b 0.0 0.0 0.0 1.0 1.0 1.0 \ + -c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \ + -r 0.6 -A 1 217 1.9 +fi + +# first unit cell in each direction without rotation displaying mirrored atoms +if [ "$type" = "1m" ]; then +echo "type: 1 no rotation, mirrored" +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 -0.20 -0.20 -fur 1.20 1.20 1.20 \ + -b 0.0 0.0 0.0 1.0 1.0 1.0 \ + -c 0.3 -1.7 0.9 -L 0.5 -1.0 0.5 \ + -r 0.6 -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 \ + -A 1 216 2.6 + #-A 1 217 2.6 + #-c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \ +fi + +# defect combination view 1 +if [ "$type" = "dc1" ]; then +echo "type: defect combination 1, mirrored" +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 -0.20 -0.80 -fur 1.20 1.20 1.20 \ + -b 0.0 0.0 0.0 1.0 1.0 1.0 \ + -c 0.3 -1.7 0.9 -L 0.5 -1.0 0.5 \ + -r 0.6 -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 \ + -A 2 217 218 2.6 +fi + +# first unit cell in each direction without rotation displaying mirrored atoms +if [ "$type" = "x1y1z13" ]; then +echo "type: x1y1z13, mirrored" +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 -0.20 -1.20 -fur 1.20 1.20 1.20 \ + -b 0.0 0.0 0.0 1.0 1.0 1.0 \ + -c 0.3 -1.7 0.4 -L 0.5 -1.0 0 \ + -r 0.6 -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 \ + -A 1 217 2.6 + #-A 2 109 217 2.6 +fi + +# first unit cell in each direction without rotation displaying mirrored atoms +if [ "$type" = "1m2" ]; then +echo "type: 1 no rotation, mirrored, displaying bonds of the 2 C atoms" +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 -0.20 -0.20 -fur 1.20 1.20 1.20 \ + -b 0.0 0.0 0.0 1.0 1.0 1.0 \ + -c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \ + -r 0.6 -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 \ + -A 2 217 218 2.6 +fi + +if [ "$type" = "1m2dv" ]; then +echo "type: 1 no rotation, mirrored, displaying bonds of db and vac" +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 -0.20 -0.20 -fur 1.20 1.20 1.20 \ + -b 0.0 0.0 0.0 1.0 1.0 1.0 \ + -c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \ + -r 0.6 -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 \ + -A 2 215 216 2.6 +fi + +# three unit cells in each direction without rotation +if [ "$type" = "3" ]; then +echo "type: 3 no rotation" +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 -0.20 -0.20 -fur 3.20 3.20 3.20 \ + -b 0.0 0.0 0.0 3.0 3.0 3.0 \ + -c 2.3 -3.7 2.4 -L 1.5 -1.0 1.5 \ + -r 0.6 -A 1 217 2.6 +fi + +# unti cell 3,0,2 +if [ "$type" = "3x2z" ]; then +echo "type: 3x2z no rotation" +./visualize -w 640 -h 480 -d $i \ + -nll 1.8 -0.2 0.8 -fur 3.20 1.20 2.20 \ + -b 2.0 0.0 1.0 3.0 1.0 2.0 \ + -c 2.3 -3.7 2.4 -L 1.5 -1.0 1.5 \ + -r 0.6 +fi + +# first unit cell rotated by 45 degrees about z-axis +if [ "$type" = "1r" ]; then +echo "type: 1 rotated" +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 -0.70 -0.20 -fur 2.00 0.70 1.20 \ + -c -0.5 -1.5 0.9 -L 1.0 0.0 0.5 \ + -r 0.6 + #-b 0.0 0.0 0.0 0.0 0.0 1.0 \ +fi + +# first unit cell rotated by 45 degrees displaying mirrored atoms +if [ "$type" = "1rm" ]; then +echo "type: 1 rotated, mirrored" +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 -0.20 -0.50 -fur 1.20 1.20 1.20 \ + -b 0.0 0.0 0.0 1.0 1.0 1.0 \ + -c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \ + -r 0.6 -m 2.0 -2.0 0.0 2.0 2.0 0.0 0.0 0.0 3.0 \ + -A 1 193 1.9 +fi + +# three unit cells (rotated) in each direction displaying mirrored atoms +if [ "$type" = "3rm" ]; then +echo "type: 3 roted, mirrored" +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 -0.20 -0.20 -fur 3.20 3.20 3.20 \ + -b 0.0 0.0 0.0 3.0 3.0 3.0 \ + -c 1.3 -3.7 2.4 -L 1.5 -1.0 1.5 \ + -r 0.6 -m 2.0 -2.0 0.0 2.0 2.0 0.0 0.0 0.0 3.0 +fi + +# x: 2,3 y 3 z 1,2 +if [ "$type" = "x123y3z123" ]; then +echo "type: x: 1,2,3 y 3 z 1,2,3" +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 1.80 -0.20 -fur 3.20 3.20 3.20 \ + -b 1.0 2.0 1.0 2.0 3.0 2.0 \ + -c 1.8 -1.7 2.2 -L 1.6 2.5 1.7 \ + -r 0.6 -A 1 217 2.6 \ + -m 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 +fi + +./ppm2avi $i + +done + +else + +# 100 db in type 1 sc (insdide sc) +for i in $1/video/atomic_conf_*.xyz; do + displace=`echo $i | awk -F_ '{ print $7 }' | sed 's/\.xyz//'` + echo "$i $displace ..." +./visualize -w 640 -h 480 -d $i \ + -nll -0.20 -0.20 -0.50 -fur 1.20 1.20 1.20 \ + -b 0.0 0.0 0.0 1.0 1.0 1.0 \ + -c 0.8 -1.7 0.9 -L 0.5 -1.0 0.5 \ + -r 0.6 -B 0.1 -D $displace -m 2.0 -2.0 0.0 2.0 2.0 0.0 0.0 0.0 3.0 +done + +fi + +#mplayer $1/video/md.avi + diff --git a/vasp_tools/tXYZp.c b/vasp_tools/tXYZp.c new file mode 100644 index 0000000..cd96040 --- /dev/null +++ b/vasp_tools/tXYZp.c @@ -0,0 +1,285 @@ +/* + * tXYZp.c + * + * author: frank.zirkelbach@physik.uni-augsburg.de + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +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 -X,Y,Z ...\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 total: ABA^-1A = AB + // => reverse sequence of transformations! + for(i=count-1;i>-1;i--) { + if(rtype[i]) { + if(i==count-1) + b_transform(rtype[i],angle[i], + cosangle[i],sinangle[i], + b,tb[i]); + else + b_transform(rtype[i],angle[i], + cosangle[i],sinangle[i], + tb[i+1],tb[i]); + } + } + + for(i=0;i<3;i++) + dprintf(poso," %f %f %f\n", + tb[0][i][0],tb[0][i][1],tb[0][i][2]); + + // 6th line + cnt=get_line(posr,buf,256); + buf[cnt-1]='\n'; + write(poso,buf,cnt); + + // 7th line + cnt=get_line(posr,buf,256); + buf[cnt-1]='\n'; + write(poso,buf,cnt); + + // 8th line + cnt=get_line(posr,buf,256); + buf[cnt-1]='\n'; + write(poso,buf,cnt); + + while(1) { + cnt=get_line(posr,buf,256); + if(cnt<=0) + break; + wptr=strtok(buf," "); + x[0]=atof(wptr); + wptr=strtok(NULL," "); + x[1]=atof(wptr); + wptr=strtok(NULL," "); + x[2]=atof(wptr); + + wptr=strtok(NULL," "); + t1=wptr[0]; + wptr=strtok(NULL," "); + t2=wptr[0]; + wptr=strtok(NULL," "); + t3=wptr[0]; + + for(i=0;i<3;i++) { + if(rtype[i]) { + X[0]=x[0]; + X[1]=x[1]; + X[2]=x[2]; + a_transform(rtype[i],angle[i], + cosangle[i],sinangle[i], + X,x); + } + } + + dprintf(poso," %f %f %f %c %c %c\n",x[0],x[1],x[2],t1,t2,t3); + } + + close(posr); + close(poso); + + printf("done!\n"); + + return 0; +} + diff --git a/vasp_tools/tXp.c b/vasp_tools/tXp.c new file mode 100644 index 0000000..6b6e6a1 --- /dev/null +++ b/vasp_tools/tXp.c @@ -0,0 +1,222 @@ +/* + * tXp.c + * + * author: frank.zirkelbach@physik.uni-augsburg.de + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +int get_line(int fd,char *line,int max) { + + int count,ret; + + count=0; + + while(1) { + if(count==max) return count; + ret=read(fd,line+count,1); + if(ret<=0) return ret; + if(line[count]=='\n') { + memset(line+count,0,max-count-1); + //line[count]='\0'; + return count+1; + } + count+=1; + } +} + + +int main(int argc,char **argv) { + + double x1,x2,x3,y1,y2,y3,z1,z2,z3; + double x_1,x_2,x_3,y_1,y_2,y_3,z_1,z_2,z_3; + double X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3; + double theta; + double costheta,sintheta; + double normx,normy,normz; + int posr,poso; + char file[128],buf[256]; + char *wptr; + char t1,t2,t3; + int cnt; + + posr=open("POSCAR",O_RDONLY); + if(posr<0) { + perror("open POSCAR (read) file\n"); + return posr; + } + + theta=(atof(argv[1])/180.0*M_PI); + costheta=cos(theta); + sintheta=sin(theta); + + snprintf(file,127,"POSCAR.X%f",theta); + poso=open(file,O_WRONLY|O_CREAT); + if(poso<0) { + perror("open POSCAR (write) file\n"); + return poso; + } + + // first line + cnt=get_line(posr,buf,256); + buf[cnt-1]='\n'; + write(poso,buf,cnt); + + // second line + cnt=get_line(posr,buf,256); + buf[cnt-1]='\n'; + write(poso,buf,cnt); + + // basis + cnt=get_line(posr,buf,256); + wptr=strtok(buf," "); + x1=atof(wptr); + wptr=strtok(NULL," "); + x2=atof(wptr); + wptr=strtok(NULL," "); + x3=atof(wptr); + + cnt=get_line(posr,buf,256); + wptr=strtok(buf," "); + y1=atof(wptr); + wptr=strtok(NULL," "); + y2=atof(wptr); + wptr=strtok(NULL," "); + y3=atof(wptr); + + cnt=get_line(posr,buf,256); + wptr=strtok(buf," "); + z1=atof(wptr); + wptr=strtok(NULL," "); + z2=atof(wptr); + wptr=strtok(NULL," "); + z3=atof(wptr); + + /* norm */ + normx=sqrt(x1*x1+x2*x2+x3*x3); + normy=sqrt(y1*y1+y2*y2+y3*y3); + normz=sqrt(z1*z1+z2*z2+z3*z3); + + /* basis in given basis */ + X1=(x1*x1+x2*x2+x3*x3)/normx; + X2=(y1*x1+y2*x2+y3*x3)/normy; + X3=(z1*x1+z2*x2+z3*x3)/normz; + + Y1=(x1*y1+x2*y2+x3*y3)/normx; + Y2=(y1*y1+y2*y2+y3*y3)/normy; + Y3=(z1*y1+z2*y2+z3*y3)/normz; + + Z1=(x1*z1+x2*z2+x3*z3)/normx; + Z2=(y1*z1+y2*z2+y3*z3)/normy; + Z3=(z1*z1+z2*z2+z3*z3)/normz; + + printf("Basis expressed by itself:\n"); + printf(" %f %f %f\n",X1,Y1,Z1); + printf(" x = %f y = %f z = %f\n",X2,Y2,Z2); + printf(" %f %f %f\n",X3,Y3,Z3); + + /* transformed basis */ + x_1=X1; + x_2=costheta*X2-sintheta*X3; + x_3=sintheta*X2+costheta*X3; + + y_1=Y1; + y_2=costheta*Y2-sintheta*Y3; + y_3=sintheta*Y2+costheta*Y3; + + z_1=Z1; + z_2=costheta*Z2-sintheta*Z3; + z_3=sintheta*Z2+costheta*Z3; + + printf("Transformed basis in the given basis:\n"); + printf(" %f %f %f\n",x_1,y_1,z_1); + printf(" x = %f y = %f z = %f\n",x_2,y_2,z_2); + printf(" %f %f %f\n",x_3,y_3,z_3); + + /* transformed basis in cartesian coordinates */ + X1=(x1/normx*x_1+y1/normy*x_2+z1/normz*x_3); + X2=(x2/normx*x_1+y2/normy*x_2+z2/normz*x_3); + X3=(x3/normx*x_1+y3/normy*x_2+z3/normz*x_3); + + Y1=(x1/normx*y_1+y1/normy*y_2+z1/normz*y_3); + Y2=(x2/normx*y_1+y2/normy*y_2+z2/normz*y_3); + Y3=(x3/normx*y_1+y3/normy*y_2+z3/normz*y_3); + + Z1=(x1/normx*z_1+y1/normy*z_2+z1/normz*z_3); + Z2=(x2/normx*z_1+y2/normy*z_2+z2/normz*z_3); + Z3=(x3/normx*z_1+y3/normy*z_2+z3/normz*z_3); + + printf("Transformed basis in cartesian coordinates:\n"); + printf(" %f %f %f\n",X1,Y1,Z1); + printf(" x = %f y = %f z = %f\n",X2,Y2,Z2); + printf(" %f %f %f\n",X3,Y3,Z3); + + dprintf(poso," %f %f %f\n",X1,X2,X3); + dprintf(poso," %f %f %f\n",Y1,Y2,Y3); + dprintf(poso," %f %f %f\n",Z1,Z2,Z3); + + // 6th line + cnt=get_line(posr,buf,256); + buf[cnt-1]='\n'; + write(poso,buf,cnt); + + // 7th line + cnt=get_line(posr,buf,256); + buf[cnt-1]='\n'; + write(poso,buf,cnt); + + // 8th line + cnt=get_line(posr,buf,256); + buf[cnt-1]='\n'; + write(poso,buf,cnt); + + while(1) { + cnt=get_line(posr,buf,256); + if(cnt<=0) + break; + wptr=strtok(buf," "); + x1=atof(wptr); + wptr=strtok(NULL," "); + x2=atof(wptr); + wptr=strtok(NULL," "); + x3=atof(wptr); + + wptr=strtok(NULL," "); + t1=wptr[0]; + wptr=strtok(NULL," "); + t2=wptr[0]; + wptr=strtok(NULL," "); + t3=wptr[0]; + + X1=x1; + X2=costheta*x2+sintheta*x3; + X3=costheta*x3-sintheta*x2; + + /* check! */ + double tmp1,tmp2,tmp3; + tmp1=(X1*x_1+X2*y_1+X3*z_1)/normx; + tmp2=(X1*x_2+X2*y_2+X3*z_2)/normy; + tmp3=(X1*x_3+X2*y_3+X3*z_3)/normz; + printf("%f %f %f - %f %f %f | %f %f %f\n", + x1,x2,x3,tmp1,tmp2,tmp3,x1-tmp1,x2-tmp2,x3-tmp3); + + dprintf(poso," %f %f %f %c %c %c\n",X1,X2,X3,t1,t2,t3); + } + + close(posr); + close(poso); + + printf("done!\n"); + + return 0; +} + diff --git a/vasp_tools/trafoXposcar b/vasp_tools/trafoXposcar new file mode 100755 index 0000000..1cd5286 --- /dev/null +++ b/vasp_tools/trafoXposcar @@ -0,0 +1,177 @@ +#!/bin/bash + +echo "parsing POSCAR file ..." + +theta=$1 + +trg=POSCAR.Xtrafo$theta + +sicnt=`sed -n 6p POSCAR | awk '{ print $1 }'` +ccnt=`sed -n 6p POSCAR | awk '{ print $2 }'` + +lc=`sed -n 2p POSCAR | awk '{ print $1 }'` + +x1=`sed -n 3p POSCAR | awk '{ print $1 }'` +x2=`sed -n 3p POSCAR | awk '{ print $2 }'` +x3=`sed -n 3p POSCAR | awk '{ print $3 }'` + +y1=`sed -n 4p POSCAR | awk '{ print $1 }'` +y2=`sed -n 4p POSCAR | awk '{ print $2 }'` +y3=`sed -n 4p POSCAR | awk '{ print $3 }'` + +z1=`sed -n 5p POSCAR | awk '{ print $1 }'` +z2=`sed -n 5p POSCAR | awk '{ print $2 }'` +z3=`sed -n 5p POSCAR | awk '{ print $3 }'` + +((total=sicnt+ccnt)) + +echo " Si: $sicnt, C: $ccnt, total: $total" +echo " Lattice constant: $lc A" +echo " Basis:" +echo " $x1 $y1 $z1" +echo " x = $x2 y = $y2 z = $z2" +echo " $x3 $y3 $z3" +echo +echo " -----" +echo " Trafo: x axis, $theta degree" +echo " -----" +echo + +# determine trafo of cartesian coordinates to this one +normx=`echo $x1 $x2 $x3 | awk '{ print sqrt($1*$1+$2*$2+$3*$3) }'` +normy=`echo $y1 $y2 $y3 | awk '{ print sqrt($1*$1+$2*$2+$3*$3) }'` +normz=`echo $z1 $z2 $z3 | awk '{ print sqrt($1*$1+$2*$2+$3*$3) }'` +echo $normx $normz $normy +t11=`echo $x1 $normx | awk '{ print $1/$2 }'` +t12=`echo $x2 $normx | awk '{ print $1/$2 }'` +t13=`echo $x3 $normx | awk '{ print $1/$2 }'` +t21=`echo $y1 $normy | awk '{ print $1/$2 }'` +t22=`echo $y2 $normy | awk '{ print $1/$2 }'` +t23=`echo $y3 $normy | awk '{ print $1/$2 }'` +t31=`echo $z1 $normz | awk '{ print $1/$2 }'` +t32=`echo $z2 $normz | awk '{ print $1/$2 }'` +t33=`echo $z3 $normz | awk '{ print $1/$2 }'` +echo " Matrix from cartesian to used coordinates:" +echo " | $t11 $t21 $t31 |" +echo " | $t12 $t22 $t32 |" +echo " | $t13 $t23 $t33 |" +echo +i11=$t11 +i12=$t21 +i13=$t31 +i21=$t12 +i22=$t22 +i23=$t32 +i31=$t13 +i32=$t23 +i33=$t33 +echo " Inverse matrix (i=t^T):" +echo " | $i11 $i21 $i31 |" +echo " | $i12 $i22 $i32 |" +echo " | $i13 $i23 $i33 |" +echo +# i * basis +X1=`echo $i11 $i21 $i31 $x1 $x2 $x3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +X2=`echo $i12 $i22 $i32 $x1 $x2 $x3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +X3=`echo $i13 $i23 $i33 $x1 $x2 $x3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` + +Y1=`echo $i11 $i21 $i31 $y1 $y2 $y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +Y2=`echo $i12 $i22 $i32 $y1 $y2 $y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +Y3=`echo $i13 $i23 $i33 $y1 $y2 $y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` + +Z1=`echo $i11 $i21 $i31 $z1 $z2 $z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +Z2=`echo $i12 $i22 $i32 $z1 $z2 $z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +Z3=`echo $i13 $i23 $i33 $z1 $z2 $z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +echo " Basis (in rotation system):" +echo " $X1 $Y1 $Z1" +echo " x = $X2 y = $Y2 z = $Z2" +echo " $X3 $Y3 $Z3" +echo + +costheta=`echo $theta | awk '{ print cos($1*3.1415927/180.0) }'` +sintheta=`echo $theta | awk '{ print sin($1*3.1415927/180.0) }'` + +x1=$X1 +x2=$X2 +x3=$X3 +X1=$x1 +X2=`echo $x2 $x3 $costheta $sintheta | awk '{ print $3*$1-$4*$2 }'` +X3=`echo $x2 $x3 $costheta $sintheta | awk '{ print $4*$1+$3*$2 }'` + +y1=$Y1 +y2=$Y2 +y3=$Y3 +Y1=$y1 +Y2=`echo $y2 $y3 $costheta $sintheta | awk '{ print $3*$1-$4*$2 }'` +Y3=`echo $y2 $y3 $costheta $sintheta | awk '{ print $4*$1+$3*$2 }'` + +z1=$Z1 +z2=$Z2 +z3=$Z3 +Z1=$z1 +Z2=`echo $z2 $z3 $costheta $sintheta | awk '{ print $3*$1-$4*$2 }'` +Z3=`echo $z2 $z3 $costheta $sintheta | awk '{ print $4*$1+$3*$2 }'` + +echo " Transformed basis (in rotation system):" +echo " $X1 $Y1 $Z1" +echo " x' = $X2 y' = $Y2 z' = $Z2" +echo " $X3 $Y3 $Z3" +echo + +# t * basis +x1=`echo $t11 $t21 $t31 $X1 $X2 $X3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +x2=`echo $t12 $t22 $t32 $X1 $X2 $X3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +x3=`echo $t13 $t23 $t33 $X1 $X2 $X3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +X1=$x1 +X2=$x2 +X3=$x3 + +y1=`echo $t11 $t21 $t31 $Y1 $Y2 $Y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +y2=`echo $t12 $t22 $t32 $Y1 $Y2 $Y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +y3=`echo $t13 $t23 $t33 $Y1 $Y2 $Y3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +Y1=$y1 +Y2=$y2 +Y3=$y3 + +z1=`echo $t11 $t21 $t31 $Z1 $Z2 $Z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +z2=`echo $t12 $t22 $t32 $Z1 $Z2 $Z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +z3=`echo $t13 $t23 $t33 $Z1 $Z2 $Z3 | awk '{ print $1*$4+$2*$5+$3*$6 }'` +Z1=$z1 +Z2=$z2 +Z3=$z3 + + +echo " Transformed basis (cartesian coordinates):" +echo " $X1 $Y1 $Z1" +echo " x' = $X2 y' = $Y2 z' = $Z2" +echo " $X3 $Y3 $Z3" +echo + +cnt=0 +tcnt=0 + +cx=1.0 +cy=1.0 +cz=0.8 + +# header +sed -n 1p POSCAR > $trg +echo " $lc" >> $trg +echo " $X1 $X2 $X3" >> $trg +echo " $Y1 $Y2 $Y3" >> $trg +echo " $Z1 $Z2 $Z3" >> $trg +echo " $sicnt $ccnt" >> $trg +echo "selective dynamics" >> $trg +echo "direct" >> $trg + +tail -${total} POSCAR | \ + while read x y z fx fy fz; do + Y=`echo $y $z $costheta $sintheta | \ + awk '{ print $3*$1+$4*$2 }'` + Z=`echo $y $z $costheta $sintheta | \ + awk '{ print $3*$2-$4*$1 }'` + echo " $x $Y $Z $fx $fy $fz" >> $trg + done + +echo "done" + diff --git a/vasp_tools/visualize b/vasp_tools/visualize new file mode 100755 index 0000000..1ed430c --- /dev/null +++ b/vasp_tools/visualize @@ -0,0 +1,453 @@ +#!/bin/sh + +# +# visualization script +# author: frank.zirkelbach@physik.uni-augsburg.de +# + +# help function +draw_cyl() { + cat >> temp.pov <<-EOF +cylinder { +<$1, $3, $2>, <$4, $6, $5>, 0.05 +pigment { color White } +} +EOF +} +draw_bond() { + cat >> temp.pov <<-EOF +cylinder { +<$1, $3, $2>, <$4, $6, $5>, $7 +pigment { color Blue } +} +EOF +} + +# defaults + +lc=5.429 +directory="doesnt_exist____for_sure" +width="640" +height="480" +radius="0.6" +x0="-0.6"; y0="-0.6"; z0="-0.6"; +x1="0.6"; y1="0.6"; z1="0.6"; +cx=""; cy=""; cz=""; +lx="0"; ly="-100"; lz="100"; +ortographic="" +bx0=""; by0=""; bz0=""; +bx1=""; by1=""; bz1=""; +bcr="0.1"; +clx="0"; cly="0"; clz="0"; +extra=0 +displace="" +mirror=0 +mx1=0; mx2=0; mx3=0; +my1=0; my2=0; my3=0; +mz1=0; mz2=0; mz3=0; +ab=0 + +# parse argv + +while [ "$1" ]; do + case "$1" in + -d) directory=$2; shift 2;; + -w) width=$2; shift 2;; + -h) height=$2; shift 2;; + -r) radius=$2; shift 2;; + -nll) x0=$2; y0=$3; z0=$4; shift 4;; + -fur) x1=$2; y1=$3; z1=$4; shift 4;; + -c) cx=$2; cy=$3; cz=$4; shift 4;; + -L) clx=$2; cly=$3; clz=$4; shift 4;; + -l) lx=$2; ly=$3; lz=$4; shift 4;; + -o) ortographic=1; shift 1;; + -b) bx0=$2; by0=$3; bz0=$4; + bx1=$5; by1=$6; bz1=$7; shift 7;; + -B) bcr=$2; shift 2;; + -C) lc=$2; shift 2;; + -e) extra=1; shift 1;; + -D) displace=$2; shift 2;; + -m) mx1=$2; mx2=$3; mx3=$4; + my1=$5; my2=$6; my3=$7; + mz1=$8; mz2=$9; mz3=${10}; + mirror=1; shift 10;; + -A) ab=$2; shift 2; + ((cnt=1)) + while [ $cnt -le $ab ]; do + anr[$cnt]=$1; shift 1; + ((cnt+=1)) + done + cutoff=$1; shift 1;; + *) + echo "options:" + echo "########" + echo "directory to progress:" + echo " -d (mandatory)" + echo "png dim:" + echo " -w " + echo " -h " + echo "atom size:" + echo " -r " + echo " -B " + echo "unit cell:" + echo " -C " + echo " -m (mirror atoms)" + echo "visualization volume:" + echo " -nll (near lower left)" + echo " -fur (far upper right)" + echo " -o (ortographic)" + echo "bounding box:" + echo " -b " + echo "povray:" + echo " -c (camera position)" + echo " -L (camera look)" + echo " -l (light source)" + echo "bonds:" + echo " -ab (auto bonds)" + exit 1;; + esac +done + +# calculation from lattic eunits to angstroms + +[ "$lc" = "sic" ] && lc=4.359 +[ "$lc" = "si" ] && lc=5.480 +[ "$lc" = "c" ] && lc=3.566 + +#offset=`echo 0.125 \* $lc | bc` +offset=0.0 + +x0=`echo $x0 \* $lc + $offset | bc` +y0=`echo $y0 \* $lc + $offset | bc` +z0=`echo $z0 \* $lc + $offset | bc` +x1=`echo $x1 \* $lc + $offset | bc` +y1=`echo $y1 \* $lc + $offset | bc` +z1=`echo $z1 \* $lc + $offset | bc` + +mx1=`echo $mx1 \* $lc + $offset | bc` +my1=`echo $my1 \* $lc + $offset | bc` +mz1=`echo $mz1 \* $lc + $offset | bc` +mx2=`echo $mx2 \* $lc + $offset | bc` +my2=`echo $my2 \* $lc + $offset | bc` +mz2=`echo $mz2 \* $lc + $offset | bc` +mx3=`echo $mx3 \* $lc + $offset | bc` +my3=`echo $my3 \* $lc + $offset | bc` +mz3=`echo $mz3 \* $lc + $offset | bc` + +clx=`echo $clx \* $lc + $offset | bc` +cly=`echo $cly \* $lc + $offset | bc` +clz=`echo $clz \* $lc + $offset | bc` + +if [ -n "$cx" -a -n "$cy" -a -n "$cz" ]; then + cx=`echo $cx \* $lc + $offset | bc` + cy=`echo $cy \* $lc + $offset | bc` + cz=`echo $cz \* $lc + $offset | bc` +fi + +if [ -n "$bx0" ]; then + bx0=`echo $bx0 \* $lc + $offset | bc` + by0=`echo $by0 \* $lc + $offset | bc` + bz0=`echo $bz0 \* $lc + $offset | bc` + bx1=`echo $bx1 \* $lc + $offset | bc` + by1=`echo $by1 \* $lc + $offset | bc` + bz1=`echo $bz1 \* $lc + $offset | bc` +fi + +# povray command + +POVRAY="povray -W${width} -H${height} -d" + +# convert options + +COPTS="-font /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf" +COPTS="$COPTS -depth 8 -fill white -stroke blue -pointsize 24" + +# do it ... + +if [ -d $directory ]; then + filesource=$directory/atomic_conf_*.xyz +fi + +if [ -f $directory ]; then + filesource=$directory +fi + +for file in $filesource; do + + cat > temp.pov <<-EOF +#include "colors.inc" +#include "textures.inc" +#include "shapes.inc" +#include "glass.inc" +#include "metals.inc" +#include "woods.inc" +#include "stones.inc" +EOF + + # meta info + count=`grep '# \[P\]' $file | awk '{ print $3 }'` + time=`grep '# \[P\]' $file | awk '{ print $4 }'` + camloc=`grep '# \[P\]' $file | awk '{ print $5 }'` + [ -n "$cx" -a -n "$cy" -a -n "$cz" ] && camloc="<$cx,$cz,$cy>" + + # atoms +#echo "-----> $x0 $y0 $z0 $x1 $y1 $z1 <-----" + if [ -n "$x0" ]; then + export x0 y0 z0 x1 y1 z1 radius extra + export mx1 mx2 mx3 + export my1 my2 my3 + export mz1 mz2 mz3 + export mirror + cat $file | grep -v '#' | awk '\ + BEGIN { + x0=ENVIRON["x0"]; y0=ENVIRON["y0"]; z0=ENVIRON["z0"]; + x1=ENVIRON["x1"]; y1=ENVIRON["y1"]; z1=ENVIRON["z1"]; + mx1=ENVIRON["mx1"]; my1=ENVIRON["my1"]; + mz1=ENVIRON["mz1"]; mx2=ENVIRON["mx2"]; + my2=ENVIRON["my2"]; mz2=ENVIRON["mz2"]; + mx3=ENVIRON["mx3"]; my3=ENVIRON["my3"]; + mz3=ENVIRON["mz3"]; mirror=ENVIRON["mirror"]; + radius=ENVIRON["radius"]; extra=ENVIRON["extra"]; + nx=0; ny=0; nz=0; + } + { + if(($2>=x0)&&($3>=y0)&&($4>=z0)&&\ + ($2<=x1)&&($3<=y1)&&($4<=z1)) { + print "sphere { <"$2","$4","$3">, "radius" "; + if(extra) + print "texture { pigment { color rgb<"$6/4.4",0,"1-$6/4.4"> } "; + else + print "texture { pigment { color "$5" } "; + print "finish { phong 1 metallic } } }"; + } + + if(mirror) { + + nx=$2-mx1; ny=$3-mx2; nz=$4-mx3; + if((nx>=x0)&&(ny>=y0)&&(nz>=z0)&&\ + (nx<=x1)&&(ny<=y1)&&(nz<=z1)) { +print "// translation: "$2/5.480" "$3/5.480" "$4/5.480" -> "nx/5.480" "ny/5.480" "nz/5.480" ..."; + print "sphere { <"nx","nz","ny">, "radius" "; + if(extra) + print "texture { pigment { color rgb<"$6/4.4",0,"1-$6/4.4"> } "; + else + print "texture { pigment { color "$5" } "; + print "finish { phong 1 metallic } } }"; + } + nx=$2-my1; ny=$3-my2; nz=$4-my3; + if((nx>=x0)&&(ny>=y0)&&(nz>=z0)&&\ + (nx<=x1)&&(ny<=y1)&&(nz<=z1)) { + print "sphere { <"nx","nz","ny">, "radius" "; + if(extra) + print "texture { pigment { color rgb<"$6/4.4",0,"1-$6/4.4"> } "; + else + print "texture { pigment { color "$5" } "; + print "finish { phong 1 metallic } } }"; + } + nx=$2-mz1; ny=$3-mz2; nz=$4-mz3; + if((nx>=x0)&&(ny>=y0)&&(nz>=z0)&&\ + (nx<=x1)&&(ny<=y1)&&(nz<=z1)) { + print "sphere { <"nx","nz","ny">, "radius" "; + if(extra) + print "texture { pigment { color rgb<"$6/4.4",0,"1-$6/4.4"> } "; + else + print "texture { pigment { color "$5" } "; + print "finish { phong 1 metallic } } }"; + } + + } + + }' >> temp.pov + else + cat $file | grep -v '#' | while read name x y z color temp; do + cat >> temp.pov <<-EOF +sphere { +<$x, $z, $y>, $radius +texture { +pigment { color $color } +finish { +phong 1 +metallic +} +} +} +EOF + done + fi + + # boundaries + if [ -z "$bx0" ]; then + + #if [ -z "$x0" ]; then + + cat $file | grep '# \[D\]' | while read foo bar x1 y1 z1 x2 y2 z2 ; do + draw_cyl $x1 $y1 $z1 $x2 $y2 $z2 0.05 + done + + #else + + # manually drawing the 3x4 boundaries ... +# draw_cyl $x0 $y0 $z0 $x1 $y0 $z0 +# draw_cyl $x0 $y0 $z0 $x0 $y1 $z0 +# draw_cyl $x1 $y1 $z0 $x1 $y0 $z0 +# draw_cyl $x0 $y1 $z0 $x1 $y1 $z0 + +# draw_cyl $x0 $y0 $z1 $x1 $y0 $z1 +# draw_cyl $x0 $y0 $z1 $x0 $y1 $z1 +# draw_cyl $x1 $y1 $z1 $x1 $y0 $z1 +# draw_cyl $x0 $y1 $z1 $x1 $y1 $z1 + +# draw_cyl $x0 $y0 $z1 $x0 $y0 $z0 +# draw_cyl $x0 $y1 $z1 $x0 $y1 $z0 +# draw_cyl $x1 $y0 $z1 $x1 $y0 $z0 +# draw_cyl $x1 $y1 $z1 $x1 $y1 $z0 +# fi + + else + + # manually drawing the 3x4 boundaries specified by argv ... + draw_cyl $bx0 $by0 $bz0 $bx1 $by0 $bz0 + draw_cyl $bx0 $by0 $bz0 $bx0 $by1 $bz0 + draw_cyl $bx1 $by1 $bz0 $bx1 $by0 $bz0 + draw_cyl $bx0 $by1 $bz0 $bx1 $by1 $bz0 + + draw_cyl $bx0 $by0 $bz1 $bx1 $by0 $bz1 + draw_cyl $bx0 $by0 $bz1 $bx0 $by1 $bz1 + draw_cyl $bx1 $by1 $bz1 $bx1 $by0 $bz1 + draw_cyl $bx0 $by1 $bz1 $bx1 $by1 $bz1 + + draw_cyl $bx0 $by0 $bz1 $bx0 $by0 $bz0 + draw_cyl $bx0 $by1 $bz1 $bx0 $by1 $bz0 + draw_cyl $bx1 $by0 $bz1 $bx1 $by0 $bz0 + draw_cyl $bx1 $by1 $bz1 $bx1 $by1 $bz0 + + fi + + # bonds + if [ -n "$bcr" ]; then + + if [ -z "$x0" ]; then + + cat $file | grep '# \[B\]' | while read foo bar x1 y1 z1 x2 y2 z2 ; do + draw_bond $x1 $z1 $y1 $x2 $z2 $y2 $bcr + done + + else + + export x0 y0 z0 x1 y1 z1 bcr + cat $file | grep '# \[B\]' | awk '\ + BEGIN { + x0=ENVIRON["x0"]; y0=ENVIRON["y0"]; z0=ENVIRON["z0"]; + x1=ENVIRON["x1"]; y1=ENVIRON["y1"]; z1=ENVIRON["z1"]; + bcr=ENVIRON["bcr"]; + } + { + if(($3>=x0)&&($4>=y0)&&($5>=z0)&&\ + ($3<=x1)&&($4<=y1)&&($5<=z1)) { + print "cylinder {"; + print "<"$3","$5","$4">,"; + print "<"$6","$8","$7">, "bcr; + print "pigment { color Blue }"; + print "}"; + } + }' >> temp.pov + + fi + fi + + # auto bonds + if [ "$ab" != "0" ]; then + ((cnt=1)) + while [ $cnt -le $ab ]; do + anr=${anr[$cnt]} + + ((tmp=anr+1)) + line="`sed -n ${tmp}p $file`" + aX=`echo $line | awk '{ print $2 }'` + aY=`echo $line | awk '{ print $3 }'` + aZ=`echo $line | awk '{ print $4 }'` + export aX aY aZ cutoff mirror + cat $file | grep -v '#' | awk '\ + BEGIN { + x=ENVIRON["aX"]; y=ENVIRON["aY"]; z=ENVIRON["aZ"]; + co=ENVIRON["cutoff"]; dist=0; bcr=ENVIRON["bcr"]; + mx1=ENVIRON["mx1"]; my1=ENVIRON["my1"]; + mz1=ENVIRON["mz1"]; mx2=ENVIRON["mx2"]; + my2=ENVIRON["my2"]; mz2=ENVIRON["mz2"]; + mx3=ENVIRON["mx3"]; my3=ENVIRON["my3"]; + mz3=ENVIRON["mz3"]; mirror=ENVIRON["mirror"]; + } + { + dist=sqrt((x-$2)^2+(y-$3)^2+(z-$4)^2); + if((dist<=co)&&(dist>0.01)) { + print "cylinder {"; + print "<"x","z","y">,"; + print "<"$2","$4","$3">, "bcr; + print "pigment { color Blue }"; + print "}"; + } + + if(mirror) { + nx=$2-mx1; ny=$3-mx2; nz=$4-mx3; + dist=sqrt((x-nx)^2+(y-ny)^2+(z-nz)^2) + if((dist<=co)&&(dist>0.01)) { + print "cylinder {"; + print "<"x","z","y">,"; + print "<"nx","nz","ny">, "bcr; + print "pigment { color Blue }"; + print "}"; + } + nx=$2-my1; ny=$3-my2; nz=$4-my3; + dist=sqrt((x-nx)^2+(y-ny)^2+(z-nz)^2) + if((dist<=co)&&(dist>0.01)) { + print "cylinder {"; + print "<"x","z","y">,"; + print "<"nx","nz","ny">, "bcr; + print "pigment { color Blue }"; + print "}"; + } + nx=$2-mz1; ny=$3-mz2; nz=$4-mz3; + dist=sqrt((x-nx)^2+(y-ny)^2+(z-nz)^2) + if((dist<=co)&&(dist>0.01)) { + print "cylinder {"; + print "<"x","z","y">,"; + print "<"nx","nz","ny">, "bcr; + print "pigment { color Blue }"; + print "}"; + } + } + + }' >> temp.pov + + ((cnt+=1)) + done + fi + + # add camera and light source + cat >> temp.pov <<-EOF +camera { +EOF + if [ -n "$ortographic" ]; then cat >> temp.pov <<-EOF +orthographic +EOF + fi + cat >> temp.pov <<-EOF +location $camloc +look_at <$clx,$clz,$clz> +} +light_source { <0,100,-100> color White shadowless } +EOF + + # mv png + $POVRAY temp.pov > /dev/null 2>&1 + time=`basename $file | awk -F. '{ print $1 }' | awk -F_ '{ print $3 }'` + if [ ! -z $displace ]; then + convert $COPTS -draw "text 5,20 'd = $displace %'" temp.png temp.png + else + convert $COPTS -draw "text 5,20 't = $time fs'" temp.png temp.png + fi + mv temp.png `echo $file | sed 's/\.xyz/\.png/'` + +done + +echo "done" diff --git a/vasp_tools/visualize_contcar b/vasp_tools/visualize_contcar new file mode 100755 index 0000000..61ed143 --- /dev/null +++ b/vasp_tools/visualize_contcar @@ -0,0 +1,497 @@ +#!/bin/sh + +# +# visualization script +# author: frank.zirkelbach@physik.uni-augsburg.de +# + +# help function +draw_cyl() { + cat >> temp.pov <<-EOF +cylinder { +<$1, $3, $2>, <$4, $6, $5>, 0.05 +pigment { color White } +} +EOF +} +draw_bond() { + cat >> temp.pov <<-EOF +cylinder { +<$1, $3, $2>, <$4, $6, $5>, $7 +pigment { + color rgbf <0, 0, 1.0, 0.8> + finish { phong 1 metallic } +} +} +EOF +} + +# defaults + +lc=5.429 +directory="doesnt_exist____for_sure" +width="640" +height="480" +radius="0.6" +x0="-0.6"; y0="-0.6"; z0="-0.6"; +x1="0.6"; y1="0.6"; z1="0.6"; +cx=""; cy=""; cz=""; +lx="0"; ly="-100"; lz="100"; +ortographic="" +bx0=""; by0=""; bz0=""; +bx1=""; by1=""; bz1=""; +bcr="0.1"; +clx="0"; cly="0"; clz="0"; +extra=0 +displace="" +mirror=0 +mx1=0; mx2=0; mx3=0; +my1=0; my2=0; my3=0; +mz1=0; mz2=0; mz3=0; +ab=0 +sym=0 + +# parse argv + +while [ "$1" ]; do + case "$1" in + -d) directory=$2; shift 2;; + -w) width=$2; shift 2;; + -h) height=$2; shift 2;; + -r) radius=$2; shift 2;; + -nll) x0=$2; y0=$3; z0=$4; shift 4;; + -fur) x1=$2; y1=$3; z1=$4; shift 4;; + -c) cx=$2; cy=$3; cz=$4; shift 4;; + -L) clx=$2; cly=$3; clz=$4; shift 4;; + -l) lx=$2; ly=$3; lz=$4; shift 4;; + -o) ortographic=1; shift 1;; + -b) bx0=$2; by0=$3; bz0=$4; + bx1=$5; by1=$6; bz1=$7; shift 7;; + -B) bcr=$2; shift 2;; + -C) lc=$2; shift 2;; + -e) extra=1; shift 1;; + -D) displace=$2; shift 2;; + -m) mx1=$2; mx2=$3; mx3=$4; + my1=$5; my2=$6; my3=$7; + mz1=$8; mz2=$9; mz3=${10}; + mirror=1; shift 10;; + -A) ab=$2; shift 2; + ((cnt=1)) + while [ $cnt -le $ab ]; do + anr[$cnt]=$1; shift 1; + ((cnt+=1)) + done + cutoff=$1; shift 1;; + -s) sym=$2; shift 2;; + *) + echo "options:" + echo "########" + echo "directory to progress:" + echo " -d (mandatory)" + echo "png dim:" + echo " -w " + echo " -h " + echo "atom size:" + echo " -r " + echo " -B " + echo "unit cell:" + echo " -C " + echo " -m (mirror atoms)" + echo "visualization volume:" + echo " -nll (near lower left)" + echo " -fur (far upper right)" + echo " -o (ortographic)" + echo "bounding box:" + echo " -b " + echo "povray:" + echo " -c (camera position)" + echo " -L (camera look)" + echo " -l (light source)" + echo "bonds:" + echo " -ab (auto bonds)" + echo "symmetry:" + echo " -s " + 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" diff --git a/visual_atoms.c b/visual_atoms.c index 50507db..68901ec 100644 --- a/visual_atoms.c +++ b/visual_atoms.c @@ -16,6 +16,21 @@ #include "moldyn.h" +/* pse */ +#define PSE_NAME +#define PSE_COL +#include "pse.h" +#undef PSE_NAME +#undef PSE_COL + +typedef struct s_data { + int ca; + double radius; + double lc; + int ma; + double ox,oy,oz; +} t_data; + int usage(char *prog) { printf("\nusage:\n"); @@ -25,33 +40,47 @@ int usage(char *prog) { return -1; } +int process(t_moldyn *moldyn,t_atom *itom,t_atom *jtom,void *ptr,u8 bc) { + + t_3dvec dist; + double d; + t_data *data; + + data=ptr; + + v3_sub(&dist,&(itom->r),&(jtom->r)); + if(bc) check_per_bound(moldyn,&dist); + d=v3_norm(&dist); + + if(d<=data->radius) { + printf("%s %f %f %f %s %f\n", + pse_name[jtom->element], + jtom->r.x+data->ox,jtom->r.y+data->oy,jtom->r.z+data->oz, + (jtom->tag==data->ma)?"Red":pse_col[jtom->element], + jtom->ekin); + } + + return 0; +} + int main(int argc,char **argv) { t_moldyn moldyn; - t_atom *itom,*jtom; - int j; + t_data data; int ret; - t_list n[27]; - t_list *this; - t_linkcell *lc; - t_3dvec dist; - double d,radius; - double ox,oy,oz; - int ma,ca; - double lac; + t_atom *atom; if(argc<4) { usage(argv[0]); return -1; } - - ca=atoi(argv[2]); - radius=atof(argv[3]); - lac=atof(argv[4]); - - ma=-1; + + data.ca=atoi(argv[2]); + data.radius=atof(argv[3]); + data.lc=atof(argv[4]); + data.ma=-1; if(argc==6) - ma=atoi(argv[5]); + data.ma=atoi(argv[5]); memset(&moldyn,0,sizeof(t_moldyn)); @@ -63,87 +92,52 @@ int main(int argc,char **argv) { } /* link cell init */ - moldyn.cutoff=radius; + moldyn.cutoff=data.radius; link_cell_init(&moldyn,VERBOSE); - lc=&(moldyn.lc); - - /* serach atoms */ - itom=&(moldyn.atom[ca]); - link_cell_neighbour_index(&moldyn, - (itom->r.x+moldyn.dim.x/2)/lc->x, - (itom->r.y+moldyn.dim.y/2)/lc->y, - (itom->r.z+moldyn.dim.z/2)/lc->z, - n); + atom=&(moldyn.atom[data.ca]); /* prepare offset */ - ox=0.0; - if(itom->r.x<0) { - while((itom->r.x+ox)<(-lac/2.0)) - ox+=lac; + data.ox=0.0; + if(atom->r.x<0) { + while((atom->r.x+data.ox)<(-data.lc/2.0)) + data.ox+=data.lc; } else { - while((itom->r.x+ox)>(lac/2.0)) - ox-=lac; + while((atom->r.x+data.ox)>(data.lc/2.0)) + data.ox-=data.lc; } - oy=0.0; - if(itom->r.y<0) { - while((itom->r.y+oy)<(-lac/2.0)) - oy+=lac; + data.oy=0.0; + if(atom->r.y<0) { + while((atom->r.y+data.oy)<(-data.lc/2.0)) + data.oy+=data.lc; } else { - while((itom->r.y+oy)>(lac/2.0)) - oy-=lac; + while((atom->r.y+data.oy)>(data.lc/2.0)) + data.oy-=data.lc; } - oz=0.0; - if(itom->r.z<0) { - while((itom->r.z+oz)<(-lac/2.0)) - oz+=lac; + data.oz=0.0; + if(atom->r.z<0) { + while((atom->r.z+data.oz)<(-data.lc/2.0)) + data.oz+=data.lc; } else { - while((itom->r.z+oz)>(lac/2.0)) - oz-=lac; + while((atom->r.z+data.oz)>(data.lc/2.0)) + data.oz-=data.lc; } - + /* print the centered atom */ printf("%s %f %f %f %s %f\n", - pse_name[itom->element],itom->r.x+ox,itom->r.y+oy,itom->r.z+oz, - "Green",itom->ekin); - - for(j=0;j<27;j++) { - this=&(n[j]); - list_reset_f(this); - - if(this->start==NULL) - continue; - - do { - - jtom=this->current->data; - - if(jtom==itom) - continue; - - v3_sub(&dist,&(itom->r),&(jtom->r)); - check_per_bound(&moldyn,&dist); - d=v3_norm(&dist); - - if(d<=radius) { - printf("%s %f %f %f %s %f\n", - pse_name[jtom->element], - jtom->r.x+ox,jtom->r.y+oy,jtom->r.z+oz, - (jtom->tag==ma)?"Red":pse_col[jtom->element], - jtom->ekin); - } - - } while(list_next_f(this)!=L_NO_NEXT_ELEMENT); - } + pse_name[atom->element],atom->r.x+data.ox,atom->r.y+data.oy, + atom->r.z+data.oz,"Green",atom->ekin); + process_neighbours(&moldyn,&data,atom,process); + link_cell_shutdown(&moldyn); - moldyn_free_save_file(&moldyn); return 0; } + diff --git a/visual_atoms_script b/visual_atoms_script new file mode 100755 index 0000000..2b7f55f --- /dev/null +++ b/visual_atoms_script @@ -0,0 +1,33 @@ +#!/bin/bash + +rm -f $5/va_*.* + +((count=0)) + +./search_bonds $1 $2 $3 $4 | grep ' # atoms' | while read a b c d e f; do + + ca=`echo $c | awk -F/ '{ print $1}'` + ma=`echo $d | awk -F/ '{ print $1}'` + + ./visual_atoms $1 $ca 12.0 5.429 $ma | \ + grep ^[A-Z] > $5/va_${count}.xyz + + which povray + ret=$? + if [ "$ret" = "0" ]; then + ./visualize -w 640 -h 480 -d $5/va_${count}.xyz \ + -nll -0.76 -0.76 -0.76 -fur 0.76 0.76 0.76 \ + -b -0.5 -0.5 -0.5 0.5 0.5 0.5 \ + -c -0.2 -2.0 0.6 -L 0 0 -0.1 \ + -r 0.6 -B 0.1 + fi + + echo -en "$count " + + ((count+=1)) +done + +echo "done" + +qiv $5/va_*.png + diff --git a/visualize b/visualize index 7dc964e..0b8fc61 100755 --- a/visualize +++ b/visualize @@ -31,7 +31,7 @@ width="640" height="480" radius="0.6" x0="-0.6"; y0="-0.6"; z0="-0.6"; -x1="+0.6"; y1="+0.6"; z1="+0.6"; +x1="0.6"; y1="0.6"; z1="0.6"; cx=""; cy=""; cz=""; lx="0"; ly="-100"; lz="100"; ortographic="" @@ -39,6 +39,7 @@ bx0=""; by0=""; bz0=""; bx1=""; by1=""; bz1=""; bcr=""; clx="0"; cly="0"; clz="0"; +extra=0 # parse argv @@ -58,6 +59,7 @@ while [ "$1" ]; do bx1=$5; by1=$6; bz1=$7; shift 7;; -B) bcr=$2; shift 2;; -C) lc=$2; shift 2;; + -e) extra=1; shift 1;; *) echo "options:" echo "########" @@ -92,6 +94,7 @@ done [ "$lc" = "c" ] && lc=3.566 offset=`echo 0.125 \* $lc | bc` +#offset=0.0 x0=`echo $x0 \* $lc + $offset | bc` y0=`echo $y0 \* $lc + $offset | bc` @@ -123,6 +126,11 @@ fi POVRAY="povray -W${width} -H${height} -d" +# convert options + +COPTS="-font /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf" +COPTS="$COPTS -depth 8 -fill white -stroke blue -pointsize 24" + # do it ... if [ -d $directory ]; then @@ -153,18 +161,21 @@ EOF # atoms if [ -n "$x0" ]; then - export x0 y0 z0 x1 y1 z1 radius + export x0 y0 z0 x1 y1 z1 radius extra cat $file | grep -v '#' | awk '\ BEGIN { x0=ENVIRON["x0"]; y0=ENVIRON["y0"]; z0=ENVIRON["z0"]; x1=ENVIRON["x1"]; y1=ENVIRON["y1"]; z1=ENVIRON["z1"]; - radius=ENVIRON["radius"]; + radius=ENVIRON["radius"]; extra=ENVIRON["extra"]; } { if(($2>=x0)&&($3>=y0)&&($4>=z0)&&\ ($2<=x1)&&($3<=y1)&&($4<=z1)) { print "sphere { <"$2","$4","$3">, "radius" "; - print "texture { pigment { color "$5" } "; + if(extra) + print "texture { pigment { color rgb<"$6/4.4",0,"1-$6/4.4"> } "; + else + print "texture { pigment { color "$5" } "; print "finish { phong 1 metallic } } }"; } }' >> temp.pov @@ -188,29 +199,30 @@ EOF # boundaries if [ -z "$bx0" ]; then - if [ -z "$x0" ]; then + #if [ -z "$x0" ]; then cat $file | grep '# \[D\]' | while read foo bar x1 y1 z1 x2 y2 z2 ; do - draw_cyl $x1 $z1 $y1 $x2 $z2 $y2 0.05 + draw_cyl $x1 $y1 $z1 $x2 $y2 $z2 0.05 done - else + #else + # manually drawing the 3x4 boundaries ... - draw_cyl $x0 $y0 $z0 $x1 $y0 $z0 - draw_cyl $x0 $y0 $z0 $x0 $y1 $z0 - draw_cyl $x1 $y1 $z0 $x1 $y0 $z0 - draw_cyl $x0 $y1 $z0 $x1 $y1 $z0 - - draw_cyl $x0 $y0 $z1 $x1 $y0 $z1 - draw_cyl $x0 $y0 $z1 $x0 $y1 $z1 - draw_cyl $x1 $y1 $z1 $x1 $y0 $z1 - draw_cyl $x0 $y1 $z1 $x1 $y1 $z1 - - draw_cyl $x0 $y0 $z1 $x0 $y0 $z0 - draw_cyl $x0 $y1 $z1 $x0 $y1 $z0 - draw_cyl $x1 $y0 $z1 $x1 $y0 $z0 - draw_cyl $x1 $y1 $z1 $x1 $y1 $z0 - fi +# draw_cyl $x0 $y0 $z0 $x1 $y0 $z0 +# draw_cyl $x0 $y0 $z0 $x0 $y1 $z0 +# draw_cyl $x1 $y1 $z0 $x1 $y0 $z0 +# draw_cyl $x0 $y1 $z0 $x1 $y1 $z0 + +# draw_cyl $x0 $y0 $z1 $x1 $y0 $z1 +# draw_cyl $x0 $y0 $z1 $x0 $y1 $z1 +# draw_cyl $x1 $y1 $z1 $x1 $y0 $z1 +# draw_cyl $x0 $y1 $z1 $x1 $y1 $z1 + +# draw_cyl $x0 $y0 $z1 $x0 $y0 $z0 +# draw_cyl $x0 $y1 $z1 $x0 $y1 $z0 +# draw_cyl $x1 $y0 $z1 $x1 $y0 $z0 +# draw_cyl $x1 $y1 $z1 $x1 $y1 $z0 +# fi else @@ -281,6 +293,8 @@ EOF # mv png $POVRAY temp.pov > /dev/null 2>&1 + time=`basename $file | awk -F. '{ print $1 }' | awk -F_ '{ print $3 }'` + convert $COPTS -draw "text 5,20 't = $time fs'" temp.png temp.png mv temp.png `echo $file | sed 's/\.xyz/\.png/'` done