1 /*
2  * Copyright (c) 2017, Lawrence Livermore National Security, LLC.
3  * Produced at the Lawrence Livermore National Laboratory.
4  *
5  * All rights reserved.
6  *
7  * This source code cannot be distributed without permission and further
8  * review from Lawrence Livermore National Laboratory.
9  */
10 
11 #include "gtest/gtest.h"
12 
13 #include "axom/mint/mesh/ConnectivityArray.hpp"
14 #include "axom/mint/mesh/CellTypes.hpp"
15 #include "axom/mint/config.hpp"
16 #include "axom/slic/interface/slic.hpp"
17 #include "axom/slic/core/SimpleLogger.hpp" /* for SimpleLogger */
18 
19 #ifdef AXOM_MINT_USE_SIDRE
20   #include "axom/sidre/core/sidre.hpp"
21 #endif
22 
23 #include <algorithm>
24 
25 namespace axom
26 {
27 namespace mint
28 {
29 const char IGNORE_OUTPUT[] = ".*";
30 
31 constexpr IndexType vertex_stride = 1;
32 constexpr IndexType hex_stride = 8;
33 
34 namespace internal
35 {
36 /*!
37  * \brief Return the new ID capacity for a ConnectivityArray given an
38  *  increase.
39  *
40  * \param [in] connec the ConnectivityArray in question.
41  * \param [in] increase the amount the number of IDs will increase by
42  */
calc_ID_capacity(const ConnectivityArray<NO_INDIRECTION> & connec,IndexType increase)43 IndexType calc_ID_capacity(const ConnectivityArray<NO_INDIRECTION>& connec,
44                            IndexType increase)
45 {
46   IndexType new_n_IDs = connec.getNumberOfIDs() + increase;
47   if(new_n_IDs > connec.getIDCapacity())
48   {
49     return static_cast<IndexType>(new_n_IDs * connec.getResizeRatio() + 0.5);
50   }
51 
52   return connec.getIDCapacity();
53 }
54 
55 /*!
56  * \brief Return the new ID capacity for a ConnectivityArray given an
57  *  increase.
58  *
59  * \param [in] connec the ConnectivityArray in question.
60  * \param [in] increase the amount the number of IDs will increase by
61  *
62  * \note The plus/minus one are to account for the fact that the offset array is
63  *  what gets resized which has capacity getIDCapacity() + 1.
64  */
calc_ID_capacity(const ConnectivityArray<INDIRECTION> & connec,IndexType increase)65 IndexType calc_ID_capacity(const ConnectivityArray<INDIRECTION>& connec,
66                            IndexType increase)
67 {
68   IndexType new_n_IDs = connec.getNumberOfIDs() + increase;
69   if(new_n_IDs > connec.getIDCapacity())
70   {
71     return (
72       static_cast<IndexType>((new_n_IDs + 1) * connec.getResizeRatio() + 0.5) - 1);
73   }
74 
75   return connec.getIDCapacity();
76 }
77 
78 /*!
79  * \brief Return the new ID capacity for a ConnectivityArray given an
80  *  increase.
81  *
82  * \param [in] connec the ConnectivityArray in question.
83  * \param [in] increase the amount the number of IDs will increase by
84  */
calc_ID_capacity(const ConnectivityArray<TYPED_INDIRECTION> & connec,IndexType increase)85 IndexType calc_ID_capacity(const ConnectivityArray<TYPED_INDIRECTION>& connec,
86                            IndexType increase)
87 {
88   IndexType new_n_IDs = connec.getNumberOfIDs() + increase;
89   if(new_n_IDs > connec.getIDCapacity())
90   {
91     return static_cast<IndexType>(new_n_IDs * connec.getResizeRatio() + 0.5);
92   }
93 
94   return connec.getIDCapacity();
95 }
96 
97 /*!
98  * \brief Return the new value capacity for a ConnectivityArray given an
99  *  increase.
100  *
101  * \param [in] connec the ConnectivityArray in question.
102  * \param [in] increase the amount the number of values will increase by
103  */
calc_value_capacity(const ConnectivityArray<NO_INDIRECTION> & connec,IndexType increase)104 IndexType calc_value_capacity(const ConnectivityArray<NO_INDIRECTION>& connec,
105                               IndexType increase)
106 {
107   IndexType stride = getCellInfo(connec.getIDType()).num_nodes;
108   return calc_ID_capacity(connec, increase / stride) * stride;
109 }
110 
111 /*!
112  * \brief Return the new value capacity for a ConnectivityArray given an
113  *  increase.
114  *
115  * \param [in] connec the ConnectivityArray in question.
116  * \param [in] increase the amount the number of values will increase by
117  */
118 template <ConnectivityType TYPE>
calc_value_capacity(const ConnectivityArray<TYPE> & connec,IndexType increase)119 IndexType calc_value_capacity(const ConnectivityArray<TYPE>& connec,
120                               IndexType increase)
121 {
122   IndexType new_n_values = connec.getNumberOfValues() + increase;
123   if(new_n_values > connec.getValueCapacity())
124   {
125     return static_cast<IndexType>(new_n_values * connec.getResizeRatio() + 0.5);
126   }
127 
128   return connec.getValueCapacity();
129 }
130 
131 /*!
132  * \brief Get the type associated with the given ID to be inserted into a
133  *  ConnectivityArray.
134  *
135  * \param [in] ID the ID in question.
136  * \param [in] cell_type the CellType of the ConnectivityArray.
137  * \param [in] types the array of types.
138  */
get_type(IndexType ID,CellType cell_type,const CellType * types)139 CellType get_type(IndexType ID, CellType cell_type, const CellType* types)
140 {
141   if(types == nullptr)
142   {
143     return cell_type;
144   }
145   else
146   {
147     return types[ID];
148   }
149 }
150 
151 /*!
152  * \brief Get a pointer to the types starting at the given ID.
153  *
154  * \param [in] ID the ID in question.
155  * \param [in] types the array of types.
156  */
get_type_ptr(IndexType ID,const CellType * types)157 const CellType* get_type_ptr(IndexType ID, const CellType* types)
158 {
159   if(types == nullptr)
160   {
161     return nullptr;
162   }
163   else
164   {
165     return types + ID;
166   }
167 }
168 
169 /*!
170  * \brief Return the number of values associated with ID.
171  *
172  * \param [in] ID the ID in question.
173  * \param [in] stride the stride of the ConnectivityArray.
174  * \param [in] offsets the offsets array.
175  */
get_n_values(IndexType ID,IndexType stride,const IndexType * offsets)176 IndexType get_n_values(IndexType ID, IndexType stride, const IndexType* offsets)
177 {
178   if(offsets == nullptr)
179   {
180     return stride;
181   }
182   else
183   {
184     return offsets[ID + 1] - offsets[ID];
185   }
186 }
187 
188 /*!
189  * \brief Return the number of values between the given IDs.
190  *
191  * \param [in] startID the start of the range.
192  * \param [in] endID the end of the range.
193  * \param [in] stride the stride of the ConnectivityArray.
194  * \param [in] offsets pointer to the offsets array for the values in question.
195  */
get_n_values(IndexType startID,IndexType endID,IndexType stride,const IndexType * offsets)196 IndexType get_n_values(IndexType startID,
197                        IndexType endID,
198                        IndexType stride,
199                        const IndexType* offsets)
200 {
201   if(offsets == nullptr)
202   {
203     return stride * (endID - startID);
204   }
205   else
206   {
207     return offsets[endID] - offsets[startID];
208   }
209 }
210 
211 /*!
212  * \brief Return a pointer to the values array starting with the given ID.
213  *
214  * \param [in] ID the ID used to index into the values array.
215  * \param [in] stride the stride of the ConnectivityArray.
216  * \param [in] values the array of values.
217  * \param [in] offsets pointer to the offsets array for the values in question.
218  */
get_value_ptr(IndexType ID,IndexType stride,const IndexType * values,const IndexType * offsets)219 const IndexType* get_value_ptr(IndexType ID,
220                                IndexType stride,
221                                const IndexType* values,
222                                const IndexType* offsets)
223 {
224   if(offsets == nullptr)
225   {
226     return values + ID * stride;
227   }
228   else
229   {
230     return values + offsets[ID];
231   }
232 }
233 
234 /*!
235  * \brief Return a pointer to the offsets array starting with the given ID.
236  *
237  * \param [in] ID the ID in question.
238  * \param [in] offsets the offsets array.
239  */
get_offset_ptr(IndexType ID,const IndexType * offsets)240 const IndexType* get_offset_ptr(IndexType ID, const IndexType* offsets)
241 {
242   if(offsets == nullptr)
243   {
244     return nullptr;
245   }
246   else
247   {
248     return offsets + ID;
249   }
250 }
251 
252 /*!
253  * \brief Check that the given pointers point to the same values or that they
254  *  are both null.
255  *
256  * \param [in] p1 the first pointer to check.
257  * \param [in] p2 the second pointer to check.
258  * \param [in] n the number of values to check.
259  */
260 template <typename T>
check_pointers(const T * p1,const T * p2,IndexType n)261 void check_pointers(const T* p1, const T* p2, IndexType n)
262 {
263   if(p1 == nullptr && p2 == nullptr)
264   {
265     return;
266   }
267 
268   for(IndexType i = 0; i < n; ++i)
269   {
270     EXPECT_EQ(p1[i], p2[i]) << "i = " << i;
271   }
272 }
273 
274 /*!
275  * \brief Check that the given ConnectivityArrays are equal.
276  *
277  * \param [in] lhs the first ConnectivityArray to check.
278  * \param [in] rhs the second ConnectivityArray to check.
279  */
280 template <ConnectivityType TYPE>
check_equality(const ConnectivityArray<TYPE> & lhs,const ConnectivityArray<TYPE> & rhs)281 void check_equality(const ConnectivityArray<TYPE>& lhs,
282                     const ConnectivityArray<TYPE>& rhs)
283 {
284   ASSERT_EQ(lhs.getNumberOfIDs(), rhs.getNumberOfIDs());
285   ASSERT_EQ(lhs.getNumberOfValues(), rhs.getNumberOfValues());
286   EXPECT_EQ(lhs.getIDCapacity(), rhs.getIDCapacity());
287   EXPECT_EQ(lhs.isExternal(), rhs.isExternal());
288   EXPECT_EQ(lhs.isInSidre(), rhs.isInSidre());
289 
290   const IndexType n_IDs = lhs.getNumberOfIDs();
291   for(IndexType ID = 0; ID < n_IDs; ++ID)
292   {
293     const IndexType cur_n_values = lhs.getNumberOfValuesForID(ID);
294     ASSERT_EQ(cur_n_values, rhs.getNumberOfValuesForID(ID));
295     EXPECT_EQ(lhs.getIDType(ID), rhs.getIDType(ID));
296     check_pointers(lhs[ID], rhs[ID], cur_n_values);
297   }
298 }
299 
300 /*!
301  * \brief Checks that the given values were properly appended to the
302  *  ConnectivityArray.
303  *
304  * \param [in/out] connec the ConnectivityArray to check.
305  * \param [in] n_IDs the number of IDs appended.
306  * \param [in] initial_n_IDs the number of IDs in the ConnectivityArray before
307  *  appending.
308  * \param [in] values the array of values to check.
309  * \param [in] offsets the offsets array.
310  * \param [in] types the type of each ID that was appended.
311  */
312 template <ConnectivityType TYPE>
checkAppend(const ConnectivityArray<TYPE> & connec,IndexType n_IDs,IndexType initial_n_IDs,const IndexType * values,const IndexType * offsets=nullptr,const CellType * types=nullptr)313 void checkAppend(const ConnectivityArray<TYPE>& connec,
314                  IndexType n_IDs,
315                  IndexType initial_n_IDs,
316                  const IndexType* values,
317                  const IndexType* offsets = nullptr,
318                  const CellType* types = nullptr)
319 {
320   const CellType cell_type = connec.getIDType();
321   const IndexType stride =
322     (cell_type == UNDEFINED_CELL) ? -1 : getCellInfo(cell_type).num_nodes;
323 
324   for(IndexType ID = 0; ID < n_IDs; ++ID)
325   {
326     const IndexType cur_n_values = get_n_values(ID, stride, offsets);
327     const IndexType* cur_values = get_value_ptr(ID, stride, values, offsets);
328     const CellType cur_type = get_type(ID, cell_type, types);
329     EXPECT_EQ(connec.getIDType(initial_n_IDs + ID), cur_type);
330     EXPECT_EQ(connec.getNumberOfValuesForID(initial_n_IDs + ID), cur_n_values);
331     check_pointers(cur_values, connec[initial_n_IDs + ID], cur_n_values);
332   }
333 }
334 
335 /*!
336  * \brief Check that appending to the given ConnectivityArray functions as
337  *  expected.
338  *
339  * \param [in/out] connec the ConnectivityArray to append to.
340  * \param [in] n_IDs the number of IDs to append.
341  * \param [in] values the array of values to append.
342  * \param [in] offsets the offsets array.
343  * \param [in] types the type of each ID to append.
344  */
345 template <ConnectivityType TYPE>
append(ConnectivityArray<TYPE> & connec,IndexType n_IDs,const IndexType * values,const IndexType * offsets=nullptr,const CellType * types=nullptr)346 void append(ConnectivityArray<TYPE>& connec,
347             IndexType n_IDs,
348             const IndexType* values,
349             const IndexType* offsets = nullptr,
350             const CellType* types = nullptr)
351 {
352   const CellType cell_type = connec.getIDType();
353   const IndexType stride =
354     (cell_type == UNDEFINED_CELL) ? -1 : getCellInfo(cell_type).num_nodes;
355   const IndexType initial_n_IDs = connec.getNumberOfIDs();
356 
357   IndexType half_n_IDs = n_IDs / 2;
358   for(IndexType ID = 0; ID < half_n_IDs; ++ID)
359   {
360     const IndexType cur_n_values = get_n_values(ID, stride, offsets);
361     const IndexType* cur_values = get_value_ptr(ID, stride, values, offsets);
362     const CellType type = get_type(ID, cell_type, types);
363 
364     connec.append(cur_values, cur_n_values, type);
365     EXPECT_EQ(connec.getNumberOfIDs(), initial_n_IDs + ID + 1);
366     EXPECT_EQ(connec.getIDType(initial_n_IDs + ID), type);
367     EXPECT_EQ(connec.getNumberOfValuesForID(initial_n_IDs + ID), cur_n_values);
368     check_pointers(cur_values, connec[initial_n_IDs + ID], cur_n_values);
369   }
370 
371   const IndexType cur_ID = half_n_IDs;
372   const IndexType* cur_values = get_value_ptr(cur_ID, stride, values, offsets);
373   const IndexType* cur_offsets = get_offset_ptr(cur_ID, offsets);
374   const CellType* cur_types = get_type_ptr(cur_ID, types);
375   connec.appendM(cur_values, n_IDs - cur_ID, cur_offsets, cur_types);
376 
377   EXPECT_EQ(connec.getNumberOfIDs(), initial_n_IDs + n_IDs);
378   checkAppend(connec, n_IDs, initial_n_IDs, values, offsets, types);
379 }
380 
381 /*!
382  * \brief Calls internal::append multiple times and checks that the output is as
383  *  expected.
384  *
385  * \param [in/out] connec the ConnectivityArray to append to.
386  * \param [in] max_IDs the max number of IDs to append in a given iteration.
387  * \param [in] values the array of values to append.
388  * \param [in] offsets the offsets array.
389  * \param [in] types the type of each ID to append.
390  */
391 template <ConnectivityType TYPE>
testAppend(ConnectivityArray<TYPE> & connec,IndexType max_IDs,const IndexType * values,const IndexType * offsets=nullptr,const CellType * types=nullptr)392 void testAppend(ConnectivityArray<TYPE>& connec,
393                 IndexType max_IDs,
394                 const IndexType* values,
395                 const IndexType* offsets = nullptr,
396                 const CellType* types = nullptr)
397 {
398   /* Append the values */
399   for(IndexType n_IDs = 1; n_IDs <= max_IDs; ++n_IDs)
400   {
401     internal::append(connec, n_IDs, values, offsets, types);
402   }
403 
404   /* Check that the values were appended properly */
405   IndexType initial_n_IDs = 0;
406   for(IndexType n_IDs = 1; n_IDs <= max_IDs; ++n_IDs)
407   {
408     checkAppend(connec, n_IDs, initial_n_IDs, values, offsets, types);
409     initial_n_IDs += n_IDs;
410   }
411 }
412 
413 /*!
414  * \brief Check that setting the values of the given ConnectivityArray
415  *  functions as expected.
416  *
417  * \param [in/out] connec the ConnectivityArray to append to.
418  * \param [in] n_IDs the number of IDs to append.
419  * \param [in] initial_values the array of values to append.
420  * \param [in] values the array of values to set.
421  * \param [in] offsets the offsets array.
422  * \param [in] types the type of each ID to append.
423  */
424 template <ConnectivityType TYPE>
set(ConnectivityArray<TYPE> & connec,IndexType n_IDs,const IndexType * initial_values,const IndexType * values,const IndexType * offsets=nullptr,const CellType * types=nullptr)425 void set(ConnectivityArray<TYPE>& connec,
426          IndexType n_IDs,
427          const IndexType* initial_values,
428          const IndexType* values,
429          const IndexType* offsets = nullptr,
430          const CellType* types = nullptr)
431 {
432   const CellType cell_type = connec.getIDType();
433   const IndexType stride =
434     (cell_type == UNDEFINED_CELL) ? -1 : getCellInfo(cell_type).num_nodes;
435   const IndexType initial_n_IDs = connec.getNumberOfIDs();
436 
437   /* Append the initial values. */
438   append(connec, n_IDs, initial_values, offsets, types);
439 
440   IndexType half_n_IDs = n_IDs / 2;
441   for(IndexType ID = 0; ID < half_n_IDs; ++ID)
442   {
443     const IndexType cur_n_values = get_n_values(ID, stride, offsets);
444     const IndexType* cur_values = get_value_ptr(ID, stride, values, offsets);
445     const CellType type = get_type(ID, cell_type, types);
446 
447     connec.set(cur_values, initial_n_IDs + ID);
448     EXPECT_EQ(connec.getIDType(initial_n_IDs + ID), type);
449     EXPECT_EQ(connec.getNumberOfValuesForID(initial_n_IDs + ID), cur_n_values);
450     check_pointers(cur_values, connec[initial_n_IDs + ID], cur_n_values);
451   }
452 
453   const IndexType cur_ID = half_n_IDs;
454   const IndexType* cur_values = get_value_ptr(cur_ID, stride, values, offsets);
455   connec.setM(cur_values, initial_n_IDs + cur_ID, n_IDs - cur_ID);
456 
457   EXPECT_EQ(connec.getNumberOfIDs(), initial_n_IDs + n_IDs);
458   checkAppend(connec, n_IDs, initial_n_IDs, values, offsets, types);
459 }
460 
461 /*!
462  * \brief Calls internal::set multiple times and checks that the output is as
463  *  expected.
464  *
465  * \param [in/out] connec the ConnectivityArray to append to and then set.
466  * \param [in] max_IDs the max number of IDs to append in a given iteration.
467  * \param [in] initial_values the array of values to append.
468  * \param [in] values the array of values to set.
469  * \param [in] offsets the offsets array.
470  * \param [in] types the type of each ID to append.
471  */
472 template <ConnectivityType TYPE>
testSet(ConnectivityArray<TYPE> & connec,IndexType max_IDs,const IndexType * initial_values,const IndexType * values,const IndexType * offsets=nullptr,const CellType * types=nullptr)473 void testSet(ConnectivityArray<TYPE>& connec,
474              IndexType max_IDs,
475              const IndexType* initial_values,
476              const IndexType* values,
477              const IndexType* offsets = nullptr,
478              const CellType* types = nullptr)
479 {
480   for(IndexType n_IDs = 1; n_IDs <= max_IDs; ++n_IDs)
481   {
482     internal::set(connec, n_IDs, initial_values, values, offsets, types);
483   }
484 
485   /* Check that the values were appended and set properly */
486   IndexType initial_n_IDs = 0;
487   for(IndexType n_IDs = 1; n_IDs <= max_IDs; ++n_IDs)
488   {
489     checkAppend(connec, n_IDs, initial_n_IDs, values, offsets, types);
490     initial_n_IDs += n_IDs;
491   }
492 }
493 
494 /*!
495  * \brief Check that inserting the values into the given ConnectivityArray
496  *  functions as expected.
497  *
498  * \param [in/out] connec the ConnectivityArray to insert into.
499  * \param [in] n_IDs the number of IDs to insert.
500  * \param [in] values the array of values to set.
501  * \param [in] offsets the offsets array.
502  * \param [in] types the type of each ID to append.
503  *
504  * \pre connec.empty()
505  * \pre n_IDs % 6 == 0
506  *
507  * \note For n_IDs / 6 repetitions inserts an ID to the front, interior, and
508  *  rear of the ConnectivityArray. Finally inserts n_IDs / 6 IDs each to the
509  *  front, interior, and rear of the ConnectivityArray in one go.
510  */
511 template <ConnectivityType TYPE>
testInsert(ConnectivityArray<TYPE> & connec,IndexType n_IDs,const IndexType * values,const IndexType * offsets=nullptr,const CellType * types=nullptr)512 void testInsert(ConnectivityArray<TYPE>& connec,
513                 IndexType n_IDs,
514                 const IndexType* values,
515                 const IndexType* offsets = nullptr,
516                 const CellType* types = nullptr)
517 {
518   SLIC_ERROR_IF(!connec.empty(),
519                 "Insertion test requires an empty ConnectivityArray.");
520   SLIC_ERROR_IF(n_IDs % 6 != 0,
521                 "Insertion test requires n_IDs to be a multiple of 6.");
522 
523   const CellType cell_type = connec.getIDType();
524   const IndexType stride =
525     (cell_type == UNDEFINED_CELL) ? -1 : getCellInfo(cell_type).num_nodes;
526 
527   const IndexType half_n_IDs = n_IDs / 2;
528   const IndexType third_n_IDs = n_IDs / 3;
529   const IndexType sixth_n_IDs = n_IDs / 6;
530 
531   /* Array of IDs the next ID to insert at the front, middle, and back. */
532   IndexType IDs[3] = {third_n_IDs - 1, third_n_IDs, 2 * third_n_IDs};
533 
534   /* Array of positions at which to insert for the front, middle, and back. */
535   IndexType insert_positions[3] = {0, 1, 2};
536 
537   for(IndexType round = 0; round < sixth_n_IDs; ++round)
538   {
539     for(IndexType i = 0; i < 3; ++i)
540     {
541       const IndexType cur_ID = IDs[i];
542       const IndexType insert_pos = insert_positions[i];
543       const IndexType cur_n_values = get_n_values(cur_ID, stride, offsets);
544       const IndexType* cur_values =
545         get_value_ptr(cur_ID, stride, values, offsets);
546       const CellType type = get_type(cur_ID, cell_type, types);
547 
548       connec.insert(cur_values, insert_pos, cur_n_values, type);
549       EXPECT_EQ(connec.getNumberOfIDs(), 3 * round + i + 1);
550       EXPECT_EQ(connec.getIDType(insert_pos), type);
551       EXPECT_EQ(connec.getNumberOfValuesForID(insert_pos), cur_n_values);
552       check_pointers(cur_values, connec[insert_pos], cur_n_values);
553     }
554 
555     /* The middle insertion increases by two, the back by three. */
556     insert_positions[1] += 2;
557     insert_positions[2] += 3;
558 
559     /* The front ID decreases by one while the middle and rear increase by one.
560      */
561     IDs[0]--;
562     IDs[1]++;
563     IDs[2]++;
564   }
565 
566   /* Insert the rest of the front values. */
567   const IndexType front_ID = 0;
568   const IndexType* front_offsets = get_offset_ptr(front_ID, offsets);
569   const IndexType* front_values =
570     get_value_ptr(front_ID, stride, values, offsets);
571   const CellType* front_types = get_type_ptr(front_ID, types);
572   connec.insertM(front_values, front_ID, sixth_n_IDs, front_offsets, front_types);
573   EXPECT_EQ(connec.getNumberOfIDs(), 2 * third_n_IDs);
574 
575   /* Insert the rest of the middle values. */
576   const IndexType middle_ID = half_n_IDs;
577   const IndexType* middle_offsets = get_offset_ptr(middle_ID, offsets);
578   const IndexType* middle_values =
579     get_value_ptr(middle_ID, stride, values, offsets);
580   const CellType* middle_types = get_type_ptr(middle_ID, types);
581   connec.insertM(middle_values, middle_ID, sixth_n_IDs, middle_offsets, middle_types);
582   EXPECT_EQ(connec.getNumberOfIDs(), 5 * sixth_n_IDs);
583 
584   /* Insert the rest of the back values. */
585   const IndexType back_ID = 5 * sixth_n_IDs;
586   const IndexType* back_offsets = get_offset_ptr(back_ID, offsets);
587   const IndexType* back_values = get_value_ptr(back_ID, stride, values, offsets);
588   const CellType* back_types = get_type_ptr(back_ID, types);
589   connec.insertM(back_values, back_ID, sixth_n_IDs, back_offsets, back_types);
590   EXPECT_EQ(connec.getNumberOfIDs(), n_IDs);
591 
592   /* Check that the values were correctly inserted. */
593   checkAppend(connec, n_IDs, 0, values, offsets, types);
594 }
595 
596 /*!
597  * \brief Check that capacity of the given ConnectivityArray functions as
598  *  expected.
599  *
600  * \param [in/out] connec the ConnectivityArray to append to.
601  * \param [in] n_IDs the number of IDs to append.
602  * \param [in] values the array of values to append.
603  * \param [in] offsets the offsets array.
604  * \param [in] types the type of each ID to append.
605  *
606  * \pre connec.empty()
607  *
608  * \note offsets only need to be specified for ConnectivityArrays that need
609  *  indirection and types only needs to be specified for ConnectivityArrays
610  *  that have variable ID types. First reserves space for half of n_IDs and half
611  *  the values, then appends that many IDs one at a time. Then appends one extra
612  *  ID and checks that the resizing occured as expected. Then shrinks the
613  *  ConnectivityArray and appends the remaining IDs all at once.
614  */
615 template <ConnectivityType TYPE>
testCapacity(ConnectivityArray<TYPE> & connec,IndexType n_IDs,const IndexType * values,const IndexType * offsets=nullptr,const CellType * types=nullptr)616 void testCapacity(ConnectivityArray<TYPE>& connec,
617                   IndexType n_IDs,
618                   const IndexType* values,
619                   const IndexType* offsets = nullptr,
620                   const CellType* types = nullptr)
621 {
622   SLIC_ERROR_IF(!connec.empty(),
623                 "Insertion test requires an empty ConnectivityArray.");
624   const CellType cell_type = connec.getIDType();
625   const IndexType stride =
626     (cell_type == UNDEFINED_CELL) ? -1 : getCellInfo(cell_type).num_nodes;
627   const IndexType half_n_IDs = n_IDs / 2;
628   const IndexType n_values = get_n_values(0, n_IDs, stride, offsets);
629   const IndexType first_half_n_values =
630     get_n_values(0, half_n_IDs, stride, offsets);
631   IndexType cur_ID_size = connec.getNumberOfIDs();
632   IndexType cur_value_size = connec.getNumberOfValues();
633 
634   EXPECT_EQ(cur_ID_size, 0);
635   EXPECT_EQ(cur_value_size, 0);
636 
637   connec.reserve(half_n_IDs, first_half_n_values);
638   const IndexType* cur_values_ptr = connec.getValuePtr();
639   const IndexType* cur_offsets_ptr = connec.getOffsetPtr();
640   const CellType* cur_types_ptr = connec.getTypePtr();
641   IndexType cur_ID_capacity = connec.getIDCapacity();
642   IndexType cur_value_capacity = connec.getValueCapacity();
643 
644   EXPECT_NE(cur_values_ptr, nullptr);
645   EXPECT_GE(cur_ID_capacity, half_n_IDs);
646   EXPECT_GE(cur_value_capacity, first_half_n_values);
647 
648   /* Append the first half of the IDs, no resize should occur. */
649   for(IndexType ID = 0; ID < half_n_IDs; ++ID)
650   {
651     const IndexType cur_n_values = get_n_values(ID, stride, offsets);
652     const IndexType* cur_values = get_value_ptr(ID, stride, values, offsets);
653     const CellType type = get_type(ID, cell_type, types);
654 
655     connec.append(cur_values, cur_n_values, type);
656     cur_ID_size += 1;
657     cur_value_size += cur_n_values;
658     EXPECT_EQ(connec.getNumberOfIDs(), cur_ID_size);
659     EXPECT_EQ(connec.getIDCapacity(), cur_ID_capacity);
660     EXPECT_EQ(connec.getNumberOfValues(), cur_value_size);
661     EXPECT_EQ(connec.getValueCapacity(), cur_value_capacity);
662     EXPECT_EQ(connec.getValuePtr(), cur_values_ptr);
663     EXPECT_EQ(connec.getOffsetPtr(), cur_offsets_ptr);
664     EXPECT_EQ(connec.getTypePtr(), cur_types_ptr);
665     EXPECT_EQ(connec.getIDType(ID), type);
666     EXPECT_EQ(connec.getNumberOfValuesForID(ID), cur_n_values);
667     check_pointers(cur_values, connec[ID], cur_n_values);
668   }
669 
670   /* Append one more value, should trigger a resize. */
671   IndexType cur_ID = half_n_IDs;
672   IndexType cur_n_values = get_n_values(cur_ID, stride, offsets);
673   const IndexType* cur_values = get_value_ptr(cur_ID, stride, values, offsets);
674   CellType type = get_type(cur_ID, cell_type, types);
675 
676   cur_ID_capacity = calc_ID_capacity(connec, 1);
677   cur_value_capacity = calc_value_capacity(connec, cur_n_values);
678   connec.append(cur_values, cur_n_values, type);
679   cur_ID_size += 1;
680   cur_value_size += cur_n_values;
681 
682   EXPECT_EQ(connec.getNumberOfIDs(), cur_ID_size);
683   EXPECT_EQ(connec.getIDCapacity(), cur_ID_capacity);
684   EXPECT_EQ(connec.getNumberOfValues(), cur_value_size);
685   EXPECT_EQ(connec.getValueCapacity(), cur_value_capacity);
686   EXPECT_EQ(connec.getIDType(cur_ID), type);
687   EXPECT_EQ(connec.getNumberOfValuesForID(cur_ID), cur_n_values);
688   check_pointers(cur_values, connec[cur_ID], cur_n_values);
689 
690   /* Shrink. */
691   connec.shrink();
692   cur_ID_capacity = cur_ID_size;
693   cur_value_capacity = cur_value_size;
694   EXPECT_EQ(connec.getIDCapacity(), cur_ID_capacity);
695   EXPECT_EQ(connec.getValueCapacity(), cur_value_capacity);
696 
697   /* Append the rest of the values all at once, should trigger a resize. */
698   cur_ID = half_n_IDs + 1;
699   cur_values = get_value_ptr(cur_ID, stride, values, offsets);
700   cur_n_values = get_n_values(cur_ID, n_IDs, stride, offsets);
701   const IndexType* cur_offsets = get_offset_ptr(cur_ID, offsets);
702   const CellType* cur_types = get_type_ptr(cur_ID, types);
703 
704   cur_ID_capacity = calc_ID_capacity(connec, n_IDs - cur_ID);
705   cur_value_capacity = calc_value_capacity(connec, cur_n_values);
706   connec.appendM(cur_values, n_IDs - cur_ID, cur_offsets, cur_types);
707   EXPECT_EQ(connec.getNumberOfIDs(), n_IDs);
708   EXPECT_EQ(connec.getIDCapacity(), cur_ID_capacity);
709   EXPECT_EQ(connec.getNumberOfValues(), n_values);
710   EXPECT_EQ(connec.getValueCapacity(), cur_value_capacity);
711 
712   for(IndexType ID = 0; ID < n_IDs; ++ID)
713   {
714     cur_n_values = get_n_values(ID, stride, offsets);
715     cur_values = get_value_ptr(ID, stride, values, offsets);
716     type = get_type(ID, cell_type, types);
717     EXPECT_EQ(connec.getIDType(ID), type);
718     check_pointers(cur_values, connec[ID], cur_n_values);
719   }
720 
721   check_pointers(connec.getValuePtr(), values, n_values);
722   check_pointers(connec.getOffsetPtr(), offsets, n_IDs + 1);
723   check_pointers(connec.getTypePtr(), types, n_IDs);
724 }
725 
726 /*!
727  * \brief Create values in the range [0, n_vals) scaled by a factor.
728  *
729  * \param [in] n_vals the number of values to create.
730  * \param [in] factor the scaling factor.
731  */
createValues(IndexType n_vals,const IndexType factor=1)732 const IndexType* createValues(IndexType n_vals, const IndexType factor = 1)
733 {
734   IndexType* values = new IndexType[n_vals];
735   for(IndexType i = 0; i < n_vals; ++i)
736   {
737     values[i] = factor * i;
738   }
739 
740   return values;
741 }
742 
743 /*!
744  * \brief Create offsets and types arrays for the given number of IDs.
745  *
746  * \param [in] n_IDs the number of values to create.
747  * \param [out] offsets where the offsets array is stored.
748  * \param [out] types where the types array is stored.
749  *
750  * \return The number of values accounted for in the offsets array.
751  */
createOffsetsAndTypes(IndexType n_IDs,IndexType * & offsets,CellType * & types)752 IndexType createOffsetsAndTypes(IndexType n_IDs,
753                                 IndexType*& offsets,
754                                 CellType*& types)
755 {
756   offsets = new IndexType[n_IDs + 1];
757   types = new CellType[n_IDs];
758   offsets[0] = 0;
759   for(IndexType i = 0; i < n_IDs; ++i)
760   {
761     if(i % 2 == 0)
762     {
763       types[i] = VERTEX;
764       offsets[i + 1] = offsets[i] + vertex_stride;
765     }
766     else
767     {
768       types[i] = HEX;
769       offsets[i + 1] = offsets[i] + hex_stride;
770     }
771   }
772 
773   return offsets[n_IDs];
774 }
775 
776 /*!
777  * \brief Calaculate the total number of IDs and Values to insert given
778  *  the maximum number inserted in a given iteration.
779  *
780  * \param [in] max_IDs the max number of IDs inserted in a single iteration.
781  * \param [out] total_IDs the total number of IDs calculated.
782  * \param [out] total_values the total number of values calculated.
783  */
calcTotalIDsAndValues(IndexType max_IDs,IndexType & total_IDs,IndexType & total_values)784 void calcTotalIDsAndValues(IndexType max_IDs,
785                            IndexType& total_IDs,
786                            IndexType& total_values)
787 {
788   total_IDs = (max_IDs * (max_IDs + 1)) / 2;
789   total_values = 0;
790   for(IndexType n_IDs = 1; n_IDs <= max_IDs; ++n_IDs)
791   {
792     total_values += (n_IDs / 2) * (vertex_stride + hex_stride);
793     if(n_IDs % 2 == 1)
794     {
795       total_values += vertex_stride;
796     }
797   }
798 }
799 
800 /*!
801  * \brief Check that the provided ConnectivityArray meets certain criteria.
802  *
803  * \param [in] connec the ConnectivityArray to check.
804  * \param [in] external if the ConnectivityArray is external.
805  * \param [in] n_IDs the number of IDs.
806  * \param [in] n_values the number of values.
807  * \param [in] pointer to the values array.
808  * \param [in] pointer to the offsets array.
809  * \param [in] pointer to the types array.
810  */
811 template <ConnectivityType TYPE>
checkConnectivity(const ConnectivityArray<TYPE> & connec,bool external,IndexType n_IDs,IndexType n_values,const IndexType * values=nullptr,const IndexType * offsets=nullptr,const CellType * types=nullptr)812 void checkConnectivity(const ConnectivityArray<TYPE>& connec,
813                        bool external,
814                        IndexType n_IDs,
815                        IndexType n_values,
816                        const IndexType* values = nullptr,
817                        const IndexType* offsets = nullptr,
818                        const CellType* types = nullptr)
819 {
820   EXPECT_EQ(connec.isExternal(), external);
821   EXPECT_EQ(connec.isInSidre(), false);
822   EXPECT_EQ(connec.getNumberOfIDs(), n_IDs);
823   EXPECT_EQ(connec.getNumberOfValues(), n_values);
824   bool empty = n_IDs == 0 && n_values == 0;
825   EXPECT_EQ(connec.empty(), empty);
826 
827   if(values != nullptr)
828   {
829     EXPECT_EQ(connec.getValuePtr(), values);
830   }
831 
832   if(offsets != nullptr)
833   {
834     EXPECT_EQ(connec.getOffsetPtr(), offsets);
835   }
836 
837   if(types != nullptr)
838   {
839     EXPECT_EQ(connec.getTypePtr(), types);
840   }
841 
842 #ifdef AXOM_MINT_USE_SIDRE
843   EXPECT_EQ(connec.getGroup(), nullptr);
844 #endif
845 }
846 
847 #ifdef AXOM_MINT_USE_SIDRE
848 /*!
849  * \brief Check that the provided ConnectivityArray meets certain criteria.
850  *
851  * \param [in] connec the ConnectivityArray to check.
852  * \param [in] n_IDs the number of IDs.
853  * \param [in] n_values the number of values.
854  * \param [in] group the sidr::Group of the ConnectivityArray.
855  */
856 template <ConnectivityType TYPE>
checkConnectivity(const ConnectivityArray<TYPE> & connec,IndexType n_IDs,IndexType n_values,const sidre::Group * group=nullptr)857 void checkConnectivity(const ConnectivityArray<TYPE>& connec,
858                        IndexType n_IDs,
859                        IndexType n_values,
860                        const sidre::Group* group = nullptr)
861 {
862   EXPECT_EQ(connec.isExternal(), false);
863   EXPECT_EQ(connec.isInSidre(), true);
864   EXPECT_EQ(connec.getNumberOfIDs(), n_IDs);
865   EXPECT_EQ(connec.getNumberOfValues(), n_values);
866   bool empty = n_IDs == 0 && n_values == 0;
867   EXPECT_EQ(connec.empty(), empty);
868   EXPECT_EQ(connec.getGroup(), group);
869 }
870 
871 /*!
872  * \brief Check that the ConnectivityArray can be reconstructed from
873  *  a sidre::Group.
874  *
875  * \param [in] connec the ConnectivityArray to check.
876  */
877 template <ConnectivityType TYPE>
checkSidreConstructor(const ConnectivityArray<TYPE> & connec)878 void checkSidreConstructor(const ConnectivityArray<TYPE>& connec)
879 {
880   ASSERT_TRUE(connec.isInSidre());
881 
882   sidre::Group* group = const_cast<sidre::Group*>(connec.getGroup());
883   ConnectivityArray<TYPE> cpy(group);
884   internal::check_equality(connec, cpy);
885 }
886 #endif /* AXOM_MINT_USE_SIDRE */
887 
888 /*!
889  * \brief Check that the ConnectivityArray can be reconstructed from
890  *  a external buffers.
891  *
892  * \param [in] connec the ConnectivityArray to check.
893  */
checkExternalConstructor(const ConnectivityArray<NO_INDIRECTION> & connec)894 void checkExternalConstructor(const ConnectivityArray<NO_INDIRECTION>& connec)
895 {
896   ASSERT_TRUE(connec.isExternal());
897 
898   CellType cell_type = connec.getIDType();
899   const IndexType n_IDs = connec.getNumberOfIDs();
900   IndexType* values = const_cast<IndexType*>(connec.getValuePtr());
901   ConnectivityArray<NO_INDIRECTION> connec_cpy(cell_type, n_IDs, values);
902   internal::check_equality(connec, connec_cpy);
903 }
904 
905 /*!
906  * \brief Check that the ConnectivityArray can be reconstructed from
907  *  a external buffers.
908  *
909  * \param [in] connec the ConnectivityArray to check.
910  */
checkExternalConstructor(const ConnectivityArray<INDIRECTION> & connec)911 void checkExternalConstructor(const ConnectivityArray<INDIRECTION>& connec)
912 {
913   ASSERT_TRUE(connec.isExternal());
914 
915   CellType cell_type = connec.getIDType();
916   const IndexType n_IDs = connec.getNumberOfIDs();
917   IndexType* values = const_cast<IndexType*>(connec.getValuePtr());
918   IndexType* offsets = const_cast<IndexType*>(connec.getOffsetPtr());
919   ConnectivityArray<INDIRECTION> connec_cpy(cell_type, n_IDs, values, offsets);
920   internal::check_equality(connec, connec_cpy);
921 }
922 
923 /*!
924  * \brief Check that the ConnectivityArray can be reconstructed from
925  *  a external buffers.
926  *
927  * \param [in] connec the ConnectivityArray to check.
928  */
checkExternalConstructor(const ConnectivityArray<TYPED_INDIRECTION> & connec)929 void checkExternalConstructor(const ConnectivityArray<TYPED_INDIRECTION>& connec)
930 {
931   ASSERT_TRUE(connec.isExternal());
932 
933   const IndexType n_IDs = connec.getNumberOfIDs();
934   IndexType* values = const_cast<IndexType*>(connec.getValuePtr());
935   IndexType* offsets = const_cast<IndexType*>(connec.getOffsetPtr());
936   CellType* types = const_cast<CellType*>(connec.getTypePtr());
937   ConnectivityArray<TYPED_INDIRECTION> connec_cpy(n_IDs, values, offsets, types);
938   internal::check_equality(connec, connec_cpy);
939 }
940 
941 } /* end namespace internal */
942 
943 /*******************************************************************************
944  *                          Append tests                                       *
945  ******************************************************************************/
946 
947 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,NoIndirectionNativeAppend)948 TEST(mint_connectivity_array, NoIndirectionNativeAppend)
949 {
950   constexpr IndexType max_IDs = 100;
951   constexpr IndexType max_values = hex_stride * max_IDs;
952   constexpr IndexType total_IDs = (max_IDs * (max_IDs + 1)) / 2;
953 
954   /* Allocate and populate the values buffer. */
955   const IndexType* values = internal::createValues(max_values);
956 
957   /* Create the native storage ConnectivityArrays to be tested. */
958   ConnectivityArray<NO_INDIRECTION> native_vertex(VERTEX);
959   internal::checkConnectivity(native_vertex, false, 0, 0);
960 
961   ConnectivityArray<NO_INDIRECTION> native_hex(HEX);
962   internal::checkConnectivity(native_vertex, false, 0, 0);
963 
964   internal::testAppend(native_vertex, max_IDs, values);
965   internal::testAppend(native_hex, max_IDs, values);
966 
967   /* Check that the number of IDs is correct. */
968   internal::checkConnectivity(native_vertex,
969                               false,
970                               total_IDs,
971                               total_IDs * vertex_stride);
972   internal::checkConnectivity(native_hex, false, total_IDs, total_IDs * hex_stride);
973 
974   delete[] values;
975 }
976 
977 //------------------------------------------------------------------------------
TEST(mint_connectivity_array_DeathTest,NoIndirectionExternalAppend)978 TEST(mint_connectivity_array_DeathTest, NoIndirectionExternalAppend)
979 {
980   constexpr IndexType max_IDs = 100;
981   constexpr IndexType max_values = hex_stride * max_IDs;
982   constexpr IndexType total_IDs = (max_IDs * (max_IDs + 1)) / 2;
983 
984   /* Allocate and populate the values buffer. */
985   const IndexType* values = internal::createValues(max_values);
986 
987   /* Create the external storage ConnectivityArrays to be tested. */
988   IndexType* ext_vertex_values = new IndexType[total_IDs * vertex_stride];
989   ConnectivityArray<NO_INDIRECTION> ext_vertex(VERTEX,
990                                                0,
991                                                ext_vertex_values,
992                                                total_IDs);
993   internal::checkConnectivity(ext_vertex, true, 0, 0, ext_vertex_values);
994 
995   IndexType* ext_hex_values = new IndexType[total_IDs * hex_stride];
996   ConnectivityArray<NO_INDIRECTION> ext_hex(HEX, 0, ext_hex_values, total_IDs);
997   internal::checkConnectivity(ext_hex, true, 0, 0, ext_hex_values);
998 
999   /* Check that appending functions properly */
1000   internal::testAppend(ext_vertex, max_IDs, values);
1001   internal::testAppend(ext_hex, max_IDs, values);
1002 
1003   /* Check that the number of IDs is correct. */
1004   internal::checkConnectivity(ext_vertex,
1005                               true,
1006                               total_IDs,
1007                               total_IDs * vertex_stride,
1008                               ext_vertex_values);
1009   internal::checkConnectivity(ext_hex,
1010                               true,
1011                               total_IDs,
1012                               total_IDs * hex_stride,
1013                               ext_hex_values);
1014 
1015   /* Check that the external ConnectivityArrays cannot append any more. */
1016   EXPECT_DEATH_IF_SUPPORTED(ext_vertex.append(values), IGNORE_OUTPUT);
1017   EXPECT_DEATH_IF_SUPPORTED(ext_hex.append(values), IGNORE_OUTPUT);
1018 
1019   /* Check that the external constructor functions properly. */
1020   internal::checkExternalConstructor(ext_vertex);
1021   internal::checkExternalConstructor(ext_hex);
1022 
1023   delete[] values;
1024   delete[] ext_vertex_values;
1025   delete[] ext_hex_values;
1026 }
1027 
1028 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,NoIndirectionSidreAppend)1029 TEST(mint_connectivity_array, NoIndirectionSidreAppend)
1030 {
1031 #ifdef AXOM_MINT_USE_SIDRE
1032   constexpr IndexType max_IDs = 100;
1033   constexpr IndexType max_values = hex_stride * max_IDs;
1034   constexpr IndexType total_IDs = (max_IDs * (max_IDs + 1)) / 2;
1035 
1036   sidre::DataStore ds;
1037   sidre::Group* root = ds.getRoot();
1038 
1039   /* Allocate and populate the values buffer. */
1040   const IndexType* values = internal::createValues(max_values);
1041 
1042   /* Create the sidre storage ConnectivityArrays to be tested. */
1043   sidre::Group* vertex_group = root->createGroup("vertex");
1044   ConnectivityArray<NO_INDIRECTION> sidre_vertex(VERTEX, vertex_group, "test");
1045   internal::checkConnectivity(sidre_vertex, 0, 0, vertex_group);
1046 
1047   sidre::Group* hex_group = root->createGroup("hex");
1048   ConnectivityArray<NO_INDIRECTION> sidre_hex(HEX, hex_group, "test");
1049   internal::checkConnectivity(sidre_hex, 0, 0, hex_group);
1050 
1051   internal::testAppend(sidre_vertex, max_IDs, values);
1052   internal::testAppend(sidre_hex, max_IDs, values);
1053 
1054   /* Check that the number of IDs is correct. */
1055   internal::checkConnectivity(sidre_vertex,
1056                               total_IDs,
1057                               total_IDs * vertex_stride,
1058                               vertex_group);
1059   internal::checkConnectivity(sidre_hex,
1060                               total_IDs,
1061                               total_IDs * hex_stride,
1062                               hex_group);
1063 
1064   /* Check that restoring from sidre functions properly */
1065   internal::checkSidreConstructor(sidre_vertex);
1066   internal::checkSidreConstructor(sidre_hex);
1067 
1068   delete[] values;
1069 #else
1070   EXPECT_TRUE(true);
1071 #endif /* AXOM_MINT_USE_SIDRE */
1072 }
1073 
1074 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,IndirectionNativeAppend)1075 TEST(mint_connectivity_array, IndirectionNativeAppend)
1076 {
1077   constexpr IndexType max_IDs = 100;
1078 
1079   /* Allocate and populate the types and offsets buffer. */
1080   IndexType* offsets;
1081   CellType* types;
1082   const IndexType max_values =
1083     internal::createOffsetsAndTypes(max_IDs, offsets, types);
1084 
1085   /* Allocate and populate the values buffer. */
1086   const IndexType* values = internal::createValues(max_values);
1087 
1088   /* Calculate the total number of IDs and values. */
1089   IndexType total_IDs;
1090   IndexType total_values;
1091   internal::calcTotalIDsAndValues(max_IDs, total_IDs, total_values);
1092 
1093   /* Create the native storage ConnectivityArrays to be tested. */
1094   ConnectivityArray<INDIRECTION> native_vertex(VERTEX);
1095   internal::checkConnectivity(native_vertex, false, 0, 0);
1096 
1097   ConnectivityArray<TYPED_INDIRECTION> native_mixed;
1098   internal::checkConnectivity(native_mixed, false, 0, 0);
1099 
1100   /* Append the values */
1101   internal::testAppend(native_vertex, max_IDs, values, offsets);
1102   internal::testAppend(native_mixed, max_IDs, values, offsets, types);
1103 
1104   /* Check that the number of IDs and values is correct. */
1105   internal::checkConnectivity(native_vertex, false, total_IDs, total_values);
1106   internal::checkConnectivity(native_mixed, false, total_IDs, total_values);
1107 
1108   delete[] values;
1109   delete[] offsets;
1110   delete[] types;
1111 }
1112 
1113 //------------------------------------------------------------------------------
TEST(mint_connectivity_array_DeathTest,IndirectionExternalAppend)1114 TEST(mint_connectivity_array_DeathTest, IndirectionExternalAppend)
1115 {
1116   constexpr IndexType max_IDs = 100;
1117 
1118   /* Allocate and populate the types and offsets buffer. */
1119   IndexType* offsets;
1120   CellType* types;
1121   const IndexType max_values =
1122     internal::createOffsetsAndTypes(max_IDs, offsets, types);
1123 
1124   /* Allocate and populate the values buffer. */
1125   const IndexType* values = internal::createValues(max_values);
1126 
1127   /* Calculate the total number of IDs and values. */
1128   IndexType total_IDs;
1129   IndexType total_values;
1130   internal::calcTotalIDsAndValues(max_IDs, total_IDs, total_values);
1131 
1132   /* Create the external storage ConnectivityArrays to be tested. */
1133   IndexType* ext_vertex_values = new IndexType[total_values];
1134   IndexType* ext_vertex_offsets = new IndexType[total_IDs + 1];
1135   ConnectivityArray<INDIRECTION> ext_vertex(VERTEX,
1136                                             0,
1137                                             ext_vertex_values,
1138                                             ext_vertex_offsets,
1139                                             total_IDs,
1140                                             total_values);
1141   internal::checkConnectivity(ext_vertex,
1142                               true,
1143                               0,
1144                               0,
1145                               ext_vertex_values,
1146                               ext_vertex_offsets);
1147 
1148   IndexType* ext_mixed_values = new IndexType[total_IDs * hex_stride];
1149   IndexType* ext_mixed_offsets = new IndexType[total_IDs + 1];
1150   CellType* ext_mixed_types = new CellType[total_IDs];
1151   ConnectivityArray<TYPED_INDIRECTION> ext_mixed(0,
1152                                                  ext_mixed_values,
1153                                                  ext_mixed_offsets,
1154                                                  ext_mixed_types,
1155                                                  total_IDs,
1156                                                  total_values);
1157   internal::checkConnectivity(ext_mixed,
1158                               true,
1159                               0,
1160                               0,
1161                               ext_mixed_values,
1162                               ext_mixed_offsets,
1163                               ext_mixed_types);
1164 
1165   /* Check that appending functions properly */
1166   internal::testAppend(ext_vertex, max_IDs, values, offsets);
1167   internal::testAppend(ext_mixed, max_IDs, values, offsets, types);
1168 
1169   /* Check that the number of IDs and values is correct. */
1170   internal::checkConnectivity(ext_vertex,
1171                               true,
1172                               total_IDs,
1173                               total_values,
1174                               ext_vertex_values,
1175                               ext_vertex_offsets);
1176   internal::checkConnectivity(ext_mixed,
1177                               true,
1178                               total_IDs,
1179                               total_values,
1180                               ext_mixed_values,
1181                               ext_mixed_offsets,
1182                               ext_mixed_types);
1183 
1184   /* Check that the external ConnectivityArrays cannot append any more. */
1185   EXPECT_DEATH_IF_SUPPORTED(ext_vertex.append(values, 1), IGNORE_OUTPUT);
1186   EXPECT_DEATH_IF_SUPPORTED(ext_mixed.append(values, 1, VERTEX), IGNORE_OUTPUT);
1187 
1188   /* Check that the external constructor functions properly. */
1189   internal::checkExternalConstructor(ext_vertex);
1190   internal::checkExternalConstructor(ext_mixed);
1191 
1192   delete[] values;
1193   delete[] offsets;
1194   delete[] types;
1195   delete[] ext_vertex_values;
1196   delete[] ext_vertex_offsets;
1197   delete[] ext_mixed_values;
1198   delete[] ext_mixed_offsets;
1199   delete[] ext_mixed_types;
1200 }
1201 
1202 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,IndirectionSidreAppend)1203 TEST(mint_connectivity_array, IndirectionSidreAppend)
1204 {
1205 #ifdef AXOM_MINT_USE_SIDRE
1206   sidre::DataStore ds;
1207   sidre::Group* root = ds.getRoot();
1208 
1209   constexpr IndexType max_IDs = 100;
1210 
1211   /* Allocate and populate the types and offsets buffer. */
1212   IndexType* offsets;
1213   CellType* types;
1214   const IndexType max_values =
1215     internal::createOffsetsAndTypes(max_IDs, offsets, types);
1216 
1217   /* Allocate and populate the values buffer. */
1218   const IndexType* values = internal::createValues(max_values);
1219 
1220   /* Calculate the total number of IDs and values. */
1221   IndexType total_IDs;
1222   IndexType total_values;
1223   internal::calcTotalIDsAndValues(max_IDs, total_IDs, total_values);
1224 
1225   /* Create the sidre storage ConnectivityArrays to be tested. */
1226   sidre::Group* vertex_group = root->createGroup("vertex");
1227   ConnectivityArray<INDIRECTION> sidre_vertex(VERTEX, vertex_group, "test");
1228   internal::checkConnectivity(sidre_vertex, 0, 0, vertex_group);
1229 
1230   sidre::Group* mixed_group = root->createGroup("mixed");
1231   ConnectivityArray<TYPED_INDIRECTION> sidre_mixed(mixed_group, "test");
1232   internal::checkConnectivity(sidre_mixed, 0, 0, mixed_group);
1233 
1234   /* Append the values */
1235   internal::testAppend(sidre_vertex, max_IDs, values, offsets);
1236   internal::testAppend(sidre_mixed, max_IDs, values, offsets, types);
1237 
1238   /* Check that the number of IDs and values is correct. */
1239   internal::checkConnectivity(sidre_vertex, total_IDs, total_values, vertex_group);
1240   internal::checkConnectivity(sidre_mixed, total_IDs, total_values, mixed_group);
1241 
1242   /* Check that restoring from sidre functions properly */
1243   internal::checkSidreConstructor(sidre_vertex);
1244   internal::checkSidreConstructor(sidre_mixed);
1245 
1246   delete[] values;
1247   delete[] offsets;
1248   delete[] types;
1249 
1250 #else
1251   EXPECT_TRUE(true);
1252 #endif /* AXOM_MINT_USE_SIDRE */
1253 }
1254 
1255 /*******************************************************************************
1256  *                          Set tests                                          *
1257  ******************************************************************************/
1258 
1259 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,NoIndirectionNativeSet)1260 TEST(mint_connectivity_array, NoIndirectionNativeSet)
1261 {
1262   constexpr IndexType max_IDs = 100;
1263   constexpr IndexType max_values = hex_stride * max_IDs;
1264   constexpr IndexType total_IDs = (max_IDs * (max_IDs + 1)) / 2;
1265 
1266   /* Allocate and populate the values buffer. */
1267   const IndexType* initial_values = internal::createValues(max_values, -1);
1268   const IndexType* values = internal::createValues(max_values);
1269 
1270   /* Create the native storage ConnectivityArrays to be tested. */
1271   ConnectivityArray<NO_INDIRECTION> native_vertex(VERTEX);
1272   internal::checkConnectivity(native_vertex, false, 0, 0);
1273 
1274   ConnectivityArray<NO_INDIRECTION> native_hex(HEX);
1275   internal::checkConnectivity(native_vertex, false, 0, 0);
1276 
1277   /* Append and set the values */
1278   internal::testSet(native_vertex, max_IDs, initial_values, values);
1279   internal::testSet(native_hex, max_IDs, initial_values, values);
1280 
1281   /* Check that the number of IDs is correct. */
1282   internal::checkConnectivity(native_vertex,
1283                               false,
1284                               total_IDs,
1285                               total_IDs * vertex_stride);
1286   internal::checkConnectivity(native_hex, false, total_IDs, total_IDs * hex_stride);
1287 
1288   delete[] values;
1289   delete[] initial_values;
1290 }
1291 
1292 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,NoIndirectionExternalSet)1293 TEST(mint_connectivity_array, NoIndirectionExternalSet)
1294 {
1295   constexpr IndexType max_IDs = 100;
1296   constexpr IndexType max_values = hex_stride * max_IDs;
1297   constexpr IndexType total_IDs = (max_IDs * (max_IDs + 1)) / 2;
1298 
1299   /* Allocate and populate the values buffer. */
1300   const IndexType* initial_values = internal::createValues(max_values, -1);
1301   const IndexType* values = internal::createValues(max_values);
1302 
1303   /* Create the external storage ConnectivityArrays to be tested. */
1304   IndexType* ext_vertex_values = new IndexType[total_IDs * vertex_stride];
1305   ConnectivityArray<NO_INDIRECTION> ext_vertex(VERTEX,
1306                                                0,
1307                                                ext_vertex_values,
1308                                                total_IDs);
1309   internal::checkConnectivity(ext_vertex, true, 0, 0, ext_vertex_values);
1310 
1311   IndexType* ext_hex_values = new IndexType[total_IDs * hex_stride];
1312   ConnectivityArray<NO_INDIRECTION> ext_hex(HEX, 0, ext_hex_values, total_IDs);
1313   internal::checkConnectivity(ext_hex, true, 0, 0, ext_hex_values);
1314 
1315   /* Append and set the values */
1316   internal::testSet(ext_vertex, max_IDs, initial_values, values);
1317   internal::testSet(ext_hex, max_IDs, initial_values, values);
1318 
1319   /* Check that the number of IDs is correct. */
1320   internal::checkConnectivity(ext_vertex,
1321                               true,
1322                               total_IDs,
1323                               total_IDs * vertex_stride,
1324                               ext_vertex_values);
1325   internal::checkConnectivity(ext_hex,
1326                               true,
1327                               total_IDs,
1328                               total_IDs * hex_stride,
1329                               ext_hex_values);
1330 
1331   /* Check that the external constructor functions properly. */
1332   internal::checkExternalConstructor(ext_vertex);
1333   internal::checkExternalConstructor(ext_hex);
1334 
1335   delete[] values;
1336   delete[] initial_values;
1337   delete[] ext_vertex_values;
1338   delete[] ext_hex_values;
1339 }
1340 
1341 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,NoIndirectionSidreSet)1342 TEST(mint_connectivity_array, NoIndirectionSidreSet)
1343 {
1344 #ifdef AXOM_MINT_USE_SIDRE
1345   constexpr IndexType max_IDs = 100;
1346   constexpr IndexType max_values = hex_stride * max_IDs;
1347   constexpr IndexType total_IDs = (max_IDs * (max_IDs + 1)) / 2;
1348 
1349   sidre::DataStore ds;
1350   sidre::Group* root = ds.getRoot();
1351 
1352   /* Allocate and populate the values buffer. */
1353   const IndexType* initial_values = internal::createValues(max_values, -1);
1354   const IndexType* values = internal::createValues(max_values);
1355 
1356   /* Create the sidre storage ConnectivityArrays to be tested. */
1357   sidre::Group* vertex_group = root->createGroup("vertex");
1358   ConnectivityArray<NO_INDIRECTION> sidre_vertex(VERTEX, vertex_group, "test");
1359   internal::checkConnectivity(sidre_vertex, 0, 0, vertex_group);
1360 
1361   sidre::Group* hex_group = root->createGroup("hex");
1362   ConnectivityArray<NO_INDIRECTION> sidre_hex(HEX, hex_group, "test");
1363   internal::checkConnectivity(sidre_hex, 0, 0, hex_group);
1364 
1365   /* Append and set the values */
1366   internal::testSet(sidre_vertex, max_IDs, initial_values, values);
1367   internal::testSet(sidre_hex, max_IDs, initial_values, values);
1368 
1369   /* Check that the number of IDs is correct. */
1370   internal::checkConnectivity(sidre_vertex,
1371                               total_IDs,
1372                               total_IDs * vertex_stride,
1373                               vertex_group);
1374   internal::checkConnectivity(sidre_hex,
1375                               total_IDs,
1376                               total_IDs * hex_stride,
1377                               hex_group);
1378 
1379   /* Check that restoring from sidre functions properly */
1380   internal::checkSidreConstructor(sidre_vertex);
1381   internal::checkSidreConstructor(sidre_hex);
1382 
1383   delete[] values;
1384   delete[] initial_values;
1385 #else
1386   EXPECT_TRUE(true);
1387 #endif /* AXOM_MINT_USE_SIDRE */
1388 }
1389 
1390 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,IndirectionNativeSet)1391 TEST(mint_connectivity_array, IndirectionNativeSet)
1392 {
1393   constexpr IndexType max_IDs = 100;
1394 
1395   /* Allocate and populate the types and offsets buffer. */
1396   IndexType* offsets;
1397   CellType* types;
1398   const IndexType max_values =
1399     internal::createOffsetsAndTypes(max_IDs, offsets, types);
1400 
1401   /* Allocate and populate the values buffer. */
1402   const IndexType* initial_values = internal::createValues(max_values, -1);
1403   const IndexType* values = internal::createValues(max_values);
1404 
1405   /* Calculate the total number of IDs and values. */
1406   IndexType total_IDs;
1407   IndexType total_values;
1408   internal::calcTotalIDsAndValues(max_IDs, total_IDs, total_values);
1409 
1410   /* Create the native storage ConnectivityArrays to be tested. */
1411   ConnectivityArray<INDIRECTION> native_vertex(VERTEX);
1412   internal::checkConnectivity(native_vertex, false, 0, 0);
1413 
1414   ConnectivityArray<TYPED_INDIRECTION> native_mixed;
1415   internal::checkConnectivity(native_mixed, false, 0, 0);
1416 
1417   /* Append and set the values */
1418   internal::testSet(native_vertex, max_IDs, initial_values, values, offsets);
1419   internal::testSet(native_mixed, max_IDs, initial_values, values, offsets, types);
1420 
1421   /* Check that the number of IDs and values is correct. */
1422   internal::checkConnectivity(native_vertex, false, total_IDs, total_values);
1423   internal::checkConnectivity(native_mixed, false, total_IDs, total_values);
1424 
1425   delete[] values;
1426   delete[] initial_values;
1427   delete[] offsets;
1428   delete[] types;
1429 }
1430 
1431 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,IndirectionExternalSet)1432 TEST(mint_connectivity_array, IndirectionExternalSet)
1433 {
1434   constexpr IndexType max_IDs = 100;
1435 
1436   /* Allocate and populate the types and offsets buffer. */
1437   IndexType* offsets;
1438   CellType* types;
1439   const IndexType max_values =
1440     internal::createOffsetsAndTypes(max_IDs, offsets, types);
1441 
1442   /* Allocate and populate the values buffer. */
1443   const IndexType* initial_values = internal::createValues(max_values, -1);
1444   const IndexType* values = internal::createValues(max_values);
1445 
1446   /* Calculate the total number of IDs and values. */
1447   IndexType total_IDs;
1448   IndexType total_values;
1449   internal::calcTotalIDsAndValues(max_IDs, total_IDs, total_values);
1450 
1451   /* Create the external storage ConnectivityArrays to be tested. */
1452   IndexType* ext_vertex_values = new IndexType[total_values];
1453   IndexType* ext_vertex_offsets = new IndexType[total_IDs + 1];
1454   ConnectivityArray<INDIRECTION> ext_vertex(VERTEX,
1455                                             0,
1456                                             ext_vertex_values,
1457                                             ext_vertex_offsets,
1458                                             total_IDs,
1459                                             total_values);
1460   internal::checkConnectivity(ext_vertex,
1461                               true,
1462                               0,
1463                               0,
1464                               ext_vertex_values,
1465                               ext_vertex_offsets);
1466 
1467   IndexType* ext_mixed_values = new IndexType[total_IDs * hex_stride];
1468   IndexType* ext_mixed_offsets = new IndexType[total_IDs + 1];
1469   CellType* ext_mixed_types = new CellType[total_IDs];
1470   ConnectivityArray<TYPED_INDIRECTION> ext_mixed(0,
1471                                                  ext_mixed_values,
1472                                                  ext_mixed_offsets,
1473                                                  ext_mixed_types,
1474                                                  total_IDs,
1475                                                  total_values);
1476   internal::checkConnectivity(ext_mixed,
1477                               true,
1478                               0,
1479                               0,
1480                               ext_mixed_values,
1481                               ext_mixed_offsets,
1482                               ext_mixed_types);
1483 
1484   /* Append and set the values */
1485   internal::testSet(ext_vertex, max_IDs, initial_values, values, offsets);
1486   internal::testSet(ext_mixed, max_IDs, initial_values, values, offsets, types);
1487 
1488   /* Check that the number of IDs and values is correct. */
1489   internal::checkConnectivity(ext_vertex,
1490                               true,
1491                               total_IDs,
1492                               total_values,
1493                               ext_vertex_values,
1494                               ext_vertex_offsets);
1495   internal::checkConnectivity(ext_mixed,
1496                               true,
1497                               total_IDs,
1498                               total_values,
1499                               ext_mixed_values,
1500                               ext_mixed_offsets,
1501                               ext_mixed_types);
1502 
1503   /* Check that the external constructor functions properly. */
1504   internal::checkExternalConstructor(ext_vertex);
1505   internal::checkExternalConstructor(ext_mixed);
1506 
1507   delete[] values;
1508   delete[] offsets;
1509   delete[] types;
1510   delete[] ext_vertex_values;
1511   delete[] ext_vertex_offsets;
1512   delete[] ext_mixed_values;
1513   delete[] ext_mixed_offsets;
1514   delete[] ext_mixed_types;
1515 }
1516 
1517 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,IndirectionSidreSet)1518 TEST(mint_connectivity_array, IndirectionSidreSet)
1519 {
1520 #ifdef AXOM_MINT_USE_SIDRE
1521   sidre::DataStore ds;
1522   sidre::Group* root = ds.getRoot();
1523 
1524   constexpr IndexType max_IDs = 100;
1525 
1526   /* Allocate and populate the types and offsets buffer. */
1527   IndexType* offsets;
1528   CellType* types;
1529   const IndexType max_values =
1530     internal::createOffsetsAndTypes(max_IDs, offsets, types);
1531 
1532   /* Allocate and populate the values buffer. */
1533   const IndexType* initial_values = internal::createValues(max_values, -1);
1534   const IndexType* values = internal::createValues(max_values);
1535 
1536   /* Calculate the total number of IDs and values. */
1537   IndexType total_IDs;
1538   IndexType total_values;
1539   internal::calcTotalIDsAndValues(max_IDs, total_IDs, total_values);
1540 
1541   /* Create the sidre storage ConnectivityArrays to be tested. */
1542   sidre::Group* vertex_group = root->createGroup("vertex");
1543   ConnectivityArray<INDIRECTION> sidre_vertex(VERTEX, vertex_group, "test");
1544   internal::checkConnectivity(sidre_vertex, 0, 0, vertex_group);
1545 
1546   sidre::Group* mixed_group = root->createGroup("mixed");
1547   ConnectivityArray<TYPED_INDIRECTION> sidre_mixed(mixed_group, "test");
1548   internal::checkConnectivity(sidre_mixed, 0, 0, mixed_group);
1549 
1550   /* Append and set the values */
1551   internal::testSet(sidre_vertex, max_IDs, initial_values, values, offsets);
1552   internal::testSet(sidre_mixed, max_IDs, initial_values, values, offsets, types);
1553 
1554   /* Check that the number of IDs and values is correct. */
1555   internal::checkConnectivity(sidre_vertex, total_IDs, total_values, vertex_group);
1556   internal::checkConnectivity(sidre_mixed, total_IDs, total_values, mixed_group);
1557 
1558   /* Check that restoring from sidre functions properly */
1559   internal::checkSidreConstructor(sidre_vertex);
1560   internal::checkSidreConstructor(sidre_mixed);
1561 
1562   delete[] values;
1563   delete[] initial_values;
1564   delete[] offsets;
1565   delete[] types;
1566 
1567 #else
1568   EXPECT_TRUE(true);
1569 #endif /* AXOM_MINT_USE_SIDRE */
1570 }
1571 
1572 /*******************************************************************************
1573  *                          Insert tests                                       *
1574  ******************************************************************************/
1575 
1576 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,NoIndirectionNativeInsert)1577 TEST(mint_connectivity_array, NoIndirectionNativeInsert)
1578 {
1579   constexpr IndexType total_IDs = 500 * 6;
1580   constexpr IndexType max_values = hex_stride * total_IDs;
1581 
1582   /* Allocate and populate the values buffer. */
1583   const IndexType* values = internal::createValues(max_values);
1584 
1585   /* Create the native storage ConnectivityArrays to be tested. */
1586   ConnectivityArray<NO_INDIRECTION> native_vertex(VERTEX);
1587   internal::checkConnectivity(native_vertex, false, 0, 0);
1588 
1589   ConnectivityArray<NO_INDIRECTION> native_hex(HEX);
1590   internal::checkConnectivity(native_vertex, false, 0, 0);
1591 
1592   /* Insert the values */
1593   internal::testInsert(native_vertex, total_IDs, values);
1594   internal::testInsert(native_hex, total_IDs, values);
1595 
1596   /* Check that the number of IDs is correct. */
1597   internal::checkConnectivity(native_vertex,
1598                               false,
1599                               total_IDs,
1600                               total_IDs * vertex_stride);
1601   internal::checkConnectivity(native_hex, false, total_IDs, total_IDs * hex_stride);
1602 
1603   delete[] values;
1604 }
1605 
1606 //------------------------------------------------------------------------------
TEST(mint_connectivity_array_DeathTest,NoIndirectionExternalInsert)1607 TEST(mint_connectivity_array_DeathTest, NoIndirectionExternalInsert)
1608 {
1609   constexpr IndexType total_IDs = 500 * 6;
1610   constexpr IndexType max_values = hex_stride * total_IDs;
1611 
1612   /* Allocate and populate the values buffer. */
1613   const IndexType* values = internal::createValues(max_values);
1614 
1615   /* Create the external storage ConnectivityArrays to be tested. */
1616   IndexType* ext_vertex_values = new IndexType[total_IDs * vertex_stride];
1617   ConnectivityArray<NO_INDIRECTION> ext_vertex(VERTEX,
1618                                                0,
1619                                                ext_vertex_values,
1620                                                total_IDs);
1621   internal::checkConnectivity(ext_vertex, true, 0, 0, ext_vertex_values);
1622 
1623   IndexType* ext_hex_values = new IndexType[total_IDs * hex_stride];
1624   ConnectivityArray<NO_INDIRECTION> ext_hex(HEX, 0, ext_hex_values, total_IDs);
1625   internal::checkConnectivity(ext_hex, true, 0, 0, ext_hex_values);
1626 
1627   /* Insert the values */
1628   internal::testInsert(ext_vertex, total_IDs, values);
1629   internal::testInsert(ext_hex, total_IDs, values);
1630 
1631   /* Check that the number of IDs is correct. */
1632   internal::checkConnectivity(ext_vertex,
1633                               true,
1634                               total_IDs,
1635                               total_IDs * vertex_stride,
1636                               ext_vertex_values);
1637   internal::checkConnectivity(ext_hex,
1638                               true,
1639                               total_IDs,
1640                               total_IDs * hex_stride,
1641                               ext_hex_values);
1642 
1643   /* Check that the external ConnectivityArrays cannot insert any more. */
1644   EXPECT_DEATH_IF_SUPPORTED(ext_vertex.insert(values, 0), IGNORE_OUTPUT);
1645   EXPECT_DEATH_IF_SUPPORTED(ext_hex.insert(values, 0), IGNORE_OUTPUT);
1646 
1647   /* Check that the external constructor functions properly. */
1648   internal::checkExternalConstructor(ext_vertex);
1649   internal::checkExternalConstructor(ext_hex);
1650 
1651   delete[] values;
1652   delete[] ext_vertex_values;
1653   delete[] ext_hex_values;
1654 }
1655 
1656 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,NoIndirectionSidreInsert)1657 TEST(mint_connectivity_array, NoIndirectionSidreInsert)
1658 {
1659 #ifdef AXOM_MINT_USE_SIDRE
1660   sidre::DataStore ds;
1661   sidre::Group* root = ds.getRoot();
1662 
1663   constexpr IndexType total_IDs = 500 * 6;
1664   constexpr IndexType max_values = hex_stride * total_IDs;
1665 
1666   /* Allocate and populate the values buffer. */
1667   const IndexType* values = internal::createValues(max_values);
1668 
1669   /* Create the sidre storage ConnectivityArrays to be tested. */
1670   sidre::Group* vertex_group = root->createGroup("vertex");
1671   ConnectivityArray<NO_INDIRECTION> sidre_vertex(VERTEX, vertex_group, "test");
1672   internal::checkConnectivity(sidre_vertex, 0, 0, vertex_group);
1673 
1674   sidre::Group* hex_group = root->createGroup("hex");
1675   ConnectivityArray<NO_INDIRECTION> sidre_hex(HEX, hex_group, "test");
1676   internal::checkConnectivity(sidre_hex, 0, 0, hex_group);
1677 
1678   /* Insert the values */
1679   internal::testInsert(sidre_vertex, total_IDs, values);
1680   internal::testInsert(sidre_hex, total_IDs, values);
1681 
1682   /* Check that the number of IDs is correct. */
1683   internal::checkConnectivity(sidre_vertex,
1684                               total_IDs,
1685                               total_IDs * vertex_stride,
1686                               vertex_group);
1687   internal::checkConnectivity(sidre_hex,
1688                               total_IDs,
1689                               total_IDs * hex_stride,
1690                               hex_group);
1691 
1692   /* Check that restoring from sidre functions properly */
1693   internal::checkSidreConstructor(sidre_vertex);
1694   internal::checkSidreConstructor(sidre_hex);
1695 
1696   delete[] values;
1697 #else
1698   EXPECT_TRUE(true);
1699 #endif /* AXOM_MINT_USE_SIDRE */
1700 }
1701 
1702 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,IndirectionNativeInsert)1703 TEST(mint_connectivity_array, IndirectionNativeInsert)
1704 {
1705   constexpr IndexType total_IDs = 500 * 6;
1706 
1707   /* Allocate and populate the types and offsets buffer. */
1708   IndexType* offsets;
1709   CellType* types;
1710   const IndexType total_values =
1711     internal::createOffsetsAndTypes(total_IDs, offsets, types);
1712 
1713   /* Allocate and populate the values buffer. */
1714   const IndexType* values = internal::createValues(total_values);
1715 
1716   /* Create the native storage ConnectivityArrays to be tested. */
1717   ConnectivityArray<INDIRECTION> native_vertex(VERTEX);
1718   internal::checkConnectivity(native_vertex, false, 0, 0);
1719 
1720   ConnectivityArray<TYPED_INDIRECTION> native_mixed;
1721   internal::checkConnectivity(native_mixed, false, 0, 0);
1722 
1723   /* Insert the values. */
1724   internal::testInsert(native_vertex, total_IDs, values, offsets);
1725   internal::testInsert(native_mixed, total_IDs, values, offsets, types);
1726 
1727   /* Check that the number of IDs and values is correct. */
1728   internal::checkConnectivity(native_vertex, false, total_IDs, total_values);
1729 
1730   delete[] values;
1731   delete[] offsets;
1732   delete[] types;
1733 }
1734 
1735 //------------------------------------------------------------------------------
TEST(mint_connectivity_array_DeathTest,IndirectionExternalInsert)1736 TEST(mint_connectivity_array_DeathTest, IndirectionExternalInsert)
1737 {
1738   constexpr IndexType total_IDs = 500 * 6;
1739 
1740   /* Allocate and populate the types and offsets buffer. */
1741   IndexType* offsets;
1742   CellType* types;
1743   const IndexType total_values =
1744     internal::createOffsetsAndTypes(total_IDs, offsets, types);
1745 
1746   /* Allocate and populate the values buffer. */
1747   const IndexType* values = internal::createValues(total_values);
1748 
1749   /* Create the external storage ConnectivityArrays to be tested. */
1750   IndexType* ext_vertex_values = new IndexType[total_values];
1751   IndexType* ext_vertex_offsets = new IndexType[total_IDs + 1];
1752   ConnectivityArray<INDIRECTION> ext_vertex(VERTEX,
1753                                             0,
1754                                             ext_vertex_values,
1755                                             ext_vertex_offsets,
1756                                             total_IDs,
1757                                             total_values);
1758   internal::checkConnectivity(ext_vertex,
1759                               true,
1760                               0,
1761                               0,
1762                               ext_vertex_values,
1763                               ext_vertex_offsets);
1764 
1765   IndexType* ext_mixed_values = new IndexType[total_IDs * hex_stride];
1766   IndexType* ext_mixed_offsets = new IndexType[total_IDs + 1];
1767   CellType* ext_mixed_types = new CellType[total_IDs];
1768   ConnectivityArray<TYPED_INDIRECTION> ext_mixed(0,
1769                                                  ext_mixed_values,
1770                                                  ext_mixed_offsets,
1771                                                  ext_mixed_types,
1772                                                  total_IDs,
1773                                                  total_values);
1774   internal::checkConnectivity(ext_mixed,
1775                               true,
1776                               0,
1777                               0,
1778                               ext_mixed_values,
1779                               ext_mixed_offsets,
1780                               ext_mixed_types);
1781 
1782   /* Insert the values. */
1783   internal::testInsert(ext_vertex, total_IDs, values, offsets);
1784   internal::testInsert(ext_mixed, total_IDs, values, offsets, types);
1785 
1786   /* Check that the number of IDs and values is correct. */
1787   internal::checkConnectivity(ext_vertex,
1788                               true,
1789                               total_IDs,
1790                               total_values,
1791                               ext_vertex_values,
1792                               ext_vertex_offsets);
1793   internal::checkConnectivity(ext_mixed,
1794                               true,
1795                               total_IDs,
1796                               total_values,
1797                               ext_mixed_values,
1798                               ext_mixed_offsets,
1799                               ext_mixed_types);
1800 
1801   /* Check that the external ConnectivityArrays cannot append any more. */
1802   EXPECT_DEATH_IF_SUPPORTED(ext_vertex.insert(values, 0, 1), IGNORE_OUTPUT);
1803   EXPECT_DEATH_IF_SUPPORTED(ext_mixed.insert(values, 0, 1, VERTEX),
1804                             IGNORE_OUTPUT);
1805 
1806   /* Check that the external constructor functions properly. */
1807   internal::checkExternalConstructor(ext_vertex);
1808   internal::checkExternalConstructor(ext_mixed);
1809 
1810   delete[] values;
1811   delete[] offsets;
1812   delete[] types;
1813   delete[] ext_vertex_values;
1814   delete[] ext_vertex_offsets;
1815   delete[] ext_mixed_values;
1816   delete[] ext_mixed_offsets;
1817   delete[] ext_mixed_types;
1818 }
1819 
1820 //------------------------------------------------------------------------------
TEST(mint_connectivity_array,IndirectionSidreInsert)1821 TEST(mint_connectivity_array, IndirectionSidreInsert)
1822 {
1823 #ifdef AXOM_MINT_USE_SIDRE
1824   sidre::DataStore ds;
1825   sidre::Group* root = ds.getRoot();
1826 
1827   constexpr IndexType total_IDs = 500 * 6;
1828 
1829   /* Allocate and populate the types and offsets buffer. */
1830   IndexType* offsets;
1831   CellType* types;
1832   const IndexType total_values =
1833     internal::createOffsetsAndTypes(total_IDs, offsets, types);
1834 
1835   /* Allocate and populate the values buffer. */
1836   const IndexType* values = internal::createValues(total_values);
1837 
1838   /* Create the sidre storage ConnectivityArrays to be tested. */
1839   sidre::Group* vertex_group = root->createGroup("vertex");
1840   ConnectivityArray<INDIRECTION> sidre_vertex(VERTEX, vertex_group, "test");
1841   internal::checkConnectivity(sidre_vertex, 0, 0, vertex_group);
1842 
1843   sidre::Group* mixed_group = root->createGroup("mixed");
1844   ConnectivityArray<TYPED_INDIRECTION> sidre_mixed(mixed_group, "test");
1845   internal::checkConnectivity(sidre_mixed, 0, 0, mixed_group);
1846 
1847   /* Insert the values */
1848   internal::testInsert(sidre_vertex, total_IDs, values, offsets);
1849   internal::testInsert(sidre_mixed, total_IDs, values, offsets, types);
1850 
1851   /* Check that the number of IDs and values is correct. */
1852   internal::checkConnectivity(sidre_vertex, total_IDs, total_values, vertex_group);
1853   internal::checkConnectivity(sidre_mixed, total_IDs, total_values, mixed_group);
1854 
1855   /* Check that restoring from sidre functions properly */
1856   internal::checkSidreConstructor(sidre_vertex);
1857   internal::checkSidreConstructor(sidre_mixed);
1858 
1859   delete[] values;
1860   delete[] offsets;
1861   delete[] types;
1862 #else
1863   EXPECT_TRUE(true);
1864 #endif /* AXOM_MINT_USE_SIDRE */
1865 }
1866 
1867 /*******************************************************************************
1868  *                          Capacity tests                                     *
1869  ******************************************************************************/
1870 
1871 //------------------------------------------------------------------------------
TEST(mint_connectivity_array_DeathTest,NoIndirectionNativeCapacity)1872 TEST(mint_connectivity_array_DeathTest, NoIndirectionNativeCapacity)
1873 {
1874   constexpr IndexType n_IDs = 100;
1875   constexpr IndexType max_values = hex_stride * n_IDs;
1876 
1877   /* Allocate and populate the values buffer. */
1878   const IndexType* values = internal::createValues(max_values);
1879 
1880   for(double ratio = 0.75; ratio <= 3.0; ratio += 0.25)
1881   {
1882     /* Create the native storage ConnectivityArrays to be tested. */
1883     ConnectivityArray<NO_INDIRECTION> native_vertex(VERTEX);
1884     native_vertex.setResizeRatio(ratio);
1885     internal::checkConnectivity(native_vertex, false, 0, 0);
1886 
1887     ConnectivityArray<NO_INDIRECTION> native_hex(HEX);
1888     native_hex.setResizeRatio(ratio);
1889     internal::checkConnectivity(native_vertex, false, 0, 0);
1890 
1891     /* Append the values */
1892     if(ratio < 1.0)
1893     {
1894       EXPECT_DEATH_IF_SUPPORTED(
1895         internal::testCapacity(native_vertex, n_IDs, values),
1896         IGNORE_OUTPUT);
1897       EXPECT_DEATH_IF_SUPPORTED(internal::testCapacity(native_hex, n_IDs, values),
1898                                 IGNORE_OUTPUT);
1899     }
1900     else
1901     {
1902       internal::testCapacity(native_vertex, n_IDs, values);
1903       internal::testCapacity(native_hex, n_IDs, values);
1904     }
1905   }
1906 
1907   delete[] values;
1908 }
1909 
1910 //------------------------------------------------------------------------------
TEST(mint_connectivity_array_DeathTest,NoIndirectionSidreCapacity)1911 TEST(mint_connectivity_array_DeathTest, NoIndirectionSidreCapacity)
1912 {
1913 #ifdef AXOM_MINT_USE_SIDRE
1914   sidre::DataStore ds;
1915   sidre::Group* root = ds.getRoot();
1916 
1917   constexpr IndexType n_IDs = 100;
1918   constexpr IndexType max_values = hex_stride * n_IDs;
1919 
1920   /* Allocate and populate the values buffer. */
1921   const IndexType* values = internal::createValues(max_values);
1922 
1923   for(double ratio = 0.75; ratio <= 3.0; ratio += 0.25)
1924   {
1925     /* Create the sidre storage ConnectivityArrays to be tested. */
1926     sidre::Group* vertex_group = root->createGroup("vertex");
1927     ConnectivityArray<NO_INDIRECTION> sidre_vertex(VERTEX, vertex_group, "test");
1928     sidre_vertex.setResizeRatio(ratio);
1929     internal::checkConnectivity(sidre_vertex, 0, 0, vertex_group);
1930 
1931     sidre::Group* hex_group = root->createGroup("hex");
1932     ConnectivityArray<NO_INDIRECTION> sidre_hex(HEX, hex_group, "test");
1933     sidre_hex.setResizeRatio(ratio);
1934     internal::checkConnectivity(sidre_hex, 0, 0, hex_group);
1935 
1936     /* Append the values */
1937     if(ratio < 1.0)
1938     {
1939       EXPECT_DEATH_IF_SUPPORTED(
1940         internal::testCapacity(sidre_vertex, n_IDs, values),
1941         IGNORE_OUTPUT);
1942       EXPECT_DEATH_IF_SUPPORTED(internal::testCapacity(sidre_hex, n_IDs, values),
1943                                 IGNORE_OUTPUT);
1944     }
1945     else
1946     {
1947       internal::testCapacity(sidre_vertex, n_IDs, values);
1948       internal::testCapacity(sidre_hex, n_IDs, values);
1949     }
1950 
1951     root->destroyGroups();
1952   }
1953 
1954   delete[] values;
1955 #else
1956   EXPECT_TRUE(true);
1957 #endif /* AXOM_MINT_USE_SIDRE */
1958 }
1959 
1960 //------------------------------------------------------------------------------
TEST(mint_connectivity_array_DeathTest,IndirectionNativeCapacity)1961 TEST(mint_connectivity_array_DeathTest, IndirectionNativeCapacity)
1962 {
1963   constexpr IndexType n_IDs = 100;
1964 
1965   /* Allocate and populate the types and offsets buffer. */
1966   IndexType* offsets;
1967   CellType* types;
1968   const IndexType max_values =
1969     internal::createOffsetsAndTypes(n_IDs, offsets, types);
1970 
1971   /* Allocate and populate the values buffer. */
1972   const IndexType* values = internal::createValues(max_values);
1973 
1974   for(double ratio = 0.75; ratio <= 3.0; ratio += 0.25)
1975   {
1976     /* Create the native storage ConnectivityArrays to be tested. */
1977     ConnectivityArray<INDIRECTION> native_vertex(VERTEX, 0, 0);
1978     native_vertex.setResizeRatio(ratio);
1979     internal::checkConnectivity(native_vertex, false, 0, 0);
1980 
1981     ConnectivityArray<TYPED_INDIRECTION> native_mixed(0, 0);
1982     native_mixed.setResizeRatio(ratio);
1983     internal::checkConnectivity(native_mixed, false, 0, 0);
1984 
1985     /* Append the values */
1986     if(ratio < 1.0)
1987     {
1988       EXPECT_DEATH_IF_SUPPORTED(
1989         internal::testCapacity(native_vertex, n_IDs, values, offsets),
1990         IGNORE_OUTPUT);
1991       EXPECT_DEATH_IF_SUPPORTED(
1992         internal::testCapacity(native_mixed, n_IDs, values, offsets, types),
1993         IGNORE_OUTPUT);
1994     }
1995     else
1996     {
1997       internal::testCapacity(native_vertex, n_IDs, values, offsets);
1998       internal::testCapacity(native_mixed, n_IDs, values, offsets, types);
1999     }
2000   }
2001 
2002   delete[] values;
2003   delete[] offsets;
2004   delete[] types;
2005 }
2006 
2007 //------------------------------------------------------------------------------
TEST(mint_connectivity_array_DeathTest,IndirectionSidreCapacity)2008 TEST(mint_connectivity_array_DeathTest, IndirectionSidreCapacity)
2009 {
2010 #ifdef AXOM_MINT_USE_SIDRE
2011   sidre::DataStore ds;
2012   sidre::Group* root = ds.getRoot();
2013 
2014   constexpr IndexType n_IDs = 100;
2015 
2016   /* Allocate and populate the types and offsets buffer. */
2017   IndexType* offsets;
2018   CellType* types;
2019   const IndexType max_values =
2020     internal::createOffsetsAndTypes(n_IDs, offsets, types);
2021 
2022   /* Allocate and populate the values buffer. */
2023   const IndexType* values = internal::createValues(max_values);
2024 
2025   for(double ratio = 0.75; ratio <= 3.0; ratio += 0.25)
2026   {
2027     /* Create the sidre storage ConnectivityArrays to be tested. */
2028     sidre::Group* vertex_group = root->createGroup("vertex");
2029     ConnectivityArray<INDIRECTION> sidre_vertex(VERTEX, vertex_group, "test", 0, 0);
2030     sidre_vertex.setResizeRatio(ratio);
2031     internal::checkConnectivity(sidre_vertex, 0, 0, vertex_group);
2032 
2033     sidre::Group* mixed_group = root->createGroup("mixed");
2034     ConnectivityArray<TYPED_INDIRECTION> sidre_mixed(mixed_group, "test", 0, 0);
2035     sidre_mixed.setResizeRatio(ratio);
2036     internal::checkConnectivity(sidre_mixed, 0, 0, mixed_group);
2037 
2038     /* Append the values */
2039     if(ratio < 1.0)
2040     {
2041       EXPECT_DEATH_IF_SUPPORTED(
2042         internal::testCapacity(sidre_vertex, n_IDs, values, offsets),
2043         IGNORE_OUTPUT);
2044       EXPECT_DEATH_IF_SUPPORTED(
2045         internal::testCapacity(sidre_mixed, n_IDs, values, offsets, types),
2046         IGNORE_OUTPUT);
2047     }
2048     else
2049     {
2050       internal::testCapacity(sidre_vertex, n_IDs, values, offsets);
2051       internal::testCapacity(sidre_mixed, n_IDs, values, offsets, types);
2052     }
2053 
2054     root->destroyGroups();
2055   }
2056 
2057   delete[] values;
2058   delete[] offsets;
2059   delete[] types;
2060 #else
2061   EXPECT_TRUE(true);
2062 #endif /* AXOM_MINT_USE_SIDRE */
2063 }
2064 
2065 } /* end namespace mint */
2066 } /* end namespace axom */
2067 
2068 //------------------------------------------------------------------------------
2069 using axom::slic::SimpleLogger;
2070 
main(int argc,char * argv[])2071 int main(int argc, char* argv[])
2072 {
2073   int result = 0;
2074   ::testing::InitGoogleTest(&argc, argv);
2075   SimpleLogger logger;
2076   result = RUN_ALL_TESTS();
2077   return result;
2078 }
2079