#include #include #include "parse.h" #include "getvalue.h" #include "version.h" #include "stringo.h" #include "findsym.h" void find_all_atom_in_subcell(Array *psub_atom_pos, Array *psub_atom_type, const Array &atom_pos, const Array &atom_type, const rMatrix3d &cell, const rMatrix3d &subcell) { int nb_atom_subcell=iround((Real)atom_pos.get_size()*fabs(det(subcell)/det(cell))); rMatrix3d isubcell=(!subcell); psub_atom_pos->resize(nb_atom_subcell); psub_atom_type->resize(nb_atom_subcell); int redun=atom_pos.get_size()/nb_atom_subcell; Array done(atom_pos.get_size()); zero_array(&done); int j=0; for (int i=0; i *psuper_atom_pos, Array *psuper_atom_type, const Array &atom_pos, const Array &atom_type, const rMatrix3d &cell, const rMatrix3d &subcell) { int nb_atom_subcell=iround(atom_pos.get_size()*fabs(det(subcell)/det(cell))); rMatrix3d isubcell=(!subcell); psuper_atom_pos->resize(nb_atom_subcell); psuper_atom_type->resize(nb_atom_subcell); LatticePointInCellIterator l(cell,subcell); int index=0; for ( ; l; l++) { for (int s=0; s> v; pcell->set_column(i,axes*v); } } void add_redundant_atom_in_cell(Array *patom_pos, Array *patom_type, const Array &atom_pos, const Array &atom_type, const rMatrix3d &cell) { rMatrix3d icell=!cell; Array fatom_pos(atom_pos.get_size()); for (int s=0; s atom_pos_list; LinkedList atom_type_list; MultiDimIterator l(iVector3d(-1,-1,-1),iVector3d(1,1,1)); for (; l; l++) { for (int s=0; s1.); return v; } int main(int argc, char *argv[]) { char *axesfilename=""; char *cellfilename=""; int simplesupercell=0; int docart=0; int dofrac=0; int doconv=0; int doabc=0; int donoabc=0; int readocc=0; int sigdig=6; int fixcell=0; int find_t=0; char *orig_setting=""; char *final_setting=""; int dorecip=0; int nbskip=1; int nbprint=MAXINT; int printnb=0; int printvol=0; int dosym=0; int dosymname=0; int printbravaistype=0; char *shift_str=""; rVector3d shift(0.,0.,0.); int wrapinside=0; int wrapinsideunshift=0; char *spcgrpfile=""; char *strtokeep=""; int genspcgrp=0; int remred=0; int remredavg=0; int addred=0; Real scale=1.; int seed=0; Real jitteratom=0.; Real jittercell=0.; AskStruct options[]={ {"","cellcvrt " MAPS_VERSION ", by Axel van de Walle",TITLEVAL,NULL}, {"","Performs various conversions/changes on structure (or lattices).",TITLEVAL,NULL}, {"","Reads from stdin, writes to stdout.",TITLEVAL,NULL}, {"-c","Use cartesian coordinates",BOOLVAL,&docart}, {"-f","Use fractional coordinates",BOOLVAL,&dofrac}, {"-cc","Find conventional cell and use it as coordinate system",BOOLVAL,&doconv}, {"-abc","Use a b c alpha beta gamma format to specify axes",BOOLVAL,&doabc}, {"-noabc","Use cartesian format to specify the axes (the default)",BOOLVAL,&donoabc}, {"-ro","Read fractional Occupation",BOOLVAL,&readocc}, {"-u","User-specified coordinate system input file (optional)",STRINGVAL,&axesfilename}, {"-uss","User-specified supercell",STRINGVAL,&cellfilename}, {"-ss","Simple supercell (multiple of axes in all directions)",INTVAL,&simplesupercell}, {"-fc","Fix cell (to make it as symmetric as possible)",BOOLVAL,&fixcell}, {"-s","Look for smaller unit cell",BOOLVAL,&find_t}, {"-sh","Shift all atoms (default 0,0,0).",STRINGVAL,&shift_str}, {"-ja","Jitter all atoms positions by a random amount less than specified",REALVAL,&jitteratom}, {"-jc","Jitter all cell parameters by a random amount less than the fraction specified",REALVAL,&jittercell}, {"-sd","Seed for random number generation (default: use clock)",INTVAL,&seed}, {"-sg","Space group file",STRINGVAL,&spcgrpfile}, {"-gsg","Generate Space Group",BOOLVAL,&genspcgrp}, {"-wi","Wrap all atoms inside unit cell",BOOLVAL,&wrapinside}, {"-wiu","Wrap all atoms inside unit cell and undo shift",BOOLVAL,&wrapinsideunshift}, {"-rr","Remove redundant atoms",BOOLVAL,&remred}, {"-rra","Remove redundant atoms and average",BOOLVAL,&remredavg}, {"-ar","Add redundant atoms",BOOLVAL,&addred}, {"-osf","Original setting file (optional)",STRINGVAL,&orig_setting}, {"-fsf","Final setting file (optional)",STRINGVAL,&final_setting}, {"-r","Print reciprocal unit cell",BOOLVAL,&dorecip}, {"-fs","Index of first structure to process (default: 1)",INTVAL,&nbskip}, {"-ns","Number of structures to process",INTVAL,&nbprint}, {"-slf","Structure list file",STRINGVAL,&strtokeep}, {"-pn","Print the number of atoms in the structure only",BOOLVAL,&printnb}, {"-pv","Print volume of cell only",BOOLVAL,&printvol}, {"-sym","Print spacegroup",BOOLVAL,&dosym}, {"-ppg","Print point group name",BOOLVAL,&dosymname}, {"-pbv","Print Bravais Lattice name",BOOLVAL,&printbravaistype}, {"-sc","Scale factor (default: 1)",REALVAL,&scale}, {"-sig","Number of significant digits to print in output files",INTVAL,&sigdig}, {"-z","Tolerance for checking overlap (Default 1e-3)",REALVAL,&zero_tolerance}, }; if (!get_values(argc,argv,countof(options),options)) { display_help(countof(options),options); return 1; } if (docart+dofrac+doconv+(strlen(axesfilename)>0)>1) { ERRORQUIT("Must specify no more than one of -c, -f, -cc or -u=filename."); } rMatrix3d transfo; transfo.identity(); if (strlen(orig_setting)>0 || strlen(final_setting)>0) { rMatrix3d orig; orig.identity(); if (strlen(orig_setting)>0) { ifstream origfile(orig_setting); if (!origfile) {ERRORQUIT("Unable to open original setting file");} read_axes_cell(&orig,origfile); } rMatrix3d final; final.identity(); if (strlen(final_setting)>0) { ifstream finalfile(final_setting); if (!finalfile) {ERRORQUIT("Unable to open final setting file");} read_axes_cell(&final,finalfile); } transfo=final*(!orig); } // read in structure list if any; LinkedList strlist; if (strlen(strtokeep)>0) { nbskip=1; ifstream file(strtokeep); if (!file) ERRORQUIT("Unable to open structure list file."); while (1) { int s=-1; file >> s; if (s==-1) break; strlist << new int(s); } } LinkedListIterator istr(strlist); // read in lattice (see parse.h); Structure lat; Array site_type_list; Array atom_label; Array > occ; rMatrix3d axes; for (int s=1; s0) { if (!istr) break; if ((s+1)!=*istr) continue; istr++; } if (printend) { cout << "end" << endl << endl; } else { printend=1; } rndseed(seed); if (jitteratom>0.) { for (int at=0; at0.) { for (int i=0; i<3; i++) { rVector3d v=rnd_ball()*jittercell; for (int j=0; j<3; j++) { transfo(j,i)+=v(j); } } } lat.cell=transfo*lat.cell; axes=transfo*axes; for (int i=0; i0 || simplesupercell>0) { Structure supercell; if (simplesupercell>0) { supercell.cell.identity(); } else { ifstream cellfile(cellfilename); if (!cellfile) ERRORQUIT("Unable to open cell file."); read_cell(&supercell.cell,cellfile); } supercell.cell=(axes*supercell.cell)*(simplesupercell>1 ? (Real)simplesupercell : 1.); if (!is_int((!lat.cell)*supercell.cell)) { ERRORQUIT("Supercell is incomensurate with unit cell"); } find_all_atom_in_supercell(&supercell.atom_pos,&supercell.atom_type,lat.atom_pos,lat.atom_type,lat.cell,supercell.cell); lat=supercell; } for (int at=0; at0) { ifstream file(axesfilename); if (!file) { ERRORQUIT("Unable to open user-defined axes input file."); } read_cell(&axes,file); } if (strlen(shift_str)>0) { istrstream s(shift_str); for (int i=0; i<3; i++) { skip_delim(s,",;:"); s >> shift(i); } shift=axes*shift; for (int i=0; i0) { ifstream file(spcgrpfile); if (!file) ERRORQUIT("Unable to open space group file."); int nop=0; file >> nop; SpaceGroup spacegroup; spacegroup.point_op.resize(nop); spacegroup.trans.resize(nop); spacegroup.cell=lat.cell; for (int op=0; op> m; spacegroup.point_op(op)=axes*(m*(!axes)); rVector3d v; file >> v; spacegroup.trans(op)=axes*v; } if (genspcgrp) { generate_space_group(&spacegroup, spacegroup); ofstream symfile("fullsym.out"); symfile.setf(ios::fixed); symfile.precision(sigdig); symfile << spacegroup.point_op.get_size() << endl; for (int i=0; i newpos; LinkedList newtype; for (int i=0; i avgpos(lat.atom_pos.get_size()); Array weight(lat.atom_pos.get_size()); zero_array(&weight); for (int i=0; i newpos; LinkedList newtype; for (int i=0; i0) { newpos << new rVector3d(avgpos(i)/weight(i)); newtype << new int(lat.atom_type(i)); } } LinkedList_to_Array(&lat.atom_pos,newpos); LinkedList_to_Array(&lat.atom_type,newtype); } if (wrapinside || wrapinsideunshift) { wrap_inside_cell(&lat.atom_pos,lat.atom_pos,lat.cell); } if (wrapinsideunshift) { for (int i=0; i