LCOV - code coverage report
Current view: top level - include/problems - NavierStokesProblem.h (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: ba1ead Lines: 3 3 100.0 %
Date: 2025-08-13 06:50:25 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include "FEProblem.h"
      13             : #include "libmesh/libmesh_config.h"
      14             : #include <petscsnes.h>
      15             : 
      16             : class NonlinearSystem;
      17             : 
      18             : /**
      19             :  * A problem that handles Schur complement preconditioning of the incompressible Navier-Stokes
      20             :  * equations
      21             :  */
      22             : class NavierStokesProblem : public FEProblem
      23             : {
      24             : public:
      25             :   static InputParameters validParams();
      26             : 
      27             :   NavierStokesProblem(const InputParameters & parameters);
      28             : 
      29             : #if PETSC_RELEASE_GREATER_EQUALS(3, 20, 0)
      30             :   /**
      31             :    * @returns the mass matrix tag ID
      32             :    */
      33        1906 :   TagID massMatrixTagID() const { return getMatrixTagID(_mass_matrix); }
      34             : 
      35             :   /**
      36             :    * @returns the poisson operator matrix tag ID
      37             :    */
      38          42 :   TagID LMatrixTagID() const { return getMatrixTagID(_L_matrix); }
      39             : 
      40             :   /**
      41             :    * Clear the field split index sets
      42             :    */
      43        1906 :   void clearIndexSets() { _index_sets.clear(); }
      44             : 
      45             :   /*
      46             :    * Given a \p KSP \p node and where we are in the field split tree, given by \p tree_position,
      47             :    * return the next \p KSP object in the tree on the way to the Schur complement \p KSP object.
      48             :    * Each invocation of this method moves through one level of our \p _index_sets data member. This
      49             :    * method will call itself recursively until it reaches the Schur complement \p KSP
      50             :    */
      51             :   KSP findSchurKSP(KSP node, unsigned int tree_position);
      52             : 
      53             :   /**
      54             :    * Setup the Least Squares Commutator (LSC) preconditioner given the Schur complement \p KSP
      55             :    * object
      56             :    */
      57             :   void setupLSCMatrices(KSP schur_ksp);
      58             : 
      59             :   /**
      60             :    * Will destroy any matrices we allocated
      61             :    */
      62             :   virtual ~NavierStokesProblem();
      63             : 
      64             : protected:
      65             :   /**
      66             :    * Reinitialize PETSc output for proper linear/nonlinear iteration display
      67             :    */
      68             :   virtual void initPetscOutputAndSomeSolverSettings() override;
      69             : 
      70             : private:
      71             :   /// Whether to commute operators in the style of Olshanskii. If this is true, then the user must
      72             :   /// provide both (pressure) mass matrices and a Poisson operator for the velocity
      73             :   const bool _commute_lsc;
      74             :   /// The tag name of the mass matrix
      75             :   const TagName & _mass_matrix;
      76             :   /// The tag name of the Poisson operator
      77             :   const TagName & _L_matrix;
      78             :   /// Whether the user attached a mass matrix
      79             :   const bool _have_mass_matrix;
      80             :   /// Whether the user attached a Poisson operator matrix
      81             :   const bool _have_L_matrix;
      82             : 
      83             :   /// Whether to directly use the pressure mass matrix to form the Schur complement
      84             :   /// preconditioner. This is only appropriate for Stokes flow in which the pressure mass matrix is
      85             :   /// spectrally equivalent to the Schur complement
      86             :   const bool _pressure_mass_matrix_as_pre;
      87             : 
      88             :   /// The length of this vector should correspond to the number of split nesting levels there are in
      89             :   /// the field split. Then the integers should indicate the path one shold take in the nesting tree
      90             :   /// to get to the location of the Schur complement field split
      91             :   const std::vector<unsigned int> & _schur_fs_index;
      92             : 
      93             :   /// The mass matrix used for scaling
      94             :   Mat _Q_scale = nullptr;
      95             :   /// The Poisson operator
      96             :   Mat _L = nullptr;
      97             : 
      98             :   /// This will end up being the same length as \p _schur_fs_index. Let's give an example of what
      99             :   /// this data member means. If the user sets "schur_fs_index = '1'", then this means the Schur
     100             :   /// complement field split is nested within another field split, and the Schur complement field
     101             :   /// split is at the 1st index of the top split (some other set of degrees of freedom take up the
     102             :   /// 0th index of the top split). So in this example \p _index_sets will be of length 1, and the
     103             :   /// Index Set (IS) held by this container will hold all the Schur complement field split degrees
     104             :   /// of freedom (e.g. all the system degrees of freedom minus the degrees of freedom held in the
     105             :   /// 0th index of the top split). An example of this example is if we split out all the velocity
     106             :   /// Dirichlet degrees of freedom into the 0th index of the top split, and then our Schur
     107             :   /// complement at index 1 of the top split handles all non-Dirichlet velocity degrees of freedom
     108             :   /// and all pressure degrees of freedom
     109             :   std::vector<IS> _index_sets;
     110             : #endif
     111             : };

Generated by: LCOV version 1.14