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_QOI_SET_H 21 : #define LIBMESH_QOI_SET_H 22 : 23 : 24 : // Local Includes 25 : #include "libmesh/libmesh_common.h" 26 : 27 : // C++ Includes 28 : #include <vector> 29 : 30 : namespace libMesh 31 : { 32 : 33 : // Forward Declarations 34 : class System; 35 : 36 : /** 37 : * Data structure for specifying which Quantities of Interest 38 : * should be calculated in an adjoint or a parameter sensitivity 39 : * calculation. 40 : * 41 : * \author Roy Stogner 42 : * \date 2009 43 : * \brief Used to specify quantities of interest in a simulation. 44 : */ 45 15840 : class QoISet 46 : { 47 : public: 48 : class iterator 49 : { 50 : public: 51 : iterator(std::size_t i, const std::vector<bool> & v) : _i(i), _vecbool(v) 52 : { 53 : while (_i < _vecbool.size() && !_vecbool[_i]) 54 : _i++; 55 : } 56 : 57 : std::size_t operator*() const { return _i; } 58 : 59 : iterator & operator++() 60 : { 61 : do { 62 : _i++; 63 : } while (_i < _vecbool.size() && !_vecbool[_i]); 64 : return *this; 65 : } 66 : 67 : iterator operator++(int) 68 : { 69 : iterator it = *this; 70 : ++(*this); 71 : return it; 72 : } 73 : 74 : bool operator==(const iterator & other) const 75 : { 76 : libmesh_assert_equal_to (&_vecbool, &other._vecbool); 77 : return _i == other._i; 78 : } 79 : 80 : bool operator!=(const iterator & other) const 81 : { 82 : libmesh_assert_equal_to (&_vecbool, &other._vecbool); 83 : return _i != other._i; 84 : } 85 : 86 : private: 87 : 88 : std::size_t _i; 89 : 90 : const std::vector<bool> & _vecbool; 91 : }; 92 : 93 : /** 94 : * Empty constructor: "calculate all QoIs in the System" 95 : * 96 : * No further changes to this special QoISet should be made; 97 : * it doesn't even know how many QoIs your system has, it 98 : * just knows to instruct a function to use all of them. 99 : */ 100 3536 : QoISet() : _indices(), _weights() {} 101 : 102 : /** 103 : * Default constructor: "calculate all QoIs in the System", 104 : * "give every QoI weight 1.0" 105 : */ 106 : explicit 107 : QoISet(const System & sys); 108 : 109 : /** 110 : * Constructor-from-vector-of-bool: "calculate the QoIs for which 111 : * \p indices[q] is true" 112 : */ 113 : explicit 114 : QoISet(std::vector<bool> indices) : 115 : _indices(std::move(indices)), _weights() {} 116 : 117 : /** 118 : * Constructor-from-vector: "calculate the listed QoIs", "give every 119 : * QoI weight 1.0" 120 : */ 121 : explicit 122 : QoISet(const std::vector<unsigned int> & indices); 123 : 124 : /** 125 : * Resets to "calculate all QoIs, give every QoI weight 1.0" 126 : */ 127 : void clear() { _indices.clear(); _weights.clear(); } 128 : 129 : /** 130 : * \returns The number of QoIs that would be computed for the 131 : * System \p sys 132 : */ 133 : std::size_t size(const System & sys) const; 134 : 135 : /** 136 : * Add this indices to the set to be calculated 137 : */ 138 : void add_indices(const std::vector<unsigned int> & indices); 139 : 140 : /** 141 : * Add this index to the set to be calculated 142 : */ 143 : void add_index(std::size_t); 144 : 145 : /** 146 : * Remove these indices from the set to be calculated 147 : */ 148 : void remove_indices(const std::vector<unsigned int> & indices); 149 : 150 : /** 151 : * Remove this index from the set to be calculated 152 : */ 153 : void remove_index(std::size_t); 154 : 155 : /** 156 : * Set the weight for this index 157 : */ 158 : void set_weight(std::size_t, Real); 159 : 160 : /** 161 : * Get the weight for this index (default 1.0) 162 : */ 163 : Real weight(std::size_t) const; 164 : 165 : /** 166 : * Return whether or not this index is in the set to be calculated 167 : */ 168 : bool has_index(std::size_t) const; 169 : 170 : /** 171 : * Return an iterator pointing to the first index in the set 172 : */ 173 : iterator begin() const { return iterator(0, _indices); } 174 : 175 : private: 176 : /** 177 : * Interpret _indices.empty() to mean "calculate all indices" 178 : */ 179 : std::vector<bool> _indices; 180 : 181 : /** 182 : * Interpret _weights.size() <= i to mean "weight i = 1.0" 183 : */ 184 : std::vector<Real> _weights; 185 : }; 186 : 187 : 188 : 189 : // ------------------------------------------------------------ 190 : // QoISet inline methods 191 : 192 : 193 : 194 : inline 195 : QoISet::QoISet(const std::vector<unsigned int> & indices) : 196 : _indices(), _weights() 197 : { 198 : this->add_indices(indices); 199 : } 200 : 201 : 202 : 203 : inline 204 : void QoISet::add_index(std::size_t i) 205 : { 206 : if (i >= _indices.size()) 207 : _indices.resize(i+1, true); 208 : _indices[i] = true; 209 : } 210 : 211 : 212 : 213 : inline 214 : void QoISet::remove_index(std::size_t i) 215 : { 216 : if (i >= _indices.size()) 217 : _indices.resize(i+1, true); 218 : _indices[i] = false; 219 : } 220 : 221 : 222 : 223 : inline 224 2640081 : bool QoISet::has_index(std::size_t i) const 225 : { 226 2888865 : return (_indices.size() <= i || _indices[i]); 227 : } 228 : 229 : 230 : 231 : inline 232 : void QoISet::set_weight(std::size_t i, Real w) 233 : { 234 : if (_weights.size() <= i) 235 : _weights.resize(i+1, 1.0); 236 : 237 : _weights[i] = w; 238 : } 239 : 240 : 241 : 242 : inline 243 1122 : Real QoISet::weight(std::size_t i) const 244 : { 245 37837 : if (_weights.size() <= i) 246 40 : return 1.0; 247 35315 : return _weights[i]; 248 : } 249 : 250 : } // namespace libMesh 251 : 252 : #endif // LIBMESH_QOI_SET_H