Nektar++
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | Private Member Functions | List of all members
Nektar::SolverUtils::CouplingCwipi Class Reference

#include <CouplingCwipi.h>

Inheritance diagram for Nektar::SolverUtils::CouplingCwipi:
[legend]

Public Member Functions

SOLVER_UTILS_EXPORT CouplingCwipi (MultiRegions::ExpListSharedPtr field)
 
virtual SOLVER_UTILS_EXPORT ~CouplingCwipi ()
 
SOLVER_UTILS_EXPORT void SendCallback (Array< OneD, Array< OneD, NekDouble > > &interpField, Array< OneD, Array< OneD, NekDouble > > &distCoords)
 
- Public Member Functions inherited from Nektar::SolverUtils::Coupling
virtual SOLVER_UTILS_EXPORT ~Coupling ()
 
SOLVER_UTILS_EXPORT void Init ()
 
SOLVER_UTILS_EXPORT const std::map< std::string, std::string > GetConfig ()
 
SOLVER_UTILS_EXPORT std::vector< std::string > GetSendFieldNames ()
 
SOLVER_UTILS_EXPORT std::vector< std::string > GetRecvFieldNames ()
 
SOLVER_UTILS_EXPORT void Finalize ()
 
SOLVER_UTILS_EXPORT void Send (const int step, const NekDouble time, const Array< OneD, const Array< OneD, NekDouble > > &field, std::vector< std::string > &varNames)
 
SOLVER_UTILS_EXPORT void Receive (const int step, const NekDouble time, Array< OneD, Array< OneD, NekDouble > > &field, std::vector< std::string > &varNames)
 

Static Public Member Functions

static CouplingSharedPtr create (MultiRegions::ExpListSharedPtr field)
 Creates an instance of this class. More...
 
static SOLVER_UTILS_EXPORT void InterpCallback (const int entities_dim, const int n_local_vertex, const int n_local_element, const int n_local_polhyedra, const int n_distant_point, const double local_coordinates[], const int local_connectivity_index[], const int local_connectivity[], const int local_polyhedra_face_index[], const int local_polyhedra_cell_to_face_connectivity[], const int local_polyhedra_face_connectivity_index[], const int local_polyhedra_face_connectivity[], const double distant_points_coordinates[], const int distant_points_location[], const float distant_points_distance[], const int distant_points_barycentric_coordinates_index[], const double distant_points_barycentric_coordinates[], const int stride, const cwipi_solver_type_t solver_type, const void *local_field, void *distant_field)
 

Static Public Attributes

static std::string className
 

Protected Member Functions

virtual SOLVER_UTILS_EXPORT void v_Init ()
 
virtual SOLVER_UTILS_EXPORT void v_Send (const int step, const NekDouble time, const Array< OneD, const Array< OneD, NekDouble > > &field, std::vector< std::string > &varNames)
 
virtual SOLVER_UTILS_EXPORT void v_Receive (const int step, const NekDouble time, Array< OneD, Array< OneD, NekDouble > > &field, std::vector< std::string > &varNames)
 
virtual SOLVER_UTILS_EXPORT void v_Finalize ()
 
SOLVER_UTILS_EXPORT NekDouble GetSendField (const int i, const int j) const
 
- Protected Member Functions inherited from Nektar::SolverUtils::Coupling
SOLVER_UTILS_EXPORT Coupling (MultiRegions::ExpListSharedPtr field)
 
SOLVER_UTILS_EXPORT std::vector< int > GenerateVariableMapping (std::vector< std::string > &vars, std::vector< std::string > &transVars)
 

Protected Attributes

NekDouble m_filtWidth
 
Array< OneD, Array< OneD, NekDouble > > m_sendField
 
MultiRegions::ExpListSharedPtr m_recvField
 
Array< OneD, Array< OneD, NekDouble > > m_oldFields
 
Array< OneD, Array< OneD, NekDouble > > m_newFields
 
int m_sendHandle
 
int m_recvHandle
 
int m_sendTag
 
int m_recvTag
 
int m_lastSend
 
int m_lastReceive
 
int m_spacedim
 
int m_nPoints
 
double * m_points
 
double * m_coords
 
int * m_connecIdx
 
int * m_connec
 
double * m_rValsInterl
 
double * m_sValsInterl
 
std::map< int, int > m_vertMap
 
FieldUtils::InterpolatorSharedPtr m_sendInterpolator
 
FieldUtils::InterpolatorSharedPtr m_extrapInterpolator
 
- Protected Attributes inherited from Nektar::SolverUtils::Coupling
std::string m_couplingName
 
CouplingConfigMap m_config
 
MultiRegions::ExpListSharedPtr m_evalField
 
int m_nSendVars
 
std::vector< std::string > m_sendFieldNames
 
int m_sendSteps
 
int m_nRecvVars
 
std::vector< std::string > m_recvFieldNames
 
int m_recvSteps
 

Private Member Functions

void ReadConfig (LibUtilities::SessionReaderSharedPtr session)
 
void SetupReceive ()
 
void SetupSend ()
 
void SendComplete ()
 
void ReceiveStart ()
 
void ReceiveCwipi (const int step, const NekDouble time, Array< OneD, Array< OneD, NekDouble > > &field)
 
void EvaluateFields (Array< OneD, Array< OneD, NekDouble > > interpField, Array< OneD, Array< OneD, NekDouble > > distCoords)
 
void SetupSendInterpolation ()
 
void AnnounceMesh ()
 
void DumpRawFields (const NekDouble time, Array< OneD, Array< OneD, NekDouble > > rVals)
 
void ExtrapolateFields (Array< OneD, Array< OneD, NekDouble > > &rVals, Array< OneD, int > &notLoc)
 
template<typename T >
void AddElementsToMesh (T geom, int &coordsPos, int &connecPos, int &conidxPos)
 

Additional Inherited Members

- Public Types inherited from Nektar::SolverUtils::Coupling
typedef std::map< std::string, std::string > CouplingConfigMap
 

Detailed Description

Definition at line 51 of file CouplingCwipi.h.

Constructor & Destructor Documentation

◆ CouplingCwipi()

Nektar::SolverUtils::CouplingCwipi::CouplingCwipi ( MultiRegions::ExpListSharedPtr  field)

Definition at line 128 of file CouplingCwipi.cpp.

References Nektar::SolverUtils::Coupling::m_config.

Referenced by create().

129  : Coupling(field), m_sendHandle(-1), m_recvHandle(-1), m_lastSend(-1E6),
130  m_lastReceive(-1E6), m_points(NULL), m_coords(NULL), m_connecIdx(NULL),
131  m_connec(NULL), m_rValsInterl(NULL), m_sValsInterl(NULL)
132 {
133  // defaults
134  m_config["GEOMTOL"] = "0.1";
135  m_config["LOCALNAME"] = "nektar";
136  m_config["REMOTENAME"] = "precise";
137  m_config["OVERSAMPLE"] = "0";
138  m_config["FILTERWIDTH"] = "-1";
139  m_config["DUMPRAW"] = "0";
140  m_config["SENDMETHOD"] = "EVALUATE";
141  m_config["NOTLOCMETHOD"] = "KEEP";
142 }
CouplingConfigMap m_config
Definition: Coupling.h:113
SOLVER_UTILS_EXPORT Coupling(MultiRegions::ExpListSharedPtr field)
Definition: Coupling.cpp:50

◆ ~CouplingCwipi()

Nektar::SolverUtils::CouplingCwipi::~CouplingCwipi ( )
virtual

Member Function Documentation

◆ AddElementsToMesh()

template<typename T >
void Nektar::SolverUtils::CouplingCwipi::AddElementsToMesh ( geom,
int &  coordsPos,
int &  connecPos,
int &  conidxPos 
)
private

Definition at line 553 of file CouplingCwipi.cpp.

References m_connec, m_connecIdx, m_coords, and m_vertMap.

Referenced by AnnounceMesh(), and GetSendField().

