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 154 155 156 157 158 159
|
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
#include "vtkOpenFOAMReader.h"
#include "vtkCellData.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkNew.h"
#include "vtkPolyData.h"
#include "vtkTestUtilities.h"
#include <map>
int TestOpenFOAMReaderRegEx(int argc, char* argv[])
{
// Placeholder file in the OpenFOAM case
char* filename =
vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/OpenFOAM/regex/test.foam");
// Read the case to get list of boundary patches and fields
vtkNew<vtkOpenFOAMReader> reader;
reader->SetFileName(filename);
delete[] filename;
reader->Update();
// Re-read again, this time with all patches (i.e. polydata)
reader->EnableAllPatchArrays();
reader->EnableAllCellArrays();
reader->Update();
// Now, this is what we expect to be read from the OpenFOAM test case.
// Every time a field at a given patch is read and verified, its data
// are erased from this data structure, until at the end it should remain
// totally empty.
std::map<std::string, std::map<std::string, std::vector<double>>> expected_data = {
{
"inlet",
{
{ "p", { 0 } },
{ "U", { 1.0, 0.0, 0.0 } },
},
},
{
"outlet",
{
{ "p", { 0 } },
{ "U", { 1.0, 0.0, 0.0 } },
},
},
{
"frontAndBack",
{
{ "p", { 0 } },
{ "U", { 1.0, 0.0, 0.0 } },
},
},
{
"slippyWall", // present in the test case as "*Wall" regex only
{
{ "p", { 0 } },
{ "U", { 1.0, 0.0, 0.0 } },
},
},
{
"stickyWall", // present in the test case explicitly
{
{ "p", { 0 } },
{ "U", { 0.0, 0.0, 0.0 } },
},
},
};
// Print summary
vtkMultiBlockDataSet* result = reader->GetOutput();
if (result->GetNumberOfBlocks() > 1)
{
if (vtkMultiBlockDataSet* patches = vtkMultiBlockDataSet::SafeDownCast(result->GetBlock(1)))
{
int num_blocks = patches->GetNumberOfBlocks();
for (int i = 0; i < num_blocks; i++)
{
// Get name of this boundary patch and fail if this patch name is not expected
const char* patch_name = patches->GetMetaData(i)->Get(vtkCompositeDataSet::NAME());
if (!patch_name || expected_data.find(patch_name) == expected_data.end())
return EXIT_FAILURE;
if (vtkPolyData* patch = vtkPolyData::SafeDownCast(patches->GetBlock(i)))
{
if (vtkCellData* fields = patch->GetCellData())
{
for (int j = 0; j < fields->GetNumberOfArrays(); j++)
{
if (vtkFloatArray* array = vtkFloatArray::SafeDownCast(fields->GetAbstractArray(j)))
{
// Get name of this boundary field and fail if this name is not expected
const char* field_name = fields->GetArrayName(j);
if (!field_name ||
expected_data[patch_name].find(field_name) == expected_data[patch_name].end())
{
std::cout << "Unexpected field \"" << (field_name ? field_name : "(null)")
<< "\" at patch \"" << patch_name << "\"" << std::endl;
return EXIT_FAILURE;
}
// Fail if the number of components read is different than expected
const std::vector<double>& expected_components =
expected_data[patch_name][field_name];
int expected_num_components = static_cast<int>(expected_components.size());
if (expected_num_components != array->GetNumberOfComponents())
{
std::cout << "Unexpected number of components \""
<< array->GetNumberOfComponents() << "\" of field \"" << field_name
<< "\" at patch \"" << patch_name << "\"" << std::endl;
return EXIT_FAILURE;
}
// Fail if any field component is different than expected
for (int k = 0; k < array->GetNumberOfComponents(); k++)
{
if (array->GetValue(k) != expected_components[k])
{
std::cout << "Unexpected value \"" << array->GetValue(k) << "\" of component "
<< k << " of field \"" << field_name << "\" at patch \"" << patch_name
<< "\" (expected \"" << expected_components[k] << "\")" << std::endl;
return EXIT_FAILURE;
}
}
// OK, this boundary field is verified, and no longer expected -> remove
expected_data[patch_name].erase(field_name);
}
}
}
}
// OK, this boundary is verified -> remove
if (expected_data[patch_name].empty())
expected_data.erase(patch_name);
}
}
}
// By now, all expected data must have been read (and erased)
if (!expected_data.empty())
{
std::cout << "FAILURE! The following data were not read:" << std::endl;
for (const auto& p : expected_data)
{
std::cout << " patch \"" << p.first << "\"" << std::endl;
for (const auto& q : p.second)
std::cout << " field \"" << q.first << "\"" << std::endl;
}
}
return expected_data.empty() ? EXIT_SUCCESS : EXIT_FAILURE;
}
|