MFEM  v4.3.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
symmat.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef MFEM_SYMMETRICMAT
13 #define MFEM_SYMMETRICMAT
14 
15 #include "../config/config.hpp"
16 #include "../general/globals.hpp"
17 #include "matrix.hpp"
18 
19 namespace mfem
20 {
21 
22 /// Dense symmetric matrix storing the upper triangular part. This class so far
23 /// has little functionality beyond storage.
25 {
26 private:
27  Memory<double> data;
28 
29 public:
30 
31  /** Default constructor for DenseSymmetricMatrix.
32  Sets data = NULL and height = width = 0. */
34 
35  /// Creates square matrix of size s.
36  explicit DenseSymmetricMatrix(int s);
37 
38  /// Construct a DenseSymmetricMatrix using an existing data array.
39  /** The DenseSymmetricMatrix does not assume ownership of the data array, i.e. it will
40  not delete the array. */
41  DenseSymmetricMatrix(double *d, int s)
42  : Matrix(s, s) { UseExternalData(d, s); }
43 
44  /// Change the data array and the size of the DenseSymmetricMatrix.
45  /** The DenseSymmetricMatrix does not assume ownership of the data array, i.e. it will
46  not delete the data array @a d. This method should not be used with
47  DenseSymmetricMatrix that owns its current data array. */
48  void UseExternalData(double *d, int s)
49  {
50  data.Wrap(d, (s*(s+1))/2, false);
51  height = s; width = s;
52  }
53 
54  /// Change the data array and the size of the DenseSymmetricMatrix.
55  /** The DenseSymmetricMatrix does not assume ownership of the data array, i.e. it will
56  not delete the new array @a d. This method will delete the current data
57  array, if owned. */
58  void Reset(double *d, int s)
59  { if (OwnsData()) { data.Delete(); } UseExternalData(d, s); }
60 
61  /** Clear the data array and the dimensions of the DenseSymmetricMatrix. This method
62  should not be used with DenseSymmetricMatrix that owns its current data array. */
63  void ClearExternalData() { data.Reset(); height = width = 0; }
64 
65  /// Delete the matrix data array (if owned) and reset the matrix state.
66  void Clear()
67  { if (OwnsData()) { data.Delete(); } ClearExternalData(); }
68 
69  /// Change the size of the DenseSymmetricMatrix to s x s.
70  void SetSize(int s);
71 
72  /// Returns the matrix data array.
73  inline double *Data() const
74  { return const_cast<double*>((const double*)data);}
75 
76  /// Returns the matrix data array.
77  inline double *GetData() const { return Data(); }
78 
79  Memory<double> &GetMemory() { return data; }
80  const Memory<double> &GetMemory() const { return data; }
81 
82  /// Return the DenseSymmetricMatrix data (host pointer) ownership flag.
83  inline bool OwnsData() const { return data.OwnsHostPtr(); }
84 
85  /// Returns reference to a_{ij}.
86  inline double &operator()(int i, int j);
87 
88  /// Returns constant reference to a_{ij}.
89  inline const double &operator()(int i, int j) const;
90 
91  /// Returns reference to a_{ij}.
92  virtual double &Elem(int i, int j);
93 
94  /// Returns constant reference to a_{ij}.
95  virtual const double &Elem(int i, int j) const;
96 
97  /// Sets the matrix elements equal to constant c
99 
100  DenseSymmetricMatrix &operator*=(double c);
101 
102  long MemoryUsage() const { return data.Capacity() * sizeof(double); }
103 
104  /// Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
105  const double *Read(bool on_dev = true) const
106  { return mfem::Read(data, Height()*Width(), on_dev); }
107 
108  /// Shortcut for mfem::Read(GetMemory(), TotalSize(), false).
109  const double *HostRead() const
110  { return mfem::Read(data, Height()*Width(), false); }
111 
112  /// Shortcut for mfem::Write(GetMemory(), TotalSize(), on_dev).
113  double *Write(bool on_dev = true)
114  { return mfem::Write(data, Height()*Width(), on_dev); }
115 
116  /// Shortcut for mfem::Write(GetMemory(), TotalSize(), false).
117  double *HostWrite()
118  { return mfem::Write(data, Height()*Width(), false); }
119 
120  /// Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), on_dev).
121  double *ReadWrite(bool on_dev = true)
122  { return mfem::ReadWrite(data, Height()*Width(), on_dev); }
123 
124  /// Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), false).
125  double *HostReadWrite()
126  { return mfem::ReadWrite(data, Height()*Width(), false); }
127 
128  /// Matrix vector multiplication.
129  virtual void Mult(const Vector &x, Vector &y) const;
130 
131  /// Returns a pointer to (an approximation) of the matrix inverse.
132  virtual MatrixInverse *Inverse() const;
133 
134  /// Prints matrix to stream out.
135  virtual void Print (std::ostream & out = mfem::out, int width_ = 4) const;
136 
137  /// Destroys the symmetric matrix.
138  virtual ~DenseSymmetricMatrix();
139 };
140 
141 // Inline methods
142 
143 // The number of entries stored in rows 1,...,k is
144 // n + n-1 + n-2 + ... + n-k+1, where there are k terms. This equals
145 // kn - sum_{i=1}^{k-1} i = kn - (k-1)k/2
146 // This formula is used for the offset for each row.
147 inline double &DenseSymmetricMatrix::operator()(int i, int j)
148 {
149  MFEM_ASSERT(data && i >= 0 && i < height && j >= 0 && j < width, "");
150  if (i > j) // reverse i and j
151  {
152  return data[(j*height) - (((j-1)*j)/2) + i - j];
153  }
154  else
155  {
156  return data[(i*height) - (((i-1)*i)/2) + j - i];
157  }
158 }
159 
160 inline const double &DenseSymmetricMatrix::operator()(int i, int j) const
161 {
162  MFEM_ASSERT(data && i >= 0 && i < height && j >= 0 && j < width, "");
163  if (i > j) // reverse i and j
164  {
165  return data[(j*height) - (((j-1)*j)/2) + i - j];
166  }
167  else
168  {
169  return data[(i*height) - (((i-1)*i)/2) + j - i];
170  }
171 }
172 
173 } // namespace mfem
174 
175 #endif
bool OwnsData() const
Return the DenseSymmetricMatrix data (host pointer) ownership flag.
Definition: symmat.hpp:83
double & operator()(int i, int j)
Returns reference to a_{ij}.
Definition: symmat.hpp:147
double * Write(bool on_dev=true)
Shortcut for mfem::Write(GetMemory(), TotalSize(), on_dev).
Definition: symmat.hpp:113
long MemoryUsage() const
Definition: symmat.hpp:102
void SetSize(int s)
Change the size of the DenseSymmetricMatrix to s x s.
Definition: symmat.cpp:39
void Delete()
Delete the owned pointers. The Memory is not reset by this method, i.e. it will, generally, not be Empty() after this call.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:72
DenseSymmetricMatrix & operator*=(double c)
Definition: symmat.cpp:78
const double * HostRead() const
Shortcut for mfem::Read(GetMemory(), TotalSize(), false).
Definition: symmat.hpp:109
T * Write(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for write access to mem with the mfem::Device&#39;s DeviceMemoryClass, if on_dev = true...
Definition: device.hpp:336
Abstract data type for matrix inverse.
Definition: matrix.hpp:62
virtual void Print(std::ostream &out=mfem::out, int width_=4) const
Prints matrix to stream out.
Definition: symmat.cpp:99
double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), on_dev).
Definition: symmat.hpp:121
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
Definition: symmat.cpp:68
int Capacity() const
Return the size of the allocated memory.
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
Definition: symmat.cpp:88
double * Data() const
Returns the matrix data array.
Definition: symmat.hpp:73
void Wrap(T *ptr, int size, bool own)
Wrap an externally allocated host pointer, ptr with the current host memory type returned by MemoryMa...
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:66
const double * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
Definition: symmat.hpp:105
Abstract data type matrix.
Definition: matrix.hpp:27
DenseSymmetricMatrix(double *d, int s)
Construct a DenseSymmetricMatrix using an existing data array.
Definition: symmat.hpp:41
void UseExternalData(double *d, int s)
Change the data array and the size of the DenseSymmetricMatrix.
Definition: symmat.hpp:48
bool OwnsHostPtr() const
Return true if the host pointer is owned. Ownership indicates whether the pointer will be deleted by ...
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device&#39;s DeviceMemoryClass, if on_dev = true...
Definition: device.hpp:319
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
const Memory< double > & GetMemory() const
Definition: symmat.hpp:80
int height
Dimension of the output / number of rows in the matrix.
Definition: operator.hpp:27
T * ReadWrite(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read+write access to mem with the mfem::Device&#39;s DeviceMemoryClass, if on_dev = true, or the mfem::Device&#39;s HostMemoryClass, otherwise.
Definition: device.hpp:353
virtual MatrixInverse * Inverse() const
Returns a pointer to (an approximation) of the matrix inverse.
Definition: symmat.cpp:93
void Clear()
Delete the matrix data array (if owned) and reset the matrix state.
Definition: symmat.hpp:66
double * HostReadWrite()
Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), false).
Definition: symmat.hpp:125
virtual ~DenseSymmetricMatrix()
Destroys the symmetric matrix.
Definition: symmat.cpp:104
Vector data type.
Definition: vector.hpp:60
RefCoord s[3]
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition: globals.hpp:66
double * HostWrite()
Shortcut for mfem::Write(GetMemory(), TotalSize(), false).
Definition: symmat.hpp:117
DenseSymmetricMatrix & operator=(double c)
Sets the matrix elements equal to constant c.
Definition: symmat.cpp:58
Memory< double > & GetMemory()
Definition: symmat.hpp:79
int width
Dimension of the input / number of columns in the matrix.
Definition: operator.hpp:28
double * GetData() const
Returns the matrix data array.
Definition: symmat.hpp:77
void Reset(double *d, int s)
Change the data array and the size of the DenseSymmetricMatrix.
Definition: symmat.hpp:58