557 {
558  // helper variables
559  Array<OneD, NekDouble> x(3);
561  int vertID;
562 
563  int kNverts = T::mapped_type::element_type::kNverts;
564 
565  // iterate over all elements
566  for (auto it = geom.begin(); it != geom.end(); it++)
567  {
568  // iterate over the elements vertices
569  for (int j = 0; j < kNverts; ++j)
570  {
571  vert = it->second->GetVertex(j);
572  vertID = vert->GetVid();
573 
574  // check if we already stored the vertex
575  if (m_vertMap.count(vertID) == 0)
576  {
577  // store the vertex
578  vert->GetCoords(x[0], x[1], x[2]);
579  m_coords[3 * coordsPos + 0] = double(x[0]);
580  m_coords[3 * coordsPos + 1] = double(x[1]);
581  m_coords[3 * coordsPos + 2] = double(x[2]);
582 
583  // store the vertex position in the m_coords array
584  m_vertMap[vertID] = coordsPos;
585  coordsPos++;
586  }
587 
588  m_connec[connecPos] = m_vertMap[vertID] + 1;
589  connecPos++;
590  }
591 
592  m_connecIdx[conidxPos + 1] = m_connecIdx[conidxPos] + kNverts;
593  conidxPos++;
594  }
595 }
std::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:59

◆ AnnounceMesh()

void Nektar::SolverUtils::CouplingCwipi::AnnounceMesh ( )
private

Definition at line 467 of file CouplingCwipi.cpp.

References AddElementsToMesh(), ASSERTL1, m_connec, m_connecIdx, m_coords, Nektar::SolverUtils::Coupling::m_couplingName, Nektar::SolverUtils::Coupling::m_evalField, and m_spacedim.

Referenced by GetSendField(), and v_Init().

468 {
470 
471  // get Elements
479  if (m_spacedim == 1)
480  {
481  seggeom = graph->GetAllSegGeoms();
482  }
483  else if (m_spacedim == 2)
484  {
485  trigeom = graph->GetAllTriGeoms();
486  quadgeom = graph->GetAllQuadGeoms();
487  }
488  else if (m_spacedim == 3)
489  {
490  tetgeom = graph->GetAllTetGeoms();
491  pyrgeom = graph->GetAllPyrGeoms();
492  prismgeom = graph->GetAllPrismGeoms();
493  hexgeom = graph->GetAllHexGeoms();
494  };
495 
496  int nVerts = graph->GetNvertices();
497  int nElts = seggeom.size() + trigeom.size() + quadgeom.size() +
498  tetgeom.size() + pyrgeom.size() + prismgeom.size() +
499  hexgeom.size();
500 
501  // allocate CWIPI arrays
502  m_coords = (double *)malloc(sizeof(double) * 3 * nVerts);
503  ASSERTL1(m_coords != NULL, "malloc failed for m_coords");
504  int tmp = 2 * seggeom.size() + 3 * trigeom.size() + 4 * quadgeom.size() +
505  4 * tetgeom.size() + 5 * pyrgeom.size() + 6 * prismgeom.size() +
506  8 * hexgeom.size();
507  m_connec = (int *)malloc(sizeof(int) * tmp);
508  ASSERTL1(m_connec != NULL, "malloc failed for m_connec");
509  m_connecIdx = (int *)malloc(sizeof(int) * (nElts + 1));
510  ASSERTL1(m_connecIdx != NULL, "malloc failed for m_connecIdx");
511 
512  m_connecIdx[0] = 0;
513  int coordsPos = 0;
514  int connecPos = 0;
515  int conidxPos = 0;
516 
517  AddElementsToMesh(seggeom, coordsPos, connecPos, conidxPos);
518  AddElementsToMesh(trigeom, coordsPos, connecPos, conidxPos);
519  AddElementsToMesh(quadgeom, coordsPos, connecPos, conidxPos);
520  AddElementsToMesh(tetgeom, coordsPos, connecPos, conidxPos);
521  AddElementsToMesh(pyrgeom, coordsPos, connecPos, conidxPos);
522  AddElementsToMesh(prismgeom, coordsPos, connecPos, conidxPos);
523  AddElementsToMesh(hexgeom, coordsPos, connecPos, conidxPos);
524 
525  // output the mesh in tecplot format. If this works, CWIPI will be able
526  // to process it, too
527  /*
528  cout << "VARIABLES = \"X\", \"Y\", \"Z\", \"U\"" << endl;
529  cout << "ZONE NODES=" << nVerts << ",ELEMENTS=" << nElts;
530  cout << ",DATAPACKING=POINT, ZONETYPE=FETETRAHEDRON" << endl;
531  for (int i = 0; i < nVerts; ++i)
532  {
533  cout << m_coords[3*i + 0] << " " << m_coords[3*i + 1] << " ";
534  cout << m_coords[3*i + 2] << " " << 1.0 << endl;
535  }
536  for (int i = 0; i < nElts; ++i)
537  {
538  cout << m_connec[i*4 + 0] << " " << m_connec[i*4 + 1] << " ";
539  cout << m_connec[i*4 + 2] << " " << m_connec[i*4 + 3] << endl;
540  }
541  */
542 
543  cwipi_define_mesh(
544  m_couplingName.c_str(), nVerts, nElts, m_coords, m_connecIdx, m_connec);
545 }
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:163
std::map< int, PrismGeomSharedPtr > PrismGeomMap
Definition: PrismGeom.h:89
void AddElementsToMesh(T geom, int &coordsPos, int &connecPos, int &conidxPos)
std::map< int, PyrGeomSharedPtr > PyrGeomMap
Definition: PyrGeom.h:81
std::map< int, TetGeomSharedPtr > TetGeomMap
Definition: TetGeom.h:90
std::map< int, TriGeomSharedPtr > TriGeomMap
Definition: TriGeom.h:59
std::map< int, SegGeomSharedPtr > SegGeomMap
Definition: SegGeom.h:52
std::map< int, QuadGeomSharedPtr > QuadGeomMap
Definition: QuadGeom.h:54
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250
std::map< int, HexGeomSharedPtr > HexGeomMap
Definition: HexGeom.h:91

◆ create()

static CouplingSharedPtr Nektar::SolverUtils::CouplingCwipi::create ( MultiRegions::ExpListSharedPtr  field)
inlinestatic

Creates an instance of this class.

Definition at line 58 of file CouplingCwipi.h.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), CouplingCwipi(), Nektar::SolverUtils::CouplingSharedPtr, InterpCallback(), CellMLToNektar.cellml_metadata::p, SendCallback(), SOLVER_UTILS_EXPORT, and ~CouplingCwipi().

59  {
62  p->Init();
63  return p;
64  }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
SOLVER_UTILS_EXPORT typedef std::shared_ptr< Coupling > CouplingSharedPtr
Definition: Coupling.h:45

◆ DumpRawFields()

void Nektar::SolverUtils::CouplingCwipi::DumpRawFields ( const NekDouble  time,
Array< OneD, Array< OneD, NekDouble > >  rVals 
)
private

Definition at line 1085 of file CouplingCwipi.cpp.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), CellMLToNektar.pycml::format, Nektar::SolverUtils::Coupling::m_config, Nektar::SolverUtils::Coupling::m_evalField, Nektar::SolverUtils::Coupling::m_nRecvVars, m_recvField, Nektar::SolverUtils::Coupling::m_recvFieldNames, m_spacedim, Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), and Nektar::LibUtilities::Timer::TimePerTest().

Referenced by GetSendField(), and ReceiveCwipi().

1087 {
1088  LibUtilities::Timer timer1;
1089  timer1.Start();
1090 
1091 #if (defined _WIN32 && _MSC_VER < 1900)
1092  // We need this to make sure boost::format has always
1093  // two digits in the exponents of Scientific notation.
1094  unsigned int old_exponent_format;
1095  old_exponent_format = _set_output_format(_TWO_DIGIT_EXPONENT);
1096  filename = boost::str(boost::format(filename) % m_time);
1097  _set_output_format(old_exponent_format);
1098 #else
1099  std::string filename =
1100  boost::str(boost::format(m_config["DUMPRAW"]) % time);
1101 #endif
1102 
1103  Array<OneD, Array<OneD, NekDouble> > tmp(m_nRecvVars + m_spacedim);
1104  for (int i = 0; i < 3; ++i)
1105  {
1106  tmp[i] = Array<OneD, NekDouble>(m_recvField->GetTotPoints(), 0.0);
1107  }
1108  m_recvField->GetCoords(tmp[0], tmp[1], tmp[2]);
1109 
1110  for (int i = 0; i < m_nRecvVars; ++i)
1111  {
1112  tmp[m_spacedim + i] = rVals[i];
1113  }
1114 
1115  LibUtilities::CsvIO csvIO(m_evalField->GetSession()->GetComm());
1119  csvIO.Write(filename, rvPts);
1120 
1121  timer1.Stop();
1122  if (m_evalField->GetComm()->GetRank() == 0 &&
1123  m_evalField->GetSession()->DefinesCmdLineArgument("verbose"))
1124  {
1125  cout << "DumpRawFields total time: " << timer1.TimePerTest(1) << endl;
1126  }
1127 }
CouplingConfigMap m_config
Definition: Coupling.h:113
std::vector< std::string > m_recvFieldNames
Definition: Coupling.h:122
std::shared_ptr< PtsField > PtsFieldSharedPtr
Definition: PtsField.h:179
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
MultiRegions::ExpListSharedPtr m_recvField
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115

