Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Types | Private Member Functions | Private Attributes | List of all members
Nektar::Utilities::ProcessVarOpti Class Reference

#include <ProcessVarOpti.h>

Inheritance diagram for Nektar::Utilities::ProcessVarOpti:
Inheritance graph
[legend]
Collaboration diagram for Nektar::Utilities::ProcessVarOpti:
Collaboration graph
[legend]

Public Member Functions

 ProcessVarOpti (MeshSharedPtr m)
 
virtual ~ProcessVarOpti ()
 
virtual void Process ()
 
- Public Member Functions inherited from Nektar::NekMeshUtils::ProcessModule
NEKMESHUTILS_EXPORT ProcessModule (MeshSharedPtr p_m)
 
- Public Member Functions inherited from Nektar::NekMeshUtils::Module
NEKMESHUTILS_EXPORT Module (MeshSharedPtr p_m)
 
NEKMESHUTILS_EXPORT void RegisterConfig (std::string key, std::string value)
 Register a configuration option with a module. More...
 
NEKMESHUTILS_EXPORT void PrintConfig ()
 Print out all configuration options for a module. More...
 
NEKMESHUTILS_EXPORT void SetDefaults ()
 Sets default configuration options for those which have not been set. More...
 
NEKMESHUTILS_EXPORT MeshSharedPtr GetMesh ()
 
virtual NEKMESHUTILS_EXPORT void ProcessVertices ()
 Extract element vertices. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessEdges (bool ReprocessEdges=true)
 Extract element edges. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessFaces (bool ReprocessFaces=true)
 Extract element faces. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessElements ()
 Generate element IDs. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessComposites ()
 Generate composites. More...
 
virtual NEKMESHUTILS_EXPORT void ClearElementLinks ()
 

Static Public Member Functions

static boost::shared_ptr< Modulecreate (MeshSharedPtr m)
 Creates an instance of this class. More...
 

Static Public Attributes

static ModuleKey className
 

Private Types

typedef std::map< int,
std::vector< ElUtilSharedPtr > > 
NodeElMap
 

Private Member Functions

void Analytics ()
 
std::map
< LibUtilities::ShapeType,
DerivUtilSharedPtr
BuildDerivUtil (int o)
 
void GetElementMap (int o, std::map< LibUtilities::ShapeType, DerivUtilSharedPtr > derMap)
 
std::vector< ElUtilSharedPtrGetLockedElements (NekDouble thres)
 
std::vector< std::vector
< NodeSharedPtr > > 
CreateColoursets (std::vector< NodeSharedPtr > remain)
 
std::vector< std::vector
< NodeSharedPtr > > 
GetColouredNodes (std::vector< ElUtilSharedPtr > elLock)
 
void RemoveLinearCurvature ()
 

Private Attributes

NodeElMap m_nodeElMap
 
std::vector< ElUtilSharedPtrm_dataSet
 
ResidualSharedPtr m_res
 
optiType m_opti
 

Additional Inherited Members

- Protected Member Functions inherited from Nektar::NekMeshUtils::Module
NEKMESHUTILS_EXPORT void ReorderPrisms (PerMap &perFaces)
 Reorder node IDs so that prisms and tetrahedra are aligned correctly. More...
 
NEKMESHUTILS_EXPORT void PrismLines (int prism, PerMap &perFaces, std::set< int > &prismsDone, std::vector< ElementSharedPtr > &line)
 
- Protected Attributes inherited from Nektar::NekMeshUtils::Module
MeshSharedPtr m_mesh
 Mesh object. More...
 
std::map< std::string,
ConfigOption
m_config
 List of configuration values. More...
 

Detailed Description

Definition at line 83 of file ProcessVarOpti.h.

Member Typedef Documentation

typedef std::map<int, std::vector<ElUtilSharedPtr> > Nektar::Utilities::ProcessVarOpti::NodeElMap
private

Definition at line 101 of file ProcessVarOpti.h.

Constructor & Destructor Documentation

Nektar::Utilities::ProcessVarOpti::ProcessVarOpti ( MeshSharedPtr  m)

Definition at line 67 of file ProcessVarOpti.cpp.

References Nektar::NekMeshUtils::Module::m_config.

67  : ProcessModule(m)
68 {
69  // clang-format off
70  m_config["linearelastic"] =
71  ConfigOption(true, "", "Optimise for linear elasticity");
72  m_config["winslow"] =
73  ConfigOption(true, "", "Optimise for winslow");
74  m_config["roca"] =
75  ConfigOption(true, "", "Optimise for roca method");
76  m_config["hyperelastic"] =
77  ConfigOption(true, "", "Optimise for hyper elasticity");
78  m_config["numthreads"] =
79  ConfigOption(false, "1", "Number of threads");
80  m_config["restol"] =
81  ConfigOption(false, "1e-6", "Tolerance criterion");
82  m_config["maxiter"] =
83  ConfigOption(false, "500", "Maximum number of iterations");
84  m_config["nq"] =
85  ConfigOption(false, "-1", "Order of mesh");
86  m_config["region"] =
87  ConfigOption(false, "0.0", "create regions based on target");
88  m_config["resfile"] =
89  ConfigOption(false, "", "writes residual values to file");
90  m_config["histfile"] =
91  ConfigOption(false, "", "histogram of scaled jac");
92  m_config["overint"] =
93  ConfigOption(false, "6", "over integration order");
94  m_config["analytics"] =
95  ConfigOption(false, "", "basic analytics module");
96  // clang-format on
97 }
Represents a command-line configuration option.
NEKMESHUTILS_EXPORT ProcessModule(MeshSharedPtr p_m)
std::map< std::string, ConfigOption > m_config
List of configuration values.
Nektar::Utilities::ProcessVarOpti::~ProcessVarOpti ( )
virtual

Definition at line 99 of file ProcessVarOpti.cpp.

100 {
101 }

Member Function Documentation

void Nektar::Utilities::ProcessVarOpti::Analytics ( )
private

