void IEFSolver::buildIsotropicMatrix(const Cavity & cav, const IGreensFunction & gf_i, const IGreensFunction & gf_o) { // The total size of the cavity size_t cavitySize = cav.size(); // The number of irreps in the group int nrBlocks = cav.pointGroup().nrIrrep(); // The size of the irreducible portion of the cavity int dimBlock = cav.irreducible_size(); // Compute SI and DI on the whole cavity, regardless of symmetry Eigen::MatrixXd SI = gf_i.singleLayer(cav.elements()); Eigen::MatrixXd DI = gf_i.doubleLayer(cav.elements()); // Perform symmetry blocking // If the group is C1 avoid symmetry blocking, we will just pack the fullPCMMatrix // into "block diagonal" when all other manipulations are done. if (cav.pointGroup().nrGenerators() != 0) { symmetryBlocking(DI, cavitySize, dimBlock, nrBlocks); symmetryBlocking(SI, cavitySize, dimBlock, nrBlocks); } Eigen::MatrixXd a = cav.elementArea().asDiagonal(); Eigen::MatrixXd aInv = Eigen::MatrixXd::Zero(cavitySize, cavitySize); aInv = a.inverse(); // Tq = -Rv -> q = -(T^-1 * R)v = -Kv // T = (2 * M_PI * fact * aInv - DI) * a * SI; R = (2 * M_PI * aInv - DI) // fullPCMMatrix_ = K = T^-1 * R * a // 1. Form T double epsilon = profiles::epsilon(gf_o.permittivity()); double fact = (epsilon + 1.0)/(epsilon - 1.0); fullPCMMatrix_ = (2 * M_PI * fact * aInv - DI) * a * SI; // 2. Invert T using LU decomposition with full pivoting // This is a rank-revealing LU decomposition, this allows us // to test if T is invertible before attempting to invert it. Eigen::FullPivLU<Eigen::MatrixXd> T_LU(fullPCMMatrix_); if (!(T_LU.isInvertible())) PCMSOLVER_ERROR("T matrix is not invertible!"); fullPCMMatrix_ = T_LU.inverse(); // 3. Multiply T^-1 and R fullPCMMatrix_ *= (2 * M_PI * aInv - DI); // 4. Multiply by a fullPCMMatrix_ *= a; // 5. Symmetrize K := (K + K+)/2 if (hermitivitize_) { hermitivitize(fullPCMMatrix_); } // Pack into a block diagonal matrix // For the moment just packs into a std::vector<Eigen::MatrixXd> symmetryPacking(blockPCMMatrix_, fullPCMMatrix_, dimBlock, nrBlocks); std::ofstream matrixOut("PCM_matrix"); matrixOut << "fullPCMMatrix" << std::endl; matrixOut << fullPCMMatrix_ << std::endl; for (int i = 0; i < nrBlocks; ++i) { matrixOut << "Block number " << i << std::endl; matrixOut << blockPCMMatrix_[i] << std::endl; } built_ = true; }
void IEFSolver::buildAnisotropicMatrix(const Cavity & cav, const IGreensFunction & gf_i, const IGreensFunction & gf_o) { // The total size of the cavity size_t cavitySize = cav.size(); // The number of irreps in the group int nrBlocks = cav.pointGroup().nrIrrep(); // The size of the irreducible portion of the cavity int dimBlock = cav.irreducible_size(); // Compute SI, DI and SE, DE on the whole cavity, regardless of symmetry Eigen::MatrixXd SI = gf_i.singleLayer(cav.elements()); Eigen::MatrixXd DI = gf_i.doubleLayer(cav.elements()); Eigen::MatrixXd SE = gf_o.singleLayer(cav.elements()); Eigen::MatrixXd DE = gf_o.doubleLayer(cav.elements()); // Perform symmetry blocking // If the group is C1 avoid symmetry blocking, we will just pack the fullPCMMatrix // into "block diagonal" when all other manipulations are done. if (cav.pointGroup().nrGenerators() != 0) { symmetryBlocking(DI, cavitySize, dimBlock, nrBlocks); symmetryBlocking(SI, cavitySize, dimBlock, nrBlocks); symmetryBlocking(DE, cavitySize, dimBlock, nrBlocks); symmetryBlocking(SE, cavitySize, dimBlock, nrBlocks); } Eigen::MatrixXd a = cav.elementArea().asDiagonal(); Eigen::MatrixXd aInv = a.inverse(); // 1. Form T fullPCMMatrix_ = ((2 * M_PI * aInv - DE) * a * SI + SE * a * (2 * M_PI * aInv + DI.adjoint().eval())); // 2. Invert T using LU decomposition with full pivoting // This is a rank-revealing LU decomposition, this allows us // to test if T is invertible before attempting to invert it. Eigen::FullPivLU<Eigen::MatrixXd> T_LU(fullPCMMatrix_); if (!(T_LU.isInvertible())) PCMSOLVER_ERROR("T matrix is not invertible!"); fullPCMMatrix_ = T_LU.inverse(); Eigen::FullPivLU<Eigen::MatrixXd> SI_LU(SI); if (!(SI_LU.isInvertible())) PCMSOLVER_ERROR("SI matrix is not invertible!"); fullPCMMatrix_ *= ((2 * M_PI * aInv - DE) - SE * SI_LU.inverse() * (2 * M_PI * aInv - DI)); fullPCMMatrix_ *= a; // 5. Symmetrize K := (K + K+)/2 if (hermitivitize_) { hermitivitize(fullPCMMatrix_); } // Pack into a block diagonal matrix // For the moment just packs into a std::vector<Eigen::MatrixXd> symmetryPacking(blockPCMMatrix_, fullPCMMatrix_, dimBlock, nrBlocks); std::ofstream matrixOut("PCM_matrix"); matrixOut << "fullPCMMatrix" << std::endl; matrixOut << fullPCMMatrix_ << std::endl; for (int i = 0; i < nrBlocks; ++i) { matrixOut << "Block number " << i << std::endl; matrixOut << blockPCMMatrix_[i] << std::endl; } built_ = true; }
typename PointMesher<T>::Matrix PointMesher<T>::ITMLocalMesher::delaunay2D(const Matrix matrixIn) const { typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Triangulation_vertex_base_with_info_2<int, K> Vb; typedef CGAL::Triangulation_face_base_2<K> Fb; typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds; typedef CGAL::Delaunay_triangulation_2<K, Tds> DelaunayTri; typedef DelaunayTri::Finite_faces_iterator Finite_faces_iterator; typedef DelaunayTri::Vertex_handle Vertex_handle; typedef DelaunayTri::Point Point; // Compute triangulation DelaunayTri dt; for (int i = 0; i < matrixIn.cols(); i++) { // Add point Point p = Point(matrixIn(0, i), matrixIn(1, i)); dt.push_back(Point(p)); // Add index Vertex_handle vh = dt.push_back(p); vh->info() = i; } // Iterate through faces Matrix matrixOut(3, dt.number_of_faces()); int itCol = 0; DelaunayTri::Finite_faces_iterator it; for (it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++) { for (int k = 0; k < matrixOut.rows(); k++) { // Add index of triangle vertex to list matrixOut(k, itCol) = it->vertex(k)->info(); } itCol++; } return matrixOut; }
typename PointMesher<T>::Matrix PointMesher<T>::ITMLocalMesher::cart2Spheric(const Matrix matrixIn) const { assert(matrixIn.rows() == 3); // Generate matrix Matrix matrixOut(3, matrixIn.cols()); // Compute r matrixOut.row(0) = matrixIn.colwise().norm(); for (int i = 0; i < matrixIn.cols(); i++) { // Compute theta matrixOut(1, i) = asin(matrixIn(2, i) / matrixOut(0, i)); //acos(matrixIn(2, i) / matrixOut(0, i)); // Compute phi matrixOut(2, i) = atan2(matrixIn(1, i), matrixIn(0, i)); //acos(matrixIn(0, i) / (matrixOut(0, i)*cos(matrixOut(1, i)))); } return matrixOut; }
// Generic method for printing a matrix provided an output // file name void shapeAlign::printMatrix(gsl_matrix* M, const string &outFile){ ofstream matrixOut(outFile.c_str()); if (matrixOut.is_open()){ for (size_t i = 0; i < M->size1; i++){ for (size_t j = 0; j < M->size2; j++){ if (j > 0) matrixOut << "\t"; matrixOut << gsl_matrix_get(M,i,j); } matrixOut << endl; } } else { cerr << "Error: Could not open output file (" << outFile << "). Exiting." << endl; exit(1); } matrixOut.close(); return; }