4040#include " Element.hpp"
4141#include " IGreensFunction.hpp"
4242#include " MathUtils.hpp"
43+ #include " SolverImpl.hpp"
4344
4445void IEFSolver::buildSystemMatrix_impl (const Cavity & cavity, const IGreensFunction & gf_i, const IGreensFunction & gf_o)
4546{
@@ -49,119 +50,36 @@ void IEFSolver::buildSystemMatrix_impl(const Cavity & cavity, const IGreensFunct
4950
5051void IEFSolver::buildAnisotropicMatrix (const Cavity & cav, const IGreensFunction & gf_i, const IGreensFunction & gf_o)
5152{
52- // The total size of the cavity
53- size_t cavitySize = cav.size ();
54- // The number of irreps in the group
55- int nrBlocks = cav.pointGroup ().nrIrrep ();
56- // The size of the irreducible portion of the cavity
57- int dimBlock = cav.irreducible_size ();
58-
59- // Compute SI, DI and SE, DE on the whole cavity, regardless of symmetry
60- Eigen::MatrixXd SI = gf_i.singleLayer (cav.elements ());
61- Eigen::MatrixXd DI = gf_i.doubleLayer (cav.elements ());
62- Eigen::MatrixXd SE = gf_o.singleLayer (cav.elements ());
63- Eigen::MatrixXd DE = gf_o.doubleLayer (cav.elements ());
64-
65- // Perform symmetry blocking
66- // If the group is C1 avoid symmetry blocking, we will just pack the fullPCMMatrix
67- // into "block diagonal" when all other manipulations are done.
68- if (cav.pointGroup ().nrGenerators () != 0 ) {
69- symmetryBlocking (DI, cavitySize, dimBlock, nrBlocks);
70- symmetryBlocking (SI, cavitySize, dimBlock, nrBlocks);
71- symmetryBlocking (DE, cavitySize, dimBlock, nrBlocks);
72- symmetryBlocking (SE, cavitySize, dimBlock, nrBlocks);
73- }
74-
75- Eigen::MatrixXd a = cav.elementArea ().asDiagonal ();
76- Eigen::MatrixXd aInv = a.inverse ();
77-
78- // 1. Form T
79- fullPCMMatrix_ = ((2 * M_PI * aInv - DE) * a * SI + SE * a * (2 * M_PI * aInv + DI.adjoint ().eval ()));
80- // 2. Invert T using LU decomposition with full pivoting
81- // This is a rank-revealing LU decomposition, this allows us
82- // to test if T is invertible before attempting to invert it.
83- Eigen::FullPivLU<Eigen::MatrixXd> T_LU (fullPCMMatrix_);
84- if (!(T_LU.isInvertible ())) PCMSOLVER_ERROR (" T matrix is not invertible!" );
85- fullPCMMatrix_ = T_LU.inverse ();
86- Eigen::FullPivLU<Eigen::MatrixXd> SI_LU (SI);
87- if (!(SI_LU.isInvertible ())) PCMSOLVER_ERROR (" SI matrix is not invertible!" );
88- fullPCMMatrix_ *= ((2 * M_PI * aInv - DE) - SE * SI_LU.inverse () * (2 * M_PI * aInv - DI));
89- fullPCMMatrix_ *= a;
90- // 5. Symmetrize K := (K + K+)/2
53+ fullPCMMatrix_ = anisotropicIEFMatrix (cav, gf_i, gf_o);
54+ // Symmetrize K := (K + K+)/2
9155 if (hermitivitize_) {
9256 hermitivitize (fullPCMMatrix_);
9357 }
9458 // Pack into a block diagonal matrix
59+ // The number of irreps in the group
60+ int nrBlocks = cav.pointGroup ().nrIrrep ();
61+ // The size of the irreducible portion of the cavity
62+ int dimBlock = cav.irreducible_size ();
9563 // For the moment just packs into a std::vector<Eigen::MatrixXd>
9664 symmetryPacking (blockPCMMatrix_, fullPCMMatrix_, dimBlock, nrBlocks);
97- std::ofstream matrixOut (" PCM_matrix" );
98- matrixOut << " fullPCMMatrix" << std::endl;
99- matrixOut << fullPCMMatrix_ << std::endl;
100- for (int i = 0 ; i < nrBlocks; ++i) {
101- matrixOut << " Block number " << i << std::endl;
102- matrixOut << blockPCMMatrix_[i] << std::endl;
103- }
10465
10566 built_ = true ;
10667}
10768
10869void IEFSolver::buildIsotropicMatrix (const Cavity & cav, const IGreensFunction & gf_i, const IGreensFunction & gf_o)
10970{
110- // The total size of the cavity
111- size_t cavitySize = cav.size ();
112- // The number of irreps in the group
113- int nrBlocks = cav.pointGroup ().nrIrrep ();
114- // The size of the irreducible portion of the cavity
115- int dimBlock = cav.irreducible_size ();
116-
117- // Compute SI and DI on the whole cavity, regardless of symmetry
118- Eigen::MatrixXd SI = gf_i.singleLayer (cav.elements ());
119- Eigen::MatrixXd DI = gf_i.doubleLayer (cav.elements ());
120-
121- // Perform symmetry blocking
122- // If the group is C1 avoid symmetry blocking, we will just pack the fullPCMMatrix
123- // into "block diagonal" when all other manipulations are done.
124- if (cav.pointGroup ().nrGenerators () != 0 ) {
125- symmetryBlocking (DI, cavitySize, dimBlock, nrBlocks);
126- symmetryBlocking (SI, cavitySize, dimBlock, nrBlocks);
127- }
128-
129- Eigen::MatrixXd a = cav.elementArea ().asDiagonal ();
130- Eigen::MatrixXd aInv = Eigen::MatrixXd::Zero (cavitySize, cavitySize);
131- aInv = a.inverse ();
132-
133- // Tq = -Rv -> q = -(T^-1 * R)v = -Kv
134- // T = (2 * M_PI * fact * aInv - DI) * a * SI; R = (2 * M_PI * aInv - DI)
135- // fullPCMMatrix_ = K = T^-1 * R * a
136- // 1. Form T
137- double epsilon = profiles::epsilon (gf_o.permittivity ());
138- double fact = (epsilon + 1.0 )/(epsilon - 1.0 );
139- fullPCMMatrix_ = (2 * M_PI * fact * aInv - DI) * a * SI;
140- // 2. Invert T using LU decomposition with full pivoting
141- // This is a rank-revealing LU decomposition, this allows us
142- // to test if T is invertible before attempting to invert it.
143- Eigen::FullPivLU<Eigen::MatrixXd> T_LU (fullPCMMatrix_);
144- if (!(T_LU.isInvertible ()))
145- PCMSOLVER_ERROR (" T matrix is not invertible!" );
146- fullPCMMatrix_ = T_LU.inverse ();
147- // 3. Multiply T^-1 and R
148- fullPCMMatrix_ *= (2 * M_PI * aInv - DI);
149- // 4. Multiply by a
150- fullPCMMatrix_ *= a;
151- // 5. Symmetrize K := (K + K+)/2
71+ fullPCMMatrix_ = isotropicIEFMatrix (cav, gf_i, profiles::epsilon (gf_o.permittivity ()));
72+ // Symmetrize K := (K + K+)/2
15273 if (hermitivitize_) {
15374 hermitivitize (fullPCMMatrix_);
15475 }
15576 // Pack into a block diagonal matrix
77+ // The number of irreps in the group
78+ int nrBlocks = cav.pointGroup ().nrIrrep ();
79+ // The size of the irreducible portion of the cavity
80+ int dimBlock = cav.irreducible_size ();
15681 // For the moment just packs into a std::vector<Eigen::MatrixXd>
15782 symmetryPacking (blockPCMMatrix_, fullPCMMatrix_, dimBlock, nrBlocks);
158- std::ofstream matrixOut (" PCM_matrix" );
159- matrixOut << " fullPCMMatrix" << std::endl;
160- matrixOut << fullPCMMatrix_ << std::endl;
161- for (int i = 0 ; i < nrBlocks; ++i) {
162- matrixOut << " Block number " << i << std::endl;
163- matrixOut << blockPCMMatrix_[i] << std::endl;
164- }
16583
16684 built_ = true ;
16785}
0 commit comments