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 443 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().

444 {
445  // Grab the first element from the list
446  ElementSharedPtr elmt = m_mesh->m_element[m_mesh->m_expDim][0];
447 
448  // Get curved nodes
449  vector<NodeSharedPtr> nodes;
450  elmt->GetCurvedNodes(nodes);
451 
452  // We're going to investigate only the first node (corner node)
453  NodeSharedPtr node = nodes[4];
454 
455  // Loop over overintegration orders
456  const int nPoints = 200;
457  const int overInt = 40;
458  const NekDouble originX = -1.0;
459  const NekDouble originY = -1.0;
460  const NekDouble length = 2.0;
461  const NekDouble dx = length / (nPoints - 1);
462 
463  cout << "# overint = " << overInt << endl;
464  cout << "# Columns: x, y, over-integration orders (0 -> " << overInt - 1
465  << "), "
466  << " min(scaledJac)" << endl;
467 
468  // Loop over square defined by (originX, originY), length
469  for (int k = 0; k < nPoints; ++k)
470  {
471  node->m_y = originY + k * dx;
472  for (int j = 0; j < nPoints; ++j)
473  {
474  node->m_x = originX + j * dx;
475  cout << node->m_x << " " << node->m_y << " ";
476 
477  NekDouble minJacNew;
478 
479  for (int i = 0; i < overInt; ++i)
480  {
481  // Clear any existing node to element mapping.
482  m_dataSet.clear();
483  m_nodeElMap.clear();
484 
485  // Build deriv utils and element map.
486  map<LibUtilities::ShapeType, DerivUtilSharedPtr> derivUtils =
487  BuildDerivUtil(i);
488 
489  // Reconstruct element map
490  GetElementMap(i, derivUtils);
491 
492  for (int j = 0; j < m_dataSet.size(); j++)
493  {
494  m_dataSet[j]->Evaluate();
495  m_dataSet[j]->InitialMinJac();
496  }
497 
498  // Create NodeOpti object.
499  NodeOptiSharedPtr nodeOpti =
501  m_mesh->m_spaceDim * 11, node,
502  m_nodeElMap.find(node->m_id)->second, m_res, derivUtils,
503  m_opti);
504 
505  minJacNew = 0.0;
506 
507  // Evaluate functional.
508  nodeOpti->CalcMinJac();
509  cout << nodeOpti->GetFunctional<2>(minJacNew) << " ";
510  // NekDouble eigen;
511  // nodeOpti->GetFunctional<2>(minJacNew);
512  // nodeOpti->MinEigen<2>(eigen);
513  // cout << eigen << " ";
514  }
515 
516  cout << minJacNew << endl;
517  }
518  }
519 }
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:107
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, RemoveLinearCurvature(), 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  int intOrder = m_config["overint"].as<NekDouble>();
161 
162  if (m_mesh->m_verbose)
163  {
164  cout << "Identified mesh order as: " << m_mesh->m_nummode - 1 << endl;
165  }
166 
167  if (m_mesh->m_expDim == 2 && m_mesh->m_spaceDim == 3)
168  {
169  ASSERTL0(false, "cannot deal with manifolds");
170  }
171 
172  m_res = boost::shared_ptr<Residual>(new Residual);
173  m_res->val = 1.0;
174 
175 
176  m_mesh->MakeOrder(m_mesh->m_nummode - 1,
178 
179  if (m_config["analytics"].beenSet)
180  {
181  Analytics();
182  return;
183  }
184 
185  map<LibUtilities::ShapeType, DerivUtilSharedPtr> derivUtils =
186  BuildDerivUtil(intOrder);
187 
188  GetElementMap(intOrder, derivUtils);
189 
190  m_res->startInv = 0;
191  m_res->worstJac = numeric_limits<double>::max();
192  for (int i = 0; i < m_dataSet.size(); i++)
193  {
194  m_dataSet[i]->Evaluate();
195  m_dataSet[i]->InitialMinJac();
196  }
197 
198  vector<ElUtilSharedPtr> elLock;
199 
200  if (m_config["region"].beenSet)
201  {
202  elLock = GetLockedElements(m_config["region"].as<NekDouble>());
203  }
204 
205 
206  vector<vector<NodeSharedPtr> > freenodes = GetColouredNodes(elLock);
207  vector<vector<NodeOptiSharedPtr> > optiNodes;
208 
209  // turn the free nodes into optimisable objects with all required data
210  set<int> check;
211  for (int i = 0; i < freenodes.size(); i++)
212  {
213  vector<NodeOptiSharedPtr> ns;
214  for (int j = 0; j < freenodes[i].size(); j++)
215  {
216  NodeElMap::iterator it = m_nodeElMap.find(freenodes[i][j]->m_id);
217  ASSERTL0(it != m_nodeElMap.end(), "could not find");
218 
219  int optiKind = m_mesh->m_spaceDim;
220 
221  if (freenodes[i][j]->GetNumCadCurve() == 1)
222  {
223  optiKind += 10;
224  }
225  else if (freenodes[i][j]->GetNumCADSurf() == 1)
226  {
227  optiKind += 20;
228  }
229  else
230  {
231  optiKind += 10 * m_mesh->m_expDim;
232  }
233 
234  set<int>::iterator c = check.find(freenodes[i][j]->m_id);
235  ASSERTL0(c == check.end(), "duplicate node");
236  check.insert(freenodes[i][j]->m_id);
237 
238  ns.push_back(GetNodeOptiFactory().CreateInstance(
239  optiKind, freenodes[i][j], it->second, m_res, derivUtils,
240  m_opti));
241  }
242  optiNodes.push_back(ns);
243  }
244 
245  int nset = optiNodes.size();
246  int p = 0;
247  int mn = numeric_limits<int>::max();
248  int mx = 0;
249  for (int i = 0; i < nset; i++)
250  {
251  p += optiNodes[i].size();
252  mn = min(mn, int(optiNodes[i].size()));
253  mx = max(mx, int(optiNodes[i].size()));
254  }
255 
256  if (m_config["histfile"].beenSet)
257  {
258  ofstream histFile;
259  string name = m_config["histfile"].as<string>() + "_start.txt";
260  histFile.open(name.c_str());
261 
262  for (int i = 0; i < m_dataSet.size(); i++)
263  {
264  histFile << m_dataSet[i]->GetScaledJac() << endl;
265  }
266  histFile.close();
267  }
268 
269  if(m_mesh->m_verbose)
270  {
271  cout << scientific << endl;
272  cout << "N elements:\t\t" << m_mesh->m_element[m_mesh->m_expDim].size() - elLock.size() << endl
273  << "N elements invalid:\t" << m_res->startInv << endl
274  << "Worst jacobian:\t\t" << m_res->worstJac << endl
275  << "N free nodes:\t\t" << m_res->n << endl
276  << "N Dof:\t\t\t" << m_res->nDoF << endl
277  << "N color sets:\t\t" << nset << endl
278  << "Avg set colors:\t\t" << p/nset << endl
279  << "Min set:\t\t" << mn << endl
280  << "Max set:\t\t" << mx << endl
281  << "Residual tolerance:\t" << restol << endl;
282  }
283 
284  int nThreads = m_config["numthreads"].as<int>();
285 
286  int ctr = 0;
287  Thread::ThreadMaster tms;
288  tms.SetThreadingType("ThreadManagerBoost");
290  tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads);
291 
292  Timer t;
293  t.Start();
294 
295  ofstream resFile;
296  if (m_config["resfile"].beenSet)
297  {
298  resFile.open(m_config["resfile"].as<string>().c_str());
299  }
300 
301  for (int i = 0; i < optiNodes.size(); i++)
302  {
303  vector<Thread::ThreadJob *> jobs(optiNodes[i].size());
304  for (int j = 0; j < optiNodes[i].size(); j++)
305  {
306  optiNodes[i][j]->CalcMinJac();
307  }
308  }
309 
310  while (m_res->val > restol)
311  {
312  ctr++;
313  m_res->val = 0.0;
314  m_res->func = 0.0;
315  m_res->nReset[0] = 0;
316  m_res->nReset[1] = 0;
317  m_res->nReset[2] = 0;
318  m_res->alphaI = 0;
319  for (int i = 0; i < optiNodes.size(); i++)
320  {
321  vector<Thread::ThreadJob *> jobs(optiNodes[i].size());
322  for (int j = 0; j < optiNodes[i].size(); j++)
323  {
324  jobs[j] = optiNodes[i][j]->GetJob();
325  }
326 
327  tm->SetNumWorkers(0);
328  tm->QueueJobs(jobs);
329  tm->SetNumWorkers(nThreads);
330  tm->Wait();
331  }
332 
333  m_res->startInv = 0;
334  m_res->worstJac = numeric_limits<double>::max();
335 
336  vector<Thread::ThreadJob *> elJobs(m_dataSet.size());
337  for (int i = 0; i < m_dataSet.size(); i++)
338  {
339  elJobs[i] = m_dataSet[i]->GetJob();
340  }
341 
342  tm->SetNumWorkers(0);
343  tm->QueueJobs(elJobs);
344  tm->SetNumWorkers(nThreads);
345  tm->Wait();
346 
347  if (m_config["resfile"].beenSet)
348  {
349  resFile << m_res->val << " " << m_res->worstJac << " "
350  << m_res->func << endl;
351  }
352 
353  if(m_mesh->m_verbose)
354  {
355  cout << ctr
356  << "\tResidual: " << m_res->val
357  << "\tMin Jac: " << m_res->worstJac
358  << "\tInvalid: " << m_res->startInv
359  << "\tReset nodes: " << m_res->nReset[0] << "/" << m_res->nReset[1]
360  << "/" << m_res->nReset[2] << "\tFunctional: " << m_res->func
361  << endl;
362  }
363 
364  if(ctr >= maxIter)
365  {
366  break;
367  }
368  }
369 
370  if (m_config["histfile"].beenSet)
371  {
372  ofstream histFile;
373  string name = m_config["histfile"].as<string>() + "_end.txt";
374  histFile.open(name.c_str());
375 
376  for (int i = 0; i < m_dataSet.size(); i++)
377  {
378  histFile << m_dataSet[i]->GetScaledJac() << endl;
379  }
380  histFile.close();
381  }
382  if (m_config["resfile"].beenSet)
383  {
384  resFile.close();
385  }
386 
387  t.Stop();
388 
390 
391  if(m_mesh->m_verbose)
392  {
393  cout << "Time to compute: " << t.TimePerTest(1) << endl;
394  cout << "Invalid at end: " << m_res->startInv << endl;
395  cout << "Worst at end: " << m_res->worstJac << endl;
396  }
397 }
#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.

Referenced by Process().

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().