layout: post title: 八面体与截角八面体团簇在线创建工具 categories:
晶胞类型:<input type="radio" name="cubType" id="sc" checked="checked" onChange="setabc(0)"/>简单立方(SC) <input type="radio" name="cubType" id="bcc" onChange="setabc(0)" />体心立方(BCC) <input type="radio" name="cubType" id="fcc" onChange="setabc(0)"/>面心立方(FCC, 最密堆积) <input type="radio" name="cubType" id="hcp" onChange="setabc(1)"/>密排六方(HCP, 最密堆积)<br> 团簇类型:<input type="radio" name="clsType" id="cub" checked="checked" onChange="setNedg()">立方体 <input type="radio" name="clsType" id="oct" onChange="setNedg()">八面体 <input type="radio" name="clsType" id="trc" onChange="setNedg()">截角八面体 <input type="radio" name="clsType" id="sph" onChange="setNedg()">球体<br> 晶胞参数(Å):a <input type="box" id="a" value="3" /> b <input type="box" id="b" value="3" /> c <input type="box" id="c" value="3" /><br> 球体半径(原子数):<input type="box" id="sphNO" value="3" /><br> 立方体/八面体边长(原子数):<input type="box" id="cubNO" value="3" /><br> 截角八面体多边形边长(原子数):四边形 <input type="box" id="recNO" value="3" /> 六边形 <input type="box" id="hexNO" value="3" /><br>
<input type="button" value="创建" onClick="genCoor()" style="width:100px; height:30px" /> <table><tr> <td> 坐标文件<br/>(C:顶点 B:体心 F:面心 H:六方 S:表面)<br/><textarea id="xyzCoor" style="width:400px; height:500px; resize: none"></textarea></td> <td> <figure><figurecaption>团簇结构</figurecaption><br/> <script> var Mol=new ChemDoodle.TransformCanvas3D('Mol-1', 400,500); Mol.specs.backgroundColor='black'; Mol.specs.set3DRepresentation('Ball and Stick'); Mol.specs.projectionPerspective_3D = false; Mol.loadMolecule(ChemDoodle.readXYZ("", 1)); </script></td> </tr></table><script> setNedg() var $=function(id){return document.getElementById(id)}; function setabc(YesHCP) { var Rbond=3, Rhcp=1; if(YesHCP) { Rhcp=2*Math.sqrt(2/3) } $("a").value=Rbond; $("b").value=Rbond; $("c").value=Rbond*Rhcp; } function setNedg() { $("cubNO").disabled =true $("sphNO").disabled =true $("recNO").disabled =true $("hexNO").disabled =true if($("cub").checked || $("oct").checked) $("cubNO").disabled =false if($("sph").checked) $("sphNO").disabled =false if($("trc").checked) { $("recNO").disabled =false; $("hexNO").disabled =false; } } function genCoor() { var YesCub=$("cub").checked, YesSph=$("sph").checked, YesOct=$("oct").checked, YesTrc=$("trc").checked, YesBCC=$("bcc").checked, YesFCC=$("fcc").checked, YesHCP=$("hcp").checked, a=parseFloat($("a").value), b=parseFloat($("b").value), c=parseFloat($("c").value) if(YesTrc) { var Nrec=parseInt($("recNO").value), Nhex=parseInt($("hexNO").value), // Nhex=N-2*Ntop; Nrec=Ntop+1 Ntop=Nrec-1, Nedg=parseInt(Nhex)+parseInt(2*Ntop); } else { Nedg=parseInt($("cubNO").value) if(YesSph) Nedg=parseInt($("sphNO").value)+2 } var i, j, k, x, y, z, Rcos=Math.cos(2*Math.PI/3), Rsin=Math.sin(2*Math.PI/3); var Ntot=0, Satm=[], Xatm=[], Yatm=[], Zatm=[]; var Na=Nedg, Nb=Nedg, Nc=Nedg for(i=-Na; i<=Na; i++) { for(j=-Nb; j<=Nb; j++) { for(k=-Nc; k<=Nc; k++) { Ntot++ x=i*a; y=j*b; z=k*c if(YesHCP) { x = i*a+j*b*Rcos y = j*b*Rsin } Satm[Ntot]="C"; Xatm[Ntot]=x; Yatm[Ntot]=y; Zatm[Ntot]=z if(YesBCC) { Ntot++; Satm[Ntot]="B"; Xatm[Ntot]=x+0.5*a; Yatm[Ntot]=y+0.5*b; Zatm[Ntot]=z+0.5*c } else if(YesFCC) { Ntot++; Satm[Ntot]="F"; Xatm[Ntot]=x+0.5*a; Yatm[Ntot]=y+0.5*b; Zatm[Ntot]=z Ntot++; Satm[Ntot]="F"; Xatm[Ntot]=x+0.5*a; Yatm[Ntot]=y; Zatm[Ntot]=z+0.5*c Ntot++; Satm[Ntot]="F"; Xatm[Ntot]=x; Yatm[Ntot]=y+0.5*b; Zatm[Ntot]=z+0.5*c } else if(YesHCP) { Ntot++; Satm[Ntot]="H"; Xatm[Ntot]=x+(a+2*b*Rcos)/3; Yatm[Ntot]=y+2*b*Rsin/3; Zatm[Ntot]=z+c/2 } } } } var Ra=1./(Na*a), Rb=1./(Nb*b), Rc=1./(Nc*a), Rtmp=1./(Na*a-.25*a) Reps=1.-1./Nedg+1E-3, Ncut=Nedg-Ntop-0.5001; var Natm=0, YesIn=[]; for(i=1; i<=Ntot; i++) { x=Xatm[i]; y=Yatm[i]; z=Zatm[i] if( YesCub || (YesSph && x*x*Ra*Ra+y*y*Ra*Ra+z*z*Ra*Ra<=1) || (YesOct && x*Ra+y*Rb+z*Rc<Reps && x*Ra-y*Rb+z*Rc<Reps && -x*Ra+y*Rb+z*Rc<Reps && -x*Ra-y*Rb+z*Rc<Reps && x*Ra+y*Rb-z*Rc<Reps && x*Ra-y*Rb-z*Rc<Reps && -x*Ra+y*Rb-z*Rc<Reps && -x*Ra-y*Rb-z*Rc<Reps) || (YesTrc && x*Ra+y*Rb+z*Rc<Reps && x*Ra-y*Rb+z*Rc<Reps && -x*Ra+y*Rb+z*Rc<Reps && -x*Ra-y*Rb+z*Rc<Reps && x*Ra+y*Rb-z*Rc<Reps && x*Ra-y*Rb-z*Rc<Reps && -x*Ra+y*Rb-z*Rc<Reps && -x*Ra-y*Rb-z*Rc<Reps && -Ncut*a<x && x<Ncut*a && -Ncut*b<y && y<Ncut*b && -Ncut*c<z && z<Ncut*c) ) { Natm++; YesIn[i]=1 if(YesSph && x*x*Rtmp*Rtmp+y*y*Rtmp*Rtmp+z*z*Rtmp*Rtmp>=1) Satm[i]="S" } } var Fmol=Natm+"\n" if(YesBCC) Fmol +="BCC " else if(YesFCC) Fmol +="FCC " else if(YesHCP) Fmol +="HCP " else Fmol += "SC " if(YesCub) Fmol +="Cube Length="+Nedg else if(YesSph) Fmol +="Sphere Radius="+Nedg else if(YesOct) Fmol +="Oct Length="+Nedg else if(YesTrc) Fmol +="TruncatedOct Nrec="+Nrec+" Nhex="+Nhex Fmol += "\n" for(i=1; i<=Ntot; i++) { if(YesIn[i]) Fmol += fmtStr(Satm[i],4)+fmtNum(Xatm[i],12.6)+fmtNum(Yatm[i],12.6)+fmtNum(Zatm[i],12.6)+"\n" } $("xyzCoor").value=Fmol Mol.loadMolecule(ChemDoodle.readXYZ(Fmol, 1)); } function fmtNum(num, fmt) { var fmt=String(fmt), m=fmt.split(".")[0] num=num.toFixed(fmt.split(".")[1]) if(num.length<m) num=Array(m-num.length+1).join(" ")+num return num } function fmtStr(str, fmt) { if(str.length<fmt) str += Array(fmt-str.length+1).join(" ") return str } </script>