#include"Assemble_Base.h" #include"../function/BF.h" #include"../function/Gauss.h" #include"../common/define.h" #include "../parser/mpParser.h" #include"../Eigen/Sparse" #include"../Eigen/Dense" #include using namespace Eigen; void OpticsFEM_2D_Scatter::Assemble_SBC() { //physic double k0 = 2 * Pi / _mSolver->GetLda0(); //init of Gauss point Gauss gauss; int NbrGuassPoints; double* u, * v, * w, * wght; NbrGuassPoints = gauss.GetNbrGaussPoints(ONEDIM, LINE, BF_LINEFUNC * 2); u = new double[NbrGuassPoints]; v = new double[NbrGuassPoints]; w = new double[NbrGuassPoints]; wght = new double[NbrGuassPoints]; gauss.GetGaussPoints(ONEDIM, LINE, u, v, w, wght); //init of geo Vector3d* vertex = new Vector3d[5]; Matrix3d Jac, InvJac; Vector3d normal; //init of basis function BF BF_Lagrange, BF_Nedelec; Vector3d* Et, ** Ez; BF_Lagrange.GetNbrBF(TWODIM, TRIANGLE, BF_LAGRANGE, BF_LINEFUNC); BF_Nedelec.GetNbrBF(TWODIM, TRIANGLE, BF_NEDELEC, BF_LINEFUNC); Et = new Vector3d[NbrGuassPoints]; Ez = new Vector3d * [NbrGuassPoints]; for (int i = 0; i < NbrGuassPoints; i++) { Ez[i] = new Vector3d[2]; } //inite parser mup::ParserX p(mup::pckALL_COMPLEX); p.EnableAutoCreateVar(true); mup::Value xx, yy; p.DefineVar(_T("x"), mup::Variable(&xx)); p.DefineVar(_T("y"), mup::Variable(&yy)); Vector3cd* Einc; complex* EincPhi; Einc = new Vector3cd[NbrGuassPoints]; EincPhi = new complex[NbrGuassPoints]; //overloop of SBC int NbrSBC = _mPhy->GetNbrSBC(); for (int n = 0; n < NbrSBC; n++) { //SBC data int SBCDomain = _mPhy->GetSBCDomain(n) + 1; int SBCType = _mPhy->GetSBCType(n); string Eincx, Eincy, Eincz; Vector3d kdir; if (SBCType == 1) { _mPhy->GetSBDir(n, kdir); _mPhy->GetEinc(n, Eincx, Eincy, Eincz); } VectorXi edgesIndex; _mMesh->GetEdgesIndexOfDomain(SBCDomain, edgesIndex); //overloop of edgesOfSBC for (int m = 0; m < edgesIndex.rows(); m++) { //edge data Vector2i coonOfEdges; _mMesh->GetCoonOfEdges(edgesIndex(m), coonOfEdges); int numEle = coonOfEdges(0); int numEdge = coonOfEdges(1); //coordinate of vertex,integration coordinate, and mapping int MappingIndex[3]; int index[3]; for (int i = 0; i < 3; i++) _mMesh->GetVertex(_mMesh->GetTri(numEle, i), vertex[i]); if (numEdge == 0) { vertex[3] = vertex[0]; vertex[4] = vertex[1]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = 0.0; } index[0] = 1; index[1] = 2; index[2] = 1; MappingIndex[0] = _mMesh->GetTri(numEle, 0); MappingIndex[1] = _mMesh->GetTri(numEle, 1); MappingIndex[2] = _mMesh->GetEdgeOfTri(numEle, 0) + _mMesh->GetNbrVertex(); } else if (numEdge == 1) { vertex[3] = vertex[0]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = 0.0; w[i] = (u[i] + 1.0) / 2.0; } index[0] = 1; index[1] = 3; index[2] = 2; MappingIndex[0] = _mMesh->GetTri(numEle, 0); MappingIndex[1] = _mMesh->GetTri(numEle, 2); MappingIndex[2] = _mMesh->GetEdgeOfTri(numEle, 1) + _mMesh->GetNbrVertex(); } else if (numEdge == 2) { vertex[3] = vertex[0]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = (1.0 - u[i]) / 2.0; } index[0] = 2; index[1] = 3; index[2] = 3; MappingIndex[0] = _mMesh->GetTri(numEle, 1); MappingIndex[1] = _mMesh->GetTri(numEle, 2); MappingIndex[2] = _mMesh->GetEdgeOfTri(numEle, 2) + _mMesh->GetNbrVertex(); } //Jac Jac(0, 0) = vertex[1](0) - vertex[0](0); Jac(0, 1) = vertex[1](1) - vertex[0](1); Jac(0, 2) = 0.; Jac(1, 0) = vertex[2](0) - vertex[0](0); Jac(1, 1) = vertex[2](1) - vertex[0](1); Jac(1, 2) = 0.; Jac(2, 0) = 0.; Jac(2, 1) = 0.; Jac(2, 2) = 1.; InvJac = Jac.inverse(); //integration coe double phi1 = vertex[4](1) - vertex[3](1); double phi2 = vertex[3](0) - vertex[4](0); double integCoe = 0; if (vertex[3](0)!= vertex[4](0)) { integCoe = phi1 / phi2; integCoe = fabs(sqrtf(1 + integCoe * integCoe) * phi2 / 2.0); } else { integCoe = abs(phi1) / 2.0; } //normal _mMesh->GetNormOfEdges(_mMesh->GetDomainOfEdges(edgesIndex(m))-1, normal); //basis function for (int i = 0; i < NbrGuassPoints; i++) { for (int j = 0; j < 2; j++) { BF_Lagrange.GetValueBF(index[j], v[i], w[i], 0.0, Ez[i][j]); } BF_Nedelec.GetValueBF(index[2], v[i], w[i], 0.0, Et[i]); Et[i] = InvJac * Et[i]; } //material double n = _mMatLib->GetN(_mMesh->GetDomainOfTri(numEle)); complex phySBC(0, k0 * n); //submatrix MatrixXcd Be; Be = MatrixXcd::Zero(2, 2); complexAe; for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) for (int k = 0; k < NbrGuassPoints; k++) { Be(i, j) = Be(i, j) + wght[k] * integCoe * phySBC * (normal.cross(Ez[k][i])).dot(normal.cross(Ez[k][j])); } for (int k = 0; k < NbrGuassPoints; k++) { Ae = Ae + wght[k] * integCoe * phySBC * (normal.cross(Et[k])).dot(normal.cross(Et[k])); } //store in triple for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) { _mTripleA_complex.push_back(Triplet>(MappingIndex[i], MappingIndex[j], Be(i, j))); } _mTripleA_complex.push_back(Triplet>(MappingIndex[2], MappingIndex[2], Ae)); //inc if (SBCType == 1) { //Einc for (int i = 0; i < NbrGuassPoints; i++) { double tempX = Jac(0, 0) * v[i] + Jac(1, 0) * w[i] + vertex[0](0); double tempY = Jac(0, 1) * v[i] + Jac(1, 1) * w[i] + vertex[0](1); xx = Jac(0, 0) * v[i] + Jac(1, 0) * w[i] + vertex[0](0); yy = Jac(0, 1) * v[i] + Jac(1, 1) * w[i] + vertex[0](1); p.SetExpr(_T(Eincx)); Einc[i](0).real(p.Eval().GetFloat()); Einc[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(Eincy)); Einc[i](1).real(p.Eval().GetFloat()); Einc[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(Eincz)); Einc[i](2).real(p.Eval().GetFloat()); Einc[i](2).imag(p.Eval().GetImag()); complex phi(0, -k0 * n * (kdir(0) * tempX + kdir(1) * tempY)); EincPhi[i] = exp( phi); } //submatrix complex be[3]; for (int k = 0; k < NbrGuassPoints; k++) { be[0] = be[0] + wght[k] * integCoe * phySBC * /* EincPhi[k]* */ Ez[k][0].dot(normal.cross(Einc[k].cross(normal - kdir))); be[1] = be[1] + wght[k] * integCoe * phySBC * /* EincPhi[k]* */ Ez[k][1].dot(normal.cross(Einc[k].cross(normal - kdir))); be[2] = be[2] + wght[k] * integCoe * phySBC * /* EincPhi[k]* */Et[k].dot(normal.cross(Einc[k].cross(normal - kdir))); } //store in vector for (int i = 0; i < 3; i++) _mB_complex(MappingIndex[i]) = _mB_complex(MappingIndex[i]) + be[i]; } } } delete[] u, v, w, wght; delete[] vertex; for (int i = 0; i < NbrGuassPoints; i++) { delete[] Ez[i]; } delete[] Ez, Et, Einc, EincPhi; } void OpticsFEM_2D_Scatter::Assemble_BELE() { //physic double k0 = 2 * Pi / _mSolver->GetLda0(); //init of Gauss point Gauss gauss; int NbrGuassPoints; double* u, * v, * w, * wght; NbrGuassPoints = gauss.GetNbrGaussPoints(TWODIM, TRIANGLE, BF_LINEFUNC * 2); u = new double[NbrGuassPoints]; v = new double[NbrGuassPoints]; w = new double[NbrGuassPoints]; wght = new double[NbrGuassPoints]; gauss.GetGaussPoints(TWODIM, TRIANGLE, u, v, w, wght); //init of geo Vector3d* vertex = new Vector3d[5]; Matrix3d Jac, InvJac, TJac, JacS; //init of basis function BF BF_Lagrange, BF_Curl_Lagrange, BF_Nedelec, BF_Curl_Nedelec; int sdof, vdof; Vector3d** Et, ** curlEt, ** Ez, ** curlEz; /*Vector3d** bEt, ** bcurlEt, ** bEz, ** bcurlEz;*/ sdof = BF_Lagrange.GetNbrBF(TWODIM, TRIANGLE, BF_LAGRANGE, BF_LINEFUNC); BF_Curl_Lagrange.GetNbrBF(TWODIM, TRIANGLE, BF_CURL_LAGRANGE, BF_LINEFUNC); vdof = BF_Nedelec.GetNbrBF(TWODIM, TRIANGLE, BF_NEDELEC, BF_LINEFUNC); BF_Curl_Nedelec.GetNbrBF(TWODIM, TRIANGLE, BF_CURL_NEDELEC, BF_LINEFUNC); Et = new Vector3d * [NbrGuassPoints]; curlEt = new Vector3d * [NbrGuassPoints]; Ez = new Vector3d * [NbrGuassPoints]; curlEz = new Vector3d * [NbrGuassPoints]; for (int i = 0; i < NbrGuassPoints; i++) { Et[i] = new Vector3d[vdof]; curlEt[i] = new Vector3d[vdof]; Ez[i] = new Vector3d[sdof]; curlEz[i] = new Vector3d[sdof]; } //inite parser mup::ParserX p(mup::pckALL_COMPLEX); p.EnableAutoCreateVar(true); mup::Value xx, yy; p.DefineVar(_T("x"), mup::Variable(&xx)); p.DefineVar(_T("y"), mup::Variable(&yy)); Vector3cd* bEt, * bEz, * bcurlEt, * bcurlEz; bEt = new Vector3cd[NbrGuassPoints]; bEz = new Vector3cd[NbrGuassPoints]; bcurlEt = new Vector3cd[NbrGuassPoints]; bcurlEz = new Vector3cd[NbrGuassPoints]; string Ebx, Eby, Ebz; _mPhy->GetEb(Ebx, Eby, Ebz); string curlEbx, curlEby, curlEbz; _mPhy->GetCurlEb(curlEbx, curlEby, curlEbz); //loop over tri int NbrTri = _mMesh->GetNbrTri(); for (int n = 0; n < NbrTri; n++) { int domain = _mMesh->GetDomainOfTri(n); Eigen::VectorXi BELE; _mPhy->GetBELE(BELE); if (std::find(BELE.begin(), BELE.end(), domain) == BELE.end()) { continue; } //coordinate of vertex for (int i = 0; i < 3; i++) _mMesh->GetVertex(_mMesh->GetTri(n, i), vertex[i]); //Jac Jac(0, 0) = vertex[1](0) - vertex[0](0); Jac(0, 1) = vertex[1](1) - vertex[0](1); Jac(0, 2) = 0.; Jac(1, 0) = vertex[2](0) - vertex[0](0); Jac(1, 1) = vertex[2](1) - vertex[0](1); Jac(1, 2) = 0.; Jac(2, 0) = 0.; Jac(2, 1) = 0.; Jac(2, 2) = 1.; InvJac = Jac.inverse(); JacS(0, 0) = InvJac(1, 1); JacS(0, 1) = -InvJac(1, 0); JacS(0, 2) = 0.; JacS(1, 0) = -InvJac(0, 1); JacS(1, 1) = InvJac(0, 0); JacS(1, 2) = 0.; JacS(2, 0) = 0.; JacS(2, 1) = 0.; JacS(2, 2) = 1.; double DetJac = fabs(Jac.determinant()); TJac = Jac.transpose() / Jac.determinant(); //basis function for (int i = 0; i < NbrGuassPoints; i++) { for (int j = 0; j < sdof; j++) { BF_Lagrange.GetValueBF(j + 1, u[i], v[i], w[i], Ez[i][j]); BF_Curl_Lagrange.GetValueBF(j + 1, u[i], v[i], w[i], curlEz[i][j]); curlEz[i][j] = JacS * curlEz[i][j]; } for (int j = 0; j < vdof; j++) { BF_Nedelec.GetValueBF(j + 1, u[i], v[i], w[i], Et[i][j]); Et[i][j] = InvJac * Et[i][j]; BF_Curl_Nedelec.GetValueBF(j + 1, u[i], v[i], w[i], curlEt[i][j]); curlEt[i][j] = TJac * curlEt[i][j]; } } //background field for (int i = 0; i < NbrGuassPoints; i++) { xx = vertex[0][0] + Jac(0, 0) * u[i] + Jac(1, 0) * v[i]; yy = vertex[0][1] + Jac(0, 0) * u[i] + Jac(1, 1) * v[i]; p.SetExpr(_T(Ebx)); bEt[i](0).real(p.Eval().GetFloat()); bEt[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(Eby)); bEt[i](1).real(p.Eval().GetFloat()); bEt[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(Ebz)); bEz[i](2).real(p.Eval().GetFloat()); bEz[i](2).imag(p.Eval().GetImag()); p.SetExpr(_T(curlEbx)); bcurlEz[i](0).real(p.Eval().GetFloat()); bcurlEz[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(curlEby)); bcurlEz[i](1).real(p.Eval().GetFloat()); bcurlEz[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(curlEbz)); bcurlEt[i](2).real(p.Eval().GetFloat()); bcurlEt[i](2).imag(p.Eval().GetImag()); } //material Matrix3cd epsr = _mMatLib->GetEpsr(domain); Matrix3cd Mur = _mMatLib->GetMur(domain); Matrix3cd invMur; invMur = Mur.inverse(); //submatrix MatrixXcd St, Sz, Tt, Tz; St = MatrixXcd::Zero(vdof, vdof); Sz = MatrixXcd::Zero(sdof, sdof); Tt = MatrixXcd::Zero(vdof, vdof); Tz = MatrixXcd::Zero(sdof, sdof); for (int i = 0; i < sdof; i++) for (int k = 0; k < NbrGuassPoints; k++) { Sz(i, 0) = Sz(i, 0) + wght[k] * DetJac * curlEz[k][i].dot(invMur * bcurlEz[k]); Tz(i, 0) = Tz(i, 0) + wght[k] * DetJac * k0 * k0 * Ez[k][i].dot(epsr * bEz[k]); } for (int i = 0; i < vdof; i++) for (int k = 0; k < NbrGuassPoints; k++) { St(i, 0) = St(i, 0) + wght[k] * DetJac * curlEt[k][i].dot(invMur * bcurlEt[k]); Tt(i, 0) = Tt(i, 0) + wght[k] * DetJac * k0 * k0 * Et[k][i].dot(epsr * bEt[k]); } //Mapping VectorXi MappingIndexS = VectorXi::Zero(sdof); VectorXi MappingIndexV = VectorXi::Zero(vdof); for (int i = 0; i < 3; i++) { MappingIndexS(i) = _mMesh->GetTri(n, i); MappingIndexV(i) = _mMesh->GetEdgeOfTri(n, i) + _mMesh->GetNbrVertex(); _mB_complex(MappingIndexS[i]) = _mB_complex(MappingIndexS[i]) + Tz(i, 0) - Sz(i, 0); _mB_complex(MappingIndexV[i]) = _mB_complex(MappingIndexV[i]) + Tt(i, 0) - St(i, 0); } } //Line //init of Gauss point NbrGuassPoints = gauss.GetNbrGaussPoints(ONEDIM, LINE, BF_LINEFUNC * 4); u = new double[NbrGuassPoints]; v = new double[NbrGuassPoints]; w = new double[NbrGuassPoints]; wght = new double[NbrGuassPoints]; gauss.GetGaussPoints(ONEDIM, LINE, u, v, w, wght); Eigen::VectorXi BELE; _mPhy->GetBELE(BELE); int NbrBELE = BELE.rows(); //find PML index int NbrPML = _mPhy->GetNbrPML(); Eigen::VectorXi PMLEdge = Eigen::VectorXi::Zero(NbrPML); for (int i = 0; i < NbrPML; i++) PMLEdge(i) = _mPhy->GetPMLEdge(i) + 1; Eigen::VectorXi edgeIndexOfPML, edgeNumOfPML;//edges索引 对应ELE索引 _mMesh->GetIndexOfDomain2(PMLEdge, edgeIndexOfPML, edgeNumOfPML); //overloop of edgesOfBELE for (int m = 0; m < edgeNumOfPML.rows(); m++) { //edge data Vector2i coonOfEdges; _mMesh->GetCoonOfEdges(edgeIndexOfPML(m), coonOfEdges); int numEle = coonOfEdges(0); int numEdge = coonOfEdges(1); //coordinate of vertex,integration coordinate, and mapping int index[3]; for (int i = 0; i < 3; i++) _mMesh->GetVertex(_mMesh->GetTri(numEle, i), vertex[i]); if (numEdge == 0) { vertex[3] = vertex[0]; vertex[4] = vertex[1]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = 0.0; } } else if (numEdge == 1) { vertex[3] = vertex[0]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = 0.0; w[i] = (u[i] + 1.0) / 2.0; } } else if (numEdge == 2) { vertex[3] = vertex[1]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = (1.0 - u[i]) / 2.0; } } //Jac Jac(0, 0) = vertex[1](0) - vertex[0](0); Jac(0, 1) = vertex[1](1) - vertex[0](1); Jac(0, 2) = 0.; Jac(1, 0) = vertex[2](0) - vertex[0](0); Jac(1, 1) = vertex[2](1) - vertex[0](1); Jac(1, 2) = 0.; Jac(2, 0) = 0.; Jac(2, 1) = 0.; Jac(2, 2) = 1.; InvJac = Jac.inverse(); //integration coe double phi1 = vertex[4](1) - vertex[3](1); double phi2 = vertex[3](0) - vertex[4](0); double integCoe = 0; if (vertex[3](0) != vertex[4](0)) { integCoe = phi1 / phi2; integCoe = fabs(sqrtf(1 + integCoe * integCoe) * phi2 / 2.0); } else { integCoe = abs(phi1) / 2.0; } //normal Vector3d normal; int edge = _mMesh->GetDomainOfEdges(edgeNumOfPML(m)); _mMesh->GetNormOfEdges(_mMesh->GetDomainOfEdges(edgeNumOfPML(m)) - 1, normal); if (normal.isZero()) { normal[0] = (vertex[3](0) + vertex[4](0)) / 2 - normal[0]; normal[1] = (vertex[3](1) + vertex[4](1)) / 2 - normal[1]; normal[2] = 0; normal.normalize(); } //basis function for (int i = 0; i < NbrGuassPoints; i++) { for (int j = 0; j < sdof; j++) { BF_Lagrange.GetValueBF(j + 1, v[i], w[i], 0.0, Ez[i][j]); } for (int j = 0; j < vdof; j++) { BF_Nedelec.GetValueBF(j + 1, v[i], w[i], 0.0, Et[i][j]); Et[i][j] = InvJac * Et[i][j]; } } //back ground field for (int i = 0; i < NbrGuassPoints; i++) { xx = vertex[0][0] + Jac(0, 0) * v[i] + Jac(1, 0) * w[i]; yy = vertex[0][1] + Jac(0, 0) * v[i] + Jac(1, 1) * w[i]; p.SetExpr(_T(curlEbx)); bcurlEz[i](0).real(p.Eval().GetFloat()); bcurlEz[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(curlEby)); bcurlEz[i](1).real(p.Eval().GetFloat()); bcurlEz[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(curlEbz)); bcurlEt[i](2).real(p.Eval().GetFloat()); bcurlEt[i](2).imag(p.Eval().GetImag()); } //submatrix MatrixXcd bz, bt; bz = MatrixXcd::Zero(3, 1); bt = MatrixXcd::Zero(3, 1); for (int i = 0; i < 3; i++) { for (int j = 0; j < NbrGuassPoints; j++) { bz(i) = bz(i) - wght[j] * integCoe * Ez[j][i].dot(normal.cross(bcurlEz[j])); bt(i) = bt(i) - wght[j] * integCoe * Et[j][i].dot(normal.cross(bcurlEt[j])); } } //Mapping VectorXi MappingIndexS = VectorXi::Zero(sdof); VectorXi MappingIndexV = VectorXi::Zero(vdof); for (int i = 0; i < 3; i++) { MappingIndexS(i) = _mMesh->GetTri(numEle, i); MappingIndexV(i) = _mMesh->GetEdgeOfTri(numEle, i) + _mMesh->GetNbrVertex(); _mB_complex(MappingIndexS[i]) = _mB_complex(MappingIndexS[i]) + bz(i); _mB_complex(MappingIndexV[i]) = _mB_complex(MappingIndexV[i]) + bt(i); } } delete[] u, v, w, wght; delete[] vertex; for (int i = 0; i < NbrGuassPoints; i++) { delete[] Et[i], curlEt[i], Ez[i], curlEz[i]; } delete[] Et, curlEt, Ez, curlEz, bEt, bcurlEt, bEz, bcurlEz; } void OpticsFEM_2D_Scatter::Assemble_MAG() { //physic double k0 = 2 * Pi / _mSolver->GetLda0(); //Line //init of Gauss point Gauss gauss; int NbrGuassPoints; double* u, * v, * w, * wght; NbrGuassPoints = gauss.GetNbrGaussPoints(ONEDIM, LINE, BF_LINEFUNC * 4); u = new double[NbrGuassPoints]; v = new double[NbrGuassPoints]; w = new double[NbrGuassPoints]; wght = new double[NbrGuassPoints]; gauss.GetGaussPoints(ONEDIM, LINE, u, v, w, wght); //init of basis function Vector3d* vertex = new Vector3d[5]; Matrix3d Jac, InvJac, TJac, JacS; //init of basis function BF BF_Lagrange, BF_Curl_Lagrange, BF_Nedelec, BF_Curl_Nedelec; Vector3d** Et, ** Ez; int sdof, vdof; Et = new Vector3d * [NbrGuassPoints]; Ez = new Vector3d * [NbrGuassPoints]; sdof = BF_Lagrange.GetNbrBF(TWODIM, TRIANGLE, BF_LAGRANGE, BF_LINEFUNC); vdof = BF_Nedelec.GetNbrBF(TWODIM, TRIANGLE, BF_NEDELEC, BF_LINEFUNC); for (int i = 0; i < NbrGuassPoints; i++) { Et[i] = new Vector3d[vdof]; Ez[i] = new Vector3d[sdof]; } //inite parser mup::ParserX p(mup::pckALL_COMPLEX); p.EnableAutoCreateVar(true); mup::Value xx, yy; p.DefineVar(_T("x"), mup::Variable(&xx)); p.DefineVar(_T("y"), mup::Variable(&yy)); Vector3cd * bcurlEt, * bcurlEz; bcurlEt = new Vector3cd[NbrGuassPoints]; bcurlEz = new Vector3cd[NbrGuassPoints]; //find MAG index int NbrMAG = _mPhy->GetNbrMAG(); string H0x, H0y, H0z; Eigen::VectorXi MAGDomain = Eigen::VectorXi::Zero(1); for (int n = 0; n < NbrMAG; n++) { _mPhy->GetH0(H0x, H0y, H0z, n); MAGDomain(0) = _mPhy->GetMAGDomain(n) + 1; Eigen::VectorXi edgeIndexOfMAG, edgeNumOfMAG;//edges索引 对应MAG索引 _mMesh->GetIndexOfDomain2(MAGDomain, edgeIndexOfMAG, edgeNumOfMAG); //overloop of edgesOfMAG for (int m = 0; m < edgeNumOfMAG.rows(); m++) { //edge data Vector2i coonOfEdges; _mMesh->GetCoonOfEdges(edgeIndexOfMAG(m), coonOfEdges); int numEle = coonOfEdges(0); int numEdge = coonOfEdges(1); //coordinate of vertex,integration coordinate, and mapping int index[3]; for (int i = 0; i < 3; i++) _mMesh->GetVertex(_mMesh->GetTri(numEle, i), vertex[i]); if (numEdge == 0) { vertex[3] = vertex[0]; vertex[4] = vertex[1]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = 0.0; } } else if (numEdge == 1) { vertex[3] = vertex[0]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = 0.0; w[i] = (u[i] + 1.0) / 2.0; } } else if (numEdge == 2) { vertex[3] = vertex[1]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = (1.0 - u[i]) / 2.0; } } //Jac Jac(0, 0) = vertex[1](0) - vertex[0](0); Jac(0, 1) = vertex[1](1) - vertex[0](1); Jac(0, 2) = 0.; Jac(1, 0) = vertex[2](0) - vertex[0](0); Jac(1, 1) = vertex[2](1) - vertex[0](1); Jac(1, 2) = 0.; Jac(2, 0) = 0.; Jac(2, 1) = 0.; Jac(2, 2) = 1.; InvJac = Jac.inverse(); //integration coe double phi1 = vertex[4](1) - vertex[3](1); double phi2 = vertex[3](0) - vertex[4](0); double integCoe = 0; if (vertex[3](0) != vertex[4](0)) { integCoe = phi1 / phi2; integCoe = fabs(sqrtf(1 + integCoe * integCoe) * phi2 / 2.0); } else { integCoe = abs(phi1) / 2.0; } //normal Vector3d normal; int edge = _mMesh->GetDomainOfEdges(edgeNumOfMAG(m)); _mMesh->GetNormOfEdges(_mMesh->GetDomainOfEdges(edgeNumOfMAG(m)) - 1, normal); if (normal.isZero()) { normal[0] = (vertex[3](0) + vertex[4](0)) / 2 - normal[0]; normal[1] = (vertex[3](1) + vertex[4](1)) / 2 - normal[1]; normal[2] = 0; normal.normalize(); } //basis function for (int i = 0; i < NbrGuassPoints; i++) { for (int j = 0; j < sdof; j++) { BF_Lagrange.GetValueBF(j + 1, v[i], w[i], 0.0, Ez[i][j]); } for (int j = 0; j < vdof; j++) { BF_Nedelec.GetValueBF(j + 1, v[i], w[i], 0.0, Et[i][j]); Et[i][j] = InvJac * Et[i][j]; } } //back ground field for (int i = 0; i < NbrGuassPoints; i++) { xx = vertex[0][0] + Jac(0, 0) * v[i] + Jac(1, 0) * w[i]; yy = vertex[0][1] + Jac(0, 1) * v[i] + Jac(1, 1) * w[i]; p.SetExpr(_T(H0x)); bcurlEz[i](0).real(p.Eval().GetFloat()); bcurlEz[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(H0y)); bcurlEz[i](1).real(p.Eval().GetFloat()); bcurlEz[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(H0z)); bcurlEt[i](2).real(p.Eval().GetFloat()); bcurlEt[i](2).imag(p.Eval().GetImag()); } //submatrix MatrixXcd bz, bt; bz = MatrixXcd::Zero(3, 1); bt = MatrixXcd::Zero(3, 1); for (int i = 0; i < 3; i++) { for (int j = 0; j < NbrGuassPoints; j++) { bz(i) = bz(i) - complex(0.0, 1.0) * k0 * wght[j] * integCoe * Ez[j][i].dot(normal.cross(bcurlEz[j])); bt(i) = bt(i) - complex(0.0, 1.0) * k0 * wght[j] * integCoe * Et[j][i].dot(normal.cross(bcurlEt[j])); } } //Mapping VectorXi MappingIndexS = VectorXi::Zero(sdof); VectorXi MappingIndexV = VectorXi::Zero(vdof); for (int i = 0; i < 3; i++) { MappingIndexS(i) = _mMesh->GetTri(numEle, i); MappingIndexV(i) = _mMesh->GetEdgeOfTri(numEle, i) + _mMesh->GetNbrVertex(); _mB_complex(MappingIndexS[i]) = _mB_complex(MappingIndexS[i]) + bz(i); _mB_complex(MappingIndexV[i]) = _mB_complex(MappingIndexV[i]) + bt(i); } } } delete[] u, v, w, wght; delete[] vertex; for (int i = 0; i < NbrGuassPoints; i++) { delete[] Et[i], Ez[i]; } delete[] Et, Ez, bcurlEt, bcurlEz; } void OpticsFEM_2D_Scatter::Assemble_SCD() { //physic double k0 = 2 * Pi / _mSolver->GetLda0(); //Line //init of Gauss point Gauss gauss; int NbrGuassPoints; double* u, * v, * w, * wght; NbrGuassPoints = gauss.GetNbrGaussPoints(ONEDIM, LINE, BF_LINEFUNC * 4); u = new double[NbrGuassPoints]; v = new double[NbrGuassPoints]; w = new double[NbrGuassPoints]; wght = new double[NbrGuassPoints]; gauss.GetGaussPoints(ONEDIM, LINE, u, v, w, wght); //init of basis function Vector3d* vertex = new Vector3d[5]; Matrix3d Jac, InvJac, TJac, JacS; //init of basis function BF BF_Lagrange, BF_Curl_Lagrange, BF_Nedelec, BF_Curl_Nedelec; Vector3d** Et, ** Ez; int sdof, vdof; Et = new Vector3d * [NbrGuassPoints]; Ez = new Vector3d * [NbrGuassPoints]; sdof = BF_Lagrange.GetNbrBF(TWODIM, TRIANGLE, BF_LAGRANGE, BF_LINEFUNC); vdof = BF_Nedelec.GetNbrBF(TWODIM, TRIANGLE, BF_NEDELEC, BF_LINEFUNC); for (int i = 0; i < NbrGuassPoints; i++) { Et[i] = new Vector3d[vdof]; Ez[i] = new Vector3d[sdof]; } //inite parser mup::ParserX p(mup::pckALL_COMPLEX); p.EnableAutoCreateVar(true); mup::Value xx, yy; p.DefineVar(_T("x"), mup::Variable(&xx)); p.DefineVar(_T("y"), mup::Variable(&yy)); Vector3cd* bEt, * bEz; bEt = new Vector3cd[NbrGuassPoints]; bEz = new Vector3cd[NbrGuassPoints]; //find SCD index int NbrSCD = _mPhy->GetNbrSCD(); string J0x, J0y, J0z; Eigen::VectorXi SCDDomain = Eigen::VectorXi::Zero(1); for (int n = 0; n < NbrSCD; n++) { _mPhy->GetJ0(J0x, J0y, J0z, n); SCDDomain(0) = _mPhy->GetSCDDomain(n) + 1; Eigen::VectorXi edgeIndexOfSCD, edgeNumOfSCD;//edges索引 对应SCD索引 _mMesh->GetIndexOfDomain2(SCDDomain, edgeIndexOfSCD, edgeNumOfSCD); //overloop of edgesOfSCD for (int m = 0; m < edgeNumOfSCD.rows(); m++) { //edge data Vector2i coonOfEdges; _mMesh->GetCoonOfEdges(edgeIndexOfSCD(m), coonOfEdges); int numEle = coonOfEdges(0); int numEdge = coonOfEdges(1); int index[3]; for (int i = 0; i < 3; i++) _mMesh->GetVertex(_mMesh->GetTri(numEle, i), vertex[i]); if (numEdge == 0) { vertex[3] = vertex[0]; vertex[4] = vertex[1]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = 0.0; } } else if (numEdge == 1) { vertex[3] = vertex[0]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = 0.0; w[i] = (u[i] + 1.0) / 2.0; } } else if (numEdge == 2) { vertex[3] = vertex[1]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = (1.0 - u[i]) / 2.0; } } //Jac Jac(0, 0) = vertex[1](0) - vertex[0](0); Jac(0, 1) = vertex[1](1) - vertex[0](1); Jac(0, 2) = 0.; Jac(1, 0) = vertex[2](0) - vertex[0](0); Jac(1, 1) = vertex[2](1) - vertex[0](1); Jac(1, 2) = 0.; Jac(2, 0) = 0.; Jac(2, 1) = 0.; Jac(2, 2) = 1.; InvJac = Jac.inverse(); //integration coe double phi1 = vertex[4](1) - vertex[3](1); double phi2 = vertex[3](0) - vertex[4](0); double integCoe = 0; if (vertex[3](0) != vertex[4](0)) { integCoe = phi1 / phi2; integCoe = fabs(sqrtf(1 + integCoe * integCoe) * phi2 / 2.0); } else { integCoe = abs(phi1) / 2.0; } //basis function for (int i = 0; i < NbrGuassPoints; i++) { for (int j = 0; j < sdof; j++) { BF_Lagrange.GetValueBF(j + 1, v[i], w[i], 0.0, Ez[i][j]); } for (int j = 0; j < vdof; j++) { BF_Nedelec.GetValueBF(j + 1, v[i], w[i], 0.0, Et[i][j]); Et[i][j] = InvJac * Et[i][j]; } } //back ground field for (int i = 0; i < NbrGuassPoints; i++) { xx = vertex[0][0] + Jac(0, 0) * v[i] + Jac(1, 0) * w[i]; yy = vertex[0][1] + Jac(0, 1) * v[i] + Jac(1, 1) * w[i]; p.SetExpr(_T(J0x)); bEt[i](0).real(p.Eval().GetFloat()); bEt[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(J0y)); bEt[i](1).real(p.Eval().GetFloat()); bEt[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(J0z)); bEz[i](2).real(p.Eval().GetFloat()); bEz[i](2).imag(p.Eval().GetImag()); } //submatrix MatrixXcd bz, bt; bz = MatrixXcd::Zero(3, 1); bt = MatrixXcd::Zero(3, 1); for (int i = 0; i < 3; i++) { for (int j = 0; j < NbrGuassPoints; j++) { bz(i) = bz(i) - complex(0.0, 1.0) * sqrt(mu0 / epsilon0) * k0 * wght[j] * integCoe * Ez[j][i].dot(bEz[j]); bt(i) = bt(i) - complex(0.0, 1.0) * sqrt(mu0 / epsilon0) * k0 * wght[j] * integCoe * Et[j][i].dot(bEt[j]); } } //Mapping VectorXi MappingIndexS = VectorXi::Zero(sdof); VectorXi MappingIndexV = VectorXi::Zero(vdof); for (int i = 0; i < 3; i++) { MappingIndexS(i) = _mMesh->GetTri(numEle, i); MappingIndexV(i) = _mMesh->GetEdgeOfTri(numEle, i) + _mMesh->GetNbrVertex(); _mB_complex(MappingIndexS[i]) = _mB_complex(MappingIndexS[i]) + bz(i); _mB_complex(MappingIndexV[i]) = _mB_complex(MappingIndexV[i]) + bt(i); } } } delete[] u, v, w, wght; delete[] vertex; for (int i = 0; i < NbrGuassPoints; i++) { delete[] Et[i], Ez[i]; } delete[] Et, Ez, bEt, bEz; } void OpticsFEM_2D_Scatter::Assemble_MPD() { //physic double k0 = 2 * Pi / _mSolver->GetLda0(); Eigen::MatrixXd m; Eigen::VectorXi MPD; _mPhy->GetMPD(MPD); _mPhy->GetMPDData(m); //init of Gauss point Gauss gauss; int NbrGuassPoints; double* u, * v, * w, * wght; NbrGuassPoints = gauss.GetNbrGaussPoints(TWODIM, TRIANGLE, BF_LINEFUNC * 4); u = new double[NbrGuassPoints]; v = new double[NbrGuassPoints]; w = new double[NbrGuassPoints]; wght = new double[NbrGuassPoints]; gauss.GetGaussPoints(TWODIM, TRIANGLE, u, v, w, wght); //init of geo Vector3d* vertex = new Vector3d[3]; Matrix3d Jac, InvJac, TJac, JacS; double xx, yy; Vector3cd* bEt, * bEz; bEt = new Vector3cd[NbrGuassPoints]; bEz = new Vector3cd[NbrGuassPoints]; //init of basis function BF BF_Lagrange, BF_Curl_Lagrange, BF_Nedelec, BF_Curl_Nedelec; int sdof, vdof; Vector3d** curlEt, ** curlEz; sdof = BF_Lagrange.GetNbrBF(TWODIM, TRIANGLE, BF_LAGRANGE, BF_LINEFUNC); BF_Curl_Lagrange.GetNbrBF(TWODIM, TRIANGLE, BF_CURL_LAGRANGE, BF_LINEFUNC); vdof = BF_Nedelec.GetNbrBF(TWODIM, TRIANGLE, BF_NEDELEC, BF_LINEFUNC); BF_Curl_Nedelec.GetNbrBF(TWODIM, TRIANGLE, BF_CURL_NEDELEC, BF_LINEFUNC); curlEt = new Vector3d * [NbrGuassPoints]; curlEz = new Vector3d * [NbrGuassPoints]; for (int i = 0; i < NbrGuassPoints; i++) { curlEt[i] = new Vector3d[vdof]; curlEz[i] = new Vector3d[sdof]; } //loop over tri int NbrTri = _mMesh->GetNbrTri(); int NbrMPD = MPD.size(); int num = 0; for (int i = 0; i < NbrMPD; i++) { for (int n = 0; n < NbrTri; n++) { bool found = false; for (int j = 0; j < 3; j++) { if (MPD[i] == _mMesh->GetTri(n, j)) { found = true; break; } } if (found) { //coordinate of vertex num = num + 1; for (int j = 0; j < 3; j++) _mMesh->GetVertex(_mMesh->GetTri(n, j), vertex[j]); //Jac Jac(0, 0) = vertex[1](0) - vertex[0](0); Jac(0, 1) = vertex[1](1) - vertex[0](1); Jac(0, 2) = 0.; Jac(1, 0) = vertex[2](0) - vertex[0](0); Jac(1, 1) = vertex[2](1) - vertex[0](1); Jac(1, 2) = 0.; Jac(2, 0) = 0.; Jac(2, 1) = 0.; Jac(2, 2) = 1.; InvJac = Jac.inverse(); JacS(0, 0) = InvJac(1, 1); JacS(0, 1) = -InvJac(1, 0); JacS(0, 2) = 0.; JacS(1, 0) = -InvJac(0, 1); JacS(1, 1) = InvJac(0, 0); JacS(1, 2) = 0.; JacS(2, 0) = 0.; JacS(2, 1) = 0.; JacS(2, 2) = 1.; double DetJac = fabs(Jac.determinant()); TJac = Jac.transpose() / Jac.determinant(); //basis function for (int j = 0; j < NbrGuassPoints; j++) { for (int k = 0; k < sdof; k++) { BF_Curl_Lagrange.GetValueBF(k + 1, u[j], v[j], w[j], curlEz[j][k]); curlEz[j][k] = JacS * curlEz[j][k]; } for (int k = 0; k < vdof; k++) { BF_Curl_Nedelec.GetValueBF(k + 1, u[j], v[j], w[j], curlEt[j][k]); curlEt[j][k] = TJac * curlEt[j][k]; } } //submatrix Eigen::Vector3d m_current = m.row(i); MatrixXcd Tt, Tz; Tt = MatrixXcd::Zero(vdof, 1); Tz = MatrixXcd::Zero(sdof, 1); for (int j = 0; j < sdof; j++) for (int k = 0; k < NbrGuassPoints; k++) { Tz(j) = Tz(j) + complex(0.0, -1.0) * sqrt(mu0 / epsilon0) * k0 * wght[k] * DetJac * curlEz[k][j].dot(m_current); } for (int j = 0; j < vdof; j++) for (int k = 0; k < NbrGuassPoints; k++) { Tt(j) = Tt(j) + complex(0.0, -1.0) * sqrt(mu0 / epsilon0) * k0 * wght[k] * DetJac * curlEt[k][j].dot(m_current); } //Mapping VectorXi MappingIndexS = VectorXi::Zero(sdof); VectorXi MappingIndexV = VectorXi::Zero(vdof); for (int j = 0; j < 3; j++) { MappingIndexS(j) = _mMesh->GetTri(n, j); MappingIndexV(j) = _mMesh->GetEdgeOfTri(n, j) + _mMesh->GetNbrVertex(); _mB_complex(MappingIndexS[j]) = _mB_complex(MappingIndexS[j]) + Tz(j); _mB_complex(MappingIndexV[j]) = _mB_complex(MappingIndexV[j]) + Tt(j); } } } } delete[] u, v, w, wght; delete[] vertex; for (int i = 0; i < NbrGuassPoints; i++) { delete[] curlEt[i], curlEz[i]; } delete[] bEt, bEz; } void OpticsFEM_2D_Scatter::Assemble_EPD() { //physic double k0 = 2 * Pi / _mSolver->GetLda0(); Eigen::MatrixXd p; Eigen::VectorXi EPD; _mPhy->GetEPD(EPD); _mPhy->GetEPDData(p); //init of Gauss point Gauss gauss; int NbrGuassPoints; double* u, * v, * w, * wght; NbrGuassPoints = gauss.GetNbrGaussPoints(TWODIM, TRIANGLE, BF_LINEFUNC * 4); u = new double[NbrGuassPoints]; v = new double[NbrGuassPoints]; w = new double[NbrGuassPoints]; wght = new double[NbrGuassPoints]; gauss.GetGaussPoints(TWODIM, TRIANGLE, u, v, w, wght); //init of geo Vector3d* vertex = new Vector3d[3]; Matrix3d Jac, InvJac, TJac, JacS; double xx, yy; Vector3cd* bEt, * bEz; bEt = new Vector3cd[NbrGuassPoints]; bEz = new Vector3cd[NbrGuassPoints]; //init of basis function BF BF_Lagrange, BF_Curl_Lagrange, BF_Nedelec, BF_Curl_Nedelec; int sdof, vdof; Vector3d** Et, ** Ez; sdof = BF_Lagrange.GetNbrBF(TWODIM, TRIANGLE, BF_LAGRANGE, BF_LINEFUNC); BF_Curl_Lagrange.GetNbrBF(TWODIM, TRIANGLE, BF_CURL_LAGRANGE, BF_LINEFUNC); vdof = BF_Nedelec.GetNbrBF(TWODIM, TRIANGLE, BF_NEDELEC, BF_LINEFUNC); BF_Curl_Nedelec.GetNbrBF(TWODIM, TRIANGLE, BF_CURL_NEDELEC, BF_LINEFUNC); Et = new Vector3d * [NbrGuassPoints]; Ez = new Vector3d * [NbrGuassPoints]; for (int i = 0; i < NbrGuassPoints; i++) { Et[i] = new Vector3d[vdof]; Ez[i] = new Vector3d[sdof]; } //loop over tri int NbrTri = _mMesh->GetNbrTri(); int NbrEPD = EPD.size(); int num = 0; for (int i = 0; i < NbrEPD; i++) { for (int n = 0; n < NbrTri; n++) { bool found = false; for (int j = 0; j < 3; j++) { if (EPD[i] == _mMesh->GetTri(n, j)) { found = true; break; } } if (found) { //coordinate of vertex num = num + 1; for (int j = 0; j < 3; j++) _mMesh->GetVertex(_mMesh->GetTri(n, j), vertex[j]); //Jac Jac(0, 0) = vertex[1](0) - vertex[0](0); Jac(0, 1) = vertex[1](1) - vertex[0](1); Jac(0, 2) = 0.; Jac(1, 0) = vertex[2](0) - vertex[0](0); Jac(1, 1) = vertex[2](1) - vertex[0](1); Jac(1, 2) = 0.; Jac(2, 0) = 0.; Jac(2, 1) = 0.; Jac(2, 2) = 1.; InvJac = Jac.inverse(); JacS(0, 0) = InvJac(1, 1); JacS(0, 1) = -InvJac(1, 0); JacS(0, 2) = 0.; JacS(1, 0) = -InvJac(0, 1); JacS(1, 1) = InvJac(0, 0); JacS(1, 2) = 0.; JacS(2, 0) = 0.; JacS(2, 1) = 0.; JacS(2, 2) = 1.; double DetJac = fabs(Jac.determinant()); TJac = Jac.transpose() / Jac.determinant(); //basis function for (int j = 0; j < NbrGuassPoints; j++) { for (int k = 0; k < sdof; k++) { BF_Lagrange.GetValueBF(k + 1, u[j], v[j], w[j], Ez[j][k]); } for (int k = 0; k < vdof; k++) { BF_Nedelec.GetValueBF(k + 1, u[j], v[j], w[j], Et[j][k]); Et[j][k] = InvJac * Et[j][k]; } } //submatrix Eigen::Vector3d p_current = p.row(i); MatrixXcd Tt, Tz; Tt = MatrixXcd::Zero(vdof, 1); Tz = MatrixXcd::Zero(sdof, 1); for (int j = 0; j < sdof; j++) for (int k = 0; k < NbrGuassPoints; k++) { Tz(j) = Tz(j) + complex(0.0, -1.0) * sqrt(mu0/epsilon0) * k0 * wght[k] * DetJac * Ez[k][j].dot(p_current); } for (int j = 0; j < vdof; j++) for (int k = 0; k < NbrGuassPoints; k++) { Tt(j) = Tt(j) + complex(0.0, -1.0) * sqrt(mu0 / epsilon0) * k0 * wght[k] * DetJac * Et[k][j].dot(p_current); } //Mapping VectorXi MappingIndexS = VectorXi::Zero(sdof); VectorXi MappingIndexV = VectorXi::Zero(vdof); for (int j = 0; j < 3; j++) { MappingIndexS(j) = _mMesh->GetTri(n, j); MappingIndexV(j) = _mMesh->GetEdgeOfTri(n, j) + _mMesh->GetNbrVertex(); _mB_complex(MappingIndexS[j]) = _mB_complex(MappingIndexS[j]) + Tz(j); _mB_complex(MappingIndexV[j]) = _mB_complex(MappingIndexV[j]) + Tt(j); } } } } delete[] u, v, w, wght; delete[] vertex; for (int i = 0; i < NbrGuassPoints; i++) { delete[] Et[i], Ez[i]; } delete[] bEt, bEz; } void OpticsFEM_2D_Scatter::Assemble_PEC_ELE() { //find PEC index int NbrPEC = _mPhy->GetNbrPEC(); Eigen::VectorXi PECDomain = Eigen::VectorXi::Zero(NbrPEC); for (int i = 0; i < NbrPEC; i++) PECDomain(i) = _mPhy->GetPECDomain(i) + 1; Eigen::VectorXi nodeIndexOfPEC, edgeIndexOfPEC; _mMesh->GetIndexOfDomain(PECDomain, nodeIndexOfPEC, edgeIndexOfPEC); //find ELE index int NbrELE = _mPhy->GetNbrElE(); Eigen::VectorXi ELEDomain = Eigen::VectorXi::Zero(NbrELE); for (int i = 0; i < NbrELE; i++) ELEDomain(i) = _mPhy->GetELEDomain(i) + 1; Eigen::VectorXi edgeIndexOfELE, edgeNumOfELE;//edges索引 对应ELE索引 _mMesh->GetIndexOfDomain2(ELEDomain, edgeIndexOfELE, edgeNumOfELE); //init BCIndex BCValue int NbrBC = edgeIndexOfPEC.rows() + nodeIndexOfPEC.rows() + edgeNumOfELE.rows() * 3; //两边+一顶点 Eigen::VectorXi BCIndex = Eigen::VectorXi::Zero(NbrBC);// 1:3 ELE 4:6 PEC Eigen::VectorXcd BCValue = Eigen::VectorXcd::Zero(NbrBC); //init of geo Vector3d* vertex = new Vector3d[5]; //inite parser mup::ParserX p(mup::pckALL_COMPLEX); p.EnableAutoCreateVar(true); mup::Value xx, yy, zz; p.DefineVar(_T("x"), mup::Variable(&xx)); p.DefineVar(_T("y"), mup::Variable(&yy)); p.DefineVar(_T("z"), mup::Variable(&zz)); Vector3cd E0; //overloop edge of ELE int bcOffset = 0; int NbrVertex = _mMesh->GetNbrVertex(); for (int m = 0; m < NbrELE; m++) { Eigen::VectorXi ELEDomain = Eigen::VectorXi::Zero(NbrELE); ELEDomain(0) = _mPhy->GetELEDomain(m) + 1; Eigen::VectorXi edgeIndexOfELE, currentEdgeNum;//edges索引 对应ELE索引 _mMesh->GetIndexOfDomain2(ELEDomain, edgeIndexOfELE, currentEdgeNum); string E0x, E0y, E0z; _mPhy->GetE0(E0x, E0y, E0z,m); for (int n = 0; n GetCoonOfEdges(edgeIndexOfELE(n), coonOfEdges); int numEle = coonOfEdges(0); int numEdge = coonOfEdges(1); for (int i = 0; i < 3; i++) _mMesh->GetVertex(_mMesh->GetTri(numEle, i), vertex[i]); Eigen::Vector3d ee = Eigen::Vector3d::Zero(); if (numEdge == 0) { vertex[3] = vertex[0]; vertex[4] = vertex[1]; ee(0) = vertex[1](0) - vertex[0](0); ee(1) = vertex[1](1) - vertex[0](1); BCIndex(n + bcOffset)= _mMesh->GetTri(numEle, 0); BCIndex(n + bcOffset + edgeNumOfELE.rows()) = _mMesh->GetTri(numEle, 1); BCIndex(n + bcOffset + edgeNumOfELE.rows() * 2) = _mMesh->GetEdgeOfTri(numEle, 0) + NbrVertex; } else if (numEdge == 1) { vertex[3] = vertex[0]; vertex[4] = vertex[2]; ee(0) = vertex[2](0) - vertex[0](0); ee(1) = vertex[2](1) - vertex[0](1); BCIndex(n + bcOffset) = _mMesh->GetTri(numEle, 0); BCIndex(n + bcOffset + edgeNumOfELE.rows()) = _mMesh->GetTri(numEle, 2); BCIndex(n + bcOffset + edgeNumOfELE.rows() * 2) = _mMesh->GetEdgeOfTri(numEle, 1) + NbrVertex; } else if (numEdge == 2) { vertex[3] = vertex[1]; vertex[4] = vertex[2]; ee(0) = vertex[2](0) - vertex[1](0); ee(1) = vertex[2](1) - vertex[1](1); BCIndex(n + bcOffset) = _mMesh->GetTri(numEle, 1); BCIndex(n + bcOffset + edgeNumOfELE.rows()) = _mMesh->GetTri(numEle, 2); BCIndex(n + bcOffset + edgeNumOfELE.rows() * 2) = _mMesh->GetEdgeOfTri(numEle, 2) + NbrVertex; } xx = (vertex[3](0) + vertex[4](0)) / 2; yy = (vertex[3](1) + vertex[4](1)) / 2; if (_mPhy->GetNbrBELE()) { string Ebx, Eby, Ebz; string ExFunc, EyFunc, EzFunc; _mPhy->GetEb(Ebx, Eby, Ebz); ExFunc = E0x + "-" + Ebx; EyFunc = E0y + "-" + Eby; EzFunc = E0z + "-" + Ebz; p.SetExpr(_T(ExFunc)); E0(0).real(p.Eval().GetFloat()); E0(0).imag(p.Eval().GetImag()); p.SetExpr(_T(EyFunc)); E0(1).real(p.Eval().GetFloat()); E0(1).imag(p.Eval().GetImag()); xx = vertex[3](0); yy = vertex[4](0); p.SetExpr(_T(EzFunc)); E0(2).real(p.Eval().GetFloat()); E0(2).imag(p.Eval().GetImag()); BCValue(n + bcOffset) = E0(2); xx = vertex[4](0); yy = vertex[5](0); p.SetExpr(_T(EzFunc)); E0(2).real(p.Eval().GetFloat()); E0(2).imag(p.Eval().GetImag()); BCValue(n + bcOffset + edgeNumOfELE.rows()) = E0(2); } else { p.SetExpr(_T(E0x)); E0(0).real(p.Eval().GetFloat()); E0(0).imag(p.Eval().GetImag()); p.SetExpr(_T(E0y)); E0(1).real(p.Eval().GetFloat()); E0(1).imag(p.Eval().GetImag()); xx = vertex[3](0); yy = vertex[4](0); p.SetExpr(_T(E0z)); E0(2).real(p.Eval().GetFloat()); E0(2).imag(p.Eval().GetImag()); BCValue(n + bcOffset) = E0(2); xx = vertex[4](0); yy = vertex[5](0); p.SetExpr(_T(E0z)); E0(2).real(p.Eval().GetFloat()); E0(2).imag(p.Eval().GetImag()); BCValue(n + bcOffset + edgeNumOfELE.rows()) = E0(2); } BCValue(n + bcOffset + edgeNumOfELE.rows() * 2) = E0.dot(ee); } bcOffset += currentEdgeNum.rows(); } delete[] vertex; //store PEC data for (int i = 0; i < nodeIndexOfPEC.rows(); i++) { BCIndex(i + bcOffset * 3) = nodeIndexOfPEC(i); BCValue(i + bcOffset * 3) = 0.; } for (int i = 0; i < edgeIndexOfPEC.rows(); i++) { BCIndex(i + bcOffset * 3 + nodeIndexOfPEC.rows()) = edgeIndexOfPEC(i) + NbrVertex; BCValue(i + bcOffset * 3 + nodeIndexOfPEC.rows()) = 0.; } //排序 Eigen::VectorXi tempIndex = Eigen::VectorXi::Zero(NbrBC); for (int i = 0; i < NbrBC; i++) tempIndex(i) = i; QuickSort(BCIndex, tempIndex, 0, NbrBC - 1); //去重 Unique(BCIndex, tempIndex); Eigen::VectorXcd tempValue = Eigen::VectorXcd::Zero(BCIndex.rows()); for (int i = 0; i < BCIndex.rows(); i++) tempValue(i) = BCValue(tempIndex(i)); BCValue = tempValue; //处理 if (_mIsReal) { Eigen::VectorXd tempValue; for (int i = 0; i < BCValue.rows(); i++) { tempValue = Eigen::VectorXd::Zero(_mA_real.rows()); tempValue(BCIndex(i)) = 1.; _mB_real = _mB_real - _mA_real * tempValue * BCValue(i).real(); } Eigen::SparseMatrix P(_mA_real.rows(), _mA_real.rows()); std::vector> tempTriple; int num = 0; for (int i = 0; i < _mA_real.rows(); i++) { if (num < BCIndex.rows()) { if (i == BCIndex(num)) num++; else tempTriple.push_back(Eigen::Triplet(i, i, 1.)); } else tempTriple.push_back(Eigen::Triplet(i, i, 1.)); } P.setFromTriplets(tempTriple.begin(), tempTriple.end()); _mA_real = P * _mA_real * P; P.setZero(); tempTriple.clear(); for (int i = 0; i < BCIndex.rows(); i++) { tempTriple.push_back(Eigen::Triplet(BCIndex(i), BCIndex(i), 1.)); _mB_real(BCIndex(i)) = BCValue(i).real(); } P.setFromTriplets(tempTriple.begin(), tempTriple.end()); _mA_real = _mA_real + P; } else { Eigen::VectorXcd tempValue; for (int i = 0; i < BCValue.rows(); i++) { tempValue = Eigen::VectorXcd::Zero(_mA_complex.rows()); tempValue(BCIndex(i)) = 1; _mB_complex = _mB_complex - _mA_complex * tempValue * BCValue(i); } Eigen::SparseMatrix, Eigen::RowMajor> P(_mA_complex.rows(), _mA_complex.rows()); std::vector>> tempTriple; int num = 0; for (int i = 0; i < _mA_complex.rows(); i++) { if (num < BCIndex.rows()) { if (i == BCIndex(num)) num++; else tempTriple.push_back(Eigen::Triplet>(i, i, 1.)); } else tempTriple.push_back(Eigen::Triplet>(i, i, 1.)); } P.setFromTriplets(tempTriple.begin(), tempTriple.end()); _mA_complex = P * _mA_complex * P; P.setZero(); tempTriple.clear(); for (int i = 0; i < BCIndex.rows(); i++) { tempTriple.push_back(Eigen::Triplet>(BCIndex(i), BCIndex(i), 1.)); _mB_complex(BCIndex(i)) = BCValue(i); } P.setFromTriplets(tempTriple.begin(), tempTriple.end()); _mA_complex = _mA_complex + P; } } void OpticsFEM_2D_Scatter::Assemble_PBC() { //find PBC index Eigen::VectorXi srcNodeIndex, dstNodeIndex, srcEdgeIndex, dstEdgeIndex; Eigen::VectorXcd nodePhi, edgePhi, PBCData; Eigen::MatrixXi PBC; PBC = Eigen::MatrixXi::Zero(_mPhy->GetNbrPBC(), 2); PBCData = Eigen::VectorXcd::Zero(_mPhy->GetNbrPBC()); for (int i = 0; i < _mPhy->GetNbrPBC(); i++) { PBC(i, 0) = _mPhy->GetSrcDomain(i); PBC(i, 1) = _mPhy->GetDstDomain(i); PBCData(i) = _mPhy->GetPBCPhi(i); } _mMesh->GetIndexOfPBC(PBC, PBCData, srcNodeIndex, dstNodeIndex, nodePhi, srcEdgeIndex, dstEdgeIndex, edgePhi); //行 1:DOF //列 1:(DOF-NbrPEC-NbrDst) int NbrVertex = _mMesh->GetNbrVertex(); int NbrDstIndex = dstNodeIndex.rows() + dstEdgeIndex.rows(); Eigen::VectorXi dstIndex = Eigen::VectorXi::Zero(NbrDstIndex); Eigen::VectorXi srcIndex = Eigen::VectorXi::Zero(NbrDstIndex); Eigen::VectorXcd IndexPhi = Eigen::VectorXcd::Zero(NbrDstIndex); for (int i = 0; i < dstNodeIndex.rows(); i++) { dstIndex(i) = dstNodeIndex(i); srcIndex(i) = srcNodeIndex(i); IndexPhi(i) = nodePhi(i); } for (int i = 0; i < dstEdgeIndex.rows(); i++) { int num = dstNodeIndex.rows(); dstIndex(i + num) = dstEdgeIndex(i) + NbrVertex; srcIndex(i + num) = srcEdgeIndex(i) + NbrVertex; IndexPhi(i + num) = edgePhi(i); } //排序 Eigen::VectorXi tempIndex = Eigen::VectorXi::Zero(NbrDstIndex); for (int i = 0; i < NbrDstIndex; i++) tempIndex(i) = i; QuickSort(dstIndex, tempIndex, 0, NbrDstIndex - 1); //去重 Unique(dstIndex, tempIndex); Eigen::VectorXcd tempIndexPhi = Eigen::VectorXcd::Zero(dstIndex.rows()); Eigen::VectorXi tempSrcIndex = Eigen::VectorXi::Zero(dstIndex.rows()); for (int i = 0; i < dstIndex.rows(); i++) { tempIndexPhi(i) = IndexPhi(tempIndex(i)); tempSrcIndex(i) = srcIndex(tempIndex(i)); } IndexPhi = tempIndexPhi; srcIndex = tempSrcIndex; //不同数目 int dof = _mMesh->GetNbrEdge() + _mMesh->GetNbrVertex(); int vdof = _mMesh->GetNbrEdge(); int sdof = _mMesh->GetNbrVertex(); //P矩阵 int num = 0; if (_mIsReal) { std::vector> temp_P; for (int i = 0; i < dof; i++) // { temp_P.push_back(Eigen::Triplet(i, i, 1)); if (num < dstIndex.size()) //处理PBC { if (i == dstIndex(num)) { temp_P.push_back(Eigen::Triplet(dstIndex(num), srcIndex(num), IndexPhi(num).real())); num++; } } } /*临时P矩阵排序*/ std::sort(temp_P.begin(), temp_P.end(), [](const Eigen::Triplet& a, const Eigen::Triplet& b) { return a.col() < b.col(); }); /*删除dstIndex对应列*/ std::vector> tripleP_real; num = 0;// 用于跟踪新矩阵的列索引 int DeleteIndex = 0; for (int i = 0; i < dof; i++) { DeleteIndex = 0; for (int j = 0; j < dstIndex.rows(); j++) { if (i == dstIndex[j]) { DeleteIndex = 1; } } if (DeleteIndex != 1) { for (const auto& triplet : temp_P) { if (triplet.col() == i) { tripleP_real.push_back(Eigen::Triplet(triplet.row(), triplet.col() - num, triplet.value())); } } } for (int j = 0; j < dstIndex.rows(); j++) { if (i == dstIndex[j]) { num = num + 1; } } } _mP_real = Eigen::SparseMatrix(dof, dof - dstIndex.rows()); _mP_real.setFromTriplets(tripleP_real.begin(), tripleP_real.end()); } else { std::vector>> temp_P_complex; for (int i = 0; i < dof; i++) // { temp_P_complex.push_back(Eigen::Triplet>(i, i, 1)); if (num < dstIndex.size()) //处理PEC或PBC { if (i == dstIndex(num)) { temp_P_complex.push_back(Eigen::Triplet>(dstIndex(num), srcIndex(num), IndexPhi(num))); num++; } } } /*临时P矩阵排序*/ std::sort(temp_P_complex.begin(), temp_P_complex.end(), [](const Eigen::Triplet>& a, const Eigen::Triplet>& b) { return a.col() < b.col(); }); /*删除dstIndex对应列*/ std::vector>> tripleP_complex; num = 0;// 用于跟踪新矩阵的列索引 int DeleteIndex = 0; for (int i = 0; i < dof; i++) { DeleteIndex = 0; for (int j = 0; j < dstIndex.rows(); j++) { if (i == dstIndex[j]) { DeleteIndex = 1; } } if (DeleteIndex != 1) { for (const auto& triplet : temp_P_complex) { if (triplet.col() == i) { tripleP_complex.push_back(Eigen::Triplet>(triplet.row(), triplet.col() - num, triplet.value())); } } } for (int j = 0; j < dstIndex.rows(); j++) { if (i == dstIndex[j]) { num = num + 1; } } } _mP_complex = Eigen::SparseMatrix, Eigen::RowMajor>(dof, dof - dstIndex.rows()); _mP_complex.setFromTriplets(tripleP_complex.begin(), tripleP_complex.end());; } } void OpticsFEM_2D_Scatter::Assemble_Port() { //physic double k0 = 2 * Pi / _mSolver->GetLda0(); //init of Gauss point Gauss gauss; int NbrGuassPoints; NbrGuassPoints = gauss.GetNbrGaussPoints(ONEDIM, LINE, BF_LINEFUNC * 4); double* u, * v, * w, * wght; u = new double[NbrGuassPoints]; v = new double[NbrGuassPoints]; w = new double[NbrGuassPoints]; wght = new double[NbrGuassPoints]; gauss.GetGaussPoints(ONEDIM, LINE, u, v, w, wght); //init of geo Vector3d* vertex = new Vector3d[5]; Matrix3d Jac, InvJac; Vector3d normal; //init of basis function BF BF_Lagrange, BF_Nedelec; Vector3d* Et, ** Ez; BF_Lagrange.GetNbrBF(TWODIM, TRIANGLE, BF_LAGRANGE, BF_LINEFUNC); BF_Nedelec.GetNbrBF(TWODIM, TRIANGLE, BF_NEDELEC, BF_LINEFUNC); Et = new Vector3d[NbrGuassPoints]; Ez = new Vector3d * [NbrGuassPoints]; for (int i = 0; i < NbrGuassPoints; i++) { Ez[i] = new Vector3d[2]; } //inite parser mup::ParserX p(mup::pckALL_COMPLEX); p.EnableAutoCreateVar(true); mup::Value xx, yy; p.DefineVar(_T("x"), mup::Variable(&xx)); p.DefineVar(_T("y"), mup::Variable(&yy)); Vector3cd* N0, * N2, * curlN0, * curlN1, * curlN2; N0 = new Vector3cd[NbrGuassPoints]; N2 = new Vector3cd[NbrGuassPoints]; curlN0 = new Vector3cd[NbrGuassPoints]; curlN1 = new Vector3cd[NbrGuassPoints]; curlN2 = new Vector3cd[NbrGuassPoints]; int NbrPortinc = _mPhy->GetNbrPortinc(); for (int n = 0; n < NbrPortinc; n++) { int PortincDomain = _mPhy->GetPortincDomain(n) + 1; Eigen::VectorXi edgesIndex; _mMesh->GetEdgesIndexOfDomain(PortincDomain, edgesIndex); string Eincx, Eincy, Eincz, Eoutx, Eouty, Eoutz, EincCurlx, EincCurly, EincCurlz, EoutCurlx, EoutCurly, EoutCurlz; _mPhy->GetPortEinc(Eincx, Eincy, Eincz); _mPhy->GetPortEout(Eoutx, Eouty, Eoutz); _mPhy->GetPortEincCurl(EincCurlx, EincCurly, EincCurlz); _mPhy->GetPortEoutCurl(EoutCurlx, EoutCurly, EoutCurlz); //overloop of edgesOfPortinc for (int m = 0; m < edgesIndex.rows(); m++) { // edge data Vector2i coonOfEdges; _mMesh->GetCoonOfEdges(edgesIndex(m), coonOfEdges); int numEle = coonOfEdges(0); int numEdge = coonOfEdges(1); //coordinate of vertex,integration coordinate, and mapping int MappingIndex[3]; int index[3]; for (int i = 0; i < 3; i++) _mMesh->GetVertex(_mMesh->GetTri(numEle, i), vertex[i]); if (numEdge == 0) { vertex[3] = vertex[0]; vertex[4] = vertex[1]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = 0.0; } index[0] = 1; index[1] = 2; index[2] = 1; MappingIndex[0] = _mMesh->GetTri(numEle, 0); MappingIndex[1] = _mMesh->GetTri(numEle, 1); MappingIndex[2] = _mMesh->GetEdgeOfTri(numEle, 0) + _mMesh->GetNbrVertex(); } else if (numEdge == 1) { vertex[3] = vertex[0]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = 0.0; w[i] = (u[i] + 1.0) / 2.0; } index[0] = 1; index[1] = 3; index[2] = 2; MappingIndex[0] = _mMesh->GetTri(numEle, 0); MappingIndex[1] = _mMesh->GetTri(numEle, 2); MappingIndex[2] = _mMesh->GetEdgeOfTri(numEle, 1) + _mMesh->GetNbrVertex(); } else if (numEdge == 2) { vertex[3] = vertex[0]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = (1.0 - u[i]) / 2.0; } index[0] = 2; index[1] = 3; index[2] = 3; MappingIndex[0] = _mMesh->GetTri(numEle, 1); MappingIndex[1] = _mMesh->GetTri(numEle, 2); MappingIndex[2] = _mMesh->GetEdgeOfTri(numEle, 2) + _mMesh->GetNbrVertex(); } //Jac Jac(0, 0) = vertex[1](0) - vertex[0](0); Jac(0, 1) = vertex[1](1) - vertex[0](1); Jac(0, 2) = 0.; Jac(1, 0) = vertex[2](0) - vertex[0](0); Jac(1, 1) = vertex[2](1) - vertex[0](1); Jac(1, 2) = 0.; Jac(2, 0) = 0.; Jac(2, 1) = 0.; Jac(2, 2) = 1.; InvJac = Jac.inverse(); //integration coe double phi1 = vertex[4](1) - vertex[3](1); double phi2 = vertex[3](0) - vertex[4](0); double integCoe = 0; if (vertex[3](0) != vertex[4](0)) { integCoe = phi1 / phi2; integCoe = fabs(sqrtf(1 + integCoe * integCoe) * phi2 / 2.0); } else { integCoe = abs(phi1) / 2.0; } //normal _mMesh->GetNormOfEdges(_mMesh->GetDomainOfEdges(edgesIndex(m)) - 1, normal); //basis function for (int i = 0; i < NbrGuassPoints; i++) { for (int j = 0; j < 2; j++) { BF_Lagrange.GetValueBF(index[j], v[i], w[i], 0.0, Ez[i][j]); } BF_Nedelec.GetValueBF(index[2], v[i], w[i], 0.0, Et[i]); Et[i] = InvJac * Et[i]; } for (int i = 0; i < NbrGuassPoints; i++) { double tempX = Jac(0, 0) * v[i] + Jac(1, 0) * w[i] + vertex[0](0); double tempY = Jac(0, 1) * v[i] + Jac(1, 1) * w[i] + vertex[0](1); xx = Jac(0, 0) * v[i] + Jac(1, 0) * w[i] + vertex[0](0); yy = Jac(0, 1) * v[i] + Jac(1, 1) * w[i] + vertex[0](1); //入射场N0 p.SetExpr(_T(Eincx)); N0[i](0).real(p.Eval().GetFloat()); N0[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(Eincy)); N0[i](1).real(p.Eval().GetFloat()); N0[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(Eincz)); N0[i](2).real(p.Eval().GetFloat()); N0[i](2).imag(p.Eval().GetImag()); //出射场N2 p.SetExpr(_T(Eoutx)); N2[i](0).real(p.Eval().GetFloat()); N2[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(Eincy)); N0[i](1).real(p.Eval().GetFloat()); N0[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(Eincz)); N0[i](2).real(p.Eval().GetFloat()); N0[i](2).imag(p.Eval().GetImag()); //入射场N0旋度 p.SetExpr(_T(EincCurlx)); curlN0[i](0).real(p.Eval().GetFloat()); curlN0[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(EincCurly)); curlN0[i](1).real(p.Eval().GetFloat()); curlN0[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(EincCurlz)); curlN0[i](2).real(p.Eval().GetFloat()); curlN0[i](2).imag(p.Eval().GetImag()); //入射场N1旋度 curlN1[i](0) = std::conj(curlN0[i](0)); curlN1[i](1) = std::conj(curlN0[i](1)); curlN1[i](2) = std::conj(curlN0[i](2)); //出射场N2 p.SetExpr(_T(EoutCurlx)); curlN2[i](0).real(p.Eval().GetFloat()); curlN2[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(EoutCurly)); curlN2[i](1).real(p.Eval().GetFloat()); curlN2[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(EoutCurlz)); curlN2[i](2).real(p.Eval().GetFloat()); curlN2[i](2).imag(p.Eval().GetImag()); } //material int domain = _mMesh->GetDomainOfTri(n); Matrix3cd epsr = _mMatLib->GetEpsr(domain); Matrix3cd refra = epsr.cwiseSqrt(); //submatrix MatrixXcd Se1, Ge1, be1; Se1 = MatrixXcd::Zero(2, 1); Ge1 = MatrixXcd::Zero(2, 1); be1 = MatrixXcd::Zero(2, 1); complexSe2, Ge2, be2; for (int i = 0; i < 2; i++) { for (int k = 0; k < NbrGuassPoints; k++) { be1(i, 0) = be1(i, 0) + wght[k] * integCoe * Ez[k][i].dot(curlN0[k].cross(refra * normal)); Se1(i, 0) = Se1(i, 0) + wght[k] * integCoe * Ez[k][i].dot(curlN1[k].cross(refra * normal)); Ge1(i, 0) = Ge1(i, 0) + wght[k] * integCoe * N0[k].dot(normal.cross(Ez[k][i].cross(normal))); } } for (int k = 0; k < NbrGuassPoints; k++) { be2 = be2 + wght[k] * integCoe * Et[k].dot(curlN0[k].cross(refra * normal)); Se2 = Se2 + wght[k] * integCoe * Et[k].dot(curlN1[k].cross(refra * normal)); Ge2 = Ge2 + wght[k] * integCoe * N0[k].dot(normal.cross(Et[k].cross(normal))); P1 = P1 + wght[k] * integCoe * N0[k].dot(normal.cross(N0[k].cross(normal))); b1 = b1 + wght[k] * integCoe * N0[k].dot(normal.cross(N0[k].cross(normal))); } //组装矩阵 for (int i = 0; i < 2; i++) { _mPort_B_complex(MappingIndex[i]) = _mPort_B_complex(MappingIndex[i]) - be1(i, 0); _mS_complex(MappingIndex[i]) = _mS_complex(MappingIndex[i]) + Se1(i, 0); _mG1_complex(MappingIndex[i]) = _mG1_complex(MappingIndex[i]) + Ge1(i, 0); } _mPort_B_complex(MappingIndex[2]) = _mPort_B_complex(MappingIndex[2]) - be2; _mS_complex(MappingIndex[2]) = _mS_complex(MappingIndex[2]) + Se2; _mG1_complex(MappingIndex[2]) = _mG1_complex(MappingIndex[2]) + Ge2; //出射端口 int PortoutDomain = _mPhy->GetPortoutDomain(n) + 1; Eigen::VectorXi edgesIndex; _mMesh->GetEdgesIndexOfDomain(PortoutDomain, edgesIndex); for (int m = 0; m < edgesIndex.rows(); m++) { // edge data Vector2i coonOfEdges; _mMesh->GetCoonOfEdges(edgesIndex(m), coonOfEdges); int numEle = coonOfEdges(0); int numEdge = coonOfEdges(1); //coordinate of vertex,integration coordinate, and mapping int MappingIndex[3]; int index[3]; for (int i = 0; i < 3; i++) _mMesh->GetVertex(_mMesh->GetTri(numEle, i), vertex[i]); if (numEdge == 0) { vertex[3] = vertex[0]; vertex[4] = vertex[1]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = 0.0; } index[0] = 1; index[1] = 2; index[2] = 1; MappingIndex[0] = _mMesh->GetTri(numEle, 0); MappingIndex[1] = _mMesh->GetTri(numEle, 1); MappingIndex[2] = _mMesh->GetEdgeOfTri(numEle, 0) + _mMesh->GetNbrVertex(); } else if (numEdge == 1) { vertex[3] = vertex[0]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = 0.0; w[i] = (u[i] + 1.0) / 2.0; } index[0] = 1; index[1] = 3; index[2] = 2; MappingIndex[0] = _mMesh->GetTri(numEle, 0); MappingIndex[1] = _mMesh->GetTri(numEle, 2); MappingIndex[2] = _mMesh->GetEdgeOfTri(numEle, 1) + _mMesh->GetNbrVertex(); } else if (numEdge == 2) { vertex[3] = vertex[0]; vertex[4] = vertex[2]; for (int i = 0; i < NbrGuassPoints; i++) { v[i] = (u[i] + 1.0) / 2.0; w[i] = (1.0 - u[i]) / 2.0; } index[0] = 2; index[1] = 3; index[2] = 3; MappingIndex[0] = _mMesh->GetTri(numEle, 1); MappingIndex[1] = _mMesh->GetTri(numEle, 2); MappingIndex[2] = _mMesh->GetEdgeOfTri(numEle, 2) + _mMesh->GetNbrVertex(); } //Jac Jac(0, 0) = vertex[1](0) - vertex[0](0); Jac(0, 1) = vertex[1](1) - vertex[0](1); Jac(0, 2) = 0.; Jac(1, 0) = vertex[2](0) - vertex[0](0); Jac(1, 1) = vertex[2](1) - vertex[0](1); Jac(1, 2) = 0.; Jac(2, 0) = 0.; Jac(2, 1) = 0.; Jac(2, 2) = 1.; InvJac = Jac.inverse(); //integration coe double phi1 = vertex[4](1) - vertex[3](1); double phi2 = vertex[3](0) - vertex[4](0); double integCoe = 0; if (vertex[3](0) != vertex[4](0)) { integCoe = phi1 / phi2; integCoe = fabs(sqrtf(1 + integCoe * integCoe) * phi2 / 2.0); } else { integCoe = abs(phi1) / 2.0; } //normal _mMesh->GetNormOfEdges(_mMesh->GetDomainOfEdges(edgesIndex(m)) - 1, normal); //basis function for (int i = 0; i < NbrGuassPoints; i++) { for (int j = 0; j < 2; j++) { BF_Lagrange.GetValueBF(index[j], v[i], w[i], 0.0, Ez[i][j]); } BF_Nedelec.GetValueBF(index[2], v[i], w[i], 0.0, Et[i]); Et[i] = InvJac * Et[i]; } for (int i = 0; i < NbrGuassPoints; i++) { double tempX = Jac(0, 0) * v[i] + Jac(1, 0) * w[i] + vertex[0](0); double tempY = Jac(0, 1) * v[i] + Jac(1, 1) * w[i] + vertex[0](1); xx = Jac(0, 0) * v[i] + Jac(1, 0) * w[i] + vertex[0](0); yy = Jac(0, 1) * v[i] + Jac(1, 1) * w[i] + vertex[0](1); //入射场N0 p.SetExpr(_T(Eincx)); N0[i](0).real(p.Eval().GetFloat()); N0[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(Eincy)); N0[i](1).real(p.Eval().GetFloat()); N0[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(Eincz)); N0[i](2).real(p.Eval().GetFloat()); N0[i](2).imag(p.Eval().GetImag()); //出射场N2 p.SetExpr(_T(Eoutx)); N2[i](0).real(p.Eval().GetFloat()); N2[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(Eouty)); N2[i](1).real(p.Eval().GetFloat()); N2[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(Eoutz)); N2[i](2).real(p.Eval().GetFloat()); N2[i](2).imag(p.Eval().GetImag()); //入射场N0旋度 p.SetExpr(_T(EincCurlx)); curlN0[i](0).real(p.Eval().GetFloat()); curlN0[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(EincCurly)); curlN0[i](1).real(p.Eval().GetFloat()); curlN0[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(EincCurlz)); curlN0[i](2).real(p.Eval().GetFloat()); curlN0[i](2).imag(p.Eval().GetImag()); //入射场N1旋度 curlN1[i](0) = std::conj(curlN0[i](0)); curlN1[i](1) = std::conj(curlN0[i](1)); curlN1[i](2) = std::conj(curlN0[i](2)); //出射场N2 p.SetExpr(_T(EoutCurlx)); curlN2[i](0).real(p.Eval().GetFloat()); curlN2[i](0).imag(p.Eval().GetImag()); p.SetExpr(_T(EoutCurly)); curlN2[i](1).real(p.Eval().GetFloat()); curlN2[i](1).imag(p.Eval().GetImag()); p.SetExpr(_T(EoutCurlz)); curlN2[i](2).real(p.Eval().GetFloat()); curlN2[i](2).imag(p.Eval().GetImag()); } //material int domain = _mMesh->GetDomainOfTri(n); Matrix3cd epsr = _mMatLib->GetEpsr(domain); Matrix3cd refra = epsr.cwiseSqrt(); //submatrix MatrixXcd Te1, Ge1; Te1 = MatrixXcd::Zero(2, 1); Ge1 = MatrixXcd::Zero(2, 1); complexP2; for (int i = 0; i < 2; i++) { for (int k = 0; k < NbrGuassPoints; k++) { Te1(i, 0) = Te1(i, 0) + wght[k] * integCoe * Ez[k][i].dot(curlN2[k].cross(refra * normal)); Ge1(i, 0) = Ge1(i, 0) + wght[k] * integCoe * N2[k].dot(normal.cross(Ez[k][i].cross(normal))); P2 = P2 + wght[k] * integCoe * N2[k].dot(normal.cross(N2[k].cross(normal))); } } complexTe2, Ge2; for (int k = 0; k < NbrGuassPoints; k++) { Te2 = Te2 + wght[k] * integCoe * Et[k].dot(curlN2[k].cross(refra * normal)); Ge2 = Ge2 + wght[k] * integCoe * N2[k].dot(normal.cross(Et[k].cross(normal))); } //组装矩阵 for (int i = 0; i < 2; i++) { _mT_complex(MappingIndex[i]) = _mT_complex(MappingIndex[i]) + Te1(i, 0); _mG2_complex(MappingIndex[i]) = _mG2_complex(MappingIndex[i]) + Ge1(i, 0); } _mT_complex(MappingIndex[2]) = _mT_complex(MappingIndex[2]) + Te2; _mG2_complex(MappingIndex[2]) = _mG2_complex(MappingIndex[2]) + Ge2; } } } _mS_complex = _mP_complex.adjoint() * _mS_complex; _mT_complex = _mP_complex.adjoint() * _mT_complex; _mG1_complex = _mP_complex.adjoint() * _mG1_complex; _mG2_complex = _mP_complex.adjoint() * _mG2_complex; for (const auto& triplet : _mTripleA_complex) { _mTriplePort_A_complex.push_back(Triplet>(triplet.row(), triplet.col(), triplet.value())); /*std::cout << "col: " << triplet.col() << "row: " << triplet.row() << ", Value: " << triplet.value() << std::endl;*/ } for (int k = 0; k < _mA_complex.outerSize(); k++) { for (Eigen::SparseMatrix, RowMajor>::InnerIterator it(_mA_complex, k); it; ++it) { _mTriplePort_A_complex.push_back(Triplet>(it.row(), it.col(), it.value())); } } for (int i = 0; i < _mS_complex.size(); i++) { _mTriplePort_A_complex.push_back(Triplet>(i, _mDof, _mS_complex[i])); } for (int i = 0; i < _mT_complex.size(); i++) { _mTriplePort_A_complex.push_back(Triplet>(i, _mDof + 1, _mT_complex[i])); } for (int i = 0; i < _mG1_complex.size(); i++) { _mTriplePort_A_complex.push_back(Triplet>(_mDof, i, _mG1_complex[i])); } for (int i = 0; i < _mG2_complex.size(); i++) { _mTriplePort_A_complex.push_back(Triplet>(_mDof + 1, i, _mG2_complex[i])); } _mTriplePort_A_complex.push_back(Triplet>(_mDof, _mDof, -P1)); _mTriplePort_A_complex.push_back(Triplet>(_mDof + 1, _mDof + 1, -P2)); _mPort_B_complex(_mDof) = b1; for (int k = 0; k < _mP_complex.outerSize(); k++) { for (Eigen::SparseMatrix, RowMajor>::InnerIterator it(_mP_complex, k); it; ++it) { _mPort_P_complex.coeffRef(it.row(), it.col()) = it.value(); } } }