MFEM  v4.6.0
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 BlockVector::BlockVector(Vector &v, int offset, const Array<int> &bOffsets)
86  : Vector(),
87  numBlocks(bOffsets.Size()-1),
88  blockOffsets(bOffsets.GetData())
89 {
90  MakeRef(v, offset, blockOffsets[numBlocks]);
91  blocks = new Vector[numBlocks];
92  SetBlocks();
93 }
94 
95 void BlockVector::Update(double *data, const Array<int> & bOffsets)
96 {
97  NewDataAndSize(data, bOffsets.Last());
98  blockOffsets = bOffsets.GetData();
99  if (numBlocks != bOffsets.Size()-1)
100  {
101  delete [] blocks;
102  numBlocks = bOffsets.Size()-1;
103  blocks = new Vector[numBlocks];
104  }
105  SetBlocks();
106 }
107 
108 void BlockVector::Update(Vector & data, const Array<int> & bOffsets)
109 {
110  blockOffsets = bOffsets.GetData();
111  if (numBlocks != bOffsets.Size()-1)
112  {
113  delete [] blocks;
114  numBlocks = bOffsets.Size()-1;
115  blocks = new Vector[numBlocks];
116  }
117 
118  for (int i = 0; i < numBlocks; ++i)
119  {
121  }
123 }
124 
125 void BlockVector::Update(const Array<int> &bOffsets)
126 {
127  Update(bOffsets, data.GetMemoryType());
128 }
129 
130 void BlockVector::Update(const Array<int> &bOffsets, MemoryType mt)
131 {
132  blockOffsets = bOffsets.GetData();
133  if (OwnsData() && data.GetMemoryType() == mt)
134  {
135  // check if 'bOffsets' agree with the 'blocks'
136  if (bOffsets.Size() == numBlocks+1)
137  {
138  if (numBlocks == 0) { return; }
139  if (Size() == bOffsets.Last())
140  {
141  for (int i = numBlocks - 1; true; i--)
142  {
143  if (i < 0) { return; }
144  if (blocks[i].Size() != bOffsets[i+1] - bOffsets[i]) { break; }
145  MFEM_ASSERT(blocks[i].GetData() == data + bOffsets[i],
146  "invalid blocks[" << i << ']');
147  }
148  }
149  }
150  }
151  else
152  {
153  Destroy();
154  }
155  SetSize(bOffsets.Last(), mt);
156  if (numBlocks != bOffsets.Size()-1)
157  {
158  delete [] blocks;
159  numBlocks = bOffsets.Size()-1;
160  blocks = new Vector[numBlocks];
161  }
162  SetBlocks();
163 }
164 
166 {
167  if (numBlocks!=original.numBlocks)
168  {
169  mfem_error("Number of Blocks don't match in BlockVector::operator=");
170  }
171 
172  for (int i(0); i <= numBlocks; ++i)
173  {
174  if (blockOffsets[i]!=original.blockOffsets[i])
175  {
176  mfem_error("Size of Blocks don't match in BlockVector::operator=");
177  }
178  }
179 
180  Vector::operator=(original);
181 
182  return *this;
183 }
184 
186 {
187  Vector::operator=(val);
188  return *this;
189 }
190 
191 //! Destructor
193 {
194  delete [] blocks;
195 }
196 
197 void BlockVector::GetBlockView(int i, Vector & blockView)
198 {
199  blockView.MakeRef(*this, blockOffsets[i], BlockSize(i));
200 }
201 
203 {
204  for (int i = 0; i < numBlocks; ++i)
205  {
206  blocks[i].SyncMemory(*this);
207  }
208 }
209 
211 {
212  for (int i = 0; i < numBlocks; ++i)
213  {
214  blocks[i].SyncAliasMemory(*this);
215  }
216 }
217 
218 }
~BlockVector()
Destructor.
int BlockSize(int i)
void NewDataAndSize(double *d, int s)
Set the Vector data and size, deleting the old data, if owned.
Definition: vector.hpp:160
Memory< double > data
Definition: vector.hpp:62
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:235
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:517
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:197
void Update(double *data, const Array< int > &bOffsets)
Update method.
Definition: blockvector.cpp:95
Vector & operator=(const double *v)
Copy Size() entries from v.
Definition: vector.cpp:119
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:206
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:242
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:238
void Destroy()
Destroy a vector.
Definition: vector.hpp:594
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:792
Vector data type.
Definition: vector.hpp:58
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
Definition: vector.hpp:581
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...