NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
FETransfer Class Reference

Detailed Description

Definition at line 38 of file FETransfer.H.

Public Member Functions

 FETransfer (meshBase *_source, meshBase *_target)
 
 ~FETransfer () override
 
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 point in the target mesh, find the cell of the source mesh in which it exists. More...
 
int transferPointData (int pointId, vtkSmartPointer< vtkGenericCell > containingCell, std::vector< vtkSmartPointer< vtkDoubleArray >> &dasSource, std::vector< vtkSmartPointer< vtkDoubleArray >> &dasTarget, bool flip)
 
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 on the source mesh by inverse-distance weighted averaging of data at cells sharing given point. More...
 
int transferCellData (int i, vtkSmartPointer< vtkGenericCell > genCell, std::vector< vtkSmartPointer< vtkDoubleArray >> &dasSourceToPoint, std::vector< vtkSmartPointer< vtkDoubleArray >> &dasTarget)
 
int run (const std::vector< std::string > &newnames=std::vector< std::string >()) override
 Transfer all cell and point data from source to target. More...
 
int transferPointData (const std::vector< std::string > &arrayNames, const std::vector< std::string > &newnames=std::vector< std::string >())
 Transfer point data with given field names from source to target. More...
 
int transferCellData (const std::vector< std::string > &arrayNames, const std::vector< std::string > &newnames=std::vector< std::string >())
 Transfer cell data with given field names from source to target. More...
 
void setCheckQual (bool x)
 
void setContBool (bool x)
 

Static Public Member Functions

static FETransferCreate (meshBase *source, meshBase *target)
 
static std::shared_ptr< FETransferCreateShared (meshBase *source, meshBase *target)
 

Protected Attributes

meshBasesource
 
meshBasetarget
 
vtkSmartPointer< vtkStaticCellLocator > srcCellLocator = nullptr
 
vtkSmartPointer< vtkStaticCellLocator > trgCellLocator = nullptr
 
vtkSmartPointer< vtkStaticPointLocator > srcPointLocator = nullptr
 
vtkSmartPointer< vtkStaticPointLocator > trgPointLocator = nullptr
 
bool checkQual
 
bool continuous
 
double c2cTrnsDistTol
 

Private Member Functions

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. More...
 

Inherits TransferBase.

Constructor & Destructor Documentation

◆ FETransfer()

FETransfer::FETransfer ( meshBase _source,
meshBase _target 
)

Definition at line 44 of file FETransfer.C.

References meshBase::getDataSet(), NEM::MSH::New(), TransferBase::source, TransferBase::srcCellLocator, TransferBase::srcPointLocator, TransferBase::target, TransferBase::trgCellLocator, and TransferBase::trgPointLocator.

44  {
45  source = _source;
46  target = _target;
47 
48  // since we are deprecating meshBase
49  // srcPointLocator = source->buildStaticPointLocator();
51  srcPointLocator->SetDataSet(source->getDataSet());
52  srcPointLocator->BuildLocator();
53  // trgPointLocator = target->buildStaticPointLocator();
55  trgPointLocator->SetDataSet(target->getDataSet());
56  trgPointLocator->BuildLocator();
57 
58  // srcCellLocator = source->buildStaticCellLocator();
60  srcCellLocator->SetDataSet(source->getDataSet());
61  srcCellLocator->BuildLocator();
62  // trgCellLocator = target->buildStaticCellLocator();
64  trgCellLocator->SetDataSet(target->getDataSet());
65  trgCellLocator->BuildLocator();
66 
67  auto sourceCellTypes = vtkSmartPointer<vtkCellTypes>::New();
68  auto targetCellTypes = vtkSmartPointer<vtkCellTypes>::New();
69 
70  std::cout << "FETransfer constructed" << std::endl;
71 }
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
meshBase * target
Definition: TransferBase.H:106
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
vtkSmartPointer< vtkStaticCellLocator > srcCellLocator
Definition: TransferBase.H:108
vtkSmartPointer< vtkStaticCellLocator > trgCellLocator
Definition: TransferBase.H:109
vtkSmartPointer< vtkStaticPointLocator > srcPointLocator
Definition: TransferBase.H:111
vtkSmartPointer< vtkStaticPointLocator > trgPointLocator
Definition: TransferBase.H:112
meshBase * source
Definition: TransferBase.H:105