◆ EvaluateFields()

void Nektar::SolverUtils::CouplingCwipi::EvaluateFields ( Array< OneD, Array< OneD, NekDouble > >  interpField,
Array< OneD, Array< OneD, NekDouble > >  distCoords 
)
private

Definition at line 378 of file CouplingCwipi.cpp.

References ASSERTL0, Nektar::NekConstants::kNekZeroTol, Nektar::SolverUtils::Coupling::m_evalField, Nektar::SolverUtils::Coupling::m_nSendVars, m_sendField, and m_spacedim.

Referenced by GetSendField(), and SendCallback().

381 {
382  int nOutPts = distCoords.num_elements();
383 
384  Array<OneD, NekDouble> Lcoords(m_spacedim, 0.0);
385  for (int i = 0; i < nOutPts; ++i)
386  {
387  // Obtain Element and LocalCoordinate to interpolate
388  int elmtid = -1;
390  while (elmtid < 0 && tol <= 1E3 * NekConstants::kNekZeroTol)
391  {
392  elmtid = m_evalField->GetExpIndex(distCoords[i], Lcoords, tol);
393  tol *= 2;
394  }
395  if (tol > 2 * NekConstants::kNekZeroTol)
396  {
397  for (int j = 0; j < m_spacedim; ++j)
398  {
399  if (Lcoords[j] < -1 - 0.75 * NekConstants::kNekZeroTol)
400  {
401  Lcoords[j] = -1;
402  }
403  if (Lcoords[j] > 1 + 0.75 * NekConstants::kNekZeroTol)
404  {
405  Lcoords[j] = 1;
406  }
407  }
408  }
409 
410  ASSERTL0(elmtid >= 0,
411  "no element found for (" +
412  boost::lexical_cast<string>(distCoords[i][0]) + ", " +
413  boost::lexical_cast<string>(distCoords[i][1]) + ", " +
414  boost::lexical_cast<string>(distCoords[i][2]) + ")");
415 
416  int offset = m_evalField->GetPhys_Offset(elmtid);
417 
418  for (int f = 0; f < m_nSendVars; ++f)
419  {
420  NekDouble value = m_evalField->GetExp(elmtid)->StdPhysEvaluate(
421  Lcoords, m_sendField[f] + offset);
422 
423  ASSERTL0(!(boost::math::isnan)(value), "new value is not a number");
424  interpField[f][i] = value;
425  }
426  }
427 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
static const NekDouble kNekZeroTol
double NekDouble
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115
Array< OneD, Array< OneD, NekDouble > > m_sendField

◆ ExtrapolateFields()

void Nektar::SolverUtils::CouplingCwipi::ExtrapolateFields ( Array< OneD, Array< OneD, NekDouble > > &  rVals,
Array< OneD, int > &  notLoc 
)
private

Definition at line 959 of file CouplingCwipi.cpp.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), Nektar::LibUtilities::eNearestNeighbour, Nektar::SolverUtils::Coupling::m_evalField, m_extrapInterpolator, m_nPoints, Nektar::SolverUtils::Coupling::m_nRecvVars, m_recvField, m_spacedim, Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), Nektar::LibUtilities::Timer::TimePerTest(), and Vmath::Zero().

Referenced by GetSendField(), and ReceiveCwipi().

961 {
962  LibUtilities::Timer timer1, timer2;
963  timer1.Start();
964 
965  int totvars = 3 + m_nRecvVars;
966  int nNotLoc = notLoc.num_elements();
967  int nranks = m_evalField->GetSession()->GetComm()->GetSize();
968 
969  Array<OneD, int> thisNLoc(1, m_nPoints - nNotLoc);
970  Array<OneD, int> sizeMap(nranks);
971  m_evalField->GetSession()->GetComm()->AllGather(thisNLoc, sizeMap);
972 
973  Array<OneD, int> offsetMap(nranks);
974  offsetMap[0] = 0;
975  for (int i = 1; i < nranks; ++i)
976  {
977  offsetMap[i] = offsetMap[i - 1] + sizeMap[i - 1];
978  }
979  int totNLoc = offsetMap[nranks - 1] + sizeMap[nranks - 1];
980 
981  Array<OneD, Array<OneD, NekDouble> > allVals(totvars);
982  for (int i = 0; i < 3; ++i)
983  {
984  allVals[i] = Array<OneD, NekDouble>(m_nPoints);
985  }
986  m_recvField->GetCoords(allVals[0], allVals[1], allVals[2]);
987 
988  if (m_spacedim < 3)
989  {
990  Vmath::Zero(m_nPoints, allVals[2], 1);
991  }
992  if (m_spacedim < 2)
993  {
994  Vmath::Zero(m_nPoints, allVals[1], 1);
995  }
996 
997  for (int i = 0; i < m_nRecvVars; ++i)
998  {
999  allVals[3 + i] = rVals[i];
1000  }
1001 
1002  Array<OneD, Array<OneD, NekDouble> > locatedVals(totvars);
1003  for (int i = 0; i < totvars; ++i)
1004  {
1005  locatedVals[i] = Array<OneD, NekDouble>(totNLoc, -42.0);
1006  }
1007 
1008  // only copy points from allVals to locatedVals that were located
1009  int offset = offsetMap[m_evalField->GetSession()->GetComm()->GetRank()];
1010  for (int i = 0, intPos = 0, locPos = 0; i < m_nPoints; ++i)
1011  {
1012  if (locPos < nNotLoc && notLoc[locPos] == i)
1013  {
1014  // do nothing
1015  locPos++;
1016  }
1017  else
1018  {
1019  for (int k = 0; k < totvars; ++k)
1020  {
1021  locatedVals[k][offset + intPos] = allVals[k][i];
1022  }
1023  intPos++;
1024  }
1025  }
1026 
1027  // send all located points to all ranks. This is probably horribly expensive
1028  timer2.Start();
1029  for (int i = 0; i < totvars; ++i)
1030  {
1031  m_evalField->GetSession()->GetComm()->AllGatherv(
1032  locatedVals[i], sizeMap, offsetMap);
1033  }
1034  timer2.Stop();
1035 
1036  if (nNotLoc > 0)
1037  {
1038  LibUtilities::PtsFieldSharedPtr locatedPts =
1040  3, locatedVals);
1041 
1042  Array<OneD, Array<OneD, NekDouble> > notLocVals(totvars);
1043  for (int j = 0; j < totvars; ++j)
1044  {
1045  notLocVals[j] = Array<OneD, NekDouble>(nNotLoc);
1046  for (int i = 0; i < nNotLoc; ++i)
1047  {
1048  notLocVals[j][i] = allVals[j][notLoc[i]];
1049  }
1050  }
1053  3, notLocVals);
1054 
1055  // perform a nearest neighbour interpolation from locatedVals to the not
1056  // located rVals
1057  if (!m_extrapInterpolator)
1058  {
1062  m_extrapInterpolator->CalcWeights(locatedPts, notlocPts);
1063  m_extrapInterpolator->PrintStatistics();
1064  }
1065  m_extrapInterpolator->Interpolate(locatedPts, notlocPts);
1066 
1067  for (int j = 3; j < totvars; ++j)
1068  {
1069  for (int i = 0; i < nNotLoc; ++i)
1070  {
1071  allVals[j][notLoc[i]] = notLocVals[j][i];
1072  }
1073  }
1074  }
1075 
1076  timer1.Stop();
1077  if (m_evalField->GetComm()->GetRank() == 0 &&
1078  m_evalField->GetSession()->DefinesCmdLineArgument("verbose"))
1079  {
1080  cout << "ExtrapolateFields total time: " << timer1.TimePerTest(1);
1081  cout << " (AllGathervI: " << timer2.TimePerTest(1) << ")" << endl;
1082  }
1083 }
std::shared_ptr< PtsField > PtsFieldSharedPtr
Definition: PtsField.h:179
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
FieldUtils::InterpolatorSharedPtr m_extrapInterpolator
MultiRegions::ExpListSharedPtr m_recvField
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:376