Definition at line 447 of file ProcessVarOpti.cpp.

References BuildDerivUtil(), Nektar::LibUtilities::NekFactory< tKey, tBase, >::CreateInstance(), GetElementMap(), Nektar::Utilities::GetNodeOptiFactory(), m_dataSet, Nektar::NekMeshUtils::Module::m_mesh, m_nodeElMap, m_opti, and m_res.

Referenced by Process().

448 {
449  // Grab the first element from the list
450  ElementSharedPtr elmt = m_mesh->m_element[m_mesh->m_expDim][0];
451 
452  // Get curved nodes
453  vector<NodeSharedPtr> nodes;
454  elmt->GetCurvedNodes(nodes);
455 
456  // We're going to investigate only the first node (corner node)
457  NodeSharedPtr node = nodes[4];
458 
459  // Loop over overintegration orders
460  const int nPoints = 200;
461  const int overInt = 40;
462  const NekDouble originX = -1.0;
463  const NekDouble originY = -1.0;
464  const NekDouble length = 2.0;
465  const NekDouble dx = length / (nPoints - 1);
466 
467  cout << "# overint = " << overInt << endl;
468  cout << "# Columns: x, y, over-integration orders (0 -> " << overInt - 1
469  << "), "
470  << " min(scaledJac)" << endl;
471 
472  // Loop over square defined by (originX, originY), length
473  for (int k = 0; k < nPoints; ++k)
474  {
475  node->m_y = originY + k * dx;
476  for (int j = 0; j < nPoints; ++j)
477  {
478  node->m_x = originX + j * dx;
479  cout << node->m_x << " " << node->m_y << " ";
480 
481  NekDouble minJacNew;
482 
483  for (int i = 0; i < overInt; ++i)
484  {
485  // Clear any existing node to element mapping.
486  m_dataSet.clear();
487  m_nodeElMap.clear();
488 
489  // Build deriv utils and element map.
490  map<LibUtilities::ShapeType, DerivUtilSharedPtr> derivUtils =
491  BuildDerivUtil(i);
492 
493  // Reconstruct element map
494  GetElementMap(i, derivUtils);
495 
496  for (int j = 0; j < m_dataSet.size(); j++)
497  {
498  m_dataSet[j]->Evaluate();
499  m_dataSet[j]->InitialMinJac();
500  }
501 
502  // Create NodeOpti object.
503  NodeOptiSharedPtr nodeOpti =
505  m_mesh->m_spaceDim * 11, node,
506  m_nodeElMap.find(node->m_id)->second, m_res, derivUtils,
507  m_opti);
508 
509  minJacNew = 0.0;
510 
511  // Evaluate functional.
512  nodeOpti->CalcMinJac();
513  cout << nodeOpti->GetFunctional<2>(minJacNew) << " ";
514  // NekDouble eigen;
515  // nodeOpti->GetFunctional<2>(minJacNew);
516  // nodeOpti->MinEigen<2>(eigen);
517  // cout << eigen << " ";
518  }
519 
520  cout << minJacNew << endl;
521  }
522  }
523 }
NodeOptiFactory & GetNodeOptiFactory()
Definition: NodeOpti.cpp:52
tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(MAX_PARAM) BOOST_PP_ENUM_BINARY_PARAMS(MAX_PARAM, tParam, x))
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:162
void GetElementMap(int o, std::map< LibUtilities::ShapeType, DerivUtilSharedPtr > derMap)
std::map< LibUtilities::ShapeType, DerivUtilSharedPtr > BuildDerivUtil(int o)
std::vector< ElUtilSharedPtr > m_dataSet
boost::shared_ptr< Node > NodeSharedPtr
Definition: Node.h:50
double NekDouble
boost::shared_ptr< NodeOpti > NodeOptiSharedPtr
Definition: NodeOpti.h:135
boost::shared_ptr< Element > ElementSharedPtr
Definition: Edge.h:49
map< LibUtilities::ShapeType, DerivUtilSharedPtr > Nektar::Utilities::ProcessVarOpti::BuildDerivUtil ( int  o)
private

Definition at line 49 of file PreProcessing.cpp.

References ASSERTL0, Nektar::LibUtilities::eHexahedron, Nektar::LibUtilities::eNodalPrismElec, Nektar::LibUtilities::eNodalPrismSPI, Nektar::LibUtilities::eNodalQuadElec, Nektar::LibUtilities::eNodalTetElec, Nektar::LibUtilities::eNodalTetSPI, Nektar::LibUtilities::eNodalTriElec, Nektar::LibUtilities::eNodalTriSPI, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::LibUtilities::NodalUtil::GetInterpolationMatrix(), Nektar::LibUtilities::NodalUtil::GetVandermonde(), Nektar::LibUtilities::NodalUtil::GetVandermondeForDeriv(), Nektar::iterator, and Nektar::LibUtilities::PointsManager().

Referenced by Analytics(), and Process().

