|  | @@ -653,7 +653,7 @@ template <class Real> void SphericalHarmonics<Real>::StokesEvalSL(const Vector<R
 | 
	
		
			
				|  |  |      assert(SHBasis.Dim(0) == N * COORD_DIM);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  Matrix<Real> StokesOp(SHBasis.Dim(0), SHBasis.Dim(1));
 | 
	
		
			
				|  |  | +  Matrix<Real> StokesOp(N * COORD_DIM, COORD_DIM * M);
 | 
	
		
			
				|  |  |    for (Long i = 0; i < N; i++) { // Set StokesOp
 | 
	
		
			
				|  |  |      for (Long m = 0; m <= p0; m++) {
 | 
	
		
			
				|  |  |        for (Long n = m; n <= p0; n++) {
 | 
	
	
		
			
				|  | @@ -814,7 +814,7 @@ template <class Real> void SphericalHarmonics<Real>::StokesEvalDL(const Vector<R
 | 
	
		
			
				|  |  |      assert(SHBasis.Dim(0) == N * COORD_DIM);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  Matrix<Real> StokesOp(SHBasis.Dim(0), SHBasis.Dim(1));
 | 
	
		
			
				|  |  | +  Matrix<Real> StokesOp(N * COORD_DIM, COORD_DIM * M);
 | 
	
		
			
				|  |  |    for (Long i = 0; i < N; i++) { // Set StokesOp
 | 
	
		
			
				|  |  |      for (Long m = 0; m <= p0; m++) {
 | 
	
		
			
				|  |  |        for (Long n = m; n <= p0; n++) {
 | 
	
	
		
			
				|  | @@ -937,6 +937,237 @@ template <class Real> void SphericalHarmonics<Real>::StokesEvalDL(const Vector<R
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +template <class Real> void SphericalHarmonics<Real>::StokesEvalKL(const Vector<Real>& S, SHCArrange arrange, Long p0, const Vector<Real>& coord, const Vector<Real>& norm, bool interior, Vector<Real>& X) {
 | 
	
		
			
				|  |  | +  Long M = (p0+1) * (p0+1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  Long dof;
 | 
	
		
			
				|  |  | +  Matrix<Real> B1;
 | 
	
		
			
				|  |  | +  { // Set B1, dof
 | 
	
		
			
				|  |  | +    Vector<Real> B0;
 | 
	
		
			
				|  |  | +    SHCArrange1(S, arrange, p0, B0);
 | 
	
		
			
				|  |  | +    dof = B0.Dim() / M / COORD_DIM;
 | 
	
		
			
				|  |  | +    assert(B0.Dim() == dof * COORD_DIM * M);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    B1.ReInit(dof, COORD_DIM * M);
 | 
	
		
			
				|  |  | +    Vector<Real> B1_(B1.Dim(0) * B1.Dim(1), B1.begin(), false);
 | 
	
		
			
				|  |  | +    SHCArrange0(B0, p0, B1_, SHCArrange::COL_MAJOR_NONZERO);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  assert(B1.Dim(1) == COORD_DIM * M);
 | 
	
		
			
				|  |  | +  assert(B1.Dim(0) == dof);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  Long N = coord.Dim() / COORD_DIM;
 | 
	
		
			
				|  |  | +  assert(coord.Dim() == N * COORD_DIM);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  Matrix<Real> SHBasis;
 | 
	
		
			
				|  |  | +  Vector<Real> R, cos_theta_phi;
 | 
	
		
			
				|  |  | +  { // Set R, SHBasis
 | 
	
		
			
				|  |  | +    R.ReInit(N);
 | 
	
		
			
				|  |  | +    cos_theta_phi.ReInit(2 * N);
 | 
	
		
			
				|  |  | +    for (Long i = 0; i < N; i++) { // Set R, cos_theta_phi
 | 
	
		
			
				|  |  | +      ConstIterator<Real> x = coord.begin() + i * COORD_DIM;
 | 
	
		
			
				|  |  | +      R[i] = sqrt<Real>(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
 | 
	
		
			
				|  |  | +      cos_theta_phi[i * 2 + 0] = x[2] / R[i];
 | 
	
		
			
				|  |  | +      cos_theta_phi[i * 2 + 1] = atan2(x[1], x[0]); // TODO: works only for float and double
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    SHBasisEval(p0, cos_theta_phi, SHBasis);
 | 
	
		
			
				|  |  | +    assert(SHBasis.Dim(1) == M);
 | 
	
		
			
				|  |  | +    assert(SHBasis.Dim(0) == N);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  Matrix<Real> StokesOp(N * COORD_DIM, COORD_DIM * M);
 | 
	
		
			
				|  |  | +  for (Long i = 0; i < N; i++) { // Set StokesOp
 | 
	
		
			
				|  |  | +    StaticArray<Real, COORD_DIM> norm0;
 | 
	
		
			
				|  |  | +    Real cos_theta, sin_theta, cos_phi, sin_phi;
 | 
	
		
			
				|  |  | +    { // Set cos_theta, sin_theta, cos_phi, sin_phi
 | 
	
		
			
				|  |  | +      cos_theta = cos_theta_phi[i * 2 + 0];
 | 
	
		
			
				|  |  | +      sin_theta = sqrt<Real>(1 - cos_theta * cos_theta);
 | 
	
		
			
				|  |  | +      cos_phi = cos(cos_theta_phi[i * 2 + 1]);
 | 
	
		
			
				|  |  | +      sin_phi = sin(cos_theta_phi[i * 2 + 1]);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    { // Set norm0 <-- Q^t * norm
 | 
	
		
			
				|  |  | +      StaticArray<Real,9> Q;
 | 
	
		
			
				|  |  | +      { // Set Q
 | 
	
		
			
				|  |  | +        Q[0] = sin_theta*cos_phi; Q[1] = sin_theta*sin_phi; Q[2] = cos_theta;
 | 
	
		
			
				|  |  | +        Q[3] = cos_theta*cos_phi; Q[4] = cos_theta*sin_phi; Q[5] =-sin_theta;
 | 
	
		
			
				|  |  | +        Q[6] =          -sin_phi; Q[7] =           cos_phi; Q[8] =         0;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      StaticArray<Real,COORD_DIM> in;
 | 
	
		
			
				|  |  | +      in[0] = norm[i * COORD_DIM + 0];
 | 
	
		
			
				|  |  | +      in[1] = norm[i * COORD_DIM + 1];
 | 
	
		
			
				|  |  | +      in[2] = norm[i * COORD_DIM + 2];
 | 
	
		
			
				|  |  | +      norm0[0] = Q[0] * in[0] + Q[1] * in[1] + Q[2] * in[2];
 | 
	
		
			
				|  |  | +      norm0[1] = Q[3] * in[0] + Q[4] * in[1] + Q[5] * in[2];
 | 
	
		
			
				|  |  | +      norm0[2] = Q[6] * in[0] + Q[7] * in[1] + Q[8] * in[2];
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    Complex<Real> imag(0,1);
 | 
	
		
			
				|  |  | +    Complex<Real> exp_iphi(cos_phi, sin_phi);
 | 
	
		
			
				|  |  | +    Complex<Real> exp_iphi_conj(cos_phi, -sin_phi);
 | 
	
		
			
				|  |  | +    Real cot_theta = cos_theta / sin_theta;
 | 
	
		
			
				|  |  | +    Real csc_theta = 1 / sin_theta;
 | 
	
		
			
				|  |  | +    Real cos_2theta = 2 * cos_theta * cos_theta - 1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    for (Long m = 0; m <= p0; m++) {
 | 
	
		
			
				|  |  | +      for (Long n = m; n <= p0; n++) {
 | 
	
		
			
				|  |  | +        auto read_coeff = [&](Long n, Long m) {
 | 
	
		
			
				|  |  | +          Complex<Real> c;
 | 
	
		
			
				|  |  | +          if (0 <= m && m <= n && n <= p0) {
 | 
	
		
			
				|  |  | +            Long idx = (2 * p0 - m + 2) * m - (m ? p0+1 : 0) + n;
 | 
	
		
			
				|  |  | +            c.real = SHBasis[i][idx];
 | 
	
		
			
				|  |  | +            if (m) {
 | 
	
		
			
				|  |  | +              idx += (p0+1-m);
 | 
	
		
			
				|  |  | +              c.imag = SHBasis[i][idx];
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +          return c;
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        auto write_coeff = [&](Complex<Real> c, Long n, Long m, Long k0, Long k1) {
 | 
	
		
			
				|  |  | +          if (0 <= m && m <= n && n <= p0 && 0 <= k0 && k0 < COORD_DIM && 0 <= k1 && k1 < COORD_DIM) {
 | 
	
		
			
				|  |  | +            Long idx = (2 * p0 - m + 2) * m - (m ? p0+1 : 0) + n;
 | 
	
		
			
				|  |  | +            StokesOp[i * COORD_DIM + k1][k0 * M + idx] = c.real;
 | 
	
		
			
				|  |  | +            if (m) {
 | 
	
		
			
				|  |  | +              idx += (p0+1-m);
 | 
	
		
			
				|  |  | +              StokesOp[i * COORD_DIM + k1][k0 * M + idx] = c.imag;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        auto Ynm0 = read_coeff(n, m + 0);
 | 
	
		
			
				|  |  | +        auto Ynm1 = read_coeff(n, m + 1);
 | 
	
		
			
				|  |  | +        auto Ynm2 = read_coeff(n, m + 2);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Complex<Real> KV[COORD_DIM][COORD_DIM];
 | 
	
		
			
				|  |  | +        Complex<Real> KW[COORD_DIM][COORD_DIM];
 | 
	
		
			
				|  |  | +        Complex<Real> KX[COORD_DIM][COORD_DIM];
 | 
	
		
			
				|  |  | +        if (interior) {
 | 
	
		
			
				|  |  | +          KV[0][0] = 0;
 | 
	
		
			
				|  |  | +          KV[0][1] = 0;
 | 
	
		
			
				|  |  | +          KV[0][2] = 0;
 | 
	
		
			
				|  |  | +          KV[1][0] = 0;
 | 
	
		
			
				|  |  | +          KV[1][1] = 0;
 | 
	
		
			
				|  |  | +          KV[1][2] = 0;
 | 
	
		
			
				|  |  | +          KV[2][0] = 0;
 | 
	
		
			
				|  |  | +          KV[2][1] = 0;
 | 
	
		
			
				|  |  | +          KV[2][2] = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          KW[0][0] = 0;
 | 
	
		
			
				|  |  | +          KW[0][1] = 0;
 | 
	
		
			
				|  |  | +          KW[0][2] = 0;
 | 
	
		
			
				|  |  | +          KW[1][0] = 0;
 | 
	
		
			
				|  |  | +          KW[1][1] = 0;
 | 
	
		
			
				|  |  | +          KW[1][2] = 0;
 | 
	
		
			
				|  |  | +          KW[2][0] = 0;
 | 
	
		
			
				|  |  | +          KW[2][1] = 0;
 | 
	
		
			
				|  |  | +          KW[2][2] = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          KX[0][0] = 0;
 | 
	
		
			
				|  |  | +          KX[0][1] = 0;
 | 
	
		
			
				|  |  | +          KX[0][2] = 0;
 | 
	
		
			
				|  |  | +          KX[1][0] = 0;
 | 
	
		
			
				|  |  | +          KX[1][1] = 0;
 | 
	
		
			
				|  |  | +          KX[1][2] = 0;
 | 
	
		
			
				|  |  | +          KX[2][0] = 0;
 | 
	
		
			
				|  |  | +          KX[2][1] = 0;
 | 
	
		
			
				|  |  | +          KX[2][2] = 0;
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          Real r = R[i];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          KV[0][0] =  (2*n*(n*n+3*n+2)*pow<Real>(r,-n-3)*Ynm0) / (4*n*n+8*n+3);
 | 
	
		
			
				|  |  | +          KW[0][0] = -(n*pow<Real>(r,-n-3)*(2*n*n*n*(r*r-1) + n*n*(7*r*r-5) + n*(r*r-1) - r*r + 2)*Ynm0) / (4*n*n-1);
 | 
	
		
			
				|  |  | +          KX[0][0] =  0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          KV[0][1] = -(2*n*(n+2)*exp_iphi_conj*pow<Real>(r,-n-3)*(sqrt<Real>(-m*m-m+n*n+n)*Ynm1 + m*exp_iphi*cot_theta*Ynm0)) / (4*n*n+8*n+3);
 | 
	
		
			
				|  |  | +          KW[0][1] =  (exp_iphi_conj*pow<Real>(r,-n-3)*(2*n*n*n*(r*r-1) + n*n*(r*r-3) - 2*n*(r*r-1) - r*r))*(sqrt<Real>(-m*m-m+n*n+n)*Ynm1 + m*exp_iphi*cot_theta*Ynm0) / (4*n*n-1);
 | 
	
		
			
				|  |  | +          KX[0][1] =  (imag*m*(n+2)*pow<Real>(r,-n-2)*csc_theta*Ynm0) / (2*n+1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          KV[0][2] = -(2*imag*m*n*(n+2)*pow<Real>(r,-n-3)*csc_theta*Ynm0) / (4*n*n+8*n+3);
 | 
	
		
			
				|  |  | +          KW[0][2] =  (imag*m*pow<Real>(r,-n-3)*(2*n*n*n*(r*r-1) + n*n*(r*r-3) - 2*n*(r*r-1) - r*r)*csc_theta*Ynm0) / (4*n*n-1);
 | 
	
		
			
				|  |  | +          KX[0][2] =  (pow<Real>(r,-n-3)*(-m*(n+2)*r*cot_theta*Ynm0 - (n+2)*exp_iphi_conj*r*sqrt<Real>(-m*(m+1) + n*n + n)*Ynm1)) / (2*n+1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          KV[1][0] = -(2*n*(n+2)*exp_iphi_conj*pow<Real>(r,-n-3)*(sqrt<Real>(-m*m-m+n*n+n)*Ynm1 + m*exp_iphi*cot_theta*Ynm0)) / (4*n*n+8*n+3);
 | 
	
		
			
				|  |  | +          KW[1][0] =  (exp_iphi_conj*pow<Real>(r,-n-3)*(2*n*n*n*(r*r-1) + n*n*(r*r-3) - 2*n*(r*r-1) - r*r))*(sqrt<Real>(-m*m-m+n*n+n)*Ynm1 + m*exp_iphi*cot_theta*Ynm0) / (4*n*n-1);
 | 
	
		
			
				|  |  | +          KX[1][0] =  (imag*m*(n+2)*pow<Real>(r,-n-2)*csc_theta*Ynm0) / (2*n+1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          KV[1][1] =  (2*(2*m+1)*n*exp_iphi*sqrt<Real>(-m*m-m+n*n+n)*cot_theta*Ynm1 - 2*n*exp_iphi*exp_iphi*(-m*m*cot_theta*cot_theta+m*csc_theta*csc_theta+n+1)*Ynm0 + 2*n*sqrt<Real>(m*m*m*m + 4*m*m*m + m*m*(-2*n*n-2*n+5) + m*(-4*n*n-4*n+2) + n*(n*n*n+2*n*n-n-2))*Ynm2) * (exp_iphi_conj*exp_iphi_conj*pow<Real>(r,-n-3)) / (4*n*n+8*n+3);
 | 
	
		
			
				|  |  | +          KW[1][1] =  (Ynm0*((m-1)*m*exp_iphi*exp_iphi*(2*n*n-(n-2)*(2*n+1)*r*r-n)*csc_theta*csc_theta - exp_iphi*exp_iphi*((n-2)*(2*n+1)*r*r*(n-m*m)+n*(2*n-1)*(m*m+n+1))) + sqrt<Real>((m-n)*(m-n+1)*(m+n+1)*(m+n+2))*(2*n*n-(n-2)*(2*n+1)*r*r-n)*Ynm2 + (2*m+1)*exp_iphi*sqrt<Real>(-m*(m+1)+n*n+n)*(2*n*n-(n-2)*(2*n+1)*r*r-n)*cot_theta*Ynm1) * (exp_iphi_conj*exp_iphi_conj*pow<Real>(r,-n-3)) / (4*n*n-1);
 | 
	
		
			
				|  |  | +          KX[1][1] = -(sqrt<Real>(-m*m-m+n*n+n)*Ynm1 + (m-1)*exp_iphi*cot_theta*Ynm0)*(2*imag*m*exp_iphi_conj*pow<Real>(r,-n-2)*csc_theta) / (2*n+1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          KV[1][2] =  (2*imag*m*n*exp_iphi_conj*pow<Real>(r,-n-3)*csc_theta*(sqrt<Real>(-m*m-m+n*n+n)*Ynm1 + (m-1)*exp_iphi*cot_theta*Ynm0)) / (4*n*n+8*n+3);
 | 
	
		
			
				|  |  | +          KW[1][2] = -(imag*m*exp_iphi_conj*pow<Real>(r,-n-3)*(-2*n*n + (n-2)*(2*n+1)*r*r + n)*csc_theta)*(sqrt<Real>(-m*(m+1) + n*n + n)*Ynm1 + (m-1)*exp_iphi*cot_theta*Ynm0) / (4*n*n-1);
 | 
	
		
			
				|  |  | +          KX[1][2] =  (4*m*exp_iphi*sqrt<Real>(-m*(m+1)+n*n+n)*cot_theta*Ynm1 + 2*sqrt<Real>((m-n)*(m-n+1)*(m+n+1)*(m+n+2))*Ynm2 + (m-1)*m*exp_iphi*exp_iphi*(cos_2theta+3)*csc_theta*csc_theta*Ynm0)*(exp_iphi_conj*exp_iphi_conj*pow<Real>(r,-n-2)) / (2*(2*n+1));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          KV[2][0] = -(2*imag*m*n*(n+2)*pow<Real>(r,-n-3)*csc_theta*Ynm0) / (4*n*n+8*n+3);
 | 
	
		
			
				|  |  | +          KW[2][0] =  (imag*m*pow<Real>(r,-n-3)*(2*n*n*n*(r*r-1) + n*n*(r*r-3) - 2*n*(r*r-1) - r*r)*csc_theta*Ynm0) / (4*n*n-1);
 | 
	
		
			
				|  |  | +          KX[2][0] =  (pow<Real>(r,-n-3)*(-m*(n+2)*r*cot_theta*Ynm0 - (n+2)*exp_iphi_conj*r*sqrt<Real>(-m*(m+1)+n*n+n)*Ynm1)) / (2*n+1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          KV[2][1] =  (2*imag*m*n*exp_iphi_conj*pow<Real>(r,-n-3)*csc_theta*(sqrt<Real>(-m*m-m+n*n+n)*Ynm1 + (m-1)*exp_iphi*cot_theta*Ynm0)) / (4*n*n+8*n+3);
 | 
	
		
			
				|  |  | +          KW[2][1] = -(imag*m*exp_iphi_conj*pow<Real>(r,-n-3)*(-2*n*n + (n-2)*(2*n+1)*r*r + n)*csc_theta)*(sqrt<Real>(-m*(m+1)+n*n+n)*Ynm1 + (m-1)*exp_iphi*cot_theta*Ynm0) / (4*n*n-1);
 | 
	
		
			
				|  |  | +          KX[2][1] =  (4*m*exp_iphi*sqrt<Real>(-m*(m+1)+n*n+n)*cot_theta*Ynm1 + 2*sqrt<Real>((m-n)*(m-n+1)*(m+n+1)*(m+n+2))*Ynm2 + (m-1)*m*exp_iphi*exp_iphi*(cos_2theta+3)*csc_theta*csc_theta*Ynm0)*(exp_iphi_conj*exp_iphi_conj*pow<Real>(r,-n-2)) / (2*(2*n+1));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          KV[2][2] =  (2*n*sqrt<Real>(-m*m-m+n*n+n)*cot_theta*Ynm1 - 2*n*exp_iphi*(m*m*csc_theta*csc_theta-m*cot_theta*cot_theta+n+1)*Ynm0)*(exp_iphi_conj*pow<Real>(r,-n-3)) / (4*n*n+8*n+3);
 | 
	
		
			
				|  |  | +          KW[2][2] =  (-sqrt<Real>(-m*(m+1)+n*n+n)*(-2*n*n + (n-2)*(2*n+1)*r*r + n)*cot_theta*Ynm1 + Ynm0*(m*exp_iphi*(-2*n*n + (n-2)*(2*n+1)*r*r + n)*((m-1)*csc_theta*csc_theta+1) - n*exp_iphi*(2*n*n + (n-2)*(2*n+1)*r*r + n - 1)))*(exp_iphi_conj*pow<Real>(r,-n-3)) / (4*n*n-1);
 | 
	
		
			
				|  |  | +          KX[2][2] =  (sqrt<Real>(-m*(m+1)+n*n+n)*Ynm1 + (m-1)*exp_iphi*cot_theta*Ynm0)*(2*imag*m*exp_iphi_conj*pow<Real>(r,-n-2)*csc_theta) / (2*n+1);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Complex<Real> SVr, SVt, SVp;
 | 
	
		
			
				|  |  | +        SVr = KV[0][0] * norm0[0] + KV[0][1] * norm0[1] + KV[0][2] * norm0[2];
 | 
	
		
			
				|  |  | +        SVt = KV[1][0] * norm0[0] + KV[1][1] * norm0[1] + KV[1][2] * norm0[2];
 | 
	
		
			
				|  |  | +        SVp = KV[2][0] * norm0[0] + KV[2][1] * norm0[1] + KV[2][2] * norm0[2];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Complex<Real> SWr, SWt, SWp;
 | 
	
		
			
				|  |  | +        SWr = KW[0][0] * norm0[0] + KW[0][1] * norm0[1] + KW[0][2] * norm0[2];
 | 
	
		
			
				|  |  | +        SWt = KW[1][0] * norm0[0] + KW[1][1] * norm0[1] + KW[1][2] * norm0[2];
 | 
	
		
			
				|  |  | +        SWp = KW[2][0] * norm0[0] + KW[2][1] * norm0[1] + KW[2][2] * norm0[2];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Complex<Real> SXr, SXt, SXp;
 | 
	
		
			
				|  |  | +        SXr = KX[0][0] * norm0[0] + KX[0][1] * norm0[1] + KX[0][2] * norm0[2];
 | 
	
		
			
				|  |  | +        SXt = KX[1][0] * norm0[0] + KX[1][1] * norm0[1] + KX[1][2] * norm0[2];
 | 
	
		
			
				|  |  | +        SXp = KX[2][0] * norm0[0] + KX[2][1] * norm0[1] + KX[2][2] * norm0[2];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        write_coeff(SVr, n, m, 0, 0);
 | 
	
		
			
				|  |  | +        write_coeff(SVt, n, m, 0, 1);
 | 
	
		
			
				|  |  | +        write_coeff(SVp, n, m, 0, 2);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        write_coeff(SWr, n, m, 1, 0);
 | 
	
		
			
				|  |  | +        write_coeff(SWt, n, m, 1, 1);
 | 
	
		
			
				|  |  | +        write_coeff(SWp, n, m, 1, 2);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        write_coeff(SXr, n, m, 2, 0);
 | 
	
		
			
				|  |  | +        write_coeff(SXt, n, m, 2, 1);
 | 
	
		
			
				|  |  | +        write_coeff(SXp, n, m, 2, 2);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  { // Set X <-- Q * StokesOp * B1
 | 
	
		
			
				|  |  | +    if (X.Dim() != N * dof * COORD_DIM) X.ReInit(N * dof * COORD_DIM);
 | 
	
		
			
				|  |  | +    for (Long k0 = 0; k0 < N; k0++) {
 | 
	
		
			
				|  |  | +      StaticArray<Real,9> Q;
 | 
	
		
			
				|  |  | +      { // Set Q
 | 
	
		
			
				|  |  | +        Real cos_theta = cos_theta_phi[k0 * 2 + 0];
 | 
	
		
			
				|  |  | +        Real sin_theta = sqrt<Real>(1 - cos_theta * cos_theta);
 | 
	
		
			
				|  |  | +        Real cos_phi = cos(cos_theta_phi[k0 * 2 + 1]);
 | 
	
		
			
				|  |  | +        Real sin_phi = sin(cos_theta_phi[k0 * 2 + 1]);
 | 
	
		
			
				|  |  | +        Q[0] = sin_theta*cos_phi; Q[1] = sin_theta*sin_phi; Q[2] = cos_theta;
 | 
	
		
			
				|  |  | +        Q[3] = cos_theta*cos_phi; Q[4] = cos_theta*sin_phi; Q[5] =-sin_theta;
 | 
	
		
			
				|  |  | +        Q[6] =          -sin_phi; Q[7] =           cos_phi; Q[8] =         0;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      for (Long k1 = 0; k1 < dof; k1++) { // Set X <-- Q * StokesOp * B1
 | 
	
		
			
				|  |  | +        StaticArray<Real,COORD_DIM> in;
 | 
	
		
			
				|  |  | +        for (Long j = 0; j < COORD_DIM; j++) {
 | 
	
		
			
				|  |  | +          in[j] = 0;
 | 
	
		
			
				|  |  | +          for (Long i = 0; i < COORD_DIM * M; i++) {
 | 
	
		
			
				|  |  | +            in[j] += B1[k1][i] * StokesOp[k0 * COORD_DIM + j][i];
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        X[(k0 * dof + k1) * COORD_DIM + 0] = Q[0] * in[0] + Q[3] * in[1] + Q[6] * in[2];
 | 
	
		
			
				|  |  | +        X[(k0 * dof + k1) * COORD_DIM + 1] = Q[1] * in[0] + Q[4] * in[1] + Q[7] * in[2];
 | 
	
		
			
				|  |  | +        X[(k0 * dof + k1) * COORD_DIM + 2] = Q[2] * in[0] + Q[5] * in[1] + Q[8] * in[2];
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 |