◆ ~FETransfer()

FETransfer::~FETransfer ( )
inlineoverride

Definition at line 42 of file FETransfer.H.

42 { std::cout << "FETransfer destroyed" << std::endl; }

Member Function Documentation

◆ Create()

static FETransfer* FETransfer::Create ( meshBase source,
meshBase target 
)
inlinestatic

Definition at line 45 of file FETransfer.H.

Referenced by CreateShared().

45  {
46  return new FETransfer(source, target);
47  }
FETransfer(meshBase *_source, meshBase *_target)
Definition: FETransfer.C:44

◆ CreateShared()

static std::shared_ptr<FETransfer> FETransfer::CreateShared ( meshBase source,
meshBase target 
)
inlinestatic

Definition at line 49 of file FETransfer.H.

References Create(), TransferBase::run(), TransferBase::transferCellData(), and TransferBase::transferPointData().

Referenced by NEM::DRV::TransferDriver::CreateTransferObject().

50  {
51  return std::shared_ptr<FETransfer>(FETransfer::Create(source, target));
52  }
static FETransfer * Create(meshBase *source, meshBase *target)
Definition: FETransfer.H:45

◆ getClosestSourceCell()

void FETransfer::getClosestSourceCell ( double  x[3],
bool  flip,
vtkIdType &  id,
vtkSmartPointer< vtkGenericCell >  closestCell,
double  closestPoint[3],
int &  subId,
double &  minDist2,
double *&  weights 
)
private

Definition at line 527 of file FETransfer.C.

References NEM::MSH::New(), TransferBase::source, TransferBase::srcCellLocator, TransferBase::target, and TransferBase::trgCellLocator.

Referenced by transferCellData(), and transferPointData().

530  {
531  auto locator = flip ? trgCellLocator : srcCellLocator;
532  auto localSource = flip ? target : source;
533 
534  // using fast builtin locator findcell method
535  double pcoords[3];
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,
540  weights);
541 
542  // if failed try searching
543  // TODO: find a better way to compute initial bound
544  double bound = 1e-3;
545  if (id < 0) {
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};
549  int subId;
550  double pcoords[3];
551  auto cellIds = vtkSmartPointer<vtkIdList>::New();
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,
558  weights);
559  if (minDist2 < 1e-9) {
560  return;
561  }
562  }
563  bound *= 10;
564  }
565  }
566 
567  if (id < 0) {
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();
572  throw;
573  }
574 }
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
meshBase * target
Definition: TransferBase.H:106
vtkSmartPointer< vtkStaticCellLocator > srcCellLocator
Definition: TransferBase.H:108
vtkSmartPointer< vtkStaticCellLocator > trgCellLocator
Definition: TransferBase.H:109
meshBase * source
Definition: TransferBase.H:105

◆ run()

int FETransfer::run ( const std::vector< std::string > &  newnames = std::vector<std::string>())
overridevirtual

Implements TransferBase.

Definition at line 488 of file FETransfer.C.

References meshBase::getDataSet(), TransferBase::source, TransferBase::target, transferCellData(), and transferPointData().

