Exemplo n.º 1
0
void Tartet::Allocator(void)
{
	if ((dx.data[0] != onex_) || (dx.data[1] != onex_))
		Errmsg("Fatal", "Tartet", " tartet does not support noncubic lattice");
//
// Determine list of occupied sites.
	int curSize = nx * ny;
	ixyz.Dimension(curSize, 3);

	nat0 = 0;
	for(int i=minJx; i<=maxJx; ++i)
	{
		real x = i + xoff;
// YMAX=largest value of Y which can occur for this X value
// YMIN=smallest value of Y which can occur for this X value
// ZMAX0=largest value of Z which can occur for this X value
		real ymax = (real)( shpar[0] * Sqrt(3./16.) - x / Sqrt(twox_));
		real ymin = (real)(-shpar[0] * Sqrt(3./64.) + x / Sqrt(8.));
		real zmax0 = (real)(3. * shpar[0] / 8. - x * Sqrt(3./8.));
		for(int j=minJy; j<=maxJy; ++j)
		{
			real y = j + yoff;
			if ((y >= ymin) && (y <= ymax))
			{
				real fy = (y - ymin) / (ymax - ymin);
				real zmax = (onex_ - fy) * zmax0;				// ! ZMAX=largest value of Z which can occur for this (X,Y)
				for(int k=minJz; k<=maxJz; ++k)
				{
					real z = k + zoff;
					if (Fabs(z) <= zmax)					// ! Site is occupied:
					{
						if (nat0 >= curSize)
						{
							ixyz.Extend(nz);
							curSize = ixyz.GetSize(0);
						}
						ixyz.Fill3(nat0, i, j, k);
						int index = GetLinearAddress(nat0);
						Composer(index, 0);
						iocc[index] = true;
						++nat0;
					}
				}
			}
		}
	}
	ixyz.Close(nat0);
}
Exemplo n.º 2
0
void Target_Octahedron::Allocator(void)
{
//
// Current version of TARPLATONIC is restricted to cubic lattices
	if ((dx.data[0] != onex_) || (dx.data[1] != onex_))
		Errmsg("Fatal", shortDescr.c_str(), " TargetOctahedron does not support noncubic lattice");
//
	int nlong = (int)shpar[0];
	real nlongHalf = nlong / (real)2.;
//
	int curSize = nx * ny;
	ixyz.Dimension(curSize, 3);
//
	nat0 = 0;
	for(int jx=minJx; jx<=maxJx; ++jx)
	{
		real x = (real)jx - nlongHalf;
		for(int jy=minJy; jy<=maxJy; ++jy)
		{
			real y = (real)jy - nlongHalf;
			for(int jz=minJz; jz<=maxJz; ++jz)
			{
				real z = (real)jz - nlongHalf;
				if (Check(x, y, z))
				{
					if (nat0 >= curSize)
					{
						ixyz.Extend(nz);
						curSize = ixyz.GetSize(0);
					}
					ixyz.Fill3(nat0, jx, jy, jz);
					int index = GetLinearAddress(nat0);
					Composer(index, 0);
					iocc[index] = true;
					++nat0;
				}
			}
		}
	}
	ixyz.Close(nat0);
}
Exemplo n.º 3
0
void Nearfield(AbstractTarget *currentTarget, DDscatParameters *param, const char *cfle1, const char *cfle2, const char *cfleb1, const char *cfleb2, 
	int myid, real akd, Vect3<real> &ak_tf, int ncomp, real aeff, real wave, Complex *cxadia, DielectricManager *dielec, Complex *cxpol1, Complex *cxpol2, 
	Vect3<Complex> &cxe01_tf, Vect3<Complex> &cxe02_tf, Array4Stacked<Complex> *cxzw)
{
/* **
Given
   NRWORD = length (bytes) of real word
          = 4 for single precision, 8 for double precision
   CMDFFT = FFT method
   CFLB1  = name of output file for nearfield B, for polarization state 1
   CFLB2  = name of output file for nearfield B, for polarization state 2
   CFLE1  = name of output file for nearfield E, for polarization state 1
   CFLE2  = name of output file for nearfield E, for polarization state 2
   MYID
   AKD        = k*d
   AK_TF(1:3)   = (k_x,k_y,k_z)*d in target frame
   IDVOUT     = unit to use for output
   IOCC(1:NAT)=0/1 if site is vacant/occupied
   ICOMP(1:3*NAT) = ICOMP(NAT,3)
              = composition identifier for sites 1-NAT, directions x,y,z
   MXCOMP     = dimensioning info for array CXEPS
   MXPBC      = dimensioning info
   NAT0       = number of occupied sites
   NCOMP      = number of distinct compositions
   NX,NY,NZ   = extent of lattice in x,y,z directions
   IPBC       = 0 to do isolated target
                1 to use periodic boundary conditions
                  in either y or z direction, or both y and z
   IORTH      = 1 if only doing a single polarization
                2 if doing two polarizations for each orientation
   NRFLDB     = 0 to omit calculation of B
                1 to use BSELF to compute B
   GAMMA      = convergence parameter used in PBC calculations
   NAMBIENT   = (real) refractive index of ambient medium
   PYD,PZD    = PBC period/d in y and z directions
   DX(1:3)    = lattice spacing in x,y,z directions/d
                d^3 = DX(1)*DX(2)*DX(3)
   X0(1:3)    = location/d in TF for (I,J,K)=(0,0,0)
   AEFF       = effective radius (phyical units) 
                of target or target unit cell
                aeff = (3*Volume/4*pi)^{1/3}
   WAVE       = wavelength in vacuo (physical units)
   CXADIA(1:3*NAT)=diagonal elements of polarizability tensor
                for dipoles at locations J=1-NAT
   CXEPS(1:MXCOMP)=complex dielectric function for compositions IC=1-MXCOMP
   CXPOL1(1:3*NAT)=polarization (in TF) at locations J=1-NAT
                produced by incident E polarization CXE01_TF
                propagating in direction AK_TF
   CXPOL2(1:3*NAT)=polarization (in TF) at locations J=1-NAT
                produced by incident E polarization CXE02_TF
                propagating in directin AK_TF [used only if IORTH=2]
   CXE01_TF(1:3)= incident polarization vector in TF
   CXE02_TF(1:3)= incident orthogonal polarization vector in TF
   CXZC       = work space needed by ESELF
   CXZW       = work space needed by ESELF

 returns

   CXESCA1(1:3*NAT)=macroscopic electric field at lattice sites 1-NAT
                    generated by the polarization CXPOL1
   CXESCA2(1:3*NAT)=macroscopic electric field at lattice sites 1-NAT
                    generated by the polarization CXPOL2 [only if IORTH=2]
   CXBSCA1(1:3*NAT)=macroscopic=microscopic magnetic field at lattice sites 1-NAT
                    generated by the polarization CXPOL1 [only if NRFLB=1]
   CXBSCA2(1:3*NAT)=macroscopic=microscopic magnetic field at lattice sites 1-NAT
                    generated by the polarization CXPOL2 [only if NRFLB=1 and IORTH=2]
 and writes to file
 if NRFLDB=0
      CFLE1  : P, E_inc, E_sca for incident polarization 1
      CFLE2                    for incident polarization 2 [only if IORTH=2]
 or
 if NRFLDB=1
      CFLEB1 : P, E_inc, E_sca, B_inc, B_sca for incident polarization 1 
      CFLEB2 :                               for incident polarization 2
                                             [only if IORTH=2]

History records of Fortran versions removed.

Copyright (C) 2011,2012 B.T. Draine and P.J. Flatau
Copyright (C) 2011,2012 C++ versions, Choliy V.

This code is covered by the GNU General Public License.
** */
	real dtime = Timeit("Nearfield");

	fprintf(stderr, " >Nearfield x0 = %lf %lf %lf\n", currentTarget->X0().data[0], currentTarget->X0().data[1], currentTarget->X0().data[2]);

	int nx = currentTarget->Nx();
	int ny = currentTarget->Ny();
	int nz = currentTarget->Nz();
	int nxy  = nx * ny;
	int nxyz = nxy * nz;
	int nat3 = 3 * nxyz;

	Vect3<Complex> cxb01_tf, cxb02_tf;
	Complex *cxesca1 = new Complex[nat3];
	Complex *cxbsca1 = NULL;
	if (param->Nrfldb() == NearfieldBMethodBoth)
	{
		cxbsca1 = new Complex[nat3];
	}
	currentTarget->Unreduce(cxadia);

	int j;
	Complex *coff = new Complex[ncomp];
	for(j=0; j<ncomp; ++j)
	{
		coff[j] = Complex((real)3., (real)0.) / (dielec->GetCxeps(j) + (real)2.);
	}
//
	GreenFunctionManager *greenManager = GreenFunctionManager::GetInstance();
	for(int tempIorth=1; tempIorth<=param->Iorth(); ++tempIorth)
	{
		Complex *toUnreduce = (tempIorth == 1) ? cxpol1 : cxpol2;
		currentTarget->Unreduce(toUnreduce);
		greenManager->GetElectric()->Self(param->Cmdfft(), toUnreduce, param->Gamma(), currentTarget->Pyd(), currentTarget->Pzd(), ak_tf, akd, currentTarget->Dx(), cxzw, cxesca1);
//
		if (param->Nrfldb() == NearfieldBMethodBoth)
		{
// allocate CXZG = array that will contain Green function for computing B_sca from P
			bool bAlloc = greenManager->AllocateMagneticBuffer();
			if (bAlloc)
			{
				greenManager->GetMagnetic()->Self(param->Cmdfft(), toUnreduce, param->Gamma(), currentTarget->Pyd(), currentTarget->Pzd(), ak_tf, akd, currentTarget->Dx(), cxzw, cxbsca1);
				if (tempIorth == param->Iorth())
					greenManager->DeallocateMagneticBuffer();
			}
			else
				Wrimsg("Nearfield", "Cannot allocate cxzg");
		}
//
		if (tempIorth == 1)
			cxb01_tf =  cxe02_tf;
		else
			cxb02_tf = -cxe01_tf;
//
// Evaluate incident wave for incident polarization state tempIorth
// for adopted convention E02 = khat x E01
// we have                B01 = khat x E01 = E02
//
// have calculated *microscopic* E field CXESCA1
// now convert to macroscopic E field only changes are within the target material

		short *icompData = currentTarget->Icomp().GetData();			// this loop replaces the commented portion of the code below
		for(int jxyz=0; jxyz<nat3; ++jxyz)
		{
			if (icompData[jxyz] > 0)
				cxesca1[jxyz] *= coff[icompData[jxyz] - 1];
		}
//
//              >>>>> Important Note! <<<<<
// The structure of the WRITE statements below *must* conform to the
// structure of the corresponding READ statements in readnf.f90 
// Any changes must be made in both modules.

		const char *fileName = (param->Nrfldb() == NearfieldBMethodElectric) ? 
			((tempIorth == 1) ? cfle1 : cfle2) :
			((tempIorth == 1) ? cfleb1 : cfleb2);
#ifdef _WIN32
		int modex = O_BINARY|O_WRONLY|O_CREAT;
#else
		int modex = O_WRONLY|O_CREAT;
#endif		
		int iobinFile = open(fileName, modex, S_IWRITE);
		if (iobinFile == -1)
		{
			Errmsg("Nearfield", fileName, "");
			Errmsg("Nearfield", "Error opening iobinFile in Nearfield.", "");
		}
		char Buffer[256];
        sprintf(Buffer, "%s%c", Version(), '\0');
		write(iobinFile, Buffer, strlen(Buffer)+1);
		int ii = VersionNum();
		int nrword = sizeof(real);
		write(iobinFile, &ii, sizeof(int));
		write(iobinFile, &nrword, sizeof(int));
		ii = param->Nrfldb();
		write(iobinFile, &ii, sizeof(int));
		write(iobinFile, &nxyz, sizeof(int));
		write(iobinFile, &currentTarget->Nat0(), sizeof(int));
		write(iobinFile, &nat3, sizeof(int));
		write(iobinFile, &ncomp, sizeof(int));
		write(iobinFile, &nx, sizeof(int));
		write(iobinFile, &ny, sizeof(int));
		write(iobinFile, &nz, sizeof(int));
		currentTarget->X0().Write(iobinFile);
		write(iobinFile, &aeff, sizeof(real));
		write(iobinFile, &param->Nambient(), sizeof(real));
		write(iobinFile, &wave, sizeof(real));
		ak_tf.Write(iobinFile);
		(tempIorth == 1) ? cxe01_tf.Write(iobinFile) : cxe02_tf.Write(iobinFile);
		(tempIorth == 1) ? cxb01_tf.Write(iobinFile) : cxb02_tf.Write(iobinFile);
		write(iobinFile, dielec->GetCxeps(), ncomp * sizeof(Complex));
		for(j=0; j<nxyz; ++j)			// TOREFACT
			currentTarget->Icomp().WriteLine(iobinFile, j);
		write(iobinFile, toUnreduce, nat3 * sizeof(Complex));
		write(iobinFile, cxesca1, nat3 * sizeof(Complex));
		write(iobinFile, cxadia, nat3 * sizeof(Complex));
		if (param->Nrfldb() == NearfieldBMethodBoth)
		{
			write(iobinFile, cxbsca1, nat3 * sizeof(Complex));
		}
		close(iobinFile);
	}
//
	delete [] cxesca1;
	if (param->Nrfldb() == NearfieldBMethodBoth)
		delete [] cxbsca1;
	delete [] coff;

	dtime = Timeit("Nearfield");
}
Exemplo n.º 4
0
void Getmueller(DDscatParameters *param, int ibeta, int iphi, int itheta, PeriodicBoundaryFlag jpbc, real *orderm, real *ordern, real ak1, 
	Vect3<real> *aks_tf, Vect3<real> *ensc_lf, Vect3<real> *ensc_tf, real pyddx, real pzddx, real *sm, real *smori, real *s1111, real *s2121, 
	Complex *cx1121, FourArray *cxfData, SumPackage &sumPackage, Vect3<real> *em1_lf, Vect3<real> *em2_lf, Vect3<real> *em1_tf, Vect3<real> *em2_tf)
{
/* **
 Given:
   IBETA =index specifying rotation of target around axis a1
   IORTH =number of incident polarization states being calculated for
   IPHI  =index specifying phi value for orientation of target axis a1
   ITHETA=index specifying theta value for orientation of target axis a1
   JPBC  = 0 if PBC not used
           1 if PBC used in y direction only
           2 if PBC used in z direction only
           3 if PBC used in both y and z directions
   MXBETA=dimensioning information
   MXSCA =dimensioning information
   MXPHI =dimensioning information
   MXTHET=dimensioning information
   NSCAT =number of scattering directions for evaluation of Mueller matrix
   CMDTRQ='DOTORQ' or 'NOTORQ' depending on whether or not torque calculation is to be carried out
   ENSC_LF(1-3,1-NSCAT)=normalized scattering direction vector in Lab Frame for scattering directions 1-NSCAT
   ENSCR(1-3,1-NSCAT)=normalized scattering direction vector in Target Frame for scattering directions 1-NSCA
   EM1_LF(1-3,1-NSCAT)=unit scattering polarization vector 1 in Lab Frame
   EM2_LF(1-3,1-NSCAT)=unit scattering polarization vector 2 in Lab Frame
   EM1_TF(1-3,1-NSCAT)=unit scattering polarization vector 1 in Target Frame
   EM2_TF(1-3,1-NSCAT)=unit scattering polarization vector 2 in Target Frame
   PHIN(1-NSCAT)=values of PHI for scattering directions 1-NSCAT in Lab Frame [only used if JPBC=0: scattering by finite target]
   AKS_TF(1-3,1-NSCAT)=(kx,ky,kz)*d for NSCAT scattering directions in Target Frame
   ORDERM(1-NSCAT)=scattering order M for case of 1-d or 2-d target
   ORDERN(1-NSCAT)=scattering order N for case of 2-d target
   S1111(1-NSCAT)=weighted sum of |f_11|^2 over previous orientations
   S2121(1-NSCAT)=weighted sum of |f_21|^2 over previous orientations
   CXE01_LF(1-3)    =incident pol state 1 in Lab Frame
   CXE02_LF(1-3)    =                   2
   CXF11(1-NSCAT)=f_11 for current orientation
   CXF12(1-NSCAT)=f_12 for current orientation
   CXF21(1-NSCAT)=f_21 for current orientation
   CXF22(1-NSCAT)=f_22 for current orientation
   QABS(2)       =Q_abs for two incident polarizations
   QABSUM(2)     =weighted sum of Qabs over previous orientations
   QBKSCA(2)     =Q_bk for two incident polarizations
   QBKSUM(2)     =weighted sum of Q_bk over previous orientations
   QEXSUM(2)     =weighted sum of Q_ext over previous orientations
   QEXT(2)       =Q_ext for two incident polarizations
   QPHA(2)       =Q_pha for two incident polarizations
   QPHSUM(2)     =weighted sum of Q_ph over previous orientations
   QSCAG(3,2)    =Q_pr vector for two incident polarizations
   QSCAT(2)      =Q_sca for two incident polarizations
   QSCGSUM(3,2)  =weighted sum of Q_pr vector over prev. orients.
   QSCSUM(2)     =weighted sum of Q_sca over previous orientations
   QTRQAB(3,2)   =absorptive part of Q_gamma for two inc. pols.
   QTRQABSUM(3,2)=weighted sum of Q_gamma over previous orientations
   QTRQSC(3,2)   =scattering part of Q_gamma for two inc. pols.
   QTRQSCSUM(3,2)=weighted sum of Q_gamma over previous orientations
   WGTA(ITHETA,IPHI)=weight factor for theta,phi orientation
   WGTB(IBETA)      =weight factor for beta orientation
   SMORI(1-NSCAT,4,4)=weighted sum of Mueller matrix over previous orientations
 If IORTH=1, returns:
   S1111(1-NSCAT)=updated weighted sum of |f_11|^2 over NSCAT scattering directions
   S2121(1-NSCAT)=updated weighted sum of |f_21|^2
   CX1121(1-NSCAT)=updated weighted summ of f_11*conjg(f_21)

If IORTH=2, returns:
   SM(1-NSCAT,4,4)=Mueller matrix for current orientation, and NSCAT scattering directions
   CXS1(1-NSCAT)=amplitude scattering matrix element S_1 for current orientation
   CXS2(1-NSCAT)=amplitude scattering matrix element S_2 for current orientation
   CXS3(1-NSCAT)=amplitude scattering matrix element S_3 for current orientation
   CXS4(1-NSCAT)=amplitude scattering matrix element S_4 for current orientations
   QABSUM(2)     =updated weighted sum of Q_abs
   QBKSUM(2)     =updated weighted sum of Q_bk
   QEXSUM(2)     =updated weighted sum of Q_ext
   QSCGSUM(3,2)  =updated weighted sum of Q_pr vector
   QSCSUM(2)     =updated weighted sum of Q_sca
   QTRQABSUM(3,2)=updated weighted sum of absorptive contribution to Q_gamma
   QTRQSCSUM(3,2)=updated weighted sum of scattering contribution to Q_gamma

   SMORI(1-NSCAT,4,4)=updated weighted sum of Mueller matrix elements

History:
Fortran versions history removed.

Copyright (C) 1996,1997,1998,2000,2003,2006,2007,2008,2011,2012
              B.T. Draine and P.J. Flatau
This code is covered by the GNU General Public License.
** */

/* **
!*********  Sum scattering properties over orientations ****************
Correspondence to notation of Bohren & Huffman (1983):
Our f_jk correspond to notation of Draine (1988).
For the special case where incident polarization modes 1 and 2 are
arallel and perpendicular to the scattering plane, we have the
relationship between the f_jk and the elements S_j of the amplitude
scattering matrix as defined by Bohren & Huffman (1983) is as follows:
    S_1 = -i*f_22
    S_2 = -i*f_11
    S_3 =  i*f_12
    S_4 =  i*f_21
In this case (incident pol. states parallel,perpendicular to the
scattering plane), the elements of the 4x4 Mueller matrix (see Bohren
Huffman 1983) are related to our f_jk as follows:
    S_11 = [|f_11|^2 + |f_22|^2 + |f_12|^2 + |f_21|^2]/2
    S_12 = [|f_11|^2 + |f_21|^2 - |f_22|^2 - |f_12|^2]/2
    S_13 = -Re[f_11*conjg(f_12) + f_22*conjg(f_21)]
    S_14 =  Im[f_22*conjg(f_21) - f_11*conjg(f_12)]
    S_21 = [|f_11|^2 + |f_12|^2 - |f_22|^2 - |f_21|^2]/2
    S_22 = [|f_11|^2 + |f_22|^2 - |f_21|^2 - |f_12|^2]/2
    S_23 =  Re[f_22*conjg(f_21) - f_11*conjg(f_12)]
    S_24 = -Im[f_11*conjg(f_12) + f_22*conjg(f_21)]
    S_31 = -Re[f_11*conjg(f_21) + f_22*conjg(f_22)]
    S_32 =  Re[f_22*conjg(f_12) - f_22*conjg(f_21)]
    S_33 =  Re[f_22*conjg(f_11) + f_12*conjg(f_21)]
    S_34 =  Im[f_11*conjg(f_22) + f_21*conjg(f_22)]
    S_41 = -Im[f_21*conjg(f_11) + f_22*conjg(f_12)]
    S_42 =  Im[f_22*conjg(f_12) - f_22*conjg(f_11)]
    S_43 =  Im[f_22*conjg(f_11) - f_12*conjg(f_21)]
    S_44 =  Re[f_22*conjg(f_11) - f_12*conjg(f_21)]

Notation internal to this program:
ij.ne.kl: CX_ijkl = \f_ij* \times f_kl  (summed over orientations)
           S_ijij = \f_ij* \times f_ij  (summed over orientations)
4 pure real elements: S1111,S1212,S2121,S2222
8 Complex elements:   CX1112,CX1121,CX1122,CX1221,CX1222,CX2122
4 redundant elts.:    CX1211 = Conjg(CX1112)
                      CX2111 = Conjg(CX1121)
                      CX2112 = Conjg(CX1221)
                      CX2211 = Conjg(CX1122)

In this routine we will carry out fully general calculation of the
4x4 Mueller matrix elements, valid for arbitrary incident polarization
states j=1,2 for which we have the scattering matrix f_ij

First, we compute the amplitude scattering matrix elements S_1,S_2,
S_3,S_4 as defined by Bohren & Huffman:
** */

// Notation:
//        khat_0     = unit vector along incident direction
//        ehat_01    = CXE01 = complex incident polarization vector 1
//        ehat_02    = CXE02 = complex incident polarization vector 2
//        ehat_0perp = incident pol vector perp to scattering plane scattered pol vector perp to scattering plane em2
//        ehat_0para = incident pol vector para to scattering plane
//                   = khat_0 cross ehat_0perp   [conventional def.]
//                   = xhat_LF cross ehat_0perp
//                   = xhat_LF cross [yhat_LF (yhat_LF dot ehat_0perp) + zhat_LF (zhat_LF dot ehat_0perp)]
//                   = - yhat_LF (ehat_0perp dot zhat_LF) + zhat_LF (ehat_0perp dot yhat_LF) - yhat_LF em2_LF(3) + zhat_LF em2_LF(2)
//        em2        = scattered pol vector perp to scattering plane
//        cxa        = conjg(ehat_01) dot yhat_LF
//        cxb        = conjg(ehat_01) dot zhat_LF
//        cxc        = conjg(ehat_02) dot yhat_LF
//        cxd        = conjg(ehat_02) dot zhat_LF
//
// WG=weighting factor for this orientation

	const Complex conei((real)0., (real)1.);
	const real half_ = (real)0.5;
	Complex cxa, cxb, cxc, cxd, cxfac0, cxfac1, cxfac2;
	real fac;
    int nd, k;

	real wg = param->GetOriData()->GetWgtaValue(itheta, iphi) * param->GetOriData()->GetWgtb(ibeta);
	if (param->Iorth() == 2)
	{
		FourArray *myData = new FourArray;
		myData->Alloc(param->Nscat());
		Complex *myS1 = myData->Cxs1();
		Complex *myS2 = myData->Cxs2();
		Complex *myS3 = myData->Cxs3();
		Complex *myS4 = myData->Cxs4();
//
// Compute Complex scattering amplitudes S_1,S_2,S_3,S_4 for this particular target orientation and NSCAT scattering directions:
		switch(jpbc)				// ChB: TODO the code snippets are identical for every jpbc
		{
		case PeriodicNo:
			cxa = param->Cxe01_lf().data[1].conjg();
            cxb = param->Cxe01_lf().data[2].conjg();
            cxc = param->Cxe02_lf().data[1].conjg();
            cxd = param->Cxe02_lf().data[2].conjg();
			for(nd=0; nd<param->Nscat(); ++nd)
			{
				real cosphi =  em2_lf[nd].data[2];
				real sinphi = -em2_lf[nd].data[1];
				Complex cxaa = cxa * cosphi + cxb * sinphi;
				Complex cxbb = cxb * cosphi - cxa * sinphi;
				Complex cxcc = cxc * cosphi + cxd * sinphi;
				Complex cxdd = cxd * cosphi - cxc * sinphi;
				myS1[nd] = -conei * (cxfData->Cx21(nd) * cxbb + cxfData->Cx22(nd) * cxdd);
				myS2[nd] = -conei * (cxfData->Cx11(nd) * cxaa + cxfData->Cx12(nd) * cxcc);
				myS3[nd] =  conei * (cxfData->Cx11(nd) * cxbb + cxfData->Cx12(nd) * cxdd);
				myS4[nd] =  conei * (cxfData->Cx21(nd) * cxaa + cxfData->Cx22(nd) * cxcc);
			}
			break;

		case PeriodicY:
		case PeriodicZ:
// JPBC = 1 or 2:
// ENSC(1-3,ND) = components of scattering unit vector in Lab Frame
// CXA,CXB = y,z components of incident polarization state 1 in Lab Frame
// CXC,CXD = y,z                                           2 in Lab Frame
			cxa = param->Cxe01_lf().data[1].conjg();
            cxb = param->Cxe01_lf().data[2].conjg();
            cxc = param->Cxe02_lf().data[1].conjg();
            cxd = param->Cxe02_lf().data[2].conjg();
			for(nd=0; nd<param->Nscat(); ++nd)
			{
				real cosphi =  em2_lf[nd].data[2];
				real sinphi = -em2_lf[nd].data[1];
				Complex cxaa = cxa * cosphi + cxb * sinphi;
				Complex cxbb = cxb * cosphi - cxa * sinphi;
				Complex cxcc = cxc * cosphi + cxd * sinphi;
				Complex cxdd = cxd * cosphi - cxc * sinphi;
				myS1[nd] = -conei * (cxfData->Cx21(nd) * cxbb + cxfData->Cx22(nd) * cxdd);
				myS2[nd] = -conei * (cxfData->Cx11(nd) * cxaa + cxfData->Cx12(nd) * cxcc);
				myS3[nd] =  conei * (cxfData->Cx11(nd) * cxbb + cxfData->Cx12(nd) * cxdd);
				myS4[nd] =  conei * (cxfData->Cx21(nd) * cxaa + cxfData->Cx22(nd) * cxcc);
			}
			break;

		case PeriodicBoth:
//fprintf(stderr, "Getmueller %p\n", cxfData);
//
// JPBC = 3
//     Target is periodic in y and z directions in Lab Frame Allowed scattering directions are identified by scattering order (M,N).  
//     For each allowed (M,N) there is one forward (transmitted) direction and one backward (reflected) direction.
//     Following convention set in subroutine PBCSCAVEC for JPBC=3, it is assumed that NSCAT is even, with the first NSCAT/2 directions 
//     corresponding to transmission, and the remaining NSCAT/2 directions corresponding to reflection
//
// ENSC(1-3,ND) = components of scattering unit vector in Lab Frame
// EM1(1-3,ND) = components of scattering polarization 1 in Lab Frame
// EM2(1-3,ND) = components of scattering polarization 2 in Lab Frame
			cxa = param->Cxe01_lf().data[1].conjg();
			cxb = param->Cxe01_lf().data[2].conjg();
			cxc = param->Cxe02_lf().data[1].conjg();
			cxd = param->Cxe02_lf().data[2].conjg();
			for(nd=0; nd<param->Nscat(); ++nd)
			{
				real cosphi =  em2_lf[nd].data[2];
				real sinphi = -em2_lf[nd].data[1];
				Complex cxaa = cxa * cosphi + cxb * sinphi;
				Complex cxbb = cxb * cosphi - cxa * sinphi;
				Complex cxcc = cxc * cosphi + cxd * sinphi;
				Complex cxdd = cxd * cosphi - cxc * sinphi;
				myS1[nd] = -conei * (cxfData->Cx21(nd) * cxbb + cxfData->Cx22(nd) * cxdd);
				myS2[nd] = -conei * (cxfData->Cx11(nd) * cxaa + cxfData->Cx12(nd) * cxcc);
				myS3[nd] =  conei * (cxfData->Cx11(nd) * cxbb + cxfData->Cx12(nd) * cxdd);
				myS4[nd] =  conei * (cxfData->Cx21(nd) * cxaa + cxfData->Cx22(nd) * cxcc);

//fprintf(stderr, "%lf %lf %lf %lf %lf %lf %lf %lf\n", cxfData->Cx11(nd).re, cxfData->Cx11(nd).im, cxfData->Cx12(nd).re, cxfData->Cx12(nd).im, 
//		 cxfData->Cx21(nd).re, cxfData->Cx21(nd).im, cxfData->Cx22(nd).re, cxfData->Cx22(nd).im);
//fprintf(stderr, "%lf %lf %lf %lf %lf %lf %lf %lf\n", myS1[nd].re, myS1[nd].im, myS2[nd].re, myS2[nd].im, myS3[nd].re, myS3[nd].im, myS4[nd].re, myS4[nd].im);

			}
			break;

		default:
			break;
		}
//
// if JPBC=1,2,3 (target periodic in y, z, or y and z directions):
// Check for special case: JPBC=3 (2-d target) and forward scattering wit
// ORDERM=ORDERN=0.  For this case we need to add incident wave to
// S_1 and S_2.
// Note that S_1 and S_2 are defined such that for M=N=0 we change
// iS_1 -> iS_1 +1  and iS_2 -> iS_2 +1
//  S_1 ->  S_1 -i       S_2 ->  S_2 -i
// note that CXS1 and CXS2 have yet to be multiplied by factor
// 2*pi/(ak1*aksr(1,nd)*pyddx*pzddx)
		if (jpbc == PeriodicBoth)
		{
			for(nd=0; nd<param->Nscat() / 2; ++nd)
			{
				if ((nint_(orderm[nd]) == 0) && (nint_(ordern[nd]) == 0))
				{
// Zero-degree forward-scattering need to add incident wave to radiated wave
// 2012.04.26 (BTD) change
// !                  CXFAC0=AKS_TF(1,ND)*AK1*PYDDX*PZDDX/(2._WP*PI)
					cxfac0 = Complex(Fabs(aks_tf[nd].data[0]) * ak1 * pyddx * pzddx / TwoPi, (real)0.);
// ! 2012.04.25 (BTD): for reasons not understood, incident wave added for S2 has different sign from S1
// !                   ... does this indicate a sign mistake in calculation of either S1 or S2?
// !                   ... is it possible that there is an error in eq. 68 of Draine & Flatau 2008?. Something like this could
// 							arise from a 180deg shift in directions between
// !                       the incident and scattered "parallel" basis vectors, or between the incident and scattered "perpendicular" basis vectors (should check for this in output files!)
// !                   This appears to indicate that for JPBC=3 the
// !                   sign of either CXS1 or CXS2 is incorrect
// !                   The Mueller matrix elements S11, S22, S12, and S21 appear
// !                   to be correct, but they would not be affected by
// !                   a sign error in either CXS1 or CXS2
// !                   Elements S13,S14,S23,S24,S31,S32,S33,S34,S41,S42,S43,S44
// !                   would be sensitive to a sign error, and it would be
// !                   a good idea to find a way to test them.
					myS1[nd] -= cxfac0;
					myS2[nd] += cxfac0;

//fprintf(stderr, "%d %lf %lf\n", nd, cxfac0.re, cxfac0.im);

				}
			}
		}
//
// Calculation of scattering amplitudes CXS1, CXS2, CXS3, CXS4 is complete. 
// Now compute Mueller matrix elements for this particular target orientation:

		int index;
		for(nd=0; nd<param->Nscat(); ++nd)
		{
			index = 16 * nd;
			sm[index +  0] = half_ * (myS1[nd] * myS1[nd].conjg() + myS2[nd] * myS2[nd].conjg() + myS3[nd] * myS3[nd].conjg() + myS4[nd] * myS4[nd].conjg()).re;
			sm[index +  1] = half_ * (myS2[nd] * myS2[nd].conjg() - myS1[nd] * myS1[nd].conjg() + myS4[nd] * myS4[nd].conjg() - myS3[nd] * myS3[nd].conjg()).re;
			sm[index +  2] =         (myS2[nd] * myS3[nd].conjg() + myS1[nd] * myS4[nd]).re;
			sm[index +  3] =         (myS2[nd] * myS3[nd].conjg() - myS1[nd] * myS4[nd]).im;
			sm[index +  4] = half_ * (myS2[nd] * myS2[nd].conjg() - myS1[nd] * myS1[nd].conjg() - myS4[nd] * myS4[nd].conjg() + myS3[nd] * myS3[nd].conjg()).re;
			sm[index +  5] = half_ * (myS2[nd] * myS2[nd].conjg() + myS1[nd] * myS1[nd].conjg() - myS4[nd] * myS4[nd].conjg() - myS3[nd] * myS3[nd].conjg()).re;
			sm[index +  6] =         (myS2[nd] * myS3[nd].conjg() - myS1[nd] * myS4[nd].conjg()).re;
			sm[index +  7] =         (myS2[nd] * myS3[nd].conjg() + myS1[nd] * myS4[nd].conjg()).im;
			sm[index +  8] =         (myS2[nd] * myS4[nd].conjg() + myS1[nd] * myS3[nd].conjg()).re;
			sm[index +  9] =         (myS2[nd] * myS4[nd].conjg() - myS1[nd] * myS3[nd].conjg()).re;
			sm[index + 10] =         (myS1[nd] * myS2[nd].conjg() + myS3[nd] * myS4[nd].conjg()).re;
			sm[index + 11] =         (myS2[nd] * myS1[nd].conjg() + myS4[nd] * myS3[nd].conjg()).im;
			sm[index + 12] =         (myS4[nd] * myS2[nd].conjg() + myS1[nd] * myS3[nd].conjg()).im;
			sm[index + 13] =         (myS4[nd] * myS2[nd].conjg() - myS1[nd] * myS3[nd].conjg()).im;
			sm[index + 14] =         (myS1[nd] * myS2[nd].conjg() - myS3[nd] * myS4[nd].conjg()).im;
			sm[index + 15] =         (myS1[nd] * myS2[nd].conjg() - myS3[nd] * myS4[nd].conjg()).re;
		}
//
		real fac0 = (real)0.;
		if (jpbc != PeriodicNo)
		{
			switch(jpbc)
			{
			case PeriodicY:							// Prepare to calculate S^{(1d)} for target with 1-d periodicity in y
				fac0 = TwoPi / (ak1 * pyddx * pyddx);
				break;

			case PeriodicZ:							// Prepare to calculate S^{(1d)} for target with 1-d periodicity in z
				fac0 = TwoPi / (ak1 * pzddx * pzddx);
				break;

			case PeriodicBoth:						// Prepare to calculate S^{(2d)} for target with periodicity in y and z
				fac0 = TwoPi / (ak1 * pyddx * pzddx);
				fac0 = fac0 * fac0;
				break;

			default:
				break;
			}
//
// k*sin(alpha_s)=component of k_s perpendicular to target
			for(nd=0; nd<param->Nscat(); ++nd)
			{
				switch(jpbc)
				{
				case PeriodicY:
					fac = fac0 / Sqrt(aks_tf[nd].data[0] * aks_tf[nd].data[0] + aks_tf[nd].data[2] * aks_tf[nd].data[2]);
					break;

				case PeriodicZ:
					fac = fac0 / Sqrt(aks_tf[nd].data[0] * aks_tf[nd].data[0] + aks_tf[nd].data[1] * aks_tf[nd].data[1]);
					break;

				case PeriodicBoth:
					fac = fac0 / (aks_tf[nd].data[0] * aks_tf[nd].data[0]);
					break;

				default:
					Errmsg("Fatal", "Getmueller", " invalid jpbc");
					break;
				}
               
				index = 16 * nd;
				for(k=0; k<16; ++k)
				{
					sm[index + k] *= fac;
				}
			}
		}
//
// Augment Mueller matrix for orientational average
		index = 16 * param->Nscat();
		for(nd=0; nd<index; ++nd)
		{
			smori[nd] += sm[nd] * wg;
		}
		delete myData;
	}
	else
	{
// 
// When IORTH=1, cannot compute full Mueller matrix. Compute three scattering properties:
		for(nd=0; nd<param->Nscat(); ++nd)
		{
			s1111[nd]  += (cxfData->Cx11(nd).conjg() * cxfData->Cx11(nd)).re * wg;
			s2121[nd]  += (cxfData->Cx21(nd).conjg() * cxfData->Cx21(nd)).re * wg;
			cx1121[nd] += (cxfData->Cx11(nd).conjg() * cxfData->Cx21(nd)) * wg;
		}
	}
// 
// Now augment sums of QABS,QBKSCA,QEXT,QSCA,G*QSCA over incident directions and polarizations.
	for(int jo=0; jo<param->Iorth(); ++jo)
	{
		sumPackage.Qext().Qsum1()[jo]  += sumPackage.Qext().Q()[jo] * wg;
		sumPackage.Qabs().Qsum1()[jo]  += sumPackage.Qabs().Q()[jo] * wg;
		sumPackage.Qbksca().Qsum1()[jo] += sumPackage.Qbksca().Q()[jo] * wg;
		sumPackage.Qpha().Qsum1()[jo] += sumPackage.Qpha().Q()[jo] * wg;
		sumPackage.Qsca().Qsum1()[jo] += sumPackage.Qsca().Q()[jo] * wg;
		sumPackage.Qscag2().Qsum1()[jo] += sumPackage.Qscag2().Q()[jo] * wg;
        sumPackage.Qscag().Qsum1()[jo] += sumPackage.Qscag().Q()[jo] * wg;
		if (DDscatParameters::GetInstance()->Cmdtrq() == TorqMethod_DOTORQ)
		{
			sumPackage.Qtrqab().Qsum1()[jo] += sumPackage.Qtrqab().Q()[jo] * wg;
			sumPackage.Qtrqsc().Qsum1()[jo] += sumPackage.Qtrqsc().Q()[jo] * wg;
		}
	}
}
Exemplo n.º 5
0
/////////////////////////////////////////////////////////////////////////////////////////
//
//通过文件对话框选取文件
//
//入口:
//		szFileType - 过滤串
//		szTitle    - 对话框标题串
//		bSave      - ‘打开’/‘另存为’对话框选择标签
//		hWnd       - 对话框父窗口
//		hookproc   - 对话框钩子函数
//
//返回:
//		TRUE - 关联成功、FALSE - 失败
//
///////////////////////////////////////////////////////////////////////////////////////
int ringFile::Select(LPCTSTR szFileType,LPCTSTR szTitle,BOOL bSave/*=FALSE*/, 
							HWND hWnd/*=m_hWnd*/,LPCTSTR dlgEx/*=NULL*/,LPOFNHOOKPROC hookproc/*=NULL*/,
							LONG lCustData/*=0*/)
{
	RINGOPENFILENAME	ofnTemp;
	DWORD			Errval;
	TCHAR			d[MAX_PATH],f[MAX_PATH],*p,*v;
	
	memset(d,0,MAX_PATH);

	if(szTitle == NULL)
		szTitle = LANSTR_FILEOPEN;
	
	// 规格化过滤串
	int len = MAX_PATH * sizeof(TCHAR);
	int n0cnt = 0;
	p = (LPTSTR)szFileType;
	v = f;
	memset(f,0,len);

	for(int i=0;i<len;i++)
	{
		if(*p == '|' || *p == '\0')
		{
			*v++ = '\0';
			p++;
			n0cnt ++;
			if(n0cnt > 1)
				break;
		}
		else
		{
			*v++ = *p++;
			n0cnt = 0;
		}		
	}
#if(_WIN32_WINNT < 0x0500)
	n0cnt = 0;
#else
	n0cnt = 12;
#endif
	
	if(OSType() < OST_WIN2KPRO)
		ofnTemp.m_ofn.lStructSize = sizeof( OPENFILENAME ) - n0cnt;
	else
		ofnTemp.m_ofn.lStructSize = sizeof(RINGOPENFILENAME);

	ofnTemp.m_ofn.hwndOwner         = hWnd;
	ofnTemp.m_ofn.hInstance         = GetInstance();
	ofnTemp.m_ofn.lpstrFilter       = f;
	ofnTemp.m_ofn.lpstrCustomFilter = NULL;
	ofnTemp.m_ofn.nMaxCustFilter    = 0;
	ofnTemp.m_ofn.nFilterIndex      = 1;
	ofnTemp.m_ofn.lpstrFile         = d;
	ofnTemp.m_ofn.nMaxFile          = MAX_PATH;
	ofnTemp.m_ofn.lpstrFileTitle    = NULL;
	ofnTemp.m_ofn.nMaxFileTitle     = NULL;
	ofnTemp.m_ofn.lpstrInitialDir   = NULL;//GetSpecPath(RFSP_CURRPATH);
	ofnTemp.m_ofn.lpstrTitle        = szTitle;	
	
	if(dlgEx && hookproc)
		ofnTemp.m_ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER |OFN_ENABLETEMPLATE|OFN_ENABLESIZING;
	else
		ofnTemp.m_ofn.Flags = OFN_EXPLORER;
	
	ofnTemp.m_ofn.nFileOffset    = NULL;
	ofnTemp.m_ofn.nFileExtension = 0;
	ofnTemp.m_ofn.lpstrDefExt    = "*";
	ofnTemp.m_ofn.lCustData      = lCustData;
	ofnTemp.m_ofn.lpfnHook       = hookproc;
	ofnTemp.m_ofn.lpTemplateName = dlgEx;
	
	ofnTemp.FlagsEx = 0;

	if(!bSave)
		bSave = GetOpenFileName((LPOPENFILENAME)&ofnTemp);
	else
		bSave = GetSaveFileName((LPOPENFILENAME)&ofnTemp);
	
	if(!bSave)
	{
		Errval = CommDlgExtendedError();
		
		if(Errval != 0)
		{
			memset(f,0,len);
			if(GetErrMessage(Errval,f,MAX_PATH))
				Errmsg(f);
		}
		return FALSE;
	}
	
	SetFile(d);
	
	return TRUE;
}