system_norm.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 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 #include "libmesh/enum_norm_type.h"
26 #include "libmesh/system.h"
27 
28 // C++ includes
29 #include <vector>
30 
31 namespace libMesh
32 {
33 
34 // Forward Declarations
35 
46 // ------------------------------------------------------------
47 // SystemNorm class definition
49 {
50 public:
51 
55  SystemNorm();
56 
65  SystemNorm(const FEMNormType &t);
66 
74  explicit
75  SystemNorm(const std::vector<FEMNormType> &norms);
76 
84  SystemNorm(const std::vector<FEMNormType> &norms, std::vector<Real> &weights);
85 
93  SystemNorm(const std::vector<FEMNormType> &norms, std::vector<std::vector<Real> > &weights);
94 
98  SystemNorm(const SystemNorm &s);
99 
103  bool is_discrete() const;
104 
109  Real calculate_norm(const std::vector<Real>& v);
110 
114  Real calculate_norm(const std::vector<Real>& v1, const std::vector<Real>& v2);
115 
119  bool is_identity();
120 
124  FEMNormType type(unsigned int var) const;
125 
129  void set_type(unsigned int var, const FEMNormType& t);
130 
134  Real weight(unsigned int var) const;
135 
139  void set_weight(unsigned int var, Real w);
140 
144  void set_off_diagonal_weight(unsigned int i, unsigned int j, Real w);
145 
150  Real weight_sq(unsigned int var) const;
151 
152 
153 
154 private:
155  std::vector<FEMNormType> _norms;
156 
157  std::vector<Real> _weights;
158  std::vector<Real> _weights_sq;
159 
164  std::vector<std::vector<Real> > _off_diagonal_weights;
165 };
166 
167 
168 
169 // ------------------------------------------------------------
170 // SystemNorm inline methods
171 
172 inline
174  _norms(1, DISCRETE_L2), _weights(1, 1.0), _weights_sq(1, 1.0)
175 {
176 }
177 
178 
179 inline
181  _norms(1, t), _weights(1, 1.0), _weights_sq(1, 1.0)
182 {
183 }
184 
185 
186 inline
187 SystemNorm::SystemNorm(const std::vector<FEMNormType> &norms) :
188  _norms(norms), _weights(1, 1.0), _weights_sq(1, 1.0)
189 {
190  if (_norms.empty())
191  _norms.push_back(DISCRETE_L2);
192 }
193 
194 
195 inline
196 SystemNorm::SystemNorm(const std::vector<FEMNormType> &norms,
197  std::vector<Real> &weights) :
198  _norms(norms), _weights(weights), _weights_sq(_weights.size(), 0.0)
199 {
200  if (_norms.empty())
201  _norms.push_back(DISCRETE_L2);
202 
203  if (_weights.empty())
204  {
205  _weights.push_back(1.0);
206  _weights_sq.push_back(1.0);
207  }
208  else
209  for (std::size_t i=0; i != _weights.size(); ++i)
210  _weights_sq[i] = _weights[i] * _weights[i];
211 }
212 
213 inline
214  SystemNorm::SystemNorm(const std::vector<FEMNormType> &norms,
215  std::vector<std::vector<Real> > &weights):
216  _norms(norms), _weights(weights.size()), _off_diagonal_weights(weights)
217 {
218  if(_norms.empty())
219  _norms.push_back(DISCRETE_L2);
220 
221  if (_weights.empty())
222  {
223  _weights.push_back(1.0);
224  _weights_sq.push_back(1.0);
225  }
226  else
227  {
228  // Loop over the entries of the user provided matrix and store its entries in
229  // the _off_diagonal_weights or _diagonal_weights
230  for(std::size_t i=0; i!=_off_diagonal_weights.size(); ++i)
231  {
232  if(_off_diagonal_weights[i].size() > i)
233  {
234  _weights[i] = _off_diagonal_weights[i][i];
235  _off_diagonal_weights[i][i] = 0;
236  }
237  else
238  _weights[i] = 1.0;
239  }
240  for (std::size_t i=0; i != _weights.size(); ++i)
241  _weights_sq[i] = _weights[i] * _weights[i];
242  }
243 }
244 
245 inline
247  _norms(s._norms), _weights(s._weights), _weights_sq(s._weights_sq)
248 {
249 }
250 
251 
252 inline
254 {
255  libmesh_assert (!_norms.empty());
256 
257  if (_norms[0] == DISCRETE_L1 ||
258  _norms[0] == DISCRETE_L2 ||
259  _norms[0] == DISCRETE_L_INF)
260  return true;
261 
262  return false;
263 }
264 
265 
266 inline
267 FEMNormType SystemNorm::type(unsigned int var) const
268 {
269  libmesh_assert (!_norms.empty());
270 
271  std::size_t i = (var < _norms.size()) ? var : _norms.size() - 1;
272 
273  return _norms[i];
274 }
275 
276 
277 
278 inline
279 void SystemNorm::set_type(unsigned int var, const FEMNormType &t)
280 {
281  libmesh_assert (!_norms.empty());
282 
283  if (var >= _norms.size())
284  _norms.resize(var+1, t);
285 
286  _norms[var] = t;
287 }
288 
289 
290 inline
291 Real SystemNorm::weight(unsigned int var) const
292 {
293  libmesh_assert (!_weights.empty());
294 
295  return (var < _weights.size()) ? _weights[var] : 1.0;
296 }
297 
298 
299 inline
300 void SystemNorm::set_weight(unsigned int var, Real w)
301 {
302  libmesh_assert (!_weights.empty());
303 
304  if (var >= _weights.size())
305  {
306  _weights.resize(var+1, 1.0);
307  _weights_sq.resize(var+1, 1.0);
308  }
309 
310  _weights[var] = w;
311  _weights_sq[var] = w*w;
312 }
313 
314 inline
315  void SystemNorm::set_off_diagonal_weight(unsigned int i, unsigned int j, Real w)
316 {
317  libmesh_assert (!_weights.empty());
318 
319  if (i >= _off_diagonal_weights.size())
320  {
321  _off_diagonal_weights.resize(i+1);
322  }
323 
324  if (j >= _off_diagonal_weights[i].size())
325  {
326  _off_diagonal_weights[i].resize(j+1, 0.);
327  }
328 
329  _off_diagonal_weights[i][j] = w;
330 
331 }
332 
333 
334 inline
335 Real SystemNorm::weight_sq(unsigned int var) const
336 {
337  libmesh_assert (!_weights_sq.empty());
338 
339  return (var < _weights_sq.size()) ? _weights_sq[var] : 1.0;
340 }
341 
342 
343 inline
344 Real SystemNorm::calculate_norm(const std::vector<Real>& v1, const std::vector<Real>& v2)
345 {
346  // The vectors are assumed to both be vectors of the (same number
347  // of) components
348  std::size_t vsize = v1.size();
349  libmesh_assert_equal_to (vsize, v2.size());
350 
351  // We'll support implicitly defining weights, but if the user sets
352  // more weights than he uses then something's probably wrong
353  std::size_t diagsize = this->_weights.size();
354  libmesh_assert_greater_equal (vsize, diagsize);
355 
356  // Initialize the variable val
357  Real val = 0.;
358 
359  // Loop over all the components of the system with explicit
360  // weights
361  for(std::size_t i = 0; i != diagsize; i++)
362  {
363  val += this->_weights[i] * v1[i] * v2[i];
364  }
365  // Loop over all the components of the system with implicit
366  // weights
367  for(std::size_t i = diagsize; i < vsize; i++)
368  {
369  val += v1[i] * v2[i];
370  }
371 
372  // Loop over the components of the system
373  std::size_t nrows = this->_off_diagonal_weights.size();
374  libmesh_assert_less_equal (vsize, nrows);
375 
376  for(std::size_t i = 0; i != nrows; i++)
377  {
378  std::size_t ncols = this->_off_diagonal_weights[i].size();
379  for(std::size_t j=0; j != ncols; j++)
380  {
381  // Note that the diagonal weights here were set to zero
382  // in the constructor
383  val += this->_off_diagonal_weights[i][j] * v1[i] * v2[j];
384  }
385  }
386 
387  return(val);
388  }
389 
390 inline
391 Real SystemNorm::calculate_norm(const std::vector<Real>& v1)
392 {
393  return this->calculate_norm(v1,v1);
394 }
395 
396 inline
398 {
399  std::size_t nrows = this->_off_diagonal_weights.size();
400 
401  // If any of the off-diagonal elements is not 0, then we are in the non-identity case
402  for(std::size_t i = 0; i != nrows; i++)
403  {
404  std::size_t ncols = this->_off_diagonal_weights[i].size();
405  for(std::size_t j = 0; j != ncols; j++)
406  {
407  if(_off_diagonal_weights[i][j] != 0)
408  {
409  return(false);
410  }
411  }
412  }
413 
414  // If any of the diagonal elements is not 1, then we are in the non-identity case
415  nrows = this->_weights.size();
416  for(std::size_t i = 0; i != nrows; i++)
417  if(_weights[i] != 1)
418  return(false);
419 
420  // If all the off-diagonals elements are 0, and diagonal elements 1, then we are in an identity case
421  return(true);
422 }
423 
424 } // namespace libMesh
425 
426 #endif // LIBMESH_SYSTEM_NORM_H

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:07 UTC

Hosted By:
SourceForge.net Logo