488  {
489  if (!(source && target)) {
490  std::cerr << "source and target meshes must be initialized" << std::endl;
491  exit(1);
492  }
493 
494  // transferring point data
495  int numArr = source->getDataSet()->GetPointData()->GetNumberOfArrays();
496  if (numArr > 0) {
497  std::vector<int> arrayIDs(numArr);
498  std::cout << "Transferring point arrays: " << std::endl;
499  for (int i = 0; i < numArr; ++i) {
500  arrayIDs[i] = i;
501  std::cout << "\t" << source->getDataSet()->GetPointData()->GetArrayName(i)
502  << "\n";
503  }
504  transferPointData(arrayIDs, newnames);
505  } else {
506  std::cout << "no point data found" << std::endl;
507  }
508 
509  // transferring cell data
510  numArr = source->getDataSet()->GetCellData()->GetNumberOfArrays();
511  if (numArr > 0) {
512  std::vector<int> arrayIDs(numArr);
513  std::cout << "Transferring cell arrays: " << std::endl;
514  for (int i = 0; i < numArr; ++i) {
515  arrayIDs[i] = i;
516  std::cout << "\t" << source->getDataSet()->GetCellData()->GetArrayName(i)
517  << "\n";
518  }
519  transferCellData(arrayIDs, newnames);
520  } else {
521  std::cout << "no cell data found" << std::endl;
522  }
523 
524  return 0;
525 }
meshBase * target
Definition: TransferBase.H:106
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
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...
Definition: FETransfer.C:274
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...
Definition: FETransfer.C:84
meshBase * source
Definition: TransferBase.H:105

◆ setCheckQual()

void TransferBase::setCheckQual ( bool  x)
inlineinherited

Definition at line 100 of file TransferBase.H.

100 { checkQual = x; }

◆ setContBool()

void TransferBase::setContBool ( bool  x)
inlineinherited

Definition at line 102 of file TransferBase.H.

102 { continuous = x; }

◆ transferCellData() [1/3]

int TransferBase::transferCellData ( const std::vector< std::string > &  arrayNames,
const std::vector< std::string > &  newnames = std::vector<std::string>() 
)
inherited
Parameters
arrayIDsarray of array names to specify which fields to transfer
newnamesoptional array of names to be applied to transferred fields
Returns
0 upon completion

Definition at line 47 of file TransferBase.C.

References TransferBase::getArrayIDs(), meshBase::getDataSet(), TransferBase::source, and TransferBase::transferCellData().

49 {
50  vtkCellData* cellData = source->getDataSet()->GetCellData();
51  std::vector<int> arrayIDs = getArrayIDs(arrayNames, cellData);
52 
53  return transferCellData(arrayIDs, newnames);
54 }
virtual int transferCellData(const std::vector< int > &arrayIDs, const std::vector< std::string > &newnames=std::vector< std::string >())=0
Transfer cell data with given ids from source to target.
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
std::vector< int > getArrayIDs(const std::vector< std::string > &arrayNames, vtkFieldData *fieldData)
given array names and field data, return vector of corresponding array ids in the field data ...
Definition: TransferBase.C:56
meshBase * source
Definition: TransferBase.H:105

◆ transferCellData() [2/3]

int FETransfer::transferCellData ( const std::vector< int > &  arrayIDs,
const std::vector< std::string > &  newnames = std::vector<std::string>() 
)
overridevirtual
  • cell data is assumed to be prescribed at cell centers 2) Compute the centers of cell in the target mesh 3) Transfer the converted cell-point data from the source mesh to the cell centers of the target mesh using the runPD methods
    Parameters
    arrayIDsarray of array ids for transfer
    newnamesoptional array of names for transferred data: newnames[i] specifies the transferred array name in the target at arrayId[i]

Implements TransferBase.

Definition at line 274 of file FETransfer.C.

References TransferBase::c2cTrnsDistTol, TransferBase::continuous, meshBase::getCellCenter(), getClosestSourceCell(), meshBase::getDataSet(), meshBase::getNumberOfCells(), meshBase::getNumberOfPoints(), meshBase::getPoint(), id, nemAux::l2_Norm(), NEM::MSH::New(), TransferBase::source, TransferBase::target, and meshBase::unsetCellDataArray().

Referenced by run().

