Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : 19 : 20 : #ifndef LIBMESH_SYSTEM_NORM_H 21 : #define LIBMESH_SYSTEM_NORM_H 22 : 23 : // Local includes 24 : #include "libmesh/libmesh_common.h" // for Real 25 : 26 : // C++ includes 27 : #include <vector> 28 : 29 : namespace libMesh 30 : { 31 : 32 : // Forward declarations 33 : enum FEMNormType : int; 34 : 35 : /** 36 : * This class defines a norm/seminorm to be applied to a NumericVector which 37 : * contains coefficients in a finite element space. 38 : * 39 : * Discrete vector norms and weighted l2 combinations of Sobolev norms and 40 : * seminorms are representable. 41 : * 42 : * For ease of use, if a norm or weight is queried for variable n but 43 : * has not been set for variable n, then the norm or weight set for 44 : * the highest-numbered variable below n is returned. 45 : * 46 : * \author Roy H. Stogner 47 : * \date 2008 48 : */ 49 2628 : class SystemNorm 50 : { 51 : public: 52 : 53 : /** 54 : * Constructor, defaults to DISCRETE_L2 with weight of 1.0. 55 : */ 56 : SystemNorm(); 57 : 58 : /** 59 : * Constructor, for discrete vector norms, systems with one variable, 60 : * and systems for which the same norm type should be used with a 61 : * weight of one on each variable. 62 : * 63 : * This is deliberately an implicit constructor; we want user code 64 : * to be able to include lines like "error_norm = L2" 65 : */ 66 : SystemNorm(const FEMNormType & t); 67 : 68 : /** 69 : * Constructor, for unweighted sobolev norms on systems with multiple 70 : * variables. 71 : * 72 : * For a system with n variables, the final norm will be the l2 norm of the 73 : * n-vector of the norms in each variable. 74 : */ 75 : explicit 76 : SystemNorm(std::vector<FEMNormType> norms); 77 : 78 : /** 79 : * Constructor, for weighted sobolev norms on systems with multiple 80 : * variables. 81 : * 82 : * For a system with n variables, the final norm will be the l2 norm of the 83 : * n-vector of the norms in each variable, each multiplied by weight. 84 : */ 85 : SystemNorm(std::vector<FEMNormType> norms, 86 : std::vector<Real> & weights); 87 : 88 : /** 89 : * Constructor, for weighted sobolev norms on systems with multiple 90 : * variables and their adjoints 91 : * 92 : * For a system with n variables, the final norm computed will be of the form 93 : * norm_u^T*R*norm_z where R is a scaling matrix 94 : */ 95 : SystemNorm(std::vector<FEMNormType> norms, 96 : std::vector<std::vector<Real>> & weights); 97 : 98 : /** 99 : * Copy/move ctor, copy/move assignment operator, and destructor are 100 : * all explicitly defaulted for this simple class. 101 : */ 102 2800 : SystemNorm (const SystemNorm &) = default; 103 : SystemNorm (SystemNorm &&) = default; 104 2640 : SystemNorm & operator= (const SystemNorm &) = default; 105 40768 : SystemNorm & operator= (SystemNorm &&) = default; 106 2902 : virtual ~SystemNorm() = default; 107 : 108 : /** 109 : * \returns \p true if this is purely a discrete norm 110 : */ 111 : bool is_discrete() const; 112 : 113 : /** 114 : * \returns The weighted norm v^T*W*v where W represents our 115 : * weights matrix or weights vector times identity matrix. 116 : */ 117 : Real calculate_norm(const std::vector<Real> & v); 118 : 119 : /** 120 : * \returns The weighted inner product v1^T*W*v2 where R is our weights 121 : */ 122 : Real calculate_norm(const std::vector<Real> & v1, 123 : const std::vector<Real> & v2); 124 : 125 : /** 126 : * \returns \p true if no weight matrix W is specified or an identity matrix is specified, otherwise returns false 127 : */ 128 : bool is_identity(); 129 : 130 : /** 131 : * \returns The type of the norm in variable \p var 132 : * 133 : * If no norm has been explicitly set for \p var, then the 134 : * highest-index norm explicitly set is returned, or DISCRETE_L2 135 : * is returned if no norms have been explicitly set. 136 : */ 137 : FEMNormType type(unsigned int var) const; 138 : 139 : /** 140 : * Sets the type of the norm in variable \p var, as well as for any 141 : * unset variables with index less than \p var 142 : */ 143 : void set_type(unsigned int var, const FEMNormType & t); 144 : 145 : /** 146 : * \returns The weight corresponding to the norm in variable \p var 147 : * 148 : * If no weight has been explicitly set for \p var, then the 149 : * highest-index weight explicitly set is returned, or 1.0 is 150 : * returned if no weights have been explicitly set. 151 : */ 152 : Real weight(unsigned int var) const; 153 : 154 : /** 155 : * Sets the weight corresponding to the norm in variable \p var, as 156 : * well as for any unset variables with index less than \p var. 157 : */ 158 : void set_weight(unsigned int var, Real w); 159 : 160 : /** 161 : * Sets the weight corresponding to the norm from the variable pair v1(var1) coming from v2(var2). See calculate_norm 162 : */ 163 : void set_off_diagonal_weight(unsigned int i, unsigned int j, Real w); 164 : 165 : /** 166 : * \returns The squared weight corresponding to the norm in variable 167 : * \p var. We cache that at construction time to save a few flops. 168 : */ 169 : Real weight_sq(unsigned int var) const; 170 : 171 : 172 : 173 : private: 174 : std::vector<FEMNormType> _norms; 175 : 176 : std::vector<Real> _weights; 177 : std::vector<Real> _weights_sq; 178 : 179 : /** 180 : * One more data structure needed to store the off diagonal 181 : * components for the generalize SystemNorm case 182 : */ 183 : std::vector<std::vector<Real>> _off_diagonal_weights; 184 : }; 185 : 186 : } // namespace libMesh 187 : 188 : #endif // LIBMESH_SYSTEM_NORM_H