File: TestHyperTreeGridRemoveGhostCells.cxx

package info (click to toggle)
vtk9 9.5.2%2Bdfsg3-4
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 205,916 kB
  • sloc: cpp: 2,336,565; ansic: 327,116; python: 111,200; yacc: 4,104; java: 3,977; sh: 3,032; xml: 2,771; perl: 2,189; lex: 1,787; makefile: 178; javascript: 165; objc: 153; tcl: 59
file content (153 lines) | stat: -rw-r--r-- 4,659 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause

#include "vtkCellData.h"
#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridNonOrientedCursor.h"
#include "vtkHyperTreeGridRemoveGhostCells.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkTestUtilities.h"
#include "vtkUnsignedCharArray.h"
#include "vtkXMLHyperTreeGridReader.h"

#include "vtkLogger.h"

namespace
{
/**
 * Recursively process the Hyper Tree, add ghost cell ids from the ghost array
 * to the ghostIds vector, and add non-ghost cell ids to nonGhostIds
 */
void FillGhostIdsVectors(vtkHyperTreeGridNonOrientedCursor* cursor,
  std::vector<vtkIdType>& ghostIds, std::vector<vtkIdType>& nonGhostIds,
  vtkUnsignedCharArray* ghostArray)
{
  vtkIdType currentId = cursor->GetGlobalNodeIndex();
  if (cursor->IsMasked())
  {
    return;
  }

  if (ghostArray->GetTuple1(currentId))
  {
    ghostIds.emplace_back(currentId);
    return;
  }
  else
  {
    nonGhostIds.emplace_back(currentId);
  }

  if (!cursor->IsLeaf())
  {
    for (int child = 0; child < cursor->GetNumberOfChildren(); ++child)
    {
      cursor->ToChild(child);
      ::FillGhostIdsVectors(cursor, ghostIds, nonGhostIds, ghostArray);
      cursor->ToParent();
    }
  }
}

/**
 * Recursively process the Hyper Tree and add the not hidden cell ids to a vector
 */
void FillUnmaskedIdsVector(
  vtkHyperTreeGridNonOrientedCursor* cursor, std::vector<vtkIdType>& unmaskedIds)
{
  vtkIdType currentId = cursor->GetGlobalNodeIndex();
  if (!cursor->IsMasked())
  {
    unmaskedIds.emplace_back(currentId);
  }

  if (!cursor->IsLeaf() && !cursor->IsMasked())
  {
    for (int child = 0; child < cursor->GetNumberOfChildren(); ++child)
    {
      cursor->ToChild(child);
      ::FillUnmaskedIdsVector(cursor, unmaskedIds);
      cursor->ToParent();
    }
  }
}
}

int TestHyperTreeGridRemoveGhostCells(int argc, char* argv[])
{
  int ret = EXIT_SUCCESS;

  // Read HTG file containing ghost cells
  vtkNew<vtkXMLHyperTreeGridReader> reader;
  char* ghostFile = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/HTG/ghost.htg");
  reader->SetFileName(ghostFile);
  delete[] ghostFile;

  // Remove ghost cells from input HTG
  vtkNew<vtkHyperTreeGridRemoveGhostCells> removeGhosts;
  removeGhosts->SetInputConnection(reader->GetOutputPort());
  removeGhosts->Update();

  vtkHyperTreeGrid* inputHTG = vtkHyperTreeGrid::SafeDownCast(reader->GetOutput());
  vtkHyperTreeGrid* outputHTG = removeGhosts->GetHyperTreeGridOutput();

  // Go through the input HTG and collect leaf ghost cells and unmasked non-ghost cells.
  std::vector<vtkIdType> inputGhostIds;
  std::vector<vtkIdType> inputNonGhostIds;
  inputGhostIds.reserve(inputHTG->GetNumberOfCells());
  inputNonGhostIds.reserve(inputHTG->GetNumberOfCells());

  vtkUnsignedCharArray* inputGhostArray = inputHTG->GetGhostCells();
  vtkIdType inIndex = 0;
  vtkHyperTreeGrid::vtkHyperTreeGridIterator it;
  inputHTG->InitializeTreeIterator(it);
  vtkNew<vtkHyperTreeGridNonOrientedCursor> cursor;
  while (it.GetNextTree(inIndex))
  {
    inputHTG->InitializeNonOrientedCursor(cursor, inIndex, true);
    ::FillGhostIdsVectors(cursor, inputGhostIds, inputNonGhostIds, inputGhostArray);
  }

  // Go through the output and collect unmasked cells
  std::vector<vtkIdType> outputUnmasked;
  outputUnmasked.reserve(outputHTG->GetNumberOfCells());
  outputHTG->InitializeTreeIterator(it);
  while (it.GetNextTree(inIndex))
  {
    outputHTG->InitializeNonOrientedCursor(cursor, inIndex, true);
    ::FillUnmaskedIdsVector(cursor, outputUnmasked);
  }

  // All input ghost cells should be masked in the output
  for (vtkIdType ghostId : inputGhostIds)
  {
    if (std::find(outputUnmasked.begin(), outputUnmasked.end(), ghostId) != outputUnmasked.end())
    {
      vtkErrorWithObjectMacro(
        nullptr, << "Ghost cell " << ghostId << " remains unmasked in output HTG but should be.");
      ret = EXIT_FAILURE;
    }
  }

  // All input unmasked non-ghost cells should stay unmasked in the output
  for (vtkIdType nonGhostId : inputNonGhostIds)
  {
    if (std::find(outputUnmasked.begin(), outputUnmasked.end(), nonGhostId) == outputUnmasked.end())
    {
      vtkErrorWithObjectMacro(
        nullptr, << "Cell " << nonGhostId << " has been masked in output HTG but shouldn't.");
      ret = EXIT_FAILURE;
    }
  }

  // The extracted cells don't have a ghost cell array
  if (outputHTG->GetGhostCells() != nullptr)
  {
    vtkErrorWithObjectMacro(
      nullptr, << "Extracted ghost cells should not have a ghost array anymore.");
    ret = EXIT_FAILURE;
  }

  return ret;
}