275  {
276  if (arrayIDs.empty()) {
277  std::cerr << "no arrays selected for interpolation" << std::endl;
278  exit(1);
279  }
280 
281  vtkSmartPointer<vtkCellData> cd = source->getDataSet()->GetCellData();
282  // clean target data of duplicate names if no newnames specified
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;
289  exit(1);
290  }
291  target->unsetCellDataArray(cd->GetArrayName(arrayID));
292  }
293  }
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) {
297  // get desired cell data array from source to be transferred to target
298  vtkSmartPointer<vtkDataArray> daSource = cd->GetArray(arrayIDs[id]);
299  // get tuple length of given data
300  int numComponent = daSource->GetNumberOfComponents();
301  // declare data array to be populated with values at target points
302  vtkSmartPointer<vtkDoubleArray> daTarget =
304  // names and sizing
305  if (newnames.empty())
306  daTarget->SetName(cd->GetArrayName(arrayIDs[id]));
307  else
308  daTarget->SetName(newnames[id].c_str());
309  daTarget->SetNumberOfComponents(numComponent);
310  daTarget->SetNumberOfTuples(target->getNumberOfCells());
311  dasSource[id] = daSource;
312  dasTarget[id] = daTarget;
313  }
314  // straight forward transfer without weighted averaging by locating target
315  // cell in source mesh and assigning cell data
316  if (!continuous) {
317  std::cout << "Non-continuous cell data transfer invoked" << std::endl;
318  vtkSmartPointer<vtkGenericCell> genCell =
320  for (int i = 0; i < target->getNumberOfCells(); ++i) {
321  std::vector<double> targetCenter = target->getCellCenter(i);
322  // id of the cell containing source mesh point
323  vtkIdType id;
324  int subId;
325  double minDist2;
326  // find closest point and closest cell to x
327  double closestPoint[3];
328  double *x = targetCenter.data();
329  double *weights;
330  getClosestSourceCell(x, false, id, genCell, closestPoint, subId, minDist2,
331  weights);
332  /*
333  srcCellLocator->FindClosestPoint(x, closestPoint, genCell, id, subId,
334  minDist2);
335  */
336  if (id >= 0) {
337  if (minDist2 > c2cTrnsDistTol)
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
343  << std::endl;
344  for (int j = 0; j < dasSource.size(); ++j) {
345  int numComponent = dasSource[j]->GetNumberOfComponents();
346  // double comps[numComponent];
347  std::vector<double> comps;
348  comps.resize(numComponent, 0.);
349  dasSource[j]->GetTuple(id, &comps[0]);
350  dasTarget[j]->SetTuple(i, &comps[0]);
351  }
352  } else {
353  std::cerr << "Could not locate target cell " << i
354  << " from in the source mesh! Check the source mesh."
355  << std::endl;
356  exit(1);
357  }
358  }
359  } else // transfer with weighted averaging
360  {
361  std::cout << "Continuous cell data transfer invoked" << std::endl;
362  // ---------------------- Convert source cell data to point data -------- //
363  std::vector<vtkSmartPointer<vtkDoubleArray>> dasSourceToPoint(
364  arrayIDs.size());
365 
366  // cellId container for cells sharing a point
367  vtkSmartPointer<vtkIdList> cellIds = vtkSmartPointer<vtkIdList>::New();
368 
369  // initializing arrays storing interpolated data
370  for (int id = 0; id < arrayIDs.size(); ++id) {
371  // get desired cell data array from source to be transferred to target
372  vtkSmartPointer<vtkDataArray> daSource = cd->GetArray(arrayIDs[id]);
373  // get tuple length of given data
374  int numComponent = daSource->GetNumberOfComponents();
375  // initialize cellToPoint source array
376  vtkSmartPointer<vtkDoubleArray> daSourceToPoint =
378  daSourceToPoint->SetNumberOfComponents(numComponent);
379  daSourceToPoint->SetNumberOfTuples(source->getNumberOfPoints());
380 
381  for (int i = 0; i < source->getNumberOfPoints(); ++i) {
382  // find cells sharing point i
383  source->getDataSet()->GetPointCells(i, cellIds);
384  int numSharedCells = cellIds->GetNumberOfIds();
385  double totW = 0;
386  double W;
387  // contains averaged/weighted data
388  std::vector<double> interps(numComponent, 0.0);
389  for (int j = 0; j < numSharedCells; ++j) {
390  int cellId = cellIds->GetId(j);
391  // double comps[numComponent];
392  std::vector<double> comps;
393  comps.resize(numComponent, 0.);
394  daSource->GetTuple(cellId, &comps[0]);
395  // compute distance from point to cell center
396  W = 1. / nemAux::l2_Norm(source->getCellCenter(cellId) -
397  source->getPoint(i));
398  // average over shared cells, weighted by inverse distance to center
399  for (int k = 0; k < numComponent; ++k) {
400  interps[k] += W * comps[k];
401  }
402  totW += W;
403  }
404  interps = (1.0 / totW) * interps;
405  daSourceToPoint->SetTuple(i, interps.data());
406  }
407  dasSourceToPoint[id] = daSourceToPoint;
408  }
409  // genCell used by locator
410  vtkSmartPointer<vtkGenericCell> genCell =
412  for (int i = 0; i < target->getNumberOfCells(); ++i) {
413  transferCellData(i, genCell, dasSourceToPoint, dasTarget);
414  }
415  }
416  for (int id = 0; id < arrayIDs.size(); ++id) {
417  target->getDataSet()->GetCellData()->AddArray(dasTarget[id]);
418  }
419  return 0;
420 }
double c2cTrnsDistTol
Definition: TransferBase.H:116
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.
Definition: FETransfer.C:527
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
meshBase * target
Definition: TransferBase.H:106
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
nemId_t getNumberOfPoints() const
return the number of points
Definition: meshBase.H:545
vtkIdType id
id in .inp file
Definition: inpGeoMesh.C:128
virtual void unsetCellDataArray(int arrayID)
delete array with id from dataSet&#39;s cell data
Definition: meshBase.H:391
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...
Definition: FETransfer.C:274
virtual std::vector< double > getCellCenter(nemId_t cellID) const =0
get center of a cell
nemId_t getNumberOfCells() const
return the number of cells
Definition: meshBase.H:550
virtual std::vector< double > getPoint(nemId_t id) const =0
get point with id
T l2_Norm(const std::vector< T > &x)
meshBase * source
Definition: TransferBase.H:105