51 {
52  // build Vandermonde information
53  map<LibUtilities::ShapeType, DerivUtilSharedPtr> ret;
54 
55  // Typedef for points types used in the variational optimser. First entry is
56  // the evaluation points; second entry is the distributions used for the
57  // full element (includes element boundary)
58  typedef std::pair<LibUtilities::PointsType, LibUtilities::PointsType>
59  PTypes;
60 
61  map<LibUtilities::ShapeType, PTypes> typeMap;
63 
64  if (m_mesh->m_nummode + o <= 11)
65  {
66  typeMap[LibUtilities::eTriangle] =
70  typeMap[LibUtilities::ePrism] =
72  }
73 
76  // typeMap[LibUtilities::eHexahedron] =
77  // PTypes(LibUtilities::eNodalHexElec, LibUtilities::eNodalHexElec);
78 
79  for (it = typeMap.begin(); it != typeMap.end(); it++)
80  {
81  PTypes pType = it->second;
82  DerivUtilSharedPtr der = boost::shared_ptr<DerivUtil>(new DerivUtil());
83 
84  LibUtilities::PointsKey pkey1(m_mesh->m_nummode, pType.second);
85  LibUtilities::PointsKey pkey2(m_mesh->m_nummode + o, pType.first);
86 
87  const int pDim = pkey1.GetPointsDim();
88  const int order = m_mesh->m_nummode - 1;
89 
90  Array<OneD, Array<OneD, NekDouble> > u1(pDim), u2(pDim);
91 
92  switch (pDim)
93  {
94  case 2:
95  {
96  LibUtilities::PointsManager()[pkey1]->GetPoints(u1[0], u1[1]);
97  LibUtilities::PointsManager()[pkey2]->GetPoints(u2[0], u2[1]);
98  break;
99  }
100  case 3:
101  {
102  LibUtilities::PointsManager()[pkey1]->GetPoints(u1[0], u1[1],
103  u1[2]);
104  LibUtilities::PointsManager()[pkey2]->GetPoints(u2[0], u2[1],
105  u2[2]);
106  break;
107  }
108  }
109 
110  der->ptsStd = u1[0].num_elements();
111  der->pts = u2[0].num_elements();
112 
113  LibUtilities::NodalUtil *nodalUtil = NULL;
114 
115  if (it->first == LibUtilities::eTriangle)
116  {
117  nodalUtil =
118  new LibUtilities::NodalUtilTriangle(order, u1[0], u1[1]);
119  }
120  else if (it->first == LibUtilities::eQuadrilateral)
121  {
122  nodalUtil = new LibUtilities::NodalUtilQuad(order, u1[0], u1[1]);
123  }
124  else if (it->first == LibUtilities::eTetrahedron)
125  {
126  nodalUtil = new LibUtilities::NodalUtilTetrahedron(order, u1[0],
127  u1[1], u1[2]);
128  }
129  else if (it->first == LibUtilities::ePrism)
130  {
131  nodalUtil =
132  new LibUtilities::NodalUtilPrism(order, u1[0], u1[1], u1[2]);
133  }
134  else if (it->first == LibUtilities::eHexahedron)
135  {
136  nodalUtil =
137  new LibUtilities::NodalUtilHex(order, u1[0], u1[1], u1[2]);
138  }
139  else
140  {
141  ASSERTL0(false,
142  "Unknown element type for derivative utility setup");
143  }
144 
145  NekMatrix<NekDouble> interp = *nodalUtil->GetInterpolationMatrix(u2);
146  NekMatrix<NekDouble> Vandermonde = *nodalUtil->GetVandermonde();
147  NekMatrix<NekDouble> VandermondeI = Vandermonde;
148  VandermondeI.Invert();
149 
150  for (int i = 0; i < pDim; ++i)
151  {
152  der->VdmDStd[i] =
153  *nodalUtil->GetVandermondeForDeriv(i) * VandermondeI;
154  der->VdmD[i] = interp * der->VdmDStd[i];
155  }
156 
157  Array<OneD, NekDouble> qds =
158  LibUtilities::PointsManager()[pkey2]->GetW();
159  NekVector<NekDouble> quadWi(qds);
160  der->quadW = quadWi;
161 
162  ret[it->first] = der;
163  //delete nodalUtil;
164  }
165 
166  return ret;
167 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
3D Nodal Symmetric positive internal tet (Whitherden, Vincent)
Definition: PointsType.h:78
3D Nodal Electrostatic Points on a Tetrahedron
Definition: PointsType.h:74
PointsManagerT & PointsManager(void)
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
boost::shared_ptr< DerivUtil > DerivUtilSharedPtr
Definition: ElUtil.h:51
2D Nodal Electrostatic Points on a Triangle
Definition: PointsType.h:70
3D electrostatically spaced points on a Prism
Definition: PointsType.h:76
2D Nodal Symmetric positive internal triangle (Whitherden, Vincent)
Definition: PointsType.h:77
static boost::shared_ptr<Module> Nektar::Utilities::ProcessVarOpti::create ( MeshSharedPtr  m)
inlinestatic

Creates an instance of this class.

Definition at line 87 of file ProcessVarOpti.h.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr().

88  {
90  }
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
vector< vector< NodeSharedPtr > > Nektar::Utilities::ProcessVarOpti::CreateColoursets ( std::vector< NodeSharedPtr remain)
private

Definition at line 455 of file PreProcessing.cpp.

References ASSERTL0, Nektar::iterator, and Nektar::LibUtilities::PrintProgressbar().

457 {
458  vector<vector<NodeSharedPtr> > retPart;
459 
460  // loop until all free nodes have been sorted
461  while (remain.size() > 0)
462  {
463  vector<NodeSharedPtr> layer; // one colourset
464  set<int> locked;
465  set<int> completed;
466  for (int i = 0; i < remain.size(); i++)
467  {
468  NodeElMap::iterator it = m_nodeElMap.find(remain[i]->m_id); //try to find node within all elements
469  ASSERTL0(it != m_nodeElMap.end(), "could not find node");
470 
471  vector<ElUtilSharedPtr> &elUtils = it->second; // identify the vector of all associated elements of the node
472 
473  bool islocked = false; // suppose node is not locked
474  for (int j = 0; j < elUtils.size(); j++) // loop over all associated elements of the node
475  {
476  set<int>::iterator sit = locked.find(elUtils[j]->GetId()); // check all nodes of the element
477  if (sit != locked.end()) //if node is within the set of locked nodes
478  {
479  islocked = true; // if yes, flag node as locked
480  break; // and go to next node
481  }
482  }
483  if (!islocked) // if the node is not locked
484  {
485  layer.push_back(remain[i]); // insert node into colourset
486  completed.insert(remain[i]->m_id); // insert sorted node into "completed" list
487  for (int j = 0; j < elUtils.size(); j++) // loop over all other nodes of the same element
488  {
489  locked.insert(elUtils[j]->GetId()); // and flag these nodes as locked
490  }
491  }
492  }
493 
494  // identify nodes which are not sorted, yet and create new "remain" vector
495  vector<NodeSharedPtr> tmp = remain;
496  remain.clear();
497  for (int i = 0; i < tmp.size(); i++)
498  {
499  set<int>::iterator sit = completed.find(tmp[i]->m_id);
500  if (sit == completed.end())
501  {
502  remain.push_back(tmp[i]);
503  }
504  }
505 
506  // include layer or colourset into vector of coloursets
507  retPart.push_back(layer);
508 
509  // print out progress
510  if(m_mesh->m_verbose)
511  {
512  LibUtilities::PrintProgressbar(m_res->n - remain.size(), m_res->n, "Node Coloring");
513  }
514 
515  }
516  return retPart;
517 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
int PrintProgressbar(const int position, const int goal, const string message, int lastprogress=-1)
Prints a progressbar.
Definition: Progressbar.hpp:69
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
vector< vector< NodeSharedPtr > > Nektar::Utilities::ProcessVarOpti::GetColouredNodes ( std::vector< ElUtilSharedPtr elLock)
private

Definition at line 186 of file PreProcessing.cpp.

References ASSERTL0, and Nektar::iterator.

Referenced by Process().

188 {
189 
190  // create set of nodes to be ignored and hence not included in the coloursets
191  NodeSet ignoredNodes;
192  for (int i = 0; i < elLock.size(); i++)
193  {
194  vector<NodeSharedPtr> nodes;
195  elLock[i]->GetEl()->GetCurvedNodes(nodes);
196  for (int j = 0; j < nodes.size(); j++)
197  {
198  ignoredNodes.insert(nodes[j]);
199  }
200  }
201 
202  // create set of nodes which are at the boundary and hence not included in the colourset
203  NodeSet boundaryNodes;
204 
205  switch (m_mesh->m_spaceDim)
206  {
207  case 2:
208  {
210  for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++)
211  {
212  if((*it)->m_elLink.size() == 2)
213  {
214  continue;
215  }
216 
217  boundaryNodes.insert((*it)->m_n1);
218  boundaryNodes.insert((*it)->m_n2);
219  for(int i = 0; i < (*it)->m_edgeNodes.size(); i++)
220  {
221  boundaryNodes.insert((*it)->m_edgeNodes[i]);
222  }
223  }
224  break;
225  }
226  case 3:
227  {
228  if(!m_mesh->m_cad)
229  {
231  for (it = m_mesh->m_faceSet.begin();
232  it != m_mesh->m_faceSet.end(); it++)
233  {
234  if ((*it)->m_elLink.size() == 2)
235  {
236  continue;
237  }
238 
239  vector<NodeSharedPtr> vs = (*it)->m_vertexList;
240  for (int j = 0; j < vs.size(); j++)
241  {
242  boundaryNodes.insert(vs[j]);
243  }
244 
245  vector<EdgeSharedPtr> es = (*it)->m_edgeList;
246  for (int j = 0; j < es.size(); j++)
247  {
248  for (int k = 0; k < es[j]->m_edgeNodes.size(); k++)
249  {
250  boundaryNodes.insert(es[j]->m_edgeNodes[k]);
251  }
252  }
253 
254  for (int i = 0; i < (*it)->m_faceNodes.size(); i++)
255  {
256  boundaryNodes.insert((*it)->m_faceNodes[i]);
257  }
258  }
259  }
260  else
261  {
262  //if we have CAD therefore the only fixed nodes exist on vertices only
263  NodeSet::iterator nit;
264  for (nit = m_mesh->m_vertexSet.begin(); nit != m_mesh->m_vertexSet.end(); ++nit)
265  {
266  if((*nit)->GetNumCadCurve() > 1)
267  {
268  boundaryNodes.insert((*nit));
269  }
270  }
271  }
272  break;
273  }
274  default:
275  ASSERTL0(false,"space dim issue");
276  }
277 
278 
279  //create vector of free nodes which "remain", hence will be included in the coloursets
280  vector<NodeSharedPtr> remainEdgeVertex;
281  vector<NodeSharedPtr> remainFace;
282  vector<NodeSharedPtr> remainVolume;
283  m_res->nDoF = 0;
284 
285  // check if vertex nodes are in boundary or ignored nodes, otherwise add to EDGE-VERTEX remain nodes
286  NodeSet::iterator nit;
287  for (nit = m_mesh->m_vertexSet.begin(); nit != m_mesh->m_vertexSet.end();
288  ++nit)
289  {
290  NodeSet::iterator nit2 = boundaryNodes.find(*nit);
291  NodeSet::iterator nit3 = ignoredNodes.find(*nit);
292  if (nit2 == boundaryNodes.end() && nit3 == ignoredNodes.end())
293  {
294  remainEdgeVertex.push_back(*nit);
295  if ((*nit)->GetNumCadCurve() == 1)
296  {
297  m_res->nDoF++;
298  }
299  else if ((*nit)->GetNumCADSurf() == 1)
300  {
301  m_res->nDoF += 2;
302  }
303  else
304  {
305  m_res->nDoF += m_mesh->m_spaceDim;
306  }
307  }
308  }
309 
310  // check if edge nodes are in boundary or ignored nodes, otherwise add to EDGE-VERTEX remain nodes
311  EdgeSet::iterator eit;
312  for (eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++)
313  {
314  vector<NodeSharedPtr> n = (*eit)->m_edgeNodes;
315  for (int j = 0; j < n.size(); j++)
316  {
317  NodeSet::iterator nit2 = boundaryNodes.find(n[j]);
318  NodeSet::iterator nit3 = ignoredNodes.find(n[j]);
319  if (nit2 == boundaryNodes.end() && nit3 == ignoredNodes.end())
320  {
321  remainEdgeVertex.push_back(n[j]);
322  if (n[j]->GetNumCadCurve() == 1)
323  {
324  m_res->nDoF++;
325  }
326  else if (n[j]->GetNumCADSurf() == 1)
327  {
328  m_res->nDoF += 2;
329  }
330  else
331  {
332  m_res->nDoF += m_mesh->m_spaceDim;
333  }
334  }
335  }
336  }
337 
338  // check if face nodes are in boundary or ignored nodes, otherwise add to FACE remain nodes
339  FaceSet::iterator fit;
340  for (fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++)
341  {
342  for (int j = 0; j < (*fit)->m_faceNodes.size(); j++)
343  {
344  NodeSet::iterator nit2 = boundaryNodes.find((*fit)->m_faceNodes[j]);
345  NodeSet::iterator nit3 = ignoredNodes.find((*fit)->m_faceNodes[j]);
346  if (nit2 == boundaryNodes.end() && nit3 == ignoredNodes.end())
347  {
348  remainFace.push_back((*fit)->m_faceNodes[j]);
349  if ((*fit)->m_faceNodes[j]->GetNumCADSurf() == 1)
350  {
351  m_res->nDoF += 2;
352  }
353  else
354  {
355  m_res->nDoF += m_mesh->m_spaceDim;
356  }
357  }
358  }
359  }
360 
361  // check if volume nodes are in boundary or ignored nodes, otherwise add to VOLUME remain nodes
362  for (int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++)
363  {
364  vector<NodeSharedPtr> ns =
365  m_mesh->m_element[m_mesh->m_expDim][i]->GetVolumeNodes();
366  for (int j = 0; j < ns.size(); j++)
367  {
368  NodeSet::iterator nit2 = boundaryNodes.find(ns[j]);
369  NodeSet::iterator nit3 = ignoredNodes.find(ns[j]);
370  if (nit2 == boundaryNodes.end() && nit3 == ignoredNodes.end())
371  {
372  remainVolume.push_back(ns[j]);
373  m_res->nDoF += m_mesh->m_spaceDim;
374  }
375  }
376  }
377 
378  // size of all free nodes to be included in the coloursets
379  m_res->n = remainEdgeVertex.size()
380  + remainFace.size() + remainVolume.size();
381 
382  // data structure for coloursets, that will ultimately contain all free nodes
383  vector<vector<NodeSharedPtr> > ret;
384  vector<vector<NodeSharedPtr> > retPart;
385 
386 
387  // edge and vertex nodes
388  // create vector num_el of number of associated elements of each node
389  vector<int> num_el(remainEdgeVertex.size());
390  for (int i = 0; i < remainEdgeVertex.size(); i++)
391  {
392  //try to find node within all elements
393  NodeElMap::iterator it = m_nodeElMap.find(remainEdgeVertex[i]->m_id);
394  vector<ElUtilSharedPtr> &elUtils = it->second;
395  num_el[i] = elUtils.size();
396  }
397  // finding the permutation according to num_el
398  vector<int> permNode(remainEdgeVertex.size());
399  for (int i = 0; i < remainEdgeVertex.size(); ++i)
400  {
401  permNode[i] = i;
402  }
403  std::sort(permNode.begin(), permNode.end(), NodeComparator(num_el));
404  // applying the permutation to remainEdgeVertex
405  vector<NodeSharedPtr> remainEdgeVertexSort(remainEdgeVertex.size());
406  for (int i = 0; i < remainEdgeVertex.size(); ++i)
407  {
408  int j = permNode[i];
409  remainEdgeVertexSort[i] = remainEdgeVertex[j];
410  }
411 
412  retPart = CreateColoursets(remainEdgeVertexSort);
413  if(m_mesh->m_verbose)
414  {
415  cout << "Number of Edge/Vertex Coloursets: " << retPart.size() << endl;
416  }
417  for (int i = 0; i < retPart.size(); i++)
418  {
419  ret.push_back(retPart[i]);
420  }
421 
422 
423  // face nodes
424  retPart = CreateColoursets(remainFace);
425  if(m_mesh->m_verbose)
426  {
427  cout << "Number of Face Coloursets: " << retPart.size() << endl;
428  }
429  for (int i = 0; i < retPart.size(); i++)
430  {
431  ret.push_back(retPart[i]);
432  }
433 
434 
435  // volume nodes
436  retPart = CreateColoursets(remainVolume);
437  if(m_mesh->m_verbose)
438  {
439  cout << "Number of Volume Coloursets: " << retPart.size() << endl;
440  }
441  for (int i = 0; i < retPart.size(); i++)
442  {
443  ret.push_back(retPart[i]);
444  }
445 
446 
447  if(m_mesh->m_verbose)
448  {
449  cout << endl;
450  }
451 
452  return ret;
453 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
std::vector< std::vector< NodeSharedPtr > > CreateColoursets(std::vector< NodeSharedPtr > remain)
boost::unordered_set< NodeSharedPtr, NodeHash > NodeSet
Definition: Node.h:441
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
void Nektar::Utilities::ProcessVarOpti::GetElementMap ( int  o,
std::map< LibUtilities::ShapeType, DerivUtilSharedPtr derMap 
)
private

Definition at line 520 of file PreProcessing.cpp.

References ASSERTL0.

Referenced by Analytics(), and Process().

522 {
523  for (int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++)
524  {
525  ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i];
526  vector<NodeSharedPtr> ns;
527  el->GetCurvedNodes(ns);
528  ElUtilSharedPtr d = boost::shared_ptr<ElUtil>(new ElUtil(
529  el, derMap[el->GetShapeType()], m_res, m_mesh->m_nummode, o));
530  m_dataSet.push_back(d);
531  }
532 
533  for (int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++)
534  {
535  ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i];
536  vector<NodeSharedPtr> ns;
537  el->GetCurvedNodes(ns);
538 
539  for (int j = 0; j < ns.size(); j++)
540  {
541  m_nodeElMap[ns[j]->m_id].push_back(m_dataSet[i]);
542  }
543 
544  ASSERTL0(derMap[el->GetShapeType()]->ptsStd == ns.size(),
545  "mismatch node count");
546  }
547 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
std::vector< ElUtilSharedPtr > m_dataSet
boost::shared_ptr< Element > ElementSharedPtr
Definition: Edge.h:49
boost::shared_ptr< ElUtil > ElUtilSharedPtr
Definition: ElUtil.h:114
vector< ElUtilSharedPtr > Nektar::Utilities::ProcessVarOpti::GetLockedElements ( NekDouble  thres)
private

Definition at line 549 of file PreProcessing.cpp.

References Nektar::iterator.

Referenced by Process().

550 {
551  vector<ElUtilSharedPtr> elBelowThres;
552  for (int i = 0; i < m_dataSet.size(); ++i)
553  {
554  if (m_dataSet[i]->GetScaledJac() < thres)
555  {
556  elBelowThres.push_back(m_dataSet[i]);
557  }
558  }
559 
560  boost::unordered_set<int> inmesh;
562  vector<ElUtilSharedPtr> totest;
563 
564  for (int i = 0; i < elBelowThres.size(); i++)
565  {
566  t = inmesh.insert(elBelowThres[i]->GetId());
567 
568  vector<FaceSharedPtr> f = elBelowThres[i]->GetEl()->GetFaceList();
569  for (int j = 0; j < f.size(); j++)
570  {
571  for (int k = 0; k < f[j]->m_elLink.size(); k++)
572  {
573  if (f[j]->m_elLink[k].first->GetId() ==
574  elBelowThres[i]->GetId())
575  continue;
576 
577  t = inmesh.insert(f[j]->m_elLink[k].first->GetId());
578  if (t.second)
579  {
580  totest.push_back(
581  m_dataSet[f[j]->m_elLink[k].first->GetId()]);
582  }
583  }
584  }
585  }
586 
587  for (int i = 0; i < 6; i++)
588  {
589  vector<ElUtilSharedPtr> tmp = totest;
590  totest.clear();
591  for (int j = 0; j < tmp.size(); j++)
592  {
593  vector<FaceSharedPtr> f = tmp[j]->GetEl()->GetFaceList();
594  for (int k = 0; k < f.size(); k++)
595  {
596  for (int l = 0; l < f[k]->m_elLink.size(); l++)
597  {
598  if (f[k]->m_elLink[l].first->GetId() == tmp[j]->GetId())
599  continue;
600 
601  t = inmesh.insert(f[k]->m_elLink[l].first->GetId());
602  if (t.second)
603  {
604  totest.push_back(
605  m_dataSet[f[k]->m_elLink[l].first->GetId()]);
606  }
607  }
608  }
609  }
610  }
611 
612  // now need to invert the list
613  vector<ElUtilSharedPtr> ret;
614  for (int i = 0; i < m_dataSet.size(); ++i)
615  {
617  inmesh.find(m_dataSet[i]->GetId());
618  if (s == inmesh.end())
619  {
620  ret.push_back(m_dataSet[i]);
621  }
622  }
623 
624  return ret;
625 }
std::vector< ElUtilSharedPtr > m_dataSet
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
void Nektar::Utilities::ProcessVarOpti::Process ( )
virtual

Implements Nektar::NekMeshUtils::Module.

Definition at line 103 of file ProcessVarOpti.cpp.

References Analytics(), ASSERTL0, BuildDerivUtil(), Nektar::Thread::ThreadMaster::CreateInstance(), Nektar::LibUtilities::eGaussLobattoLegendre, Nektar::Utilities::eHypEl, Nektar::Utilities::eLinEl, Nektar::Utilities::eRoca, Nektar::Utilities::eWins, GetColouredNodes(), GetElementMap(), GetLockedElements(), Nektar::Utilities::GetNodeOptiFactory(), Nektar::iterator, Nektar::NekMeshUtils::Module::m_config, m_dataSet, Nektar::NekMeshUtils::Module::m_mesh, m_nodeElMap, m_opti, m_res, CellMLToNektar.cellml_metadata::p, Nektar::Thread::ThreadMaster::SessionJob, Nektar::Thread::ThreadMaster::SetThreadingType(), Nektar::Timer::Start(), Nektar::Timer::Stop(), and Nektar::Timer::TimePerTest().

104 {
105  if (m_mesh->m_verbose)
106  {
107  cout << "ProcessVarOpti: Optimising... " << endl;
108  }
109 
110  if (m_config["linearelastic"].beenSet)
111  {
112  m_opti = eLinEl;
113  }
114  else if (m_config["winslow"].beenSet)
115  {
116  m_opti = eWins;
117  }
118  else if (m_config["roca"].beenSet)
119  {
120  m_opti = eRoca;
121  }
122  else if (m_config["hyperelastic"].beenSet)
123  {
124  m_opti = eHypEl;
125  }
126  else
127  {
128  ASSERTL0(false, "not opti type set");
129  }
130 
131  const int maxIter = m_config["maxiter"].as<int>();
132  const NekDouble restol = m_config["restol"].as<NekDouble>();
133 
134  // m_mesh->m_nummode = m_config["nq"].as<int>();
135 
136  EdgeSet::iterator eit;
137  bool fd = false;
138 
139  if (m_config["nq"].beenSet)
140  {
141  m_mesh->m_nummode = m_config["nq"].as<int>();
142  fd = true;
143  }
144 
145  if (!fd)
146  {
147  for (eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end();
148  eit++)
149  {
150  if ((*eit)->m_edgeNodes.size() > 0)
151  {
152  m_mesh->m_nummode = (*eit)->m_edgeNodes.size() + 2;
153  fd = true;
154  break;
155  }
156  }
157  }
158  ASSERTL0(fd, "failed to find order of mesh");
159 
160  // Safety feature: limit over-integration order for high-order triangles
161  // over order 5.
162  int intOrder = m_config["overint"].as<int>();
163  intOrder = m_mesh->m_nummode + intOrder <= 11 ?
164  intOrder : 11 - m_mesh->m_nummode;
165 
166  if (m_mesh->m_verbose)
167  {
168  cout << "Identified mesh order as: " << m_mesh->m_nummode - 1 << endl;
169  }
170 
171  if (m_mesh->m_expDim == 2 && m_mesh->m_spaceDim == 3)
172  {
173  ASSERTL0(false, "cannot deal with manifolds");
174  }
175 
176  m_res = boost::shared_ptr<Residual>(new Residual);
177  m_res->val = 1.0;
178 
179 
180  m_mesh->MakeOrder(m_mesh->m_nummode - 1,
182 
183  if (m_config["analytics"].beenSet)
184  {
185  Analytics();
186  return;
187  }
188 
189  map<LibUtilities::ShapeType, DerivUtilSharedPtr> derivUtils =
190  BuildDerivUtil(intOrder);
191 
192  GetElementMap(intOrder, derivUtils);
193 
194  m_res->startInv = 0;
195  m_res->worstJac = numeric_limits<double>::max();
196  for (int i = 0; i < m_dataSet.size(); i++)
197  {
198  m_dataSet[i]->Evaluate();
199  m_dataSet[i]->InitialMinJac();
200  }
201 
202  vector<ElUtilSharedPtr> elLock;
203 
204  if (m_config["region"].beenSet)
205  {
206  elLock = GetLockedElements(m_config["region"].as<NekDouble>());
207  }
208 
209 
210  vector<vector<NodeSharedPtr> > freenodes = GetColouredNodes(elLock);
211  vector<vector<NodeOptiSharedPtr> > optiNodes;
212 
213  // turn the free nodes into optimisable objects with all required data
214  set<int> check;
215  for (int i = 0; i < freenodes.size(); i++)
216  {
217  vector<NodeOptiSharedPtr> ns;
218  for (int j = 0; j < freenodes[i].size(); j++)
219  {
220  NodeElMap::iterator it = m_nodeElMap.find(freenodes[i][j]->m_id);
221  ASSERTL0(it != m_nodeElMap.end(), "could not find");
222 
223  int optiKind = m_mesh->m_spaceDim;
224 
225  if (freenodes[i][j]->GetNumCadCurve() == 1)
226  {
227  optiKind += 10;
228  }
229  else if (freenodes[i][j]->GetNumCADSurf() == 1)
230  {
231  optiKind += 20;
232  }
233  else
234  {
235  optiKind += 10 * m_mesh->m_expDim;
236  }
237 
238  set<int>::iterator c = check.find(freenodes[i][j]->m_id);
239  ASSERTL0(c == check.end(), "duplicate node");
240  check.insert(freenodes[i][j]->m_id);
241 
242  ns.push_back(GetNodeOptiFactory().CreateInstance(
243  optiKind, freenodes[i][j], it->second, m_res, derivUtils,
244  m_opti));
245  }
246  optiNodes.push_back(ns);
247  }
248 
249  int nset = optiNodes.size();
250  int p = 0;
251  int mn = numeric_limits<int>::max();
252  int mx = 0;
253  for (int i = 0; i < nset; i++)
254  {
255  p += optiNodes[i].size();
256  mn = min(mn, int(optiNodes[i].size()));
257  mx = max(mx, int(optiNodes[i].size()));
258  }
259 
260  if (m_config["histfile"].beenSet)
261  {
262  ofstream histFile;
263  string name = m_config["histfile"].as<string>() + "_start.txt";
264  histFile.open(name.c_str());
265 
266  for (int i = 0; i < m_dataSet.size(); i++)
267  {
268  histFile << m_dataSet[i]->GetScaledJac() << endl;
269  }
270  histFile.close();
271  }
272 
273  if(m_mesh->m_verbose)
274  {
275  cout << scientific << endl;
276  cout << "N elements:\t\t" << m_mesh->m_element[m_mesh->m_expDim].size() - elLock.size() << endl
277  << "N elements invalid:\t" << m_res->startInv << endl
278  << "Worst jacobian:\t\t" << m_res->worstJac << endl
279  << "N free nodes:\t\t" << m_res->n << endl
280  << "N Dof:\t\t\t" << m_res->nDoF << endl
281  << "N color sets:\t\t" << nset << endl
282  << "Avg set colors:\t\t" << p/nset << endl
283  << "Min set:\t\t" << mn << endl
284  << "Max set:\t\t" << mx << endl
285  << "Residual tolerance:\t" << restol << endl;
286  }
287 
288  int nThreads = m_config["numthreads"].as<int>();
289 
290  int ctr = 0;
291  Thread::ThreadMaster tms;
292  tms.SetThreadingType("ThreadManagerBoost");
294  tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads);
295 
296  Timer t;
297  t.Start();
298 
299  ofstream resFile;
300  if (m_config["resfile"].beenSet)
301  {
302  resFile.open(m_config["resfile"].as<string>().c_str());
303  }
304 
305  for (int i = 0; i < optiNodes.size(); i++)
306  {
307  vector<Thread::ThreadJob *> jobs(optiNodes[i].size());
308  for (int j = 0; j < optiNodes[i].size(); j++)
309  {
310  optiNodes[i][j]->CalcMinJac();
311  }
312  }
313 
314  while (m_res->val > restol)
315  {
316  ctr++;
317  m_res->val = 0.0;
318  m_res->func = 0.0;
319  m_res->nReset[0] = 0;
320  m_res->nReset[1] = 0;
321  m_res->nReset[2] = 0;
322  m_res->alphaI = 0;
323  for (int i = 0; i < optiNodes.size(); i++)
324  {
325  vector<Thread::ThreadJob *> jobs(optiNodes[i].size());
326  for (int j = 0; j < optiNodes[i].size(); j++)
327  {
328  jobs[j] = optiNodes[i][j]->GetJob();
329  }
330 
331  tm->SetNumWorkers(0);
332  tm->QueueJobs(jobs);
333  tm->SetNumWorkers(nThreads);
334  tm->Wait();
335  }
336 
337  m_res->startInv = 0;
338  m_res->worstJac = numeric_limits<double>::max();
339 
340  vector<Thread::ThreadJob *> elJobs(m_dataSet.size());
341  for (int i = 0; i < m_dataSet.size(); i++)
342  {
343  elJobs[i] = m_dataSet[i]->GetJob();
344  }
345 
346  tm->SetNumWorkers(0);
347  tm->QueueJobs(elJobs);
348  tm->SetNumWorkers(nThreads);
349  tm->Wait();
350 
351  if (m_config["resfile"].beenSet)
352  {
353  resFile << m_res->val << " " << m_res->worstJac << " "
354  << m_res->func << endl;
355  }
356 
357  if(m_mesh->m_verbose)
358  {
359  cout << ctr
360  << "\tResidual: " << m_res->val
361  << "\tMin Jac: " << m_res->worstJac
362  << "\tInvalid: " << m_res->startInv
363  << "\tReset nodes: " << m_res->nReset[0] << "/" << m_res->nReset[1]
364  << "/" << m_res->nReset[2] << "\tFunctional: " << m_res->func
365  << endl;
366  }
367 
368  if(ctr >= maxIter)
369  {
370  break;
371  }
372  }
373 
374  if (m_config["histfile"].beenSet)
375  {
376  ofstream histFile;
377  string name = m_config["histfile"].as<string>() + "_end.txt";
378  histFile.open(name.c_str());
379 
380  for (int i = 0; i < m_dataSet.size(); i++)
381  {
382  histFile << m_dataSet[i]->GetScaledJac() << endl;
383  }
384  histFile.close();
385  }
386  if (m_config["resfile"].beenSet)
387  {
388  resFile.close();
389  }
390 
391  t.Stop();
392 
393  //RemoveLinearCurvature();
394 
395  if(m_mesh->m_verbose)
396  {
397  cout << "Time to compute: " << t.TimePerTest(1) << endl;
398  cout << "Invalid at end: " << m_res->startInv << endl;
399  cout << "Worst at end: " << m_res->worstJac << endl;
400  }
401 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
NodeOptiFactory & GetNodeOptiFactory()
Definition: NodeOpti.cpp:52
std::vector< ElUtilSharedPtr > GetLockedElements(NekDouble thres)
void GetElementMap(int o, std::map< LibUtilities::ShapeType, DerivUtilSharedPtr > derMap)
std::map< LibUtilities::ShapeType, DerivUtilSharedPtr > BuildDerivUtil(int o)
std::vector< ElUtilSharedPtr > m_dataSet
std::vector< std::vector< NodeSharedPtr > > GetColouredNodes(std::vector< ElUtilSharedPtr > elLock)
double NekDouble
std::map< std::string, ConfigOption > m_config
List of configuration values.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
1D Gauss-Lobatto-Legendre quadrature points
Definition: PointsType.h:52
boost::shared_ptr< ThreadManager > ThreadManagerSharedPtr
Definition: Thread.h:74
void Nektar::Utilities::ProcessVarOpti::RemoveLinearCurvature ( )
private

Definition at line 627 of file PreProcessing.cpp.

References ASSERTL0, and Nektar::iterator.

628 {
629  for(int i = 0; i < m_dataSet.size(); i++)
630  {
631  if(m_dataSet[i]->GetScaledJac() > 0.999)
632  {
633  ElementSharedPtr el = m_dataSet[i]->GetEl();
634  vector<NodeSharedPtr> ns;
635  el->SetVolumeNodes(ns);
636  }
637  }
638 
639  map<int, vector<FaceSharedPtr> > edgeToFace;
640 
641  FaceSet::iterator fit;
642  for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++)
643  {
644  bool rm = true;
645  for(int i = 0; i < (*fit)->m_elLink.size(); i++)
646  {
647  int id = (*fit)->m_elLink[i].first->GetId();
648  if(m_dataSet[id]->GetScaledJac() <= 0.999)
649  {
650  rm = false;
651  break;
652  }
653  }
654  if(rm)
655  {
656  (*fit)->m_faceNodes.clear();
657  }
658 
659  vector<EdgeSharedPtr> es = (*fit)->m_edgeList;
660  for(int i = 0; i < es.size(); i++)
661  {
662  edgeToFace[es[i]->m_id].push_back(*fit);
663  }
664  }
665 
666  EdgeSet::iterator eit;
667  for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++)
668  {
669  map<int, vector<FaceSharedPtr> >::iterator it;
670  it = edgeToFace.find((*eit)->m_id);
671  ASSERTL0(it != edgeToFace.end(),"not found");
672  bool rm = true;
673  for(int i = 0; i < it->second.size(); i++)
674  {
675  if(it->second[i]->m_faceNodes.size() > 0)
676  {
677  rm = false;
678  break;
679  }
680  }
681  if(rm)
682  {
683  (*eit)->m_edgeNodes.clear();
684  }
685  }
686 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
std::vector< ElUtilSharedPtr > m_dataSet
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
boost::shared_ptr< Element > ElementSharedPtr
Definition: Edge.h:49

Member Data Documentation

ModuleKey Nektar::Utilities::ProcessVarOpti::className
static
Initial value:

Definition at line 91 of file ProcessVarOpti.h.

std::vector<ElUtilSharedPtr> Nektar::Utilities::ProcessVarOpti::m_dataSet
private

Definition at line 115 of file ProcessVarOpti.h.

Referenced by Analytics(), and Process().

NodeElMap Nektar::Utilities::ProcessVarOpti::m_nodeElMap
private

Definition at line 114 of file ProcessVarOpti.h.

Referenced by Analytics(), and Process().

optiType Nektar::Utilities::ProcessVarOpti::m_opti
private

Definition at line 118 of file ProcessVarOpti.h.

Referenced by Analytics(), and Process().

ResidualSharedPtr Nektar::Utilities::ProcessVarOpti::m_res
private

Definition at line 117 of file ProcessVarOpti.h.

Referenced by Analytics(), and Process().