◆ GetSendField()

SOLVER_UTILS_EXPORT NekDouble Nektar::SolverUtils::CouplingCwipi::GetSendField ( const int  i,
const int  j 
) const
inlineprotected

◆ InterpCallback()

void Nektar::SolverUtils::CouplingCwipi::InterpCallback ( const int  entities_dim,
const int  n_local_vertex,
const int  n_local_element,
const int  n_local_polhyedra,
const int  n_distant_point,
const double  local_coordinates[],
const int  local_connectivity_index[],
const int  local_connectivity[],
const int  local_polyhedra_face_index[],
const int  local_polyhedra_cell_to_face_connectivity[],
const int  local_polyhedra_face_connectivity_index[],
const int  local_polyhedra_face_connectivity[],
const double  distant_points_coordinates[],
const int  distant_points_location[],
const float  distant_points_distance[],
const int  distant_points_barycentric_coordinates_index[],
const double  distant_points_barycentric_coordinates[],
const int  stride,
const cwipi_solver_type_t  solver_type,
const void local_field,
void distant_field 
)
static

Definition at line 64 of file CouplingCwipi.cpp.

References ASSERTL0, and Nektar::SolverUtils::SendCallbackMap.

Referenced by create(), and SetupSend().

86 {
87  boost::ignore_unused(n_local_element, n_local_polyhedra, local_coordinates,
88  local_connectivity_index, local_connectivity,
89  local_polyhedra_face_index,
90  local_polyhedra_cell_to_face_connectivity,
91  local_polyhedra_face_connectivity_index,
92  local_polyhedra_face_connectivity,
93  distant_points_location,
94  distant_points_distance,
95  distant_points_barycentric_coordinates_index,
96  distant_points_barycentric_coordinates,
97  solver_type,
98  local_field);
99 
100  Array<OneD, Array<OneD, NekDouble> > interpField(stride);
101 
102  Array<OneD, Array<OneD, NekDouble> > distCoords(n_distant_point);
103  for (int i = 0; i < n_distant_point; ++i)
104  {
105  distCoords[i] = Array<OneD, NekDouble>(3);
106  for (int j = 0; j < 3; ++j)
107  {
108  distCoords[i][j] = distant_points_coordinates[3 * i + j];
109  }
110  }
111 
112  std::stringstream sst;
113  sst << entities_dim << "," << n_local_vertex << "," << stride;
114  SendCallbackMap[sst.str()](interpField, distCoords);
115 
116  ASSERTL0(interpField.num_elements() == stride, "size mismatch");
117  ASSERTL0(interpField[0].num_elements() == n_distant_point, "size mismatch");
118 
119  for (int i = 0; i < n_distant_point; i++)
120  {
121  for (int j = 0; j < stride; ++j)
122  {
123  ((double *)distant_field)[i * stride + j] = interpField[j][i];
124  }
125  }
126 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
static std::map< std::string, SendCallbackType > SendCallbackMap

◆ ReadConfig()

void Nektar::SolverUtils::CouplingCwipi::ReadConfig ( LibUtilities::SessionReaderSharedPtr  session)
private

Definition at line 248 of file CouplingCwipi.cpp.

References ASSERTL0, Nektar::SolverUtils::Coupling::m_config, and m_filtWidth.

Referenced by GetSendField(), and v_Init().

249 {
250  ASSERTL0(session->DefinesElement("Nektar/Coupling"),
251  "No Coupling config found");
252 
253  m_config["LOCALNAME"] = session->GetCmdLineArgument<std::string>("cwipi");
254 
255  TiXmlElement *vCoupling = session->GetElement("Nektar/Coupling");
256  ASSERTL0(vCoupling, "Invalid Coupling config");
257 
258  m_filtWidth = boost::lexical_cast<NekDouble>(m_config["FILTERWIDTH"]);
259 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
CouplingConfigMap m_config
Definition: Coupling.h:113
double NekDouble

◆ ReceiveCwipi()

void Nektar::SolverUtils::CouplingCwipi::ReceiveCwipi ( const int  step,
const NekDouble  time,
Array< OneD, Array< OneD, NekDouble > > &  field 
)
private

Definition at line 799 of file CouplingCwipi.cpp.

References ASSERTL1, DumpRawFields(), ExtrapolateFields(), Nektar::SolverUtils::Coupling::m_config, Nektar::SolverUtils::Coupling::m_couplingName, Nektar::SolverUtils::Coupling::m_evalField, m_filtWidth, m_lastReceive, m_nPoints, Nektar::SolverUtils::Coupling::m_nRecvVars, m_recvField, Nektar::SolverUtils::Coupling::m_recvFieldNames, m_recvHandle, Nektar::SolverUtils::Coupling::m_recvSteps, m_rValsInterl, m_spacedim, ReceiveStart(), Nektar::LibUtilities::ReduceMax, Vmath::Smul(), Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), and Nektar::LibUtilities::Timer::TimePerTest().

Referenced by GetSendField(), and v_Receive().

802 {
803  ASSERTL1(m_nRecvVars == field.num_elements(), "field size mismatch");
804 
805  if (m_nRecvVars < 1 || m_recvSteps < 1)
806  {
807  return;
808  }
809 
810  if (step >= m_lastReceive + m_recvSteps)
811  {
812  m_lastReceive = step;
813 
814  if (m_evalField->GetComm()->GetRank() == 0 &&
815  m_evalField->GetSession()->DefinesCmdLineArgument("verbose"))
816  {
817  cout << "waiting for receive at i = " << step << ", t = " << time
818  << endl;
819  }
820 
821  LibUtilities::Timer timer1, timer2, timer3;
822  timer1.Start();
823 
824  Array<OneD, NekDouble> tmpC(m_recvField->GetNcoeffs());
825  Array<OneD, Array<OneD, NekDouble> > rVals(m_nRecvVars);
826  for (int i = 0; i < m_nRecvVars; ++i)
827  {
828  rVals[i] = Array<OneD, NekDouble>(m_recvField->GetTotPoints());
829  }
830 
831  timer2.Start();
832  cwipi_wait_irecv(m_couplingName.c_str(), m_recvHandle);
833  timer2.Stop();
834 
835  // set to -1 so we know we can start receiving again
836  m_recvHandle = -1;
837 
838  int nNotLoc = cwipi_get_n_not_located_points(m_couplingName.c_str());
839  Array<OneD, int> notLoc;
840  if (nNotLoc != 0)
841  {
842  cout << "WARNING: relocating " << nNotLoc << " of " << m_nPoints
843  << " points" << endl;
844 
845  const int *tmp =
846  cwipi_get_not_located_points(m_couplingName.c_str());
847  notLoc = Array<OneD, int>(nNotLoc);
848  for (int i = 0; i < nNotLoc; ++i)
849  {
850  notLoc[i] = tmp[i] - 1;
851  }
852 
853  if (boost::to_upper_copy(m_config["NOTLOCMETHOD"]) == "KEEP")
854  {
855  // interpolate from m_evalField to m_recvField
856  for (int i = 0; i < m_nRecvVars; ++i)
857  {
858  m_evalField->FwdTrans(field[i], tmpC);
859  m_recvField->BwdTrans(tmpC, rVals[i]);
860  }
861  }
862  }
863 
864  for (int i = 0, locPos = 0, intPos = 0; i < m_nPoints; ++i)
865  {
866  if (locPos < nNotLoc && notLoc[locPos] == i)
867  {
868  // keep the original value of field[j][i]
869  locPos++;
870  }
871  else
872  {
873  for (int j = 0; j < m_nRecvVars; ++j)
874  {
875  rVals[j][i] = m_rValsInterl[intPos * m_nRecvVars + j];
876  }
877  intPos++;
878  }
879  }
880 
881  if (boost::to_upper_copy(m_config["NOTLOCMETHOD"]) == "EXTRAPOLATE")
882  {
883  int doExtrapolate = 0;
884  if (nNotLoc != 0)
885  {
886  doExtrapolate = 1;
887  }
888  m_evalField->GetSession()->GetComm()->AllReduce(
889  doExtrapolate, LibUtilities::ReduceMax);
890  if (doExtrapolate > 0)
891  {
892  ExtrapolateFields(rVals, notLoc);
893  }
894  }
895 
896  if (m_config["DUMPRAW"] != "0")
897  {
898  DumpRawFields(time, rVals);
899  }
900 
901  if (m_filtWidth > 0)
902  {
903  for (int i = 0; i < m_nRecvVars; ++i)
904  {
905  timer3.Start();
906 
907  Array<OneD, NekDouble> forcing(m_nPoints);
908 
909  Array<OneD, Array<OneD, NekDouble> > Velocity(m_spacedim);
910  for (int j = 0; j < m_spacedim; ++j)
911  {
912  Velocity[j] = Array<OneD, NekDouble>(m_nPoints, 0.0);
913  }
914 
915  Vmath::Smul(m_nPoints, -m_filtWidth, rVals[i], 1, forcing, 1);
916 
917  // Note we are using the
918  // LinearAdvectionDiffusionReaction solver here
919  // instead of HelmSolve since m_filtWidth is negative and
920  // so matrices are not positive definite. Ideally
921  // should allow for negative m_filtWidth coefficient in
922  // HelmSolve
923  m_recvField->LinearAdvectionDiffusionReactionSolve(
924  Velocity, forcing, tmpC, -m_filtWidth);
925 
926  m_evalField->BwdTrans(tmpC, field[i]);
927  timer3.Stop();
928 
929  if (m_evalField->GetComm()->GetRank() == 0 &&
930  m_evalField->GetSession()->DefinesCmdLineArgument(
931  "verbose"))
932  {
933  cout << "Smoother time (" << m_recvFieldNames[i]
934  << "): " << timer3.TimePerTest(1) << endl;
935  }
936  }
937  }
938  else
939  {
940  for (int i = 0; i < m_nRecvVars; ++i)
941  {
942  m_recvField->FwdTrans(rVals[i], tmpC);
943  m_evalField->BwdTrans(tmpC, field[i]);
944  }
945  }
946  timer1.Stop();
947 
948  if (m_evalField->GetComm()->GetRank() == 0 &&
949  m_evalField->GetSession()->DefinesCmdLineArgument("verbose"))
950  {
951  cout << "Receive total time: " << timer1.TimePerTest(1) << ", ";
952  cout << "Receive waiting time: " << timer2.TimePerTest(1) << endl;
953  }
954 
955  ReceiveStart();
956  }
957 }
CouplingConfigMap m_config
Definition: Coupling.h:113
std::vector< std::string > m_recvFieldNames
Definition: Coupling.h:122
void ExtrapolateFields(Array< OneD, Array< OneD, NekDouble > > &rVals, Array< OneD, int > &notLoc)
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
Definition: Vmath.cpp:216
MultiRegions::ExpListSharedPtr m_recvField
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115
void DumpRawFields(const NekDouble time, Array< OneD, Array< OneD, NekDouble > > rVals)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250

◆ ReceiveStart()

void Nektar::SolverUtils::CouplingCwipi::ReceiveStart ( )
private

Definition at line 709 of file CouplingCwipi.cpp.

References Nektar::SolverUtils::Coupling::m_couplingName, Nektar::SolverUtils::Coupling::m_evalField, Nektar::SolverUtils::Coupling::m_nRecvVars, m_recvHandle, m_recvTag, m_rValsInterl, Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), and Nektar::LibUtilities::Timer::TimePerTest().