◆ transferCellData() [3/3]

int FETransfer::transferCellData ( int  i,
vtkSmartPointer< vtkGenericCell >  genCell,
std::vector< vtkSmartPointer< vtkDoubleArray >> &  dasSourceToPoint,
std::vector< vtkSmartPointer< vtkDoubleArray >> &  dasTarget 
)

Definition at line 422 of file FETransfer.C.

References meshBase::getCellCenter(), getClosestSourceCell(), id, and TransferBase::target.

425  {
426  // getting point from target and setting as query
427  std::vector<double> targetCenter = target->getCellCenter(i);
428  // id of the cell containing source mesh point
429  vtkIdType id;
430  int subId;
431  double minDist2;
432  // find closest point and closest cell to x
433  double closestPoint[3];
434  double *x = targetCenter.data();
435  double *weights;
436  getClosestSourceCell(x, false, id, genCell, closestPoint, subId, minDist2,
437  weights);
438  /*
439  srcCellLocator->FindClosestPoint(x, closestPoint, genCell, id, subId,
440  minDist2);
441  */
442  if (id >= 0) {
443  // passed to evaluate position if called
444  double pcoords[3];
445  // parameters for interpolation
446  // int pntId;
447  int result;
448  auto *weights = new double[genCell->GetNumberOfPoints()];
449  result = genCell->EvaluatePosition(x, nullptr, subId, pcoords, minDist2,
450  weights);
451  if (result > 0) {
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];
461  }
462  }
463  delete[] comps;
464  // adding interpolated value to data of cell
465  dasTarget[id]->SetTuple(i, interps.data());
466  }
467  } else if (result == 0) {
468  delete[] weights;
469  std::cerr
470  << "Could not locate point from target mesh in any cells sharing"
471  << " its nearest neighbor in the source mesh" << std::endl;
472  exit(1);
473  } else {
474  delete[] weights;
475  std::cerr
476  << "problem encountered evaluating position of point from target"
477  << " mesh with respect to cell in source mesh" << std::endl;
478  exit(1);
479  }
480  } else {
481  std::cerr << "Could not locate center of cell " << i
482  << " from target in source mesh" << std::endl;
483  exit(1);
484  }
485  return 0;
486 }
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.
Definition: FETransfer.C:527
meshBase * target
Definition: TransferBase.H:106
vtkIdType id
id in .inp file
Definition: inpGeoMesh.C:128
virtual std::vector< double > getCellCenter(nemId_t cellID) const =0
get center of a cell

