MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
arrays_by_name.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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_ARRAYS_BY_NAME
13#define MFEM_ARRAYS_BY_NAME
14
15#include "../config/config.hpp"
16#include "array.hpp"
17
18#include <iostream>
19#include <map>
20#include <set>
21#include <string>
22
23namespace mfem
24{
25
26/**
27 Container class for storing arrays indexed by strings.
28
29 The Array<T> objects stored within this container must all be based on the
30 same underlying generic type T, which must be a trivial type, see
31 `std::is_trivial`.
32
33 In order to provide some level of protection against typos this class will
34 not create new named arrays when access to unrecognized names is requested.
35 New named arrays must be explicitly created using `CreateArray()`. To
36 facilitate this behavior and avoid such errors the method `EntryExists()` is
37 provided.
38
39 This container does not store pointers to pre-existing arrays. It will copy
40 or move entries as appropriate from existing Array<T> objects into new
41 Array<T> objects stored within this container.
42*/
43template <class T>
45{
46protected:
47 /// Reusing STL map iterators
48 using container = std::map<std::string,Array<T> >;
49 using iterator = typename container::iterator;
50 using const_iterator = typename container::const_iterator;
51
52 /// Map containing the data sorted alphabetically by name
54
55public:
56
57 /// Default constructor
58 ArraysByName() = default;
59
60 /// Copy constructor: deep copy from @a src
61 ArraysByName(const ArraysByName &src) = default;
62
63 /// Move constructor
64 ArraysByName(ArraysByName &&src) noexcept = default;
65
66 /// Return the number of named arrays in the container
67 int Size() const { return data.size(); }
68
69 /// Return an STL set of strings giving the names of the arrays
70 inline std::set<std::string> GetNames() const;
71
72 /// @brief Return true if an array with the given name is present in the
73 /// container
74 inline bool EntryExists(const std::string &name) const;
75
76 /// @brief Reference access to the named entry.
77 ///
78 /// @note Passing a name for a nonexistent array will print an error
79 /// message and halt execution. This is intended to call attention to
80 /// possible typos or other errors. To handle such errors more gracefully
81 /// consider first calling EntryExists.
82 inline Array<T> &operator[](const std::string &name);
83
84 /// @brief Const reference access to the named entry.
85 ///
86 /// @note Passing a name for a nonexistent array will print an error
87 /// message and halt execution. This is intended to call attention to
88 /// possible typos or other errors. To handle such errors more gracefully
89 /// consider first calling EntryExists.
90 inline const Array<T> &operator[](const std::string &name) const;
91
92 /// @brief Create a new empty array with the given name
93 ///
94 /// @note Passing a name for an already existent array will print an error
95 /// message and halt execution. This is intended to call attention to
96 /// possible typos or other errors. To handle such errors more gracefully
97 /// consider first calling EntryExists.
98 inline Array<T> &CreateArray(const std::string &name);
99
100 /// Delete all named arrays from the container
101 inline void DeleteAll();
102
103 /// @brief Delete the named array from the container
104 ///
105 /// @note Passing a name for a nonexistent array will print an error
106 /// message and halt execution. This is intended to call attention to
107 /// possible typos or other errors. To handle such errors more gracefully
108 /// consider first calling EntryExists.
109 inline void DeleteArray(const std::string &name);
110
111 /// Copy assignment operator: deep copy from 'src'.
113
114 /// Move assignment operator
115 ArraysByName<T> &operator=(ArraysByName<T> &&src) noexcept = default;
116
117 /// @brief Print the contents of the container to an output stream
118 ///
119 /// @note Each array will be printed on at least three lines; the name on
120 /// one line, the length of the associated array, lastly the array contents
121 /// with @a width entries per line. A specific number of entries per line
122 /// can be used by changing the @a width argument.
123 inline void Print(std::ostream &out = mfem::out, int width = -1) const;
124
125 /// @brief Load the contents of the container from an input stream
126 ///
127 /// @note This method will not first empty the container. First call
128 /// DeleteAll if this behavior is needed.
129 void Load(std::istream &in);
130
131 /// Sort each named array in the container
132 inline void SortAll();
133
134 /// @brief Remove duplicates from each, previously sorted, named array
135 ///
136 /// @note Identical entries may exist in multiple arrays but will only occur
137 /// at most once in each array.
138 inline void UniqueAll();
139
140 /// STL-like begin. Returns pointer to the first entry of the container.
141 iterator begin() { return data.begin(); }
142
143 /// STL-like end. Returns pointer after the last entry of the container.
144 iterator end() { return data.end(); }
145
146 /// @brief STL-like begin. Returns const pointer to the first entry of the
147 /// container.
148 const_iterator begin() const { return data.cbegin(); }
149
150 /// @brief STL-like end. Returns const pointer after the last entry of the
151 /// container.
152 const_iterator end() const { return data.cend(); }
153};
154
155template <class T>
156inline bool operator==(const ArraysByName<T> &LHS, const ArraysByName<T> &RHS)
157{
158 if ( LHS.Size() != RHS.Size() ) { return false; }
159 for (auto it1 = LHS.begin(), it2 = RHS.begin();
160 it1 != LHS.end() && it2 != RHS.end(); it1++, it2++)
161 {
162 if (it1->first != it2->first) { return false; }
163 if (it1->second != it2->second) { return false; }
164 }
165 return true;
166}
167
168template<class T>
169inline std::set<std::string> ArraysByName<T>::GetNames() const
170{
171 std::set<std::string> names;
172 for (auto const &entry : data)
173 {
174 names.insert(entry.first);
175 }
176 return names;
177}
178
179template<class T>
180inline bool ArraysByName<T>::EntryExists(const std::string &name) const
181{
182 return data.find(name) != data.end();
183}
184
185template<class T>
186inline Array<T> &ArraysByName<T>::operator[](const std::string &name)
187{
188 MFEM_VERIFY( data.find(name) != data.end(),
189 "Access to unknown named array \"" << name << "\"");
190 return data[name];
191}
192
193template<class T>
194inline const Array<T> &ArraysByName<T>::operator[](const std::string &name)
195const
196{
197 MFEM_VERIFY( data.find(name) != data.end(),
198 "Access to unknown named array \"" << name << "\"");
199 return data.at(name);
200}
201
202template<class T>
203inline Array<T> &ArraysByName<T>::CreateArray(const std::string &name)
204{
205 MFEM_VERIFY( data.find(name) == data.end(),
206 "Named array \"" << name << "\" already exists");
207 Array<T> empty_array;
208 data.insert(std::pair<std::string,Array<T> >(name,empty_array));
209 return data[name];
210}
211
212template<class T>
214{
215 data.clear();
216}
217
218template<class T>
219inline void ArraysByName<T>::DeleteArray(const std::string &name)
220{
221 MFEM_VERIFY( data.find(name) != data.end(),
222 "Attempting to delete unknown named array \"" << name << "\"");
223 data.erase(name);
224}
225
226template <class T>
228{
229 for (auto &a : data)
230 {
231 a.second.Sort();
232 }
233}
234
235template <class T>
237{
238 for (auto &a : data)
239 {
240 a.second.Unique();
241 }
242}
243
244template <class T>
245inline void ArraysByName<T>::Print(std::ostream &os, int width) const
246{
247 os << data.size() << '\n';
248 for (auto const &it : data)
249 {
250 os << '"' << it.first << '"' << '\n' << it.second.Size() << '\n';
251 it.second.Print(os, width > 0 ? width : it.second.Size());
252 }
253}
254
255template <class T>
256void ArraysByName<T>::Load(std::istream &in)
257{
258 int NumArrays;
259 in >> NumArrays;
260
261 std::string ArrayLine, ArrayName;
262 for (int i=0; i < NumArrays; i++)
263 {
264 in >> std::ws;
265 getline(in, ArrayLine);
266
267 std::size_t q0 = ArrayLine.find('"');
268 std::size_t q1 = ArrayLine.rfind('"');
269
270 if (q0 != std::string::npos && q1 > q0)
271 {
272 // Locate set name between first and last double quote
273 ArrayName = ArrayLine.substr(q0+1,q1-q0-1);
274 }
275 else
276 {
277 // If no double quotes found locate set name using white space
278 q1 = ArrayLine.find(' ');
279 ArrayName = ArrayLine.substr(0,q1-1);
280 }
281
282 // Ignore the remainder of the line which may contain explanatory comments
283 data[ArrayName].Load(in, 0);
284 }
285
286}
287
288}
289
290#endif
void Print(std::ostream &out=mfem::out, int width=-1) const
Print the contents of the container to an output stream.
void SortAll()
Sort each named array in the container.
ArraysByName()=default
Default constructor.
iterator end()
STL-like end. Returns pointer after the last entry of the container.
ArraysByName(ArraysByName &&src) noexcept=default
Move constructor.
Array< T > & operator[](const std::string &name)
Reference access to the named entry.
void UniqueAll()
Remove duplicates from each, previously sorted, named array.
const Array< T > & operator[](const std::string &name) const
Const reference access to the named entry.
typename container::const_iterator const_iterator
ArraysByName< T > & operator=(ArraysByName< T > &&src) noexcept=default
Move assignment operator.
std::set< std::string > GetNames() const
Return an STL set of strings giving the names of the arrays.
iterator begin()
STL-like begin. Returns pointer to the first entry of the container.
container data
Map containing the data sorted alphabetically by name.
ArraysByName(const ArraysByName &src)=default
Copy constructor: deep copy from src.
void DeleteAll()
Delete all named arrays from the container.
std::map< std::string, Array< T > > container
Reusing STL map iterators.
void DeleteArray(const std::string &name)
Delete the named array from the container.
int Size() const
Return the number of named arrays in the container.
bool EntryExists(const std::string &name) const
Return true if an array with the given name is present in the container.
const_iterator end() const
STL-like end. Returns const pointer after the last entry of the container.
typename container::iterator iterator
void Load(std::istream &in)
Load the contents of the container from an input stream.
const_iterator begin() const
STL-like begin. Returns const pointer to the first entry of the container.
ArraysByName< T > & operator=(const ArraysByName< T > &src)=default
Copy assignment operator: deep copy from 'src'.
Array< T > & CreateArray(const std::string &name)
Create a new empty array with the given name.
real_t a
Definition lissajous.cpp:41
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
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
Definition array.hpp:342