Referenced by GetSendField(), ReceiveCwipi(), and v_Init().

710 {
711  if (m_recvHandle >= 0)
712  {
713  return;
714  }
715 
716  LibUtilities::Timer timer1;
717  timer1.Start();
718  // workaround a bug in cwipi: receiving_field_name should be const char* but
719  // is char*
720  char recFN[10];
721  strcpy(recFN, "dummyName");
722 
723  cwipi_irecv(m_couplingName.c_str(),
724  "ex1",
725  m_recvTag,
726  m_nRecvVars,
727  0,
728  0.0,
729  recFN,
731  &m_recvHandle);
732  timer1.Stop();
733 
734  if (m_evalField->GetComm()->GetRank() == 0 &&
735  m_evalField->GetSession()->DefinesCmdLineArgument("verbose"))
736  {
737  cout << "Receive start time: " << timer1.TimePerTest(1) << endl;
738  }
739 }
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115

◆ SendCallback()

void Nektar::SolverUtils::CouplingCwipi::SendCallback ( Array< OneD, Array< OneD, NekDouble > > &  interpField,
Array< OneD, Array< OneD, NekDouble > > &  distCoords 
)

Definition at line 597 of file CouplingCwipi.cpp.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, EvaluateFields(), Nektar::SolverUtils::Coupling::m_config, Nektar::SolverUtils::Coupling::m_nSendVars, m_sendField, m_sendInterpolator, and SetupSendInterpolation().

Referenced by create(), and SetupSend().

600 {
601  ASSERTL0(interpField.num_elements() == m_nSendVars, "size mismatch");
602 
603  for (int i = 0; i < m_nSendVars; ++i)
604  {
605  interpField[i] = Array<OneD, NekDouble>(distCoords.num_elements());
606  }
607 
608  if (boost::to_upper_copy(m_config["SENDMETHOD"]) == "NEARESTNEIGHBOUR" ||
609  boost::to_upper_copy(m_config["SENDMETHOD"]) == "SHEPARD")
610  {
611  if (!m_sendInterpolator)
612  {
614  }
615 
618  0, m_sendField);
621  0, interpField);
622  m_sendInterpolator->Interpolate(ptsIn, ptsOut);
623  }
624  else
625  {
626  EvaluateFields(interpField, distCoords);
627  }
628 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
CouplingConfigMap m_config
Definition: Coupling.h:113
FieldUtils::InterpolatorSharedPtr m_sendInterpolator
void EvaluateFields(Array< OneD, Array< OneD, NekDouble > > interpField, Array< OneD, Array< OneD, NekDouble > > distCoords)
std::shared_ptr< PtsField > PtsFieldSharedPtr
Definition: PtsField.h:179
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Array< OneD, Array< OneD, NekDouble > > m_sendField

◆ SendComplete()

void Nektar::SolverUtils::CouplingCwipi::SendComplete ( )
private

Definition at line 687 of file CouplingCwipi.cpp.

References Nektar::SolverUtils::Coupling::m_couplingName, Nektar::SolverUtils::Coupling::m_evalField, m_sendHandle, Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), and Nektar::LibUtilities::Timer::TimePerTest().

Referenced by GetSendField(), and v_Send().

688 {
689  if (m_sendHandle < 0)
690  {
691  return;
692  }
693 
694  LibUtilities::Timer timer1;
695  timer1.Start();
696  cwipi_wait_issend(m_couplingName.c_str(), m_sendHandle);
697  timer1.Stop();
698 
699  // set to -1 so we dont try finishing a send before a new one was started
700  m_sendHandle = -1;
701 
702  if (m_evalField->GetComm()->GetRank() == 0 &&
703  m_evalField->GetSession()->DefinesCmdLineArgument("verbose"))
704  {
705  cout << "Send waiting time: " << timer1.TimePerTest(1) << endl;
706  }
707 }
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115

◆ SetupReceive()

void Nektar::SolverUtils::CouplingCwipi::SetupReceive ( )
private

Definition at line 261 of file CouplingCwipi.cpp.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, ASSERTL1, Nektar::SolverUtils::Coupling::m_config, Nektar::SolverUtils::Coupling::m_couplingName, Nektar::SolverUtils::Coupling::m_evalField, m_newFields, m_nPoints, Nektar::SolverUtils::Coupling::m_nRecvVars, m_oldFields, m_points, m_recvField, m_rValsInterl, m_spacedim, and Nektar::SpatialDomains::MeshGraph::Read().

Referenced by GetSendField(), and v_Init().

