32 #include <vtkCellData.h> 33 #include <vtkCellTypes.h> 34 #include <vtkPointData.h> 35 #include <vtkStaticPointLocator.h> 41 using nemAux::operator-;
42 using nemAux::operator*;
70 std::cout <<
"FETransfer constructed" << std::endl;
85 const std::vector<std::string> &newnames) {
86 if (arrayIDs.empty()) {
87 std::cerr <<
"No arrays are selected for interpolation" << std::endl;
93 if (newnames.empty()) {
94 int numArr = pd->GetNumberOfArrays();
95 for (
int arrayID : arrayIDs) {
96 if (arrayID >= numArr) {
97 std::cerr <<
"Selected arrayID is out of bounds\n";
98 std::cerr <<
"There are " << numArr <<
" point data arrays" 106 std::vector<vtkSmartPointer<vtkDoubleArray>> dasSource(arrayIDs.size());
107 std::vector<vtkSmartPointer<vtkDoubleArray>> dasTarget(arrayIDs.size());
110 for (
int id = 0;
id < arrayIDs.size(); ++
id) {
112 vtkSmartPointer<vtkDoubleArray> daSource =
113 vtkDoubleArray::SafeDownCast(pd->GetArray(arrayIDs[
id]));
115 int numComponent = daSource->GetNumberOfComponents();
117 vtkSmartPointer<vtkDoubleArray> daTarget =
120 if (newnames.empty()) {
121 daTarget->SetName(pd->GetArrayName(arrayIDs[
id]));
123 daTarget->SetName(newnames[
id].c_str());
125 daTarget->SetNumberOfComponents(numComponent);
128 std::cout <<
"Number of components : " << numComponent << std::endl;
132 dasSource[
id] = daSource;
133 dasTarget[
id] = daTarget;
139 std::cout <<
"Max number of threads available in transfer " 140 << omp_get_max_threads() << std::endl;
142 # pragma omp parallel default(none) \ 143 shared(dasSource, dasTarget, numTargetPoints, cout) 147 std::cout <<
"Number of threads used in transfer " 148 << omp_get_num_threads() << std::endl;
151 vtkSmartPointer<vtkGenericCell> tempCell =
163 vtkSmartPointer<vtkGenericCell> containingCell =
165 # pragma omp for schedule(static) 166 for (
int iPnt = 0; iPnt < numTargetPoints; ++iPnt) {
171 vtkSmartPointer<vtkGenericCell> containingCell =
178 std::cout <<
"TRANSFER TIME : " << timer.
elapsed() << std::endl;
179 for (
int id = 0;
id < arrayIDs.size(); ++
id) {
183 std::vector<vtkSmartPointer<vtkDoubleArray>> newDasSource(arrayIDs.size());
184 for (
int id = 0;
id < arrayIDs.size(); ++
id) {
185 int numComponent = dasTarget[
id]->GetNumberOfComponents();
187 vtkSmartPointer<vtkDoubleArray> newDaSource =
189 newDaSource->SetNumberOfComponents(numComponent);
191 newDasSource[
id] = newDaSource;
194 vtkSmartPointer<vtkGenericCell> genCell =
200 for (
int id = 0;
id < arrayIDs.size(); ++
id) {
201 int numComponent = newDasSource[
id]->GetNumberOfComponents();
202 double diffsum = 0.0;
204 auto *comps_old =
new double[numComponent];
205 auto *comps_new =
new double[numComponent];
206 dasSource[
id]->GetTuple(i, comps_old);
207 newDasSource[
id]->GetTuple(i, comps_new);
208 for (
int j = 0; j < numComponent; ++j) {
209 double diff = std::fabs((comps_new[j] - comps_old[j]) / comps_old[j]);
210 diffsum += std::isnan(diff) ? 0.0 : diff * diff;
217 std::cout <<
"RMS Error in Nodal Transfer: " 218 << (!(std::isnan(rmse) || std::isinf(rmse)) ? rmse : 0)
226 int pointId, vtkSmartPointer<vtkGenericCell> containingCell,
227 std::vector<vtkSmartPointer<vtkDoubleArray>> &dasSource,
228 std::vector<vtkSmartPointer<vtkDoubleArray>> &dasTarget,
const bool flip) {
232 double closestPoint[3];
247 for (
int i = 0; i < dasSource.size(); ++i) {
248 int numComponent = dasSource[i]->GetNumberOfComponents();
249 auto *comps =
new double[numComponent];
250 std::vector<double> interps(numComponent, 0.0);
251 for (
int m = 0; m < containingCell->GetNumberOfPoints(); ++m) {
252 int pntId = containingCell->GetPointId(m);
253 dasSource[i]->GetTuple(pntId, comps);
254 for (
int h = 0; h < numComponent; ++h) {
255 interps[h] += comps[h] * weights[m];
260 dasTarget[i]->SetTuple(pointId, interps.data());
275 const std::vector<std::string> &newnames) {
276 if (arrayIDs.empty()) {
277 std::cerr <<
"no arrays selected for interpolation" << std::endl;
283 if (newnames.empty()) {
284 int numArr = cd->GetNumberOfArrays();
285 for (
int arrayID : arrayIDs) {
286 if (arrayID >= numArr) {
287 std::cerr <<
"ERROR: arrayID is out of bounds\n";
288 std::cerr <<
"There are " << numArr <<
" cell data arrays" << std::endl;
294 std::vector<vtkSmartPointer<vtkDataArray>> dasSource(arrayIDs.size());
295 std::vector<vtkSmartPointer<vtkDoubleArray>> dasTarget(arrayIDs.size());
296 for (
int id = 0;
id < arrayIDs.size(); ++
id) {
298 vtkSmartPointer<vtkDataArray> daSource = cd->GetArray(arrayIDs[
id]);
300 int numComponent = daSource->GetNumberOfComponents();
302 vtkSmartPointer<vtkDoubleArray> daTarget =
305 if (newnames.empty())
306 daTarget->SetName(cd->GetArrayName(arrayIDs[
id]));
308 daTarget->SetName(newnames[
id].c_str());
309 daTarget->SetNumberOfComponents(numComponent);
311 dasSource[
id] = daSource;
312 dasTarget[
id] = daTarget;
317 std::cout <<
"Non-continuous cell data transfer invoked" << std::endl;
318 vtkSmartPointer<vtkGenericCell> genCell =
327 double closestPoint[3];
328 double *x = targetCenter.data();
338 std::cout <<
"Warning: For cell at " << x[0] <<
" " << x[1] <<
" " 339 << x[2] <<
" closest cell point found is at " 340 << closestPoint[0] <<
" " << closestPoint[1] <<
" " 341 << closestPoint[2] <<
" with distance " << minDist2
342 <<
", Cell IDs: source " <<
id <<
" target " << i
344 for (
int j = 0; j < dasSource.size(); ++j) {
345 int numComponent = dasSource[j]->GetNumberOfComponents();
347 std::vector<double> comps;
348 comps.resize(numComponent, 0.);
349 dasSource[j]->GetTuple(
id, &comps[0]);
350 dasTarget[j]->SetTuple(i, &comps[0]);
353 std::cerr <<
"Could not locate target cell " << i
354 <<
" from in the source mesh! Check the source mesh." 361 std::cout <<
"Continuous cell data transfer invoked" << std::endl;
363 std::vector<vtkSmartPointer<vtkDoubleArray>> dasSourceToPoint(
370 for (
int id = 0;
id < arrayIDs.size(); ++
id) {
372 vtkSmartPointer<vtkDataArray> daSource = cd->GetArray(arrayIDs[
id]);
374 int numComponent = daSource->GetNumberOfComponents();
376 vtkSmartPointer<vtkDoubleArray> daSourceToPoint =
378 daSourceToPoint->SetNumberOfComponents(numComponent);
384 int numSharedCells = cellIds->GetNumberOfIds();
388 std::vector<double> interps(numComponent, 0.0);
389 for (
int j = 0; j < numSharedCells; ++j) {
390 int cellId = cellIds->GetId(j);
392 std::vector<double> comps;
393 comps.resize(numComponent, 0.);
394 daSource->GetTuple(cellId, &comps[0]);
399 for (
int k = 0; k < numComponent; ++k) {
400 interps[k] += W * comps[k];
404 interps = (1.0 / totW) * interps;
405 daSourceToPoint->SetTuple(i, interps.data());
407 dasSourceToPoint[
id] = daSourceToPoint;
410 vtkSmartPointer<vtkGenericCell> genCell =
416 for (
int id = 0;
id < arrayIDs.size(); ++
id) {
423 int i, vtkSmartPointer<vtkGenericCell> genCell,
424 std::vector<vtkSmartPointer<vtkDoubleArray>> &dasSourceToPoint,
425 std::vector<vtkSmartPointer<vtkDoubleArray>> &dasTarget) {
433 double closestPoint[3];
434 double *x = targetCenter.data();
448 auto *weights =
new double[genCell->GetNumberOfPoints()];
449 result = genCell->EvaluatePosition(x,
nullptr, subId, pcoords, minDist2,
452 for (
int id = 0;
id < dasSourceToPoint.size(); ++
id) {
453 int numComponent = dasSourceToPoint[
id]->GetNumberOfComponents();
454 auto *comps =
new double[numComponent];
455 std::vector<double> interps(numComponent, 0.0);
456 for (
int m = 0; m < genCell->GetNumberOfPoints(); ++m) {
457 int pntId = genCell->GetPointId(m);
458 dasSourceToPoint[
id]->GetTuple(pntId, comps);
459 for (
int h = 0; h < numComponent; ++h) {
460 interps[h] += comps[h] * weights[m];
465 dasTarget[
id]->SetTuple(i, interps.data());
467 }
else if (result == 0) {
470 <<
"Could not locate point from target mesh in any cells sharing" 471 <<
" its nearest neighbor in the source mesh" << std::endl;
476 <<
"problem encountered evaluating position of point from target" 477 <<
" mesh with respect to cell in source mesh" << std::endl;
481 std::cerr <<
"Could not locate center of cell " << i
482 <<
" from target in source mesh" << std::endl;
490 std::cerr <<
"source and target meshes must be initialized" << std::endl;
497 std::vector<int> arrayIDs(numArr);
498 std::cout <<
"Transferring point arrays: " << std::endl;
499 for (
int i = 0; i < numArr; ++i) {
506 std::cout <<
"no point data found" << std::endl;
512 std::vector<int> arrayIDs(numArr);
513 std::cout <<
"Transferring cell arrays: " << std::endl;
514 for (
int i = 0; i < numArr; ++i) {
521 std::cout <<
"no cell data found" << std::endl;
528 double x[3],
bool flip, vtkIdType &
id,
529 vtkSmartPointer<vtkGenericCell> closestCell,
double closestPoint[3],
530 int &subId,
double &minDist2,
double *&weights) {
536 weights =
new double[20];
537 id = locator->FindCell(x, 1e-10, closestCell, pcoords, weights);
538 weights =
new double[closestCell->GetNumberOfPoints()];
539 closestCell->EvaluatePosition(x, closestPoint, subId, pcoords, minDist2,
546 while (bound < 1e+3) {
547 double bbox[6] = {x[0] - bound, x[0] + bound, x[1] - bound,
548 x[1] + bound, x[2] - bound, x[2] + bound};
552 locator->FindCellsWithinBounds(bbox, cellIds);
553 for (
int i = 0; i < cellIds->GetNumberOfIds(); ++i) {
554 id = cellIds->GetId(i);
555 localSource->getDataSet()->GetCell(
id, closestCell);
556 weights =
new double[closestCell->GetNumberOfPoints()];
557 closestCell->EvaluatePosition(x, closestPoint, subId, pcoords, minDist2,
559 if (minDist2 < 1e-9) {
568 std::cerr <<
"Could not find containing cell for point : " << x[0] <<
" " 569 << x[1] <<
" " << x[2] << std::endl;
570 closestCell =
nullptr;
571 minDist2 = vtkMath::Inf();
A brief description of meshBase.
void getClosestSourceCell(double x[3], bool flip, vtkIdType &id, vtkSmartPointer< vtkGenericCell > closestCell, double closestPoint[3], int &subId, double &minDist2, double *&weights)
Thread safe implementation using static point locator.
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
int run(const std::vector< std::string > &newnames=std::vector< std::string >()) override
Transfer all cell and point data from source to target.
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes' dataSet
virtual void unsetPointDataArray(int arrayID)
delete array with id from dataSet's point data
nemId_t getNumberOfPoints() const
return the number of points
vtkSmartPointer< vtkStaticCellLocator > srcCellLocator
vtkIdType id
id in .inp file
virtual void unsetCellDataArray(int arrayID)
delete array with id from dataSet's cell data
int transferCellData(const std::vector< int > &arrayIDs, const std::vector< std::string > &newnames=std::vector< std::string >()) override
Transfer cell data from source mesh to target The algorithm is as follows: 1) Convert the cell data o...
virtual std::vector< double > getCellCenter(nemId_t cellID) const =0
get center of a cell
vtkSmartPointer< vtkStaticCellLocator > trgCellLocator
vtkSmartPointer< vtkStaticPointLocator > srcPointLocator
vtkSmartPointer< vtkStaticPointLocator > trgPointLocator
nemId_t getNumberOfCells() const
return the number of cells
virtual std::vector< double > getPoint(nemId_t id) const =0
get point with id
int transferPointData(const std::vector< int > &arrayIDs, const std::vector< std::string > &newnames=std::vector< std::string >()) override
Transfers point data with arrayID from source mesh to target The algorithm is as follows; 1) For each...
T l2_Norm(const std::vector< T > &x)
FETransfer(meshBase *_source, meshBase *_target)