MFEM  v4.6.0 Finite element discretization library
symmat.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC. Produced
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  /// Return the number of stored nonzeros in the matrix.
73  int GetStoredSize() const { return Height()*(Height()+1)/2; }
74
75  /// Returns the matrix data array.
76  inline double *Data() const
77  { return const_cast<double*>((const double*)data);}
78
79  /// Returns the matrix data array.
80  inline double *GetData() const { return Data(); }
81
82  Memory<double> &GetMemory() { return data; }
83  const Memory<double> &GetMemory() const { return data; }
84
85  /// Return the DenseSymmetricMatrix data (host pointer) ownership flag.
86  inline bool OwnsData() const { return data.OwnsHostPtr(); }
87
88  /// Returns reference to a_{ij}.
89  inline double &operator()(int i, int j);
90
91  /// Returns constant reference to a_{ij}.
92  inline const double &operator()(int i, int j) const;
93
94  /// Returns reference to a_{ij}.
95  virtual double &Elem(int i, int j);
96
97  /// Returns constant reference to a_{ij}.
98  virtual const double &Elem(int i, int j) const;
99
100  /// Sets the matrix elements equal to constant c
101  DenseSymmetricMatrix &operator=(double c);
102
103  DenseSymmetricMatrix &operator*=(double c);
104
105  std::size_t MemoryUsage() const { return data.Capacity() * sizeof(double); }
106
107  /// Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
108  const double *Read(bool on_dev = true) const
109  { return mfem::Read(data, Height()*Width(), on_dev); }
110
111  /// Shortcut for mfem::Read(GetMemory(), TotalSize(), false).
113  { return mfem::Read(data, Height()*Width(), false); }
114
115  /// Shortcut for mfem::Write(GetMemory(), TotalSize(), on_dev).
116  double *Write(bool on_dev = true)
117  { return mfem::Write(data, Height()*Width(), on_dev); }
118
119  /// Shortcut for mfem::Write(GetMemory(), TotalSize(), false).
120  double *HostWrite()
121  { return mfem::Write(data, Height()*Width(), false); }
122
123  /// Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), on_dev).
124  double *ReadWrite(bool on_dev = true)
125  { return mfem::ReadWrite(data, Height()*Width(), on_dev); }
126
127  /// Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), false).
129  { return mfem::ReadWrite(data, Height()*Width(), false); }
130
131  /// Matrix vector multiplication.
132  virtual void Mult(const Vector &x, Vector &y) const;
133
134  /// Returns a pointer to (an approximation) of the matrix inverse.
135  virtual MatrixInverse *Inverse() const;
136
137  /// Prints matrix to stream out.
138  virtual void Print (std::ostream & out = mfem::out, int width_ = 4) const;
139
140  /// Destroys the symmetric matrix.
141  virtual ~DenseSymmetricMatrix();
142 };
143
144 // Inline methods
145
146 // The number of entries stored in rows 1,...,k is
147 // n + n-1 + n-2 + ... + n-k+1, where there are k terms. This equals
148 // kn - sum_{i=1}^{k-1} i = kn - (k-1)k/2
149 // This formula is used for the offset for each row.
150 inline double &DenseSymmetricMatrix::operator()(int i, int j)
151 {
152  MFEM_ASSERT(data && i >= 0 && i < height && j >= 0 && j < width, "");
153  if (i > j) // reverse i and j
154  {
155  return data[(j*height) - (((j-1)*j)/2) + i - j];
156  }
157  else
158  {
159  return data[(i*height) - (((i-1)*i)/2) + j - i];
160  }
161 }
162
163 inline const double &DenseSymmetricMatrix::operator()(int i, int j) const
164 {
165  MFEM_ASSERT(data && i >= 0 && i < height && j >= 0 && j < width, "");
166  if (i > j) // reverse i and j
167  {
168  return data[(j*height) - (((j-1)*j)/2) + i - j];
169  }
170  else
171  {
172  return data[(i*height) - (((i-1)*i)/2) + j - i];
173  }
174 }
175
176 } // namespace mfem
177
178 #endif
double & operator()(int i, int j)
Returns reference to a_{ij}.
Definition: symmat.hpp:150
double * Write(bool on_dev=true)
Shortcut for mfem::Write(GetMemory(), TotalSize(), on_dev).
Definition: symmat.hpp:116
void SetSize(int s)
Change the size of the DenseSymmetricMatrix to s x s.
Definition: symmat.cpp:32
void Delete()
Delete the owned pointers and reset the Memory object.
DenseSymmetricMatrix & operator*=(double c)
Definition: symmat.cpp:71
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:72
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
Definition: symmat.hpp:124
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
Definition: symmat.cpp:61
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 GetStoredSize() const
Return the number of stored nonzeros in the matrix.
Definition: symmat.hpp:73
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 OwnsData() const
Return the DenseSymmetricMatrix data (host pointer) ownership flag.
Definition: symmat.hpp:86
double * GetData() const
Returns the matrix data array.
Definition: symmat.hpp:80
int Capacity() const
Return the size of the allocated memory.
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Definition: device.hpp:319
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
virtual void Print(std::ostream &out=mfem::out, int width_=4) const
Prints matrix to stream out.
Definition: symmat.cpp:92
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
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:66
int height
Dimension of the output / number of rows in the matrix.
Definition: operator.hpp:27
const double * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
Definition: symmat.hpp:108
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
Definition: symmat.cpp:81
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
void Clear()
Delete the matrix data array (if owned) and reset the matrix state.
Definition: symmat.hpp:66
Definition: symmat.hpp:128
virtual ~DenseSymmetricMatrix()
Destroys the symmetric matrix.
Definition: symmat.cpp:97
std::size_t MemoryUsage() const
Definition: symmat.hpp:105
Definition: symmat.hpp:112
bool OwnsHostPtr() const
Return true if the host pointer is owned. Ownership indicates whether the pointer will be deleted by ...
Vector data type.
Definition: vector.hpp:58
RefCoord s[3]
const Memory< double > & GetMemory() const
Definition: symmat.hpp:83
virtual MatrixInverse * Inverse() const
Returns a pointer to (an approximation) of the matrix inverse.
Definition: symmat.cpp:86
double * HostWrite()
Shortcut for mfem::Write(GetMemory(), TotalSize(), false).
Definition: symmat.hpp:120
DenseSymmetricMatrix & operator=(double c)
Sets the matrix elements equal to constant c.
Definition: symmat.cpp:51
double * Data() const
Returns the matrix data array.
Definition: symmat.hpp:76
Memory< double > & GetMemory()
Definition: symmat.hpp:82
int width
Dimension of the input / number of columns in the matrix.
Definition: operator.hpp:28
void Reset(double *d, int s)
Change the data array and the size of the DenseSymmetricMatrix.
Definition: symmat.hpp:58