262 {
263  int oversamp = boost::lexical_cast<int>(m_config["OVERSAMPLE"]);
264 
267  recvGraph->SetExpansionsToPointOrder(
268  oversamp + m_evalField->GetExp(0)->GetNumPoints(0));
269 
270  // TODO: DeclareCoeffPhysArrays
271  switch (m_spacedim)
272  {
273  case 1:
274  {
275  m_recvField =
277  m_evalField->GetSession(), recvGraph, "DefaultVar");
278  break;
279  }
280 
281  case 2:
282  {
283 
284  m_recvField =
286  m_evalField->GetSession(), recvGraph);
287  break;
288  }
289 
290  case 3:
291  {
292 
293  m_recvField =
295  m_evalField->GetSession(), recvGraph);
296  break;
297  }
298 
299  default:
300  {
301  ASSERTL0(false, "Expansion dimension not recognised");
302  break;
303  }
304  }
305 
306  m_oldFields = Array<OneD, Array<OneD, NekDouble> >(m_nRecvVars);
307  m_newFields = Array<OneD, Array<OneD, NekDouble> >(m_nRecvVars);
308  for (int i = 0; i < m_nRecvVars; ++i)
309  {
310  m_oldFields[i] = Array<OneD, NekDouble>(m_evalField->GetTotPoints());
311  m_newFields[i] = Array<OneD, NekDouble>(m_evalField->GetTotPoints());
312  }
313 
314  // define the quadrature points at which we want to receive data
315  m_nPoints = m_recvField->GetTotPoints();
316  Array<OneD, Array<OneD, NekDouble> > coords(3);
317  coords[0] = Array<OneD, NekDouble>(m_nPoints);
318  coords[1] = Array<OneD, NekDouble>(m_nPoints);
319  coords[2] = Array<OneD, NekDouble>(m_nPoints);
320  m_recvField->GetCoords(coords[0], coords[1], coords[2]);
321 
322  m_points = (double *)malloc(sizeof(double) * 3 * m_nPoints);
323  ASSERTL1(m_points != NULL, "malloc failed for m_points");
324 
325  for (int i = 0; i < m_nPoints; ++i)
326  {
327  m_points[3 * i + 0] = double(coords[0][i]);
328 
329  if (m_spacedim > 1)
330  {
331  m_points[3 * i + 1] = double(coords[1][i]);
332  }
333  else
334  {
335  m_points[3 * i + 1] = 0.0;
336  }
337 
338  if (m_spacedim > 2)
339  {
340  m_points[3 * i + 2] = double(coords[2][i]);
341  }
342  else
343  {
344  m_points[3 * i + 2] = 0.0;
345  }
346  }
347 
348  cwipi_set_points_to_locate(m_couplingName.c_str(), m_nPoints, m_points);
349 
350  m_rValsInterl = (double *)malloc(sizeof(double) * m_nPoints * m_nRecvVars);
351  ASSERTL1(m_rValsInterl != NULL, "malloc failed for m_rValsInterl");
352 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:163
CouplingConfigMap m_config
Definition: Coupling.h:113
Array< OneD, Array< OneD, NekDouble > > m_newFields
Array< OneD, Array< OneD, NekDouble > > m_oldFields
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
MultiRegions::ExpListSharedPtr m_recvField
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250
static MeshGraphSharedPtr Read(const LibUtilities::SessionReaderSharedPtr pSession, DomainRangeShPtr rng=NullDomainRangeShPtr, bool fillGraph=true)
Definition: MeshGraph.cpp:113

◆ SetupSend()

void Nektar::SolverUtils::CouplingCwipi::SetupSend ( )
private

Definition at line 354 of file CouplingCwipi.cpp.

References ASSERTL1, InterpCallback(), Nektar::SolverUtils::Coupling::m_couplingName, Nektar::SolverUtils::Coupling::m_evalField, Nektar::SolverUtils::Coupling::m_nSendVars, m_spacedim, m_sValsInterl, SendCallback(), and Nektar::SolverUtils::SendCallbackMap.

Referenced by GetSendField(), and v_Init().

355 {
356  // this array is never used because of our send callback method
357  m_sValsInterl = (double *)malloc(
358  sizeof(double) * m_evalField->GetGraph()->GetNvertices() * m_nSendVars);
359  ASSERTL1(m_sValsInterl != NULL, "malloc failed for m_sValsInterl");
360  for (int i = 0; i < m_evalField->GetGraph()->GetNvertices() * m_nSendVars;
361  ++i)
362  {
363  m_sValsInterl[i] = i;
364  }
365 
366  // register this coupling as sender
367  std::stringstream sst;
368  sst << m_spacedim << "," << m_evalField->GetGraph()->GetNvertices() << ","
369  << m_nSendVars;
370  SendCallbackMap[sst.str()] = std::bind(&CouplingCwipi::SendCallback,
371  this,
372  std::placeholders::_1,
373  std::placeholders::_2);
374  cwipi_set_interpolation_function(m_couplingName.c_str(),
376 }
static std::map< std::string, SendCallbackType > SendCallbackMap
static SOLVER_UTILS_EXPORT void InterpCallback(const int entities_dim, const int n_local_vertex, const int n_local_element, const int n_local_polhyedra, const int n_distant_point, const double local_coordinates[], const int local_connectivity_index[], const int local_connectivity[], const int local_polyhedra_face_index[], const int local_polyhedra_cell_to_face_connectivity[], const int local_polyhedra_face_connectivity_index[], const int local_polyhedra_face_connectivity[], const double distant_points_coordinates[], const int distant_points_location[], const float distant_points_distance[], const int distant_points_barycentric_coordinates_index[], const double distant_points_barycentric_coordinates[], const int stride, const cwipi_solver_type_t solver_type, const void *local_field, void *distant_field)
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115
SOLVER_UTILS_EXPORT void SendCallback(Array< OneD, Array< OneD, NekDouble > > &interpField, Array< OneD, Array< OneD, NekDouble > > &distCoords)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250

◆ SetupSendInterpolation()

void Nektar::SolverUtils::CouplingCwipi::SetupSendInterpolation ( )
private

Definition at line 429 of file CouplingCwipi.cpp.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), Nektar::LibUtilities::eNearestNeighbour, Nektar::LibUtilities::eShepard, Nektar::SolverUtils::Coupling::m_config, Nektar::SolverUtils::Coupling::m_couplingName, Nektar::SolverUtils::Coupling::m_evalField, and m_sendInterpolator.

Referenced by GetSendField(), and SendCallback().

430 {
431  const double *distCoords =
432  cwipi_get_distant_coordinates(m_couplingName.c_str());
433  int nPts = cwipi_get_n_distant_points(m_couplingName.c_str());
434 
435  Array<OneD, Array<OneD, NekDouble> > local(3);
436  for (int i = 0; i < 3; ++i)
437  {
438  local[i] = Array<OneD, NekDouble>(m_evalField->GetTotPoints(), 0.0);
439  }
440  m_evalField->GetCoords(local[0], local[1], local[2]);
443 
444  Array<OneD, Array<OneD, NekDouble> > dist(3);
445  for (int i = 0; i < 3; ++i)
446  {
447  dist[i] = Array<OneD, NekDouble>(nPts);
448  for (int j = 0; j < nPts; ++j)
449  {
450  dist[i][j] = distCoords[3 * j + i];
451  }
452  }
455 
457  if (boost::to_upper_copy(m_config["SENDMETHOD"]) == "SHEPARD")
458  {
459  method = LibUtilities::eShepard;
460  }
463  m_sendInterpolator->CalcWeights(locatPts, distPts);
464  m_sendInterpolator->PrintStatistics();
465 }
CouplingConfigMap m_config
Definition: Coupling.h:113
FieldUtils::InterpolatorSharedPtr m_sendInterpolator
std::shared_ptr< PtsField > PtsFieldSharedPtr
Definition: PtsField.h:179
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115

◆ v_Finalize()

void Nektar::SolverUtils::CouplingCwipi::v_Finalize ( void  )
protectedvirtual

Reimplemented from Nektar::SolverUtils::Coupling.

Definition at line 547 of file CouplingCwipi.cpp.

References Nektar::SolverUtils::Coupling::m_couplingName.

548 {
549  cwipi_delete_coupling(m_couplingName.c_str());
550 }

◆ v_Init()

void Nektar::SolverUtils::CouplingCwipi::v_Init ( )
protectedvirtual

Reimplemented from Nektar::SolverUtils::Coupling.

