c c Catalogue of Subroutines in TEXTUR.F c c TEXTUR - sets up required arrays c CHARLOW - creates properties for low angle bdies c QUAT convert euler angles to a quaternion c MISQUAT combines two quaternions and finds the minimum angle c CSLQUAT gets distance (angle) from a CSL boundary: misorient must be in c the fundamental zone, q1R2>R3 c return end c c _____________________________ c c subroutine misquatinv(qq,thetamin) real qq(4,2),thetamin,qresult(4),tmp(2),rquat(4) real disor,pi real qmax,q1max,q2max c PI=3.14159265 c c algorithm for forming resultant quaternion c and determining minimum angle taken from Sutton & Baluffi c c "inv" indicates reverse order of quaternions c c note that the resultant quaternion is not returned c because it is not in the fundamental zone c c note change of signs to get inverse of second orientation c qresult(1)=-1.*qq(1,1)*qq(4,2)+qq(4,1)*qq(1,2) & +qq(2,1)*qq(3,2)-qq(3,1)*qq(2,2) qresult(2)=-1.*qq(2,1)*qq(4,2)+qq(4,1)*qq(2,2) & +qq(3,1)*qq(1,2)-qq(1,1)*qq(3,2) qresult(3)=-1.*qq(3,1)*qq(4,2)+qq(4,1)*qq(3,2) & +qq(1,1)*qq(2,2)-qq(2,1)*qq(1,2) qresult(4)=qq(4,1)*qq(4,2)+qq(1,1)*qq(1,2) & +qq(2,1)*qq(2,2)+qq(3,1)*qq(3,2) c c write(*,*) 'qresult ',qresult qmax=0. iqindex=0 do 10, i=1,4 qresult(i)=abs(qresult(i)) if(qresult(i).gt.qmax) then qmax=qresult(i) iqindex=i endif 10 continue c q1max=0. iq1index=0 c find the next highest q component do 20, i=1,4 if(i.eq.iqindex) goto 20 if(qresult(i).gt.q1max) then q1max=qresult(i) iq1index=i endif 20 continue c disor=amax1(qmax,(qmax+q1max)/sqrt(2.), & (qresult(1)+qresult(2)+qresult(3)+qresult(4))/2.) if(disor.gt.1.0) disor=1.0 if(disor.lt.-1.0) disor=-1.0 thetamin=acos(disor)*360./pi c write(*,*) 'thetamin ',thetamin c q2max=0. iq2index=0 c find the next highest q component do 30, i=1,4 if(i.eq.iqindex.or.i.eq.iq1index) goto 30 if(qresult(i).gt.q2max) then q2max=qresult(i) iq2index=i endif 30 continue c rquat(4)=qmax rquat(3)=q1max rquat(2)=q2max do 40, i=1,4 if(i.ne.iqindex.and. & i.ne.iq1index.and. & i.ne.iq2index) rquat(1)=qresult(i) 40 continue c supply the sorted quaternion c CAUTION: note that q1R2>R3 c return end c c ______________________ c subroutine cslquat(qq,numsig,theta,qresult) real qq(4),theta,qresult(4),tmp(2) real pi integer numsig ! index of CSL boundary - must be supplied include 'common.f' common/a2/quatcsl(4,50),numcsl,nsig(50) c PI=3.14159265 c c algorithm for forming resultant quaternion c and determining angle based on fourth component c c note change of signs to get inverse of second orientation c qresult(1)=qq(1)*quatcsl(4,numsig)-qq(4)*quatcsl(1,numsig) & +qq(2)*quatcsl(3,numsig)-qq(3)*quatcsl(2,numsig) qresult(2)=qq(2)*quatcsl(4,numsig)-qq(4)*quatcsl(2,numsig) & +qq(3)*quatcsl(1,numsig)-qq(1)*quatcsl(3,numsig) qresult(3)=qq(3)*quatcsl(4,numsig)-qq(4)*quatcsl(3,numsig) & +qq(1)*quatcsl(2,numsig)-qq(2)*quatcsl(1,numsig) qresult(4)=qq(4)*quatcsl(4,numsig)+qq(1)*quatcsl(1,numsig) & +qq(2)*quatcsl(2,numsig)+qq(3)*quatcsl(3,numsig) c c write(*,*) 'qresult ',qresult if(qresult(4).gt.1.0) qresult(4)=1.0 if(qresult(4).lt.-1.0) qresult(4)=-1.0 theta=acos(qresult(4))*360./pi c write(*,*) 'theta= ',theta c return end c c ______________________ c subroutine q2eulB(p1,p,p2,qq) c c converts quaternion to Bunge Euler angles c based on Altmann's solution for Euler->quat c real qq(4),p1,p,p2 real sum,diff c PI=3.14159265 c if(abs(qq(2).lt.1e-35).and.abs(qq(1).lt.1e-35)) then diff=pi/4. else diff=atan2(qq(2),qq(1)) endif c ATAN2 is unhappy is both arguments are exactly zero! c if(abs(qq(3).lt.1e-35).and.abs(qq(4).lt.1e-35)) then sum=pi/4. else sum=atan2(qq(3),qq(4)) endif c p1=(diff+sum) p2=(sum-diff) tmp=sqrt(qq(3)**2+qq(4)**2) if(tmp.gt.1.0) tmp=1.0 p=2.*acos(tmp) c write(*,*) ' quaternion input= ',qq c write(*,*) 'Bunge angles output= ',p1,p,p2 c write(*,*) ' angles [degrees]= ',180.*p1/pi,180.*p/pi,180.*p2/pi return end c c ______________________ c subroutine q2mat(qq,dd) c c converts quaternion to matrix c real qq(4),dd(3,3) real t1 c t1=qq(4)**2-qq(1)**2-qq(2)**2-qq(3)**2 do 100, i=1,3 do 90, j=1,3 dd(i,j)=0. if(i.eq.j) then dd(i,j)=dd(i,j)+t1 endif dd(i,j)=dd(i,j)+(2.*qq(i)*qq(j)) if(i.ne.j) then do 80, ijk=1,3 if(i.ne.ijk.and.j.ne.ijk) k=ijk 80 continue kl=j-i if(kl.eq.2) kl=-1 if(kl.eq.-2) kl=1 c poor man"s permutation tensor! dd(i,j)=dd(i,j)-(2.*qq(k)*qq(4)*float(kl)) endif 90 continue 100 continue return end c c +++++++++++++++++++ c subroutine vsort(a) real a(3),rmax,rmin integer i,imax,imin c write(*,*) 're-sorting components of vector' a(1)=abs(a(1)) a(2)=abs(a(2)) a(3)=abs(a(3)) rmax=0.0 rmin=1.0 do 10, i=1,3 if(a(i).ge.rmax) then rmax=a(i) imax=i endif if(a(i).le.rmin) then rmin=a(i) imin=i endif 10 continue c do 15, i=1,3 if(i.ne.imax.and.i.ne.imin) a(2)=a(i) 15 continue a(1)=rmax a(3)=rmin c write(*,*) 'sorted a= ',a c above code sorts a into descending order c return end c c c ______________________ c subroutine rfrvec(rf,din,dout) c c uses RF-vector to rotate a vector from DIN to DOUT; c Eq. 1.36 in Sutton & Balluffi c real rf(3),din(3),dout(3) real tmp,tmp2,cross(3) c tmp=2.*scalar(rf,din) tmp2=rf(1)**2+rf(2)**2+rf(3)**2 call vecpro2(din,rf,cross) dout(1)=((tmp*rf(1))+(din(1)*(1.-tmp2)))-(2.*cross(1))/(1.+tmp2) dout(2)=((tmp*rf(2))+(din(2)*(1.-tmp2)))-(2.*cross(2))/(1.+tmp2) dout(3)=((tmp*rf(3))+(din(3)*(1.-tmp2)))-(2.*cross(3))/(1.+tmp2) return end c c ______________________ c subroutine qrvec(qq,din,dout) c c uses quaternion to rotate a vector from DIN to DOUT; c note similarity to above routine c note that -q gives the same result as it should (represents same rotation) c real qq(4),din(3),dout(3) real t1 c t1=qq(4)**2-qq(1)**2-qq(2)**2-qq(3)**2 do 100, i=1,3 dout(i)=t1*din(i) c do 90, j=1,3 dout(i)=dout(i)+(2.*qq(i)*qq(j)*din(j)) c if(i.ne.j) then do 80, ijk=1,3 if(i.ne.ijk.and.j.ne.ijk) k=ijk 80 continue kl=j-i if(kl.eq.2) kl=-1 if(kl.eq.-2) kl=1 c poor man"s permutation tensor! dout(i)=dout(i)-(2.*qq(k)*qq(4)*float(kl)*din(j)) endif 90 continue 100 continue return end c c c _____________________________ c c subroutine comquat2(qq1,qq2,qresult) real qq1(4),qq2(4),qresult(4) c c PI=3.14159265 c c algorithm for forming resultant quaternion as Q1 x Q2^-1 c where Q2 follows Q1, i.e. is the second rotation; c note change of signs to get inverse of second orientation c qresult(1)=qq1(1)*qq2(4)-qq1(4)*qq2(1) & +qq1(2)*qq2(3)-qq1(3)*qq2(2) qresult(2)=qq1(2)*qq2(4)-qq1(4)*qq2(2) & +qq1(3)*qq2(1)-qq1(1)*qq2(3) qresult(3)=qq1(3)*qq2(4)-qq1(4)*qq2(3) & +qq1(1)*qq2(2)-qq1(2)*qq2(1) qresult(4)=qq1(4)*qq2(4)+qq1(1)*qq2(1) & +qq1(2)*qq2(2)+qq1(3)*qq2(3) c c write(*,*) 'qresult ',qresult c return end c c c _____________________________ c c subroutine comquat(qq,qresult) real qq(4,2),qresult(4) c c PI=3.14159265 c c algorithm for forming resultant quaternion as Q1 x Q2^-1 c where Q2 follows Q1, i.e. is the second rotation; c note change of signs to get inverse of second orientation c qresult(1)=qq(1,1)*qq(4,2)-qq(4,1)*qq(1,2) & +qq(2,1)*qq(3,2)-qq(3,1)*qq(2,2) qresult(2)=qq(2,1)*qq(4,2)-qq(4,1)*qq(2,2) & +qq(3,1)*qq(1,2)-qq(1,1)*qq(3,2) qresult(3)=qq(3,1)*qq(4,2)-qq(4,1)*qq(3,2) & +qq(1,1)*qq(2,2)-qq(2,1)*qq(1,2) qresult(4)=qq(4,1)*qq(4,2)+qq(1,1)*qq(1,2) & +qq(2,1)*qq(2,2)+qq(3,1)*qq(3,2) c c write(*,*) 'qresult ',qresult c return end c c _____________________________ c c subroutine comquatinv(qq,qresult) real qq(4,2),qresult(4) c c PI=3.14159265 c c algorithm for forming resultant quaternion as Q1^1 x Q2 c where Q2 follows Q1, i.e. is the second rotation; c note change of signs to get inverse of second orientation c qresult(1)=(-1.*qq(1,1)*qq(4,2))+qq(4,1)*qq(1,2) & +qq(2,1)*qq(3,2)-qq(3,1)*qq(2,2) qresult(2)=(-1.*qq(2,1)*qq(4,2))+qq(4,1)*qq(2,2) & +qq(3,1)*qq(1,2)-qq(1,1)*qq(3,2) qresult(3)=(-1.*qq(3,1)*qq(4,2))+qq(4,1)*qq(3,2) & +qq(1,1)*qq(2,2)-qq(2,1)*qq(1,2) qresult(4)=qq(4,1)*qq(4,2)+qq(1,1)*qq(1,2) & +qq(2,1)*qq(2,2)+qq(3,1)*qq(3,2) c c write(*,*) 'qresult ',qresult c return end c c _____________________________ c c subroutine presymm(qq,lindex,qresult) real qq(4),qresult(4) integer lindex c include 'common.f' common/a1/ quatsymm(4,48),numsymm c PI=3.14159265 c c algorithm for forming resultant quaternion c from applying a symmetry operator, QUATSYMM(n,lindex) c to the first quaternion/rotation c c If the symm oper == O, then c Qresult = (O x QQ) where QQ= Q1 x Q2^-1 c i.e. Qresult = (O x Q1) x Q2^-1 c note change of signs to get inverse of first orientation c if(lindex.gt.numsymm) stop 'error in presymm, lindex>numsymm' if(lindex.lt.1) stop 'error in presymm, lindex<1' qresult(1)=quatsymm(4,lindex)*qq(1)+quatsymm(1,lindex)*qq(4) & +quatsymm(3,lindex)*qq(2)-quatsymm(2,lindex)*qq(3) qresult(2)=quatsymm(4,lindex)*qq(2)+quatsymm(2,lindex)*qq(4) & +quatsymm(1,lindex)*qq(3)-quatsymm(3,lindex)*qq(1) qresult(3)=quatsymm(4,lindex)*qq(3)+quatsymm(3,lindex)*qq(4) & +quatsymm(2,lindex)*qq(1)-quatsymm(1,lindex)*qq(2) qresult(4)=quatsymm(4,lindex)*qq(4)-quatsymm(1,lindex)*qq(1) & -quatsymm(2,lindex)*qq(2)-quatsymm(3,lindex)*qq(3) c c write(*,*) 'qresult ',qresult c return end c c c _____________________________ c c subroutine postsymm(qq,lindex,qresult) real qq(4),qresult(4) integer lindex c include 'common.f' common/a1/ quatsymm(4,48),numsymm c PI=3.14159265 c c algorithm for forming resultant quaternion c from applying a symmetry operator, QUATSYMM(n,lindex) c to the second quaternion c c If the symm oper == O, then c Qresult = (QQ x O^-1) where QQ= Q1 x Q2^-1 c i.e. Qresult = Q1 x (O x Q2)^-1 c note change of signs to get inverse of first orientation c if(lindex.gt.numsymm) stop 'error in postsymm, lindex>numsymm' if(lindex.lt.1) stop 'error in postsymm, lindex<1' qresult(1)=qq(1)*quatsymm(4,lindex)-qq(4)*quatsymm(1,lindex) & +qq(2)*quatsymm(3,lindex)-qq(3)*quatsymm(2,lindex) qresult(2)=qq(2)*quatsymm(4,lindex)-qq(4)*quatsymm(2,lindex) & +qq(3)*quatsymm(1,lindex)-qq(1)*quatsymm(3,lindex) qresult(3)=qq(3)*quatsymm(4,lindex)-qq(4)*quatsymm(3,lindex) & +qq(1)*quatsymm(2,lindex)-qq(2)*quatsymm(1,lindex) qresult(4)=qq(4)*quatsymm(4,lindex)+qq(1)*quatsymm(1,lindex) & +qq(2)*quatsymm(2,lindex)+qq(3)*quatsymm(3,lindex) c c write(*,*) 'postsymm: qresult ',qresult c return end c c c _____________________________ c c subroutine disquat2(qq1,qq2,index1,index2,qresult,index1a,index2a) real qq1(4),qq2(4),qqn(4),qresult(4),quint(4),quintn(4),qmax real q4neg integer index1,index2,index1a,index2a,index3,iq4neg,i,j,k,ip,jp c c PI=3.14159265 c c algorithm for finding disorientation corresponding to c input quaternion, QQ (from COMQUAT): resultant quat. is in QRESULT c indices for symmetry operators are in INDEX1, INDEX2 c index1=0 index2=0 index1a=0 index2a=0 qmax=0. ip=1 jp=1 c do 200, i=1,24 call postsymm(qq1,i,quint) c do 195, jjm=1,2 if(jjm.eq.2) then do 170, k=1,4 quint(k)=quint(k)*-1.0 170 continue c can take negative of Q because identity = +/-(0,0,0,1) endif c do 190, j=1,24 c loop over the two sides of the grain boundary call postsymm(qq2,j,quintn) c call comquat2(quint,quintn,qqn) do 185, kjl=1,2 if(kjl.eq.2) then do 180, k=1,4 qresult(k)=qqn(k)*-1.0 180 continue c can take negative of Q because identity = +/-(0,0,0,1) endif c do 210, ijk=1,2 q4neg=1.0 if(ijk.gt.1) q4neg=-1.0 qresult(4)=qresult(4)*(q4neg) c take the inverse rotation, i.e. apply the switching symmetry c c write(*,"('i,j,kjl,q4neg,qresult ',3i3,5f8.3)") i,j,kjl,q4neg,qresult if(qresult(1).ge.0.0) then if((qresult(1)-qresult(2)).lt.1e-5) then if((qresult(2)-qresult(3)).lt.1e-5) then if((qresult(3)-qresult(4)).lt.1e-5) then c these IFs ensure that 0<=q1infinite result' endif return end c c c ------------------------------------------------ c subroutine rodcomABT(r1,r2,rout) c c combines two rotations as Rodrigues vectors c ROUT= R1+R2- R1 cross R2 / 1 - (R1dotR2) c except use the transpose of second rotation c real r1(3),r2(3),rout(3) real dot,cross(3) call vecneg(r2) dot=1.-scalar(r1,r2) call vecpro2(r1,r2,cross) if(abs(dot).gt.1e-5) then rout(1)=(r1(1)+r2(1)-cross(1))/dot rout(2)=(r1(2)+r2(2)-cross(2))/dot rout(3)=(r1(3)+r2(3)-cross(3))/dot else rout(1)=1e38 rout(2)=1e38 rout(3)=1e38 write(*,*) 'warning: RODCOM ->infinite result' endif return end c c c ------------------------------------------------ c subroutine rod2ang(r1,angle) real r1(3),angle c extracts a rotation angle from a Rodrigues vector c angle=2.*atan((sqrt(r1(1)**2+r1(2)**2+r1(3)**2))) return end c c c ------------------------------------------------ c subroutine rodcomATB(r1,r2,rout) c c combines two rotations as Rodrigues vectors c ROUT= R1+R2- R1 cross R2 / 1 - (R1dotR2) c except use the transpose of first rotation c real r1(3),r2(3),rout(3) real dot,cross(3) call vecneg(r1) dot=1.-scalar(r1,r2) call vecpro2(r1,r2,cross) if(abs(dot).gt.1e-5) then rout(1)=(r1(1)+r2(1)-cross(1))/dot rout(2)=(r1(2)+r2(2)-cross(2))/dot rout(3)=(r1(3)+r2(3)-cross(3))/dot else rout(1)=1e38 rout(2)=1e38 rout(3)=1e38 write(*,*) 'warning: RODCOM ->infinite result' endif return end c c ------------------------------------------------ c subroutine CSL(rodrvec,toler,sigmin,sigma) c c ADR 19 vi 99 c c NOW FOR SIGMA analysis; form a misorientation matrix from the results c c NEEDS READSIGMAS to be executed before CSL is called c real qq(3,3,50),oc(50) integer numsigs,i common /m2/ qq,oc,numsigs c real rodrvec(4),s1,s2,s3,u(3,3) real rj1,rj2,rj3,rnorm,rb,rn1,rn2,rn3,rn4,rn5 real axis(3),qsig(3,3),cresult(3,3) real sigmin,toler,sigma,pi,pi2,degrad real rodr(4) c pi=4.*atan(1.) pi2=0.5*pi degrad=180./pi sigmin=180.0 sigma=0.0 c do 10, i=1,3 axis(i)=rodrvec(i) 10 continue c call axisang2rot(axis,rodrvec(4),u) c do 3000, ijk=1,numsigs c write(*,*) 'working on sigma = ',int(oc(ijk)) c do 20, i=1,3 do 20,j=1,3 20 qsig(i,j)=qq(i,j,ijk) c c write(*,320) (u(1,j1),j1=1,3),(qsig(1,j1),j1=1,3) c write(*,320) (u(2,j1),j1=1,3),(qsig(2,j1),j1=1,3) c write(*,320) (u(3,j1),j1=1,3),(qsig(3,j1),j1=1,3) 320 format(x,3(x,f8.3),6x,3(x,f8.3)) call axbt2c(u,qsig,cresult) rnorm=(cresult(1,1)+cresult(2,2)+cresult(3,3)-1.)/2. c rnorm has the trace of the resulting rotation matrix if(rnorm.lt.-1.) rnorm=-1. if(rnorm.gt.1.) rnorm=1. rn4=acos(rnorm) c RN4 has the magnitude of rotation in radians c c call m2r(cresult,rodr,det) c write(*,190) rodr(4)*180./pi c & ,rodr(1),rodr(2),rodr(3) 190 format(' after combining: angle, vector....',4f9.3) c rb=(15.0*1./sqrt(oc(ijk))) c RB is for Brandon's criterion in degrees rn5=rn4*degrad/rb c outputs CSL and deviation c if (rn5.lt.1.0) then if (rn5.lt.toler) then c write(2,*) 'Sigma is ',int(oc(ijk)),'; V/Vm = ',rn5 c write(*,*) 'Sigma is ',int(oc(ijk)),'; V/Vm = ',rn5 endif c if((rn5.lt.toler).and.(rn5.lt.sigmin)) then sigma=oc(ijk) sigmin=rn5 endif 3000 continue return end c c ------------------- c subroutine axb2c(a,b,c) c multiply a by b to get c real a(3,3),b(3,3),c(3,3) c do 100, i=1,3 do 100, j=1,3 c(i,j)=0.0 do 100,ijk=1,3 c(i,j)=c(i,j)+a(i,ijk)*b(ijk,j) 100 continue return end c c ------------------- c subroutine atxb2c(a,b,c) c multiply a-TRANSPOSE by b to get c real a(3,3),b(3,3),c(3,3) c do 100, i=1,3 do 100, j=1,3 c(i,j)=0.0 do 100,ijk=1,3 c(i,j)=c(i,j)+a(ijk,i)*b(ijk,j) 100 continue return end c c ------------------- c subroutine axbt2c(a,b,c) c multiply a by b-TRANSPOSE to get c real a(3,3),b(3,3),c(3,3) c do 100, i=1,3 do 100, j=1,3 c(i,j)=0.0 do 100,ijk=1,3 c(i,j)=c(i,j)+a(i,ijk)*b(j,ijk) 100 continue return end c c ____________________________ c subroutine vecpro2(v1,v2,vout) c vector product real v1(3),v2(3),vout(3) vout(3)=v1(1)*v2(2)-v1(2)*v2(1) vout(1)=v1(2)*v2(3)-v1(3)*v2(2) vout(2)=v1(3)*v2(1)-v1(1)*v2(3) return end c c ____________________________ c subroutine vecpro(k,t1) c based on LApp routine c ***************** real t1(3,3) c c *** calculates axis x(k) as vector product of x(k1),x(k2) taken cyclically c k1=k+1 if(k1.gt.3) k1=k1-3 k2=k+2 if(k2.gt.3) k2=k2-3 t1(k,1)=t1(k1,2)*t1(k2,3)-t1(k1,3)*t1(k2,2) t1(k,2)=t1(k1,3)*t1(k2,1)-t1(k1,1)*t1(k2,3) t1(k,3)=t1(k1,1)*t1(k2,2)-t1(k1,2)*t1(k2,1) return c look for vector product in the kth column of t1 end c c ----------------------------------------- c C subroutine ZUR BERECHNUNG VON ORIENTIERUNGSBEZIEHUNGEN ZWISCHEN C ZWEI VORGEGEBENEN ORIENTIERUNGEN c c subroutine provided by Dierk Raabe (to Paul Lee, 1996) c subroutine misori(p1,p,p2,al_min,nsymm,ac_min) c c p1,p,p2 are (2 sets of) Bunge Euler angles c nsymm controls the sample symmetry c al_min is the disorientation angle c character meu,isy integer ac_min(3) DIMENSION D(3,3,2),SYM(3,3,24),P1(2),P(2),P2(2) $,DM(3,3),DRR(3,3,24),A(3),IA(3) $,DR(3,3) PI=3.14159265 al_min=360. ac_min(1)=0 ac_min(2)=0 ac_min(3)=0 C ERSTELLEN DER SYMMETRIEMATRIZEN C ************************************************************** DO 2 I=1,3 DO 2 J=1,3 DO 2 K=1,24 2 SYM(I,J,K)=0. C 1 SYM(1,1,1)=1. SYM(2,2,1)=1. SYM(3,3,1)=1. C 5 SYM(1,1,2)=1. SYM(2,3,2)=-1. SYM(3,2,2)=1. C 2 SYM(1,1,3)=1. SYM(2,2,3)=-1. SYM(3,3,3)=-1. C 11 SYM(1,1,4)=1. SYM(2,3,4)=1. SYM(3,2,4)=-1. C 7 SYM(1,3,5)=-1. SYM(2,2,5)=1. SYM(3,1,5)=1. C 12 SYM(1,3,6)=1. SYM(2,2,6)=1. SYM(3,1,6)=-1. C 3 SYM(1,1,7)=-1. SYM(2,2,7)=1. SYM(3,3,7)=-1. C 4 SYM(1,1,8)=-1. SYM(2,2,8)=-1. SYM(3,3,8)=1. C 13 SYM(1,2,9)=1. SYM(2,1,9)=-1. SYM(3,3,9)=1. C 6 SYM(1,2,10)=-1. SYM(2,1,10)=1. SYM(3,3,10)=1. C 20 SYM(1,2,11)=-1. SYM(2,3,11)=1. SYM(3,1,11)=-1. C 23 SYM(1,3,12)=1. SYM(2,1,12)=-1. SYM(3,2,12)=-1. C 19 SYM(1,2,13)=-1. SYM(2,3,13)=-1. SYM(3,1,13)=1. C 21 SYM(1,3,14)=-1. SYM(2,1,14)=1. SYM(3,2,14)=-1. C 18 SYM(1,2,15)=1. SYM(2,3,15)=-1. SYM(3,1,15)=-1. C 22 SYM(1,3,16)=-1. SYM(2,1,16)=-1. SYM(3,2,16)=1. C 9 SYM(1,2,17)=1. SYM(2,3,17)=1. SYM(3,1,17)=1. C 8 SYM(1,3,18)=1. SYM(2,1,18)=1. SYM(3,2,18)=1. C 17 SYM(1,2,19)=1. SYM(2,1,19)=1. SYM(3,3,19)=-1. C 24 SYM(1,1,20)=-1. SYM(2,3,20)=1. SYM(3,2,20)=1. C 10 SYM(1,3,21)=1. SYM(2,2,21)=-1. SYM(3,1,21)=1. C 15 SYM(1,1,22)=-1. SYM(2,3,22)=-1. SYM(3,2,22)=-1. C 16 SYM(1,3,23)=-1. SYM(2,2,23)=-1. SYM(3,1,23)=-1. C 14 SYM(1,2,24)=-1. SYM(2,1,24)=-1. SYM(3,3,24)=-1. C ********************************** C ERSTELLEN DER BEIDEN DMATRIZEN c 205 FORMAT(A1) meu='E' isy='E' I31MAX=nsymm DO 31 I31=1,I31MAX DO 1 I1=1,2 FAKT=PI/180. PP1=P1(I1)*FAKT PP=P(I1)*FAKT PP2=P2(I1)*FAKT C1=COS(PP1) C=COS(PP) C2=COS(PP2) S1=SIN(PP1) S=SIN(PP) S2=SIN(PP2) D(1,1,I1)=C1*C2-S1*S2*C D(1,2,I1)=S1*C2+C1*S2*C D(1,3,I1)=S2*S D(2,1,I1)=-C1*S2-S1*C2*C D(2,2,I1)=-S1*S2+C1*C2*C D(2,3,I1)=C2*S D(3,1,I1)=S1*S D(3,2,I1)=-C1*S D(3,3,I1)=C GOTO 1 1 CONTINUE C ********************************** DO 24 I24=1,3 DO 25 I25=1,3 DM(I24,I25)=D(I24,I25,1) DR(I24,I25)=D(I24,I25,2) 25 CONTINUE 24 CONTINUE F=PI/180. C C **************************************************** C BESTIMMUNG DER INVERSEN MATRIX ZUR ORIENTIERUNG 1:DM C **************************************************** DO 3 I=1,3 DO 3 J=1,3 3 DM(I,J)=D(J,I,1) C ************************* C FELDER GLEICH NULL SETZEN C ************************* DO 4 I=1,3 DO 4 J=1,3 DO 4 K=1,24 DR(I,J)=0. 4 DRR(I,J,K)=0. C *********************************************************** C MATRIZENMULTIPLIKATION DER MATRIZEN D(I,J,2) UND DM=DR(I,J) C *********************************************************** DO 5 I=1,3 DO 5 J=1,3 DO 6 K=1,3 6 DR(I,J)=D(I,K,2)*DM(K,J)+DR(I,J) 5 CONTINUE C *********************************************** C MATRIZENMULITIPLIKATION DER MATRIZEN SYM UND DR C *********************************************** DO 7 IZ=1,24 DO 8 I=1,3 DO 8 J=1,3 DO 9 K=1,3 9 DRR(I,J,IZ)=SYM(I,K,IZ)*DR(K,J)+DRR(I,J,IZ) 8 CONTINUE C ******************************* C BESTIMMUNG DES ROTATIONSWINKELS C ******************************* SPUR=0. DO 10 I=1,3 10 SPUR=SPUR+DRR(I,I,IZ) SP=(SPUR-1.)/2. IF(SP.GE.1.)SP=1.-1.E-5 IF(SP.LE.-1.)SP=-1.+1.E-5 OMEGA=PI/2.-ASIN(SP) IOMEGA=INT(OMEGA*180./PI+0.5) ALPHA=OMEGA*180./PI IF(IOMEGA.EQ.180.or.iomega.eq.0)GOTO 12 X=2.*SIN(OMEGA) C ******************************************************** C BESTIMMUNG DER ROTATIONSACHSE, INCL SONDERFALL OMEGA = 180 C ******************************************************** A(1)=100.*(DRR(2,3,IZ)-DRR(3,2,IZ))/X A(2)=100.*(DRR(3,1,IZ)-DRR(1,3,IZ))/X A(3)=100.*(DRR(1,2,IZ)-DRR(2,1,IZ))/X GOTO 13 12 A(1)=SQRT((DRR(1,1,IZ)+1.)/2.)*100. A(2)=SQRT((DRR(2,2,IZ)+1.)/2.)*100. A(3)=SQRT((DRR(3,3,IZ)+1.)/2.)*100. 13 DO 11 I=1,3 IF(A(I).EQ.0.)GOTO 19 IA(I)=INT(A(I)+0.5*A(I)/ABS(A(I))) GOTO 11 19 IA(I)=0 11 CONTINUE if(abs(alpha).lt.al_min) then al_min=abs(alpha) ac_min(1)=ia(1) ac_min(2)=ia(2) ac_min(3)=ia(3) end if 7 CONTINUE IF(I31.EQ.1)P1(2)=180.+P1(2) IF(I31.EQ.2)P1(2)=360.-P1(2) IF(I31.EQ.2)P2(2)=90.-P2(2) IF(I31.EQ.3)P1(2)=180.+P1(2) 31 CONTINUE i_min=100 if(abs(ac_min(1)).lt.i_min.and.abs(ac_min(1)).gt.0) $i_min=abs(ac_min(1)) if(abs(ac_min(2)).lt.i_min.and.abs(ac_min(2)).gt.0) $i_min=abs(ac_min(2)) if(abs(ac_min(3)).lt.i_min.and.abs(ac_min(3)).gt.0) $i_min=abs(ac_min(3)) do 5501 ii=1,3 5501 ac_min(ii)=nint(float(ac_min(ii))/float(i_min)) return end c c c ----------------------------------------- c C subroutine ZUR BERECHNUNG VON ORIENTIERUNGSBEZIEHUNGEN ZWISCHEN C ZWEI VORGEGEBENEN ORIENTIERUNGEN c c subroutine provided by Dierk Raabe (to Paul Lee, 1996) c subroutine misorinv(p1,p,p2,al_min,nsymm,ac_min) c c p1,p,p2 are (2 sets of) Bunge Euler angles c nsymm controls the sample symmetry c al_min is the disorientation angle c character meu,isy integer ac_min(3) DIMENSION D(3,3,2),SYM(3,3,24),P1(2),P(2),P2(2) $,DM(3,3),DRR(3,3,24),A(3),IA(3) $,DR(3,3) PI=3.14159265 al_min=360. ac_min(1)=0 ac_min(2)=0 ac_min(3)=0 C ERSTELLEN DER SYMMETRIEMATRIZEN C ************************************************************** DO 2 I=1,3 DO 2 J=1,3 DO 2 K=1,24 2 SYM(I,J,K)=0. C 1 SYM(1,1,1)=1. SYM(2,2,1)=1. SYM(3,3,1)=1. C 5 SYM(1,1,2)=1. SYM(2,3,2)=-1. SYM(3,2,2)=1. C 2 SYM(1,1,3)=1. SYM(2,2,3)=-1. SYM(3,3,3)=-1. C 11 SYM(1,1,4)=1. SYM(2,3,4)=1. SYM(3,2,4)=-1. C 7 SYM(1,3,5)=-1. SYM(2,2,5)=1. SYM(3,1,5)=1. C 12 SYM(1,3,6)=1. SYM(2,2,6)=1. SYM(3,1,6)=-1. C 3 SYM(1,1,7)=-1. SYM(2,2,7)=1. SYM(3,3,7)=-1. C 4 SYM(1,1,8)=-1. SYM(2,2,8)=-1. SYM(3,3,8)=1. C 13 SYM(1,2,9)=1. SYM(2,1,9)=-1. SYM(3,3,9)=1. C 6 SYM(1,2,10)=-1. SYM(2,1,10)=1. SYM(3,3,10)=1. C 20 SYM(1,2,11)=-1. SYM(2,3,11)=1. SYM(3,1,11)=-1. C 23 SYM(1,3,12)=1. SYM(2,1,12)=-1. SYM(3,2,12)=-1. C 19 SYM(1,2,13)=-1. SYM(2,3,13)=-1. SYM(3,1,13)=1. C 21 SYM(1,3,14)=-1. SYM(2,1,14)=1. SYM(3,2,14)=-1. C 18 SYM(1,2,15)=1. SYM(2,3,15)=-1. SYM(3,1,15)=-1. C 22 SYM(1,3,16)=-1. SYM(2,1,16)=-1. SYM(3,2,16)=1. C 9 SYM(1,2,17)=1. SYM(2,3,17)=1. SYM(3,1,17)=1. C 8 SYM(1,3,18)=1. SYM(2,1,18)=1. SYM(3,2,18)=1. C 17 SYM(1,2,19)=1. SYM(2,1,19)=1. SYM(3,3,19)=-1. C 24 SYM(1,1,20)=-1. SYM(2,3,20)=1. SYM(3,2,20)=1. C 10 SYM(1,3,21)=1. SYM(2,2,21)=-1. SYM(3,1,21)=1. C 15 SYM(1,1,22)=-1. SYM(2,3,22)=-1. SYM(3,2,22)=-1. C 16 SYM(1,3,23)=-1. SYM(2,2,23)=-1. SYM(3,1,23)=-1. C 14 SYM(1,2,24)=-1. SYM(2,1,24)=-1. SYM(3,3,24)=-1. C ********************************** C ERSTELLEN DER BEIDEN DMATRIZEN c 205 FORMAT(A1) meu='E' isy='E' I31MAX=nsymm DO 31 I31=1,I31MAX DO 1 I1=1,2 FAKT=PI/180. PP1=P1(I1)*FAKT PP=P(I1)*FAKT PP2=P2(I1)*FAKT C1=COS(PP1) C=COS(PP) C2=COS(PP2) S1=SIN(PP1) S=SIN(PP) S2=SIN(PP2) D(1,1,I1)=C1*C2-S1*S2*C D(1,2,I1)=S1*C2+C1*S2*C D(1,3,I1)=S2*S D(2,1,I1)=-C1*S2-S1*C2*C D(2,2,I1)=-S1*S2+C1*C2*C D(2,3,I1)=C2*S D(3,1,I1)=S1*S D(3,2,I1)=-C1*S D(3,3,I1)=C GOTO 1 1 CONTINUE C ********************************** DO 24 I24=1,3 DO 25 I25=1,3 DM(I24,I25)=D(I24,I25,1) DR(I24,I25)=D(I24,I25,2) 25 CONTINUE 24 CONTINUE F=PI/180. C C **************************************************** C BESTIMMUNG DER INVERSEN MATRIX ZUR ORIENTIERUNG 1:DM C **************************************************** DO 3 I=1,3 DO 3 J=1,3 3 DM(I,J)=D(J,I,1) C ************************* C FELDER GLEICH NULL SETZEN C ************************* DO 4 I=1,3 DO 4 J=1,3 DO 4 K=1,24 DR(I,J)=0. 4 DRR(I,J,K)=0. C *********************************************************** C MATRIZENMULTIPLIKATION DER MATRIZEN D(I,J,2) UND DM=DR(I,J) C *********************************************************** DO 5 I=1,3 DO 5 J=1,3 DO 6 K=1,3 6 DR(I,J)=D(k,i,2)*DM(j,k)+DR(I,J) c !!!!! inverted the transposition here !!!! 5 CONTINUE C *********************************************** C MATRIZENMULITIPLIKATION DER MATRIZEN SYM UND DR C *********************************************** DO 7 IZ=1,24 DO 8 I=1,3 DO 8 J=1,3 DO 9 K=1,3 9 DRR(I,J,IZ)=SYM(I,K,IZ)*DR(K,J)+DRR(I,J,IZ) 8 CONTINUE C ******************************* C BESTIMMUNG DES ROTATIONSWINKELS C ******************************* SPUR=0. DO 10 I=1,3 10 SPUR=SPUR+DRR(I,I,IZ) SP=(SPUR-1.)/2. IF(SP.GE.1.)SP=1.-1.E-5 IF(SP.LE.-1.)SP=-1.+1.E-5 OMEGA=PI/2.-ASIN(SP) IOMEGA=INT(OMEGA*180./PI+0.5) ALPHA=OMEGA*180./PI IF(IOMEGA.EQ.180.or.iomega.eq.0)GOTO 12 X=2.*SIN(OMEGA) C ******************************************************** C BESTIMMUNG DER ROTATIONSACHSE, INCL SONDERFALL OMEGA = 180 C ******************************************************** A(1)=100.*(DRR(2,3,IZ)-DRR(3,2,IZ))/X A(2)=100.*(DRR(3,1,IZ)-DRR(1,3,IZ))/X A(3)=100.*(DRR(1,2,IZ)-DRR(2,1,IZ))/X GOTO 13 12 A(1)=SQRT((DRR(1,1,IZ)+1.)/2.)*100. A(2)=SQRT((DRR(2,2,IZ)+1.)/2.)*100. A(3)=SQRT((DRR(3,3,IZ)+1.)/2.)*100. 13 DO 11 I=1,3 IF(A(I).EQ.0.)GOTO 19 IA(I)=INT(A(I)+0.5*A(I)/ABS(A(I))) GOTO 11 19 IA(I)=0 11 CONTINUE if(abs(alpha).lt.al_min) then al_min=abs(alpha) ac_min(1)=ia(1) ac_min(2)=ia(2) ac_min(3)=ia(3) end if 7 CONTINUE IF(I31.EQ.1)P1(2)=180.+P1(2) IF(I31.EQ.2)P1(2)=360.-P1(2) IF(I31.EQ.2)P2(2)=90.-P2(2) IF(I31.EQ.3)P1(2)=180.+P1(2) 31 CONTINUE i_min=100 if(abs(ac_min(1)).lt.i_min.and.abs(ac_min(1)).gt.0) $i_min=abs(ac_min(1)) if(abs(ac_min(2)).lt.i_min.and.abs(ac_min(2)).gt.0) $i_min=abs(ac_min(2)) if(abs(ac_min(3)).lt.i_min.and.abs(ac_min(3)).gt.0) $i_min=abs(ac_min(3)) do 5501 ii=1,3 5501 ac_min(ii)=nint(float(ac_min(ii))/float(i_min)) return end c