◆ transferPointData() [1/3]

int FETransfer::transferPointData ( const std::vector< int > &  arrayIDs,
const std::vector< std::string > &  newnames = std::vector<std::string>() 
)
overridevirtual
  • using a cell locator
  • if cell locator fails, find the nearest neighbor in the source mesh and all cells sharing this neighbor point. Check if the target point is in any of these neighboring cells 2) When the cell is identified, evaluate the weights for interpolation of the solution to the target point and perform the interpolation.
    Parameters
    arrayIDsarray of array ids for transfer
    newnamesoptional array of names for transferred data: newnames[i] specifies the transferred array name in the target at arrayId[i]

Implements TransferBase.

Definition at line 84 of file FETransfer.C.

References TransferBase::checkQual, nemAux::Timer::elapsed(), meshBase::getDataSet(), meshBase::getNumberOfPoints(), id, NEM::MSH::New(), TransferBase::source, nemAux::Timer::start(), nemAux::Timer::stop(), TransferBase::target, and meshBase::unsetPointDataArray().

Referenced by run().

85  {
86  if (arrayIDs.empty()) {
87  std::cerr << "No arrays are selected for interpolation" << std::endl;
88  throw;
89  }
90 
91  vtkSmartPointer<vtkPointData> pd = source->getDataSet()->GetPointData();
92  // clean target data of duplicate names if no newnames specified
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"
99  << std::endl;
100  throw;
101  }
102  target->unsetPointDataArray(pd->GetArrayName(arrayID));
103  }
104  }
105 
106  std::vector<vtkSmartPointer<vtkDoubleArray>> dasSource(arrayIDs.size());
107  std::vector<vtkSmartPointer<vtkDoubleArray>> dasTarget(arrayIDs.size());
108 
109  // initializing arrays storing interpolated data
110  for (int id = 0; id < arrayIDs.size(); ++id) {
111  // get desired point data array from source to be transferred to target
112  vtkSmartPointer<vtkDoubleArray> daSource =
113  vtkDoubleArray::SafeDownCast(pd->GetArray(arrayIDs[id]));
114  // get tuple length of given data`
115  int numComponent = daSource->GetNumberOfComponents();
116  // declare data array to be populated with values at target points
117  vtkSmartPointer<vtkDoubleArray> daTarget =
119  // names and sizing
120  if (newnames.empty()) {
121  daTarget->SetName(pd->GetArrayName(arrayIDs[id]));
122  } else {
123  daTarget->SetName(newnames[id].c_str());
124  }
125  daTarget->SetNumberOfComponents(numComponent);
126  daTarget->SetNumberOfTuples(target->getNumberOfPoints());
127 
128  std::cout << "Number of components : " << numComponent << std::endl;
129  std::cout << "Number of points : " << target->getNumberOfPoints()
130  << std::endl
131  << std::endl;
132  dasSource[id] = daSource;
133  dasTarget[id] = daTarget;
134  }
135  nemAux::Timer timer;
136  timer.start();
137 #ifdef HAVE_OPENMP
138  int numTargetPoints = target->getNumberOfPoints();
139  std::cout << "Max number of threads available in transfer "
140  << omp_get_max_threads() << std::endl;
141 // transfer point data
142 # pragma omp parallel default(none) \
143  shared(dasSource, dasTarget, numTargetPoints, cout)
144  {
145 # pragma omp single
146  {
147  std::cout << "Number of threads used in transfer "
148  << omp_get_num_threads() << std::endl;
149  // the following methods are thread safe IF called from a single thread
150  // first
151  vtkSmartPointer<vtkGenericCell> tempCell =
153  source->getDataSet()->GetCell(0, tempCell);
154  target->getDataSet()->GetCell(0, tempCell);
155  double x[3];
156  source->getDataSet()->GetPoint(0, x);
157  target->getDataSet()->GetPoint(0, x);
158  auto tempCellIds = vtkSmartPointer<vtkIdList>::New();
159  source->getDataSet()->GetPointCells(0, tempCellIds);
160  target->getDataSet()->GetPointCells(0, tempCellIds);
161  }
162  // generic cell buffer used by locator
163  vtkSmartPointer<vtkGenericCell> containingCell =
165 # pragma omp for schedule(static)
166  for (int iPnt = 0; iPnt < numTargetPoints; ++iPnt) {
167  transferPointData(iPnt, containingCell, dasSource, dasTarget, false);
168  }
169  }
170 #else
171  vtkSmartPointer<vtkGenericCell> containingCell =
173  for (int iPnt = 0; iPnt < target->getNumberOfPoints(); ++iPnt) {
174  transferPointData(iPnt, containingCell, dasSource, dasTarget, false);
175  }
176 #endif
177  timer.stop();
178  std::cout << "TRANSFER TIME : " << timer.elapsed() << std::endl;
179  for (int id = 0; id < arrayIDs.size(); ++id) {
180  target->getDataSet()->GetPointData()->AddArray(dasTarget[id]);
181  }
182  if (checkQual) {
183  std::vector<vtkSmartPointer<vtkDoubleArray>> newDasSource(arrayIDs.size());
184  for (int id = 0; id < arrayIDs.size(); ++id) {
185  int numComponent = dasTarget[id]->GetNumberOfComponents();
186  // declare data array to be populated with values at target points
187  vtkSmartPointer<vtkDoubleArray> newDaSource =
189  newDaSource->SetNumberOfComponents(numComponent);
190  newDaSource->SetNumberOfTuples(target->getNumberOfPoints());
191  newDasSource[id] = newDaSource;
192  }
193 
194  vtkSmartPointer<vtkGenericCell> genCell =
196  for (int i = 0; i < source->getNumberOfPoints(); ++i) {
197  transferPointData(i, genCell, dasTarget, newDasSource, true);
198  }
199 
200  for (int id = 0; id < arrayIDs.size(); ++id) {
201  int numComponent = newDasSource[id]->GetNumberOfComponents();
202  double diffsum = 0.0;
203  for (int i = 0; i < source->getNumberOfPoints(); ++i) {
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;
211  }
212  delete[] comps_old;
213  delete[] comps_new;
214  }
215  double rmse =
216  std::sqrt(diffsum / (numComponent * source->getNumberOfPoints()));
217  std::cout << "RMS Error in Nodal Transfer: "
218  << (!(std::isnan(rmse) || std::isinf(rmse)) ? rmse : 0)
219  << std::endl;
220  }
221  }
222  return 0;
223 }
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
meshBase * target
Definition: TransferBase.H:106
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
virtual void unsetPointDataArray(int arrayID)
delete array with id from dataSet&#39;s point data
Definition: meshBase.H:381
nemId_t getNumberOfPoints() const
return the number of points
Definition: meshBase.H:545
vtkIdType id
id in .inp file
Definition: inpGeoMesh.C:128
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...
Definition: FETransfer.C:84
meshBase * source
Definition: TransferBase.H:105