Definition at line 144 of file CouplingCwipi.cpp.

References AnnounceMesh(), ASSERTL0, Nektar::SolverUtils::Coupling::m_config, Nektar::SolverUtils::Coupling::m_couplingName, Nektar::SolverUtils::Coupling::m_evalField, m_filtWidth, Nektar::SolverUtils::Coupling::m_nRecvVars, Nektar::SolverUtils::Coupling::m_nSendVars, Nektar::SolverUtils::Coupling::m_recvSteps, m_recvTag, Nektar::SolverUtils::Coupling::m_sendSteps, m_sendTag, m_spacedim, OUTPUT_FREQ, ReadConfig(), ReceiveStart(), SetupReceive(), SetupSend(), and Nektar::SolverUtils::Coupling::v_Init().

145 {
147 
148  ReadConfig(m_evalField->GetSession());
149 
150  cwipi_add_local_int_control_parameter("nSendVars", m_nSendVars);
151  cwipi_add_local_int_control_parameter("nRecvVars", m_nRecvVars);
152  cwipi_add_local_string_control_parameter(
153  "recvFieldNames", m_config["RECEIVEVARIABLES"].c_str());
154  cwipi_add_local_string_control_parameter("sendFieldNames",
155  m_config["SENDVARIABLES"].c_str());
156 
157  // MPI_TAG_UB is guaranteed to be at least 32767, so we make
158  // sure m_recvTag < 32767. Only caveat: m_recvTag is not guaranteed to be
159  // unique.
160  m_recvTag = boost::hash<std::string>()(m_couplingName +
161  m_config["REMOTENAME"] + m_config["LOCALNAME"]) % 32767;
162 
163  cwipi_add_local_int_control_parameter("receiveTag", m_recvTag);
164 
165  m_spacedim = m_evalField->GetGraph()->GetSpaceDimension();
166 
167  if (m_filtWidth > 0)
168  {
169  m_filtWidth = 2 * M_PI / m_filtWidth;
171  }
172 
173  // Init Coupling
174  cwipi_solver_type_t solver_type = CWIPI_SOLVER_CELL_VERTEX;
175  NekDouble geom_tol = boost::lexical_cast<NekDouble>(m_config["GEOMTOL"]);
176  cwipi_create_coupling(m_couplingName.c_str(),
177  CWIPI_COUPLING_PARALLEL_WITH_PARTITIONING,
178  m_config["REMOTENAME"].c_str(),
179  m_spacedim,
180  geom_tol,
181  CWIPI_STATIC_MESH,
182  solver_type,
183  OUTPUT_FREQ,
184  "Ensight Gold",
185  "text");
186  cwipi_synchronize_control_parameter(m_config["REMOTENAME"].c_str());
187 
188  if (m_evalField->GetComm()->GetRank() == 0 &&
189  m_evalField->GetSession()->DefinesCmdLineArgument("verbose"))
190  {
191  cwipi_dump_application_properties();
192  }
193 
194  m_sendTag = cwipi_get_distant_int_control_parameter(
195  m_config["REMOTENAME"].c_str(), "receiveTag");
196 
197  if (cwipi_has_int_parameter(m_config["REMOTENAME"].c_str(), "nRecvVars"))
198  {
199  int remoteNRecvVars = cwipi_get_distant_int_control_parameter(
200  m_config["REMOTENAME"].c_str(), "nRecvVars");
201  ASSERTL0(remoteNRecvVars == m_nSendVars,
202  "Number of local send vars different to remote received vars");
203  }
204 
205  if (cwipi_has_int_parameter(m_config["REMOTENAME"].c_str(), "nSendVars"))
206  {
207  int remoteNSendVars = cwipi_get_distant_int_control_parameter(
208  m_config["REMOTENAME"].c_str(), "nSendVars");
209  ASSERTL0(remoteNSendVars == m_nRecvVars,
210  "Number of local receive vars different to remote sent vars");
211  }
212 
213  AnnounceMesh();
214 
215  if (m_nRecvVars > 0 && m_recvSteps > 0)
216  {
217  SetupReceive();
218  }
219 
220  if (m_evalField->GetComm()->GetRank() == 0 &&
221  m_evalField->GetSession()->DefinesCmdLineArgument("verbose"))
222  {
223  cout << "locating..." << endl;
224  }
225  cwipi_locate(m_couplingName.c_str());
226 
227  if (m_nSendVars > 0 && m_sendSteps > 0)
228  {
229  SetupSend();
230  }
231 
232  if (m_nRecvVars > 0 && m_recvSteps > 0)
233  {
234  ReceiveStart();
235  }
236 }
#define OUTPUT_FREQ
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
CouplingConfigMap m_config
Definition: Coupling.h:113
virtual SOLVER_UTILS_EXPORT void v_Init()
Definition: Coupling.cpp:61
double NekDouble
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115
void ReadConfig(LibUtilities::SessionReaderSharedPtr session)

◆ v_Receive()

void Nektar::SolverUtils::CouplingCwipi::v_Receive ( const int  step,
const NekDouble  time,
Array< OneD, Array< OneD, NekDouble > > &  field,
std::vector< std::string > &  varNames 
)
protectedvirtual

Implements Nektar::SolverUtils::Coupling.

Definition at line 741 of file CouplingCwipi.cpp.

References ASSERTL1, Nektar::SolverUtils::Coupling::GenerateVariableMapping(), Nektar::SolverUtils::Coupling::m_evalField, m_lastReceive, m_newFields, Nektar::SolverUtils::Coupling::m_nRecvVars, m_oldFields, Nektar::SolverUtils::Coupling::m_recvFieldNames, Nektar::SolverUtils::Coupling::m_recvSteps, ReceiveCwipi(), Vmath::Svtsvtp(), and Vmath::Vcopy().

745 {
746  if (m_nRecvVars < 1 || m_recvSteps < 1)
747  {
748  return;
749  }
750 
751  Array<OneD, Array<OneD, NekDouble> > recvFields(m_nRecvVars);
752  vector<int> recvVarsToVars =
754  ASSERTL1(m_nRecvVars == recvVarsToVars.size(), "field size mismatch");
755  for (int i = 0; i < recvVarsToVars.size(); ++i)
756  {
757  recvFields[i] = field[recvVarsToVars[i]];
758  }
759 
760  int nq = m_evalField->GetTotPoints();
761 
762  // make sure we have sensible data in old/new recvFields the first time this
763  // method is called
764  if (m_lastReceive < 0)
765  {
766  for (int i = 0; i < m_nRecvVars; ++i)
767  {
768  Vmath::Vcopy(nq, recvFields[i], 1, m_oldFields[i], 1);
769  Vmath::Vcopy(nq, recvFields[i], 1, m_newFields[i], 1);
770  }
771  }
772 
773  if (step >= m_lastReceive + m_recvSteps)
774  {
775  for (int i = 0; i < m_nRecvVars; ++i)
776  {
777  Vmath::Vcopy(nq, m_newFields[i], 1, m_oldFields[i], 1);
778  }
779 
780  ReceiveCwipi(step, time, m_newFields);
781  }
782 
783  NekDouble fact =
785  for (int i = 0; i < m_nRecvVars; ++i)
786  {
787  Vmath::Svtsvtp(nq,
788  fact,
789  m_newFields[i],
790  1,
791  (1 - fact),
792  m_oldFields[i],
793  1,
794  recvFields[i],
795  1);
796  }
797 }
void ReceiveCwipi(const int step, const NekDouble time, Array< OneD, Array< OneD, NekDouble > > &field)
Array< OneD, Array< OneD, NekDouble > > m_newFields
std::vector< std::string > m_recvFieldNames
Definition: Coupling.h:122
SOLVER_UTILS_EXPORT std::vector< int > GenerateVariableMapping(std::vector< std::string > &vars, std::vector< std::string > &transVars)
Definition: Coupling.cpp:135
Array< OneD, Array< OneD, NekDouble > > m_oldFields
double NekDouble
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115
void Svtsvtp(int n, const T alpha, const T *x, int incx, const T beta, const T *y, int incy, T *z, int incz)
vvtvvtp (scalar times vector plus scalar times vector):
Definition: Vmath.cpp:594
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1064

◆ v_Send()

