fix(poly): fixed -M bug in form
MFEM MixedVectorWeakDivergenceIntegrator is actually already -M in our derivation, I have negated this so that Mform -> M directly
This commit is contained in:
@@ -44,7 +44,14 @@ struct solverBundle {
|
||||
mfem::NewtonSolver newton; // Must be second so that when it is destroyed the solver is still alive preventing a double delete
|
||||
};
|
||||
|
||||
class PolySolver {
|
||||
struct formBundle {
|
||||
std::unique_ptr<mfem::MixedBilinearForm> M;
|
||||
std::unique_ptr<mfem::MixedBilinearForm> Q;
|
||||
std::unique_ptr<mfem::BilinearForm> D;
|
||||
std::unique_ptr<mfem::NonlinearForm> f;
|
||||
};
|
||||
|
||||
class PolySolver final{
|
||||
public: // Public methods
|
||||
PolySolver(const double n, const double order);
|
||||
~PolySolver();
|
||||
@@ -76,9 +83,96 @@ private: // Private Attributes
|
||||
|
||||
std::unique_ptr<mfem::OperatorJacobiSmoother> m_prec;
|
||||
|
||||
std::unique_ptr<mfem::VectorConstantCoefficient> m_negationCoeff;
|
||||
|
||||
|
||||
private: // Private methods
|
||||
void assembleBlockSystem();
|
||||
|
||||
/**
|
||||
* @breif Compute the block offsets for the operator. These are the offsets that define which dofs belong to which variable.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* Create the block offsets. These define the start of each block in the combined vector.
|
||||
* Block offsets will be [0, thetaDofs, thetaDofs + phiDofs].
|
||||
* The interpretation of this is that each block tells the operator where in the flattned (1D) vector
|
||||
* the degrees of freedom or coefficients for that free parameter start and end. I.e.
|
||||
* we know that in any flattened vector will have a size thetaDofs + phiDofs. The theta dofs will span
|
||||
* from blockOffsets[0] -> blockOffsets[1] and the phiDofs will span from blockOffsets[1] -> blockOffsets[2].
|
||||
*
|
||||
* This is the same for matrices only in 2D (rows and columns)
|
||||
*
|
||||
* The key point here is that this is fundamentally an accounting structure, it is here to keep track of what
|
||||
* parts of vectors and matrices belong to which variable.
|
||||
*
|
||||
* Also note that we use VSize rather than Size. Size referees to the number of true dofs. That is the dofs which
|
||||
* still are present in the system after eliminating boundary conditions. This is the wrong size to use if we are
|
||||
* trying to account for the true size of the system. VSize on the other hand refers to the total number of dofs.
|
||||
*
|
||||
* @return blockOffsets The offsets for the blocks in the operator
|
||||
*/
|
||||
mfem::Array<int> computeBlockOffsets() const;
|
||||
|
||||
/**
|
||||
* @breif Build the individual forms for the block operator (M, Q, D, and f)
|
||||
*
|
||||
* @param blockOffsets The offsets for the blocks in the operator
|
||||
* @param Mform The mixed bilinear form for the mass matrix
|
||||
* @param Qform The mixed bilinear form for the gradient matrix
|
||||
* @param Dform The bilinear form for the divergence matrix
|
||||
* @param fform The nonlinear form for the source term
|
||||
*
|
||||
* @note These forms are build exactly how they are defined in the derivation. This means that Mform -> M not -M and Qform -> Q not -Q.
|
||||
*
|
||||
* @details
|
||||
* Computes the block offsets
|
||||
* \f$\{0,\;|\theta|,\;|\theta|+|\phi|\}\f$, then builds and finalizes
|
||||
* the MixedBilinearForms \c Mform, \c Qform and the BilinearForm \c Dform,
|
||||
* plus the NonlinearForm \c fform. Finally, these are handed off to
|
||||
* \c PolytropeOperator along with the offsets.
|
||||
*
|
||||
* The discretized weak form is
|
||||
* \f[
|
||||
* R(X)
|
||||
* = \begin{pmatrix}
|
||||
* f(\theta) - M\,\theta \\[6pt]
|
||||
* D\,\theta - Q\,\phi
|
||||
* \end{pmatrix}
|
||||
* = \mathbf{0},
|
||||
* \f]
|
||||
* with
|
||||
* \f[
|
||||
* M = \int \nabla\psi^\theta \;\cdot\; N^\phi \,dV,\quad
|
||||
* D = \int \psi^\phi \;\cdot\; N^\phi \,dV,
|
||||
* \quad
|
||||
* Q = \int \psi^\phi \;\cdot\; \nabla N^\theta \,dV,
|
||||
* \quad
|
||||
* f(\theta) = \int \psi^\theta \;\cdot\; \theta^n \,dV.
|
||||
* \f]
|
||||
*
|
||||
* @note MFEM’s MixedVectorWeakDivergenceIntegrator implements
|
||||
* \f$ -\nabla\!\cdot \f$, so we supply a –1 coefficient to make
|
||||
* `Mform` represent the +M from the derivation. The single negation
|
||||
* in `PolytropeOperator` then restores the final block sign.
|
||||
*
|
||||
|
||||
*
|
||||
* @pre \c m_feTheta and \c m_fePhi must be valid, populated FiniteElementSpaces.
|
||||
* @post \c m_polytropOperator is constructed with assembled forms and offsets.
|
||||
*
|
||||
*/
|
||||
std::unique_ptr<formBundle> buildIndividualForms(const mfem::Array<int>& blockOffsets);
|
||||
|
||||
/**
|
||||
* @brief Assemble and finalize the form (Must be a form that can be assembled and finalized)
|
||||
*
|
||||
* @param f form which is to be assembled and finalized
|
||||
*
|
||||
* @pre f is a valid form that can be assembled and finalized (Such as Bilinear or MixedBilinearForm)
|
||||
* @post f is assembled and finalized
|
||||
*/
|
||||
static void assembleAndFinalizeForm(auto &f);
|
||||
SSE::MFEMArrayPairSet getEssentialTrueDof() const;
|
||||
std::pair<mfem::Array<int>, mfem::Array<int>> findCenterElement() const;
|
||||
void setInitialGuess() const;
|
||||
@@ -89,4 +183,6 @@ private: // Private methods
|
||||
void LoadSolverUserParams(double &newtonRelTol, double &newtonAbsTol, int &newtonMaxIter, int &newtonPrintLevel,
|
||||
double &gmresRelTol, double &gmresAbsTol, int &gmresMaxIter, int &gmresPrintLevel) const;
|
||||
|
||||
void GetDofCoordinates(mfem::FiniteElementSpace &fes, const std::string& filename) const;
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user