◆ transferPointData() [2/3]

int FETransfer::transferPointData ( int  pointId,
vtkSmartPointer< vtkGenericCell >  containingCell,
std::vector< vtkSmartPointer< vtkDoubleArray >> &  dasSource,
std::vector< vtkSmartPointer< vtkDoubleArray >> &  dasTarget,
bool  flip 
)

Definition at line 225 of file FETransfer.C.

References getClosestSourceCell(), meshBase::getDataSet(), TransferBase::source, and TransferBase::target.

228  {
229  // id of the cell containing source/target mesh point
230 
231  double x[3]; // target point
232  double closestPoint[3]; // nearest source point
233  vtkIdType cellId;
234  int subId;
235  double minDist2;
236  double *weights;
237 
238  if (!flip) {
239  target->getDataSet()->GetPoint(pointId, x);
240  getClosestSourceCell(x, flip, cellId, containingCell, closestPoint, subId,
241  minDist2, weights);
242  } else {
243  source->getDataSet()->GetPoint(pointId, x);
244  getClosestSourceCell(x, flip, cellId, containingCell, closestPoint, subId,
245  minDist2, weights);
246  }
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];
256  }
257  }
258  delete[] comps;
259  // adding interpolated value to data of cell
260  dasTarget[i]->SetTuple(pointId, interps.data());
261  }
262  return 0;
263 }
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.
Definition: FETransfer.C:527
meshBase * target
Definition: TransferBase.H:106
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
meshBase * source
Definition: TransferBase.H:105