void Nektar::SolverUtils::CouplingCwipi::v_Send ( const int  step,
const NekDouble  time,
const Array< OneD, const Array< OneD, NekDouble > > &  field,
std::vector< std::string > &  varNames 
)
protectedvirtual

Implements Nektar::SolverUtils::Coupling.

Definition at line 630 of file CouplingCwipi.cpp.

References Nektar::SolverUtils::Coupling::GenerateVariableMapping(), Nektar::SolverUtils::Coupling::m_couplingName, Nektar::SolverUtils::Coupling::m_evalField, m_lastSend, Nektar::SolverUtils::Coupling::m_nSendVars, m_sendField, Nektar::SolverUtils::Coupling::m_sendFieldNames, m_sendHandle, Nektar::SolverUtils::Coupling::m_sendSteps, m_sendTag, m_sValsInterl, SendComplete(), Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), and Nektar::LibUtilities::Timer::TimePerTest().

635 {
636  if (m_nSendVars < 1 || m_sendSteps < 1)
637  {
638  return;
639  }
640 
641  if (step >= m_lastSend + m_sendSteps)
642  {
643  SendComplete();
644 
645  m_lastSend = step;
646 
647  vector<int> sendVarsToVars =
649  m_sendField = Array<OneD, Array<OneD, NekDouble> >(m_nSendVars);
650  for (int i = 0; i < sendVarsToVars.size(); ++i)
651  {
652  m_sendField[i] = field[sendVarsToVars[i]];
653  }
654 
655  if (m_evalField->GetComm()->GetRank() == 0 &&
656  m_evalField->GetSession()->DefinesCmdLineArgument("verbose"))
657  {
658  cout << "sending fields at i = " << step << ", t = " << time
659  << endl;
660  }
661 
662  LibUtilities::Timer timer1;
663  timer1.Start();
664 
665  char sendFN[10];
666  strcpy(sendFN, "dummyName");
667 
668  cwipi_issend(m_couplingName.c_str(),
669  "ex1",
670  m_sendTag,
671  m_nSendVars,
672  step,
673  time,
674  sendFN,
676  &m_sendHandle);
677  timer1.Stop();
678 
679  if (m_evalField->GetComm()->GetRank() == 0 &&
680  m_evalField->GetSession()->DefinesCmdLineArgument("verbose"))
681  {
682  cout << "Send total time: " << timer1.TimePerTest(1) << endl;
683  }
684  }
685 }
SOLVER_UTILS_EXPORT std::vector< int > GenerateVariableMapping(std::vector< std::string > &vars, std::vector< std::string > &transVars)
Definition: Coupling.cpp:135
std::vector< std::string > m_sendFieldNames
Definition: Coupling.h:118
MultiRegions::ExpListSharedPtr m_evalField
Definition: Coupling.h:115
Array< OneD, Array< OneD, NekDouble > > m_sendField

Member Data Documentation

◆ className

std::string Nektar::SolverUtils::CouplingCwipi::className
static
Initial value:
=
GetCouplingFactory().RegisterCreatorFunction(
"Cwipi", CouplingCwipi::create, "Cwipi Coupling")

Definition at line 55 of file CouplingCwipi.h.

◆ m_connec

int* Nektar::SolverUtils::CouplingCwipi::m_connec
protected

Definition at line 121 of file CouplingCwipi.h.

Referenced by AddElementsToMesh(), AnnounceMesh(), and ~CouplingCwipi().

◆ m_connecIdx

int* Nektar::SolverUtils::CouplingCwipi::m_connecIdx
protected

Definition at line 120 of file CouplingCwipi.h.

Referenced by AddElementsToMesh(), AnnounceMesh(), and ~CouplingCwipi().

◆ m_coords

double* Nektar::SolverUtils::CouplingCwipi::m_coords
protected

Definition at line 119 of file CouplingCwipi.h.

Referenced by AddElementsToMesh(), AnnounceMesh(), and ~CouplingCwipi().

◆ m_extrapInterpolator

FieldUtils::InterpolatorSharedPtr Nektar::SolverUtils::CouplingCwipi::m_extrapInterpolator
protected

Definition at line 129 of file CouplingCwipi.h.

Referenced by ExtrapolateFields().

◆ m_filtWidth

NekDouble Nektar::SolverUtils::CouplingCwipi::m_filtWidth
protected

Definition at line 98 of file CouplingCwipi.h.

Referenced by ReadConfig(), ReceiveCwipi(), and v_Init().

◆ m_lastReceive

int Nektar::SolverUtils::CouplingCwipi::m_lastReceive
protected

Definition at line 114 of file CouplingCwipi.h.

Referenced by ReceiveCwipi(), and v_Receive().

◆ m_lastSend

int Nektar::SolverUtils::CouplingCwipi::m_lastSend
protected

Definition at line 113 of file CouplingCwipi.h.

Referenced by v_Send().

◆ m_newFields

Array<OneD, Array<OneD, NekDouble> > Nektar::SolverUtils::CouplingCwipi::m_newFields
protected

Definition at line 105 of file CouplingCwipi.h.

Referenced by SetupReceive(), and v_Receive().

◆ m_nPoints

int Nektar::SolverUtils::CouplingCwipi::m_nPoints
protected

Definition at line 117 of file CouplingCwipi.h.

Referenced by ExtrapolateFields(), ReceiveCwipi(), and SetupReceive().

◆ m_oldFields

Array<OneD, Array<OneD, NekDouble> > Nektar::SolverUtils::CouplingCwipi::m_oldFields
protected

Definition at line 104 of file CouplingCwipi.h.

Referenced by SetupReceive(), and v_Receive().

◆ m_points

double* Nektar::SolverUtils::CouplingCwipi::m_points
protected

Definition at line 118 of file CouplingCwipi.h.

Referenced by SetupReceive(), and ~CouplingCwipi().

◆ m_recvField

MultiRegions::ExpListSharedPtr Nektar::SolverUtils::CouplingCwipi::m_recvField
protected

Definition at line 102 of file CouplingCwipi.h.

Referenced by DumpRawFields(), ExtrapolateFields(), ReceiveCwipi(), and SetupReceive().

◆ m_recvHandle

int Nektar::SolverUtils::CouplingCwipi::m_recvHandle
protected

Definition at line 108 of file CouplingCwipi.h.

Referenced by ReceiveCwipi(), and ReceiveStart().

◆ m_recvTag

int Nektar::SolverUtils::CouplingCwipi::m_recvTag
protected

Definition at line 111 of file CouplingCwipi.h.

Referenced by ReceiveStart(), and v_Init().

◆ m_rValsInterl

double* Nektar::SolverUtils::CouplingCwipi::m_rValsInterl
protected

Definition at line 122 of file CouplingCwipi.h.

Referenced by ReceiveCwipi(), ReceiveStart(), SetupReceive(), and ~CouplingCwipi().

◆ m_sendField

Array<OneD, Array<OneD, NekDouble> > Nektar::SolverUtils::CouplingCwipi::m_sendField
protected

Definition at line 100 of file CouplingCwipi.h.

Referenced by EvaluateFields(), SendCallback(), and v_Send().

◆ m_sendHandle

int Nektar::SolverUtils::CouplingCwipi::m_sendHandle
protected

Definition at line 107 of file CouplingCwipi.h.

Referenced by SendComplete(), and v_Send().

◆ m_sendInterpolator

FieldUtils::InterpolatorSharedPtr Nektar::SolverUtils::CouplingCwipi::m_sendInterpolator
protected

Definition at line 127 of file CouplingCwipi.h.

Referenced by SendCallback(), and SetupSendInterpolation().

◆ m_sendTag

int Nektar::SolverUtils::CouplingCwipi::m_sendTag
protected

Definition at line 110 of file CouplingCwipi.h.

Referenced by v_Init(), and v_Send().

◆ m_spacedim

int Nektar::SolverUtils::CouplingCwipi::m_spacedim
protected

◆ m_sValsInterl

double* Nektar::SolverUtils::CouplingCwipi::m_sValsInterl
protected

Definition at line 123 of file CouplingCwipi.h.

Referenced by SetupSend(), v_Send(), and ~CouplingCwipi().

◆ m_vertMap

std::map<int, int> Nektar::SolverUtils::CouplingCwipi::m_vertMap
protected

Definition at line 125 of file CouplingCwipi.h.

Referenced by AddElementsToMesh().