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_PARAMETER_ACCESSOR_H 21 : #define LIBMESH_PARAMETER_ACCESSOR_H 22 : 23 : 24 : // Local Includes 25 : #include "libmesh/libmesh_common.h" 26 : #include "libmesh/compare_types.h" // remove_const 27 : 28 : // C++ includes 29 : #include <memory> 30 : 31 : namespace libMesh 32 : { 33 : 34 : // Forward declarations 35 : template <typename T> 36 : class ParameterProxy; 37 : 38 : template <typename T> 39 : class ConstParameterProxy; 40 : 41 : 42 : /** 43 : * Accessor object allowing reading and modification of the 44 : * independent variables in a parameter sensitivity calculation. 45 : * 46 : * This is an abstract base class. Derived objects may simply modify 47 : * the parameter value at some address in memory, or may call 48 : * arbitrary setter/getter functions. 49 : * 50 : * \author Roy Stogner 51 : * \date 2015 52 : * \brief Base class for reading/writing sensitivity parameters. 53 : */ 54 : template <typename T=Number> 55 : class ParameterAccessor 56 : { 57 : public: 58 : /** 59 : * Virtual destructor - we'll be deleting subclasses from 60 : * pointers-to-ParameterAccessor 61 : */ 62 0 : virtual ~ParameterAccessor() = default; 63 : 64 : /** 65 : * Setter: change the value of the parameter we access. 66 : */ 67 : virtual void set (const T & new_value) = 0; 68 : 69 : /** 70 : * Getter: get the value of the parameter we access. 71 : */ 72 : virtual const T & get () const = 0; 73 : 74 : /** 75 : * Proxy: for backward compatibility, we allow codes to treat a 76 : * ParameterAccessor as if it were a simple pointer-to-value. We 77 : * can't safely allow "Number * n = parameter_vector[p]" to compile, 78 : * but we can allow "*parameter_vector[p] += deltap" to work. 79 : */ 80 160 : ParameterProxy<T> operator* () { return ParameterProxy<T>(*this); } 81 : 82 0 : ConstParameterProxy<T> operator* () const { return ConstParameterProxy<T>(*this); } 83 : 84 : /** 85 : * \returns A new copy of the accessor. The new copy should probably 86 : * be as shallow as possible, but should still access the same 87 : * parameter. 88 : */ 89 : virtual std::unique_ptr<ParameterAccessor<T>> clone() const = 0; 90 : }; 91 : 92 : template <typename T=Number> 93 : class ParameterProxy 94 : { 95 : public: 96 : /** 97 : * Constructor: which parameter are we a proxy for? 98 : */ 99 160 : ParameterProxy (ParameterAccessor<T> & accessor) 100 160 : : _accessor(accessor) {} 101 : 102 : /** 103 : * Default Copy Constructor works 104 : */ 105 : ParameterProxy (const ParameterProxy<T> & accessor) = default; 106 : 107 : /** 108 : * Setter: change the value of the parameter we access. 109 : */ 110 36190 : ParameterProxy & operator = (const T & new_value) { _accessor.set(new_value); return *this; } 111 : 112 : /** 113 : * Setter: change the value of the parameter we access. 114 : */ 115 : ParameterProxy & operator = (const ParameterProxy<T> & new_value) { _accessor.set(new_value._accessor.get()); return *this; } 116 : 117 : /** 118 : * Setter: change the value of the parameter we access. 119 : */ 120 0 : ParameterProxy & operator = (const ConstParameterProxy<T> & new_value) { _accessor.set(new_value.get()); return *this; } 121 : 122 : /** 123 : * Setter: change the value of the parameter we access. 124 : */ 125 0 : ParameterProxy & operator += (const T & value_increment) { _accessor.set(_accessor.get() + value_increment); return *this; } 126 : 127 : /** 128 : * Setter: change the value of the parameter we access. 129 : */ 130 7430 : ParameterProxy & operator -= (const T & value_decrement) { _accessor.set(_accessor.get() - value_decrement); return *this; } 131 : 132 : /** 133 : * Setter: change the value of the parameter we access. 134 : */ 135 0 : ParameterProxy & operator *= (const T & value_multiplier) { _accessor.set(_accessor.get() * value_multiplier); return *this; } 136 : 137 : /** 138 : * Setter: change the value of the parameter we access. 139 : */ 140 : ParameterProxy & operator /= (const T & value_divisor) { _accessor.set(_accessor.get() / value_divisor); return *this; } 141 : 142 : /** 143 : * Getter: get the value of the parameter we access. 144 : */ 145 14476 : operator T () const { return _accessor.get(); } 146 : 147 : /** 148 : * Getter: get the value of the parameter we access. 149 : */ 150 : T get() const { return _accessor.get(); } 151 : 152 : #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION 153 : operator boost::multiprecision::backends::float128_backend () const { return _accessor.get().backend(); } 154 : #endif 155 : 156 : private: 157 : ParameterAccessor<T> & _accessor; 158 : }; 159 : 160 : 161 : template <typename T=Number> 162 : class ConstParameterProxy 163 : { 164 : public: 165 : /** 166 : * Constructor: which parameter are we a proxy for? 167 : */ 168 0 : ConstParameterProxy (const ParameterAccessor<T> & accessor) 169 0 : : _accessor(accessor) {} 170 : 171 : /** 172 : * Getter: get the value of the parameter we access. 173 : */ 174 0 : operator T () const { return _accessor.get(); } 175 : 176 : /** 177 : * Getter: get the value of the parameter we access. 178 : */ 179 0 : T get() const { return _accessor.get(); } 180 : 181 : #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION 182 : operator boost::multiprecision::backends::float128_backend () const { return _accessor.get().backend(); } 183 : #endif 184 : 185 : private: 186 : const ParameterAccessor<T> & _accessor; 187 : }; 188 : 189 : 190 : } // namespace libMesh 191 : 192 : #endif // LIBMESH_PARAMETER_ACCESSOR_H