◆ transferPointData() [3/3]

int TransferBase::transferPointData ( const std::vector< std::string > &  arrayNames,
const std::vector< std::string > &  newnames = std::vector<std::string>() 
)
inherited
Parameters
arrayIDsarray of array names to specify which fields to transfer
newnamesoptional array of names to be applied to transferred fields
Returns
0 upon completion

Definition at line 36 of file TransferBase.C.

References TransferBase::getArrayIDs(), meshBase::getDataSet(), TransferBase::source, and TransferBase::transferPointData().

38 {
39  vtkPointData* pointData = source->getDataSet()->GetPointData();
40  std::vector<int> arrayIDs = getArrayIDs(arrayNames, pointData);
41 
42  return transferPointData(arrayIDs, newnames);
43 }
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
virtual int transferPointData(const std::vector< int > &arrayIDs, const std::vector< std::string > &newnames=std::vector< std::string >())=0
Transfer point data with given ids from source to target.
std::vector< int > getArrayIDs(const std::vector< std::string > &arrayNames, vtkFieldData *fieldData)
given array names and field data, return vector of corresponding array ids in the field data ...
Definition: TransferBase.C:56
meshBase * source
Definition: TransferBase.H:105

Member Data Documentation

◆ c2cTrnsDistTol

double TransferBase::c2cTrnsDistTol
protectedinherited

Definition at line 116 of file TransferBase.H.

Referenced by transferCellData().

◆ checkQual

bool TransferBase::checkQual
protectedinherited

Definition at line 114 of file TransferBase.H.

Referenced by transferPointData().

◆ continuous

bool TransferBase::continuous
protectedinherited

Definition at line 115 of file TransferBase.H.

Referenced by transferCellData().

◆ source

◆ srcCellLocator

vtkSmartPointer<vtkStaticCellLocator> TransferBase::srcCellLocator = nullptr
protectedinherited

Definition at line 108 of file TransferBase.H.

Referenced by FETransfer(), and getClosestSourceCell().

◆ srcPointLocator

vtkSmartPointer<vtkStaticPointLocator> TransferBase::srcPointLocator = nullptr
protectedinherited

Definition at line 111 of file TransferBase.H.

Referenced by FETransfer().

◆ target

◆ trgCellLocator

vtkSmartPointer<vtkStaticCellLocator> TransferBase::trgCellLocator = nullptr
protectedinherited

Definition at line 109 of file TransferBase.H.

Referenced by FETransfer(), and getClosestSourceCell().

◆ trgPointLocator

vtkSmartPointer<vtkStaticPointLocator> TransferBase::trgPointLocator = nullptr
protectedinherited

Definition at line 112 of file TransferBase.H.

Referenced by FETransfer().


The documentation for this class was generated from the following files: