File: TestHyperTreeGridExtractGhostCells.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 (144 lines) | stat: -rw-r--r-- 4,572 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
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause

#include "vtkCellData.h"
#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridExtractGhostCells.h"
#include "vtkHyperTreeGridNonOrientedCursor.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 and add ghost cell ids from the ghost array
 * to the outputGhost vector
 */
void FillGhostVector(vtkHyperTreeGridNonOrientedCursor* cursor,
  std::vector<vtkIdType>& outputGhosts, vtkUnsignedCharArray* ghostArray)
{
  vtkIdType currentId = cursor->GetGlobalNodeIndex();
  if (ghostArray->GetTuple1(currentId))
  {
    outputGhosts.emplace_back(currentId);
  }

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

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

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

int TestHyperTreeGridExtractGhostCells(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;

  // Extract ghost cells
  vtkNew<vtkHyperTreeGridExtractGhostCells> extractor;
  extractor->SetOutputGhostArrayName("GhostOut");
  extractor->SetInputConnection(reader->GetOutputPort());
  extractor->Update();
  vtkHyperTreeGrid* extractedGhosts = extractor->GetHyperTreeGridOutput();
  vtkHyperTreeGrid* inputHTG = vtkHyperTreeGrid::SafeDownCast(reader->GetOutput());

  // Go through the input dataset and collect leaf ghost cells
  std::vector<vtkIdType> outputGhosts;
  outputGhosts.reserve(extractedGhosts->GetNumberOfCells());
  vtkUnsignedCharArray* ghostArray = inputHTG->GetGhostCells();
  vtkIdType inIndex = 0;
  vtkHyperTreeGrid::vtkHyperTreeGridIterator it;
  inputHTG->InitializeTreeIterator(it);
  vtkNew<vtkHyperTreeGridNonOrientedCursor> cursor;
  while (it.GetNextTree(inIndex))
  {
    inputHTG->InitializeNonOrientedCursor(cursor, inIndex, true);
    ::FillGhostVector(cursor, outputGhosts, ghostArray);
  }

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

  // All ghost cells should be unmasked and vice-versa
  for (vtkIdType ghostId : outputGhosts)
  {
    if (std::find(outputUnmasked.begin(), outputUnmasked.end(), ghostId) == outputUnmasked.end())
    {
      vtkErrorWithObjectMacro(
        nullptr, << "Could not find ghost cell " << ghostId << " in output HTG");
      ret = EXIT_FAILURE;
    }
  }

  for (vtkIdType unmaskedId : outputUnmasked)
  {
    if (std::find(outputGhosts.begin(), outputGhosts.end(), unmaskedId) == outputGhosts.end())
    {
      vtkErrorWithObjectMacro(
        nullptr, << "Could not find unmasked cell " << unmaskedId << " in input HTG ghosts");
      ret = EXIT_FAILURE;
    }
  }

  // The extracted cells don't have a ghost cell array,
  // but the array is kept with another name
  if (extractedGhosts->GetGhostCells() != nullptr)
  {
    vtkErrorWithObjectMacro(
      nullptr, << "Extracted ghost cells should not have a ghost array anymore");
    ret = EXIT_FAILURE;
  }
  if (extractedGhosts->GetCellData()->GetArray("GhostOut") == nullptr)
  {
    vtkErrorWithObjectMacro(nullptr, << "Could not find renamed ghost array in output HTG");
    ret = EXIT_FAILURE;
  }

  return ret;
}