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_RAW_ACCESSOR_H
21 : #define LIBMESH_RAW_ACCESSOR_H
22 :
23 : // Local includes
24 : #include "libmesh/libmesh_common.h"
25 :
26 : #include "libmesh/tensor_value.h"
27 : #include "libmesh/vector_value.h"
28 : #include "libmesh/type_n_tensor.h"
29 :
30 : namespace libMesh
31 : {
32 :
33 : /**
34 : * What underlying data type would we need to access in each field?
35 : */
36 : template <typename FieldType>
37 : struct RawFieldType {};
38 :
39 : template <>
40 : struct RawFieldType<Number>
41 : {
42 : typedef Number type;
43 : };
44 :
45 : template <>
46 : struct RawFieldType<Gradient>
47 : {
48 : typedef Number type;
49 : };
50 :
51 : template <>
52 : struct RawFieldType<Tensor>
53 : {
54 : typedef Number type;
55 : };
56 :
57 : template<>
58 : struct RawFieldType<TypeNTensor<3, Number>>
59 : {
60 : typedef Number type;
61 : };
62 :
63 : #ifdef LIBMESH_USE_COMPLEX_NUMBERS
64 : template <>
65 : struct RawFieldType<Real>
66 : {
67 : typedef Real type;
68 : };
69 :
70 : template <>
71 : struct RawFieldType<RealGradient>
72 : {
73 : typedef Real type;
74 : };
75 :
76 : template <>
77 : struct RawFieldType<RealTensor>
78 : {
79 : typedef Real type;
80 : };
81 :
82 : template<>
83 : struct RawFieldType<TypeNTensor<3, Real>>
84 : {
85 : typedef Real type;
86 : };
87 : #endif
88 :
89 : /**
90 : * This class provides single index access to FieldType (i.e. Number, Gradient, Tensor, etc.).
91 : */
92 : template <typename FieldType>
93 : class RawAccessor
94 : {
95 : public:
96 :
97 5637223 : RawAccessor(FieldType & data, const unsigned int dim)
98 : : _data(data),
99 5637223 : _dim(dim)
100 5637223 : {}
101 :
102 : ~RawAccessor() = default;
103 :
104 : typename RawFieldType<FieldType>::type & operator()( unsigned int i );
105 : const typename RawFieldType<FieldType>::type & operator()( unsigned int i ) const;
106 :
107 : private:
108 : RawAccessor();
109 :
110 : FieldType & _data;
111 : const unsigned int _dim;
112 : };
113 :
114 : // Specialize for specific cases
115 : template<>
116 : inline
117 1055650 : Number & RawAccessor<Number>::operator()( unsigned int libmesh_dbg_var(i) )
118 : {
119 1055650 : libmesh_assert_equal_to (i, 0);
120 1055650 : return this->_data;
121 : }
122 :
123 : template<>
124 : inline
125 5580600 : Number & RawAccessor<Gradient>::operator()( unsigned int i )
126 : {
127 5580600 : libmesh_assert_less (i, this->_dim);
128 5580600 : return this->_data(i);
129 : }
130 :
131 : template<>
132 : inline
133 7908415 : Number & RawAccessor<Tensor>::operator()( unsigned int k )
134 : {
135 7908415 : libmesh_assert_less (k, this->_dim*this->_dim);
136 :
137 : // For tensors, each row is filled first, i.e. for 2-D
138 : // [ 0 1; 2 3]
139 : // Thus, k(i,j) = j + i*dim
140 14029995 : unsigned int ii = k/_dim;
141 15261586 : unsigned int jj = k - ii*_dim;
142 :
143 7908415 : return this->_data(ii,jj);
144 : }
145 :
146 : /**
147 : * Stub implementations for stub TypeNTensor object
148 : */
149 : template <unsigned int N, typename ScalarType>
150 : class RawAccessor<TypeNTensor<N, ScalarType>>
151 : {
152 : public:
153 :
154 : typedef TypeNTensor<N, ScalarType> FieldType;
155 :
156 887369 : RawAccessor(FieldType & data, const unsigned int dim)
157 : : _data(data),
158 887369 : _dim(dim)
159 887369 : {}
160 :
161 : ~RawAccessor() = default;
162 :
163 0 : typename RawFieldType<FieldType>::type & operator()( unsigned int /*i*/ )
164 0 : { return dummy; }
165 :
166 : const typename RawFieldType<FieldType>::type & operator()( unsigned int /*i*/ ) const
167 : { return dummy; }
168 :
169 : private:
170 : RawAccessor();
171 :
172 : ScalarType dummy = 0;
173 :
174 : FieldType & _data;
175 : const unsigned int _dim;
176 : };
177 :
178 : #ifdef LIBMESH_USE_COMPLEX_NUMBERS
179 : template<>
180 : inline
181 : Real & RawAccessor<Real>::operator()( unsigned int libmesh_dbg_var(i) )
182 : {
183 : libmesh_assert_equal_to (i, 0);
184 : return this->_data;
185 : }
186 :
187 : template<>
188 : inline
189 : Real & RawAccessor<RealGradient>::operator()( unsigned int i )
190 : {
191 : libmesh_assert_less (i, this->_dim);
192 : return this->_data(i);
193 : }
194 :
195 : template<>
196 : inline
197 : Real & RawAccessor<RealTensor>::operator()( unsigned int k )
198 : {
199 : libmesh_assert_less (k, this->_dim*this->_dim);
200 :
201 : // For tensors, each row is filled first, i.e. for 2-D
202 : // [ 0 1; 2 3]
203 : // Thus, k(i,j) = i + j*dim
204 : unsigned int jj = k/_dim;
205 : unsigned int ii = k - jj*_dim;
206 :
207 : return this->_data(ii,jj);
208 : }
209 :
210 : #endif
211 :
212 : }
213 : #endif // LIBMESH_RAW_ACCESSOR_H
|