MFEM  v4.5.2
Finite element discretization library
blockvector.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, 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 #include "../general/array.hpp"
13 #include "vector.hpp"
14 #include "blockvector.hpp"
15 
16 namespace mfem
17 {
18 
20 {
21  for (int i = 0; i < numBlocks; ++i)
22  {
23  blocks[i].MakeRef(*this, blockOffsets[i], BlockSize(i));
24  }
25 }
26 
28  Vector(),
29  numBlocks(0),
30  blockOffsets(NULL),
31  blocks(NULL)
32 {
33 
34 }
35 
36 //! Standard constructor
38  Vector(bOffsets.Last()),
39  numBlocks(bOffsets.Size()-1),
40  blockOffsets(bOffsets.GetData())
41 {
42  blocks = new Vector[numBlocks];
43  SetBlocks();
44 }
45 
47  : Vector(bOffsets.Last(), mt),
48  numBlocks(bOffsets.Size()-1),
49  blockOffsets(bOffsets.GetData())
50 {
51  blocks = new Vector[numBlocks];
52  SetBlocks();
53 }
54 
55 //! Copy constructor
57  Vector(v),
58  numBlocks(v.numBlocks),
59  blockOffsets(v.blockOffsets)
60 {
61  blocks = new Vector[numBlocks];
62  SetBlocks();
63 }
64 
65 //! View constructor
66 BlockVector::BlockVector(double *data, const Array<int> & bOffsets):
67  Vector(data, bOffsets.Last()),
68  numBlocks(bOffsets.Size()-1),
69  blockOffsets(bOffsets.GetData())
70 {
71  blocks = new Vector[numBlocks];
72  SetBlocks();
73 }
74 
76  : Vector(),
77  numBlocks(bOffsets.Size()-1),
78  blockOffsets(bOffsets.GetData())
79 {
81  blocks = new Vector[numBlocks];
82  SetBlocks();
83 }
84 
85 void BlockVector::Update(double *data, const Array<int> & bOffsets)
86 {
87  NewDataAndSize(data, bOffsets.Last());
88  blockOffsets = bOffsets.GetData();
89  if (numBlocks != bOffsets.Size()-1)
90  {
91  delete [] blocks;
92  numBlocks = bOffsets.Size()-1;
93  blocks = new Vector[numBlocks];
94  }
95  SetBlocks();
96 }
97 
98 void BlockVector::Update(Vector & data, const Array<int> & bOffsets)
99 {
100  blockOffsets = bOffsets.GetData();
101  if (numBlocks != bOffsets.Size()-1)
102  {
103  delete [] blocks;
104  numBlocks = bOffsets.Size()-1;
105  blocks = new Vector[numBlocks];
106  }
107 
108  for (int i = 0; i < numBlocks; ++i)
109  {
111  }
113 }
114 
115 void BlockVector::Update(const Array<int> &bOffsets)
116 {
117  Update(bOffsets, data.GetMemoryType());
118 }
119 
120 void BlockVector::Update(const Array<int> &bOffsets, MemoryType mt)
121 {
122  blockOffsets = bOffsets.GetData();
123  if (OwnsData() && data.GetMemoryType() == mt)
124  {
125  // check if 'bOffsets' agree with the 'blocks'
126  if (bOffsets.Size() == numBlocks+1)
127  {
128  if (numBlocks == 0) { return; }
129  if (Size() == bOffsets.Last())
130  {
131  for (int i = numBlocks - 1; true; i--)
132  {
133  if (i < 0) { return; }
134  if (blocks[i].Size() != bOffsets[i+1] - bOffsets[i]) { break; }
135  MFEM_ASSERT(blocks[i].GetData() == data + bOffsets[i],
136  "invalid blocks[" << i << ']');
137  }
138  }
139  }
140  }
141  else
142  {
143  Destroy();
144  }
145  SetSize(bOffsets.Last(), mt);
146  if (numBlocks != bOffsets.Size()-1)
147  {
148  delete [] blocks;
149  numBlocks = bOffsets.Size()-1;
150  blocks = new Vector[numBlocks];
151  }
152  SetBlocks();
153 }
154 
156 {
157  if (numBlocks!=original.numBlocks)
158  {
159  mfem_error("Number of Blocks don't match in BlockVector::operator=");
160  }
161 
162  for (int i(0); i <= numBlocks; ++i)
163  {
164  if (blockOffsets[i]!=original.blockOffsets[i])
165  {
166  mfem_error("Size of Blocks don't match in BlockVector::operator=");
167  }
168  }
169 
170  Vector::operator=(original);
171 
172  return *this;
173 }
174 
176 {
177  Vector::operator=(val);
178  return *this;
179 }
180 
181 //! Destructor
183 {
184  delete [] blocks;
185 }
186 
187 void BlockVector::GetBlockView(int i, Vector & blockView)
188 {
189  blockView.MakeRef(*this, blockOffsets[i], BlockSize(i));
190 }
191 
193 {
194  for (int i = 0; i < numBlocks; ++i)
195  {
196  blocks[i].SyncMemory(*this);
197  }
198 }
199 
201 {
202  for (int i = 0; i < numBlocks; ++i)
203  {
204  blocks[i].SyncAliasMemory(*this);
205  }
206 }
207 
208 }
~BlockVector()
Destructor.
int BlockSize(int i)
Definition: blockvector.hpp:97
void NewDataAndSize(double *d, int s)
Set the Vector data and size, deleting the old data, if owned.
Definition: vector.hpp:162
Memory< double > data
Definition: vector.hpp:64
void GetBlockView(int i, Vector &blockView)
Get the i-th vector in the block.
A class to handle Vectors in a block fashion.
Definition: blockvector.hpp:30
void SyncMemory(const Vector &v) const
Update the memory location of the vector to match v.
Definition: vector.hpp:237
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:512
BlockVector()
empty constructor
Definition: blockvector.cpp:27
const int * blockOffsets
Offset for each block start. (length numBlocks+1)
Definition: blockvector.hpp:42
void SyncFromBlocks() const
Synchronize the memory location flags (i.e. the memory validity flags) of the big/monolithic block-ve...
T * GetData()
Returns the data.
Definition: array.hpp:115
int Size() const
Returns the size of the vector.
Definition: vector.hpp:199
void Update(double *data, const Array< int > &bOffsets)
Update method.
Definition: blockvector.cpp:85
Vector & operator=(const double *v)
Copy Size() entries from v.
Definition: vector.cpp:124
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
Definition: error.cpp:154
int numBlocks
Number of blocks in the blockVector.
Definition: blockvector.hpp:35
double * GetData() const
Return a pointer to the beginning of the Vector data.
Definition: vector.hpp:208
BlockVector & operator=(const BlockVector &original)
Assignment operator. this and original must have the same block structure.
MemoryType
Memory types supported by MFEM.
Definition: mem_manager.hpp:31
bool OwnsData() const
Read the Vector data (host pointer) ownership flag.
Definition: vector.hpp:244
void SyncToBlocks() const
Synchronize the memory location flags (i.e. the memory validity flags) of the big/monolithic block-ve...
void SyncAliasMemory(const Vector &v) const
Update the alias memory location of the vector to match v.
Definition: vector.hpp:240
void Destroy()
Destroy a vector.
Definition: vector.hpp:589
int Size() const
Return the logical size of the array.
Definition: array.hpp:141
T & Last()
Return the last element in the array.
Definition: array.hpp:789
Vector data type.
Definition: vector.hpp:60
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
Definition: vector.hpp:576
Vector * blocks
array of Vector objects used to extract blocks without allocating memory.
Definition: blockvector.hpp:45
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...