From 6d5350360bd0dac1a7dc129ecfd8b0a5f4bf1b36 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 18 Apr 2016 15:45:12 +0100 Subject: [PATCH 001/236] start variational optimisation --- utilities/NekMesh/CMakeLists.txt | 2 + .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 201 ++++++++++++++++++ .../NekMesh/ProcessModules/ProcessVarOpti.h | 74 +++++++ 3 files changed, 277 insertions(+) create mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp create mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti.h diff --git a/utilities/NekMesh/CMakeLists.txt b/utilities/NekMesh/CMakeLists.txt index 9c65a187b..b6091bc3f 100644 --- a/utilities/NekMesh/CMakeLists.txt +++ b/utilities/NekMesh/CMakeLists.txt @@ -21,6 +21,7 @@ SET(NekMeshHeaders ProcessModules/ProcessSpherigon.h ProcessModules/ProcessTetSplit.h ProcessModules/ProcessOptiExtract.h + ProcessModules/ProcessVarOpti.h ) SET(NekMeshSources @@ -47,6 +48,7 @@ SET(NekMeshSources ProcessModules/ProcessSpherigon.cpp ProcessModules/ProcessTetSplit.cpp ProcessModules/ProcessOptiExtract.cpp + ProcessModules/ProcessVarOpti.cpp ) IF (NEKTAR_USE_CCM) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp new file mode 100644 index 000000000..94b4d9916 --- /dev/null +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -0,0 +1,201 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessJac.cpp +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Calculate Jacobians of elements. +// +//////////////////////////////////////////////////////////////////////////////// + +#include + +#include +#include "ProcessVarOpti.h" + +using namespace std; +using namespace Nektar::NekMeshUtils; + +namespace Nektar +{ +namespace Utilities +{ + +ModuleKey ProcessVarOpti::className = GetModuleFactory().RegisterCreatorFunction( + ModuleKey(eProcessModule, "varopti"), + ProcessVarOpti::create, + "Optimise mesh locations."); + +ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) +{ + +} + +ProcessVarOpti::~ProcessVarOpti() +{ +} + +void ProcessVarOpti::Process() +{ + if (m_mesh->m_verbose) + { + cout << "ProcessVarOpti: Optimising... " << endl; + } + + if(m_mesh->m_expDim == 3 || m_mesh->m_spaceDim == 3) + { + ASSERTL0(false,"wrong mesh dim"); + } + + FillQuadPoints(); + + vector optiNodes = GetFreeNodes(); + + map > nodeElMap = GetElementMap(); + + for(int i = 0; i < optiNodes.size(); i++) + { + map >::iterator it; + it = nodeElMap.find(optiNodes[i]); + ASSERTL0(it != nodeElMap.end(), "not found"); + cout << i << " " << it->second.size() << endl; + } + +} + +map > ProcessVarOpti::GetElementMap() +{ + map > ret; + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + + vector n; + el->GetCurvedNodes(n); + for(int j = 0; j < 3 * (5 - 1); j++) + { + ret[n[j]].push_back(el); + } + } + return ret; +} + +vector ProcessVarOpti::GetFreeNodes() +{ + //loop over the composites to build a set of nodes which lie in + //boundary composites + //then iterate over all nodes, if the node is not in the set its free + //add it to the vector + NodeSet boundaryNodes; + + CompositeMap cm = m_mesh->m_composite; + CompositeMap::iterator it; + for(it = cm.begin(); it != cm.end(); it++) + { + if(it->second->m_tag != "E") + { + continue; + } + + for(int i = 0; i < it->second->m_items.size(); i++) + { + EdgeSharedPtr e = it->second->m_items[i]->GetEdgeLink(); + vector n; + e->GetCurvedNodes(n); + for(int j = 0; j < n.size(); j++) + { + boundaryNodes.insert(n[j]); + } + } + } + + vector ret; + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + vector n; + m_mesh->m_element[m_mesh->m_expDim][i]->GetCurvedNodes(n); + for(int j = 0; j < 3 * (5 - 1); j++) + { + if(!n[j]) + { + cout << "error in node " << j << endl; + exit(-1); + } + NodeSet::iterator it = boundaryNodes.find(n[j]); + if(it == boundaryNodes.end()) + { + ret.push_back(n[j]); + } + } + } + + return ret; +} + +void ProcessVarOpti::FillQuadPoints() +{ + //not all quadrature points are there + //this function adds GLL points to linear edges + EdgeSet::iterator it; + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + { + if((*it)->m_edgeNodes.size() > 0) + { + //already high-order ignore + continue; + } + + //need to fix nummode at some point, set to 5 to match sqcr.xml + LibUtilities::PointsKey ekey(5,LibUtilities::eGaussLobattoLegendre); + Array gll; + LibUtilities::PointsManager()[ekey]->GetPoints(gll); + + Array > xyi(5 - 2); + for (int k = 1; k < 5 - 1; k++) + { + Array xy(2); + xy[0] = (*it)->m_n1->m_x * (1.0 - gll[k]) / 2.0 + + (*it)->m_n2->m_x * (1.0 + gll[k]) / 2.0; + xy[1] = (*it)->m_n1->m_y * (1.0 - gll[k]) / 2.0 + + (*it)->m_n2->m_y * (1.0 + gll[k]) / 2.0; + xyi[k-1] = xy; + } + + vector ns; + for(int i = 0; i < xyi.num_elements(); i++) + { + ns.push_back(boost::shared_ptr(new Node(0,xyi[i][0],xyi[i][1],0.0))); + } + + (*it)->m_edgeNodes = ns; + (*it)->m_curveType = LibUtilities::eGaussLobattoLegendre; + } +} + +} +} diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h new file mode 100644 index 000000000..956a42c75 --- /dev/null +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -0,0 +1,74 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessJac.h +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Calculate jacobians of elements. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTILITIES_NEKMESH_PROCESSVAROPTI +#define UTILITIES_NEKMESH_PROCESSVAROPTI + +#include "../Module.h" + +namespace Nektar +{ +namespace Utilities +{ + +/** + * @brief This processing module calculates the Jacobian of elements + * using %SpatialDomains::GeomFactors and the %Element::GetGeom + * method. For now it simply prints a list of elements which have + * negative Jacobian. + */ +class ProcessVarOpti : public ProcessModule +{ +public: + /// Creates an instance of this class + static boost::shared_ptr create(MeshSharedPtr m) + { + return MemoryManager::AllocateSharedPtr(m); + } + static ModuleKey className; + + ProcessVarOpti(MeshSharedPtr m); + virtual ~ProcessVarOpti(); + + /// Write mesh to output file. + virtual void Process(); + void FillQuadPoints(); + vector GetFreeNodes(); + map > GetElementMap(); +}; +} +} + +#endif -- GitLab From 96097074046f63365d658347a54cf0f2ffaa60e5 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Tue, 19 Apr 2016 11:15:36 +0100 Subject: [PATCH 002/236] added more steps --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 172 ++++++++++++++---- .../NekMesh/ProcessModules/ProcessVarOpti.h | 10 +- 2 files changed, 149 insertions(+), 33 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 94b4d9916..3c07907ca 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -38,6 +38,11 @@ #include #include "ProcessVarOpti.h" +#include +#include +#include +#include + using namespace std; using namespace Nektar::NekMeshUtils; @@ -76,21 +81,134 @@ void ProcessVarOpti::Process() vector optiNodes = GetFreeNodes(); - map > nodeElMap = GetElementMap(); + GetElementMap(); for(int i = 0; i < optiNodes.size(); i++) { - map >::iterator it; - it = nodeElMap.find(optiNodes[i]); - ASSERTL0(it != nodeElMap.end(), "not found"); - cout << i << " " << it->second.size() << endl; + NekDouble w = GetFunctional(optiNodes[i]); + } + +} + +NekDouble ProcessVarOpti::GetFunctional(NodeSharedPtr n) +{ + NodeElMap::iterator it = nodeElMap.find(n); + ASSERTL0(it != nodeElMap.end(),"could not find"); + vector els = it->second; + + NekDouble r = 0.0; + for(int i = 0; i < els.size(); i++) + { + r += GetElFunctional(els[i]); + } +} + +NekDouble ProcessVarOpti::GetElFunctional(ElementSharedPtr el) +{ + SpatialDomains::GeometrySharedPtr geom = el->GetGeom(m_mesh->m_spaceDim); + StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); + LibUtilities::PointsKeyVector p = chi->GetPointsKeys(); + SpatialDomains::GeomFactorsSharedPtr gfac = geom->GetGeomFactors(); + const int expDim = chi->GetNumBases(); + int nElemPts = 1; + + vector basisKeys; + + for (int i = 0; i < expDim; ++i) + { + basisKeys.push_back(chi->GetBasis(i)->GetBasisKey()); } + for(int i = 0; i < basisKeys.size(); i++) + { + cout << basisKeys[i].GetTotNumPoints() << endl; + } + exit(-1); + + StdRegions::StdExpansionSharedPtr chiMod; + switch(chi->DetShapeType()) + { + case LibUtilities::eTriangle: + chiMod = MemoryManager::AllocateSharedPtr( + basisKeys[0], basisKeys[1]); + break; + case LibUtilities::eQuadrilateral: + chiMod = MemoryManager::AllocateSharedPtr( + basisKeys[0], basisKeys[1]); + break; + case LibUtilities::eTetrahedron: + chiMod = MemoryManager::AllocateSharedPtr( + basisKeys[0], basisKeys[1], basisKeys[2]); + break; + case LibUtilities::ePrism: + chiMod = MemoryManager::AllocateSharedPtr( + basisKeys[0], basisKeys[1], basisKeys[2]); + break; + default: + ASSERTL0(false, "nope"); + } + + SpatialDomains::DerivStorage deriv = gfac->GetDeriv(p); + + const int pts = deriv[0][0].num_elements(); + cout << pts << endl; + exit(-1); + /* + const int nq = chiMod->GetTotPoints(); + + ASSERTL0(pts == nq, "what"); + + vector i2rm = MappingIdealToRef(geom, chiMod); + Array eta(nq); + + for (int k = 0; k < pts; ++k) + { + DNekMat jac (expDim, expDim, 0.0, eFULL); + DNekMat jacIdeal(expDim, expDim, 0.0, eFULL); + + for (int i = 0; i < expDim; ++i) + { + for (int j = 0; j < expDim; ++j) + { + jac(j,i) = deriv[i][j][k]; + } + } + + jacIdeal = jac * i2rm[k]; + NekDouble jacDet; + + if(expDim == 2) + { + jacDet = jacIdeal(0,0) * jacIdeal(1,1) - jacIdeal(0,1)*jacIdeal(1,0); + } + else if(expDim == 3) + { + jacDet = jacIdeal(0,0) * (jacIdeal(1,1)*jacIdeal(2,2) - jacIdeal(2,1)*jacIdeal(1,2)) - + jacIdeal(0,1) * (jacIdeal(1,0)*jacIdeal(2,2) - jacIdeal(2,0)*jacIdeal(1,2)) + + jacIdeal(0,2) * (jacIdeal(1,0)*jacIdeal(2,1) - jacIdeal(2,0)*jacIdeal(1,1)); + } + else + { + ASSERTL0(false,"silly exp dim"); + } + + NekDouble frob = 0.0; + + for (int i = 0; i < expDim; ++i) + { + for (int j = 0; j < expDim; ++j) + { + frob += jacIdeal(i,j) * jacIdeal(i,j); + } + } + + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet)); + eta[k] = expDim * pow(sigma, 2.0/expDim) / frob; + }*/ } -map > ProcessVarOpti::GetElementMap() +void ProcessVarOpti::GetElementMap() { - map > ret; for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; @@ -99,10 +217,9 @@ map > ProcessVarOpti::GetElementMap() el->GetCurvedNodes(n); for(int j = 0; j < 3 * (5 - 1); j++) { - ret[n[j]].push_back(el); + nodeElMap[n[j]].push_back(el); } } - return ret; } vector ProcessVarOpti::GetFreeNodes() @@ -113,41 +230,34 @@ vector ProcessVarOpti::GetFreeNodes() //add it to the vector NodeSet boundaryNodes; - CompositeMap cm = m_mesh->m_composite; - CompositeMap::iterator it; - for(it = cm.begin(); it != cm.end(); it++) + EdgeSet::iterator it; + int ct = 0; + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) { - if(it->second->m_tag != "E") + if((*it)->m_elLink.size() == 2) { continue; } - for(int i = 0; i < it->second->m_items.size(); i++) + ct++; + + vector n; + (*it)->GetCurvedNodes(n); + for(int i = 0; i < n.size(); i++) { - EdgeSharedPtr e = it->second->m_items[i]->GetEdgeLink(); - vector n; - e->GetCurvedNodes(n); - for(int j = 0; j < n.size(); j++) - { - boundaryNodes.insert(n[j]); - } + boundaryNodes.insert(n[i]); } } vector ret; - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) { vector n; - m_mesh->m_element[m_mesh->m_expDim][i]->GetCurvedNodes(n); - for(int j = 0; j < 3 * (5 - 1); j++) + (*it)->GetCurvedNodes(n); + for(int j = 0; j < n.size(); j++) { - if(!n[j]) - { - cout << "error in node " << j << endl; - exit(-1); - } - NodeSet::iterator it = boundaryNodes.find(n[j]); - if(it == boundaryNodes.end()) + NodeSet::iterator nit = boundaryNodes.find(n[j]); + if(nit == boundaryNodes.end()) { ret.push_back(n[j]); } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index 956a42c75..ce903b55e 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -42,7 +42,7 @@ namespace Nektar { namespace Utilities { - +typedef boost::unordered_map, NodeHash> NodeElMap; /** * @brief This processing module calculates the Jacobian of elements * using %SpatialDomains::GeomFactors and the %Element::GetGeom @@ -64,10 +64,16 @@ public: /// Write mesh to output file. virtual void Process(); +private: void FillQuadPoints(); vector GetFreeNodes(); - map > GetElementMap(); + void GetElementMap(); + NodeElMap nodeElMap; + NekDouble GetFunctional(NodeSharedPtr n); + NekDouble GetElFunctional(ElementSharedPtr el); + }; + } } -- GitLab From 629ca203183a11fd7a77caa15355ab85a7c2ddba Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Wed, 20 Apr 2016 15:28:45 +0100 Subject: [PATCH 003/236] functioning functional evaluation --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 243 +++++++++++++++--- 1 file changed, 209 insertions(+), 34 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 3c07907ca..3729bf218 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -86,6 +86,7 @@ void ProcessVarOpti::Process() for(int i = 0; i < optiNodes.size(); i++) { NekDouble w = GetFunctional(optiNodes[i]); + cout << w << endl; } } @@ -101,6 +102,186 @@ NekDouble ProcessVarOpti::GetFunctional(NodeSharedPtr n) { r += GetElFunctional(els[i]); } + return r; +} + +inline vector MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, + StdRegions::StdExpansionSharedPtr chi) +{ + int dim = geom->GetShapeDim(); + vector ret; + + if(geom->GetShapeType() == LibUtilities::eQuadrilateral) + { + vector > xy; + for(int i = 0; i < geom->GetNumVerts(); i++) + { + Array loc(2); + SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); + p->GetCoords(loc); + xy.push_back(loc); + } + + Array b = chi->GetBase(); + Array u = b[0]->GetZ(); + Array v = b[1]->GetZ(); + + for(int j = 0; j < b[1]->GetNumPoints(); j++) + { + for(int i = 0; i < b[0]->GetNumPoints(); i++) + { + NekDouble a1 = 0.5*(1.0-u[i]), a2 = 0.5*(1.0+u[i]); + NekDouble b1 = 0.5*(1.0-v[j]), b2 = 0.5*(1.0+v[j]); + DNekMat dxdz(2,2,1.0,eFULL); + + dxdz(0,0) = 0.5*(-b1*xy[0][0] + b1*xy[1][0] + b2*xy[2][0] - b2*xy[3][0]); + dxdz(1,0) = 0.5*(-b1*xy[0][1] + b1*xy[1][1] + b2*xy[2][1] - b2*xy[3][1]); + + dxdz(0,1) = 0.5*(-a1*xy[0][0] - a2*xy[1][0] + a2*xy[2][0] + a1*xy[3][0]); + dxdz(1,1) = 0.5*(-a1*xy[0][1] - a2*xy[1][1] + a2*xy[2][1] + a1*xy[3][1]); + + NekDouble det = 1.0/(dxdz(0,0)*dxdz(1,1) - dxdz(1,0)*dxdz(0,1)); + + dxdz.Invert(); + ret.push_back(dxdz); + } + } + } + else if(geom->GetShapeType() == LibUtilities::eTriangle) + { + vector > xy; + for(int i = 0; i < geom->GetNumVerts(); i++) + { + Array loc(2); + SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); + p->GetCoords(loc); + xy.push_back(loc); + } + + Array b = chi->GetBase(); + Array u = b[0]->GetZ(); + Array v = b[1]->GetZ(); + + for(int i = 0; i < b[0]->GetNumPoints(); i++) + { + for(int j = 0; j < b[1]->GetNumPoints(); j++) + { + DNekMat dxdz(2,2,1.0,eFULL); + dxdz(0,0) = -xy[0][0]/2.0 + xy[1][0]/2.0; + + dxdz(0,1) = -xy[0][0]/2.0 + xy[2][0]/2.0; + + dxdz(1,0) = -xy[0][1]/2.0 + xy[1][1]/2.0; + + dxdz(1,1) = -xy[0][1]/2.0 + xy[2][1]/2.0; + + dxdz.Invert(); + ret.push_back(dxdz); + } + } + } + else if(geom->GetShapeType() == LibUtilities::eTetrahedron) + { + vector > xyz; + for(int i = 0; i < geom->GetNumVerts(); i++) + { + Array loc(3); + SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); + p->GetCoords(loc); + xyz.push_back(loc); + } + + Array b = chi->GetBase(); + Array u = b[0]->GetZ(); + Array v = b[1]->GetZ(); + Array z = b[2]->GetZ(); + + for(int i = 0; i < b[0]->GetNumPoints(); i++) + { + for(int j = 0; j < b[1]->GetNumPoints(); j++) + { + for(int k = 0; k < b[2]->GetNumPoints(); k++) + { + DNekMat dxdz(3,3,1.0,eFULL); + dxdz(0,0) = -xyz[0][0]/2.0 + xyz[1][0]/2.0; + + dxdz(0,1) = -xyz[0][0]/2.0 + xyz[2][0]/2.0; + + dxdz(0,2) = -xyz[0][0]/2.0 + xyz[3][0]/2.0; + + + dxdz(1,0) = -xyz[0][1]/2.0 + xyz[1][1]/2.0; + + dxdz(1,1) = -xyz[0][1]/2.0 + xyz[2][1]/2.0; + + dxdz(1,2) = -xyz[0][1]/2.0 + xyz[3][1]/2.0; + + + dxdz(2,0) = -xyz[0][2]/2.0 + xyz[1][2]/2.0; + + dxdz(2,1) = -xyz[0][2]/2.0 + xyz[2][2]/2.0; + + dxdz(2,2) = -xyz[0][2]/2.0 + xyz[3][2]/2.0; + + dxdz.Invert(); + ret.push_back(dxdz); + } + } + } + } + else if(geom->GetShapeType() == LibUtilities::ePrism) + { + vector > xyz; + for(int i = 0; i < geom->GetNumVerts(); i++) + { + Array loc(3); + SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); + p->GetCoords(loc); + xyz.push_back(loc); + } + + Array b = chi->GetBase(); + Array eta1 = b[0]->GetZ(); + Array eta2 = b[1]->GetZ(); + Array eta3 = b[2]->GetZ(); + + for(int k = 0; k < b[2]->GetNumPoints(); k++) + { + for(int j = 0; j < b[1]->GetNumPoints(); j++) + { + for(int i = 0; i < b[0]->GetNumPoints(); i++) + { + NekDouble xi1 = 0.5*(1+eta1[i])*(1-eta3[k])-1.0; + NekDouble a1 = 0.5*(1-xi1), a2 = 0.5*(1+xi1); + NekDouble b1 = 0.5*(1-eta2[j]), b2 = 0.5*(1+eta2[j]); + NekDouble c1 = 0.5*(1-eta3[k]), c2 = 0.5*(1+eta3[k]); + + DNekMat dxdz(3,3,1.0,eFULL); + + dxdz(0,0) = 0.5*(-b1*xyz[0][0] + b1*xyz[1][0] + b2*xyz[2][0] - b2*xyz[3][0]); + dxdz(1,0) = 0.5*(-b1*xyz[0][1] + b1*xyz[1][1] + b2*xyz[2][1] - b2*xyz[3][1]); + dxdz(2,0) = 0.5*(-b1*xyz[0][2] + b1*xyz[1][2] + b2*xyz[2][2] - b2*xyz[3][2]); + + dxdz(0,1) = 0.5*((a2-c1)*xyz[0][0] - a2*xyz[1][0] + a2*xyz[2][0] + (c1-a2)*xyz[3][0] - c2*xyz[4][0] + c2*xyz[5][0]); + dxdz(1,1) = 0.5*((a2-c1)*xyz[0][1] - a2*xyz[1][1] + a2*xyz[2][1] + (c1-a2)*xyz[3][1] - c2*xyz[4][1] + c2*xyz[5][1]); + dxdz(2,1) = 0.5*((a2-c1)*xyz[0][2] - a2*xyz[1][2] + a2*xyz[2][2] + (c1-a2)*xyz[3][2] - c2*xyz[4][2] + c2*xyz[5][2]); + + dxdz(0,2) = 0.5*(-b1*xyz[0][0] - b2*xyz[3][0] + b1*xyz[4][0] + b2*xyz[5][0]); + dxdz(1,2) = 0.5*(-b1*xyz[0][1] - b2*xyz[3][1] + b1*xyz[4][1] + b2*xyz[5][1]); + dxdz(2,2) = 0.5*(-b1*xyz[0][2] - b2*xyz[3][2] + b1*xyz[4][2] + b2*xyz[5][2]); + + dxdz.Invert(); + ret.push_back(dxdz); + } + } + } + } + else + { + ASSERTL0(false,"not coded"); + } + + return ret; } NekDouble ProcessVarOpti::GetElFunctional(ElementSharedPtr el) @@ -119,12 +300,6 @@ NekDouble ProcessVarOpti::GetElFunctional(ElementSharedPtr el) basisKeys.push_back(chi->GetBasis(i)->GetBasisKey()); } - for(int i = 0; i < basisKeys.size(); i++) - { - cout << basisKeys[i].GetTotNumPoints() << endl; - } - exit(-1); - StdRegions::StdExpansionSharedPtr chiMod; switch(chi->DetShapeType()) { @@ -151,15 +326,13 @@ NekDouble ProcessVarOpti::GetElFunctional(ElementSharedPtr el) SpatialDomains::DerivStorage deriv = gfac->GetDeriv(p); const int pts = deriv[0][0].num_elements(); - cout << pts << endl; - exit(-1); - /* const int nq = chiMod->GetTotPoints(); ASSERTL0(pts == nq, "what"); vector i2rm = MappingIdealToRef(geom, chiMod); - Array eta(nq); + + Array dW(nq); for (int k = 0; k < pts; ++k) { @@ -175,36 +348,38 @@ NekDouble ProcessVarOpti::GetElFunctional(ElementSharedPtr el) } jacIdeal = jac * i2rm[k]; - NekDouble jacDet; - if(expDim == 2) - { - jacDet = jacIdeal(0,0) * jacIdeal(1,1) - jacIdeal(0,1)*jacIdeal(1,0); - } - else if(expDim == 3) - { - jacDet = jacIdeal(0,0) * (jacIdeal(1,1)*jacIdeal(2,2) - jacIdeal(2,1)*jacIdeal(1,2)) - - jacIdeal(0,1) * (jacIdeal(1,0)*jacIdeal(2,2) - jacIdeal(2,0)*jacIdeal(1,2)) + - jacIdeal(0,2) * (jacIdeal(1,0)*jacIdeal(2,1) - jacIdeal(2,0)*jacIdeal(1,1)); - } - else - { - ASSERTL0(false,"silly exp dim"); - } + DNekMat jacIdealT; + jacIdealT = jacIdeal; + jacIdealT.Transpose(); - NekDouble frob = 0.0; + DNekMat C = jacIdealT * jacIdeal; - for (int i = 0; i < expDim; ++i) + DNekMat I (expDim,expDim,1.0,eDIAGONAL); + + DNekMat E = 0.5*(C - I); + + DNekMat Et = E; + Et.Transpose(); + + DNekMat EtE = Et * E; + + NekDouble trE = 0.0; + NekDouble trEtE = 0.0; + + for(int i = 0; i < expDim; i++) { - for (int j = 0; j < expDim; ++j) - { - frob += jacIdeal(i,j) * jacIdeal(i,j); - } + trE += E(i,i); + trEtE += EtE(i,i); } - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet)); - eta[k] = expDim * pow(sigma, 2.0/expDim) / frob; - }*/ + NekDouble nu = 0.45; + NekDouble lam = nu/(1.0+nu)/(1-2.0*nu); + NekDouble mu = 1.0/2.0/(1.0+nu); + dW[k] = 0.5*lam*trE*trE + mu*trEtE; + } + + return chi->Integral(dW); } void ProcessVarOpti::GetElementMap() -- GitLab From c7c97a4d5ce83799a747404e582b4de55193abd7 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Thu, 21 Apr 2016 12:33:19 +0100 Subject: [PATCH 004/236] started opti --- library/NekMeshUtils/MeshElements/Node.h | 16 ++++ .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 88 +++++++++++++++++-- .../NekMesh/ProcessModules/ProcessVarOpti.h | 2 +- 3 files changed, 100 insertions(+), 6 deletions(-) diff --git a/library/NekMeshUtils/MeshElements/Node.h b/library/NekMeshUtils/MeshElements/Node.h index db315bfe9..fcb2c46cf 100644 --- a/library/NekMeshUtils/MeshElements/Node.h +++ b/library/NekMeshUtils/MeshElements/Node.h @@ -360,6 +360,22 @@ struct NodeHash : std::unary_function } }; typedef boost::unordered_set NodeSet; + +struct NodeComp : std::binary_function +{ + bool operator()(NodeSharedPtr const &p1, NodeSharedPtr const &p2) const + { + NekDouble dist = sqrt((p1->m_x-p2->m_x)*(p1->m_x-p2->m_x)+ + (p1->m_y-p2->m_y)*(p1->m_y-p2->m_y)+ + (p1->m_z-p2->m_z)*(p1->m_z-p2->m_z)); + if(dist < 1e-6) + { + return false; + } + + return p1->m_x < p2->m_x; + } +}; } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 3729bf218..03765cb9a 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -65,6 +65,9 @@ ProcessVarOpti::~ProcessVarOpti() { } +NekDouble dir[8][2] ={{1.0,1.0} , {0.0,1.0} , {-1.0,1.0}, {-1.0,0.0}, {-1.0,-1.0}, + {0.0,-1.0}, {1.0,-1.0}, {1.0,0.0}}; + void ProcessVarOpti::Process() { if (m_mesh->m_verbose) @@ -83,17 +86,80 @@ void ProcessVarOpti::Process() GetElementMap(); - for(int i = 0; i < optiNodes.size(); i++) + NekDouble functionalStart = 0.0; + for(int i = 0; i < m_mesh->m_element[2].size(); i++) + { + functionalStart += GetElFunctional(m_mesh->m_element[2][i]); + } + + + int ctr = 0; + bool repeat = true; + while (repeat) + { + repeat = false; + for(int i = 0; i < optiNodes.size(); i++) + { + cout << i << endl; + NekDouble currentW = GetFunctional(optiNodes[i]); + NekDouble dx = 0.01; + + while(dx > 1e-6) + { + bool end = false; + for(int j = 0; j < 8; j++) + { + NodeSharedPtr tstNode = optiNodes[i]->copy(); + tstNode->m_x += dir[j][0] * dx; + tstNode->m_y += dir[j][1] * dx; + + cout << currentW << " " << GetFunctional(tstNode) << endl; + if(GetFunctional(tstNode) < currentW) + { + cout << "hit" << endl; + optiNodes[i] = tstNode; + end = true; + break; + } + } + if(end) + { + repeat = true; + break; + } + else + { + dx /= 2.0; + } + } + } + break; + } + + + + + + + + + + NekDouble functionalEnd = 0.0; + + for(int i = 0; i < m_mesh->m_element[2].size(); i++) { - NekDouble w = GetFunctional(optiNodes[i]); - cout << w << endl; + functionalEnd += GetElFunctional(m_mesh->m_element[2][i]); } + + cout << "start: " << functionalStart << " end: " << functionalEnd << endl; + exit(-1); + } NekDouble ProcessVarOpti::GetFunctional(NodeSharedPtr n) { - NodeElMap::iterator it = nodeElMap.find(n); + NodeElMap::iterator it = nodeElMap.find(n->m_id); ASSERTL0(it != nodeElMap.end(),"could not find"); vector els = it->second; @@ -392,7 +458,7 @@ void ProcessVarOpti::GetElementMap() el->GetCurvedNodes(n); for(int j = 0; j < 3 * (5 - 1); j++) { - nodeElMap[n[j]].push_back(el); + nodeElMap[n[j]->m_id].push_back(el); } } } @@ -439,6 +505,18 @@ vector ProcessVarOpti::GetFreeNodes() } } + int id = m_mesh->m_vertexSet.size(); + //enumerate the curved nodes for mapping purposes + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + { + vector n; + (*it)->GetCurvedNodes(n); + for(int j = 1; j < n.size()-1; j++) + { + n[j]->m_id = id++; + } + } + return ret; } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index ce903b55e..d156e9a80 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -42,7 +42,7 @@ namespace Nektar { namespace Utilities { -typedef boost::unordered_map, NodeHash> NodeElMap; +typedef map > NodeElMap; /** * @brief This processing module calculates the Jacobian of elements * using %SpatialDomains::GeomFactors and the %Element::GetGeom -- GitLab From 4bf5634ae56e81811bac6b592801aada9d371e66 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Thu, 21 Apr 2016 16:24:43 +0100 Subject: [PATCH 005/236] appears to be working variational optimisation --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 72 ++++++++----------- 1 file changed, 30 insertions(+), 42 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 03765cb9a..a77b79639 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -92,69 +92,57 @@ void ProcessVarOpti::Process() functionalStart += GetElFunctional(m_mesh->m_element[2][i]); } + cout << scientific << endl; + NekDouble functionalEnd; int ctr = 0; bool repeat = true; while (repeat) { + ctr++; repeat = false; for(int i = 0; i < optiNodes.size(); i++) { - cout << i << endl; NekDouble currentW = GetFunctional(optiNodes[i]); NekDouble dx = 0.01; while(dx > 1e-6) { - bool end = false; + NodeSharedPtr bstNode = optiNodes[i]->copy(); + NekDouble xc = optiNodes[i]->m_x; + NekDouble yc = optiNodes[i]->m_y; for(int j = 0; j < 8; j++) { - NodeSharedPtr tstNode = optiNodes[i]->copy(); - tstNode->m_x += dir[j][0] * dx; - tstNode->m_y += dir[j][1] * dx; - - cout << currentW << " " << GetFunctional(tstNode) << endl; - if(GetFunctional(tstNode) < currentW) + optiNodes[i]->m_x += dir[j][0] * dx; + optiNodes[i]->m_y += dir[j][1] * dx; + NekDouble nW = GetFunctional(optiNodes[i]); + if(nW < currentW) { - cout << "hit" << endl; - optiNodes[i] = tstNode; - end = true; - break; + currentW = nW; + bstNode = optiNodes[i]->copy(); + repeat = true; } + optiNodes[i]->m_x = xc; + optiNodes[i]->m_y = yc; } - if(end) - { - repeat = true; - break; - } - else - { - dx /= 2.0; - } + optiNodes[i]->m_x = bstNode->m_x; + optiNodes[i]->m_y = bstNode->m_y; + dx /= 2.0; } } - break; - } - - - - - - - - - - NekDouble functionalEnd = 0.0; + if(ctr > 20) + { + break; + } + functionalEnd = 0.0; - for(int i = 0; i < m_mesh->m_element[2].size(); i++) - { - functionalEnd += GetElFunctional(m_mesh->m_element[2][i]); + for(int i = 0; i < m_mesh->m_element[2].size(); i++) + { + functionalEnd += GetElFunctional(m_mesh->m_element[2][i]); + } + cout << ctr << " start: " << functionalStart << " end: " << + functionalEnd << endl; } - - - cout << "start: " << functionalStart << " end: " << functionalEnd << endl; - exit(-1); - } NekDouble ProcessVarOpti::GetFunctional(NodeSharedPtr n) @@ -439,7 +427,7 @@ NekDouble ProcessVarOpti::GetElFunctional(ElementSharedPtr el) trEtE += EtE(i,i); } - NekDouble nu = 0.45; + NekDouble nu = 0.49; NekDouble lam = nu/(1.0+nu)/(1-2.0*nu); NekDouble mu = 1.0/2.0/(1.0+nu); dW[k] = 0.5*lam*trE*trE + mu*trEtE; -- GitLab From 8d29d3be6a760052e32598f66480b7ab3e0df550 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 25 Apr 2016 17:12:37 +0100 Subject: [PATCH 006/236] winslow roca and elastic working --- library/NekMeshUtils/MeshElements/Node.h | 15 - .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 347 ++++++++++++------ .../NekMesh/ProcessModules/ProcessVarOpti.h | 24 +- 3 files changed, 246 insertions(+), 140 deletions(-) diff --git a/library/NekMeshUtils/MeshElements/Node.h b/library/NekMeshUtils/MeshElements/Node.h index fcb2c46cf..8792b27ba 100644 --- a/library/NekMeshUtils/MeshElements/Node.h +++ b/library/NekMeshUtils/MeshElements/Node.h @@ -361,21 +361,6 @@ struct NodeHash : std::unary_function }; typedef boost::unordered_set NodeSet; -struct NodeComp : std::binary_function -{ - bool operator()(NodeSharedPtr const &p1, NodeSharedPtr const &p2) const - { - NekDouble dist = sqrt((p1->m_x-p2->m_x)*(p1->m_x-p2->m_x)+ - (p1->m_y-p2->m_y)*(p1->m_y-p2->m_y)+ - (p1->m_z-p2->m_z)*(p1->m_z-p2->m_z)); - if(dist < 1e-6) - { - return false; - } - - return p1->m_x < p2->m_x; - } -}; } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index a77b79639..583984c0e 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -58,16 +58,18 @@ ModuleKey ProcessVarOpti::className = GetModuleFactory().RegisterCreatorFunction ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) { - + m_config["linearelastic"] = + ConfigOption(true, "", "Optimise for linear elasticity"); + m_config["winslow"] = + ConfigOption(true, "", "Optimise for winslow"); + m_config["roca"] = + ConfigOption(true, "", "Optimise for roca method"); } ProcessVarOpti::~ProcessVarOpti() { } -NekDouble dir[8][2] ={{1.0,1.0} , {0.0,1.0} , {-1.0,1.0}, {-1.0,0.0}, {-1.0,-1.0}, - {0.0,-1.0}, {1.0,-1.0}, {1.0,0.0}}; - void ProcessVarOpti::Process() { if (m_mesh->m_verbose) @@ -75,6 +77,23 @@ void ProcessVarOpti::Process() cout << "ProcessVarOpti: Optimising... " << endl; } + if(m_config["linearelastic"].beenSet) + { + opti = eLinEl; + } + else if(m_config["winslow"].beenSet) + { + opti = eWins; + } + else if(m_config["roca"].beenSet) + { + opti = eRoca; + } + else + { + ASSERTL0(false,"not opti type set"); + } + if(m_mesh->m_expDim == 3 || m_mesh->m_spaceDim == 3) { ASSERTL0(false,"wrong mesh dim"); @@ -89,76 +108,212 @@ void ProcessVarOpti::Process() NekDouble functionalStart = 0.0; for(int i = 0; i < m_mesh->m_element[2].size(); i++) { - functionalStart += GetElFunctional(m_mesh->m_element[2][i]); + functionalStart += GetElFunctional(dataSet[i]); } cout << scientific << endl; - NekDouble functionalEnd; + NekDouble functionalEnd = functionalStart; + NekDouble functionalLast = 0.0; int ctr = 0; - bool repeat = true; - while (repeat) + while (fabs(functionalLast - functionalEnd) > 1e-5) { ctr++; - repeat = false; + functionalLast = functionalEnd; + int c = 0; for(int i = 0; i < optiNodes.size(); i++) { - NekDouble currentW = GetFunctional(optiNodes[i]); - NekDouble dx = 0.01; + //cout << i << endl; + Array G = GetGrad(optiNodes[i]); + + //cout << G[0] << " " << G[1] << endl; - while(dx > 1e-6) + if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-3) { - NodeSharedPtr bstNode = optiNodes[i]->copy(); + //needs to optimise + NekDouble currentW = GetFunctional(optiNodes[i]); NekDouble xc = optiNodes[i]->m_x; NekDouble yc = optiNodes[i]->m_y; - for(int j = 0; j < 8; j++) + NekDouble alpha = 1.0; + bool found = false; + while(alpha > 1e-6) { - optiNodes[i]->m_x += dir[j][0] * dx; - optiNodes[i]->m_y += dir[j][1] * dx; - NekDouble nW = GetFunctional(optiNodes[i]); - if(nW < currentW) + optiNodes[i]->m_x = xc - alpha * G[0]; + optiNodes[i]->m_y = yc - alpha * G[1]; + + if(GetFunctional(optiNodes[i]) < currentW) { - currentW = nW; - bstNode = optiNodes[i]->copy(); - repeat = true; + found = true; + break; } + + alpha /= 2.0; + } + if(found) + { + //found an optimal position and moved the node + c++; + } + else + { + //reset the node optiNodes[i]->m_x = xc; optiNodes[i]->m_y = yc; + cout << "warning: had to reset node" << endl; } - optiNodes[i]->m_x = bstNode->m_x; - optiNodes[i]->m_y = bstNode->m_y; - dx /= 2.0; } } - if(ctr > 20) - { - break; - } functionalEnd = 0.0; - for(int i = 0; i < m_mesh->m_element[2].size(); i++) { - functionalEnd += GetElFunctional(m_mesh->m_element[2][i]); + functionalEnd += dataSet[i]->lastEval; } - cout << ctr << " start: " << functionalStart << " end: " << + cout << ctr << " " << c << " " << functionalStart << " " << functionalEnd << endl; + if(ctr > 1000) + break; } } +NekDouble dir[4][2] = {{1.0,0},{0,1.0},{-1.0,0},{0,-1.0}}; + +Array ProcessVarOpti::GetGrad(NodeSharedPtr n) +{ + NekDouble xc = n->m_x; + NekDouble yc = n->m_y; + NekDouble dx = 1e-6; + + NekDouble wi = GetFunctional(n); + vector w; + + for(int i = 0; i < 4; i++) + { + n->m_x += dir[i][0] * dx; + n->m_y += dir[i][1] * dx; + w.push_back(GetFunctional(n)); + n->m_x = xc; + n->m_y = yc; + } + + Array ret(2); + + ret[0] = (w[0] - w[2]) / 2.0 / dx; + ret[1] = (w[1] - w[3]) / 2.0 / dx; + + return ret; +} + NekDouble ProcessVarOpti::GetFunctional(NodeSharedPtr n) { NodeElMap::iterator it = nodeElMap.find(n->m_id); ASSERTL0(it != nodeElMap.end(),"could not find"); - vector els = it->second; NekDouble r = 0.0; - for(int i = 0; i < els.size(); i++) + for(int i = 0; i < it->second.size(); i++) { - r += GetElFunctional(els[i]); + r += GetElFunctional(it->second[i]); } return r; } +NekDouble ProcessVarOpti::GetElFunctional(ElDataSharedPtr d) +{ + SpatialDomains::GeometrySharedPtr geom = d->el->GetGeom(m_mesh->m_spaceDim); + StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); + LibUtilities::PointsKeyVector p = chi->GetPointsKeys(); + SpatialDomains::GeomFactorsSharedPtr gfac = geom->GetGeomFactors(); + const int expDim = m_mesh->m_expDim; + + SpatialDomains::DerivStorage deriv = gfac->GetDeriv(p); + + const int pts = deriv[0][0].num_elements(); + + ASSERTL0(pts == d->maps.size(), "what"); + + Array dW(pts); + + for (int k = 0; k < pts; ++k) + { + DNekMat jac (expDim, expDim, 0.0, eFULL); + DNekMat jacIdeal(expDim, expDim, 0.0, eFULL); + + for (int i = 0; i < expDim; ++i) + { + for (int j = 0; j < expDim; ++j) + { + jac(j,i) = deriv[i][j][k]; + } + } + + jacIdeal = jac * d->maps[k]; + + switch (opti) + { + case eLinEl: + { + NekDouble trEtE = 0.25*( + (jacIdeal(0,0) * jacIdeal(0,0) + jacIdeal(1,0) * jacIdeal(1,0) - 1.0)* + (jacIdeal(0,0) * jacIdeal(0,0) + jacIdeal(1,0) * jacIdeal(1,0) - 1.0) + + (jacIdeal(0,0) * jacIdeal(0,1) + jacIdeal(1,0) * jacIdeal(1,1))* + (jacIdeal(0,0) * jacIdeal(0,1) + jacIdeal(1,0) * jacIdeal(1,1)) + + (jacIdeal(0,0) * jacIdeal(0,1) + jacIdeal(1,0) * jacIdeal(1,1))* + (jacIdeal(0,0) * jacIdeal(0,1) + jacIdeal(1,0) * jacIdeal(1,1)) + + (jacIdeal(0,1) * jacIdeal(0,1) + jacIdeal(1,1) * jacIdeal(1,1) - 1.0)* + (jacIdeal(0,1) * jacIdeal(0,1) + jacIdeal(1,1) * jacIdeal(1,1) - 1.0)); + NekDouble ljacDet = log(jacIdeal(0,0) * jacIdeal(1,1) - jacIdeal(0,1)*jacIdeal(1,0)); + + NekDouble nu = 0.45; + NekDouble mu = 1.0/2.0/(1.0+nu); + NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + dW[k] = K *0.5 * ljacDet * ljacDet + mu * trEtE; + break; + } + + case eWins: + { + NekDouble jacDet = jacIdeal(0,0) * jacIdeal(1,1) - jacIdeal(0,1)*jacIdeal(1,0); + NekDouble frob = 0.0; + + for (int i = 0; i < expDim; ++i) + { + for (int j = 0; j < expDim; ++j) + { + frob += jacIdeal(i,j) * jacIdeal(i,j); + } + } + + if(jacDet < 1E-6) + { + jacDet = 1E-6; + } + dW[k] = frob / jacDet; + break; + } + + case eRoca: + { + NekDouble jacDet = jacIdeal(0,0) * jacIdeal(1,1) - jacIdeal(0,1)*jacIdeal(1,0); + NekDouble frob = 0.0; + + for (int i = 0; i < expDim; ++i) + { + for (int j = 0; j < expDim; ++j) + { + frob += jacIdeal(i,j) * jacIdeal(i,j); + } + } + + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet)); + dW[k] = frob / expDim * pow(sigma, 2.0/expDim); + break; + } + } + } + + d->lastEval = chi->Integral(dW); + return d->lastEval; +} + inline vector MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, StdRegions::StdExpansionSharedPtr chi) { @@ -338,106 +493,53 @@ inline vector MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, return ret; } -NekDouble ProcessVarOpti::GetElFunctional(ElementSharedPtr el) +void ProcessVarOpti::GetElementMap() { - SpatialDomains::GeometrySharedPtr geom = el->GetGeom(m_mesh->m_spaceDim); - StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); - LibUtilities::PointsKeyVector p = chi->GetPointsKeys(); - SpatialDomains::GeomFactorsSharedPtr gfac = geom->GetGeomFactors(); - const int expDim = chi->GetNumBases(); - int nElemPts = 1; - - vector basisKeys; - - for (int i = 0; i < expDim; ++i) - { - basisKeys.push_back(chi->GetBasis(i)->GetBasisKey()); - } - - StdRegions::StdExpansionSharedPtr chiMod; - switch(chi->DetShapeType()) + //build ideal maps and structs; + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { - case LibUtilities::eTriangle: - chiMod = MemoryManager::AllocateSharedPtr( - basisKeys[0], basisKeys[1]); - break; - case LibUtilities::eQuadrilateral: - chiMod = MemoryManager::AllocateSharedPtr( - basisKeys[0], basisKeys[1]); - break; - case LibUtilities::eTetrahedron: - chiMod = MemoryManager::AllocateSharedPtr( - basisKeys[0], basisKeys[1], basisKeys[2]); - break; - case LibUtilities::ePrism: - chiMod = MemoryManager::AllocateSharedPtr( - basisKeys[0], basisKeys[1], basisKeys[2]); - break; - default: - ASSERTL0(false, "nope"); - } - - SpatialDomains::DerivStorage deriv = gfac->GetDeriv(p); - - const int pts = deriv[0][0].num_elements(); - const int nq = chiMod->GetTotPoints(); - - ASSERTL0(pts == nq, "what"); - - vector i2rm = MappingIdealToRef(geom, chiMod); + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + ElDataSharedPtr d = boost::shared_ptr(new ElData); + d->el = el; - Array dW(nq); + SpatialDomains::GeometrySharedPtr geom = el->GetGeom(m_mesh->m_spaceDim); + StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); - for (int k = 0; k < pts; ++k) - { - DNekMat jac (expDim, expDim, 0.0, eFULL); - DNekMat jacIdeal(expDim, expDim, 0.0, eFULL); + vector basisKeys; - for (int i = 0; i < expDim; ++i) + for (int i = 0; i < m_mesh->m_expDim; ++i) { - for (int j = 0; j < expDim; ++j) - { - jac(j,i) = deriv[i][j][k]; - } + basisKeys.push_back(chi->GetBasis(i)->GetBasisKey()); } - jacIdeal = jac * i2rm[k]; - - DNekMat jacIdealT; - jacIdealT = jacIdeal; - jacIdealT.Transpose(); - - DNekMat C = jacIdealT * jacIdeal; - - DNekMat I (expDim,expDim,1.0,eDIAGONAL); - - DNekMat E = 0.5*(C - I); - - DNekMat Et = E; - Et.Transpose(); - - DNekMat EtE = Et * E; - - NekDouble trE = 0.0; - NekDouble trEtE = 0.0; - - for(int i = 0; i < expDim; i++) + StdRegions::StdExpansionSharedPtr chiMod; + switch(chi->DetShapeType()) { - trE += E(i,i); - trEtE += EtE(i,i); + case LibUtilities::eTriangle: + chiMod = MemoryManager::AllocateSharedPtr( + basisKeys[0], basisKeys[1]); + break; + case LibUtilities::eQuadrilateral: + chiMod = MemoryManager::AllocateSharedPtr( + basisKeys[0], basisKeys[1]); + break; + case LibUtilities::eTetrahedron: + chiMod = MemoryManager::AllocateSharedPtr( + basisKeys[0], basisKeys[1], basisKeys[2]); + break; + case LibUtilities::ePrism: + chiMod = MemoryManager::AllocateSharedPtr( + basisKeys[0], basisKeys[1], basisKeys[2]); + break; + default: + ASSERTL0(false, "nope"); } - NekDouble nu = 0.49; - NekDouble lam = nu/(1.0+nu)/(1-2.0*nu); - NekDouble mu = 1.0/2.0/(1.0+nu); - dW[k] = 0.5*lam*trE*trE + mu*trEtE; - } + d->maps = MappingIdealToRef(geom, chiMod); - return chi->Integral(dW); -} + dataSet.push_back(d); + } -void ProcessVarOpti::GetElementMap() -{ for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; @@ -446,7 +548,8 @@ void ProcessVarOpti::GetElementMap() el->GetCurvedNodes(n); for(int j = 0; j < 3 * (5 - 1); j++) { - nodeElMap[n[j]->m_id].push_back(el); + //data set and elements have same index in vector + nodeElMap[n[j]->m_id].push_back(dataSet[i]); } } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index d156e9a80..5b4cfdc33 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -42,7 +42,23 @@ namespace Nektar { namespace Utilities { -typedef map > NodeElMap; +struct ElData +{ + ElementSharedPtr el; + vector maps; + NekDouble lastEval; +}; +typedef boost::shared_ptr ElDataSharedPtr; + +typedef map > NodeElMap; + +enum optimiser +{ + eLinEl, + eWins, + eRoca +}; + /** * @brief This processing module calculates the Jacobian of elements * using %SpatialDomains::GeomFactors and the %Element::GetGeom @@ -70,8 +86,10 @@ private: void GetElementMap(); NodeElMap nodeElMap; NekDouble GetFunctional(NodeSharedPtr n); - NekDouble GetElFunctional(ElementSharedPtr el); - + NekDouble GetElFunctional(ElDataSharedPtr d); + Array GetGrad(NodeSharedPtr n); + vector dataSet; + optimiser opti; }; } -- GitLab From 75db894e8e6951d871283abffb5a67933560b1a0 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Tue, 26 Apr 2016 09:20:11 +0100 Subject: [PATCH 007/236] remove some more dnekmat --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 583984c0e..e078c3d5b 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -105,6 +105,8 @@ void ProcessVarOpti::Process() GetElementMap(); + + NekDouble functionalStart = 0.0; for(int i = 0; i < m_mesh->m_element[2].size(); i++) { @@ -234,33 +236,37 @@ NekDouble ProcessVarOpti::GetElFunctional(ElDataSharedPtr d) for (int k = 0; k < pts; ++k) { - DNekMat jac (expDim, expDim, 0.0, eFULL); - DNekMat jacIdeal(expDim, expDim, 0.0, eFULL); + Array jacIdeal(2,2); + Array jac(2,2); for (int i = 0; i < expDim; ++i) { for (int j = 0; j < expDim; ++j) { - jac(j,i) = deriv[i][j][k]; + jac[j][i] = deriv[i][j][k]; } } - jacIdeal = jac * d->maps[k]; + //jacIdeal = jac * d->maps[k]; + jacIdeal[0][0] = jac[0][0] * d->maps[k](0,0) + jac[0][1] * d->maps[k](1,0); + jacIdeal[1][1] = jac[1][0] * d->maps[k](0,1) + jac[1][1] * d->maps[k](1,1); + jacIdeal[0][1] = jac[0][0] * d->maps[k](0,1) + jac[0][1] * d->maps[k](1,1); + jacIdeal[1][0] = jac[1][0] * d->maps[k](0,0) + jac[1][1] * d->maps[k](1,0); switch (opti) { case eLinEl: { NekDouble trEtE = 0.25*( - (jacIdeal(0,0) * jacIdeal(0,0) + jacIdeal(1,0) * jacIdeal(1,0) - 1.0)* - (jacIdeal(0,0) * jacIdeal(0,0) + jacIdeal(1,0) * jacIdeal(1,0) - 1.0) + - (jacIdeal(0,0) * jacIdeal(0,1) + jacIdeal(1,0) * jacIdeal(1,1))* - (jacIdeal(0,0) * jacIdeal(0,1) + jacIdeal(1,0) * jacIdeal(1,1)) + - (jacIdeal(0,0) * jacIdeal(0,1) + jacIdeal(1,0) * jacIdeal(1,1))* - (jacIdeal(0,0) * jacIdeal(0,1) + jacIdeal(1,0) * jacIdeal(1,1)) + - (jacIdeal(0,1) * jacIdeal(0,1) + jacIdeal(1,1) * jacIdeal(1,1) - 1.0)* - (jacIdeal(0,1) * jacIdeal(0,1) + jacIdeal(1,1) * jacIdeal(1,1) - 1.0)); - NekDouble ljacDet = log(jacIdeal(0,0) * jacIdeal(1,1) - jacIdeal(0,1)*jacIdeal(1,0)); + (jacIdeal[0][0] * jacIdeal[0][0] + jacIdeal[1][0] * jacIdeal[1][0] - 1.0)* + (jacIdeal[0][0] * jacIdeal[0][0] + jacIdeal[1][0] * jacIdeal[1][0] - 1.0) + + (jacIdeal[0][0] * jacIdeal[0][1] + jacIdeal[1][0] * jacIdeal[1][1])* + (jacIdeal[0][0] * jacIdeal[0][1] + jacIdeal[1][0] * jacIdeal[1][1]) + + (jacIdeal[0][0] * jacIdeal[0][1] + jacIdeal[1][0] * jacIdeal[1][1])* + (jacIdeal[0][0] * jacIdeal[0][1] + jacIdeal[1][0] * jacIdeal[1][1]) + + (jacIdeal[0][1] * jacIdeal[0][1] + jacIdeal[1][1] * jacIdeal[1][1] - 1.0)* + (jacIdeal[0][1] * jacIdeal[0][1] + jacIdeal[1][1] * jacIdeal[1][1] - 1.0)); + NekDouble ljacDet = log(jacIdeal[0][0] * jacIdeal[1][1] - jacIdeal[0][1]*jacIdeal[1][0]); NekDouble nu = 0.45; NekDouble mu = 1.0/2.0/(1.0+nu); @@ -271,14 +277,14 @@ NekDouble ProcessVarOpti::GetElFunctional(ElDataSharedPtr d) case eWins: { - NekDouble jacDet = jacIdeal(0,0) * jacIdeal(1,1) - jacIdeal(0,1)*jacIdeal(1,0); + NekDouble jacDet = jacIdeal[0][0] * jacIdeal[1][1] - jacIdeal[0][1]*jacIdeal[1][0]; NekDouble frob = 0.0; for (int i = 0; i < expDim; ++i) { for (int j = 0; j < expDim; ++j) { - frob += jacIdeal(i,j) * jacIdeal(i,j); + frob += jacIdeal[i][j] * jacIdeal[i][j]; } } @@ -292,14 +298,14 @@ NekDouble ProcessVarOpti::GetElFunctional(ElDataSharedPtr d) case eRoca: { - NekDouble jacDet = jacIdeal(0,0) * jacIdeal(1,1) - jacIdeal(0,1)*jacIdeal(1,0); + NekDouble jacDet = jacIdeal[0][0] * jacIdeal[1][1] - jacIdeal[0][1]*jacIdeal[1][0]; NekDouble frob = 0.0; for (int i = 0; i < expDim; ++i) { for (int j = 0; j < expDim; ++j) { - frob += jacIdeal(i,j) * jacIdeal(i,j); + frob += jacIdeal[i][j] * jacIdeal[i][j]; } } -- GitLab From f9776e6f4e955193a421131c05f691ae46b56913 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Tue, 26 Apr 2016 10:27:52 +0100 Subject: [PATCH 008/236] coloring --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 143 ++++++++++++------ .../NekMesh/ProcessModules/ProcessVarOpti.h | 1 + 2 files changed, 98 insertions(+), 46 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index e078c3d5b..9dcc1dcd5 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -101,11 +101,9 @@ void ProcessVarOpti::Process() FillQuadPoints(); - vector optiNodes = GetFreeNodes(); - GetElementMap(); - + vector > optiNodes = GetColouredNodes(GetFreeNodes()); NekDouble functionalStart = 0.0; for(int i = 0; i < m_mesh->m_element[2].size(); i++) @@ -125,43 +123,46 @@ void ProcessVarOpti::Process() int c = 0; for(int i = 0; i < optiNodes.size(); i++) { - //cout << i << endl; - Array G = GetGrad(optiNodes[i]); + for(int j = 0; j < optiNodes[i].size(); j++) + { + //cout << i << endl; + Array G = GetGrad(optiNodes[i][j]); - //cout << G[0] << " " << G[1] << endl; + //cout << G[0] << " " << G[1] << endl; - if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-3) - { - //needs to optimise - NekDouble currentW = GetFunctional(optiNodes[i]); - NekDouble xc = optiNodes[i]->m_x; - NekDouble yc = optiNodes[i]->m_y; - NekDouble alpha = 1.0; - bool found = false; - while(alpha > 1e-6) + if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-3) { - optiNodes[i]->m_x = xc - alpha * G[0]; - optiNodes[i]->m_y = yc - alpha * G[1]; + //needs to optimise + NekDouble currentW = GetFunctional(optiNodes[i][j]); + NekDouble xc = optiNodes[i][j]->m_x; + NekDouble yc = optiNodes[i][j]->m_y; + NekDouble alpha = 1.0; + bool found = false; + while(alpha > 1e-6) + { + optiNodes[i][j]->m_x = xc - alpha * G[0]; + optiNodes[i][j]->m_y = yc - alpha * G[1]; - if(GetFunctional(optiNodes[i]) < currentW) + if(GetFunctional(optiNodes[i][j]) < currentW) + { + found = true; + break; + } + + alpha /= 2.0; + } + if(found) { - found = true; - break; + //found an optimal position and moved the node + c++; + } + else + { + //reset the node + optiNodes[i][j]->m_x = xc; + optiNodes[i][j]->m_y = yc; + cout << "warning: had to reset node" << endl; } - - alpha /= 2.0; - } - if(found) - { - //found an optimal position and moved the node - c++; - } - else - { - //reset the node - optiNodes[i]->m_x = xc; - optiNodes[i]->m_y = yc; - cout << "warning: had to reset node" << endl; } } } @@ -499,6 +500,55 @@ inline vector MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, return ret; } +vector > ProcessVarOpti::GetColouredNodes(vector n) +{ + vector > ret; + vector remain = n; + while (remain.size() > 0) + { + vector layer; + set locked; + set completed; + for(int i = 0; i < remain.size(); i++) + { + NodeElMap::iterator it = nodeElMap.find(remain[i]->m_id); + ASSERTL0(it != nodeElMap.end(),"could not find"); + bool islocked = false; + for(int j = 0; j < it->second.size(); j++) + { + set::iterator sit = locked.find(it->second[j]->el->GetId()); + if(sit != locked.end()) + { + islocked = true; + break; + } + } + if(!islocked) + { + layer.push_back(remain[i]); + completed.insert(remain[i]->m_id); + for(int j = 0; j < it->second.size(); j++) + { + locked.insert(it->second[j]->el->GetId()); + } + } + } + + vector tmp = remain; + remain.clear(); + for(int i = 0; i < tmp.size(); i++) + { + set::iterator sit = completed.find(tmp[i]->m_id); + if(sit == completed.end()) + { + remain.push_back(tmp[i]); + } + } + ret.push_back(layer); + } + return ret; +} + void ProcessVarOpti::GetElementMap() { //build ideal maps and structs; @@ -602,18 +652,6 @@ vector ProcessVarOpti::GetFreeNodes() } } - int id = m_mesh->m_vertexSet.size(); - //enumerate the curved nodes for mapping purposes - for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) - { - vector n; - (*it)->GetCurvedNodes(n); - for(int j = 1; j < n.size()-1; j++) - { - n[j]->m_id = id++; - } - } - return ret; } @@ -655,6 +693,19 @@ void ProcessVarOpti::FillQuadPoints() (*it)->m_edgeNodes = ns; (*it)->m_curveType = LibUtilities::eGaussLobattoLegendre; } + + int id = m_mesh->m_vertexSet.size(); + //enumerate the curved nodes for mapping purposes + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + { + vector n; + (*it)->GetCurvedNodes(n); + for(int j = 1; j < n.size()-1; j++) + { + n[j]->m_id = id++; + } + } + } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index 5b4cfdc33..f103a30ab 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -88,6 +88,7 @@ private: NekDouble GetFunctional(NodeSharedPtr n); NekDouble GetElFunctional(ElDataSharedPtr d); Array GetGrad(NodeSharedPtr n); + vector > GetColouredNodes(vector n); vector dataSet; optimiser opti; }; -- GitLab From 048ed428303fb993527bfe2a5b006f4bb5f65cbe Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Tue, 26 Apr 2016 14:50:46 +0100 Subject: [PATCH 009/236] seg faulting mess of a threading attempt --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 455 +++++++++--------- .../NekMesh/ProcessModules/ProcessVarOpti.h | 33 +- 2 files changed, 262 insertions(+), 226 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 9dcc1dcd5..ffe945e10 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -50,182 +50,13 @@ namespace Nektar { namespace Utilities { - -ModuleKey ProcessVarOpti::className = GetModuleFactory().RegisterCreatorFunction( - ModuleKey(eProcessModule, "varopti"), - ProcessVarOpti::create, - "Optimise mesh locations."); - -ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) -{ - m_config["linearelastic"] = - ConfigOption(true, "", "Optimise for linear elasticity"); - m_config["winslow"] = - ConfigOption(true, "", "Optimise for winslow"); - m_config["roca"] = - ConfigOption(true, "", "Optimise for roca method"); -} - -ProcessVarOpti::~ProcessVarOpti() +inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti) { -} - -void ProcessVarOpti::Process() -{ - if (m_mesh->m_verbose) - { - cout << "ProcessVarOpti: Optimising... " << endl; - } - - if(m_config["linearelastic"].beenSet) - { - opti = eLinEl; - } - else if(m_config["winslow"].beenSet) - { - opti = eWins; - } - else if(m_config["roca"].beenSet) - { - opti = eRoca; - } - else - { - ASSERTL0(false,"not opti type set"); - } - - if(m_mesh->m_expDim == 3 || m_mesh->m_spaceDim == 3) - { - ASSERTL0(false,"wrong mesh dim"); - } - - FillQuadPoints(); - - GetElementMap(); - - vector > optiNodes = GetColouredNodes(GetFreeNodes()); - - NekDouble functionalStart = 0.0; - for(int i = 0; i < m_mesh->m_element[2].size(); i++) - { - functionalStart += GetElFunctional(dataSet[i]); - } - - cout << scientific << endl; - - NekDouble functionalEnd = functionalStart; - NekDouble functionalLast = 0.0; - int ctr = 0; - while (fabs(functionalLast - functionalEnd) > 1e-5) - { - ctr++; - functionalLast = functionalEnd; - int c = 0; - for(int i = 0; i < optiNodes.size(); i++) - { - for(int j = 0; j < optiNodes[i].size(); j++) - { - //cout << i << endl; - Array G = GetGrad(optiNodes[i][j]); - - //cout << G[0] << " " << G[1] << endl; - - if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-3) - { - //needs to optimise - NekDouble currentW = GetFunctional(optiNodes[i][j]); - NekDouble xc = optiNodes[i][j]->m_x; - NekDouble yc = optiNodes[i][j]->m_y; - NekDouble alpha = 1.0; - bool found = false; - while(alpha > 1e-6) - { - optiNodes[i][j]->m_x = xc - alpha * G[0]; - optiNodes[i][j]->m_y = yc - alpha * G[1]; - - if(GetFunctional(optiNodes[i][j]) < currentW) - { - found = true; - break; - } - - alpha /= 2.0; - } - if(found) - { - //found an optimal position and moved the node - c++; - } - else - { - //reset the node - optiNodes[i][j]->m_x = xc; - optiNodes[i][j]->m_y = yc; - cout << "warning: had to reset node" << endl; - } - } - } - } - functionalEnd = 0.0; - for(int i = 0; i < m_mesh->m_element[2].size(); i++) - { - functionalEnd += dataSet[i]->lastEval; - } - cout << ctr << " " << c << " " << functionalStart << " " << - functionalEnd << endl; - if(ctr > 1000) - break; - } -} - -NekDouble dir[4][2] = {{1.0,0},{0,1.0},{-1.0,0},{0,-1.0}}; - -Array ProcessVarOpti::GetGrad(NodeSharedPtr n) -{ - NekDouble xc = n->m_x; - NekDouble yc = n->m_y; - NekDouble dx = 1e-6; - - NekDouble wi = GetFunctional(n); - vector w; - - for(int i = 0; i < 4; i++) - { - n->m_x += dir[i][0] * dx; - n->m_y += dir[i][1] * dx; - w.push_back(GetFunctional(n)); - n->m_x = xc; - n->m_y = yc; - } - - Array ret(2); - - ret[0] = (w[0] - w[2]) / 2.0 / dx; - ret[1] = (w[1] - w[3]) / 2.0 / dx; - - return ret; -} - -NekDouble ProcessVarOpti::GetFunctional(NodeSharedPtr n) -{ - NodeElMap::iterator it = nodeElMap.find(n->m_id); - ASSERTL0(it != nodeElMap.end(),"could not find"); - - NekDouble r = 0.0; - for(int i = 0; i < it->second.size(); i++) - { - r += GetElFunctional(it->second[i]); - } - return r; -} - -NekDouble ProcessVarOpti::GetElFunctional(ElDataSharedPtr d) -{ - SpatialDomains::GeometrySharedPtr geom = d->el->GetGeom(m_mesh->m_spaceDim); + SpatialDomains::GeometrySharedPtr geom = d->el->GetGeom(2); StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); LibUtilities::PointsKeyVector p = chi->GetPointsKeys(); SpatialDomains::GeomFactorsSharedPtr gfac = geom->GetGeomFactors(); - const int expDim = m_mesh->m_expDim; + const int expDim = 2; SpatialDomains::DerivStorage deriv = gfac->GetDeriv(p); @@ -500,10 +331,241 @@ inline vector MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, return ret; } -vector > ProcessVarOpti::GetColouredNodes(vector n) +ModuleKey ProcessVarOpti::className = GetModuleFactory().RegisterCreatorFunction( + ModuleKey(eProcessModule, "varopti"), + ProcessVarOpti::create, + "Optimise mesh locations."); + +ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) +{ + m_config["linearelastic"] = + ConfigOption(true, "", "Optimise for linear elasticity"); + m_config["winslow"] = + ConfigOption(true, "", "Optimise for winslow"); + m_config["roca"] = + ConfigOption(true, "", "Optimise for roca method"); +} + +ProcessVarOpti::~ProcessVarOpti() +{ +} + +void ProcessVarOpti::Process() { + if (m_mesh->m_verbose) + { + cout << "ProcessVarOpti: Optimising... " << endl; + } + + if(m_config["linearelastic"].beenSet) + { + opti = eLinEl; + } + else if(m_config["winslow"].beenSet) + { + opti = eWins; + } + else if(m_config["roca"].beenSet) + { + opti = eRoca; + } + else + { + ASSERTL0(false,"not opti type set"); + } + + if(m_mesh->m_expDim == 3 || m_mesh->m_spaceDim == 3) + { + ASSERTL0(false,"wrong mesh dim"); + } + + FillQuadPoints(); + + GetElementMap(); + + vector > freenodes = GetColouredNodes(); + + vector > optiNodes; + for(int i = 0; i < freenodes.size(); i++) + { + vector ns; + for(int j = 0; j < freenodes[i].size(); j++) + { + NodeElMap::iterator it = nodeElMap.find(freenodes[i][j]->m_id); + ASSERTL0(it != nodeElMap.end(),"could not find"); + ns.push_back(NodeOpti(freenodes[i][j],it->second,opti)); + } + optiNodes.push_back(ns); + } + + NekDouble functionalStart = 0.0; + for(int i = 0; i < m_mesh->m_element[2].size(); i++) + { + functionalStart += GetElFunctional(dataSet[i], opti); + } + + cout << scientific << endl; + + NekDouble functionalEnd = functionalStart; + NekDouble functionalLast = 0.0; + int ctr = 0; + Thread::ThreadMaster tms; + tms.SetThreadingType("ThreadManagerBoost"); + Thread::ThreadManagerSharedPtr tm = tms.CreateInstance(Thread::ThreadMaster::SessionJob, 4); + while (fabs(functionalLast - functionalEnd) > 1e-5) + { + ctr++; + functionalLast = functionalEnd; + int c = 0; + for(int i = 0; i < optiNodes.size(); i++) + { + vector ns = optiNodes[i]; //make copy + vector jobs; + for(int j = 0; j < ns.size(); j++) + { + jobs.push_back(&ns[j]); + } + tm->SetNumWorkers(0); + tm->QueueJobs(jobs); + cout << "here" << endl; + tm->SetNumWorkers(2); + cout << "there" << endl; + tm->Wait(); + cout << "balls" << endl; + + /*for(int j = 0; j < optiNodes[i].size(); j++) + { + optiNodes[i][j].Run(); + }*/ + } + functionalEnd = 0.0; + for(int i = 0; i < m_mesh->m_element[2].size(); i++) + { + functionalEnd += dataSet[i]->lastEval; + } + cout << ctr << " " << functionalStart << " " << + functionalEnd << endl; + if(ctr > 1000) + break; + } +} + +NekDouble dir[4][2] = {{1.0,0},{0,1.0},{-1.0,0},{0,-1.0}}; + +void ProcessVarOpti::NodeOpti::Run() +{ + Array G = GetGrad(); + + if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-3) + { + //needs to optimise + NekDouble currentW = GetFunctional(); + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble alpha = 1.0; + bool found = false; + while(alpha > 1e-6) + { + node->m_x = xc - alpha * G[0]; + node->m_y = yc - alpha * G[1]; + + if(GetFunctional() < currentW) + { + found = true; + break; + } + + alpha /= 2.0; + } + if(!found) + { + //reset the node + node->m_x = xc; + node->m_y = yc; + cout << "warning: had to reset node" << endl; + } + } +} + +Array ProcessVarOpti::NodeOpti::GetGrad() +{ + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble dx = 1e-6; + + vector w; + + for(int i = 0; i < 4; i++) + { + node->m_x += dir[i][0] * dx; + node->m_y += dir[i][1] * dx; + w.push_back(GetFunctional()); + node->m_x = xc; + node->m_y = yc; + } + + Array ret(2); + + ret[0] = (w[0] - w[2]) / 2.0 / dx; + ret[1] = (w[1] - w[3]) / 2.0 / dx; + + return ret; +} + +NekDouble ProcessVarOpti::NodeOpti::GetFunctional() +{ + NekDouble r = 0.0; + for(int i = 0; i < data.size(); i++) + { + r += GetElFunctional(data[i], opti); + } + return r; +} + +vector > ProcessVarOpti::GetColouredNodes() +{ + //loop over the composites to build a set of nodes which lie in + //boundary composites + //then iterate over all nodes, if the node is not in the set its free + //add it to the vector + NodeSet boundaryNodes; + + EdgeSet::iterator it; + int ct = 0; + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + { + if((*it)->m_elLink.size() == 2) + { + continue; + } + + ct++; + + vector n; + (*it)->GetCurvedNodes(n); + for(int i = 0; i < n.size(); i++) + { + boundaryNodes.insert(n[i]); + } + } + + vector remain; + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + { + vector n; + (*it)->GetCurvedNodes(n); + for(int j = 0; j < n.size(); j++) + { + NodeSet::iterator nit = boundaryNodes.find(n[j]); + if(nit == boundaryNodes.end()) + { + remain.push_back(n[j]); + } + } + } + vector > ret; - vector remain = n; + while (remain.size() > 0) { vector layer; @@ -610,51 +672,6 @@ void ProcessVarOpti::GetElementMap() } } -vector ProcessVarOpti::GetFreeNodes() -{ - //loop over the composites to build a set of nodes which lie in - //boundary composites - //then iterate over all nodes, if the node is not in the set its free - //add it to the vector - NodeSet boundaryNodes; - - EdgeSet::iterator it; - int ct = 0; - for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) - { - if((*it)->m_elLink.size() == 2) - { - continue; - } - - ct++; - - vector n; - (*it)->GetCurvedNodes(n); - for(int i = 0; i < n.size(); i++) - { - boundaryNodes.insert(n[i]); - } - } - - vector ret; - for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) - { - vector n; - (*it)->GetCurvedNodes(n); - for(int j = 0; j < n.size(); j++) - { - NodeSet::iterator nit = boundaryNodes.find(n[j]); - if(nit == boundaryNodes.end()) - { - ret.push_back(n[j]); - } - } - } - - return ret; -} - void ProcessVarOpti::FillQuadPoints() { //not all quadrature points are there diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index f103a30ab..cd7bad66f 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -38,6 +38,8 @@ #include "../Module.h" +#include + namespace Nektar { namespace Utilities @@ -50,8 +52,6 @@ struct ElData }; typedef boost::shared_ptr ElDataSharedPtr; -typedef map > NodeElMap; - enum optimiser { eLinEl, @@ -81,16 +81,35 @@ public: /// Write mesh to output file. virtual void Process(); private: + typedef map > NodeElMap; + void FillQuadPoints(); - vector GetFreeNodes(); void GetElementMap(); + vector > GetColouredNodes(); + NodeElMap nodeElMap; - NekDouble GetFunctional(NodeSharedPtr n); - NekDouble GetElFunctional(ElDataSharedPtr d); - Array GetGrad(NodeSharedPtr n); - vector > GetColouredNodes(vector n); vector dataSet; optimiser opti; + + class NodeOpti : public Thread::ThreadJob + { + public: + NodeOpti(NodeSharedPtr n, vector e, optimiser o) + : node(n), data(e), opti(o) + { + } + + ~NodeOpti(){}; + + virtual void Run(); + private: + Array GetGrad(); + NekDouble GetFunctional(); + NodeSharedPtr node; + vector data; + optimiser opti; + }; + }; } -- GitLab From 0f699c3a46944b7d7af7d732a73d93ff4341c9c3 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Wed, 27 Apr 2016 09:07:45 +0100 Subject: [PATCH 010/236] works with one worker thread --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 14 +++++------- .../NekMesh/ProcessModules/ProcessVarOpti.h | 22 +++++++++++++++++-- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index ffe945e10..bb6172300 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -419,19 +419,16 @@ void ProcessVarOpti::Process() int c = 0; for(int i = 0; i < optiNodes.size(); i++) { - vector ns = optiNodes[i]; //make copy vector jobs; - for(int j = 0; j < ns.size(); j++) + for(int j = 0; j < optiNodes[i].size(); j++) { - jobs.push_back(&ns[j]); + jobs.push_back(optiNodes[i][j].GetJob()); } + cout << jobs.size() << endl; tm->SetNumWorkers(0); tm->QueueJobs(jobs); - cout << "here" << endl; - tm->SetNumWorkers(2); - cout << "there" << endl; + tm->SetNumWorkers(1); tm->Wait(); - cout << "balls" << endl; /*for(int j = 0; j < optiNodes[i].size(); j++) { @@ -452,7 +449,7 @@ void ProcessVarOpti::Process() NekDouble dir[4][2] = {{1.0,0},{0,1.0},{-1.0,0},{0,-1.0}}; -void ProcessVarOpti::NodeOpti::Run() +void ProcessVarOpti::NodeOpti::Optimise() { Array G = GetGrad(); @@ -485,6 +482,7 @@ void ProcessVarOpti::NodeOpti::Run() cout << "warning: had to reset node" << endl; } } + cout << "done" << endl; } Array ProcessVarOpti::NodeOpti::GetGrad() diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index cd7bad66f..bed7da6c0 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -91,7 +91,9 @@ private: vector dataSet; optimiser opti; - class NodeOpti : public Thread::ThreadJob + class NodeOptiJob; + + class NodeOpti { public: NodeOpti(NodeSharedPtr n, vector e, optimiser o) @@ -101,7 +103,11 @@ private: ~NodeOpti(){}; - virtual void Run(); + void Optimise(); + NodeOptiJob *GetJob() + { + return new NodeOptiJob(*this); + } private: Array GetGrad(); NekDouble GetFunctional(); @@ -110,6 +116,18 @@ private: optimiser opti; }; + class NodeOptiJob : public Thread::ThreadJob + { + public: + NodeOptiJob(NodeOpti no) : node(no) {} + void Run() + { + node.Optimise(); + } + private: + NodeOpti node; + }; + }; } -- GitLab From d7c6b3fdaf4167cd653dd15b259aa3b383299097 Mon Sep 17 00:00:00 2001 From: David Moxey Date: Wed, 27 Apr 2016 15:26:36 +0100 Subject: [PATCH 011/236] Add some mutex locks to avoid threading issues --- library/NekMeshUtils/MeshElements/Edge.h | 5 +++++ .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/library/NekMeshUtils/MeshElements/Edge.h b/library/NekMeshUtils/MeshElements/Edge.h index 13891cad3..e1fee6b0d 100644 --- a/library/NekMeshUtils/MeshElements/Edge.h +++ b/library/NekMeshUtils/MeshElements/Edge.h @@ -38,6 +38,8 @@ #include +#include + #include #include @@ -136,6 +138,9 @@ public: /// Generate a SpatialDomains::SegGeom object for this edge. NEKMESHUTILS_EXPORT SpatialDomains::SegGeomSharedPtr GetGeom(int coordDim) { + static boost::mutex io_mutex; + boost::mutex::scoped_lock lock(io_mutex); + // Create edge vertices. SpatialDomains::PointGeomSharedPtr p[2]; SpatialDomains::SegGeomSharedPtr ret; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index bb6172300..129e81a97 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -38,6 +38,8 @@ #include #include "ProcessVarOpti.h" +#include + #include #include #include @@ -50,14 +52,19 @@ namespace Nektar { namespace Utilities { + +boost::mutex tmp; + inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti) { SpatialDomains::GeometrySharedPtr geom = d->el->GetGeom(2); StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); LibUtilities::PointsKeyVector p = chi->GetPointsKeys(); + tmp.lock(); SpatialDomains::GeomFactorsSharedPtr gfac = geom->GetGeomFactors(); const int expDim = 2; + tmp.unlock(); SpatialDomains::DerivStorage deriv = gfac->GetDeriv(p); const int pts = deriv[0][0].num_elements(); @@ -148,7 +155,9 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti) } } + tmp.lock(); d->lastEval = chi->Integral(dW); + tmp.unlock(); return d->lastEval; } @@ -344,6 +353,8 @@ ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) ConfigOption(true, "", "Optimise for winslow"); m_config["roca"] = ConfigOption(true, "", "Optimise for roca method"); + m_config["numthreads"] = + ConfigOption(false, "1", "Number of threads"); } ProcessVarOpti::~ProcessVarOpti() @@ -406,12 +417,15 @@ void ProcessVarOpti::Process() cout << scientific << endl; + int nThreads = m_config["numthreads"].as(); + NekDouble functionalEnd = functionalStart; NekDouble functionalLast = 0.0; int ctr = 0; Thread::ThreadMaster tms; tms.SetThreadingType("ThreadManagerBoost"); - Thread::ThreadManagerSharedPtr tm = tms.CreateInstance(Thread::ThreadMaster::SessionJob, 4); + Thread::ThreadManagerSharedPtr tm = tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads); + while (fabs(functionalLast - functionalEnd) > 1e-5) { ctr++; @@ -427,7 +441,7 @@ void ProcessVarOpti::Process() cout << jobs.size() << endl; tm->SetNumWorkers(0); tm->QueueJobs(jobs); - tm->SetNumWorkers(1); + tm->SetNumWorkers(nThreads); tm->Wait(); /*for(int j = 0; j < optiNodes[i].size(); j++) -- GitLab From 35e08827fccaf7a47ed46e332ed4124a0c6d95ec Mon Sep 17 00:00:00 2001 From: David Moxey Date: Wed, 27 Apr 2016 18:28:50 +0100 Subject: [PATCH 012/236] Nicer couts --- utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 129e81a97..e36f5af4b 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -438,7 +438,8 @@ void ProcessVarOpti::Process() { jobs.push_back(optiNodes[i][j].GetJob()); } - cout << jobs.size() << endl; + cout << " -- inner loop " << i+1 << "/" << optiNodes.size() + << " of size: " << jobs.size() << endl; tm->SetNumWorkers(0); tm->QueueJobs(jobs); tm->SetNumWorkers(nThreads); @@ -496,7 +497,6 @@ void ProcessVarOpti::NodeOpti::Optimise() cout << "warning: had to reset node" << endl; } } - cout << "done" << endl; } Array ProcessVarOpti::NodeOpti::GetGrad() -- GitLab From b83b4548aad7b82206483977755a0ee2b0b66a4f Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Wed, 27 Apr 2016 19:25:07 +0100 Subject: [PATCH 013/236] fix for roca --- .../ProcessModules/ProcessQualityMetric.cpp | 43 ++++++++++++++----- .../ProcessModules/ProcessQualityMetric.h | 3 +- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 30 ++++++++++--- .../NekMesh/ProcessModules/ProcessVarOpti.h | 3 +- 4 files changed, 62 insertions(+), 17 deletions(-) diff --git a/utilities/FieldConvert/ProcessModules/ProcessQualityMetric.cpp b/utilities/FieldConvert/ProcessModules/ProcessQualityMetric.cpp index ec3a14486..4385c368a 100644 --- a/utilities/FieldConvert/ProcessModules/ProcessQualityMetric.cpp +++ b/utilities/FieldConvert/ProcessModules/ProcessQualityMetric.cpp @@ -61,7 +61,8 @@ ModuleKey ProcessQualityMetric::className = ProcessQualityMetric::ProcessQualityMetric(FieldSharedPtr f) : ProcessModule(f) { - + m_config["scaled"] = + ConfigOption(true, "", "use scaled jacobian instead"); } ProcessQualityMetric::~ProcessQualityMetric() @@ -84,7 +85,7 @@ void ProcessQualityMetric::Process(po::variables_map &vm) // copy Jacobian into field LocalRegions::ExpansionSharedPtr Elmt = m_f->m_exp[0]->GetExp(i); int offset = m_f->m_exp[0]->GetPhys_Offset(i); - Array q = GetQ(Elmt); + Array q = GetQ(Elmt,m_config["scaled"].m_beenSet); Array out = phys + offset; ASSERTL0(q.num_elements() == Elmt->GetTotPoints(), "number of points mismatch"); @@ -288,7 +289,7 @@ inline vector MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, return ret; } -Array ProcessQualityMetric::GetQ(LocalRegions::ExpansionSharedPtr e) +Array ProcessQualityMetric::GetQ(LocalRegions::ExpansionSharedPtr e, bool s) { SpatialDomains::GeometrySharedPtr geom = e->GetGeom(); StdRegions::StdExpansionSharedPtr chi = e->GetGeom()->GetXmap(); @@ -389,18 +390,40 @@ Array ProcessQualityMetric::GetQ(LocalRegions::ExpansionSharedP ASSERTL0(false,"silly exp dim"); } - NekDouble frob = 0.0; - - for (int i = 0; i < expDim; ++i) + if(s) { - for (int j = 0; j < expDim; ++j) + eta[k] = jacDet; + } + else + { + NekDouble frob = 0.0; + + for (int i = 0; i < expDim; ++i) { - frob += jacIdeal(i,j) * jacIdeal(i,j); + for (int j = 0; j < expDim; ++j) + { + frob += jacIdeal(i,j) * jacIdeal(i,j); + } } + + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet)); + eta[k] = expDim * pow(sigma, 2.0/expDim) / frob; } + } - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet)); - eta[k] = expDim * pow(sigma, 2.0/expDim) / frob; + if(s) + { + NekDouble mx = -1.0 * numeric_limits::max(); + NekDouble mn = numeric_limits::max(); + for(int k = 0; k < pts; k++) + { + mx = max(mx,eta[k]); + mn = min(mn,eta[k]); + } + for(int k = 0; k < pts; k++) + { + eta[k] = mn/mx; + } } // Project onto output stuff diff --git a/utilities/FieldConvert/ProcessModules/ProcessQualityMetric.h b/utilities/FieldConvert/ProcessModules/ProcessQualityMetric.h index 8066085e3..ecc622395 100644 --- a/utilities/FieldConvert/ProcessModules/ProcessQualityMetric.h +++ b/utilities/FieldConvert/ProcessModules/ProcessQualityMetric.h @@ -61,7 +61,8 @@ class ProcessQualityMetric : public ProcessModule virtual void Process(po::variables_map &vm); private: - Array GetQ(LocalRegions::ExpansionSharedPtr e); + Array GetQ(LocalRegions::ExpansionSharedPtr e, + bool s); }; } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index e36f5af4b..b1204c581 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -127,9 +127,9 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti) } } - if(jacDet < 1E-6) + if(jacDet < 1E-10) { - jacDet = 1E-6; + jacDet = 1E-10; } dW[k] = frob / jacDet; break; @@ -148,10 +148,23 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti) } } - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet)); - dW[k] = frob / expDim * pow(sigma, 2.0/expDim); + NekDouble i2rmDet = 1.0 / (d->maps[k](0,0)*d->maps[k](1,1) - d->maps[k](1,0)*d->maps[k](0,1)); + NekDouble de = fabs(i2rmDet) * sqrt(1E-6 + 1E-3); + + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); + dW[k] = frob / expDim / pow(sigma, 2.0/expDim); break; } + + case eHypEl: + { + NekDouble jacDet = jacIdeal[0][0] * jacIdeal[1][1] - jacIdeal[0][1]*jacIdeal[1][0]; + NekDouble ljacDet = log(jacDet); + NekDouble nu = 0.45; + NekDouble mu = 1.0/2.0/(1.0+nu); + NekDouble lam = nu / (1.0 - 2.0 * nu) / (1.0+nu); + dW[k] = 0.5 * mu * (jacDet * jacDet - 3.0) - mu * ljacDet + 0.5 * lam * ljacDet * ljacDet; + } } } @@ -353,6 +366,8 @@ ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) ConfigOption(true, "", "Optimise for winslow"); m_config["roca"] = ConfigOption(true, "", "Optimise for roca method"); + m_config["hyperelastic"] = + ConfigOption(true, "", "Optimise for hyper elasticity"); m_config["numthreads"] = ConfigOption(false, "1", "Number of threads"); } @@ -380,6 +395,10 @@ void ProcessVarOpti::Process() { opti = eRoca; } + else if(m_config["hyperelastic"].beenSet) + { + opti = eHypEl; + } else { ASSERTL0(false,"not opti type set"); @@ -440,6 +459,7 @@ void ProcessVarOpti::Process() } cout << " -- inner loop " << i+1 << "/" << optiNodes.size() << " of size: " << jobs.size() << endl; + tm->SetNumWorkers(0); tm->QueueJobs(jobs); tm->SetNumWorkers(nThreads); @@ -468,7 +488,7 @@ void ProcessVarOpti::NodeOpti::Optimise() { Array G = GetGrad(); - if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-3) + if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-6) { //needs to optimise NekDouble currentW = GetFunctional(); diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index bed7da6c0..4d1e7af53 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -56,7 +56,8 @@ enum optimiser { eLinEl, eWins, - eRoca + eRoca, + eHypEl }; /** -- GitLab From 37b08c23b512746212be9368d34c7338690ef83a Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Thu, 28 Apr 2016 15:23:02 +0100 Subject: [PATCH 014/236] fully 3 and 2D, got rid of the last dnekmat --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 697 +++++++++++++----- .../NekMesh/ProcessModules/ProcessVarOpti.h | 17 +- 2 files changed, 541 insertions(+), 173 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index b1204c581..7984982a5 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -53,18 +53,17 @@ namespace Nektar namespace Utilities { -boost::mutex tmp; +boost::mutex mtx; -inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti) +inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim) { - SpatialDomains::GeometrySharedPtr geom = d->el->GetGeom(2); + SpatialDomains::GeometrySharedPtr geom = d->el->GetGeom(dim); StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); LibUtilities::PointsKeyVector p = chi->GetPointsKeys(); - tmp.lock(); + mtx.lock(); SpatialDomains::GeomFactorsSharedPtr gfac = geom->GetGeomFactors(); - const int expDim = 2; - tmp.unlock(); + mtx.unlock(); SpatialDomains::DerivStorage deriv = gfac->GetDeriv(p); const int pts = deriv[0][0].num_elements(); @@ -73,112 +72,247 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti) Array dW(pts); - for (int k = 0; k < pts; ++k) + switch (opti) { - Array jacIdeal(2,2); - Array jac(2,2); - - for (int i = 0; i < expDim; ++i) + case eLinEl: { - for (int j = 0; j < expDim; ++j) + for(int k = 0; k < pts; k++) { - jac[j][i] = deriv[i][j][k]; - } - } - - //jacIdeal = jac * d->maps[k]; - jacIdeal[0][0] = jac[0][0] * d->maps[k](0,0) + jac[0][1] * d->maps[k](1,0); - jacIdeal[1][1] = jac[1][0] * d->maps[k](0,1) + jac[1][1] * d->maps[k](1,1); - jacIdeal[0][1] = jac[0][0] * d->maps[k](0,1) + jac[0][1] * d->maps[k](1,1); - jacIdeal[1][0] = jac[1][0] * d->maps[k](0,0) + jac[1][1] * d->maps[k](1,0); + Array jac(9,0.0); + for (int i = 0; i < dim; ++i) + { + for (int j = 0; j < dim; ++j) + { + jac[j+i*3] = deriv[i][j][k]; + } + } - switch (opti) - { - case eLinEl: - { - NekDouble trEtE = 0.25*( - (jacIdeal[0][0] * jacIdeal[0][0] + jacIdeal[1][0] * jacIdeal[1][0] - 1.0)* - (jacIdeal[0][0] * jacIdeal[0][0] + jacIdeal[1][0] * jacIdeal[1][0] - 1.0) + - (jacIdeal[0][0] * jacIdeal[0][1] + jacIdeal[1][0] * jacIdeal[1][1])* - (jacIdeal[0][0] * jacIdeal[0][1] + jacIdeal[1][0] * jacIdeal[1][1]) + - (jacIdeal[0][0] * jacIdeal[0][1] + jacIdeal[1][0] * jacIdeal[1][1])* - (jacIdeal[0][0] * jacIdeal[0][1] + jacIdeal[1][0] * jacIdeal[1][1]) + - (jacIdeal[0][1] * jacIdeal[0][1] + jacIdeal[1][1] * jacIdeal[1][1] - 1.0)* - (jacIdeal[0][1] * jacIdeal[0][1] + jacIdeal[1][1] * jacIdeal[1][1] - 1.0)); - NekDouble ljacDet = log(jacIdeal[0][0] * jacIdeal[1][1] - jacIdeal[0][1]*jacIdeal[1][0]); + Array jacIdeal(9,0.0); + jacIdeal[0] = jac[0]*d->maps[k][0] + jac[3]*d->maps[k][1] + jac[6]*d->maps[k][2]; + jacIdeal[1] = jac[1]*d->maps[k][0] + jac[4]*d->maps[k][1] + jac[7]*d->maps[k][2]; + jacIdeal[2] = jac[2]*d->maps[k][0] + jac[5]*d->maps[k][1] + jac[8]*d->maps[k][2]; + + jacIdeal[3] = jac[0]*d->maps[k][3] + jac[3]*d->maps[k][4] + jac[6]*d->maps[k][5]; + jacIdeal[4] = jac[1]*d->maps[k][3] + jac[4]*d->maps[k][4] + jac[7]*d->maps[k][5]; + jacIdeal[5] = jac[2]*d->maps[k][3] + jac[5]*d->maps[k][4] + jac[8]*d->maps[k][5]; + + jacIdeal[6] = jac[0]*d->maps[k][6] + jac[3]*d->maps[k][7] + jac[6]*d->maps[k][8]; + jacIdeal[7] = jac[1]*d->maps[k][6] + jac[4]*d->maps[k][7] + jac[7]*d->maps[k][8]; + jacIdeal[8] = jac[2]*d->maps[k][6] + jac[5]*d->maps[k][7] + jac[8]*d->maps[k][8]; + + NekDouble a = (jacIdeal[0]*jacIdeal[0]+jacIdeal[1]*jacIdeal[1]+jacIdeal[2]*jacIdeal[2]-1.0)* + (jacIdeal[0]*jacIdeal[0]+jacIdeal[1]*jacIdeal[1]+jacIdeal[2]*jacIdeal[2]-1.0); + NekDouble b = (jacIdeal[3]*jacIdeal[3]+jacIdeal[4]*jacIdeal[4]+jacIdeal[5]*jacIdeal[5]-1.0)* + (jacIdeal[3]*jacIdeal[3]+jacIdeal[4]*jacIdeal[4]+jacIdeal[5]*jacIdeal[5]-1.0); + NekDouble c = (jacIdeal[6]*jacIdeal[6]+jacIdeal[7]*jacIdeal[7]+jacIdeal[8]*jacIdeal[8]-1.0)* + (jacIdeal[6]*jacIdeal[6]+jacIdeal[7]*jacIdeal[7]+jacIdeal[8]*jacIdeal[8]-1.0); + NekDouble d = (jacIdeal[0]*jacIdeal[6]+jacIdeal[1]*jacIdeal[7]+jacIdeal[2]*jacIdeal[8])* + (jacIdeal[0]*jacIdeal[6]+jacIdeal[1]*jacIdeal[7]+jacIdeal[2]*jacIdeal[8]); + NekDouble e = (jacIdeal[3]*jacIdeal[6]+jacIdeal[4]*jacIdeal[7]+jacIdeal[5]*jacIdeal[8])* + (jacIdeal[3]*jacIdeal[6]+jacIdeal[4]*jacIdeal[7]+jacIdeal[5]*jacIdeal[8]); + NekDouble f = (jacIdeal[0]*jacIdeal[3]+jacIdeal[1]*jacIdeal[4]+jacIdeal[3]*jacIdeal[5])* + (jacIdeal[0]*jacIdeal[3]+jacIdeal[1]*jacIdeal[4]+jacIdeal[3]*jacIdeal[5]); + + NekDouble trEtE = 0.25 * (a+b+c) + 0.5 * (d+e+f); + NekDouble ljacDet; + if(dim == 2) + { + ljacDet = log(jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]); + } + else + { + ljacDet = log(jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) + -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) + +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4])); + } NekDouble nu = 0.45; NekDouble mu = 1.0/2.0/(1.0+nu); NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); dW[k] = K *0.5 * ljacDet * ljacDet + mu * trEtE; - break; - } - case eWins: + } + break; + } + case eHypEl: + { + for(int k = 0; k < pts; k++) { - NekDouble jacDet = jacIdeal[0][0] * jacIdeal[1][1] - jacIdeal[0][1]*jacIdeal[1][0]; - NekDouble frob = 0.0; - - for (int i = 0; i < expDim; ++i) + Array jac(9,0.0); + for (int i = 0; i < dim; ++i) { - for (int j = 0; j < expDim; ++j) + for (int j = 0; j < dim; ++j) { - frob += jacIdeal[i][j] * jacIdeal[i][j]; + jac[j+i*3] = deriv[i][j][k]; } } - if(jacDet < 1E-10) + Array jacIdeal(9,0.0); + jacIdeal[0] = jac[0]*d->maps[k][0] + jac[3]*d->maps[k][1] + jac[6]*d->maps[k][2]; + jacIdeal[1] = jac[1]*d->maps[k][0] + jac[4]*d->maps[k][1] + jac[7]*d->maps[k][2]; + jacIdeal[2] = jac[2]*d->maps[k][0] + jac[5]*d->maps[k][1] + jac[8]*d->maps[k][2]; + + jacIdeal[3] = jac[0]*d->maps[k][3] + jac[3]*d->maps[k][4] + jac[6]*d->maps[k][5]; + jacIdeal[4] = jac[1]*d->maps[k][3] + jac[4]*d->maps[k][4] + jac[7]*d->maps[k][5]; + jacIdeal[5] = jac[2]*d->maps[k][3] + jac[5]*d->maps[k][4] + jac[8]*d->maps[k][5]; + + jacIdeal[6] = jac[0]*d->maps[k][6] + jac[3]*d->maps[k][7] + jac[6]*d->maps[k][8]; + jacIdeal[7] = jac[1]*d->maps[k][6] + jac[4]*d->maps[k][7] + jac[7]*d->maps[k][8]; + jacIdeal[8] = jac[2]*d->maps[k][6] + jac[5]*d->maps[k][7] + jac[8]*d->maps[k][8]; + + NekDouble jacDet; + if(dim == 2) { - jacDet = 1E-10; + jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; + } + else + { + jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) + -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) + +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); } - dW[k] = frob / jacDet; - break; - } - case eRoca: - { - NekDouble jacDet = jacIdeal[0][0] * jacIdeal[1][1] - jacIdeal[0][1]*jacIdeal[1][0]; - NekDouble frob = 0.0; + NekDouble ljacDet = log(jacDet); + NekDouble nu = 0.45; + NekDouble mu = 1.0/2.0/(1.0+nu); + NekDouble lam = nu / (1.0 - 2.0 * nu) / (1.0+nu); + dW[k] = 0.5 * mu * (jacDet * jacDet - 3.0) - mu * ljacDet + 0.5 * lam * ljacDet * ljacDet; - for (int i = 0; i < expDim; ++i) + } + break; + } + case eRoca: + { + for(int k = 0; k < pts; k++) + { + Array jac(9,0.0); + for (int i = 0; i < dim; ++i) { - for (int j = 0; j < expDim; ++j) + for (int j = 0; j < dim; ++j) { - frob += jacIdeal[i][j] * jacIdeal[i][j]; + jac[j+i*3] = deriv[i][j][k]; } } - NekDouble i2rmDet = 1.0 / (d->maps[k](0,0)*d->maps[k](1,1) - d->maps[k](1,0)*d->maps[k](0,1)); + Array jacIdeal(9,0.0); + jacIdeal[0] = jac[0]*d->maps[k][0] + jac[3]*d->maps[k][1] + jac[6]*d->maps[k][2]; + jacIdeal[1] = jac[1]*d->maps[k][0] + jac[4]*d->maps[k][1] + jac[7]*d->maps[k][2]; + jacIdeal[2] = jac[2]*d->maps[k][0] + jac[5]*d->maps[k][1] + jac[8]*d->maps[k][2]; + + jacIdeal[3] = jac[0]*d->maps[k][3] + jac[3]*d->maps[k][4] + jac[6]*d->maps[k][5]; + jacIdeal[4] = jac[1]*d->maps[k][3] + jac[4]*d->maps[k][4] + jac[7]*d->maps[k][5]; + jacIdeal[5] = jac[2]*d->maps[k][3] + jac[5]*d->maps[k][4] + jac[8]*d->maps[k][5]; + + jacIdeal[6] = jac[0]*d->maps[k][6] + jac[3]*d->maps[k][7] + jac[6]*d->maps[k][8]; + jacIdeal[7] = jac[1]*d->maps[k][6] + jac[4]*d->maps[k][7] + jac[7]*d->maps[k][8]; + jacIdeal[8] = jac[2]*d->maps[k][6] + jac[5]*d->maps[k][7] + jac[8]*d->maps[k][8]; + + NekDouble jacDet, i2rmDet; + if(dim == 2) + { + jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; + i2rmDet = 1.0 / (d->maps[k][0]*d->maps[k][4] - d->maps[k][1]*d->maps[k][3]); + } + else + { + jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) + -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) + +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); + ASSERTL0(false,"need to extend to do i2rmDet in 3d"); + } + + NekDouble frob = 0.0; + + frob += jacIdeal[0] * jacIdeal[0]; + frob += jacIdeal[1] * jacIdeal[1]; + frob += jacIdeal[2] * jacIdeal[2]; + frob += jacIdeal[3] * jacIdeal[3]; + frob += jacIdeal[4] * jacIdeal[4]; + frob += jacIdeal[5] * jacIdeal[5]; + frob += jacIdeal[6] * jacIdeal[6]; + frob += jacIdeal[7] * jacIdeal[7]; + frob += jacIdeal[8] * jacIdeal[8]; + NekDouble de = fabs(i2rmDet) * sqrt(1E-6 + 1E-3); NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - dW[k] = frob / expDim / pow(sigma, 2.0/expDim); - break; + dW[k] = frob / dim / pow(sigma, 2.0/dim); } - - case eHypEl: + break; + } + case eWins: + { + for(int k = 0; k < pts; k++) { - NekDouble jacDet = jacIdeal[0][0] * jacIdeal[1][1] - jacIdeal[0][1]*jacIdeal[1][0]; - NekDouble ljacDet = log(jacDet); - NekDouble nu = 0.45; - NekDouble mu = 1.0/2.0/(1.0+nu); - NekDouble lam = nu / (1.0 - 2.0 * nu) / (1.0+nu); - dW[k] = 0.5 * mu * (jacDet * jacDet - 3.0) - mu * ljacDet + 0.5 * lam * ljacDet * ljacDet; + Array jac(9,0.0); + for (int i = 0; i < dim; ++i) + { + for (int j = 0; j < dim; ++j) + { + jac[j+i*3] = deriv[i][j][k]; + } + } + + Array jacIdeal(9,0.0); + jacIdeal[0] = jac[0]*d->maps[k][0] + jac[3]*d->maps[k][1] + jac[6]*d->maps[k][2]; + jacIdeal[1] = jac[1]*d->maps[k][0] + jac[4]*d->maps[k][1] + jac[7]*d->maps[k][2]; + jacIdeal[2] = jac[2]*d->maps[k][0] + jac[5]*d->maps[k][1] + jac[8]*d->maps[k][2]; + + jacIdeal[3] = jac[0]*d->maps[k][3] + jac[3]*d->maps[k][4] + jac[6]*d->maps[k][5]; + jacIdeal[4] = jac[1]*d->maps[k][3] + jac[4]*d->maps[k][4] + jac[7]*d->maps[k][5]; + jacIdeal[5] = jac[2]*d->maps[k][3] + jac[5]*d->maps[k][4] + jac[8]*d->maps[k][5]; + + jacIdeal[6] = jac[0]*d->maps[k][6] + jac[3]*d->maps[k][7] + jac[6]*d->maps[k][8]; + jacIdeal[7] = jac[1]*d->maps[k][6] + jac[4]*d->maps[k][7] + jac[7]*d->maps[k][8]; + jacIdeal[8] = jac[2]*d->maps[k][6] + jac[5]*d->maps[k][7] + jac[8]*d->maps[k][8]; + + NekDouble jacDet; + if(dim == 2) + { + jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; + } + else + { + jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) + -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) + +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); + ASSERTL0(false,"need to extend to do i2rmDet in 3d"); + } + + if(jacDet < 1E-10) + { + jacDet = 1E-10; + } + + NekDouble frob = 0.0; + + frob += jacIdeal[0] * jacIdeal[0]; + frob += jacIdeal[1] * jacIdeal[1]; + frob += jacIdeal[2] * jacIdeal[2]; + frob += jacIdeal[3] * jacIdeal[3]; + frob += jacIdeal[4] * jacIdeal[4]; + frob += jacIdeal[5] * jacIdeal[5]; + frob += jacIdeal[6] * jacIdeal[6]; + frob += jacIdeal[7] * jacIdeal[7]; + frob += jacIdeal[8] * jacIdeal[8]; + + dW[k] = frob / jacDet; } + break; } } - tmp.lock(); - d->lastEval = chi->Integral(dW); - tmp.unlock(); - return d->lastEval; + mtx.lock(); + NekDouble inte = chi->Integral(dW); + mtx.unlock(); + return inte; } -inline vector MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, +inline vector > MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, StdRegions::StdExpansionSharedPtr chi) { int dim = geom->GetShapeDim(); - vector ret; + vector > ret; if(geom->GetShapeType() == LibUtilities::eQuadrilateral) { @@ -212,7 +346,12 @@ inline vector MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, NekDouble det = 1.0/(dxdz(0,0)*dxdz(1,1) - dxdz(1,0)*dxdz(0,1)); dxdz.Invert(); - ret.push_back(dxdz); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + ret.push_back(r); } } } @@ -245,7 +384,12 @@ inline vector MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, dxdz(1,1) = -xy[0][1]/2.0 + xy[2][1]/2.0; dxdz.Invert(); - ret.push_back(dxdz); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + ret.push_back(r); } } } @@ -293,7 +437,17 @@ inline vector MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, dxdz(2,2) = -xyz[0][2]/2.0 + xyz[3][2]/2.0; dxdz.Invert(); - ret.push_back(dxdz); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + r[2] = dxdz(2,0); + r[5] = dxdz(2,1); + r[6] = dxdz(0,2); + r[7] = dxdz(1,2); + r[8] = dxdz(2,2); + ret.push_back(r); } } } @@ -340,7 +494,17 @@ inline vector MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, dxdz(2,2) = 0.5*(-b1*xyz[0][2] - b2*xyz[3][2] + b1*xyz[4][2] + b2*xyz[5][2]); dxdz.Invert(); - ret.push_back(dxdz); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + r[2] = dxdz(2,0); + r[5] = dxdz(2,1); + r[6] = dxdz(0,2); + r[7] = dxdz(1,2); + r[8] = dxdz(2,2); + ret.push_back(r); } } } @@ -370,6 +534,8 @@ ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) ConfigOption(true, "", "Optimise for hyper elasticity"); m_config["numthreads"] = ConfigOption(false, "1", "Number of threads"); + m_config["nq"] = + ConfigOption(false, "0", "Number of quad points"); } ProcessVarOpti::~ProcessVarOpti() @@ -404,9 +570,13 @@ void ProcessVarOpti::Process() ASSERTL0(false,"not opti type set"); } - if(m_mesh->m_expDim == 3 || m_mesh->m_spaceDim == 3) + m_mesh->m_nummode = m_config["nq"].as(); + + ASSERTL0(m_mesh->m_nummode > 2,"not specified high-order"); + + if(m_mesh->m_expDim == 2 && m_mesh->m_spaceDim == 3) { - ASSERTL0(false,"wrong mesh dim"); + ASSERTL0(false,"cannot deal with manifolds"); } FillQuadPoints(); @@ -415,6 +585,9 @@ void ProcessVarOpti::Process() vector > freenodes = GetColouredNodes(); + ResidualSharedPtr res = boost::shared_ptr(new Residual); + res->val = 1.0; + vector > optiNodes; for(int i = 0; i < freenodes.size(); i++) { @@ -423,7 +596,7 @@ void ProcessVarOpti::Process() { NodeElMap::iterator it = nodeElMap.find(freenodes[i][j]->m_id); ASSERTL0(it != nodeElMap.end(),"could not find"); - ns.push_back(NodeOpti(freenodes[i][j],it->second,opti)); + ns.push_back(NodeOpti(freenodes[i][j],it->second,opti,res,m_mesh->m_spaceDim)); } optiNodes.push_back(ns); } @@ -431,25 +604,23 @@ void ProcessVarOpti::Process() NekDouble functionalStart = 0.0; for(int i = 0; i < m_mesh->m_element[2].size(); i++) { - functionalStart += GetElFunctional(dataSet[i], opti); + functionalStart += GetElFunctional(dataSet[i], opti, m_mesh->m_spaceDim); } cout << scientific << endl; + cout << "starting energy: " << functionalStart << endl; int nThreads = m_config["numthreads"].as(); - NekDouble functionalEnd = functionalStart; - NekDouble functionalLast = 0.0; int ctr = 0; Thread::ThreadMaster tms; tms.SetThreadingType("ThreadManagerBoost"); Thread::ThreadManagerSharedPtr tm = tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads); - while (fabs(functionalLast - functionalEnd) > 1e-5) + while (res->val > 1e-3) { ctr++; - functionalLast = functionalEnd; - int c = 0; + res->val = 0.0; for(int i = 0; i < optiNodes.size(); i++) { vector jobs; @@ -457,8 +628,8 @@ void ProcessVarOpti::Process() { jobs.push_back(optiNodes[i][j].GetJob()); } - cout << " -- inner loop " << i+1 << "/" << optiNodes.size() - << " of size: " << jobs.size() << endl; + //cout << " -- inner loop " << i+1 << "/" << optiNodes.size() + // << " of size: " << jobs.size() << endl; tm->SetNumWorkers(0); tm->QueueJobs(jobs); @@ -470,36 +641,39 @@ void ProcessVarOpti::Process() optiNodes[i][j].Run(); }*/ } - functionalEnd = 0.0; - for(int i = 0; i < m_mesh->m_element[2].size(); i++) - { - functionalEnd += dataSet[i]->lastEval; - } - cout << ctr << " " << functionalStart << " " << - functionalEnd << endl; - if(ctr > 1000) - break; + + cout << ctr << "\tResidual: " << res->val << endl; + } -} -NekDouble dir[4][2] = {{1.0,0},{0,1.0},{-1.0,0},{0,-1.0}}; + functionalStart = 0.0; + for(int i = 0; i < m_mesh->m_element[2].size(); i++) + { + functionalStart += GetElFunctional(dataSet[i], opti, m_mesh->m_spaceDim); + } + cout << "end energy: " << functionalStart << endl; +} void ProcessVarOpti::NodeOpti::Optimise() { + //it doesnt matter at this point what the dim is so long that + //in the 2d case z is left as zero Array G = GetGrad(); - if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-6) + if(sqrt(G[0]*G[0] + G[1]*G[1] + G[2]*G[2]) > 1e-6) { //needs to optimise NekDouble currentW = GetFunctional(); NekDouble xc = node->m_x; NekDouble yc = node->m_y; + NekDouble zc = node->m_z; NekDouble alpha = 1.0; bool found = false; while(alpha > 1e-6) { node->m_x = xc - alpha * G[0]; node->m_y = yc - alpha * G[1]; + node->m_z = zc - alpha * G[2]; if(GetFunctional() < currentW) { @@ -514,32 +688,48 @@ void ProcessVarOpti::NodeOpti::Optimise() //reset the node node->m_x = xc; node->m_y = yc; + node->m_z = zc; cout << "warning: had to reset node" << endl; } + mtx.lock(); + res->val += sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ + (node->m_z-zc)*(node->m_z-zc)); + mtx.unlock(); } } +NekDouble dir[6][3] = {{1.0,0.0,0.0},{-1.0,0.0,0.0}, + {0.0,1.0,0.0},{0.0,-1.0,0.0}, + {0.0,0.0,1.0},{0.0,0.0,-1.0}}; + Array ProcessVarOpti::NodeOpti::GetGrad() { NekDouble xc = node->m_x; NekDouble yc = node->m_y; + NekDouble zc = node->m_z; NekDouble dx = 1e-6; vector w; - for(int i = 0; i < 4; i++) + for(int i = 0; i < dim * 2; i++) { node->m_x += dir[i][0] * dx; node->m_y += dir[i][1] * dx; + node->m_z += dir[i][2] * dx; w.push_back(GetFunctional()); node->m_x = xc; node->m_y = yc; + node->m_z = zc; } - Array ret(2); + Array ret(3,0.0); - ret[0] = (w[0] - w[2]) / 2.0 / dx; - ret[1] = (w[1] - w[3]) / 2.0 / dx; + ret[0] = (w[0] - w[1]) / 2.0 / dx; + ret[1] = (w[2] - w[3]) / 2.0 / dx; + if(dim == 3) + { + ret[3] = (w[4] - w[5]) / 2.0 / dx; + } return ret; } @@ -549,51 +739,105 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() NekDouble r = 0.0; for(int i = 0; i < data.size(); i++) { - r += GetElFunctional(data[i], opti); + r += GetElFunctional(data[i], opti,dim); } return r; } vector > ProcessVarOpti::GetColouredNodes() { - //loop over the composites to build a set of nodes which lie in - //boundary composites - //then iterate over all nodes, if the node is not in the set its free - //add it to the vector + //this figures out the dirclet nodes and colors the others into paralell sets NodeSet boundaryNodes; - EdgeSet::iterator it; - int ct = 0; - for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + vector remain; + + switch (m_mesh->m_spaceDim) { - if((*it)->m_elLink.size() == 2) + case 2: { - continue; - } + EdgeSet::iterator it; + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + { + if((*it)->m_elLink.size() == 2) + { + continue; + } - ct++; + boundaryNodes.insert((*it)->m_n1); + boundaryNodes.insert((*it)->m_n2); + for(int i = 0; i < (*it)->m_edgeNodes.size(); i++) + { + boundaryNodes.insert((*it)->m_edgeNodes[i]); + } + } - vector n; - (*it)->GetCurvedNodes(n); - for(int i = 0; i < n.size(); i++) - { - boundaryNodes.insert(n[i]); + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + { + vector n = (*it)->m_edgeNodes; + n.push_back((*it)->m_n1); + n.push_back((*it)->m_n2); + for(int j = 0; j < n.size(); j++) + { + NodeSet::iterator nit = boundaryNodes.find(n[j]); + if(nit == boundaryNodes.end()) + { + remain.push_back(n[j]); + } + } + } + break; } - } - - vector remain; - for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) - { - vector n; - (*it)->GetCurvedNodes(n); - for(int j = 0; j < n.size(); j++) + case 3: { - NodeSet::iterator nit = boundaryNodes.find(n[j]); - if(nit == boundaryNodes.end()) + FaceSet::iterator it; + for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) { - remain.push_back(n[j]); + if((*it)->m_elLink.size() == 2) + { + continue; + } + + vector vs = (*it)->m_vertexList; + for(int j = 0; j < vs.size(); j++) + { + boundaryNodes.insert(vs[j]); + } + + vector es = (*it)->m_edgeList; + for(int j = 0; j < es.size(); j++) + { + for(int k = 0; k < es[j]->m_edgeNodes.size(); k++) + { + boundaryNodes.insert(es[j]->m_edgeNodes[k]); + } + } } + + for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) + { + vector n = (*it)->m_vertexList; + + vector es = (*it)->m_edgeList; + for(int j = 0; j < es.size(); j++) + { + for(int k = 0; k < es[j]->m_edgeNodes.size(); k++) + { + n.push_back(es[j]->m_edgeNodes[k]); + } + } + for(int j = 0; j < n.size(); j++) + { + NodeSet::iterator nit = boundaryNodes.find(n[j]); + if(nit == boundaryNodes.end()) + { + remain.push_back(n[j]); + } + } + } + break; } + default: + ASSERTL0(false,"space dim issue"); } vector > ret; @@ -694,64 +938,179 @@ void ProcessVarOpti::GetElementMap() { ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - vector n; - el->GetCurvedNodes(n); - for(int j = 0; j < 3 * (5 - 1); j++) + vector vs = el->GetVertexList(); + for(int j = 0; j < vs.size(); j++) { - //data set and elements have same index in vector - nodeElMap[n[j]->m_id].push_back(dataSet[i]); + nodeElMap[vs[j]->m_id].push_back(dataSet[i]); + } + + vector es = el->GetEdgeList(); + for(int j = 0; j < es.size(); j++) + { + for(int k = 0; k < es[j]->m_edgeNodes.size(); k++) + { + nodeElMap[es[j]->m_edgeNodes[k]->m_id].push_back(dataSet[i]); + } + } + + if(m_mesh->m_spaceDim == 3) + { + vector fs = el->GetFaceList(); + for(int j = 0; j < fs.size(); j++) + { + for(int k = 0; k < fs[j]->m_faceNodes.size(); k++) + { + nodeElMap[fs[j]->m_faceNodes[k]->m_id].push_back(dataSet[i]); + } + } } } } void ProcessVarOpti::FillQuadPoints() { - //not all quadrature points are there - //this function adds GLL points to linear edges - EdgeSet::iterator it; - for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + + //this routine is going to take linear or curved egdes and then project + //a set of GLL points onto the system (either way) which is of order of the + //input variable nq + int nq = m_mesh->m_nummode; + LibUtilities::PointsKey ekey(nq,LibUtilities::eGaussLobattoLegendre); + Array gll; + LibUtilities::PointsManager()[ekey]->GetPoints(gll); + EdgeSet::iterator eit; + for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) { - if((*it)->m_edgeNodes.size() > 0) - { - //already high-order ignore - continue; - } + SpatialDomains::Geometry1DSharedPtr geom = (*eit)->GetGeom(m_mesh->m_spaceDim); + geom->FillGeom(); + StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); - //need to fix nummode at some point, set to 5 to match sqcr.xml - LibUtilities::PointsKey ekey(5,LibUtilities::eGaussLobattoLegendre); - Array gll; - LibUtilities::PointsManager()[ekey]->GetPoints(gll); + vector hons; + (*eit)->m_edgeNodes.clear(); - Array > xyi(5 - 2); - for (int k = 1; k < 5 - 1; k++) + switch (m_mesh->m_spaceDim) { - Array xy(2); - xy[0] = (*it)->m_n1->m_x * (1.0 - gll[k]) / 2.0 + - (*it)->m_n2->m_x * (1.0 + gll[k]) / 2.0; - xy[1] = (*it)->m_n1->m_y * (1.0 - gll[k]) / 2.0 + - (*it)->m_n2->m_y * (1.0 + gll[k]) / 2.0; - xyi[k-1] = xy; + case 2: + { + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + + Array xc(nq+1); + Array yc(nq+1); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + + for(int i = 1; i < nq - 1; i++) + { + Array xp(1); + xp[0] = gll[i]; + + hons.push_back(boost::shared_ptr(new Node( + 0,xmap->PhysEvaluate(xp,xc),xmap->PhysEvaluate(xp,yc),0.0))); + } + break; + } + case 3: + { + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); + + Array xc(nq); + Array yc(nq); + Array zc(nq); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + xmap->BwdTrans(coeffs2,zc); + + for(int i = 1; i < nq - 1; i++) + { + Array xp(1); + xp[0] = gll[i]; + + hons.push_back(boost::shared_ptr(new Node( + 0,xmap->PhysEvaluate(xp,xc),xmap->PhysEvaluate(xp,yc), + xmap->PhysEvaluate(xp,zc)))); + } + break; + } } - vector ns; - for(int i = 0; i < xyi.num_elements(); i++) + (*eit)->m_edgeNodes = hons; + (*eit)->m_curveType = LibUtilities::eGaussLobattoLegendre; + } + + if(m_mesh->m_spaceDim == 3) + { + //need to do the same for faces + int np = nq * (nq + 1) / 2; + int ni = (nq-2)*(nq-3) / 2; + FaceSet::iterator fit; + + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + Array u, v; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v); + + vector hons; + (*fit)->m_faceNodes.clear(); + + for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) { - ns.push_back(boost::shared_ptr(new Node(0,xyi[i][0],xyi[i][1],0.0))); - } + SpatialDomains::Geometry2DSharedPtr geom = (*fit)->GetGeom(3); + geom->FillGeom(); + StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); + + Array xc(nq*nq); + Array yc(nq*nq); + Array zc(nq*nq); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + xmap->BwdTrans(coeffs2,zc); + + for(int j = np-ni; j < np; j++) + { + Array xp(2); + xp[0] = u[j]; + xp[1] = v[j]; + + Array xyz(3); + xyz[0] = xmap->PhysEvaluate(xp, xc); + xyz[1] = xmap->PhysEvaluate(xp, yc); + xyz[2] = xmap->PhysEvaluate(xp, zc); - (*it)->m_edgeNodes = ns; - (*it)->m_curveType = LibUtilities::eGaussLobattoLegendre; + hons.push_back(boost::shared_ptr(new Node(0, + xyz[0],xyz[1],xyz[2]))); + } + + (*fit)->m_faceNodes = hons; + (*fit)->m_curveType = LibUtilities::eNodalTriElec; + } } int id = m_mesh->m_vertexSet.size(); //enumerate the curved nodes for mapping purposes - for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) { - vector n; - (*it)->GetCurvedNodes(n); - for(int j = 1; j < n.size()-1; j++) + for(int j = 0; j < (*eit)->m_edgeNodes.size(); j++) { - n[j]->m_id = id++; + (*eit)->m_edgeNodes[j]->m_id = id++; + } + } + if(m_mesh->m_spaceDim == 3) + { + FaceSet::iterator fit; + for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) + { + for(int j = 0; j < (*fit)->m_faceNodes.size(); j++) + { + (*fit)->m_faceNodes[j]->m_id = id++; + } } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index 4d1e7af53..1b1ac15f8 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -47,8 +47,7 @@ namespace Utilities struct ElData { ElementSharedPtr el; - vector maps; - NekDouble lastEval; + vector > maps; }; typedef boost::shared_ptr ElDataSharedPtr; @@ -60,6 +59,13 @@ enum optimiser eHypEl }; +struct Residual +{ + NekDouble val; +}; + +typedef boost::shared_ptr ResidualSharedPtr; + /** * @brief This processing module calculates the Jacobian of elements * using %SpatialDomains::GeomFactors and the %Element::GetGeom @@ -97,8 +103,9 @@ private: class NodeOpti { public: - NodeOpti(NodeSharedPtr n, vector e, optimiser o) - : node(n), data(e), opti(o) + NodeOpti(NodeSharedPtr n, vector e, optimiser o, + ResidualSharedPtr r, int d) + : node(n), data(e), opti(o), res(r), dim(d) { } @@ -115,6 +122,8 @@ private: NodeSharedPtr node; vector data; optimiser opti; + ResidualSharedPtr res; + int dim; }; class NodeOptiJob : public Thread::ThreadJob -- GitLab From c0495a4a4d73877fdae66ba7df521651f4726c60 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Sun, 1 May 2016 13:16:43 +0100 Subject: [PATCH 015/236] working version without getgeom, threading much faster --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 968 +++++++++--------- .../NekMesh/ProcessModules/ProcessVarOpti.h | 11 +- 2 files changed, 492 insertions(+), 487 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 7984982a5..e02e68592 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -45,6 +45,8 @@ #include #include +#include + using namespace std; using namespace Nektar::NekMeshUtils; @@ -55,21 +57,81 @@ namespace Utilities boost::mutex mtx; -inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim) +inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, + NekMatrix &VdmDx, + NekMatrix &VdmDy, + NekVector &quadW) { - SpatialDomains::GeometrySharedPtr geom = d->el->GetGeom(dim); - StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); - LibUtilities::PointsKeyVector p = chi->GetPointsKeys(); - mtx.lock(); - SpatialDomains::GeomFactorsSharedPtr gfac = geom->GetGeomFactors(); + vector ns; + d->el->GetCurvedNodes(ns); + + /*SpatialDomains::GeometrySharedPtr geom = d->el->GetGeom(2); + geom->FillGeom(); + StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); + + LibUtilities::PointsKey pkey(5, + LibUtilities::eNodalTriFekete); + Array u, v; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v); + + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + + vector ns; - mtx.unlock(); - SpatialDomains::DerivStorage deriv = gfac->GetDeriv(p); + for(int j = 0; j < u.num_elements(); j++) + { + Array xp(2); + xp[0] = u[j]; + xp[1] = v[j]; + + ns.push_back(boost::shared_ptr(new Node( + 0,xmap->PhysEvaluate(xp,xc),xmap->PhysEvaluate(xp,yc),0.0))); + }*/ - const int pts = deriv[0][0].num_elements(); + int pts = ns.size(); ASSERTL0(pts == d->maps.size(), "what"); + Array > jac(pts); + + if(dim == 2) + { + NekVector X(pts),Y(pts),x1(pts),y1(pts),x2(pts),y2(pts); + for(int i = 0; i < pts; i++) + { + X(i) = ns[i]->m_x; + Y(i) = ns[i]->m_y; + } + + x1 = VdmDx*X; + y1 = VdmDx*Y; + x2 = VdmDy*X; + y2 = VdmDy*Y; + + for(int i = 0; i < pts; i++) + { + Array jaci(9,0.0); + jaci[0] = x1(i); + jaci[1] = y1(i); + jaci[3] = x2(i); + jaci[4] = y2(i); + jac[i] = jaci; + + } + + } + else + { + ASSERTL0(false,"3d"); + } + Array dW(pts); switch (opti) @@ -78,27 +140,18 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim) { for(int k = 0; k < pts; k++) { - Array jac(9,0.0); - for (int i = 0; i < dim; ++i) - { - for (int j = 0; j < dim; ++j) - { - jac[j+i*3] = deriv[i][j][k]; - } - } - Array jacIdeal(9,0.0); - jacIdeal[0] = jac[0]*d->maps[k][0] + jac[3]*d->maps[k][1] + jac[6]*d->maps[k][2]; - jacIdeal[1] = jac[1]*d->maps[k][0] + jac[4]*d->maps[k][1] + jac[7]*d->maps[k][2]; - jacIdeal[2] = jac[2]*d->maps[k][0] + jac[5]*d->maps[k][1] + jac[8]*d->maps[k][2]; + jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; + jacIdeal[1] = jac[k][1]*d->maps[k][0] + jac[k][4]*d->maps[k][1] + jac[k][7]*d->maps[k][2]; + jacIdeal[2] = jac[k][2]*d->maps[k][0] + jac[k][5]*d->maps[k][1] + jac[k][8]*d->maps[k][2]; - jacIdeal[3] = jac[0]*d->maps[k][3] + jac[3]*d->maps[k][4] + jac[6]*d->maps[k][5]; - jacIdeal[4] = jac[1]*d->maps[k][3] + jac[4]*d->maps[k][4] + jac[7]*d->maps[k][5]; - jacIdeal[5] = jac[2]*d->maps[k][3] + jac[5]*d->maps[k][4] + jac[8]*d->maps[k][5]; + jacIdeal[3] = jac[k][0]*d->maps[k][3] + jac[k][3]*d->maps[k][4] + jac[k][6]*d->maps[k][5]; + jacIdeal[4] = jac[k][1]*d->maps[k][3] + jac[k][4]*d->maps[k][4] + jac[k][7]*d->maps[k][5]; + jacIdeal[5] = jac[k][2]*d->maps[k][3] + jac[k][5]*d->maps[k][4] + jac[k][8]*d->maps[k][5]; - jacIdeal[6] = jac[0]*d->maps[k][6] + jac[3]*d->maps[k][7] + jac[6]*d->maps[k][8]; - jacIdeal[7] = jac[1]*d->maps[k][6] + jac[4]*d->maps[k][7] + jac[7]*d->maps[k][8]; - jacIdeal[8] = jac[2]*d->maps[k][6] + jac[5]*d->maps[k][7] + jac[8]*d->maps[k][8]; + jacIdeal[6] = jac[k][0]*d->maps[k][6] + jac[k][3]*d->maps[k][7] + jac[k][6]*d->maps[k][8]; + jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; + jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; NekDouble a = (jacIdeal[0]*jacIdeal[0]+jacIdeal[1]*jacIdeal[1]+jacIdeal[2]*jacIdeal[2]-1.0)* (jacIdeal[0]*jacIdeal[0]+jacIdeal[1]*jacIdeal[1]+jacIdeal[2]*jacIdeal[2]-1.0); @@ -114,18 +167,21 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim) (jacIdeal[0]*jacIdeal[3]+jacIdeal[1]*jacIdeal[4]+jacIdeal[3]*jacIdeal[5]); NekDouble trEtE = 0.25 * (a+b+c) + 0.5 * (d+e+f); - NekDouble ljacDet; + NekDouble jacDet; if(dim == 2) { - ljacDet = log(jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]); + jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; } else { - ljacDet = log(jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) - -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) - +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4])); + jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) + -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) + +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); + ASSERTL0(false,"need to extend to do i2rmDet in 3d"); } + NekDouble ljacDet = log(jacDet); + NekDouble nu = 0.45; NekDouble mu = 1.0/2.0/(1.0+nu); NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); @@ -138,27 +194,28 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim) { for(int k = 0; k < pts; k++) { - Array jac(9,0.0); - for (int i = 0; i < dim; ++i) - { - for (int j = 0; j < dim; ++j) - { - jac[j+i*3] = deriv[i][j][k]; - } - } - Array jacIdeal(9,0.0); - jacIdeal[0] = jac[0]*d->maps[k][0] + jac[3]*d->maps[k][1] + jac[6]*d->maps[k][2]; - jacIdeal[1] = jac[1]*d->maps[k][0] + jac[4]*d->maps[k][1] + jac[7]*d->maps[k][2]; - jacIdeal[2] = jac[2]*d->maps[k][0] + jac[5]*d->maps[k][1] + jac[8]*d->maps[k][2]; - - jacIdeal[3] = jac[0]*d->maps[k][3] + jac[3]*d->maps[k][4] + jac[6]*d->maps[k][5]; - jacIdeal[4] = jac[1]*d->maps[k][3] + jac[4]*d->maps[k][4] + jac[7]*d->maps[k][5]; - jacIdeal[5] = jac[2]*d->maps[k][3] + jac[5]*d->maps[k][4] + jac[8]*d->maps[k][5]; - - jacIdeal[6] = jac[0]*d->maps[k][6] + jac[3]*d->maps[k][7] + jac[6]*d->maps[k][8]; - jacIdeal[7] = jac[1]*d->maps[k][6] + jac[4]*d->maps[k][7] + jac[7]*d->maps[k][8]; - jacIdeal[8] = jac[2]*d->maps[k][6] + jac[5]*d->maps[k][7] + jac[8]*d->maps[k][8]; + jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; + jacIdeal[1] = jac[k][1]*d->maps[k][0] + jac[k][4]*d->maps[k][1] + jac[k][7]*d->maps[k][2]; + jacIdeal[2] = jac[k][2]*d->maps[k][0] + jac[k][5]*d->maps[k][1] + jac[k][8]*d->maps[k][2]; + + jacIdeal[3] = jac[k][0]*d->maps[k][3] + jac[k][3]*d->maps[k][4] + jac[k][6]*d->maps[k][5]; + jacIdeal[4] = jac[k][1]*d->maps[k][3] + jac[k][4]*d->maps[k][4] + jac[k][7]*d->maps[k][5]; + jacIdeal[5] = jac[k][2]*d->maps[k][3] + jac[k][5]*d->maps[k][4] + jac[k][8]*d->maps[k][5]; + + jacIdeal[6] = jac[k][0]*d->maps[k][6] + jac[k][3]*d->maps[k][7] + jac[k][6]*d->maps[k][8]; + jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; + jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; + + NekDouble I1 = jacIdeal[0]*jacIdeal[0] + + jacIdeal[1]*jacIdeal[1] + + jacIdeal[2]*jacIdeal[2] + + jacIdeal[3]*jacIdeal[3] + + jacIdeal[4]*jacIdeal[4] + + jacIdeal[5]*jacIdeal[5] + + jacIdeal[6]*jacIdeal[6] + + jacIdeal[7]*jacIdeal[7] + + jacIdeal[8]*jacIdeal[8]; NekDouble jacDet; if(dim == 2) @@ -175,8 +232,8 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim) NekDouble ljacDet = log(jacDet); NekDouble nu = 0.45; NekDouble mu = 1.0/2.0/(1.0+nu); - NekDouble lam = nu / (1.0 - 2.0 * nu) / (1.0+nu); - dW[k] = 0.5 * mu * (jacDet * jacDet - 3.0) - mu * ljacDet + 0.5 * lam * ljacDet * ljacDet; + NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + dW[k] = 0.5 * mu * (I1 - 3.0 - 2.0*ljacDet) + 0.5 * K * ljacDet * ljacDet; } break; @@ -185,27 +242,18 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim) { for(int k = 0; k < pts; k++) { - Array jac(9,0.0); - for (int i = 0; i < dim; ++i) - { - for (int j = 0; j < dim; ++j) - { - jac[j+i*3] = deriv[i][j][k]; - } - } - Array jacIdeal(9,0.0); - jacIdeal[0] = jac[0]*d->maps[k][0] + jac[3]*d->maps[k][1] + jac[6]*d->maps[k][2]; - jacIdeal[1] = jac[1]*d->maps[k][0] + jac[4]*d->maps[k][1] + jac[7]*d->maps[k][2]; - jacIdeal[2] = jac[2]*d->maps[k][0] + jac[5]*d->maps[k][1] + jac[8]*d->maps[k][2]; + jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; + jacIdeal[1] = jac[k][1]*d->maps[k][0] + jac[k][4]*d->maps[k][1] + jac[k][7]*d->maps[k][2]; + jacIdeal[2] = jac[k][2]*d->maps[k][0] + jac[k][5]*d->maps[k][1] + jac[k][8]*d->maps[k][2]; - jacIdeal[3] = jac[0]*d->maps[k][3] + jac[3]*d->maps[k][4] + jac[6]*d->maps[k][5]; - jacIdeal[4] = jac[1]*d->maps[k][3] + jac[4]*d->maps[k][4] + jac[7]*d->maps[k][5]; - jacIdeal[5] = jac[2]*d->maps[k][3] + jac[5]*d->maps[k][4] + jac[8]*d->maps[k][5]; + jacIdeal[3] = jac[k][0]*d->maps[k][3] + jac[k][3]*d->maps[k][4] + jac[k][6]*d->maps[k][5]; + jacIdeal[4] = jac[k][1]*d->maps[k][3] + jac[k][4]*d->maps[k][4] + jac[k][7]*d->maps[k][5]; + jacIdeal[5] = jac[k][2]*d->maps[k][3] + jac[k][5]*d->maps[k][4] + jac[k][8]*d->maps[k][5]; - jacIdeal[6] = jac[0]*d->maps[k][6] + jac[3]*d->maps[k][7] + jac[6]*d->maps[k][8]; - jacIdeal[7] = jac[1]*d->maps[k][6] + jac[4]*d->maps[k][7] + jac[7]*d->maps[k][8]; - jacIdeal[8] = jac[2]*d->maps[k][6] + jac[5]*d->maps[k][7] + jac[8]*d->maps[k][8]; + jacIdeal[6] = jac[k][0]*d->maps[k][6] + jac[k][3]*d->maps[k][7] + jac[k][6]*d->maps[k][8]; + jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; + jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; NekDouble jacDet, i2rmDet; if(dim == 2) @@ -244,27 +292,18 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim) { for(int k = 0; k < pts; k++) { - Array jac(9,0.0); - for (int i = 0; i < dim; ++i) - { - for (int j = 0; j < dim; ++j) - { - jac[j+i*3] = deriv[i][j][k]; - } - } - Array jacIdeal(9,0.0); - jacIdeal[0] = jac[0]*d->maps[k][0] + jac[3]*d->maps[k][1] + jac[6]*d->maps[k][2]; - jacIdeal[1] = jac[1]*d->maps[k][0] + jac[4]*d->maps[k][1] + jac[7]*d->maps[k][2]; - jacIdeal[2] = jac[2]*d->maps[k][0] + jac[5]*d->maps[k][1] + jac[8]*d->maps[k][2]; + jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; + jacIdeal[1] = jac[k][1]*d->maps[k][0] + jac[k][4]*d->maps[k][1] + jac[k][7]*d->maps[k][2]; + jacIdeal[2] = jac[k][2]*d->maps[k][0] + jac[k][5]*d->maps[k][1] + jac[k][8]*d->maps[k][2]; - jacIdeal[3] = jac[0]*d->maps[k][3] + jac[3]*d->maps[k][4] + jac[6]*d->maps[k][5]; - jacIdeal[4] = jac[1]*d->maps[k][3] + jac[4]*d->maps[k][4] + jac[7]*d->maps[k][5]; - jacIdeal[5] = jac[2]*d->maps[k][3] + jac[5]*d->maps[k][4] + jac[8]*d->maps[k][5]; + jacIdeal[3] = jac[k][0]*d->maps[k][3] + jac[k][3]*d->maps[k][4] + jac[k][6]*d->maps[k][5]; + jacIdeal[4] = jac[k][1]*d->maps[k][3] + jac[k][4]*d->maps[k][4] + jac[k][7]*d->maps[k][5]; + jacIdeal[5] = jac[k][2]*d->maps[k][3] + jac[k][5]*d->maps[k][4] + jac[k][8]*d->maps[k][5]; - jacIdeal[6] = jac[0]*d->maps[k][6] + jac[3]*d->maps[k][7] + jac[6]*d->maps[k][8]; - jacIdeal[7] = jac[1]*d->maps[k][6] + jac[4]*d->maps[k][7] + jac[7]*d->maps[k][8]; - jacIdeal[8] = jac[2]*d->maps[k][6] + jac[5]*d->maps[k][7] + jac[8]*d->maps[k][8]; + jacIdeal[6] = jac[k][0]*d->maps[k][6] + jac[k][3]*d->maps[k][7] + jac[k][6]*d->maps[k][8]; + jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; + jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; NekDouble jacDet; if(dim == 2) @@ -302,219 +341,12 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim) } } - mtx.lock(); - NekDouble inte = chi->Integral(dW); - mtx.unlock(); - return inte; -} - -inline vector > MappingIdealToRef(SpatialDomains::GeometrySharedPtr geom, - StdRegions::StdExpansionSharedPtr chi) -{ - int dim = geom->GetShapeDim(); - vector > ret; - - if(geom->GetShapeType() == LibUtilities::eQuadrilateral) - { - vector > xy; - for(int i = 0; i < geom->GetNumVerts(); i++) - { - Array loc(2); - SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); - p->GetCoords(loc); - xy.push_back(loc); - } - - Array b = chi->GetBase(); - Array u = b[0]->GetZ(); - Array v = b[1]->GetZ(); - - for(int j = 0; j < b[1]->GetNumPoints(); j++) - { - for(int i = 0; i < b[0]->GetNumPoints(); i++) - { - NekDouble a1 = 0.5*(1.0-u[i]), a2 = 0.5*(1.0+u[i]); - NekDouble b1 = 0.5*(1.0-v[j]), b2 = 0.5*(1.0+v[j]); - DNekMat dxdz(2,2,1.0,eFULL); - - dxdz(0,0) = 0.5*(-b1*xy[0][0] + b1*xy[1][0] + b2*xy[2][0] - b2*xy[3][0]); - dxdz(1,0) = 0.5*(-b1*xy[0][1] + b1*xy[1][1] + b2*xy[2][1] - b2*xy[3][1]); - - dxdz(0,1) = 0.5*(-a1*xy[0][0] - a2*xy[1][0] + a2*xy[2][0] + a1*xy[3][0]); - dxdz(1,1) = 0.5*(-a1*xy[0][1] - a2*xy[1][1] + a2*xy[2][1] + a1*xy[3][1]); - - NekDouble det = 1.0/(dxdz(0,0)*dxdz(1,1) - dxdz(1,0)*dxdz(0,1)); - - dxdz.Invert(); - Array r(9,0.0); - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - ret.push_back(r); - } - } - } - else if(geom->GetShapeType() == LibUtilities::eTriangle) - { - vector > xy; - for(int i = 0; i < geom->GetNumVerts(); i++) - { - Array loc(2); - SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); - p->GetCoords(loc); - xy.push_back(loc); - } - - Array b = chi->GetBase(); - Array u = b[0]->GetZ(); - Array v = b[1]->GetZ(); - - for(int i = 0; i < b[0]->GetNumPoints(); i++) - { - for(int j = 0; j < b[1]->GetNumPoints(); j++) - { - DNekMat dxdz(2,2,1.0,eFULL); - dxdz(0,0) = -xy[0][0]/2.0 + xy[1][0]/2.0; - - dxdz(0,1) = -xy[0][0]/2.0 + xy[2][0]/2.0; - - dxdz(1,0) = -xy[0][1]/2.0 + xy[1][1]/2.0; - - dxdz(1,1) = -xy[0][1]/2.0 + xy[2][1]/2.0; - - dxdz.Invert(); - Array r(9,0.0); - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - ret.push_back(r); - } - } - } - else if(geom->GetShapeType() == LibUtilities::eTetrahedron) - { - vector > xyz; - for(int i = 0; i < geom->GetNumVerts(); i++) - { - Array loc(3); - SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); - p->GetCoords(loc); - xyz.push_back(loc); - } - - Array b = chi->GetBase(); - Array u = b[0]->GetZ(); - Array v = b[1]->GetZ(); - Array z = b[2]->GetZ(); - - for(int i = 0; i < b[0]->GetNumPoints(); i++) - { - for(int j = 0; j < b[1]->GetNumPoints(); j++) - { - for(int k = 0; k < b[2]->GetNumPoints(); k++) - { - DNekMat dxdz(3,3,1.0,eFULL); - dxdz(0,0) = -xyz[0][0]/2.0 + xyz[1][0]/2.0; - - dxdz(0,1) = -xyz[0][0]/2.0 + xyz[2][0]/2.0; - - dxdz(0,2) = -xyz[0][0]/2.0 + xyz[3][0]/2.0; - - - dxdz(1,0) = -xyz[0][1]/2.0 + xyz[1][1]/2.0; - - dxdz(1,1) = -xyz[0][1]/2.0 + xyz[2][1]/2.0; - - dxdz(1,2) = -xyz[0][1]/2.0 + xyz[3][1]/2.0; - - - dxdz(2,0) = -xyz[0][2]/2.0 + xyz[1][2]/2.0; - - dxdz(2,1) = -xyz[0][2]/2.0 + xyz[2][2]/2.0; - - dxdz(2,2) = -xyz[0][2]/2.0 + xyz[3][2]/2.0; - - dxdz.Invert(); - Array r(9,0.0); - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - r[2] = dxdz(2,0); - r[5] = dxdz(2,1); - r[6] = dxdz(0,2); - r[7] = dxdz(1,2); - r[8] = dxdz(2,2); - ret.push_back(r); - } - } - } - } - else if(geom->GetShapeType() == LibUtilities::ePrism) - { - vector > xyz; - for(int i = 0; i < geom->GetNumVerts(); i++) - { - Array loc(3); - SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); - p->GetCoords(loc); - xyz.push_back(loc); - } - - Array b = chi->GetBase(); - Array eta1 = b[0]->GetZ(); - Array eta2 = b[1]->GetZ(); - Array eta3 = b[2]->GetZ(); - - for(int k = 0; k < b[2]->GetNumPoints(); k++) - { - for(int j = 0; j < b[1]->GetNumPoints(); j++) - { - for(int i = 0; i < b[0]->GetNumPoints(); i++) - { - NekDouble xi1 = 0.5*(1+eta1[i])*(1-eta3[k])-1.0; - NekDouble a1 = 0.5*(1-xi1), a2 = 0.5*(1+xi1); - NekDouble b1 = 0.5*(1-eta2[j]), b2 = 0.5*(1+eta2[j]); - NekDouble c1 = 0.5*(1-eta3[k]), c2 = 0.5*(1+eta3[k]); - - DNekMat dxdz(3,3,1.0,eFULL); - - dxdz(0,0) = 0.5*(-b1*xyz[0][0] + b1*xyz[1][0] + b2*xyz[2][0] - b2*xyz[3][0]); - dxdz(1,0) = 0.5*(-b1*xyz[0][1] + b1*xyz[1][1] + b2*xyz[2][1] - b2*xyz[3][1]); - dxdz(2,0) = 0.5*(-b1*xyz[0][2] + b1*xyz[1][2] + b2*xyz[2][2] - b2*xyz[3][2]); - - dxdz(0,1) = 0.5*((a2-c1)*xyz[0][0] - a2*xyz[1][0] + a2*xyz[2][0] + (c1-a2)*xyz[3][0] - c2*xyz[4][0] + c2*xyz[5][0]); - dxdz(1,1) = 0.5*((a2-c1)*xyz[0][1] - a2*xyz[1][1] + a2*xyz[2][1] + (c1-a2)*xyz[3][1] - c2*xyz[4][1] + c2*xyz[5][1]); - dxdz(2,1) = 0.5*((a2-c1)*xyz[0][2] - a2*xyz[1][2] + a2*xyz[2][2] + (c1-a2)*xyz[3][2] - c2*xyz[4][2] + c2*xyz[5][2]); - - dxdz(0,2) = 0.5*(-b1*xyz[0][0] - b2*xyz[3][0] + b1*xyz[4][0] + b2*xyz[5][0]); - dxdz(1,2) = 0.5*(-b1*xyz[0][1] - b2*xyz[3][1] + b1*xyz[4][1] + b2*xyz[5][1]); - dxdz(2,2) = 0.5*(-b1*xyz[0][2] - b2*xyz[3][2] + b1*xyz[4][2] + b2*xyz[5][2]); - - dxdz.Invert(); - Array r(9,0.0); - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - r[2] = dxdz(2,0); - r[5] = dxdz(2,1); - r[6] = dxdz(0,2); - r[7] = dxdz(1,2); - r[8] = dxdz(2,2); - ret.push_back(r); - } - } - } - } - else + NekDouble integral = 0.0; + for(int i = 0; i < dW.num_elements(); i++) { - ASSERTL0(false,"not coded"); + integral += quadW(i) * dW[i]; } - - return ret; + return integral; } ModuleKey ProcessVarOpti::className = GetModuleFactory().RegisterCreatorFunction( @@ -581,10 +413,37 @@ void ProcessVarOpti::Process() FillQuadPoints(); - GetElementMap(); - - vector > freenodes = GetColouredNodes(); - + //build Vandermonde information + switch (m_mesh->m_spaceDim) + { + case 2: + { + LibUtilities::PointsKey pkey(m_mesh->m_nummode, LibUtilities::eNodalTriFekete); + Array u, v; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v); + + NekVector U(u.num_elements()) , V(v.num_elements()); + for(int i = 0; i < u.num_elements(); i++) + { + U(i) = u[i]; + V(i) = v[i]; + } + Vandermonde = LibUtilities::GetVandermonde(U,V); + VandermondeI = Vandermonde; + VandermondeI.Invert(); + VdmDx = LibUtilities::GetVandermondeForXDerivative(U,V) * VandermondeI; + VdmDy = LibUtilities::GetVandermondeForYDerivative(U,V) * VandermondeI; + quadW = LibUtilities::MakeQuadratureWeights(U,V); + } + break; + case 3: + ASSERTL0(false,"vdm not setup for this yet"); + } + + GetElementMap(); + + vector > freenodes = GetColouredNodes(); + ResidualSharedPtr res = boost::shared_ptr(new Residual); res->val = 1.0; @@ -596,7 +455,8 @@ void ProcessVarOpti::Process() { NodeElMap::iterator it = nodeElMap.find(freenodes[i][j]->m_id); ASSERTL0(it != nodeElMap.end(),"could not find"); - ns.push_back(NodeOpti(freenodes[i][j],it->second,opti,res,m_mesh->m_spaceDim)); + ns.push_back(NodeOpti(freenodes[i][j],it->second,opti,res,m_mesh->m_spaceDim, + VdmDx,VdmDy,quadW)); } optiNodes.push_back(ns); } @@ -604,7 +464,8 @@ void ProcessVarOpti::Process() NekDouble functionalStart = 0.0; for(int i = 0; i < m_mesh->m_element[2].size(); i++) { - functionalStart += GetElFunctional(dataSet[i], opti, m_mesh->m_spaceDim); + functionalStart += GetElFunctional(dataSet[i], opti, m_mesh->m_spaceDim, + VdmDx,VdmDy,quadW); } cout << scientific << endl; @@ -643,13 +504,13 @@ void ProcessVarOpti::Process() } cout << ctr << "\tResidual: " << res->val << endl; - } functionalStart = 0.0; for(int i = 0; i < m_mesh->m_element[2].size(); i++) { - functionalStart += GetElFunctional(dataSet[i], opti, m_mesh->m_spaceDim); + functionalStart += GetElFunctional(dataSet[i], opti, m_mesh->m_spaceDim, + VdmDx,VdmDy,quadW); } cout << "end energy: " << functionalStart << endl; } @@ -658,6 +519,7 @@ void ProcessVarOpti::NodeOpti::Optimise() { //it doesnt matter at this point what the dim is so long that //in the 2d case z is left as zero + Array G = GetGrad(); if(sqrt(G[0]*G[0] + G[1]*G[1] + G[2]*G[2]) > 1e-6) @@ -689,7 +551,8 @@ void ProcessVarOpti::NodeOpti::Optimise() node->m_x = xc; node->m_y = yc; node->m_z = zc; - cout << "warning: had to reset node" << endl; + // cout << "warning: had to reset node" << endl; + // cout << G[0] << " " << G[1] << " " << G[2] << " " << node->m_id << endl; } mtx.lock(); res->val += sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ @@ -713,14 +576,14 @@ Array ProcessVarOpti::NodeOpti::GetGrad() for(int i = 0; i < dim * 2; i++) { - node->m_x += dir[i][0] * dx; - node->m_y += dir[i][1] * dx; - node->m_z += dir[i][2] * dx; + node->m_x = xc + dir[i][0] * dx; + node->m_y = yc + dir[i][1] * dx; + node->m_z = zc + dir[i][2] * dx; w.push_back(GetFunctional()); - node->m_x = xc; - node->m_y = yc; - node->m_z = zc; } + node->m_x = xc; + node->m_y = yc; + node->m_z = zc; Array ret(3,0.0); @@ -739,7 +602,7 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() NekDouble r = 0.0; for(int i = 0; i < data.size(); i++) { - r += GetElFunctional(data[i], opti,dim); + r += GetElFunctional(data[i], opti,dim,VdmDx,VdmDy,quadW); } return r; } @@ -749,8 +612,6 @@ vector > ProcessVarOpti::GetColouredNodes() //this figures out the dirclet nodes and colors the others into paralell sets NodeSet boundaryNodes; - vector remain; - switch (m_mesh->m_spaceDim) { case 2: @@ -770,21 +631,6 @@ vector > ProcessVarOpti::GetColouredNodes() boundaryNodes.insert((*it)->m_edgeNodes[i]); } } - - for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) - { - vector n = (*it)->m_edgeNodes; - n.push_back((*it)->m_n1); - n.push_back((*it)->m_n2); - for(int j = 0; j < n.size(); j++) - { - NodeSet::iterator nit = boundaryNodes.find(n[j]); - if(nit == boundaryNodes.end()) - { - remain.push_back(n[j]); - } - } - } break; } case 3: @@ -812,32 +658,48 @@ vector > ProcessVarOpti::GetColouredNodes() } } } + break; + } + default: + ASSERTL0(false,"space dim issue"); + } - for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) + vector remain; + + EdgeSet::iterator eit; + for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) + { + vector n = (*eit)->m_edgeNodes; + n.push_back((*eit)->m_n1); + n.push_back((*eit)->m_n2); + for(int j = 0; j < n.size(); j++) + { + NodeSet::iterator nit = boundaryNodes.find(n[j]); + if(nit == boundaryNodes.end()) { - vector n = (*it)->m_vertexList; + remain.push_back(n[j]); + } + } + } - vector es = (*it)->m_edgeList; - for(int j = 0; j < es.size(); j++) - { - for(int k = 0; k < es[j]->m_edgeNodes.size(); k++) - { - n.push_back(es[j]->m_edgeNodes[k]); - } - } - for(int j = 0; j < n.size(); j++) + if(m_mesh->m_expDim == 2) + { + for(int i = 0; i < m_mesh->m_element[2].size(); i++) + { + vector ns = m_mesh->m_element[2][i]->GetVolumeNodes(); + for(int j = 0; j < ns.size(); j++) + { + NodeSet::iterator nit = boundaryNodes.find(ns[j]); + if(nit == boundaryNodes.end()) { - NodeSet::iterator nit = boundaryNodes.find(n[j]); - if(nit == boundaryNodes.end()) - { - remain.push_back(n[j]); - } + remain.push_back(ns[j]); } } - break; } - default: - ASSERTL0(false,"space dim issue"); + } + else + { + ASSERTL0(false,"3D"); } vector > ret; @@ -896,88 +758,273 @@ void ProcessVarOpti::GetElementMap() ElDataSharedPtr d = boost::shared_ptr(new ElData); d->el = el; - SpatialDomains::GeometrySharedPtr geom = el->GetGeom(m_mesh->m_spaceDim); - StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); + d->maps = MappingIdealToRef(el); - vector basisKeys; + dataSet.push_back(d); + } - for (int i = 0; i < m_mesh->m_expDim; ++i) + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + vector ns; + el->GetCurvedNodes(ns); + + for(int j = 0; j < ns.size(); j++) { - basisKeys.push_back(chi->GetBasis(i)->GetBasisKey()); + nodeElMap[ns[j]->m_id].push_back(dataSet[i]); } + } +} + +vector > ProcessVarOpti::MappingIdealToRef(ElementSharedPtr el) +{ + //need to make ideal element out of old element + ElmtConfig ec = el->GetConf(); + ec.m_order = 1; + ec.m_faceNodes = false; + ec.m_volumeNodes = false; + + ElementSharedPtr E = GetElementFactory().CreateInstance( + ec.m_e, ec, el->GetVertexList(), + el->GetTagList()); + + SpatialDomains::GeometrySharedPtr geom = E->GetGeom(el->GetDim()); + geom->FillGeom(); + StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); + int dim = E->GetDim(); - StdRegions::StdExpansionSharedPtr chiMod; - switch(chi->DetShapeType()) + vector > ret; + + if(geom->GetShapeType() == LibUtilities::eQuadrilateral) + { + ASSERTL0(false,"Not coded"); + /*vector > xy; + for(int i = 0; i < geom->GetNumVerts(); i++) { - case LibUtilities::eTriangle: - chiMod = MemoryManager::AllocateSharedPtr( - basisKeys[0], basisKeys[1]); - break; - case LibUtilities::eQuadrilateral: - chiMod = MemoryManager::AllocateSharedPtr( - basisKeys[0], basisKeys[1]); - break; - case LibUtilities::eTetrahedron: - chiMod = MemoryManager::AllocateSharedPtr( - basisKeys[0], basisKeys[1], basisKeys[2]); - break; - case LibUtilities::ePrism: - chiMod = MemoryManager::AllocateSharedPtr( - basisKeys[0], basisKeys[1], basisKeys[2]); - break; - default: - ASSERTL0(false, "nope"); + Array loc(2); + SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); + p->GetCoords(loc); + xy.push_back(loc); } - d->maps = MappingIdealToRef(geom, chiMod); + Array b = chi->GetBase(); + Array u = b[0]->GetZ(); + Array v = b[1]->GetZ(); - dataSet.push_back(d); - } + for(int j = 0; j < b[1]->GetNumPoints(); j++) + { + for(int i = 0; i < b[0]->GetNumPoints(); i++) + { + NekDouble a1 = 0.5*(1.0-u[i]), a2 = 0.5*(1.0+u[i]); + NekDouble b1 = 0.5*(1.0-v[j]), b2 = 0.5*(1.0+v[j]); + DNekMat dxdz(2,2,1.0,eFULL); - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + dxdz(0,0) = 0.5*(-b1*xy[0][0] + b1*xy[1][0] + b2*xy[2][0] - b2*xy[3][0]); + dxdz(1,0) = 0.5*(-b1*xy[0][1] + b1*xy[1][1] + b2*xy[2][1] - b2*xy[3][1]); + + dxdz(0,1) = 0.5*(-a1*xy[0][0] - a2*xy[1][0] + a2*xy[2][0] + a1*xy[3][0]); + dxdz(1,1) = 0.5*(-a1*xy[0][1] - a2*xy[1][1] + a2*xy[2][1] + a1*xy[3][1]); + + NekDouble det = 1.0/(dxdz(0,0)*dxdz(1,1) - dxdz(1,0)*dxdz(0,1)); + + dxdz.Invert(); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + ret.push_back(r); + } + }*/ + } + else if(geom->GetShapeType() == LibUtilities::eTriangle) { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTriFekete); + Array u, v; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v); + + Array xc(chi->GetTotPoints()); + Array yc(chi->GetTotPoints()); - vector vs = el->GetVertexList(); - for(int j = 0; j < vs.size(); j++) + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + + chi->BwdTrans(coeffs0,xc); + chi->BwdTrans(coeffs1,yc); + + NekVector X(u.num_elements()),Y(u.num_elements()); + for(int j = 0; j < u.num_elements(); j++) { - nodeElMap[vs[j]->m_id].push_back(dataSet[i]); + Array xp(2); + xp[0] = u[j]; + xp[1] = v[j]; + + X(j) = chi->PhysEvaluate(xp, xc); + Y(j) = chi->PhysEvaluate(xp, yc); } - vector es = el->GetEdgeList(); - for(int j = 0; j < es.size(); j++) + NekVector x1 = VdmDx*X; + NekVector y1 = VdmDx*Y; + NekVector x2 = VdmDy*X; + NekVector y2 = VdmDy*Y; + + for(int i = 0 ; i < u.num_elements(); i++) { - for(int k = 0; k < es[j]->m_edgeNodes.size(); k++) + DNekMat dxdz(2,2,1.0,eFULL); + dxdz(0,0) = x1(i); + dxdz(0,1) = x2(i); + dxdz(1,0) = y1(i); + dxdz(1,1) = y2(i); + + dxdz.Invert(); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + ret.push_back(r); + } + } + else if(geom->GetShapeType() == LibUtilities::eTetrahedron) + { + ASSERTL0(false,"not coded"); + /*vector > xyz; + for(int i = 0; i < geom->GetNumVerts(); i++) + { + Array loc(3); + SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); + p->GetCoords(loc); + xyz.push_back(loc); + } + + Array b = chi->GetBase(); + Array u = b[0]->GetZ(); + Array v = b[1]->GetZ(); + Array z = b[2]->GetZ(); + + for(int i = 0; i < b[0]->GetNumPoints(); i++) + { + for(int j = 0; j < b[1]->GetNumPoints(); j++) { - nodeElMap[es[j]->m_edgeNodes[k]->m_id].push_back(dataSet[i]); + for(int k = 0; k < b[2]->GetNumPoints(); k++) + { + DNekMat dxdz(3,3,1.0,eFULL); + dxdz(0,0) = -xyz[0][0]/2.0 + xyz[1][0]/2.0; + + dxdz(0,1) = -xyz[0][0]/2.0 + xyz[2][0]/2.0; + + dxdz(0,2) = -xyz[0][0]/2.0 + xyz[3][0]/2.0; + + + dxdz(1,0) = -xyz[0][1]/2.0 + xyz[1][1]/2.0; + + dxdz(1,1) = -xyz[0][1]/2.0 + xyz[2][1]/2.0; + + dxdz(1,2) = -xyz[0][1]/2.0 + xyz[3][1]/2.0; + + + dxdz(2,0) = -xyz[0][2]/2.0 + xyz[1][2]/2.0; + + dxdz(2,1) = -xyz[0][2]/2.0 + xyz[2][2]/2.0; + + dxdz(2,2) = -xyz[0][2]/2.0 + xyz[3][2]/2.0; + + dxdz.Invert(); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + r[2] = dxdz(2,0); + r[5] = dxdz(2,1); + r[6] = dxdz(0,2); + r[7] = dxdz(1,2); + r[8] = dxdz(2,2); + ret.push_back(r); + } } + }*/ + } + else if(geom->GetShapeType() == LibUtilities::ePrism) + { + ASSERTL0(false, "not coded"); + /*vector > xyz; + for(int i = 0; i < geom->GetNumVerts(); i++) + { + Array loc(3); + SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); + p->GetCoords(loc); + xyz.push_back(loc); } - if(m_mesh->m_spaceDim == 3) + Array b = chi->GetBase(); + Array eta1 = b[0]->GetZ(); + Array eta2 = b[1]->GetZ(); + Array eta3 = b[2]->GetZ(); + + for(int k = 0; k < b[2]->GetNumPoints(); k++) { - vector fs = el->GetFaceList(); - for(int j = 0; j < fs.size(); j++) + + /*for(int j = 0; j < b[1]->GetNumPoints(); j++) { - for(int k = 0; k < fs[j]->m_faceNodes.size(); k++) + for(int i = 0; i < b[0]->GetNumPoints(); i++) { - nodeElMap[fs[j]->m_faceNodes[k]->m_id].push_back(dataSet[i]); + NekDouble xi1 = 0.5*(1+eta1[i])*(1-eta3[k])-1.0; + NekDouble a1 = 0.5*(1-xi1), a2 = 0.5*(1+xi1); + NekDouble b1 = 0.5*(1-eta2[j]), b2 = 0.5*(1+eta2[j]); + NekDouble c1 = 0.5*(1-eta3[k]), c2 = 0.5*(1+eta3[k]); + + DNekMat dxdz(3,3,1.0,eFULL); + + dxdz(0,0) = 0.5*(-b1*xyz[0][0] + b1*xyz[1][0] + b2*xyz[2][0] - b2*xyz[3][0]); + dxdz(1,0) = 0.5*(-b1*xyz[0][1] + b1*xyz[1][1] + b2*xyz[2][1] - b2*xyz[3][1]); + dxdz(2,0) = 0.5*(-b1*xyz[0][2] + b1*xyz[1][2] + b2*xyz[2][2] - b2*xyz[3][2]); + + dxdz(0,1) = 0.5*((a2-c1)*xyz[0][0] - a2*xyz[1][0] + a2*xyz[2][0] + (c1-a2)*xyz[3][0] - c2*xyz[4][0] + c2*xyz[5][0]); + dxdz(1,1) = 0.5*((a2-c1)*xyz[0][1] - a2*xyz[1][1] + a2*xyz[2][1] + (c1-a2)*xyz[3][1] - c2*xyz[4][1] + c2*xyz[5][1]); + dxdz(2,1) = 0.5*((a2-c1)*xyz[0][2] - a2*xyz[1][2] + a2*xyz[2][2] + (c1-a2)*xyz[3][2] - c2*xyz[4][2] + c2*xyz[5][2]); + + dxdz(0,2) = 0.5*(-b1*xyz[0][0] - b2*xyz[3][0] + b1*xyz[4][0] + b2*xyz[5][0]); + dxdz(1,2) = 0.5*(-b1*xyz[0][1] - b2*xyz[3][1] + b1*xyz[4][1] + b2*xyz[5][1]); + dxdz(2,2) = 0.5*(-b1*xyz[0][2] - b2*xyz[3][2] + b1*xyz[4][2] + b2*xyz[5][2]); + + dxdz.Invert(); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + r[2] = dxdz(2,0); + r[5] = dxdz(2,1); + r[6] = dxdz(0,2); + r[7] = dxdz(1,2); + r[8] = dxdz(2,2); + ret.push_back(r); } } - } + }*/ + } + else + { + ASSERTL0(false,"not coded"); } + + return ret; } void ProcessVarOpti::FillQuadPoints() { - - //this routine is going to take linear or curved egdes and then project - //a set of GLL points onto the system (either way) which is of order of the - //input variable nq int nq = m_mesh->m_nummode; - LibUtilities::PointsKey ekey(nq,LibUtilities::eGaussLobattoLegendre); + int id = m_mesh->m_vertexSet.size(); + + LibUtilities::PointsKey ekey(m_mesh->m_nummode, + LibUtilities::eGaussLobattoLegendre); Array gll; LibUtilities::PointsManager()[ekey]->GetPoints(gll); + EdgeSet::iterator eit; + for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) { SpatialDomains::Geometry1DSharedPtr geom = (*eit)->GetGeom(m_mesh->m_spaceDim); @@ -985,7 +1032,6 @@ void ProcessVarOpti::FillQuadPoints() StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); vector hons; - (*eit)->m_edgeNodes.clear(); switch (m_mesh->m_spaceDim) { @@ -994,126 +1040,78 @@ void ProcessVarOpti::FillQuadPoints() Array coeffs0 = geom->GetCoeffs(0); Array coeffs1 = geom->GetCoeffs(1); - Array xc(nq+1); - Array yc(nq+1); + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); xmap->BwdTrans(coeffs0,xc); xmap->BwdTrans(coeffs1,yc); - for(int i = 1; i < nq - 1; i++) + for(int j = 1; j < m_mesh->m_nummode - 1; j++) { - Array xp(1); - xp[0] = gll[i]; + Array xp(2); + xp[0] = gll[j]; hons.push_back(boost::shared_ptr(new Node( - 0,xmap->PhysEvaluate(xp,xc),xmap->PhysEvaluate(xp,yc),0.0))); + id++,xmap->PhysEvaluate(xp,xc),xmap->PhysEvaluate(xp,yc),0.0))); } - break; + (*eit)->m_edgeNodes.clear(); + (*eit)->m_edgeNodes = hons; + (*eit)->m_curveType = LibUtilities::eGaussLobattoLegendre; } + break; case 3: { - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - Array coeffs2 = geom->GetCoeffs(2); - - Array xc(nq); - Array yc(nq); - Array zc(nq); - - xmap->BwdTrans(coeffs0,xc); - xmap->BwdTrans(coeffs1,yc); - xmap->BwdTrans(coeffs2,zc); - - for(int i = 1; i < nq - 1; i++) - { - Array xp(1); - xp[0] = gll[i]; - - hons.push_back(boost::shared_ptr(new Node( - 0,xmap->PhysEvaluate(xp,xc),xmap->PhysEvaluate(xp,yc), - xmap->PhysEvaluate(xp,zc)))); - } - break; + ASSERTL0(false,"need to do 3d"); } } - - (*eit)->m_edgeNodes = hons; - (*eit)->m_curveType = LibUtilities::eGaussLobattoLegendre; } - if(m_mesh->m_spaceDim == 3) + if(m_mesh->m_expDim == 2) { - //need to do the same for faces - int np = nq * (nq + 1) / 2; - int ni = (nq-2)*(nq-3) / 2; - FaceSet::iterator fit; - - LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriElec); - Array u, v; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v); - - vector hons; - (*fit)->m_faceNodes.clear(); - - for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) + //for faces need to do volume nodes + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { - SpatialDomains::Geometry2DSharedPtr geom = (*fit)->GetGeom(3); + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + + SpatialDomains::GeometrySharedPtr geom = el->GetGeom(m_mesh->m_spaceDim); geom->FillGeom(); StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); + + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + Array u, v; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v); + Array coeffs0 = geom->GetCoeffs(0); Array coeffs1 = geom->GetCoeffs(1); - Array coeffs2 = geom->GetCoeffs(2); - Array xc(nq*nq); - Array yc(nq*nq); - Array zc(nq*nq); + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); xmap->BwdTrans(coeffs0,xc); xmap->BwdTrans(coeffs1,yc); - xmap->BwdTrans(coeffs2,zc); - for(int j = np-ni; j < np; j++) + vector hons; + + for(int j = nq * (nq + 1) / 2 - (nq-2)*(nq-3) / 2; j < u.num_elements(); j++) { Array xp(2); xp[0] = u[j]; xp[1] = v[j]; - Array xyz(3); - xyz[0] = xmap->PhysEvaluate(xp, xc); - xyz[1] = xmap->PhysEvaluate(xp, yc); - xyz[2] = xmap->PhysEvaluate(xp, zc); - - hons.push_back(boost::shared_ptr(new Node(0, - xyz[0],xyz[1],xyz[2]))); + hons.push_back(boost::shared_ptr(new Node( + id++,xmap->PhysEvaluate(xp,xc),xmap->PhysEvaluate(xp,yc),0.0))); } - (*fit)->m_faceNodes = hons; - (*fit)->m_curveType = LibUtilities::eNodalTriElec; + el->SetVolumeNodes(hons); + el->SetCurveType(LibUtilities::eNodalTriElec); } } - - int id = m_mesh->m_vertexSet.size(); - //enumerate the curved nodes for mapping purposes - for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) - { - for(int j = 0; j < (*eit)->m_edgeNodes.size(); j++) - { - (*eit)->m_edgeNodes[j]->m_id = id++; - } - } - if(m_mesh->m_spaceDim == 3) + else { - FaceSet::iterator fit; - for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) - { - for(int j = 0; j < (*fit)->m_faceNodes.size(); j++) - { - (*fit)->m_faceNodes[j]->m_id = id++; - } - } + //need to do face set iterator in 3d + //then volume nodes over elements } - } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index 1b1ac15f8..e59a7d761 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -92,11 +92,14 @@ private: void FillQuadPoints(); void GetElementMap(); + vector > MappingIdealToRef(ElementSharedPtr el); vector > GetColouredNodes(); NodeElMap nodeElMap; vector dataSet; optimiser opti; + NekMatrix Vandermonde, VandermondeI, VdmDx, VdmDy; + NekVector quadW; class NodeOptiJob; @@ -104,8 +107,10 @@ private: { public: NodeOpti(NodeSharedPtr n, vector e, optimiser o, - ResidualSharedPtr r, int d) - : node(n), data(e), opti(o), res(r), dim(d) + ResidualSharedPtr r, int d, + NekMatrix &vx, NekMatrix &vy, + NekVector &w) + : node(n), data(e), opti(o), res(r), dim(d), VdmDx(vx), VdmDy(vy), quadW(w) { } @@ -124,6 +129,8 @@ private: optimiser opti; ResidualSharedPtr res; int dim; + NekMatrix VdmDx, VdmDy; + NekVector quadW; }; class NodeOptiJob : public Thread::ThreadJob -- GitLab From 578c529d73d790f3c71b49618f30d02f70c2e1e5 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 2 May 2016 11:37:16 +0100 Subject: [PATCH 016/236] tweak outputnekpp to do volume curvature in 2D --- utilities/NekMesh/OutputModules/OutputNekpp.cpp | 4 ++-- utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/utilities/NekMesh/OutputModules/OutputNekpp.cpp b/utilities/NekMesh/OutputModules/OutputNekpp.cpp index 1800dc0d4..ce05412a5 100644 --- a/utilities/NekMesh/OutputModules/OutputNekpp.cpp +++ b/utilities/NekMesh/OutputModules/OutputNekpp.cpp @@ -679,7 +679,7 @@ void OutputNekpp::WriteXmlCurves(TiXmlElement *pRoot) } } // 2D elements in 3-space, output face curvature information - else if (m_mesh->m_expDim == 2 && m_mesh->m_spaceDim == 3) + else if (m_mesh->m_expDim == 2 && m_mesh->m_spaceDim >= 2) { vector::iterator it; for (it = m_mesh->m_element[m_mesh->m_expDim].begin(); @@ -831,7 +831,7 @@ void OutputNekpp::WriteXmlCurves(TiXmlElement *pRoot) } } // 2D elements in 3-space, output face curvature information - else if (m_mesh->m_expDim == 2 && m_mesh->m_spaceDim == 3) + else if (m_mesh->m_expDim == 2 && m_mesh->m_spaceDim >= 2) { vector::iterator it; for (it = m_mesh->m_element[m_mesh->m_expDim].begin(); diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index e02e68592..dc1ddb7ea 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -1078,7 +1078,7 @@ void ProcessVarOpti::FillQuadPoints() StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriElec); + LibUtilities::eNodalTriFekete); Array u, v; LibUtilities::PointsManager()[pkey]->GetPoints(u, v); @@ -1104,7 +1104,7 @@ void ProcessVarOpti::FillQuadPoints() } el->SetVolumeNodes(hons); - el->SetCurveType(LibUtilities::eNodalTriElec); + el->SetCurveType(LibUtilities::eNodalTriFekete); } } else -- GitLab From b93db0cc1639c1f6c824321d288127327e9cc404 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 2 May 2016 12:12:31 +0100 Subject: [PATCH 017/236] add some more 3D stuff in --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 277 ++++++++++++++---- .../NekMesh/ProcessModules/ProcessVarOpti.h | 2 +- 2 files changed, 217 insertions(+), 62 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index dc1ddb7ea..de8ce7f4e 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -418,7 +418,8 @@ void ProcessVarOpti::Process() { case 2: { - LibUtilities::PointsKey pkey(m_mesh->m_nummode, LibUtilities::eNodalTriFekete); + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTriFekete); Array u, v; LibUtilities::PointsManager()[pkey]->GetPoints(u, v); @@ -431,13 +432,40 @@ void ProcessVarOpti::Process() Vandermonde = LibUtilities::GetVandermonde(U,V); VandermondeI = Vandermonde; VandermondeI.Invert(); - VdmDx = LibUtilities::GetVandermondeForXDerivative(U,V) * VandermondeI; - VdmDy = LibUtilities::GetVandermondeForYDerivative(U,V) * VandermondeI; + VdmDx = LibUtilities::GetVandermondeForXDerivative(U,V) * + VandermondeI; + VdmDy = LibUtilities::GetVandermondeForYDerivative(U,V) * + VandermondeI; quadW = LibUtilities::MakeQuadratureWeights(U,V); } break; case 3: - ASSERTL0(false,"vdm not setup for this yet"); + { + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + Array u, v, w; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); + + NekVector U(u.num_elements()) , V(v.num_elements()), + W(u.num_elements()); + for(int i = 0; i < u.num_elements(); i++) + { + U(i) = u[i]; + V(i) = v[i]; + W(i) = w[i]; + } + Vandermonde = LibUtilities::GetTetVandermonde(U,V,W); + VandermondeI = Vandermonde; + VandermondeI.Invert(); + VdmDx = LibUtilities::GetVandermondeForTetXDerivative(U,V,W) * + VandermondeI; + VdmDy = LibUtilities::GetVandermondeForTetYDerivative(U,V,W) * + VandermondeI; + VdmDz = LibUtilities::GetVandermondeForTetZDerivative(U,V,W) * + VandermondeI; + quadW = LibUtilities::MakeTetWeights(U,V,W); + ASSERTL0(false,"vdm not setup for this yet, because quad weights are wrong"); + } } GetElementMap(); @@ -888,63 +916,73 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP } else if(geom->GetShapeType() == LibUtilities::eTetrahedron) { - ASSERTL0(false,"not coded"); - /*vector > xyz; - for(int i = 0; i < geom->GetNumVerts(); i++) - { - Array loc(3); - SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); - p->GetCoords(loc); - xyz.push_back(loc); - } - - Array b = chi->GetBase(); - Array u = b[0]->GetZ(); - Array v = b[1]->GetZ(); - Array z = b[2]->GetZ(); - - for(int i = 0; i < b[0]->GetNumPoints(); i++) - { - for(int j = 0; j < b[1]->GetNumPoints(); j++) - { - for(int k = 0; k < b[2]->GetNumPoints(); k++) - { - DNekMat dxdz(3,3,1.0,eFULL); - dxdz(0,0) = -xyz[0][0]/2.0 + xyz[1][0]/2.0; - - dxdz(0,1) = -xyz[0][0]/2.0 + xyz[2][0]/2.0; - - dxdz(0,2) = -xyz[0][0]/2.0 + xyz[3][0]/2.0; - + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + Array u, v, w; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); - dxdz(1,0) = -xyz[0][1]/2.0 + xyz[1][1]/2.0; + Array xc(chi->GetTotPoints()); + Array yc(chi->GetTotPoints()); + Array zc(chi->GetTotPoints()); - dxdz(1,1) = -xyz[0][1]/2.0 + xyz[2][1]/2.0; + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); - dxdz(1,2) = -xyz[0][1]/2.0 + xyz[3][1]/2.0; + chi->BwdTrans(coeffs0,xc); + chi->BwdTrans(coeffs1,yc); + chi->BwdTrans(coeffs2,yc); + NekVector X(u.num_elements()),Y(u.num_elements()), + Z(u.num_elements()); + for(int j = 0; j < u.num_elements(); j++) + { + Array xp(3); + xp[0] = u[j]; + xp[1] = v[j]; + xp[1] = w[j]; - dxdz(2,0) = -xyz[0][2]/2.0 + xyz[1][2]/2.0; + X(j) = chi->PhysEvaluate(xp, xc); + Y(j) = chi->PhysEvaluate(xp, yc); + Z(j) = chi->PhysEvaluate(xp, zc); + } - dxdz(2,1) = -xyz[0][2]/2.0 + xyz[2][2]/2.0; + NekVector x1 = VdmDx*X; + NekVector y1 = VdmDx*Y; + NekVector z1 = VdmDx*Z; + NekVector x2 = VdmDy*X; + NekVector y2 = VdmDy*Y; + NekVector z2 = VdmDy*Z; + NekVector x3 = VdmDz*X; + NekVector y3 = VdmDz*Y; + NekVector z3 = VdmDz*Z; - dxdz(2,2) = -xyz[0][2]/2.0 + xyz[3][2]/2.0; + for(int i = 0 ; i < u.num_elements(); i++) + { + DNekMat dxdz(3,3,1.0,eFULL); + dxdz(0,0) = x1(i); + dxdz(0,1) = x2(i); + dxdz(0,2) = x3(i); + dxdz(1,0) = y1(i); + dxdz(1,1) = y2(i); + dxdz(1,2) = y3(i); + dxdz(2,0) = z1(i); + dxdz(2,1) = z2(i); + dxdz(2,2) = z3(i); - dxdz.Invert(); - Array r(9,0.0); - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - r[2] = dxdz(2,0); - r[5] = dxdz(2,1); - r[6] = dxdz(0,2); - r[7] = dxdz(1,2); - r[8] = dxdz(2,2); - ret.push_back(r); - } - } - }*/ + dxdz.Invert(); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[2] = dxdz(2,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + r[5] = dxdz(2,1); + r[6] = dxdz(0,2); + r[7] = dxdz(1,2); + r[8] = dxdz(2,2); + ret.push_back(r); + } } else if(geom->GetShapeType() == LibUtilities::ePrism) { @@ -1027,7 +1065,8 @@ void ProcessVarOpti::FillQuadPoints() for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) { - SpatialDomains::Geometry1DSharedPtr geom = (*eit)->GetGeom(m_mesh->m_spaceDim); + SpatialDomains::Geometry1DSharedPtr geom = + (*eit)->GetGeom(m_mesh->m_spaceDim); geom->FillGeom(); StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); @@ -1052,7 +1091,8 @@ void ProcessVarOpti::FillQuadPoints() xp[0] = gll[j]; hons.push_back(boost::shared_ptr(new Node( - id++,xmap->PhysEvaluate(xp,xc),xmap->PhysEvaluate(xp,yc),0.0))); + id++,xmap->PhysEvaluate(xp,xc), + xmap->PhysEvaluate(xp,yc),0.0))); } (*eit)->m_edgeNodes.clear(); (*eit)->m_edgeNodes = hons; @@ -1061,8 +1101,33 @@ void ProcessVarOpti::FillQuadPoints() break; case 3: { - ASSERTL0(false,"need to do 3d"); + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); + + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); + Array zc(xmap->GetTotPoints()); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + xmap->BwdTrans(coeffs2,zc); + + for(int j = 1; j < m_mesh->m_nummode - 1; j++) + { + Array xp(2); + xp[0] = gll[j]; + + hons.push_back(boost::shared_ptr(new Node( + id++,xmap->PhysEvaluate(xp,xc), + xmap->PhysEvaluate(xp,yc), + xmap->PhysEvaluate(xp,zc)))); + } + (*eit)->m_edgeNodes.clear(); + (*eit)->m_edgeNodes = hons; + (*eit)->m_curveType = LibUtilities::eGaussLobattoLegendre; } + break; } } @@ -1073,7 +1138,8 @@ void ProcessVarOpti::FillQuadPoints() { ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - SpatialDomains::GeometrySharedPtr geom = el->GetGeom(m_mesh->m_spaceDim); + SpatialDomains::GeometrySharedPtr geom = + el->GetGeom(m_mesh->m_spaceDim); geom->FillGeom(); StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); @@ -1093,14 +1159,16 @@ void ProcessVarOpti::FillQuadPoints() vector hons; - for(int j = nq * (nq + 1) / 2 - (nq-2)*(nq-3) / 2; j < u.num_elements(); j++) + for(int j = nq * (nq + 1) / 2 - (nq-2)*(nq-3) / 2; + j < u.num_elements(); j++) { Array xp(2); xp[0] = u[j]; xp[1] = v[j]; hons.push_back(boost::shared_ptr(new Node( - id++,xmap->PhysEvaluate(xp,xc),xmap->PhysEvaluate(xp,yc),0.0))); + id++,xmap->PhysEvaluate(xp,xc), + xmap->PhysEvaluate(xp,yc),0.0))); } el->SetVolumeNodes(hons); @@ -1109,8 +1177,95 @@ void ProcessVarOpti::FillQuadPoints() } else { - //need to do face set iterator in 3d - //then volume nodes over elements + FaceSet::iterator it; + for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) + { + SpatialDomains::Geometry2DSharedPtr geom = + (*it)->GetGeom(m_mesh->m_spaceDim); + geom->FillGeom(); + StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); + + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTriFekete); + Array u, v; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v); + + vector hons; + + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); + + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); + Array zc(xmap->GetTotPoints()); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + xmap->BwdTrans(coeffs2,zc); + + for(int j = nq * (nq + 1) / 2 - (nq-2)*(nq-3) / 2; + j < u.num_elements(); j++) + { + Array xp(2); + xp[0] = u[j]; + xp[1] = v[j]; + + hons.push_back(boost::shared_ptr(new Node( + id++,xmap->PhysEvaluate(xp,xc), + xmap->PhysEvaluate(xp,yc), + xmap->PhysEvaluate(xp,zc)))); + } + (*it)->m_faceNodes.clear(); + (*it)->m_faceNodes = hons; + (*it)->m_curveType = LibUtilities::eNodalTriFekete; + } + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + + SpatialDomains::GeometrySharedPtr geom = + el->GetGeom(m_mesh->m_spaceDim); + geom->FillGeom(); + StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); + + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + Array u, v, w; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); + + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); + + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); + Array zc(xmap->GetTotPoints()); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + xmap->BwdTrans(coeffs2,zc); + + vector hons; + + //need to finish for tet + ASSERTL0(false,"need to finish 3D"); + + /*for(int j = nq * (nq + 1) / 2 - (nq-2)*(nq-3) / 2; + j < u.num_elements(); j++) + { + Array xp(2); + xp[0] = u[j]; + xp[1] = v[j]; + + hons.push_back(boost::shared_ptr(new Node( + id++,xmap->PhysEvaluate(xp,xc), + xmap->PhysEvaluate(xp,yc),0.0))); + } + + el->SetVolumeNodes(hons); + el->SetCurveType(LibUtilities::eNodalTriFekete);*/ + } } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index e59a7d761..6a0db0abd 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -98,7 +98,7 @@ private: NodeElMap nodeElMap; vector dataSet; optimiser opti; - NekMatrix Vandermonde, VandermondeI, VdmDx, VdmDy; + NekMatrix Vandermonde, VandermondeI, VdmDx, VdmDy, VdmDz; NekVector quadW; class NodeOptiJob; -- GitLab From 6ec2e31de7e60ac23d4579d1a3ec2ee951e22aa0 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 2 May 2016 13:55:58 +0100 Subject: [PATCH 018/236] more 3D --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 90 ++++++++++--------- .../NekMesh/ProcessModules/ProcessVarOpti.h | 6 +- 2 files changed, 52 insertions(+), 44 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index de8ce7f4e..2bbc547f6 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -60,41 +60,12 @@ boost::mutex mtx; inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, NekMatrix &VdmDx, NekMatrix &VdmDy, + NekMatrix &VdmDz, NekVector &quadW) { vector ns; d->el->GetCurvedNodes(ns); - /*SpatialDomains::GeometrySharedPtr geom = d->el->GetGeom(2); - geom->FillGeom(); - StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); - - LibUtilities::PointsKey pkey(5, - LibUtilities::eNodalTriFekete); - Array u, v; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v); - - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - - Array xc(xmap->GetTotPoints()); - Array yc(xmap->GetTotPoints()); - - xmap->BwdTrans(coeffs0,xc); - xmap->BwdTrans(coeffs1,yc); - - vector ns; - - for(int j = 0; j < u.num_elements(); j++) - { - Array xp(2); - xp[0] = u[j]; - xp[1] = v[j]; - - ns.push_back(boost::shared_ptr(new Node( - 0,xmap->PhysEvaluate(xp,xc),xmap->PhysEvaluate(xp,yc),0.0))); - }*/ - int pts = ns.size(); ASSERTL0(pts == d->maps.size(), "what"); @@ -103,7 +74,9 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, if(dim == 2) { - NekVector X(pts),Y(pts),x1(pts),y1(pts),x2(pts),y2(pts); + NekVector X(pts),Y(pts),Z(pts), + x1(pts),y1(pts), + x2(pts),y2(pts); for(int i = 0; i < pts; i++) { X(i) = ns[i]->m_x; @@ -129,7 +102,42 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } else { - ASSERTL0(false,"3d"); + NekVector X(pts),Y(pts),Z(pts), + x1(pts),y1(pts),z1(pts), + x2(pts),y2(pts),z2(pts), + x3(pts),y3(pts),z3(pts); + for(int i = 0; i < pts; i++) + { + X(i) = ns[i]->m_x; + Y(i) = ns[i]->m_y; + Z(i) = ns[i]->m_z; + } + + x1 = VdmDx*X; + y1 = VdmDx*Y; + z1 = VdmDx*Z; + x2 = VdmDy*X; + y2 = VdmDy*Y; + z2 = VdmDy*Z; + x3 = VdmDz*X; + y3 = VdmDz*Y; + z3 = VdmDz*Z; + + for(int i = 0; i < pts; i++) + { + Array jaci(9,0.0); + jaci[0] = x1(i); + jaci[1] = y1(i); + jaci[2] = z1(i); + jaci[3] = x2(i); + jaci[4] = y2(i); + jaci[5] = z2(i); + jaci[6] = x3(i); + jaci[7] = y3(i); + jaci[8] = z3(i); + jac[i] = jaci; + + } } Array dW(pts); @@ -177,7 +185,6 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - ASSERTL0(false,"need to extend to do i2rmDet in 3d"); } NekDouble ljacDet = log(jacDet); @@ -255,7 +262,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; - NekDouble jacDet, i2rmDet; + NekDouble jacDet, i2rmDet = 0.0; if(dim == 2) { jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; @@ -315,7 +322,6 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - ASSERTL0(false,"need to extend to do i2rmDet in 3d"); } if(jacDet < 1E-10) @@ -484,7 +490,7 @@ void ProcessVarOpti::Process() NodeElMap::iterator it = nodeElMap.find(freenodes[i][j]->m_id); ASSERTL0(it != nodeElMap.end(),"could not find"); ns.push_back(NodeOpti(freenodes[i][j],it->second,opti,res,m_mesh->m_spaceDim, - VdmDx,VdmDy,quadW)); + VdmDx,VdmDy,VdmDz,quadW)); } optiNodes.push_back(ns); } @@ -493,7 +499,7 @@ void ProcessVarOpti::Process() for(int i = 0; i < m_mesh->m_element[2].size(); i++) { functionalStart += GetElFunctional(dataSet[i], opti, m_mesh->m_spaceDim, - VdmDx,VdmDy,quadW); + VdmDx,VdmDy,VdmDz,quadW); } cout << scientific << endl; @@ -504,7 +510,8 @@ void ProcessVarOpti::Process() int ctr = 0; Thread::ThreadMaster tms; tms.SetThreadingType("ThreadManagerBoost"); - Thread::ThreadManagerSharedPtr tm = tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads); + Thread::ThreadManagerSharedPtr tm = + tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads); while (res->val > 1e-3) { @@ -538,7 +545,7 @@ void ProcessVarOpti::Process() for(int i = 0; i < m_mesh->m_element[2].size(); i++) { functionalStart += GetElFunctional(dataSet[i], opti, m_mesh->m_spaceDim, - VdmDx,VdmDy,quadW); + VdmDx,VdmDy,VdmDz,quadW); } cout << "end energy: " << functionalStart << endl; } @@ -630,7 +637,7 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() NekDouble r = 0.0; for(int i = 0; i < data.size(); i++) { - r += GetElFunctional(data[i], opti,dim,VdmDx,VdmDy,quadW); + r += GetElFunctional(data[i], opti,dim,VdmDx,VdmDy,VdmDz,quadW); } return r; } @@ -819,7 +826,6 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP SpatialDomains::GeometrySharedPtr geom = E->GetGeom(el->GetDim()); geom->FillGeom(); StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); - int dim = E->GetDim(); vector > ret; @@ -1004,7 +1010,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP for(int k = 0; k < b[2]->GetNumPoints(); k++) { - /*for(int j = 0; j < b[1]->GetNumPoints(); j++) + for(int j = 0; j < b[1]->GetNumPoints(); j++) { for(int i = 0; i < b[0]->GetNumPoints(); i++) { diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index 6a0db0abd..8318f49b1 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -109,8 +109,10 @@ private: NodeOpti(NodeSharedPtr n, vector e, optimiser o, ResidualSharedPtr r, int d, NekMatrix &vx, NekMatrix &vy, + NekMatrix &vz, NekVector &w) - : node(n), data(e), opti(o), res(r), dim(d), VdmDx(vx), VdmDy(vy), quadW(w) + : node(n), data(e), opti(o), res(r), dim(d), + VdmDx(vx), VdmDy(vy), VdmDz(vz), quadW(w) { } @@ -129,7 +131,7 @@ private: optimiser opti; ResidualSharedPtr res; int dim; - NekMatrix VdmDx, VdmDy; + NekMatrix VdmDx, VdmDy, VdmDz; NekVector quadW; }; -- GitLab From fbb9fe7f6fbc7199c03fe017650099c2f45c1c71 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 2 May 2016 15:55:23 +0100 Subject: [PATCH 019/236] stats module --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 58 +++++++++++++++++++ .../NekMesh/ProcessModules/ProcessVarOpti.h | 1 + 2 files changed, 59 insertions(+) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 2bbc547f6..36359b15b 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -374,6 +374,8 @@ ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) ConfigOption(false, "1", "Number of threads"); m_config["nq"] = ConfigOption(false, "0", "Number of quad points"); + m_config["stats"] = + ConfigOption(false, "", "Write a file with list of scaled jacobians"); } ProcessVarOpti::~ProcessVarOpti() @@ -548,6 +550,13 @@ void ProcessVarOpti::Process() VdmDx,VdmDy,VdmDz,quadW); } cout << "end energy: " << functionalStart << endl; + + if(m_config["stats"].beenSet) + { + string file = m_config["stats"].as(); + cout << "writing stats to " << file.c_str() << endl; + WriteStats(file); + } } void ProcessVarOpti::NodeOpti::Optimise() @@ -1275,5 +1284,54 @@ void ProcessVarOpti::FillQuadPoints() } } +void ProcessVarOpti::WriteStats(string file) +{ + ASSERTL0(file != "", "no file name given"); + + ofstream out; + out.open(file.c_str()); + out << scientific; + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + vector ns; + m_mesh->m_element[m_mesh->m_expDim][i]->GetCurvedNodes(ns); + int pts = ns.size(); + int dim = m_mesh->m_element[m_mesh->m_expDim][i]->GetDim(); + + NekDouble mx = -1.0 * numeric_limits::max(); + NekDouble mn = numeric_limits::max(); + + if(dim == 2) + { + NekVector X(pts),Y(pts),Z(pts), + x1(pts),y1(pts), + x2(pts),y2(pts); + for(int i = 0; i < pts; i++) + { + X(i) = ns[i]->m_x; + Y(i) = ns[i]->m_y; + } + + x1 = VdmDx*X; + y1 = VdmDx*Y; + x2 = VdmDy*X; + y2 = VdmDy*Y; + + for(int i = 0; i < pts; i++) + { + mx = max(mx, x1(i)*y2(i)-y1(i)*x2(i)); + mn = min(mn, x1(i)*y2(i)-y1(i)*x2(i)); + } + + } + else + { + ASSERTL0(false,"not coded"); + } + out << mn / mx << endl; + } +} + } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index 8318f49b1..0ee82bf44 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -94,6 +94,7 @@ private: void GetElementMap(); vector > MappingIdealToRef(ElementSharedPtr el); vector > GetColouredNodes(); + void WriteStats(string file); NodeElMap nodeElMap; vector dataSet; -- GitLab From b792f9e9a338f5c9f7997fa6dfd36d14114d3751 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Wed, 4 May 2016 20:08:20 +0100 Subject: [PATCH 020/236] lots of code to get tets working --- .../LibUtilities/Foundations/NodalTetElec.cpp | 449 +++++++++++++++++- library/NekMeshUtils/MeshElements/Element.h | 216 +++++++++ library/NekMeshUtils/MeshElements/Triangle.h | 135 ------ .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 273 ++++++++--- 4 files changed, 855 insertions(+), 218 deletions(-) diff --git a/library/LibUtilities/Foundations/NodalTetElec.cpp b/library/LibUtilities/Foundations/NodalTetElec.cpp index 15a49b767..ae3336aab 100644 --- a/library/LibUtilities/Foundations/NodalTetElec.cpp +++ b/library/LibUtilities/Foundations/NodalTetElec.cpp @@ -28,7 +28,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// +// // Description: 3D Nodal Tet Electrostatic Point Definitions // /////////////////////////////////////////////////////////////////////////////// @@ -42,12 +42,12 @@ namespace Nektar { - namespace LibUtilities + namespace LibUtilities { - + // //////////////////////////////////////////////////////// // Coordinate the nodal tetrahedron electrostatic points - + void NodalTetElec::CalculatePoints() { // Allocate the storage for points @@ -80,7 +80,7 @@ namespace Nektar continue; }//end symmetry 1 - + // 4 Point symmetry: aaab or abbb if(int(NodalTetElecData[index][1])) { @@ -89,7 +89,7 @@ namespace Nektar b = NodalTetElecData[index][offset + perm4_3d[j][1]]; c = NodalTetElecData[index][offset + perm4_3d[j][2]]; d = NodalTetElecData[index][offset + perm4_3d[j][3]]; - + m_points[0][isum] = 2.0*b - 1.0; m_points[1][isum] = 2.0*c - 1.0; m_points[2][isum] = 2.0*d - 1.0; @@ -98,7 +98,7 @@ namespace Nektar continue; }//end symmetry 4 - + // 6 Point symmetry: aabb if(int(NodalTetElecData[index][2])) { @@ -107,15 +107,15 @@ namespace Nektar b = NodalTetElecData[index][offset + perm6_3d[j][1]]; c = NodalTetElecData[index][offset + perm6_3d[j][2]]; d = NodalTetElecData[index][offset + perm6_3d[j][3]]; - + m_points[0][isum] = 2.0*b - 1.0; m_points[1][isum] = 2.0*c - 1.0; m_points[2][isum] = 2.0*d - 1.0; isum++; }//end j - continue; - }//end symmetry6 - + continue; + }//end symmetry6 + // 12 Point symmetry: case aabc if(int(NodalTetElecData[index][3]) == 1) @@ -125,7 +125,7 @@ namespace Nektar b = NodalTetElecData[index][offset + perm12A_3d[j][1]]; c = NodalTetElecData[index][offset + perm12A_3d[j][2]]; d = NodalTetElecData[index][offset + perm12A_3d[j][3]]; - + m_points[0][isum] = 2.0*b - 1.0; m_points[1][isum] = 2.0*c - 1.0; m_points[2][isum] = 2.0*d - 1.0; @@ -134,7 +134,7 @@ namespace Nektar continue; }//end symmetry 12 aabc - + // 12 Point symmetry: case abcc if(int(NodalTetElecData[index][3]) == 2) { @@ -143,7 +143,7 @@ namespace Nektar b = NodalTetElecData[index][offset + perm12B_3d[j][1]]; c = NodalTetElecData[index][offset + perm12B_3d[j][2]]; d = NodalTetElecData[index][offset + perm12B_3d[j][3]]; - + m_points[0][isum] = 2.0*b - 1.0; m_points[1][isum] = 2.0*c - 1.0; m_points[2][isum] = 2.0*d - 1.0; @@ -161,7 +161,7 @@ namespace Nektar b = NodalTetElecData[index][offset + perm12C_3d[j][1]]; c = NodalTetElecData[index][offset + perm12C_3d[j][2]]; d = NodalTetElecData[index][offset + perm12C_3d[j][3]]; - + m_points[0][isum] = 2.0*b - 1.0; m_points[1][isum] = 2.0*c - 1.0; m_points[2][isum] = 2.0*d - 1.0; @@ -178,7 +178,7 @@ namespace Nektar b = NodalTetElecData[index][offset + perm24_3d[j][1]]; c = NodalTetElecData[index][offset + perm24_3d[j][2]]; d = NodalTetElecData[index][offset + perm24_3d[j][3]]; - + m_points[0][isum] = 2.0*b - 1.0; m_points[1][isum] = 2.0*c - 1.0; m_points[2][isum] = 2.0*d - 1.0; @@ -186,7 +186,7 @@ namespace Nektar }//end j continue; }//end symmetry24abcd - + }//end npts @@ -201,10 +201,10 @@ namespace Nektar PointsBaseType::CalculateWeights(); typedef DataType T; - + // Solve the Vandermonde system of integrals for the weight vector NekVector w = MakeTetWeights(NekVector(m_points[0]), NekVector(m_points[1]), NekVector(m_points[2])); - + m_weights = Array( w.GetRows(), w.GetPtr() ); } @@ -212,7 +212,7 @@ namespace Nektar // CalculateInterpMatrix() void NodalTetElec::CalculateInterpMatrix(const Array& xia, const Array& yia, const Array& zia, Array& interp) - + { NekVector x( m_points[0] ); NekVector y( m_points[1] ); @@ -227,7 +227,7 @@ namespace Nektar for( int j = 0; j < cols; ++j ) { interp[j + i*cols] = interMat(i,j); } - } + } } void NodalTetElec::CalculateDerivMatrix() @@ -258,7 +258,412 @@ namespace Nektar void NodalTetElec::NodalPointReorder3d() { - } + int cnt; + int istart,iend; + + const int nVerts = 4; + const int nEdgeInteriorPoints = GetNumPoints()-2; + const int nFaceInteriorPoints = (GetNumPoints()-3)*(GetNumPoints()-2)/2; + //const int nBoundaryPoints = 4 + 6*nEdgeInteriorPoints + 4*nFaceInteriorPoints; + const int nAllPoints = GetNumPoints()*(GetNumPoints()+1)*(GetNumPoints()+2)/6; + if(nEdgeInteriorPoints==0) + { + return; + } + + //group all edge 1 points + istart = nVerts; + for(int i = cnt = istart; i < nAllPoints; i++) + { + if( fabs(m_points[1][i] + 1.0) < NekConstants::kNekZeroTol && + fabs(m_points[2][i] + 1.0) < NekConstants::kNekZeroTol) + { + std::swap(m_points[0][cnt], m_points[0][i]); + std::swap(m_points[1][cnt], m_points[1][i]); + std::swap(m_points[2][cnt], m_points[2][i]); + cnt++; + } + } + + // bubble sort edge 1 (counterclockwise numbering) + iend = istart + nEdgeInteriorPoints; + for(int i = istart; i < iend; i++) + { + for(int j = istart+1; j < iend; j++) + { + if(m_points[0][j] < m_points[0][j-1]) + { + std::swap(m_points[0][j], m_points[0][j-1]); + std::swap(m_points[1][j], m_points[1][j-1]); + std::swap(m_points[2][j], m_points[2][j-1]); + } + } + } + + // group the points of edge 2 together; + istart = iend; + for(int i = cnt = istart; i < nAllPoints; i++) + { + if( fabs(m_points[1][i]+m_points[0][i]) < NekConstants::kNekZeroTol && + fabs(m_points[2][i] + 1.0) < NekConstants::kNekZeroTol) + { + std::swap(m_points[0][cnt], m_points[0][i]); + std::swap(m_points[1][cnt], m_points[1][i]); + std::swap(m_points[2][cnt], m_points[2][i]); + cnt++; + } + } + + // bubble sort edge 2 (counterclockwise numbering) + iend = istart + nEdgeInteriorPoints; + for(int i = istart; i < iend; i++) + { + for(int j = istart+1; j < iend; j++) + { + if(m_points[1][j] < m_points[1][j-1]) + { + std::swap(m_points[0][j], m_points[0][j-1]); + std::swap(m_points[1][j], m_points[1][j-1]); + std::swap(m_points[2][j], m_points[2][j-1]); + } + } + } + + // group the points of edge 3 together; + istart = iend; + for(int i = cnt = istart; i < nAllPoints; i++) + { + if( fabs(m_points[0][i] + 1.0) < NekConstants::kNekZeroTol && + fabs(m_points[2][i] + 1.0) < NekConstants::kNekZeroTol) + { + std::swap(m_points[0][cnt], m_points[0][i]); + std::swap(m_points[1][cnt], m_points[1][i]); + std::swap(m_points[2][cnt], m_points[2][i]); + cnt++; + } + } + + // bubble sort edge 3 (counterclockwise numbering) + iend = istart + nEdgeInteriorPoints; + for(int i = istart; i < iend; i++) + { + for(int j = istart+1; j < iend; j++) + { + if(m_points[1][j] > m_points[1][j-1]) + { + std::swap(m_points[0][j], m_points[0][j-1]); + std::swap(m_points[1][j], m_points[1][j-1]); + std::swap(m_points[2][j], m_points[2][j-1]); + } + } + } + + // group the points of edge 4 together; + istart = iend; + for(int i = cnt = istart; i < nAllPoints; i++) + { + if( fabs(m_points[0][i] + 1.0) < NekConstants::kNekZeroTol && + fabs(m_points[1][i] + 1.0) < NekConstants::kNekZeroTol) + { + std::swap(m_points[0][cnt], m_points[0][i]); + std::swap(m_points[1][cnt], m_points[1][i]); + std::swap(m_points[2][cnt], m_points[2][i]); + cnt++; + } + } + + // bubble sort edge 3 (counterclockwise numbering) + iend = istart + nEdgeInteriorPoints; + for(int i = istart; i < iend; i++) + { + for(int j = istart+1; j < iend; j++) + { + if(m_points[2][j] < m_points[2][j-1]) + { + std::swap(m_points[0][j], m_points[0][j-1]); + std::swap(m_points[1][j], m_points[1][j-1]); + std::swap(m_points[2][j], m_points[2][j-1]); + } + } + } + + // group the points of edge 5 together; + istart = iend; + for(int i = cnt = istart; i < nAllPoints; i++) + { + if( fabs(m_points[0][i]+m_points[2][i]) < NekConstants::kNekZeroTol && + fabs(m_points[1][i] + 1.0) < NekConstants::kNekZeroTol) + { + std::swap(m_points[0][cnt], m_points[0][i]); + std::swap(m_points[1][cnt], m_points[1][i]); + std::swap(m_points[2][cnt], m_points[2][i]); + cnt++; + } + } + + // bubble sort edge 5 (counterclockwise numbering) + iend = istart + nEdgeInteriorPoints; + for(int i = istart; i < iend; i++) + { + for(int j = istart+1; j < iend; j++) + { + if(m_points[2][j] < m_points[2][j-1]) + { + std::swap(m_points[0][j], m_points[0][j-1]); + std::swap(m_points[1][j], m_points[1][j-1]); + std::swap(m_points[2][j], m_points[2][j-1]); + } + } + } + + // group the points of edge 6 together; + istart = iend; + for(int i = cnt = istart; i < nAllPoints; i++) + { + if( fabs(m_points[1][i]+m_points[2][i]) < NekConstants::kNekZeroTol && + fabs(m_points[0][i] + 1.0) < NekConstants::kNekZeroTol) + { + std::swap(m_points[0][cnt], m_points[0][i]); + std::swap(m_points[1][cnt], m_points[1][i]); + std::swap(m_points[2][cnt], m_points[2][i]); + cnt++; + } + } + + // bubble sort edge 6 (counterclockwise numbering) + iend = istart + nEdgeInteriorPoints; + for(int i = istart; i < iend; i++) + { + for(int j = istart+1; j < iend; j++) + { + if(m_points[2][j] < m_points[2][j-1]) + { + std::swap(m_points[0][j], m_points[0][j-1]); + std::swap(m_points[1][j], m_points[1][j-1]); + std::swap(m_points[2][j], m_points[2][j-1]); + } + } + } + + if(GetNumPoints() < 4) + { + //no face points + return; + } + + // group the points of face 1 together; + istart = iend; + for(int i = cnt = istart; i < nAllPoints; i++) + { + if(fabs(m_points[2][i] + 1.0) < NekConstants::kNekZeroTol) + { + std::swap(m_points[0][cnt], m_points[0][i]); + std::swap(m_points[1][cnt], m_points[1][i]); + std::swap(m_points[2][cnt], m_points[2][i]); + cnt++; + } + } + + // bubble sort face1 (tensor numbering) + iend = istart + nFaceInteriorPoints; + bool repeat = true; + while(repeat) + { + repeat = false; + for(int i = istart; i < iend - 1; i++) + { + if(m_points[1][i] > m_points[1][i+1]) + { + std::swap(m_points[0][i+1], m_points[0][i]); + std::swap(m_points[1][i+1], m_points[1][i]); + std::swap(m_points[2][i+1], m_points[2][i]); + repeat = true; + } + } + } + int offset = 0; + int npl = GetNumPoints() - 3; + while(npl > 1) + { + repeat = true; + while(repeat) + { + repeat = false; + for(int i = offset+istart; i < offset+istart + npl - 1; i++) + { + if(m_points[0][i] > m_points[0][i+1]) + { + std::swap(m_points[0][i+1], m_points[0][i]); + std::swap(m_points[1][i+1], m_points[1][i]); + std::swap(m_points[2][i+1], m_points[2][i]); + repeat = true; + } + } + } + offset += npl; + npl--; + } + + // group the points of face 2 together; + istart = iend; + for(int i = cnt = istart; i < nAllPoints; i++) + { + if(fabs(m_points[1][i] + 1.0) < NekConstants::kNekZeroTol) + { + std::swap(m_points[0][cnt], m_points[0][i]); + std::swap(m_points[1][cnt], m_points[1][i]); + std::swap(m_points[2][cnt], m_points[2][i]); + cnt++; + } + } + + // bubble sort face2 (tensor numbering) + iend = istart + nFaceInteriorPoints; + repeat = true; + while(repeat) + { + repeat = false; + for(int i = istart; i < iend - 1; i++) + { + if(m_points[2][i] > m_points[2][i+1]) + { + std::swap(m_points[0][i+1], m_points[0][i]); + std::swap(m_points[1][i+1], m_points[1][i]); + std::swap(m_points[2][i+1], m_points[2][i]); + repeat = true; + } + } + } + offset = 0; + npl = GetNumPoints() - 3; + while(npl > 1) + { + repeat = true; + while(repeat) + { + repeat = false; + for(int i = offset+istart; i < offset+istart + npl - 1; i++) + { + if(m_points[0][i] > m_points[0][i+1]) + { + std::swap(m_points[0][i+1], m_points[0][i]); + std::swap(m_points[1][i+1], m_points[1][i]); + std::swap(m_points[2][i+1], m_points[2][i]); + repeat = true; + } + } + } + offset += npl; + npl--; + } + + // group the points of face 3 together; + istart = iend; + for(int i = cnt = istart; i < nAllPoints; i++) + { + if(fabs(m_points[1][i]+m_points[0][i]+m_points[2][i]+1) < NekConstants::kNekZeroTol) + { + std::swap(m_points[0][cnt], m_points[0][i]); + std::swap(m_points[1][cnt], m_points[1][i]); + std::swap(m_points[2][cnt], m_points[2][i]); + cnt++; + } + } + + // bubble sort face3 (tensor numbering) + iend = istart + nFaceInteriorPoints; + repeat = true; + while(repeat) + { + repeat = false; + for(int i = istart; i < iend - 1; i++) + { + if(m_points[2][i] > m_points[2][i+1]) + { + std::swap(m_points[0][i+1], m_points[0][i]); + std::swap(m_points[1][i+1], m_points[1][i]); + std::swap(m_points[2][i+1], m_points[2][i]); + repeat = true; + } + } + } + offset = 0; + npl = GetNumPoints() - 3; + while(npl > 1) + { + repeat = true; + while(repeat) + { + repeat = false; + for(int i = offset+istart; i < offset+istart + npl - 1; i++) + { + if(m_points[1][i] > m_points[1][i+1]) + { + std::swap(m_points[0][i+1], m_points[0][i]); + std::swap(m_points[1][i+1], m_points[1][i]); + std::swap(m_points[2][i+1], m_points[2][i]); + repeat = true; + } + } + } + offset += npl; + npl--; + } + + // group the points of face 4 together; + istart = iend; + for(int i = cnt = istart; i < nAllPoints; i++) + { + if(fabs(m_points[0][i] + 1.0) < NekConstants::kNekZeroTol) + { + std::swap(m_points[0][cnt], m_points[0][i]); + std::swap(m_points[1][cnt], m_points[1][i]); + std::swap(m_points[2][cnt], m_points[2][i]); + cnt++; + } + } + + // bubble sort face4 (tensor numbering) + iend = istart + nFaceInteriorPoints; + repeat = true; + while(repeat) + { + repeat = false; + for(int i = istart; i < iend - 1; i++) + { + if(m_points[2][i] > m_points[2][i+1]) + { + std::swap(m_points[0][i+1], m_points[0][i]); + std::swap(m_points[1][i+1], m_points[1][i]); + std::swap(m_points[2][i+1], m_points[2][i]); + repeat = true; + } + } + } + offset = 0; + npl = GetNumPoints() - 3; + while(npl > 1) + { + repeat = true; + while(repeat) + { + repeat = false; + for(int i = offset+istart; i < offset+istart + npl - 1; i++) + { + if(m_points[1][i] > m_points[1][i+1]) + { + std::swap(m_points[0][i+1], m_points[0][i]); + std::swap(m_points[1][i+1], m_points[1][i]); + std::swap(m_points[2][i+1], m_points[2][i]); + repeat = true; + } + } + } + offset += npl; + npl--; + } + + } } // end of namespace stdregion } // end of namespace stdregion diff --git a/library/NekMeshUtils/MeshElements/Element.h b/library/NekMeshUtils/MeshElements/Element.h index a321a36a6..d94e8e856 100644 --- a/library/NekMeshUtils/MeshElements/Element.h +++ b/library/NekMeshUtils/MeshElements/Element.h @@ -49,6 +49,142 @@ namespace Nektar { namespace NekMeshUtils { +/** + * @brief A lightweight struct for dealing with high-order triangle + * alignment. + * + * The logic underlying these routines is taken from the original Nektar + * code. + */ +template struct HOTriangle +{ + HOTriangle(vector pVertId, vector pSurfVerts) + : vertId(pVertId), surfVerts(pSurfVerts) + { + } + HOTriangle(vector pVertId) : vertId(pVertId) + { + } + + /// The triangle vertex IDs + vector vertId; + + /// The triangle surface vertices -- templated so that this can + /// either be nodes or IDs. + vector surfVerts; + + /** + * @brief Rotates the triangle of data points inside #surfVerts + * counter-clockwise nrot times. + * + * @param nrot Number of times to rotate triangle. + */ + void Rotate(int nrot) + { + int n, i, j, cnt; + int np = ((int)sqrt(8.0 * surfVerts.size() + 1.0) - 1) / 2; + vector tmp(np * np); + + for (n = 0; n < nrot; ++n) + { + for (cnt = i = 0; i < np; ++i) + { + for (j = 0; j < np - i; ++j, cnt++) + { + tmp[i * np + j] = surfVerts[cnt]; + } + } + for (cnt = i = 0; i < np; ++i) + { + for (j = 0; j < np - i; ++j, cnt++) + { + surfVerts[cnt] = tmp[(np - 1 - i - j) * np + i]; + } + } + } + } + + /** + * @brief Reflect data points inside #surfVerts. + * + * This applies a mapping essentially doing the following + * reordering: + * + * 9 9 + * 7 8 -> 8 7 + * 4 5 6 6 5 4 + * 0 1 2 3 3 2 1 0 + */ + void Reflect() + { + int i, j, cnt; + int np = ((int)sqrt(8.0 * surfVerts.size() + 1.0) - 1) / 2; + vector tmp(np * np); + + for (cnt = i = 0; i < np; ++i) + { + for (j = 0; j < np - i; ++j, cnt++) + { + tmp[i * np + np - i - 1 - j] = surfVerts[cnt]; + } + } + + for (cnt = i = 0; i < np; ++i) + { + for (j = 0; j < np - i; ++j, cnt++) + { + surfVerts[cnt] = tmp[i * np + j]; + } + } + } + + /** + * @brief Align this surface to a given vertex ID. + */ + void Align(vector vertId) + { + if (vertId[0] == this->vertId[0]) + { + if (vertId[1] == this->vertId[1] || vertId[1] == this->vertId[2]) + { + if (vertId[1] == this->vertId[2]) + { + Rotate(1); + Reflect(); + } + } + } + else if (vertId[0] == this->vertId[1]) + { + if (vertId[1] == this->vertId[0] || vertId[1] == this->vertId[2]) + { + if (vertId[1] == this->vertId[0]) + { + Reflect(); + } + else + { + Rotate(2); + } + } + } + else if (vertId[0] == this->vertId[2]) + { + if (vertId[1] == this->vertId[0] || vertId[1] == this->vertId[1]) + { + if (vertId[1] == this->vertId[1]) + { + Rotate(2); + Reflect(); + } + else + { + Rotate(1); + } + } + } + } +}; /** * @brief Basic information about an element. * @@ -410,6 +546,86 @@ public: } } } + else if (m_dim == 3 && m_vertex.size() == 4) + { + int n = m_edge[0]->GetNodeCount(); + nodeList.resize(n*(n+1)*(n+2)/6); + + nodeList[0] = m_vertex[0]; + nodeList[1] = m_vertex[1]; + nodeList[2] = m_vertex[2]; + nodeList[3] = m_vertex[3]; + int k = 4; + + for(int i = 0; i < 6; i++) + { + bool reverseEdge = false; + if(i < 3) + { + reverseEdge = m_edge[i]->m_n1 == m_vertex[i]; + } + else + { + reverseEdge = m_edge[i]->m_n1 == m_vertex[i-3]; + } + + if (reverseEdge) + { + for(int j = 0; j < n-2; j++) + { + nodeList[k++] = m_edge[i]->m_edgeNodes[j]; + } + } + else + { + for(int j = n-3; j >= 0; j--) + { + nodeList[k++] = m_edge[i]->m_edgeNodes[j]; + } + } + } + + vector > ts; + vector t(3); + t[0] = m_vertex[0]->m_id; + t[1] = m_vertex[1]->m_id; + t[2] = m_vertex[2]->m_id; + ts.push_back(t); + t[0] = m_vertex[0]->m_id; + t[1] = m_vertex[1]->m_id; + t[2] = m_vertex[3]->m_id; + ts.push_back(t); + t[0] = m_vertex[1]->m_id; + t[1] = m_vertex[2]->m_id; + t[2] = m_vertex[3]->m_id; + ts.push_back(t); + t[0] = m_vertex[0]->m_id; + t[1] = m_vertex[2]->m_id; + t[2] = m_vertex[3]->m_id; + ts.push_back(t); + + for(int i = 0; i < 4; i++) + { + vector fcid; + fcid.push_back(m_face[i]->m_vertexList[0]->m_id); + fcid.push_back(m_face[i]->m_vertexList[1]->m_id); + fcid.push_back(m_face[i]->m_vertexList[2]->m_id); + + HOTriangle hot(fcid, m_face[i]->m_faceNodes); + + hot.Align(ts[i]); + + std::copy(hot.surfVerts.begin(), + hot.surfVerts.end(), + nodeList.begin() + k); + k+= hot.surfVerts.size(); + } + + std::copy(m_volumeNodes.begin(), + m_volumeNodes.end(), + nodeList.begin() + k); + + } else { cerr << "GetXmlCurveString for a " << m_vertex.size() diff --git a/library/NekMeshUtils/MeshElements/Triangle.h b/library/NekMeshUtils/MeshElements/Triangle.h index 0f0c70955..af9e38982 100644 --- a/library/NekMeshUtils/MeshElements/Triangle.h +++ b/library/NekMeshUtils/MeshElements/Triangle.h @@ -43,142 +43,7 @@ namespace Nektar { namespace NekMeshUtils { -/** - * @brief A lightweight struct for dealing with high-order triangle - * alignment. - * - * The logic underlying these routines is taken from the original Nektar - * code. - */ -template struct HOTriangle -{ - HOTriangle(vector pVertId, vector pSurfVerts) - : vertId(pVertId), surfVerts(pSurfVerts) - { - } - HOTriangle(vector pVertId) : vertId(pVertId) - { - } - - /// The triangle vertex IDs - vector vertId; - - /// The triangle surface vertices -- templated so that this can - /// either be nodes or IDs. - vector surfVerts; - - /** - * @brief Rotates the triangle of data points inside #surfVerts - * counter-clockwise nrot times. - * - * @param nrot Number of times to rotate triangle. - */ - void Rotate(int nrot) - { - int n, i, j, cnt; - int np = ((int)sqrt(8.0 * surfVerts.size() + 1.0) - 1) / 2; - vector tmp(np * np); - - for (n = 0; n < nrot; ++n) - { - for (cnt = i = 0; i < np; ++i) - { - for (j = 0; j < np - i; ++j, cnt++) - { - tmp[i * np + j] = surfVerts[cnt]; - } - } - for (cnt = i = 0; i < np; ++i) - { - for (j = 0; j < np - i; ++j, cnt++) - { - surfVerts[cnt] = tmp[(np - 1 - i - j) * np + i]; - } - } - } - } - /** - * @brief Reflect data points inside #surfVerts. - * - * This applies a mapping essentially doing the following - * reordering: - * - * 9 9 - * 7 8 -> 8 7 - * 4 5 6 6 5 4 - * 0 1 2 3 3 2 1 0 - */ - void Reflect() - { - int i, j, cnt; - int np = ((int)sqrt(8.0 * surfVerts.size() + 1.0) - 1) / 2; - vector tmp(np * np); - - for (cnt = i = 0; i < np; ++i) - { - for (j = 0; j < np - i; ++j, cnt++) - { - tmp[i * np + np - i - 1 - j] = surfVerts[cnt]; - } - } - - for (cnt = i = 0; i < np; ++i) - { - for (j = 0; j < np - i; ++j, cnt++) - { - surfVerts[cnt] = tmp[i * np + j]; - } - } - } - - /** - * @brief Align this surface to a given vertex ID. - */ - void Align(vector vertId) - { - if (vertId[0] == this->vertId[0]) - { - if (vertId[1] == this->vertId[1] || vertId[1] == this->vertId[2]) - { - if (vertId[1] == this->vertId[2]) - { - Rotate(1); - Reflect(); - } - } - } - else if (vertId[0] == this->vertId[1]) - { - if (vertId[1] == this->vertId[0] || vertId[1] == this->vertId[2]) - { - if (vertId[1] == this->vertId[0]) - { - Reflect(); - } - else - { - Rotate(2); - } - } - } - else if (vertId[0] == this->vertId[2]) - { - if (vertId[1] == this->vertId[0] || vertId[1] == this->vertId[1]) - { - if (vertId[1] == this->vertId[1]) - { - Rotate(2); - Reflect(); - } - else - { - Rotate(1); - } - } - } - } -}; /** * @brief A 2-dimensional three-sided element. diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 36359b15b..73812bf7d 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -167,15 +167,15 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, (jacIdeal[3]*jacIdeal[3]+jacIdeal[4]*jacIdeal[4]+jacIdeal[5]*jacIdeal[5]-1.0); NekDouble c = (jacIdeal[6]*jacIdeal[6]+jacIdeal[7]*jacIdeal[7]+jacIdeal[8]*jacIdeal[8]-1.0)* (jacIdeal[6]*jacIdeal[6]+jacIdeal[7]*jacIdeal[7]+jacIdeal[8]*jacIdeal[8]-1.0); - NekDouble d = (jacIdeal[0]*jacIdeal[6]+jacIdeal[1]*jacIdeal[7]+jacIdeal[2]*jacIdeal[8])* + NekDouble D = (jacIdeal[0]*jacIdeal[6]+jacIdeal[1]*jacIdeal[7]+jacIdeal[2]*jacIdeal[8])* (jacIdeal[0]*jacIdeal[6]+jacIdeal[1]*jacIdeal[7]+jacIdeal[2]*jacIdeal[8]); NekDouble e = (jacIdeal[3]*jacIdeal[6]+jacIdeal[4]*jacIdeal[7]+jacIdeal[5]*jacIdeal[8])* (jacIdeal[3]*jacIdeal[6]+jacIdeal[4]*jacIdeal[7]+jacIdeal[5]*jacIdeal[8]); NekDouble f = (jacIdeal[0]*jacIdeal[3]+jacIdeal[1]*jacIdeal[4]+jacIdeal[3]*jacIdeal[5])* (jacIdeal[0]*jacIdeal[3]+jacIdeal[1]*jacIdeal[4]+jacIdeal[3]*jacIdeal[5]); - NekDouble trEtE = 0.25 * (a+b+c) + 0.5 * (d+e+f); - NekDouble jacDet; + NekDouble trEtE = 0.25 * (a+b+c) + 0.5 * (D+e+f); + /*NekDouble jacDet; if(dim == 2) { jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; @@ -192,7 +192,37 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, NekDouble nu = 0.45; NekDouble mu = 1.0/2.0/(1.0+nu); NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); - dW[k] = K *0.5 * ljacDet * ljacDet + mu * trEtE; + dW[k] = K *0.5 * ljacDet * ljacDet + mu * trEtE;*/ + NekDouble jacDet, i2rmDet = 0.0; + if(dim == 2) + { + jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; + i2rmDet = 1.0 / (d->maps[k][0]*d->maps[k][4] - d->maps[k][1]*d->maps[k][3]); + } + else + { + jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) + -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) + +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); + ASSERTL0(false,"need to extend to do i2rmDet in 3d"); + } + + NekDouble ljacDet = log(jacDet); + NekDouble nu = 0.45; + NekDouble mu = 1.0/2.0/(1.0+nu); + NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + + if(jacDet > 0) + { + dW[k] = K *0.5 * ljacDet * ljacDet + mu * trEtE; + } + else + { + NekDouble de = fabs(i2rmDet) * sqrt(1E-1*1E-1 + 1E-1); + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); + NekDouble lsigma = log(sigma); + dW[k] = K *0.5 * lsigma * lsigma + mu * trEtE; + } } break; @@ -224,7 +254,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, jacIdeal[7]*jacIdeal[7] + jacIdeal[8]*jacIdeal[8]; - NekDouble jacDet; + /*NekDouble jacDet; if(dim == 2) { jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; @@ -240,7 +270,37 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, NekDouble nu = 0.45; NekDouble mu = 1.0/2.0/(1.0+nu); NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); - dW[k] = 0.5 * mu * (I1 - 3.0 - 2.0*ljacDet) + 0.5 * K * ljacDet * ljacDet; + dW[k] = 0.5 * mu * (I1 - 3.0 - 2.0*ljacDet) + 0.5 * K * ljacDet * ljacDet;*/ + NekDouble jacDet, i2rmDet = 0.0; + if(dim == 2) + { + jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; + i2rmDet = 1.0 / (d->maps[k][0]*d->maps[k][4] - d->maps[k][1]*d->maps[k][3]); + } + else + { + jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) + -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) + +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); + ASSERTL0(false,"need to extend to do i2rmDet in 3d"); + } + + NekDouble ljacDet = log(jacDet); + NekDouble nu = 0.45; + NekDouble mu = 1.0/2.0/(1.0+nu); + NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + + if(jacDet > 0) + { + dW[k] = 0.5 * mu * (I1 - 3.0 - 2.0*ljacDet) + 0.5 * K * ljacDet * ljacDet; + } + else + { + NekDouble de = fabs(i2rmDet) * sqrt(1E-1*1E-1 + 1E-1); + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); + NekDouble lsigma = log(sigma); + dW[k] = 0.5 * mu * (I1 - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma; + } } break; @@ -273,7 +333,11 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - ASSERTL0(false,"need to extend to do i2rmDet in 3d"); + i2rmDet = d->maps[k][0]*(d->maps[k][4]*d->maps[k][8]-d->maps[k][5]*d->maps[k][7]) + -d->maps[k][3]*(d->maps[k][1]*d->maps[k][8]-d->maps[k][2]*d->maps[k][7]) + +d->maps[k][6]*(d->maps[k][1]*d->maps[k][5]-d->maps[k][2]*d->maps[k][4]); + cout << endl << i2rmDet << endl; + i2rmDet = 1.0 / i2rmDet; } NekDouble frob = 0.0; @@ -288,10 +352,17 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, frob += jacIdeal[7] * jacIdeal[7]; frob += jacIdeal[8] * jacIdeal[8]; - NekDouble de = fabs(i2rmDet) * sqrt(1E-6 + 1E-3); - - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - dW[k] = frob / dim / pow(sigma, 2.0/dim); + if(jacDet > 0) + { + dW[k] = frob / dim / pow(fabs(jacDet), 2.0/dim); + } + else + { + NekDouble de = fabs(i2rmDet) * sqrt(1E-3*1E-3 + 1E-3); + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); + dW[k] = frob / dim / pow(fabs(sigma), 2.0/dim); + } + dW[k] = (dW[k]-1.0)*(dW[k]-1.0); } break; } @@ -312,21 +383,18 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; - NekDouble jacDet; + NekDouble jacDet, i2rmDet = 0.0; if(dim == 2) { jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; + i2rmDet = 1.0 / (d->maps[k][0]*d->maps[k][4] - d->maps[k][1]*d->maps[k][3]); } else { jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - } - - if(jacDet < 1E-10) - { - jacDet = 1E-10; + ASSERTL0(false,"need to extend to do i2rmDet in 3d"); } NekDouble frob = 0.0; @@ -341,7 +409,16 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, frob += jacIdeal[7] * jacIdeal[7]; frob += jacIdeal[8] * jacIdeal[8]; - dW[k] = frob / jacDet; + if(jacDet > 0) + { + dW[k] = frob / dim / pow(fabs(jacDet), 2.0/dim); + } + else + { + NekDouble de = fabs(i2rmDet) * sqrt(1E-2*1E-2 + 1E-2); + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); + dW[k] = frob / dim / pow(fabs(sigma), 2.0/dim); + } } break; } @@ -350,8 +427,9 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, NekDouble integral = 0.0; for(int i = 0; i < dW.num_elements(); i++) { - integral += quadW(i) * dW[i]; + integral += fabs(quadW(i)) * dW[i]; } + cout << integral << endl; return integral; } @@ -427,7 +505,7 @@ void ProcessVarOpti::Process() case 2: { LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriFekete); + LibUtilities::eNodalTriElec); Array u, v; LibUtilities::PointsManager()[pkey]->GetPoints(u, v); @@ -472,10 +550,11 @@ void ProcessVarOpti::Process() VdmDz = LibUtilities::GetVandermondeForTetZDerivative(U,V,W) * VandermondeI; quadW = LibUtilities::MakeTetWeights(U,V,W); - ASSERTL0(false,"vdm not setup for this yet, because quad weights are wrong"); } } + cout << quadW << endl << endl; + GetElementMap(); vector > freenodes = GetColouredNodes(); @@ -507,6 +586,8 @@ void ProcessVarOpti::Process() cout << scientific << endl; cout << "starting energy: " << functionalStart << endl; + exit(-1); + int nThreads = m_config["numthreads"].as(); int ctr = 0; @@ -574,13 +655,19 @@ void ProcessVarOpti::NodeOpti::Optimise() NekDouble yc = node->m_y; NekDouble zc = node->m_z; NekDouble alpha = 1.0; + NekDouble delX = 1.0/(G[3]*G[4]-G[6]*G[6])*(G[4]*G[0] - G[6]*G[1]); + NekDouble delY = 1.0/(G[3]*G[4]-G[6]*G[6])*(G[3]*G[1] - G[6]*G[0]); + //if(sqrt(delX*delX + delY*delY) > 1e-3) + //{ + // cout << endl; + // cout << delX << " " << delY << endl; + //} bool found = false; while(alpha > 1e-6) { - node->m_x = xc - alpha * G[0]; - node->m_y = yc - alpha * G[1]; - node->m_z = zc - alpha * G[2]; - + node->m_x = xc - alpha * delX; + node->m_y = yc - alpha * delY; + //node->m_z = zc - alpha * G[2]; if(GetFunctional() < currentW) { found = true; @@ -589,6 +676,11 @@ void ProcessVarOpti::NodeOpti::Optimise() alpha /= 2.0; } + //if(sqrt(delX*delX + delY*delY) > 1e-2) + //{ + // cout << alpha << endl; + //} + if(!found) { //reset the node @@ -605,37 +697,59 @@ void ProcessVarOpti::NodeOpti::Optimise() } } -NekDouble dir[6][3] = {{1.0,0.0,0.0},{-1.0,0.0,0.0}, - {0.0,1.0,0.0},{0.0,-1.0,0.0}, - {0.0,0.0,1.0},{0.0,0.0,-1.0}}; +NekDouble dir[9][2] = {{0.0,0.0}, + {1.0,0.0}, + {1.0,1.0}, + {0.0,1.0}, + {-1.0,1.0}, + {-1.0,0.0}, + {-1.0,-1.0}, + {0.0,-1.0}, + {1.0,-1.0}}; Array ProcessVarOpti::NodeOpti::GetGrad() { NekDouble xc = node->m_x; NekDouble yc = node->m_y; NekDouble zc = node->m_z; - NekDouble dx = 1e-6; + NekDouble dx = 1e-3; + + ASSERTL0(dim == 2,"dir not coded in 3d"); vector w; - for(int i = 0; i < dim * 2; i++) + for(int i = 0; i < 9; i++) { node->m_x = xc + dir[i][0] * dx; node->m_y = yc + dir[i][1] * dx; - node->m_z = zc + dir[i][2] * dx; + //node->m_z = zc + dir[i][2] * dx; w.push_back(GetFunctional()); } node->m_x = xc; node->m_y = yc; node->m_z = zc; - Array ret(3,0.0); + Array ret(9,0.0); + + //ret[0] d/dx + //ret[1] d/dy + //ret[2] d/dz + + //ret[3] d2/dx2 + //ret[4] d2/dy2 + //ret[5] d2/dz2 + //ret[6] d2/dxdy + //ret[7] d2/dxdz + //ret[8] d2/dydz - ret[0] = (w[0] - w[1]) / 2.0 / dx; - ret[1] = (w[2] - w[3]) / 2.0 / dx; + ret[0] = (w[1] - w[5]) / 2.0 / dx; + ret[1] = (w[3] - w[7]) / 2.0 / dx; + ret[3] = (w[1] + w[5] - 2.0*w[0]) / dx / dx; + ret[4] = (w[3] + w[7] - 2.0*w[0]) / dx / dx; + ret[6] = (w[2] + w[6] - w[4] - w[8]) / 4.0 / dx /dx; if(dim == 3) { - ret[3] = (w[4] - w[5]) / 2.0 / dx; + ret[2] = (w[4] - w[5]) / 2.0 / dx; } return ret; @@ -701,6 +815,11 @@ vector > ProcessVarOpti::GetColouredNodes() boundaryNodes.insert(es[j]->m_edgeNodes[k]); } } + + for(int i = 0; i < (*it)->m_faceNodes.size(); i++) + { + boundaryNodes.insert((*it)->m_faceNodes[i]); + } } break; } @@ -710,24 +829,24 @@ vector > ProcessVarOpti::GetColouredNodes() vector remain; - EdgeSet::iterator eit; - for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) + if(m_mesh->m_expDim == 2) { - vector n = (*eit)->m_edgeNodes; - n.push_back((*eit)->m_n1); - n.push_back((*eit)->m_n2); - for(int j = 0; j < n.size(); j++) + EdgeSet::iterator eit; + for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) { - NodeSet::iterator nit = boundaryNodes.find(n[j]); - if(nit == boundaryNodes.end()) + vector n = (*eit)->m_edgeNodes; + n.push_back((*eit)->m_n1); + n.push_back((*eit)->m_n2); + for(int j = 0; j < n.size(); j++) { - remain.push_back(n[j]); + NodeSet::iterator nit = boundaryNodes.find(n[j]); + if(nit == boundaryNodes.end()) + { + remain.push_back(n[j]); + } } } - } - if(m_mesh->m_expDim == 2) - { for(int i = 0; i < m_mesh->m_element[2].size(); i++) { vector ns = m_mesh->m_element[2][i]->GetVolumeNodes(); @@ -743,7 +862,33 @@ vector > ProcessVarOpti::GetColouredNodes() } else { - ASSERTL0(false,"3D"); + FaceSet::iterator fit; + for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) + { + vector n; + (*fit)->GetCurvedNodes(n); + for(int j = 0; j < n.size(); j++) + { + NodeSet::iterator nit = boundaryNodes.find(n[j]); + if(nit == boundaryNodes.end()) + { + remain.push_back(n[j]); + } + } + } + + for(int i = 0; i < m_mesh->m_element[3].size(); i++) + { + vector ns = m_mesh->m_element[3][i]->GetVolumeNodes(); + for(int j = 0; j < ns.size(); j++) + { + NodeSet::iterator nit = boundaryNodes.find(ns[j]); + if(nit == boundaryNodes.end()) + { + remain.push_back(ns[j]); + } + } + } } vector > ret; @@ -883,7 +1028,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP else if(geom->GetShapeType() == LibUtilities::eTriangle) { LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriFekete); + LibUtilities::eNodalTriElec); Array u, v; LibUtilities::PointsManager()[pkey]->GetPoints(u, v); @@ -946,7 +1091,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP chi->BwdTrans(coeffs0,xc); chi->BwdTrans(coeffs1,yc); - chi->BwdTrans(coeffs2,yc); + chi->BwdTrans(coeffs2,zc); NekVector X(u.num_elements()),Y(u.num_elements()), Z(u.num_elements()); @@ -955,7 +1100,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP Array xp(3); xp[0] = u[j]; xp[1] = v[j]; - xp[1] = w[j]; + xp[2] = w[j]; X(j) = chi->PhysEvaluate(xp, xc); Y(j) = chi->PhysEvaluate(xp, yc); @@ -1159,7 +1304,7 @@ void ProcessVarOpti::FillQuadPoints() StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriFekete); + LibUtilities::eNodalTriElec); Array u, v; LibUtilities::PointsManager()[pkey]->GetPoints(u, v); @@ -1187,7 +1332,7 @@ void ProcessVarOpti::FillQuadPoints() } el->SetVolumeNodes(hons); - el->SetCurveType(LibUtilities::eNodalTriFekete); + el->SetCurveType(LibUtilities::eNodalTriElec); } } else @@ -1195,13 +1340,19 @@ void ProcessVarOpti::FillQuadPoints() FaceSet::iterator it; for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) { + //this is a hack and needs to be fixed + //it really should take the get geom of the whole element and + //then pick the correct parts + ///////// + (*it)->m_faceNodes.clear(); + //////// SpatialDomains::Geometry2DSharedPtr geom = (*it)->GetGeom(m_mesh->m_spaceDim); geom->FillGeom(); StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriFekete); + LibUtilities::eNodalTriElec); Array u, v; LibUtilities::PointsManager()[pkey]->GetPoints(u, v); @@ -1233,7 +1384,7 @@ void ProcessVarOpti::FillQuadPoints() } (*it)->m_faceNodes.clear(); (*it)->m_faceNodes = hons; - (*it)->m_curveType = LibUtilities::eNodalTriFekete; + (*it)->m_curveType = LibUtilities::eNodalTriElec; } for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { @@ -1264,22 +1415,22 @@ void ProcessVarOpti::FillQuadPoints() vector hons; //need to finish for tet - ASSERTL0(false,"need to finish 3D"); - - /*for(int j = nq * (nq + 1) / 2 - (nq-2)*(nq-3) / 2; + for(int j = 4 + 6*(nq-2) + 4 * ((nq-2)*(nq-3) / 2); j < u.num_elements(); j++) { - Array xp(2); + Array xp(3); xp[0] = u[j]; xp[1] = v[j]; + xp[2] = w[j]; hons.push_back(boost::shared_ptr(new Node( id++,xmap->PhysEvaluate(xp,xc), - xmap->PhysEvaluate(xp,yc),0.0))); + xmap->PhysEvaluate(xp,yc), + xmap->PhysEvaluate(xp,zc)))); } el->SetVolumeNodes(hons); - el->SetCurveType(LibUtilities::eNodalTriFekete);*/ + el->SetCurveType(LibUtilities::eNodalTetElec); } } } -- GitLab From 5875b735bd779c85191983779453785d9ec7eb12 Mon Sep 17 00:00:00 2001 From: David Moxey Date: Thu, 5 May 2016 13:12:54 +0100 Subject: [PATCH 021/236] Add dealiasing --- .../Demos/LibUtilities/NodalTriElecDemo.cpp | 11 ++++ .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 66 +++++++++++-------- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/library/Demos/LibUtilities/NodalTriElecDemo.cpp b/library/Demos/LibUtilities/NodalTriElecDemo.cpp index 47b5a6d03..ca6e669d7 100644 --- a/library/Demos/LibUtilities/NodalTriElecDemo.cpp +++ b/library/Demos/LibUtilities/NodalTriElecDemo.cpp @@ -218,4 +218,15 @@ int main(int argc, char *argv[]) cout << "\n W = \n" << ToVector(weight) << endl; cout << "------------------------------- End of Integral Demo ---------------------------------------" << endl; + { + int nPts = weight.num_elements(); + Array func(nPts); + + NekDouble integral = 0; + for (int i = 0; i < nPts; ++i) + { + integral += weight[i]* (sin(ax[i])*cos(ay[i])); + } + cout << "integral = " << integral << endl; + } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 73812bf7d..e6abc133e 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -56,6 +56,7 @@ namespace Utilities { boost::mutex mtx; +NekMatrix interp; inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, NekMatrix &VdmDx, @@ -67,28 +68,34 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, d->el->GetCurvedNodes(ns); int pts = ns.size(); + int pts2 = VdmDx.GetRows(); - ASSERTL0(pts == d->maps.size(), "what"); + //cout << pts2 << " " << interp.GetRows() << " " << interp.GetColumns() << endl; + ASSERTL0(pts2 == d->maps.size(), "what"); - Array > jac(pts); + Array > jac(pts2); if(dim == 2) { - NekVector X(pts),Y(pts),Z(pts), - x1(pts),y1(pts), - x2(pts),y2(pts); + NekVector X(pts),Y(pts), + x1(pts2),y1(pts2), + x2(pts2),y2(pts2); for(int i = 0; i < pts; i++) { X(i) = ns[i]->m_x; Y(i) = ns[i]->m_y; } - x1 = VdmDx*X; - y1 = VdmDx*Y; - x2 = VdmDy*X; - y2 = VdmDy*Y; + NekVector Xint(pts2), Yint(pts2); + Xint = interp * X; + Yint = interp * Y; - for(int i = 0; i < pts; i++) + x1 = VdmDx*Xint; + y1 = VdmDx*Yint; + x2 = VdmDy*Xint; + y2 = VdmDy*Yint; + + for(int i = 0; i < pts2; i++) { Array jaci(9,0.0); jaci[0] = x1(i); @@ -140,13 +147,13 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } } - Array dW(pts); + Array dW(pts2); switch (opti) { case eLinEl: { - for(int k = 0; k < pts; k++) + for(int k = 0; k < pts2; k++) { Array jacIdeal(9,0.0); jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; @@ -229,7 +236,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } case eHypEl: { - for(int k = 0; k < pts; k++) + for(int k = 0; k < pts2; k++) { Array jacIdeal(9,0.0); jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; @@ -504,25 +511,26 @@ void ProcessVarOpti::Process() { case 2: { - LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriElec); - Array u, v; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v); - - NekVector U(u.num_elements()) , V(v.num_elements()); - for(int i = 0; i < u.num_elements(); i++) - { - U(i) = u[i]; - V(i) = v[i]; - } - Vandermonde = LibUtilities::GetVandermonde(U,V); + LibUtilities::PointsKey pkey1(m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + LibUtilities::PointsKey pkey2(2*m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + Array u1, v1, u2, v2; + LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); + LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2); + NekVector U1(u1), V1(v1); + NekVector U2(u2), V2(v2); + + interp = LibUtilities::GetInterpolationMatrix(U1, V1, U2, V2); + + Vandermonde = LibUtilities::GetVandermonde(U2,V2); VandermondeI = Vandermonde; VandermondeI.Invert(); - VdmDx = LibUtilities::GetVandermondeForXDerivative(U,V) * + VdmDx = LibUtilities::GetVandermondeForXDerivative(U2,V2) * VandermondeI; - VdmDy = LibUtilities::GetVandermondeForYDerivative(U,V) * + VdmDy = LibUtilities::GetVandermondeForYDerivative(U2,V2) * VandermondeI; - quadW = LibUtilities::MakeQuadratureWeights(U,V); + quadW = LibUtilities::MakeQuadratureWeights(U2,V2); } break; case 3: @@ -1027,7 +1035,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP } else if(geom->GetShapeType() == LibUtilities::eTriangle) { - LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::PointsKey pkey(2*m_mesh->m_nummode, LibUtilities::eNodalTriElec); Array u, v; LibUtilities::PointsManager()[pkey]->GetPoints(u, v); -- GitLab From ad275c08fe90a013fb05aef9132a295ee9d09acb Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Thu, 5 May 2016 13:23:55 +0100 Subject: [PATCH 022/236] edits --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 105 +++++++++++------- 1 file changed, 67 insertions(+), 38 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 73812bf7d..7e4fa2d6a 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -322,22 +322,16 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; - NekDouble jacDet, i2rmDet = 0.0; + NekDouble jacDet = 0.0; if(dim == 2) { jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; - i2rmDet = 1.0 / (d->maps[k][0]*d->maps[k][4] - d->maps[k][1]*d->maps[k][3]); } else { jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - i2rmDet = d->maps[k][0]*(d->maps[k][4]*d->maps[k][8]-d->maps[k][5]*d->maps[k][7]) - -d->maps[k][3]*(d->maps[k][1]*d->maps[k][8]-d->maps[k][2]*d->maps[k][7]) - +d->maps[k][6]*(d->maps[k][1]*d->maps[k][5]-d->maps[k][2]*d->maps[k][4]); - cout << endl << i2rmDet << endl; - i2rmDet = 1.0 / i2rmDet; } NekDouble frob = 0.0; @@ -358,7 +352,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } else { - NekDouble de = fabs(i2rmDet) * sqrt(1E-3*1E-3 + 1E-3); + NekDouble de = fabs(d->maps[k][9]) * sqrt(1E-2*1E-2 + 1E-2); NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); dW[k] = frob / dim / pow(fabs(sigma), 2.0/dim); } @@ -429,7 +423,6 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, { integral += fabs(quadW(i)) * dW[i]; } - cout << integral << endl; return integral; } @@ -586,8 +579,6 @@ void ProcessVarOpti::Process() cout << scientific << endl; cout << "starting energy: " << functionalStart << endl; - exit(-1); - int nThreads = m_config["numthreads"].as(); int ctr = 0; @@ -655,19 +646,43 @@ void ProcessVarOpti::NodeOpti::Optimise() NekDouble yc = node->m_y; NekDouble zc = node->m_z; NekDouble alpha = 1.0; - NekDouble delX = 1.0/(G[3]*G[4]-G[6]*G[6])*(G[4]*G[0] - G[6]*G[1]); - NekDouble delY = 1.0/(G[3]*G[4]-G[6]*G[6])*(G[3]*G[1] - G[6]*G[0]); - //if(sqrt(delX*delX + delY*delY) > 1e-3) - //{ - // cout << endl; - // cout << delX << " " << delY << endl; - //} + NekDouble delX=0.0; + NekDouble delY=0.0; + NekDouble delZ=0.0; + if(dim == 2) + { + delX = 1.0/(G[3]*G[4]-G[6]*G[6])*(G[4]*G[0] - G[6]*G[1]); + delY = 1.0/(G[3]*G[4]-G[6]*G[6])*(G[3]*G[1] - G[6]*G[0]); + } + else + { + DNekMat H(3,3,0.0); + H(0,0) = G[3]; + H(1,1) = G[4]; + H(2,2) = G[5]; + H(0,1) = G[6]; + H(1,0) = G[6]; + H(0,2) = G[8]; + H(2,0) = G[8]; + H(2,1) = G[7]; + H(1,2) = G[7]; + H.Invert(); + NekVector g(3); + g[0] = G[0]; + g[1] = G[1]; + g[2] = G[2]; + NekVector del = H * g; + delX = del[0]; + delY = del[1]; + delZ = del[2]; + } + bool found = false; while(alpha > 1e-6) { node->m_x = xc - alpha * delX; node->m_y = yc - alpha * delY; - //node->m_z = zc - alpha * G[2]; + node->m_z = zc - alpha * delZ; if(GetFunctional() < currentW) { found = true; @@ -676,10 +691,6 @@ void ProcessVarOpti::NodeOpti::Optimise() alpha /= 2.0; } - //if(sqrt(delX*delX + delY*delY) > 1e-2) - //{ - // cout << alpha << endl; - //} if(!found) { @@ -697,15 +708,25 @@ void ProcessVarOpti::NodeOpti::Optimise() } } -NekDouble dir[9][2] = {{0.0,0.0}, - {1.0,0.0}, - {1.0,1.0}, - {0.0,1.0}, - {-1.0,1.0}, - {-1.0,0.0}, - {-1.0,-1.0}, - {0.0,-1.0}, - {1.0,-1.0}}; +NekDouble dir[19][3] = {{0.0,0.0,0.0}, + {1.0,0.0,0.0}, + {1.0,1.0,0.0}, + {0.0,1.0,0.0}, + {-1.0,1.0,0.0}, + {-1.0,0.0,0.0}, + {-1.0,-1.0,0.0}, + {0.0,-1.0,0.0}, + {1.0,-1.0,0.0}, + {-1.0,0.0,-1.0}, + {0.0,0.0,-1.0}, + {1.0,0.0,-1.0}, + {-1.0,0.0,1.0}, + {0.0,0.0,1.0}, + {1.0,0.0,1.0}, + {0.0,1.0,-1.0}, + {0.0,1.0,1.0}, + {0.0,-1.0,-1.0}, + {0.0,-1.0,1.0}}; Array ProcessVarOpti::NodeOpti::GetGrad() { @@ -714,15 +735,13 @@ Array ProcessVarOpti::NodeOpti::GetGrad() NekDouble zc = node->m_z; NekDouble dx = 1e-3; - ASSERTL0(dim == 2,"dir not coded in 3d"); - vector w; - for(int i = 0; i < 9; i++) + for(int i = 0; i < (dim == 2 ? 9 : 19); i++) { node->m_x = xc + dir[i][0] * dx; node->m_y = yc + dir[i][1] * dx; - //node->m_z = zc + dir[i][2] * dx; + node->m_z = zc + dir[i][2] * dx; w.push_back(GetFunctional()); } node->m_x = xc; @@ -742,6 +761,7 @@ Array ProcessVarOpti::NodeOpti::GetGrad() //ret[7] d2/dxdz //ret[8] d2/dydz + ret[0] = (w[1] - w[5]) / 2.0 / dx; ret[1] = (w[3] - w[7]) / 2.0 / dx; ret[3] = (w[1] + w[5] - 2.0*w[0]) / dx / dx; @@ -749,7 +769,10 @@ Array ProcessVarOpti::NodeOpti::GetGrad() ret[6] = (w[2] + w[6] - w[4] - w[8]) / 4.0 / dx /dx; if(dim == 3) { - ret[2] = (w[4] - w[5]) / 2.0 / dx; + ret[2] = (w[13] - w[10]) / 2.0 / dx; + ret[5] = (w[13] + w[10] - 2.0*w[0]) / dx / dx; + ret[7] = (w[14] + w[9] - w[11] - w[12]) / 4.0 / dx /dx; + ret[8] = (w[16] + w[17] - w[15] - w[18]) / 4.0 / dx /dx; } return ret; @@ -1130,8 +1153,14 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP dxdz(2,1) = z2(i); dxdz(2,2) = z3(i); + Array r(10,0.0); //store det in 10th entry + + r[9] = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) + -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) + +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); + dxdz.Invert(); - Array r(9,0.0); + r[0] = dxdz(0,0); r[1] = dxdz(1,0); r[2] = dxdz(2,0); -- GitLab From 7ddabbaa4d90dabc21dc49180aad3e33abd63593 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Thu, 5 May 2016 16:25:42 +0100 Subject: [PATCH 023/236] over interpolation --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 153 +++++++----------- .../NekMesh/ProcessModules/ProcessVarOpti.h | 17 +- 2 files changed, 63 insertions(+), 107 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index c11a65702..5a30934ce 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -57,36 +57,36 @@ namespace Utilities boost::mutex mtx; NekMatrix interp; - -inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, - NekMatrix &VdmDx, - NekMatrix &VdmDy, - NekMatrix &VdmDz, - NekVector &quadW) +int ptsLow; +int ptsHigh; +int dim; +NekMatrix VdmDx; +NekMatrix VdmDy; +NekMatrix VdmDz; +NekVector quadW; +optimiser opti; + +inline NekDouble GetElFunctional(ElDataSharedPtr d) { vector ns; d->el->GetCurvedNodes(ns); - int pts = ns.size(); - int pts2 = VdmDx.GetRows(); - - //cout << pts2 << " " << interp.GetRows() << " " << interp.GetColumns() << endl; - ASSERTL0(pts2 == d->maps.size(), "what"); + ASSERTL0(ptsHigh == d->maps.size(), "what"); - Array > jac(pts2); + Array > jac(ptsHigh); if(dim == 2) { - NekVector X(pts),Y(pts), - x1(pts2),y1(pts2), - x2(pts2),y2(pts2); - for(int i = 0; i < pts; i++) + NekVector X(ptsLow),Y(ptsLow), + x1(ptsHigh),y1(ptsHigh), + x2(ptsHigh),y2(ptsHigh); + for(int i = 0; i < ptsLow; i++) { X(i) = ns[i]->m_x; Y(i) = ns[i]->m_y; } - NekVector Xint(pts2), Yint(pts2); + NekVector Xint(ptsHigh), Yint(ptsHigh); Xint = interp * X; Yint = interp * Y; @@ -95,7 +95,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, x2 = VdmDy*Xint; y2 = VdmDy*Yint; - for(int i = 0; i < pts2; i++) + for(int i = 0; i < ptsHigh; i++) { Array jaci(9,0.0); jaci[0] = x1(i); @@ -109,7 +109,8 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } else { - NekVector X(pts),Y(pts),Z(pts), + ASSERTL0(false,"fix"); + /*NekVector X(pts),Y(pts),Z(pts), x1(pts),y1(pts),z1(pts), x2(pts),y2(pts),z2(pts), x3(pts),y3(pts),z3(pts); @@ -144,16 +145,16 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, jaci[8] = z3(i); jac[i] = jaci; - } + }*/ } - Array dW(pts2); + Array dW(ptsHigh); switch (opti) { case eLinEl: { - for(int k = 0; k < pts2; k++) + for(int k = 0; k < ptsHigh; k++) { Array jacIdeal(9,0.0); jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; @@ -182,36 +183,17 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, (jacIdeal[0]*jacIdeal[3]+jacIdeal[1]*jacIdeal[4]+jacIdeal[3]*jacIdeal[5]); NekDouble trEtE = 0.25 * (a+b+c) + 0.5 * (D+e+f); - /*NekDouble jacDet; - if(dim == 2) - { - jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; - } - else - { - jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) - -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) - +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - } - - NekDouble ljacDet = log(jacDet); - NekDouble nu = 0.45; - NekDouble mu = 1.0/2.0/(1.0+nu); - NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); - dW[k] = K *0.5 * ljacDet * ljacDet + mu * trEtE;*/ - NekDouble jacDet, i2rmDet = 0.0; + NekDouble jacDet; if(dim == 2) { jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; - i2rmDet = 1.0 / (d->maps[k][0]*d->maps[k][4] - d->maps[k][1]*d->maps[k][3]); } else { jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - ASSERTL0(false,"need to extend to do i2rmDet in 3d"); } NekDouble ljacDet = log(jacDet); @@ -225,7 +207,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } else { - NekDouble de = fabs(i2rmDet) * sqrt(1E-1*1E-1 + 1E-1); + NekDouble de = fabs(d->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); NekDouble lsigma = log(sigma); dW[k] = K *0.5 * lsigma * lsigma + mu * trEtE; @@ -236,7 +218,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } case eHypEl: { - for(int k = 0; k < pts2; k++) + for(int k = 0; k < ptsHigh; k++) { Array jacIdeal(9,0.0); jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; @@ -261,7 +243,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, jacIdeal[7]*jacIdeal[7] + jacIdeal[8]*jacIdeal[8]; - /*NekDouble jacDet; + NekDouble jacDet; if(dim == 2) { jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; @@ -273,25 +255,6 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); } - NekDouble ljacDet = log(jacDet); - NekDouble nu = 0.45; - NekDouble mu = 1.0/2.0/(1.0+nu); - NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); - dW[k] = 0.5 * mu * (I1 - 3.0 - 2.0*ljacDet) + 0.5 * K * ljacDet * ljacDet;*/ - NekDouble jacDet, i2rmDet = 0.0; - if(dim == 2) - { - jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; - i2rmDet = 1.0 / (d->maps[k][0]*d->maps[k][4] - d->maps[k][1]*d->maps[k][3]); - } - else - { - jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) - -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) - +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - ASSERTL0(false,"need to extend to do i2rmDet in 3d"); - } - NekDouble ljacDet = log(jacDet); NekDouble nu = 0.45; NekDouble mu = 1.0/2.0/(1.0+nu); @@ -303,7 +266,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } else { - NekDouble de = fabs(i2rmDet) * sqrt(1E-1*1E-1 + 1E-1); + NekDouble de = fabs(d->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); NekDouble lsigma = log(sigma); dW[k] = 0.5 * mu * (I1 - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma; @@ -314,7 +277,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } case eRoca: { - for(int k = 0; k < pts; k++) + for(int k = 0; k < ptsHigh; k++) { Array jacIdeal(9,0.0); jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; @@ -329,7 +292,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; - NekDouble jacDet = 0.0; + NekDouble jacDet; if(dim == 2) { jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; @@ -359,7 +322,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } else { - NekDouble de = fabs(d->maps[k][9]) * sqrt(1E-2*1E-2 + 1E-2); + NekDouble de = fabs(d->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); dW[k] = frob / dim / pow(fabs(sigma), 2.0/dim); } @@ -369,7 +332,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } case eWins: { - for(int k = 0; k < pts; k++) + for(int k = 0; k < ptsHigh; k++) { Array jacIdeal(9,0.0); jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; @@ -384,18 +347,16 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; - NekDouble jacDet, i2rmDet = 0.0; + NekDouble jacDet; if(dim == 2) { jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; - i2rmDet = 1.0 / (d->maps[k][0]*d->maps[k][4] - d->maps[k][1]*d->maps[k][3]); } else { jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - ASSERTL0(false,"need to extend to do i2rmDet in 3d"); } NekDouble frob = 0.0; @@ -412,13 +373,13 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, if(jacDet > 0) { - dW[k] = frob / dim / pow(fabs(jacDet), 2.0/dim); + dW[k] = frob / jacDet; } else { - NekDouble de = fabs(i2rmDet) * sqrt(1E-2*1E-2 + 1E-2); + NekDouble de = fabs(d->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - dW[k] = frob / dim / pow(fabs(sigma), 2.0/dim); + dW[k] = frob / sigma; } } break; @@ -426,9 +387,9 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d, optimiser opti, int dim, } NekDouble integral = 0.0; - for(int i = 0; i < dW.num_elements(); i++) + for(int i = 0; i < ptsHigh; i++) { - integral += fabs(quadW(i)) * dW[i]; + integral += quadW(i) * dW[i]; } return integral; } @@ -500,13 +461,16 @@ void ProcessVarOpti::Process() FillQuadPoints(); //build Vandermonde information + dim = m_mesh->m_spaceDim; switch (m_mesh->m_spaceDim) { case 2: { + ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)/2; + ptsHigh = (3*m_mesh->m_nummode-4)*((3*m_mesh->m_nummode-4)+1)/2; LibUtilities::PointsKey pkey1(m_mesh->m_nummode, LibUtilities::eNodalTriElec); - LibUtilities::PointsKey pkey2(2*m_mesh->m_nummode, + LibUtilities::PointsKey pkey2(3*m_mesh->m_nummode-4, LibUtilities::eNodalTriElec); Array u1, v1, u2, v2; LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); @@ -516,8 +480,8 @@ void ProcessVarOpti::Process() interp = LibUtilities::GetInterpolationMatrix(U1, V1, U2, V2); - Vandermonde = LibUtilities::GetVandermonde(U2,V2); - VandermondeI = Vandermonde; + NekMatrix Vandermonde = LibUtilities::GetVandermonde(U2,V2); + NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); VdmDx = LibUtilities::GetVandermondeForXDerivative(U2,V2) * VandermondeI; @@ -541,8 +505,8 @@ void ProcessVarOpti::Process() V(i) = v[i]; W(i) = w[i]; } - Vandermonde = LibUtilities::GetTetVandermonde(U,V,W); - VandermondeI = Vandermonde; + NekMatrix Vandermonde = LibUtilities::GetTetVandermonde(U,V,W); + NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); VdmDx = LibUtilities::GetVandermondeForTetXDerivative(U,V,W) * VandermondeI; @@ -554,8 +518,6 @@ void ProcessVarOpti::Process() } } - cout << quadW << endl << endl; - GetElementMap(); vector > freenodes = GetColouredNodes(); @@ -571,8 +533,7 @@ void ProcessVarOpti::Process() { NodeElMap::iterator it = nodeElMap.find(freenodes[i][j]->m_id); ASSERTL0(it != nodeElMap.end(),"could not find"); - ns.push_back(NodeOpti(freenodes[i][j],it->second,opti,res,m_mesh->m_spaceDim, - VdmDx,VdmDy,VdmDz,quadW)); + ns.push_back(NodeOpti(freenodes[i][j],it->second,res)); } optiNodes.push_back(ns); } @@ -580,8 +541,7 @@ void ProcessVarOpti::Process() NekDouble functionalStart = 0.0; for(int i = 0; i < m_mesh->m_element[2].size(); i++) { - functionalStart += GetElFunctional(dataSet[i], opti, m_mesh->m_spaceDim, - VdmDx,VdmDy,VdmDz,quadW); + functionalStart += GetElFunctional(dataSet[i]); } cout << scientific << endl; @@ -626,8 +586,7 @@ void ProcessVarOpti::Process() functionalStart = 0.0; for(int i = 0; i < m_mesh->m_element[2].size(); i++) { - functionalStart += GetElFunctional(dataSet[i], opti, m_mesh->m_spaceDim, - VdmDx,VdmDy,VdmDz,quadW); + functionalStart += GetElFunctional(dataSet[i]); } cout << "end energy: " << functionalStart << endl; @@ -685,6 +644,11 @@ void ProcessVarOpti::NodeOpti::Optimise() delZ = del[2]; } + if(sqrt(delX*delX + delY*delY) > 1e-2) + { + return; + } + bool found = false; while(alpha > 1e-6) { @@ -791,7 +755,7 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() NekDouble r = 0.0; for(int i = 0; i < data.size(); i++) { - r += GetElFunctional(data[i], opti,dim,VdmDx,VdmDy,VdmDz,quadW); + r += GetElFunctional(data[i]); } return r; } @@ -1058,7 +1022,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP } else if(geom->GetShapeType() == LibUtilities::eTriangle) { - LibUtilities::PointsKey pkey(2*m_mesh->m_nummode, + LibUtilities::PointsKey pkey(3*m_mesh->m_nummode-4, LibUtilities::eNodalTriElec); Array u, v; LibUtilities::PointsManager()[pkey]->GetPoints(u, v); @@ -1096,8 +1060,11 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP dxdz(1,0) = y1(i); dxdz(1,1) = y2(i); + Array r(10,0.0); + r[9] = dxdz(0,0)*dxdz(1,1)-dxdz(1,0)*dxdz(0,1); + dxdz.Invert(); - Array r(9,0.0); + r[0] = dxdz(0,0); r[1] = dxdz(1,0); r[3] = dxdz(0,1); diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index 0ee82bf44..74ff098d8 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -98,22 +98,15 @@ private: NodeElMap nodeElMap; vector dataSet; - optimiser opti; - NekMatrix Vandermonde, VandermondeI, VdmDx, VdmDy, VdmDz; - NekVector quadW; class NodeOptiJob; class NodeOpti { public: - NodeOpti(NodeSharedPtr n, vector e, optimiser o, - ResidualSharedPtr r, int d, - NekMatrix &vx, NekMatrix &vy, - NekMatrix &vz, - NekVector &w) - : node(n), data(e), opti(o), res(r), dim(d), - VdmDx(vx), VdmDy(vy), VdmDz(vz), quadW(w) + NodeOpti(NodeSharedPtr n, vector e, + ResidualSharedPtr r) + : node(n), data(e), res(r) { } @@ -129,11 +122,7 @@ private: NekDouble GetFunctional(); NodeSharedPtr node; vector data; - optimiser opti; ResidualSharedPtr res; - int dim; - NekMatrix VdmDx, VdmDy, VdmDz; - NekVector quadW; }; class NodeOptiJob : public Thread::ThreadJob -- GitLab From 448f47990eee608423a501889c7a9d7d2ce970ef Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Thu, 5 May 2016 16:50:17 +0100 Subject: [PATCH 024/236] fix roca --- utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 5a30934ce..7a3484ea9 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -324,9 +324,8 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d) { NekDouble de = fabs(d->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - dW[k] = frob / dim / pow(fabs(sigma), 2.0/dim); + dW[k] = frob / dim / pow(fabs(sigma), 2.0/dim) -1.0; } - dW[k] = (dW[k]-1.0)*(dW[k]-1.0); } break; } -- GitLab From 08e78291f62b89c449cfbac694a8697e6ada9d9c Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Fri, 6 May 2016 09:47:33 +0100 Subject: [PATCH 025/236] tets and residual --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 109 ++++++++++-------- .../NekMesh/ProcessModules/ProcessVarOpti.h | 3 + 2 files changed, 67 insertions(+), 45 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 7a3484ea9..6d019d6b5 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -109,29 +109,33 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d) } else { - ASSERTL0(false,"fix"); - /*NekVector X(pts),Y(pts),Z(pts), - x1(pts),y1(pts),z1(pts), - x2(pts),y2(pts),z2(pts), - x3(pts),y3(pts),z3(pts); - for(int i = 0; i < pts; i++) + NekVector X(ptsLow),Y(ptsLow),Z(ptsLow), + x1(ptsHigh),y1(ptsHigh),z1(ptsHigh), + x2(ptsHigh),y2(ptsHigh),z2(ptsHigh), + x3(ptsHigh),y3(ptsHigh),z3(ptsHigh); + for(int i = 0; i < ptsLow; i++) { X(i) = ns[i]->m_x; Y(i) = ns[i]->m_y; Z(i) = ns[i]->m_z; } - x1 = VdmDx*X; - y1 = VdmDx*Y; - z1 = VdmDx*Z; - x2 = VdmDy*X; - y2 = VdmDy*Y; - z2 = VdmDy*Z; - x3 = VdmDz*X; - y3 = VdmDz*Y; - z3 = VdmDz*Z; - - for(int i = 0; i < pts; i++) + NekVector Xint(ptsHigh), Yint(ptsHigh), Zint(ptsHigh); + Xint = interp * X; + Yint = interp * Y; + Zint = interp * Z; + + x1 = VdmDx*Xint; + y1 = VdmDx*Yint; + z1 = VdmDx*Zint; + x2 = VdmDy*Xint; + y2 = VdmDy*Yint; + z2 = VdmDy*Zint; + x3 = VdmDz*Xint; + y3 = VdmDz*Yint; + z3 = VdmDz*Zint; + + for(int i = 0; i < ptsHigh; i++) { Array jaci(9,0.0); jaci[0] = x1(i); @@ -145,7 +149,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d) jaci[8] = z3(i); jac[i] = jaci; - }*/ + } } Array dW(ptsHigh); @@ -491,39 +495,43 @@ void ProcessVarOpti::Process() break; case 3: { - LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTetElec); - Array u, v, w; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); - - NekVector U(u.num_elements()) , V(v.num_elements()), - W(u.num_elements()); - for(int i = 0; i < u.num_elements(); i++) - { - U(i) = u[i]; - V(i) = v[i]; - W(i) = w[i]; - } - NekMatrix Vandermonde = LibUtilities::GetTetVandermonde(U,V,W); + ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)*(m_mesh->m_nummode+2)/6; + ptsHigh = (3*m_mesh->m_nummode-4)*((3*m_mesh->m_nummode-4)+1) + *((3*m_mesh->m_nummode-4)+2)/6; + LibUtilities::PointsKey pkey1(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + LibUtilities::PointsKey pkey2(3*m_mesh->m_nummode-4, + LibUtilities::eNodalTetElec); + Array u1, v1, u2, v2, w1, w2; + LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1, w1); + LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2, w2); + NekVector U1(u1), V1(v1), W1(w1); + NekVector U2(u2), V2(v2), W2(w2); + + interp = LibUtilities::GetTetInterpolationMatrix(U1, V1, W1, + U2, V2, W2); + + NekMatrix Vandermonde = + LibUtilities::GetTetVandermonde(U2,V2,W2); NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); - VdmDx = LibUtilities::GetVandermondeForTetXDerivative(U,V,W) * + VdmDx = LibUtilities::GetVandermondeForTetXDerivative(U2,V2,W2) * VandermondeI; - VdmDy = LibUtilities::GetVandermondeForTetYDerivative(U,V,W) * + VdmDy = LibUtilities::GetVandermondeForTetYDerivative(U2,V2,W2) * VandermondeI; - VdmDz = LibUtilities::GetVandermondeForTetZDerivative(U,V,W) * + VdmDz = LibUtilities::GetVandermondeForTetZDerivative(U2,V2,W2) * VandermondeI; - quadW = LibUtilities::MakeTetWeights(U,V,W); + quadW = LibUtilities::MakeTetWeights(U2,V2,W2); } } + res = boost::shared_ptr(new Residual); + res->val = 1.0; + GetElementMap(); vector > freenodes = GetColouredNodes(); - ResidualSharedPtr res = boost::shared_ptr(new Residual); - res->val = 1.0; - vector > optiNodes; for(int i = 0; i < freenodes.size(); i++) { @@ -544,6 +552,9 @@ void ProcessVarOpti::Process() } cout << scientific << endl; + cout << "N elements: " << m_mesh->m_element[m_mesh->m_expDim].size() << endl + << "N free nodes: " << res->n << endl + << "N Dof: " << res->nDoF << endl; cout << "starting energy: " << functionalStart << endl; int nThreads = m_config["numthreads"].as(); @@ -554,7 +565,7 @@ void ProcessVarOpti::Process() Thread::ThreadManagerSharedPtr tm = tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads); - while (res->val > 1e-3) + while (res->val > 1e-6) { ctr++; res->val = 0.0; @@ -579,6 +590,8 @@ void ProcessVarOpti::Process() }*/ } + res->val = sqrt(res->val / res->n); + cout << ctr << "\tResidual: " << res->val << endl; } @@ -673,8 +686,8 @@ void ProcessVarOpti::NodeOpti::Optimise() // cout << G[0] << " " << G[1] << " " << G[2] << " " << node->m_id << endl; } mtx.lock(); - res->val += sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ - (node->m_z-zc)*(node->m_z-zc)); + res->val += (node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ + (node->m_z-zc)*(node->m_z-zc); mtx.unlock(); } } @@ -885,6 +898,9 @@ vector > ProcessVarOpti::GetColouredNodes() } } + res->n = remain.size(); + res->nDoF = res->n * dim; + vector > ret; while (remain.size() > 0) @@ -1073,7 +1089,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP } else if(geom->GetShapeType() == LibUtilities::eTetrahedron) { - LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::PointsKey pkey(3*m_mesh->m_nummode-4, LibUtilities::eNodalTetElec); Array u, v, w; LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); @@ -1417,7 +1433,10 @@ void ProcessVarOpti::FillQuadPoints() vector hons; - //need to finish for tet + ASSERTL0(4 + 6*(nq-2) + 4 * ((nq-2)*(nq-3) / 2) <= u.num_elements(), + "volume interior nodes in tet"); + + /*//need to finish for tet for(int j = 4 + 6*(nq-2) + 4 * ((nq-2)*(nq-3) / 2); j < u.num_elements(); j++) { @@ -1432,7 +1451,7 @@ void ProcessVarOpti::FillQuadPoints() xmap->PhysEvaluate(xp,zc)))); } - el->SetVolumeNodes(hons); + el->SetVolumeNodes(hons);*/ el->SetCurveType(LibUtilities::eNodalTetElec); } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index 74ff098d8..fe6c8d96e 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -62,6 +62,8 @@ enum optimiser struct Residual { NekDouble val; + int n; + int nDoF; }; typedef boost::shared_ptr ResidualSharedPtr; @@ -98,6 +100,7 @@ private: NodeElMap nodeElMap; vector dataSet; + ResidualSharedPtr res; class NodeOptiJob; -- GitLab From 3a879d664620921c20c5f98275bd10b0ad98de1e Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Sun, 8 May 2016 10:23:38 +0100 Subject: [PATCH 026/236] verbosity, tets not working --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 58 ++++++++++++++----- .../NekMesh/ProcessModules/ProcessVarOpti.h | 4 ++ 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 6d019d6b5..5bcbc34f1 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -461,6 +461,9 @@ void ProcessVarOpti::Process() ASSERTL0(false,"cannot deal with manifolds"); } + res = boost::shared_ptr(new Residual); + res->val = 1.0; + FillQuadPoints(); //build Vandermonde information @@ -525,9 +528,6 @@ void ProcessVarOpti::Process() } } - res = boost::shared_ptr(new Residual); - res->val = 1.0; - GetElementMap(); vector > freenodes = GetColouredNodes(); @@ -545,17 +545,33 @@ void ProcessVarOpti::Process() optiNodes.push_back(ns); } - NekDouble functionalStart = 0.0; + res->startE = 0.0; for(int i = 0; i < m_mesh->m_element[2].size(); i++) { - functionalStart += GetElFunctional(dataSet[i]); + res->startE += GetElFunctional(dataSet[i]); + } + + int nset = optiNodes.size(); + int p = 0; + int mn = numeric_limits::max(); + int mx = 0; + for(int i = 0; i < nset; i++) + { + p += optiNodes[i].size(); + mn = min(mn, int(optiNodes[i].size())); + mx = max(mx, int(optiNodes[i].size())); } cout << scientific << endl; - cout << "N elements: " << m_mesh->m_element[m_mesh->m_expDim].size() << endl - << "N free nodes: " << res->n << endl - << "N Dof: " << res->nDoF << endl; - cout << "starting energy: " << functionalStart << endl; + cout << "N elements:\t\t" << m_mesh->m_element[m_mesh->m_expDim].size() << endl + << "N elements invalid:\t" << res->startInv << endl + << "N free nodes:\t\t" << res->n << endl + << "N Dof:\t\t\t" << res->nDoF << endl + << "N color sets:\t\t" << nset << endl + << "Avg set colors:\t\t" << p/nset << endl + << "Min set:\t\t" << mn << endl + << "Max set:\t\t" << mx << endl; + cout << "Starting energy:\t" << res->startE << endl; int nThreads = m_config["numthreads"].as(); @@ -565,7 +581,7 @@ void ProcessVarOpti::Process() Thread::ThreadManagerSharedPtr tm = tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads); - while (res->val > 1e-6) + while (res->val > 1e-5) { ctr++; res->val = 0.0; @@ -595,12 +611,12 @@ void ProcessVarOpti::Process() cout << ctr << "\tResidual: " << res->val << endl; } - functionalStart = 0.0; + res->endE = 0.0; for(int i = 0; i < m_mesh->m_element[2].size(); i++) { - functionalStart += GetElFunctional(dataSet[i]); + res->endE += GetElFunctional(dataSet[i]); } - cout << "end energy: " << functionalStart << endl; + cout << "end energy: " << res->endE << endl; if(m_config["stats"].beenSet) { @@ -1455,6 +1471,22 @@ void ProcessVarOpti::FillQuadPoints() el->SetCurveType(LibUtilities::eNodalTetElec); } } + + res->startInv =0; + res->worstJac = numeric_limits::max(); + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + + SpatialDomains::GeometrySharedPtr geom = + el->GetGeom(m_mesh->m_spaceDim); + SpatialDomains::GeomFactorsSharedPtr gfac = geom->GetGeomFactors(); + if(!gfac->IsValid()) + { + res->startInv++; + } + } } void ProcessVarOpti::WriteStats(string file) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index fe6c8d96e..a43fab4b8 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -64,6 +64,10 @@ struct Residual NekDouble val; int n; int nDoF; + NekDouble startE; + NekDouble endE; + int startInv; + NekDouble worstJac; }; typedef boost::shared_ptr ResidualSharedPtr; -- GitLab From 29afda8653750867654e215b0af75a412fa1fd50 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 9 May 2016 11:12:59 +0100 Subject: [PATCH 027/236] add new point class --- library/LibUtilities/CMakeLists.txt | 3 + .../LibUtilities/Foundations/Foundations.hpp | 9 +- .../Foundations/ManagerAccess.cpp | 12 +- .../LibUtilities/Foundations/NodalTriSPI.cpp | 114 ++++++++++++++++++ .../LibUtilities/Foundations/NodalTriSPI.h | 79 ++++++++++++ .../Foundations/NodalTriSPIData.h | 71 +++++++++++ library/LibUtilities/Foundations/Points.h | 54 +++++---- library/LibUtilities/Foundations/PointsType.h | 5 +- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 85 ++++++++----- 9 files changed, 364 insertions(+), 68 deletions(-) create mode 100644 library/LibUtilities/Foundations/NodalTriSPI.cpp create mode 100644 library/LibUtilities/Foundations/NodalTriSPI.h create mode 100644 library/LibUtilities/Foundations/NodalTriSPIData.h diff --git a/library/LibUtilities/CMakeLists.txt b/library/LibUtilities/CMakeLists.txt index 65f699fac..bf50e0f17 100644 --- a/library/LibUtilities/CMakeLists.txt +++ b/library/LibUtilities/CMakeLists.txt @@ -120,6 +120,8 @@ SET(FoundationHeaders ./Foundations/NodalTriEvenlySpaced.h ./Foundations/NodalTriFeketeData.h ./Foundations/NodalTriFekete.h + ./Foundations/NodalTriSPIData.h + ./Foundations/NodalTriSPI.h ./Foundations/NodalUtil.h ./Foundations/PhysGalerkinProject.h ./Foundations/Points.h @@ -143,6 +145,7 @@ SET(FoundationSources ./Foundations/NodalTriElec.cpp ./Foundations/NodalTriEvenlySpaced.cpp ./Foundations/NodalTriFekete.cpp + ./Foundations/NodalTriSPI.cpp ./Foundations/NodalUtil.cpp ./Foundations/PhysGalerkinProject.cpp ./Foundations/Points.cpp diff --git a/library/LibUtilities/Foundations/Foundations.hpp b/library/LibUtilities/Foundations/Foundations.hpp index 1fd909dd0..bb2c26244 100644 --- a/library/LibUtilities/Foundations/Foundations.hpp +++ b/library/LibUtilities/Foundations/Foundations.hpp @@ -41,10 +41,10 @@ #include namespace Nektar -{ +{ namespace LibUtilities - { - const char* const BasisTypeMap[] = + { + const char* const BasisTypeMap[] = { "NoBasisType", "Ortho_A", @@ -66,7 +66,7 @@ namespace Nektar - const std::string kPointsTypeStr[] = + const std::string kPointsTypeStr[] = { "NoPointsType", "GaussGaussLegendre", @@ -92,6 +92,7 @@ namespace Nektar "BoundaryLayerPointsRev", "NodalTriElec", "NodalTriFekete", + "NodalTriSPI", "NodalTriEvenlySpaced", "NodalTetEvenlySpaced", "NodalTetElec", diff --git a/library/LibUtilities/Foundations/ManagerAccess.cpp b/library/LibUtilities/Foundations/ManagerAccess.cpp index 128af3b60..a94e51a7e 100644 --- a/library/LibUtilities/Foundations/ManagerAccess.cpp +++ b/library/LibUtilities/Foundations/ManagerAccess.cpp @@ -28,8 +28,8 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// -// Description: C functions to provide access to managers. +// +// Description: C functions to provide access to managers. // /////////////////////////////////////////////////////////////////////////////// @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -51,7 +52,7 @@ namespace Nektar { - namespace LibUtilities + namespace LibUtilities { // Register all points and basis creators. namespace @@ -68,12 +69,12 @@ namespace Nektar const bool gaussInited10 = PointsManager().RegisterCreator(PointsKey(0, eGaussRadauMAlpha0Beta2), GaussPoints::Create); const bool gaussInited11 = PointsManager().RegisterCreator(PointsKey(0, eGaussRadauMAlpha1Beta0), GaussPoints::Create); const bool gaussInited12 = PointsManager().RegisterCreator(PointsKey(0, eGaussRadauMAlpha2Beta0), GaussPoints::Create); - + const bool gaussInited13 = PointsManager().RegisterCreator(PointsKey(0, eGaussKronrodLegendre), GaussPoints::Create); const bool gaussInited14 = PointsManager().RegisterCreator(PointsKey(0, eGaussRadauKronrodMLegendre), GaussPoints::Create); const bool gaussInited15 = PointsManager().RegisterCreator(PointsKey(0, eGaussRadauKronrodMAlpha1Beta0), GaussPoints::Create); const bool gaussInited16 = PointsManager().RegisterCreator(PointsKey(0, eGaussLobattoKronrodLegendre), GaussPoints::Create); - + const bool fourierInited0 = PointsManager().RegisterCreator(PointsKey(0, eFourierEvenlySpaced), FourierPoints::Create); const bool fourierInitedSM0 = PointsManager().RegisterCreator(PointsKey(0, eFourierSingleModeSpaced), FourierSingleModePoints::Create); const bool BLInited0 = PointsManager().RegisterCreator(PointsKey(0, eBoundaryLayerPoints), BLPoints::Create); @@ -81,6 +82,7 @@ namespace Nektar const bool polyeInited10 = PointsManager().RegisterCreator(PointsKey(0, ePolyEvenlySpaced), PolyEPoints::Create); const bool NodalTriInited0 = PointsManager().RegisterCreator(PointsKey(0, eNodalTriElec), NodalTriElec::Create); const bool NodalTriInited1 = PointsManager().RegisterCreator(PointsKey(0, eNodalTriFekete), NodalTriFekete::Create); + const bool NodalTriInited2 = PointsManager().RegisterCreator(PointsKey(0, eNodalTriSPI), NodalTriSPI::Create); const bool nodalTetElecInited = PointsManager().RegisterCreator(PointsKey(0, eNodalTetElec), NodalTetElec::Create); const bool NodalTriEveInited = PointsManager().RegisterCreator(PointsKey(0, eNodalTriEvenlySpaced), NodalTriEvenlySpaced::Create); const bool NodalTetEveInited = PointsManager().RegisterCreator(PointsKey(0, eNodalTetEvenlySpaced), NodalTetEvenlySpaced::Create); diff --git a/library/LibUtilities/Foundations/NodalTriSPI.cpp b/library/LibUtilities/Foundations/NodalTriSPI.cpp new file mode 100644 index 000000000..2d57598c7 --- /dev/null +++ b/library/LibUtilities/Foundations/NodalTriSPI.cpp @@ -0,0 +1,114 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// File NodalTriElec.cpp +// +// For more information, please see: http://www.nektar.info +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: 2D Nodal Triangle Fekete Point Definitions +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include + +namespace Nektar +{ + namespace LibUtilities + { + void NodalTriSPI::CalculatePoints() + { + // Allocate the storage for points + unsigned int numPoints = GetNumPoints(); + + for(int i = 0; i < 2; i++) + { + m_points[i] = Array(NodalTriSPINPTS[numPoints-2]); + } + + int index=0; + + // initialize values + for(unsigned int i=0; i < numPoints-2; ++i) + { + index += NodalTriSPINPTS[i]; + } + + for(int i = 0; i < NodalTriSPINPTS[numPoints-2]; i++) + { + m_points[0][i] = NodalTriSPIData[index][0]; + m_points[1][i] = NodalTriSPIData[index][1]; + index++; + } + + + //exit(0); + } + + void NodalTriSPI::CalculateWeights() + { + unsigned int numPoints = GetNumPoints(); + + m_weights = Array(NodalTriSPINPTS[numPoints-2]); + + int index=0; + + // initialize values + for(unsigned int i=0; i < numPoints-2; ++i) + { + index += NodalTriSPINPTS[i]; + } + + for(int i = 0; i < NodalTriSPINPTS[numPoints-2]; i++) + { + m_weights[i] = NodalTriSPIData[index][2]; + index++; + } + } + + void NodalTriSPI::CalculateDerivMatrix() + { + + } + + boost::shared_ptr NodalTriSPI::Create(const PointsKey &key) + { + boost::shared_ptr returnval(MemoryManager::AllocateSharedPtr(key)); + returnval->Initialize(); + return returnval; + } + + + } // end of namespace stdregion +} // end of namespace stdregion + + diff --git a/library/LibUtilities/Foundations/NodalTriSPI.h b/library/LibUtilities/Foundations/NodalTriSPI.h new file mode 100644 index 000000000..138724841 --- /dev/null +++ b/library/LibUtilities/Foundations/NodalTriSPI.h @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// File NodalTriElec.h +// +// For more information, please see: http://www.nektar.info +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Header file of 2D Nodal Triangle Fekete Points +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NODALTRISPI_H +#define NODALTRISPI_H + +#include +#include +#include +#include +#include +#include + +namespace Nektar +{ + namespace LibUtilities + { + + class NodalTriSPI: public Points + { + public: + + virtual ~NodalTriSPI() + { + } + + LIB_UTILITIES_EXPORT static boost::shared_ptr + Create(const PointsKey &key); + + NodalTriSPI(const PointsKey &key):PointsBaseType(key) + { + } + + private: + NodalTriSPI():PointsBaseType(NullPointsKey) + { + } + + void CalculatePoints(); + void CalculateWeights(); + void CalculateDerivMatrix(); + + }; + } // end of namespace +} // end of namespace + +#endif //NODALTRIELEC_H diff --git a/library/LibUtilities/Foundations/NodalTriSPIData.h b/library/LibUtilities/Foundations/NodalTriSPIData.h new file mode 100644 index 000000000..260e83cef --- /dev/null +++ b/library/LibUtilities/Foundations/NodalTriSPIData.h @@ -0,0 +1,71 @@ + +namespace Nektar +{ + namespace LibUtilities + { + const unsigned int NodalTriSPIAvailable = 7; + static const unsigned int NodalTriSPINPTS[NodalTriSPIAvailable] = {1,3,6,6,7,12,15}; + static const NekDouble NodalTriSPIData[][3] = { + + // %%% x y w + // 1 1 %%% Order / Number of Points + {-0.33333333333333333333333333333333333333,-0.33333333333333333333333333333333333333, 2}, + // 2 3 %%% Order / Number of Points + {-0.66666666666666666666666666666666666667, 0.33333333333333333333333333333333333333, 0.66666666666666666666666666666666666667}, + {0.33333333333333333333333333333333333333, -0.66666666666666666666666666666666666667, 0.66666666666666666666666666666666666667}, + {-0.66666666666666666666666666666666666667, -0.66666666666666666666666666666666666667, 0.66666666666666666666666666666666666667}, + //3 6 %%% Order / Number of Points + {-0.1081030181680702273633414922338960232, -0.7837939636638595452733170155322079536, 0.44676317935602293139001401686624560874}, + {-0.7837939636638595452733170155322079536, -0.1081030181680702273633414922338960232, 0.44676317935602293139001401686624560874}, + {-0.1081030181680702273633414922338960232, -0.1081030181680702273633414922338960232, 0.44676317935602293139001401686624560874}, + {-0.81684757298045851308085707319559698429, 0.63369514596091702616171414639119396858, 0.21990348731064373527665264980042105793}, + {0.63369514596091702616171414639119396858, -0.81684757298045851308085707319559698429, 0.21990348731064373527665264980042105793}, + {-0.81684757298045851308085707319559698429, -0.81684757298045851308085707319559698429, 0.21990348731064373527665264980042105793}, + //4 6 %%% Order / Number of Points + {-0.1081030181680702273633414922338960232, -0.7837939636638595452733170155322079536, 0.44676317935602293139001401686624560874}, + {-0.7837939636638595452733170155322079536, -0.1081030181680702273633414922338960232, 0.44676317935602293139001401686624560874}, + {-0.1081030181680702273633414922338960232, -0.1081030181680702273633414922338960232, 0.44676317935602293139001401686624560874}, + {-0.81684757298045851308085707319559698429, 0.63369514596091702616171414639119396858, 0.21990348731064373527665264980042105793}, + {0.63369514596091702616171414639119396858, -0.81684757298045851308085707319559698429, 0.21990348731064373527665264980042105793}, + {-0.81684757298045851308085707319559698429, -0.81684757298045851308085707319559698429, 0.21990348731064373527665264980042105793}, + // 5 7 %%% Order / Number of Points + {-0.33333333333333333333333333333333333333, -0.33333333333333333333333333333333333333, 0.45}, + {-0.79742698535308732239802527616975234389, 0.59485397070617464479605055233950468778, 0.25187836108965430519136789100036266732}, + {0.59485397070617464479605055233950468778, -0.79742698535308732239802527616975234389, 0.25187836108965430519136789100036266732}, + {-0.79742698535308732239802527616975234389, -0.79742698535308732239802527616975234389, 0.25187836108965430519136789100036266732}, + {-0.059715871789769820459117580973104798968, -0.88056825642046035908176483805379040206, 0.26478830557701236147529877566630399935}, + {-0.88056825642046035908176483805379040206, -0.059715871789769820459117580973104798968, 0.26478830557701236147529877566630399935}, + {-0.059715871789769820459117580973104798968, -0.059715871789769820459117580973104798968, 0.26478830557701236147529877566630399935}, + // 6 12 %%% Order / Number of Points + {-0.87382197101699554331933679425836168532, 0.74764394203399108663867358851672337064, 0.10168981274041363384187361821373796809}, + {0.74764394203399108663867358851672337064, -0.87382197101699554331933679425836168532, 0.10168981274041363384187361821373796809}, + {-0.87382197101699554331933679425836168532, -0.87382197101699554331933679425836168532, 0.10168981274041363384187361821373796809}, + {-0.50142650965817915741672289378596184782, 0.0028530193163583148334457875719236956481, 0.23357255145275873205057922277115888265}, + {0.0028530193163583148334457875719236956481, -0.50142650965817915741672289378596184782, 0.23357255145275873205057922277115888265}, + {-0.50142650965817915741672289378596184782, -0.50142650965817915741672289378596184782, 0.23357255145275873205057922277115888265}, + {-0.89370990031036610529350065673720370601, 0.27300499824279729446028518882409939961, 0.16570215123674715038710691284088490796}, + {0.27300499824279729446028518882409939961, -0.89370990031036610529350065673720370601, 0.16570215123674715038710691284088490796}, + {-0.37929509793243118916678453208689569359, 0.27300499824279729446028518882409939961, 0.16570215123674715038710691284088490796}, + {0.27300499824279729446028518882409939961, -0.37929509793243118916678453208689569359, 0.16570215123674715038710691284088490796}, + {-0.37929509793243118916678453208689569359, -0.89370990031036610529350065673720370601, 0.16570215123674715038710691284088490796}, + {-0.89370990031036610529350065673720370601, -0.37929509793243118916678453208689569359, 0.16570215123674715038710691284088490796}, + // 7 15 %%% Order / Number of Points + { -0.93253870289082430257005654739836752385, 0.8650774057816486051401130947967350477, 0.033090100221584262071955896945834891238}, + {0.8650774057816486051401130947967350477, -0.93253870289082430257005654739836752385, 0.033090100221584262071955896945834891238}, + {-0.93253870289082430257005654739836752385, -0.93253870289082430257005654739836752385, 0.033090100221584262071955896945834891238}, + {-0.51684523480919288209962646032443600082, 0.033690469618385764199252920648872001638, 0.25588834246031114556580247036929262133}, + {0.033690469618385764199252920648872001638, -0.51684523480919288209962646032443600082, 0.25588834246031114556580247036929262133}, + {-0.51684523480919288209962646032443600082, -0.51684523480919288209962646032443600082, 0.25588834246031114556580247036929262133}, + {-0.051380614990563531580838528101628435036, -0.89723877001887293683832294379674312993, 0.15417329237197213566964304166748277293}, + {-0.89723877001887293683832294379674312993, -0.051380614990563531580838528101628435036, 0.15417329237197213566964304166748277293}, + {-0.051380614990563531580838528101628435036, -0.051380614990563531580838528101628435036, 0.15417329237197213566964304166748277293}, + {-0.90592671069480953331718004928623004897, 0.50856008110010635471247864925623992738, 0.11175746580639956167963262884202819059}, + {0.50856008110010635471247864925623992738, -0.90592671069480953331718004928623004897, 0.11175746580639956167963262884202819059}, + {-0.60263337040529682139529859997000987842, 0.50856008110010635471247864925623992738, 0.11175746580639956167963262884202819059}, + {0.50856008110010635471247864925623992738, -0.60263337040529682139529859997000987842, 0.11175746580639956167963262884202819059}, + {-0.60263337040529682139529859997000987842, -0.90592671069480953331718004928623004897, 0.11175746580639956167963262884202819059}, + {-0.90592671069480953331718004928623004897, -0.60263337040529682139529859997000987842, 0.11175746580639956167963262884202819059}}; + + + } +} diff --git a/library/LibUtilities/Foundations/Points.h b/library/LibUtilities/Foundations/Points.h index d662fac36..2f4f2aea4 100644 --- a/library/LibUtilities/Foundations/Points.h +++ b/library/LibUtilities/Foundations/Points.h @@ -28,8 +28,8 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// -// Description: Header file of Points definition +// +// Description: Header file of Points definition // /////////////////////////////////////////////////////////////////////////////// @@ -48,12 +48,12 @@ namespace Nektar { - + namespace LibUtilities { // Need to add method to compute total number of points given dimension // and number of points. - + /// Defines a specification for a set of points. class PointsKey { @@ -65,24 +65,24 @@ namespace Nektar { LIB_UTILITIES_EXPORT bool operator()(const PointsKey &lhs, const PointsKey &rhs) const; }; - + /// Default constructor. PointsKey(void): - m_numpoints(0), + m_numpoints(0), m_pointstype(eNoPointsType), m_factor(NekConstants::kNekUnsetDouble) { } - + /// Constructor defining the number and distribution of points. PointsKey(const int &numpoints, const PointsType &pointstype, - const NekDouble factor = NekConstants::kNekUnsetDouble): - m_numpoints(numpoints), + const NekDouble factor = NekConstants::kNekUnsetDouble): + m_numpoints(numpoints), m_pointstype(pointstype), m_factor(factor) { } - + /// Destructor. virtual ~PointsKey() { @@ -93,16 +93,16 @@ namespace Nektar { *this = key; // defer to assignment operator } - + PointsKey& operator=(const PointsKey &key) { m_numpoints = key.m_numpoints; m_pointstype = key.m_pointstype; m_factor = key.m_factor; - + return *this; } - + inline unsigned int GetNumPoints() const { return m_numpoints; @@ -120,7 +120,7 @@ namespace Nektar inline bool operator==(const PointsKey &key) { - + if(fabs(m_factor - key.m_factor) < NekConstants::kNekZeroTol) { return (m_numpoints == key.m_numpoints && @@ -163,7 +163,7 @@ namespace Nektar case eNodalPrismEvenlySpaced: dimpoints = 3; break; - + default: break; } @@ -183,16 +183,18 @@ namespace Nektar case eNodalTriEvenlySpaced: totpoints = m_numpoints*(m_numpoints+1)/2; break; + case eNodalTriSPI: ASSERTL0(false,"this method cannot be implemented"); + break; case eNodalTetElec: case eNodalTetEvenlySpaced: totpoints = m_numpoints*(m_numpoints+1)*(m_numpoints+2)/6; break; - + case eNodalPrismEvenlySpaced: totpoints = m_numpoints*m_numpoints*(m_numpoints+1)/2; break; - + default: break; } @@ -263,13 +265,13 @@ namespace Nektar return m_points[0]; } - inline const Array& GetW() const + inline const Array& GetW() const { - return m_weights; - } + return m_weights; + } inline void GetZW(Array &z, - Array &w) const + Array &w) const { z = m_points[0]; w = m_weights; @@ -307,21 +309,21 @@ namespace Nektar boost::shared_ptr > returnval(MemoryManager >::AllocateSharedPtr()); return returnval; } - + virtual const MatrixSharedPtrType GetI(const Array& x) { ASSERTL0(false, "Method not implemented"); boost::shared_ptr > returnval(MemoryManager >::AllocateSharedPtr()); return returnval; } - + virtual const MatrixSharedPtrType GetI(unsigned int numpoints, const Array& x) { ASSERTL0(false, "Method not implemented"); boost::shared_ptr > returnval(MemoryManager >::AllocateSharedPtr()); return returnval; } - + virtual const MatrixSharedPtrType GetI(const Array& x, const Array& y) { ASSERTL0(false, "Method not implemented"); @@ -351,7 +353,7 @@ namespace Nektar MatrixSharedPtrType m_derivmatrix[3]; NekManager, PointsKey::opLess> m_InterpManager; NekManager, PointsKey::opLess> m_GalerkinProjectionManager; - + virtual void CalculatePoints() { unsigned int pointsDim = GetPointsDim(); @@ -394,6 +396,6 @@ namespace Nektar }; }; // end of namespace -} // end of namespace +} // end of namespace #endif //NEKTAR_LIB_UTILITIES_FOUNDATIONS_POINTS_H diff --git a/library/LibUtilities/Foundations/PointsType.h b/library/LibUtilities/Foundations/PointsType.h index 4447e0cc5..2ad263e13 100644 --- a/library/LibUtilities/Foundations/PointsType.h +++ b/library/LibUtilities/Foundations/PointsType.h @@ -37,9 +37,9 @@ #define NEKTAR_LIB_UTILITIES_POINTS_TYPE_H namespace Nektar -{ +{ namespace LibUtilities - { + { enum PointsType { @@ -67,6 +67,7 @@ namespace Nektar eBoundaryLayerPointsRev, //!< 1D power law distribution for boundary layer points eNodalTriElec, //!< 2D Nodal Electrostatic Points on a Triangle eNodalTriFekete, //!< 2D Nodal Fekete Points on a Triangle + eNodalTriSPI, //!< 2D Nodal Symmetric positive internal triangle (Whitherden, Vincent) eNodalTriEvenlySpaced, //!< 2D Evenly-spaced points on a Triangle eNodalTetEvenlySpaced, //!< 3D Evenly-spaced points on a Tetrahedron eNodalTetElec, //!< 3D Nodal Electrostatic Points on a Tetrahedron diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 5bcbc34f1..d16a907b3 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -78,30 +78,34 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d) if(dim == 2) { NekVector X(ptsLow),Y(ptsLow), - x1(ptsHigh),y1(ptsHigh), - x2(ptsHigh),y2(ptsHigh); + x1(ptsLow),y1(ptsLow), + x2(ptsLow),y2(ptsLow); for(int i = 0; i < ptsLow; i++) { X(i) = ns[i]->m_x; Y(i) = ns[i]->m_y; } - NekVector Xint(ptsHigh), Yint(ptsHigh); - Xint = interp * X; - Yint = interp * Y; + NekVector x1i(ptsHigh),y1i(ptsHigh), + x2i(ptsHigh),y2i(ptsHigh); - x1 = VdmDx*Xint; - y1 = VdmDx*Yint; - x2 = VdmDy*Xint; - y2 = VdmDy*Yint; + x1 = VdmDx*X; + y1 = VdmDx*Y; + x2 = VdmDy*X; + y2 = VdmDy*Y; + + x1i = interp * x1; + x2i = interp * x2; + y1i = interp * y1; + y2i = interp * y2; for(int i = 0; i < ptsHigh; i++) { Array jaci(9,0.0); - jaci[0] = x1(i); - jaci[1] = y1(i); - jaci[3] = x2(i); - jaci[4] = y2(i); + jaci[0] = x1i(i); + jaci[1] = y1i(i); + jaci[3] = x2i(i); + jaci[4] = y2i(i); jac[i] = jaci; } @@ -473,12 +477,13 @@ void ProcessVarOpti::Process() case 2: { ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)/2; - ptsHigh = (3*m_mesh->m_nummode-4)*((3*m_mesh->m_nummode-4)+1)/2; + ptsHigh = 12; LibUtilities::PointsKey pkey1(m_mesh->m_nummode, LibUtilities::eNodalTriElec); - LibUtilities::PointsKey pkey2(3*m_mesh->m_nummode-4, - LibUtilities::eNodalTriElec); + LibUtilities::PointsKey pkey2(m_mesh->m_nummode, + LibUtilities::eNodalTriSPI); Array u1, v1, u2, v2; + LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2); NekVector U1(u1), V1(v1); @@ -486,14 +491,21 @@ void ProcessVarOpti::Process() interp = LibUtilities::GetInterpolationMatrix(U1, V1, U2, V2); - NekMatrix Vandermonde = LibUtilities::GetVandermonde(U2,V2); + NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); - VdmDx = LibUtilities::GetVandermondeForXDerivative(U2,V2) * + VdmDx = LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI; - VdmDy = LibUtilities::GetVandermondeForYDerivative(U2,V2) * + VdmDy = LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI; - quadW = LibUtilities::MakeQuadratureWeights(U2,V2); + //quadW = LibUtilities::MakeQuadratureWeights(U2,V1); + Array q = LibUtilities::PointsManager()[pkey2]->GetW(); + NekVector quadW(q); + for(int i= 0; i < u2.num_elements(); i++) + { + cout << q[i] << endl; + } + exit(-1); } break; case 3: @@ -1053,7 +1065,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP } else if(geom->GetShapeType() == LibUtilities::eTriangle) { - LibUtilities::PointsKey pkey(3*m_mesh->m_nummode-4, + LibUtilities::PointsKey pkey(m_mesh->m_nummode, LibUtilities::eNodalTriElec); Array u, v; LibUtilities::PointsManager()[pkey]->GetPoints(u, v); @@ -1067,7 +1079,9 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP chi->BwdTrans(coeffs0,xc); chi->BwdTrans(coeffs1,yc); - NekVector X(u.num_elements()),Y(u.num_elements()); + NekVector X(ptsLow),Y(ptsLow), + x1(ptsLow),y1(ptsLow), + x2(ptsLow),y2(ptsLow); for(int j = 0; j < u.num_elements(); j++) { Array xp(2); @@ -1078,18 +1092,27 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP Y(j) = chi->PhysEvaluate(xp, yc); } - NekVector x1 = VdmDx*X; - NekVector y1 = VdmDx*Y; - NekVector x2 = VdmDy*X; - NekVector y2 = VdmDy*Y; + NekVector x1i(ptsHigh),y1i(ptsHigh), + x2i(ptsHigh),y2i(ptsHigh); - for(int i = 0 ; i < u.num_elements(); i++) + x1 = VdmDx*X; + y1 = VdmDx*Y; + x2 = VdmDy*X; + y2 = VdmDy*Y; + + x1i = interp * x1; + x2i = interp * x2; + y1i = interp * y1; + y2i = interp * y2; + + + for(int i = 0 ; i < ptsHigh; i++) { DNekMat dxdz(2,2,1.0,eFULL); - dxdz(0,0) = x1(i); - dxdz(0,1) = x2(i); - dxdz(1,0) = y1(i); - dxdz(1,1) = y2(i); + dxdz(0,0) = x1i(i); + dxdz(0,1) = x2i(i); + dxdz(1,0) = y1i(i); + dxdz(1,1) = y2i(i); Array r(10,0.0); r[9] = dxdz(0,0)*dxdz(1,1)-dxdz(1,0)*dxdz(0,1); -- GitLab From 064c72abb84e76c8857abf8cab75f862d831fbbf Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 9 May 2016 12:56:25 +0100 Subject: [PATCH 028/236] tri working --- .../LibUtilities/Foundations/NodalTriSPI.cpp | 5 +++++ .../LibUtilities/Foundations/NodalTriSPI.h | 2 ++ library/LibUtilities/Foundations/Points.h | 6 +++++ .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 22 ++++++------------- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/library/LibUtilities/Foundations/NodalTriSPI.cpp b/library/LibUtilities/Foundations/NodalTriSPI.cpp index 2d57598c7..39fc24bbe 100644 --- a/library/LibUtilities/Foundations/NodalTriSPI.cpp +++ b/library/LibUtilities/Foundations/NodalTriSPI.cpp @@ -107,6 +107,11 @@ namespace Nektar return returnval; } + int NodalTriSPI::GetNumPointsAlt() + { + return NodalTriSPINPTS[GetNumPoints()-2]; + } + } // end of namespace stdregion } // end of namespace stdregion diff --git a/library/LibUtilities/Foundations/NodalTriSPI.h b/library/LibUtilities/Foundations/NodalTriSPI.h index 138724841..11b33a544 100644 --- a/library/LibUtilities/Foundations/NodalTriSPI.h +++ b/library/LibUtilities/Foundations/NodalTriSPI.h @@ -63,6 +63,8 @@ namespace Nektar { } + int GetNumPointsAlt(); + private: NodalTriSPI():PointsBaseType(NullPointsKey) { diff --git a/library/LibUtilities/Foundations/Points.h b/library/LibUtilities/Foundations/Points.h index 2f4f2aea4..f2af69bc5 100644 --- a/library/LibUtilities/Foundations/Points.h +++ b/library/LibUtilities/Foundations/Points.h @@ -346,6 +346,12 @@ namespace Nektar return returnval; } + virtual int GetNumPointsAlt() + { + ASSERTL0(false,"Method not implemented"); + return 0; + } + protected: PointsKey m_pointsKey; Array m_points[3]; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index d16a907b3..8b3e85950 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -396,7 +396,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d) NekDouble integral = 0.0; for(int i = 0; i < ptsHigh; i++) { - integral += quadW(i) * dW[i]; + integral += quadW[i] * dW[i]; } return integral; } @@ -477,10 +477,10 @@ void ProcessVarOpti::Process() case 2: { ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)/2; - ptsHigh = 12; + LibUtilities::PointsKey pkey1(m_mesh->m_nummode, LibUtilities::eNodalTriElec); - LibUtilities::PointsKey pkey2(m_mesh->m_nummode, + LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, LibUtilities::eNodalTriSPI); Array u1, v1, u2, v2; @@ -488,6 +488,7 @@ void ProcessVarOpti::Process() LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2); NekVector U1(u1), V1(v1); NekVector U2(u2), V2(v2); + ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); interp = LibUtilities::GetInterpolationMatrix(U1, V1, U2, V2); @@ -499,13 +500,9 @@ void ProcessVarOpti::Process() VdmDy = LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI; //quadW = LibUtilities::MakeQuadratureWeights(U2,V1); - Array q = LibUtilities::PointsManager()[pkey2]->GetW(); - NekVector quadW(q); - for(int i= 0; i < u2.num_elements(); i++) - { - cout << q[i] << endl; - } - exit(-1); + Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); + NekVector quadWi(qds); + quadW = quadWi; } break; case 3: @@ -684,11 +681,6 @@ void ProcessVarOpti::NodeOpti::Optimise() delZ = del[2]; } - if(sqrt(delX*delX + delY*delY) > 1e-2) - { - return; - } - bool found = false; while(alpha > 1e-6) { -- GitLab From 068b6983953c60d663c4bed7082ab62b07e8012c Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 9 May 2016 15:16:19 +0100 Subject: [PATCH 029/236] third order tets working --- library/LibUtilities/CMakeLists.txt | 3 + .../LibUtilities/Foundations/Foundations.hpp | 1 + .../Foundations/ManagerAccess.cpp | 2 + .../LibUtilities/Foundations/NodalTetElec.cpp | 2 +- .../LibUtilities/Foundations/NodalTetSPI.cpp | 120 ++++++++++++ .../LibUtilities/Foundations/NodalTetSPI.h | 81 +++++++++ .../Foundations/NodalTetSPIData.h | 121 +++++++++++++ library/LibUtilities/Foundations/Points.h | 2 + library/LibUtilities/Foundations/PointsType.h | 1 + .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 171 ++++++++++++------ 10 files changed, 448 insertions(+), 56 deletions(-) create mode 100644 library/LibUtilities/Foundations/NodalTetSPI.cpp create mode 100644 library/LibUtilities/Foundations/NodalTetSPI.h create mode 100644 library/LibUtilities/Foundations/NodalTetSPIData.h diff --git a/library/LibUtilities/CMakeLists.txt b/library/LibUtilities/CMakeLists.txt index bf50e0f17..82470c000 100644 --- a/library/LibUtilities/CMakeLists.txt +++ b/library/LibUtilities/CMakeLists.txt @@ -122,6 +122,8 @@ SET(FoundationHeaders ./Foundations/NodalTriFekete.h ./Foundations/NodalTriSPIData.h ./Foundations/NodalTriSPI.h + ./Foundations/NodalTetSPI.h + ./Foundations/NodalTetSPIData.h ./Foundations/NodalUtil.h ./Foundations/PhysGalerkinProject.h ./Foundations/Points.h @@ -146,6 +148,7 @@ SET(FoundationSources ./Foundations/NodalTriEvenlySpaced.cpp ./Foundations/NodalTriFekete.cpp ./Foundations/NodalTriSPI.cpp + ./Foundations/NodalTetSPI.cpp ./Foundations/NodalUtil.cpp ./Foundations/PhysGalerkinProject.cpp ./Foundations/Points.cpp diff --git a/library/LibUtilities/Foundations/Foundations.hpp b/library/LibUtilities/Foundations/Foundations.hpp index bb2c26244..8ca533d8a 100644 --- a/library/LibUtilities/Foundations/Foundations.hpp +++ b/library/LibUtilities/Foundations/Foundations.hpp @@ -96,6 +96,7 @@ namespace Nektar "NodalTriEvenlySpaced", "NodalTetEvenlySpaced", "NodalTetElec", + "NodalTetSPI", "NodalPrismEvenlySpaced" }; diff --git a/library/LibUtilities/Foundations/ManagerAccess.cpp b/library/LibUtilities/Foundations/ManagerAccess.cpp index a94e51a7e..1c893c0d6 100644 --- a/library/LibUtilities/Foundations/ManagerAccess.cpp +++ b/library/LibUtilities/Foundations/ManagerAccess.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,7 @@ namespace Nektar const bool NodalTriInited1 = PointsManager().RegisterCreator(PointsKey(0, eNodalTriFekete), NodalTriFekete::Create); const bool NodalTriInited2 = PointsManager().RegisterCreator(PointsKey(0, eNodalTriSPI), NodalTriSPI::Create); const bool nodalTetElecInited = PointsManager().RegisterCreator(PointsKey(0, eNodalTetElec), NodalTetElec::Create); + const bool nodalTetElecInited1 = PointsManager().RegisterCreator(PointsKey(0, eNodalTetSPI), NodalTetSPI::Create); const bool NodalTriEveInited = PointsManager().RegisterCreator(PointsKey(0, eNodalTriEvenlySpaced), NodalTriEvenlySpaced::Create); const bool NodalTetEveInited = PointsManager().RegisterCreator(PointsKey(0, eNodalTetEvenlySpaced), NodalTetEvenlySpaced::Create); const bool NodalPrismEveInited = PointsManager().RegisterCreator(PointsKey(0, eNodalPrismEvenlySpaced), NodalPrismEvenlySpaced::Create); diff --git a/library/LibUtilities/Foundations/NodalTetElec.cpp b/library/LibUtilities/Foundations/NodalTetElec.cpp index ae3336aab..72dd0f591 100644 --- a/library/LibUtilities/Foundations/NodalTetElec.cpp +++ b/library/LibUtilities/Foundations/NodalTetElec.cpp @@ -561,7 +561,7 @@ namespace Nektar istart = iend; for(int i = cnt = istart; i < nAllPoints; i++) { - if(fabs(m_points[1][i]+m_points[0][i]+m_points[2][i]+1) < NekConstants::kNekZeroTol) + if(fabs(m_points[1][i]+m_points[0][i]+m_points[2][i]+1.0) < 1E-9) //nek zero tol too small { std::swap(m_points[0][cnt], m_points[0][i]); std::swap(m_points[1][cnt], m_points[1][i]); diff --git a/library/LibUtilities/Foundations/NodalTetSPI.cpp b/library/LibUtilities/Foundations/NodalTetSPI.cpp new file mode 100644 index 000000000..3a2fd9e03 --- /dev/null +++ b/library/LibUtilities/Foundations/NodalTetSPI.cpp @@ -0,0 +1,120 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// File NodalTriElec.cpp +// +// For more information, please see: http://www.nektar.info +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: 2D Nodal Triangle Fekete Point Definitions +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include + +namespace Nektar +{ + namespace LibUtilities + { + void NodalTetSPI::CalculatePoints() + { + // Allocate the storage for points + unsigned int numPoints = GetNumPoints(); + + for(int i = 0; i < 3; i++) + { + m_points[i] = Array(NodalTetSPINPTS[numPoints-2]); + } + + int index=0; + + // initialize values + for(unsigned int i=0; i < numPoints-2; ++i) + { + index += NodalTetSPINPTS[i]; + } + + for(int i = 0; i < NodalTetSPINPTS[numPoints-2]; i++) + { + m_points[0][i] = NodalTetSPIData[index][0]; + m_points[1][i] = NodalTetSPIData[index][1]; + m_points[2][i] = NodalTetSPIData[index][2]; + index++; + } + + + //exit(0); + } + + void NodalTetSPI::CalculateWeights() + { + unsigned int numPoints = GetNumPoints(); + + m_weights = Array(NodalTetSPINPTS[numPoints-2]); + + int index=0; + + // initialize values + for(unsigned int i=0; i < numPoints-2; ++i) + { + index += NodalTetSPINPTS[i]; + } + + for(int i = 0; i < NodalTetSPINPTS[numPoints-2]; i++) + { + m_weights[i] = NodalTetSPIData[index][3]; + index++; + } + } + + void NodalTetSPI::CalculateDerivMatrix() + { + + } + + boost::shared_ptr NodalTetSPI::Create(const PointsKey &key) + { + boost::shared_ptr returnval(MemoryManager::AllocateSharedPtr(key)); + returnval->Initialize(); + return returnval; + } + + int NodalTetSPI::GetNumPointsAlt() + { + return NodalTetSPINPTS[GetNumPoints()-2]; + } + + + } // end of namespace stdregion +} // end of namespace stdregion + + diff --git a/library/LibUtilities/Foundations/NodalTetSPI.h b/library/LibUtilities/Foundations/NodalTetSPI.h new file mode 100644 index 000000000..68b8c795c --- /dev/null +++ b/library/LibUtilities/Foundations/NodalTetSPI.h @@ -0,0 +1,81 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// File NodalTriElec.h +// +// For more information, please see: http://www.nektar.info +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Header file of 2D Nodal Triangle Fekete Points +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NODALTETSPI_H +#define NODALTETSPI_H + +#include +#include +#include +#include +#include +#include + +namespace Nektar +{ + namespace LibUtilities + { + + class NodalTetSPI: public Points + { + public: + + virtual ~NodalTetSPI() + { + } + + LIB_UTILITIES_EXPORT static boost::shared_ptr + Create(const PointsKey &key); + + NodalTetSPI(const PointsKey &key):PointsBaseType(key) + { + } + + int GetNumPointsAlt(); + + private: + NodalTetSPI():PointsBaseType(NullPointsKey) + { + } + + void CalculatePoints(); + void CalculateWeights(); + void CalculateDerivMatrix(); + + }; + } // end of namespace +} // end of namespace + +#endif //NODALTRIELEC_H diff --git a/library/LibUtilities/Foundations/NodalTetSPIData.h b/library/LibUtilities/Foundations/NodalTetSPIData.h new file mode 100644 index 000000000..f61eaa559 --- /dev/null +++ b/library/LibUtilities/Foundations/NodalTetSPIData.h @@ -0,0 +1,121 @@ + +namespace Nektar +{ + namespace LibUtilities + { + const unsigned int NodalTetSPIAvailable = 7; + static const unsigned int NodalTetSPINPTS[NodalTetSPIAvailable] = {1,4,8,14,14,24,35}; + static const NekDouble NodalTetSPIData[][4] = { + + // %%% x y w + // 1 1 %%% Order / Number of Points + {-0.5, -0.5,-0.5, 1.3333333333333333333333333333333333333}, + // 2 4 %%% Order / Number of Points + {-0.72360679774997896964091736687312762354, -0.72360679774997896964091736687312762354, 0.17082039324993690892275210061938287063, 0.33333333333333333333333333333333333333}, + {-0.72360679774997896964091736687312762354, 0.17082039324993690892275210061938287063, -0.72360679774997896964091736687312762354, 0.33333333333333333333333333333333333333}, + {0.17082039324993690892275210061938287063, -0.72360679774997896964091736687312762354, -0.72360679774997896964091736687312762354, 0.33333333333333333333333333333333333333}, + {-0.72360679774997896964091736687312762354, -0.72360679774997896964091736687312762354, -0.72360679774997896964091736687312762354, 0.33333333333333333333333333333333333333}, + //3 8 %%% Order / Number of Points + {-0.34367339496723662642072827083693243093, -0.34367339496723662642072827083693243093, -0.9689798150982901207378151874892027072, 0.18162379004944980942342872025562069427}, + {-0.34367339496723662642072827083693243093, -0.9689798150982901207378151874892027072, -0.34367339496723662642072827083693243093, 0.18162379004944980942342872025562069427}, + {-0.9689798150982901207378151874892027072, -0.34367339496723662642072827083693243093, -0.34367339496723662642072827083693243093, 0.18162379004944980942342872025562069427}, + {-0.34367339496723662642072827083693243093, -0.34367339496723662642072827083693243093, -0.34367339496723662642072827083693243093, 0.18162379004944980942342872025562069427}, + {-0.78390550020314279176487322158837338344, -0.78390550020314279176487322158837338344, 0.35171650060942837529461966476512015033, 0.15170954328388352390990461307771263906}, + {-0.78390550020314279176487322158837338344, 0.35171650060942837529461966476512015033, -0.78390550020314279176487322158837338344, 0.15170954328388352390990461307771263906}, + {0.35171650060942837529461966476512015033, -0.78390550020314279176487322158837338344, -0.78390550020314279176487322158837338344, 0.15170954328388352390990461307771263906}, + {-0.78390550020314279176487322158837338344, -0.78390550020314279176487322158837338344, -0.78390550020314279176487322158837338344, 0.15170954328388352390990461307771263906}, + //4 14 %%% Order / Number of Points + {-0.37822816147339878040530853247308433401, -0.37822816147339878040530853247308433401, -0.86531551557980365878407440258074699796, 0.15025056762402113439891420311104844508}, + {-0.37822816147339878040530853247308433401, -0.86531551557980365878407440258074699796, -0.37822816147339878040530853247308433401, 0.15025056762402113439891420311104844508}, + {-0.86531551557980365878407440258074699796, -0.37822816147339878040530853247308433401, -0.37822816147339878040530853247308433401, 0.15025056762402113439891420311104844508}, + {-0.37822816147339878040530853247308433401, -0.37822816147339878040530853247308433401, -0.37822816147339878040530853247308433401, 0.15025056762402113439891420311104844508}, + {-0.81452949937821754719535217252593878951, -0.81452949937821754719535217252593878951, 0.44358849813465264158605651757781636853, 0.097990724155149266058280273981770004697}, + {-0.81452949937821754719535217252593878951, 0.44358849813465264158605651757781636853, -0.81452949937821754719535217252593878951, 0.097990724155149266058280273981770004697}, + {0.44358849813465264158605651757781636853, -0.81452949937821754719535217252593878951, -0.81452949937821754719535217252593878951, 0.097990724155149266058280273981770004697}, + {-0.81452949937821754719535217252593878951, -0.81452949937821754719535217252593878951, -0.81452949937821754719535217252593878951, 0.097990724155149266058280273981770004697}, + {-0.90899259174870070101623894744132112187, -0.091007408251299298983761052558678878131, -0.091007408251299298983761052558678878131, 0.05672802770277528858409257082700992237}, + {-0.091007408251299298983761052558678878131, -0.90899259174870070101623894744132112187, -0.091007408251299298983761052558678878131, 0.05672802770277528858409257082700992237}, + {-0.90899259174870070101623894744132112187, -0.90899259174870070101623894744132112187, -0.091007408251299298983761052558678878131, 0.05672802770277528858409257082700992237}, + {-0.90899259174870070101623894744132112187, -0.091007408251299298983761052558678878131, -0.90899259174870070101623894744132112187, 0.05672802770277528858409257082700992237}, + {-0.091007408251299298983761052558678878131, -0.90899259174870070101623894744132112187, -0.90899259174870070101623894744132112187, 0.05672802770277528858409257082700992237}, + {-0.091007408251299298983761052558678878131, -0.091007408251299298983761052558678878131, -0.90899259174870070101623894744132112187, 0.05672802770277528858409257082700992237}, + //5 14 %%% Order / Number of Points + {-0.37822816147339878040530853247308433401, -0.37822816147339878040530853247308433401, -0.86531551557980365878407440258074699796, 0.15025056762402113439891420311104844508}, + {-0.37822816147339878040530853247308433401, -0.86531551557980365878407440258074699796, -0.37822816147339878040530853247308433401, 0.15025056762402113439891420311104844508}, + {-0.86531551557980365878407440258074699796, -0.37822816147339878040530853247308433401, -0.37822816147339878040530853247308433401, 0.15025056762402113439891420311104844508}, + {-0.37822816147339878040530853247308433401, -0.37822816147339878040530853247308433401, -0.37822816147339878040530853247308433401, 0.15025056762402113439891420311104844508}, + {-0.81452949937821754719535217252593878951, -0.81452949937821754719535217252593878951, 0.44358849813465264158605651757781636853, 0.097990724155149266058280273981770004697}, + {-0.81452949937821754719535217252593878951, 0.44358849813465264158605651757781636853, -0.81452949937821754719535217252593878951, 0.097990724155149266058280273981770004697}, + {0.44358849813465264158605651757781636853, -0.81452949937821754719535217252593878951, -0.81452949937821754719535217252593878951, 0.097990724155149266058280273981770004697}, + {-0.81452949937821754719535217252593878951, -0.81452949937821754719535217252593878951, -0.81452949937821754719535217252593878951, 0.097990724155149266058280273981770004697}, + {-0.90899259174870070101623894744132112187, -0.091007408251299298983761052558678878131, -0.091007408251299298983761052558678878131, 0.05672802770277528858409257082700992237}, + {-0.091007408251299298983761052558678878131, -0.90899259174870070101623894744132112187, -0.091007408251299298983761052558678878131, 0.05672802770277528858409257082700992237}, + {-0.90899259174870070101623894744132112187, -0.90899259174870070101623894744132112187, -0.091007408251299298983761052558678878131, 0.05672802770277528858409257082700992237}, + {-0.90899259174870070101623894744132112187, -0.091007408251299298983761052558678878131, -0.90899259174870070101623894744132112187, 0.05672802770277528858409257082700992237}, + {-0.091007408251299298983761052558678878131, -0.90899259174870070101623894744132112187, -0.90899259174870070101623894744132112187, 0.05672802770277528858409257082700992237}, + {-0.091007408251299298983761052558678878131, -0.091007408251299298983761052558678878131, -0.90899259174870070101623894744132112187, 0.05672802770277528858409257082700992237}, + // 6 24 %%% Order / Number of Points + {-0.91865208293077729376884110208717988144, -0.91865208293077729376884110208717988144, 0.75595624879233188130652330626153964433, 0.013436281407094190597350983261249151023}, + {-0.91865208293077729376884110208717988144, 0.75595624879233188130652330626153964433, -0.91865208293077729376884110208717988144, 0.013436281407094190597350983261249151023}, + {0.75595624879233188130652330626153964433, -0.91865208293077729376884110208717988144, -0.91865208293077729376884110208717988144, 0.013436281407094190597350983261249151023}, + {-0.91865208293077729376884110208717988144, -0.91865208293077729376884110208717988144, -0.91865208293077729376884110208717988144, 0.013436281407094190597350983261249151023}, + {-0.35532421971544897931201105847501574951, -0.35532421971544897931201105847501574951, -0.93402734085365306206396682457495275146, 0.073809575391539629460204370471634688549}, + {-0.35532421971544897931201105847501574951, -0.93402734085365306206396682457495275146, -0.35532421971544897931201105847501574951, 0.073809575391539629460204370471634688549}, + {-0.93402734085365306206396682457495275146, -0.35532421971544897931201105847501574951, -0.35532421971544897931201105847501574951, 0.073809575391539629460204370471634688549}, + {-0.35532421971544897931201105847501574951, -0.35532421971544897931201105847501574951, -0.35532421971544897931201105847501574951, 0.073809575391539629460204370471634688549}, + {-0.5707942574816959414223215612274300172, -0.5707942574816959414223215612274300172, -0.28761722755491217573303531631770994839, 0.053230333677556656132920836743306636618}, + {-0.5707942574816959414223215612274300172, -0.28761722755491217573303531631770994839, -0.5707942574816959414223215612274300172, 0.053230333677556656132920836743306636618}, + {-0.28761722755491217573303531631770994839, -0.5707942574816959414223215612274300172, -0.5707942574816959414223215612274300172, 0.053230333677556656132920836743306636618}, + {-0.5707942574816959414223215612274300172, -0.5707942574816959414223215612274300172, -0.5707942574816959414223215612274300172, 0.053230333677556656132920836743306636618}, + {0.20601132958329828273486227812187937257, -0.87267799624996494940152894478854603924, -0.46065533708336838393180438854478729409, 0.064285714285714285714285714285714285714}, + {0.20601132958329828273486227812187937257, -0.87267799624996494940152894478854603924, -0.87267799624996494940152894478854603924, 0.064285714285714285714285714285714285714}, + {-0.87267799624996494940152894478854603924, -0.87267799624996494940152894478854603924, 0.20601132958329828273486227812187937257, 0.064285714285714285714285714285714285714}, + {-0.46065533708336838393180438854478729409, 0.20601132958329828273486227812187937257, -0.87267799624996494940152894478854603924, 0.064285714285714285714285714285714285714}, + {-0.87267799624996494940152894478854603924, -0.46065533708336838393180438854478729409, 0.20601132958329828273486227812187937257, 0.064285714285714285714285714285714285714}, + {-0.87267799624996494940152894478854603924, 0.20601132958329828273486227812187937257, -0.87267799624996494940152894478854603924, 0.064285714285714285714285714285714285714}, + {-0.46065533708336838393180438854478729409, -0.87267799624996494940152894478854603924, 0.20601132958329828273486227812187937257, 0.064285714285714285714285714285714285714}, + {-0.87267799624996494940152894478854603924, -0.46065533708336838393180438854478729409, -0.87267799624996494940152894478854603924, 0.064285714285714285714285714285714285714}, + {-0.87267799624996494940152894478854603924, -0.87267799624996494940152894478854603924, -0.46065533708336838393180438854478729409, 0.064285714285714285714285714285714285714}, + {-0.87267799624996494940152894478854603924, 0.20601132958329828273486227812187937257, -0.46065533708336838393180438854478729409, 0.064285714285714285714285714285714285710}, + {-0.46065533708336838393180438854478729409, -0.87267799624996494940152894478854603924, -0.87267799624996494940152894478854603924, 0.064285714285714285714285714285714285714}, + {0.20601132958329828273486227812187937257, -0.46065533708336838393180438854478729409, -0.87267799624996494940152894478854603924, 0.064285714285714285714285714285714285714}, + // 7 35 %%% Order / Number of Points + { -0.5, -0.5, -0.5, 0.12731371928550779848077124815630184245}, + {-0.36859770044359440115314000081337702315, -0.36859770044359440115314000081337702315, -0.89420689866921679654057999755986893056, 0.05643944161328937210171489439806231665}, + {-0.36859770044359440115314000081337702315, -0.89420689866921679654057999755986893056, -0.36859770044359440115314000081337702315, 0.05643944161328937210171489439806231665}, + {-0.89420689866921679654057999755986893056, -0.36859770044359440115314000081337702315, -0.36859770044359440115314000081337702315, 0.05643944161328937210171489439806231665}, + {-0.36859770044359440115314000081337702315, -0.36859770044359440115314000081337702315, -0.36859770044359440115314000081337702315, 0.05643944161328937210171489439806231665}, + {-0.89902035480320726247389235402687506805, -0.10097964519679273752610764597312493195, -0.10097964519679273752610764597312493195, 0.04252923711047677324569976544392327613}, + {-0.10097964519679273752610764597312493195, -0.89902035480320726247389235402687506805, -0.10097964519679273752610764597312493195, 0.04252923711047677324569976544392327613}, + {-0.89902035480320726247389235402687506805, -0.89902035480320726247389235402687506805, -0.10097964519679273752610764597312493195, 0.04252923711047677324569976544392327613}, + {-0.89902035480320726247389235402687506805, -0.10097964519679273752610764597312493195, -0.89902035480320726247389235402687506805, 0.04252923711047677324569976544392327613}, + {-0.10097964519679273752610764597312493195, -0.89902035480320726247389235402687506805, -0.89902035480320726247389235402687506805, 0.04252923711047677324569976544392327613}, + {-0.10097964519679273752610764597312493195, -0.10097964519679273752610764597312493195, -0.89902035480320726247389235402687506805, 0.04252923711047677324569976544392327613}, + {0.15034327517400004696648315404461503933, -0.62233233794799790452713779229082848999, -0.90567859927800423791220756946295805935, 0.049609507637779495159487414921974827082}, + {0.15034327517400004696648315404461503933, -0.62233233794799790452713779229082848999, -0.62233233794799790452713779229082848999, 0.049609507637779495159487414921974827082}, + {-0.62233233794799790452713779229082848999, -0.62233233794799790452713779229082848999, 0.15034327517400004696648315404461503933, 0.049609507637779495159487414921974827082}, + {-0.90567859927800423791220756946295805935, 0.15034327517400004696648315404461503933, -0.62233233794799790452713779229082848999, 0.049609507637779495159487414921974827082}, + {-0.62233233794799790452713779229082848999, -0.90567859927800423791220756946295805935, 0.15034327517400004696648315404461503933, 0.049609507637779495159487414921974827082}, + {-0.62233233794799790452713779229082848999, 0.15034327517400004696648315404461503933, -0.62233233794799790452713779229082848999, 0.049609507637779495159487414921974827082}, + {-0.90567859927800423791220756946295805935, -0.62233233794799790452713779229082848999, 0.15034327517400004696648315404461503933, 0.049609507637779495159487414921974827082}, + {-0.62233233794799790452713779229082848999, -0.90567859927800423791220756946295805935, -0.62233233794799790452713779229082848999, 0.049609507637779495159487414921974827082}, + {-0.62233233794799790452713779229082848999, -0.62233233794799790452713779229082848999, -0.90567859927800423791220756946295805935, 0.049609507637779495159487414921974827082}, + {-0.62233233794799790452713779229082848999, 0.15034327517400004696648315404461503933, -0.90567859927800423791220756946295805935, 0.049609507637779495159487414921974827082}, + {0.90567859927800423791220756946295805935, -0.62233233794799790452713779229082848999, -0.62233233794799790452713779229082848999, 0.049609507637779495159487414921974827082}, + {0.15034327517400004696648315404461503933, -0.90567859927800423791220756946295805935, -0.62233233794799790452713779229082848999, 0.049609507637779495159487414921974827082}, + {0.62166048219709712223621075969646478759, -0.95746905491703350802232779700036011785, -0.70672237236303010619155516569574455189, 0.010814361106537788754804577988128720209}, + {0.62166048219709712223621075969646478759, -0.95746905491703350802232779700036011785, -0.95746905491703350802232779700036011785, 0.010814361106537788754804577988128720209}, + {-0.95746905491703350802232779700036011785, -0.95746905491703350802232779700036011785, 0.62166048219709712223621075969646478759, 0.010814361106537788754804577988128720209}, + {-0.70672237236303010619155516569574455189, 0.62166048219709712223621075969646478759, -0.95746905491703350802232779700036011785, 0.010814361106537788754804577988128720209}, + {-0.95746905491703350802232779700036011785, -0.70672237236303010619155516569574455189, 0.62166048219709712223621075969646478759, 0.010814361106537788754804577988128720209}, + {-0.95746905491703350802232779700036011785, 0.62166048219709712223621075969646478759, -0.95746905491703350802232779700036011785, 0.010814361106537788754804577988128720209}, + {-0.70672237236303010619155516569574455189, -0.95746905491703350802232779700036011785, 0.62166048219709712223621075969646478759, 0.010814361106537788754804577988128720209}, + {-0.95746905491703350802232779700036011785, -0.70672237236303010619155516569574455189, -0.95746905491703350802232779700036011785, 0.010814361106537788754804577988128720209}, + {-0.95746905491703350802232779700036011785, -0.95746905491703350802232779700036011785, -0.70672237236303010619155516569574455189, 0.010814361106537788754804577988128720209}, + {-0.95746905491703350802232779700036011785, 0.62166048219709712223621075969646478759, -0.70672237236303010619155516569574455189, 0.010814361106537788754804577988128720209}, + {-0.70672237236303010619155516569574455189, -0.95746905491703350802232779700036011785, -0.95746905491703350802232779700036011785, 0.010814361106537788754804577988128720209}, + {0.62166048219709712223621075969646478759, -0.70672237236303010619155516569574455189, -0.95746905491703350802232779700036011785, 0.010814361106537788754804577988128720209}}; + + + } +} diff --git a/library/LibUtilities/Foundations/Points.h b/library/LibUtilities/Foundations/Points.h index f2af69bc5..bf5906836 100644 --- a/library/LibUtilities/Foundations/Points.h +++ b/library/LibUtilities/Foundations/Points.h @@ -190,6 +190,8 @@ namespace Nektar case eNodalTetEvenlySpaced: totpoints = m_numpoints*(m_numpoints+1)*(m_numpoints+2)/6; break; + case eNodalTetSPI: ASSERTL0(false,"this method cannot be implemented"); + break; case eNodalPrismEvenlySpaced: totpoints = m_numpoints*m_numpoints*(m_numpoints+1)/2; diff --git a/library/LibUtilities/Foundations/PointsType.h b/library/LibUtilities/Foundations/PointsType.h index 2ad263e13..7dc62bbdd 100644 --- a/library/LibUtilities/Foundations/PointsType.h +++ b/library/LibUtilities/Foundations/PointsType.h @@ -71,6 +71,7 @@ namespace Nektar eNodalTriEvenlySpaced, //!< 2D Evenly-spaced points on a Triangle eNodalTetEvenlySpaced, //!< 3D Evenly-spaced points on a Tetrahedron eNodalTetElec, //!< 3D Nodal Electrostatic Points on a Tetrahedron + eNodalTetSPI, //!< 3D Nodal Symmetric positive internal tet (Whitherden, Vincent) eNodalPrismEvenlySpaced, //!< 3D Evenly-spaced points on a Prism SIZE_PointsType //!< Length of enum list }; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 8b3e85950..c23f86544 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -124,33 +124,42 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d) Z(i) = ns[i]->m_z; } - NekVector Xint(ptsHigh), Yint(ptsHigh), Zint(ptsHigh); - Xint = interp * X; - Yint = interp * Y; - Zint = interp * Z; - - x1 = VdmDx*Xint; - y1 = VdmDx*Yint; - z1 = VdmDx*Zint; - x2 = VdmDy*Xint; - y2 = VdmDy*Yint; - z2 = VdmDy*Zint; - x3 = VdmDz*Xint; - y3 = VdmDz*Yint; - z3 = VdmDz*Zint; + x1 = VdmDx*X; + y1 = VdmDx*Y; + z1 = VdmDx*Z; + x2 = VdmDy*X; + y2 = VdmDy*Y; + z2 = VdmDy*Z; + x3 = VdmDz*X; + y3 = VdmDz*Y; + z3 = VdmDz*Z; + + NekVector x1i(ptsHigh),y1i(ptsHigh),z1i(ptsHigh), + x2i(ptsHigh),y2i(ptsHigh),z2i(ptsHigh), + x3i(ptsHigh),y3i(ptsHigh),z3i(ptsHigh); + + x1i = interp * x1; + x2i = interp * x2; + x3i = interp * x3; + y1i = interp * y1; + y2i = interp * y2; + y3i = interp * y3; + z1i = interp * z1; + z2i = interp * z2; + z3i = interp * z3; for(int i = 0; i < ptsHigh; i++) { Array jaci(9,0.0); - jaci[0] = x1(i); - jaci[1] = y1(i); - jaci[2] = z1(i); - jaci[3] = x2(i); - jaci[4] = y2(i); - jaci[5] = z2(i); - jaci[6] = x3(i); - jaci[7] = y3(i); - jaci[8] = z3(i); + jaci[0] = x1i(i); + jaci[1] = y1i(i); + jaci[2] = z1i(i); + jaci[3] = x2i(i); + jaci[4] = y2i(i); + jaci[5] = z2i(i); + jaci[6] = x3i(i); + jaci[7] = y3i(i); + jaci[8] = z3i(i); jac[i] = jaci; } @@ -508,32 +517,33 @@ void ProcessVarOpti::Process() case 3: { ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)*(m_mesh->m_nummode+2)/6; - ptsHigh = (3*m_mesh->m_nummode-4)*((3*m_mesh->m_nummode-4)+1) - *((3*m_mesh->m_nummode-4)+2)/6; LibUtilities::PointsKey pkey1(m_mesh->m_nummode, LibUtilities::eNodalTetElec); - LibUtilities::PointsKey pkey2(3*m_mesh->m_nummode-4, - LibUtilities::eNodalTetElec); + LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, + LibUtilities::eNodalTetSPI); Array u1, v1, u2, v2, w1, w2; LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1, w1); LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2, w2); NekVector U1(u1), V1(v1), W1(w1); NekVector U2(u2), V2(v2), W2(w2); + ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); interp = LibUtilities::GetTetInterpolationMatrix(U1, V1, W1, U2, V2, W2); NekMatrix Vandermonde = - LibUtilities::GetTetVandermonde(U2,V2,W2); + LibUtilities::GetTetVandermonde(U1,V1,W1); NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); - VdmDx = LibUtilities::GetVandermondeForTetXDerivative(U2,V2,W2) * + VdmDx = LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI; - VdmDy = LibUtilities::GetVandermondeForTetYDerivative(U2,V2,W2) * + VdmDy = LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI; - VdmDz = LibUtilities::GetVandermondeForTetZDerivative(U2,V2,W2) * + VdmDz = LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI; - quadW = LibUtilities::MakeTetWeights(U2,V2,W2); + Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); + NekVector quadWi(qds); + quadW = quadWi; } } @@ -1120,7 +1130,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP } else if(geom->GetShapeType() == LibUtilities::eTetrahedron) { - LibUtilities::PointsKey pkey(3*m_mesh->m_nummode-4, + LibUtilities::PointsKey pkey(m_mesh->m_nummode, LibUtilities::eNodalTetElec); Array u, v, w; LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); @@ -1137,8 +1147,10 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP chi->BwdTrans(coeffs1,yc); chi->BwdTrans(coeffs2,zc); - NekVector X(u.num_elements()),Y(u.num_elements()), - Z(u.num_elements()); + NekVector X(ptsLow),Y(ptsLow),Z(ptsLow), + x1(ptsLow),y1(ptsLow),z1(ptsLow), + x2(ptsLow),y2(ptsLow),z2(ptsLow), + x3(ptsLow),y3(ptsLow),z3(ptsLow); for(int j = 0; j < u.num_elements(); j++) { Array xp(3); @@ -1151,28 +1163,42 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP Z(j) = chi->PhysEvaluate(xp, zc); } - NekVector x1 = VdmDx*X; - NekVector y1 = VdmDx*Y; - NekVector z1 = VdmDx*Z; - NekVector x2 = VdmDy*X; - NekVector y2 = VdmDy*Y; - NekVector z2 = VdmDy*Z; - NekVector x3 = VdmDz*X; - NekVector y3 = VdmDz*Y; - NekVector z3 = VdmDz*Z; - - for(int i = 0 ; i < u.num_elements(); i++) + NekVector x1i(ptsHigh),y1i(ptsHigh),z1i(ptsHigh), + x2i(ptsHigh),y2i(ptsHigh),z2i(ptsHigh), + x3i(ptsHigh),y3i(ptsHigh),z3i(ptsHigh); + + x1 = VdmDx*X; + y1 = VdmDx*Y; + x2 = VdmDy*X; + y2 = VdmDy*Y; + z1 = VdmDx*Z; + z2 = VdmDy*Z; + x3 = VdmDz*X; + y3 = VdmDz*Y; + z3 = VdmDz*Z; + + x1i = interp * x1; + x2i = interp * x2; + x3i = interp * x3; + y1i = interp * y1; + y2i = interp * y2; + y3i = interp * y3; + z1i = interp * z1; + z2i = interp * z2; + z3i = interp * z3; + + for(int i = 0 ; i < ptsHigh; i++) { DNekMat dxdz(3,3,1.0,eFULL); - dxdz(0,0) = x1(i); - dxdz(0,1) = x2(i); - dxdz(0,2) = x3(i); - dxdz(1,0) = y1(i); - dxdz(1,1) = y2(i); - dxdz(1,2) = y3(i); - dxdz(2,0) = z1(i); - dxdz(2,1) = z2(i); - dxdz(2,2) = z3(i); + dxdz(0,0) = x1i(i); + dxdz(0,1) = x2i(i); + dxdz(0,2) = x3i(i); + dxdz(1,0) = y1i(i); + dxdz(1,1) = y2i(i); + dxdz(1,2) = y3i(i); + dxdz(2,0) = z1i(i); + dxdz(2,1) = z2i(i); + dxdz(2,2) = z3i(i); Array r(10,0.0); //store det in 10th entry @@ -1502,6 +1528,41 @@ void ProcessVarOpti::FillQuadPoints() res->startInv++; } } + + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + + SpatialDomains::GeometrySharedPtr geom = el->GetGeom(el->GetDim()); + geom->FillGeom(); + StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); + + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + Array u, v, w; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); + + Array xc(chi->GetTotPoints()); + Array yc(chi->GetTotPoints()); + Array zc(chi->GetTotPoints()); + + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); + + chi->BwdTrans(coeffs0,xc); + chi->BwdTrans(coeffs1,yc); + chi->BwdTrans(coeffs2,zc); + + for(int j = 0; j < u.num_elements(); j++) + { + Array xp(3); + xp[0] = u[j]; + xp[1] = v[j]; + xp[2] = w[j]; + } + } } void ProcessVarOpti::WriteStats(string file) -- GitLab From 88c93392164da88be824e98adf3d6c441d76b047 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 9 May 2016 16:12:58 +0100 Subject: [PATCH 030/236] fix to tetelec data --- .../Foundations/NodalTetElecData.h | 156 +++++++++--------- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 19 ++- 2 files changed, 90 insertions(+), 85 deletions(-) diff --git a/library/LibUtilities/Foundations/NodalTetElecData.h b/library/LibUtilities/Foundations/NodalTetElecData.h index 991061923..fd94dd955 100644 --- a/library/LibUtilities/Foundations/NodalTetElecData.h +++ b/library/LibUtilities/Foundations/NodalTetElecData.h @@ -1,132 +1,132 @@ namespace Nektar { - namespace LibUtilities + namespace LibUtilities { static const unsigned int perm4_3d[4][4] = {{0,1,2,3},{3,0,1,2},{2,3,0,1},{1,2,3,0}}; // Works for abbb or aaab - static const unsigned int perm6_3d[6][4] = {{0,1,2,3},{0,2,1,3},{0,2,3,1},{2,0,1,3},{2,0,3,1},{2,3,0,1}}; // Works for aabb + static const unsigned int perm6_3d[6][4] = {{0,1,2,3},{0,2,1,3},{0,2,3,1},{2,0,1,3},{2,0,3,1},{2,3,0,1}}; // Works for aabb static const unsigned int perm12A_3d[12][4] = {{0,1,2,3},{0,1,3,2},{0,2,1,3},{0,2,3,1},{0,3,1,2},{0,3,2,1}, - {2,0,1,3},{2,0,3,1},{2,3,0,1},{3,0,1,2},{3,0,2,1},{3,2,0,1}}; // Works for aabc + {2,0,1,3},{2,0,3,1},{2,3,0,1},{3,0,1,2},{3,0,2,1},{3,2,0,1}}; // Works for aabc static const unsigned int perm12B_3d[12][4] = {{0,1,2,3},{0,2,1,3},{0,2,3,1},{1,0,2,3},{1,2,0,3},{1,2,3,0}, {2,0,1,3},{2,0,3,1},{2,1,0,3},{2,1,3,0},{2,3,0,1},{2,3,1,0}}; // Works for abcc static const unsigned int perm12C_3d[12][4] = {{0,1,2,3},{0,1,3,2},{0,3,1,2},{1,0,2,3},{1,0,3,2},{1,2,0,3}, {1,2,3,0},{1,3,0,2},{1,3,2,0},{3,0,1,2},{3,1,0,2},{3,1,2,0}}; // Works for abbc - + static const unsigned int perm24_3d[24][4] = { {0,1,2,3},{0,1,3,2},{0,2,1,3},{0,2,3,1},{0,3,1,2},{0,3,2,1}, {1,0,2,3},{1,0,3,2},{1,2,0,3},{1,2,3,0},{1,3,0,2},{1,3,2,0}, {2,0,1,3},{2,0,3,1},{2,1,0,3},{2,1,3,0},{2,3,0,1},{2,3,1,0}, {3,0,1,2},{3,0,2,1},{3,1,0,2},{3,1,2,0},{3,2,0,1},{3,2,1,0} }; // Works for abcd - + const unsigned int NodalTetElecAvailable = 10; static const unsigned int NodalTetElecNPTS[NodalTetElecAvailable] = {1,2,3,5,6,9,11,15,18,23}; static const NekDouble NodalTetElecData[][9] = { // %%% n_1 n_4 n_6 n_12 n_24 l_1 l_2 l_3 l_4 // 1 1 %%% Order / Number of Points - {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, + {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, // 2 2 %%% Order / Number of Points - {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, - {0, 0, 1, 0, 0, 0.5000000000, 0.5000000000, 0.0000000000, 0.0000000000}, + {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, + {0, 0, 1, 0, 0, 0.5000000000, 0.5000000000, 0.0000000000, 0.0000000000}, // 3 3 %%% Order / Number of Points - {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, + {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, {0, 1, 0, 0, 0, 0.3333333333, 0.3333333333, 0.3333333333, 0.0000000000}, {0, 0, 0, 2, 0, 0.7236067977, 0.2763932023, 0.0000000000, 0.0000000000}, // 4 5 %%% Order / Number of Points - {1, 0, 0, 0, 0, 0.2500000000, 0.2500000000, 0.2500000000, 0.2500000000}, - {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, - {0, 0, 1, 0, 0, 0.5000000000, 0.5000000000, 0.0000000000, 0.0000000000}, + {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, + {1, 0, 0, 0, 0, 0.2500000000, 0.2500000000, 0.2500000000, 0.2500000000}, + {0, 0, 1, 0, 0, 0.5000000000, 0.5000000000, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.8273268354, 0.1726731646, 0.0000000000, 0.0000000000}, - {0, 0, 0, 1, 0, 0.2371200168, 0.2371200168, 0.5257599664, 0.0000000000}, + {0, 0, 0, 1, 0, 0.2371200168, 0.2371200168, 0.5257599664, 0.0000000000}, // 5 6 %%% Order / Number of Points - {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, - {0, 1, 0, 0, 0, 0.1834903473, 0.1834903473, 0.1834903473, 0.4495289581}, + {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, + {0, 1, 0, 0, 0, 0.1834903473, 0.1834903473, 0.1834903473, 0.4495289581}, {0, 0, 0, 2, 0, 0.8825276620, 0.1174723380, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.6426157582, 0.3573842418, 0.0000000000, 0.0000000000}, - {0, 0, 0, 1, 0, 0.1575181512, 0.1575181512, 0.6849636976, 0.0000000000}, - {0, 0, 0, 1, 0, 0.4105151510, 0.4105151510, 0.1789696980, 0.0000000000}, + {0, 0, 0, 1, 0, 0.1575181512, 0.1575181512, 0.6849636976, 0.0000000000}, + {0, 0, 0, 1, 0, 0.4105151510, 0.4105151510, 0.1789696980, 0.0000000000}, // 6 9 %%% Order / Number of Points - {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, - {0, 1, 0, 0, 0, 0.3333333333, 0.3333333333, 0.3333333333, 0.0000000000}, - {0, 1, 0, 0, 0, 0.1402705801, 0.1402705801, 0.1402705801, 0.5791882597}, - {0, 0, 1, 0, 0, 0.5000000000, 0.5000000000, 0.0000000000, 0.0000000000}, - {0, 0, 1, 0, 0, 0.3542052583, 0.3542052583, 0.1457947417, 0.1457947417}, + {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, + {0, 1, 0, 0, 0, 0.3333333333, 0.3333333333, 0.3333333333, 0.0000000000}, + {0, 1, 0, 0, 0, 0.1402705801, 0.1402705801, 0.1402705801, 0.5791882597}, + {0, 0, 1, 0, 0, 0.5000000000, 0.5000000000, 0.0000000000, 0.0000000000}, + {0, 0, 1, 0, 0, 0.3542052583, 0.3542052583, 0.1457947417, 0.1457947417}, {0, 0, 0, 2, 0, 0.9151119481, 0.0848880519, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.7344243967, 0.2655756033, 0.0000000000, 0.0000000000}, - {0, 0, 0, 1, 0, 0.1061169285, 0.1061169285, 0.7877661430, 0.0000000000}, - {0, 0, 0, 0, 1, 0.3097982151, 0.5569099204, 0.1332918645, 0.0000000000}, - // 7 11 %%% Order / Number of Points - {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, - {0, 1, 0, 0, 0, 0.1144606542, 0.1144606542, 0.1144606542, 0.6566180374}, - {0, 1, 0, 0, 0, 0.2917002822, 0.2917002822, 0.2917002822, 0.1248991534}, + {0, 0, 0, 1, 0, 0.1061169285, 0.1061169285, 0.7877661430, 0.0000000000}, + {0, 0, 0, 0, 1, 0.3097982151, 0.5569099204, 0.1332918645, 0.0000000000}, + // 7 11 %%% Order / Number of Points + {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, + {0, 1, 0, 0, 0, 0.1144606542, 0.1144606542, 0.1144606542, 0.6566180374}, + {0, 1, 0, 0, 0, 0.2917002822, 0.2917002822, 0.2917002822, 0.1248991534}, {0, 0, 0, 2, 0, 0.9358700743, 0.0641299257, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.7958500907, 0.2041499093, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.6046496090, 0.3953503910, 0.0000000000, 0.0000000000}, - {0, 0, 0, 1, 0, 0.0660520784, 0.0660520784, 0.8678958432, 0.0000000000}, - {0, 0, 0, 1, 0, 0.4477725053, 0.4477725053, 0.1044549894, 0.0000000000}, - {0, 0, 0, 1, 0, 0.2604038024, 0.2604038024, 0.4791923952, 0.0000000000}, - {0, 0, 0, 1, 0, 0.1208429970, 0.1208429970, 0.4770203357, 0.2812936703}, - {0, 0, 0, 0, 1, 0.2325524777, 0.6759625951, 0.0914849272, 0.0000000000}, + {0, 0, 0, 1, 0, 0.0660520784, 0.0660520784, 0.8678958432, 0.0000000000}, + {0, 0, 0, 1, 0, 0.4477725053, 0.4477725053, 0.1044549894, 0.0000000000}, + {0, 0, 0, 1, 0, 0.2604038024, 0.2604038024, 0.4791923952, 0.0000000000}, + {0, 0, 0, 1, 0, 0.1208429970, 0.1208429970, 0.4770203357, 0.2812936703}, + {0, 0, 0, 0, 1, 0.2325524777, 0.6759625951, 0.0914849272, 0.0000000000}, // 8 15 %%% Order / Number of Points - {1, 0, 0, 0, 0, 0.2500000000, 0.2500000000, 0.2500000000, 0.2500000000}, - {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, - {0, 1, 0, 0, 0, 0.0991203900, 0.0991203900, 0.0991203900, 0.7026388300}, - {0, 0, 1, 0, 0, 0.5000000000, 0.5000000000, 0.0000000000, 0.0000000000}, - {0, 0, 1, 0, 0, 0.3920531037, 0.3920531037, 0.1079468963, 0.1079468963}, + {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, + {1, 0, 0, 0, 0, 0.2500000000, 0.2500000000, 0.2500000000, 0.2500000000}, + {0, 1, 0, 0, 0, 0.0991203900, 0.0991203900, 0.0991203900, 0.7026388300}, + {0, 0, 1, 0, 0, 0.5000000000, 0.5000000000, 0.0000000000, 0.0000000000}, + {0, 0, 1, 0, 0, 0.3920531037, 0.3920531037, 0.1079468963, 0.1079468963}, {0, 0, 0, 2, 0, 0.9498789977, 0.0501210023, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.8385931398, 0.1614068602, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.6815587319, 0.3184412681, 0.0000000000, 0.0000000000}, - {0, 0, 0, 1, 0, 0.0660520784, 0.0660520784, 0.8678958432, 0.0000000000}, - {0, 0, 0, 1, 0, 0.2033467796, 0.2033467796, 0.5933064408, 0.0000000000}, - {0, 0, 0, 1, 0, 0.3905496216, 0.3905496216, 0.2189007568, 0.0000000000}, - {0, 0, 0, 1, 0, 0.1047451941, 0.1047451941, 0.5581946462, 0.2323149656}, - {0, 0, 0, 1, 0, 0.2419418605, 0.2419418605, 0.4062097450, 0.1099065340}, - {0, 0, 0, 0, 1, 0.3617970895, 0.5541643672, 0.0840385433, 0.0000000000}, - {0, 0, 0, 0, 1, 0.1801396087, 0.7519065566, 0.0679538347, 0.0000000000}, + {0, 0, 0, 1, 0, 0.0660520784, 0.0660520784, 0.8678958432, 0.0000000000}, + {0, 0, 0, 1, 0, 0.2033467796, 0.2033467796, 0.5933064408, 0.0000000000}, + {0, 0, 0, 1, 0, 0.3905496216, 0.3905496216, 0.2189007568, 0.0000000000}, + {0, 0, 0, 1, 0, 0.1047451941, 0.1047451941, 0.5581946462, 0.2323149656}, + {0, 0, 0, 1, 0, 0.2419418605, 0.2419418605, 0.4062097450, 0.1099065340}, + {0, 0, 0, 0, 1, 0.3617970895, 0.5541643672, 0.0840385433, 0.0000000000}, + {0, 0, 0, 0, 1, 0.1801396087, 0.7519065566, 0.0679538347, 0.0000000000}, // 9 18 %%% Order / Number of Points - {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, - {0, 1, 0, 0, 0, 0.3333333333, 0.3333333333, 0.3333333333, 0.0000000000}, - {0, 1, 0, 0, 0, 0.0823287303, 0.0823287303, 0.0823287303, 0.7530138091}, - {0, 1, 0, 0, 0, 0.2123055477, 0.2123055477, 0.2123055477, 0.3630833569}, + {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, + {0, 1, 0, 0, 0, 0.3333333333, 0.3333333333, 0.3333333333, 0.0000000000}, + {0, 1, 0, 0, 0, 0.0823287303, 0.0823287303, 0.0823287303, 0.7530138091}, + {0, 1, 0, 0, 0, 0.2123055477, 0.2123055477, 0.2123055477, 0.3630833569}, {0, 0, 0, 2, 0, 0.9597669541, 0.0402330459, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.8693869326, 0.1306130674, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.7389624749, 0.2610375251, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.5826394788, 0.4173605212, 0.0000000000, 0.0000000000}, - {0, 0, 0, 1, 0, 0.0355775717, 0.0355775717, 0.9288448566, 0.0000000000}, - {0, 0, 0, 1, 0, 0.4640303025, 0.4640303025, 0.0719393950, 0.0000000000}, - {0, 0, 0, 1, 0, 0.1633923069, 0.1633923069, 0.6732153862, 0.0000000000}, - {0, 0, 0, 1, 0, 0.0873980781, 0.0873980781, 0.6297057875, 0.1954980564}, - {0, 0, 0, 1, 0, 0.0916714679, 0.0916714679, 0.4819523024, 0.3347047619}, - {0, 0, 0, 1, 0, 0.2040338880, 0.2040338880, 0.4996292993, 0.0923029247}, - {0, 0, 0, 1, 0, 0.3483881173, 0.3483881173, 0.2075502723, 0.0956734931}, - {0, 0, 0, 0, 1, 0.2966333890, 0.6349633653, 0.0684032457, 0.0000000000}, - {0, 0, 0, 0, 0, 0.1439089974, 0.8031490682, 0.0529419344, 0.0000000000}, - {0, 0, 0, 0, 0, 0.3225890045, 0.4968009397, 0.1806100558, 0.0000000000}, + {0, 0, 0, 1, 0, 0.0355775717, 0.0355775717, 0.9288448566, 0.0000000000}, + {0, 0, 0, 1, 0, 0.4640303025, 0.4640303025, 0.0719393950, 0.0000000000}, + {0, 0, 0, 1, 0, 0.1633923069, 0.1633923069, 0.6732153862, 0.0000000000}, + {0, 0, 0, 1, 0, 0.0873980781, 0.0873980781, 0.6297057875, 0.1954980564}, + {0, 0, 0, 1, 0, 0.0916714679, 0.0916714679, 0.4819523024, 0.3347047619}, + {0, 0, 0, 1, 0, 0.2040338880, 0.2040338880, 0.4996292993, 0.0923029247}, + {0, 0, 0, 1, 0, 0.3483881173, 0.3483881173, 0.2075502723, 0.0956734931}, + {0, 0, 0, 0, 1, 0.2966333890, 0.6349633653, 0.0684032457, 0.0000000000}, + {0, 0, 0, 0, 0, 0.1439089974, 0.8031490682, 0.0529419344, 0.0000000000}, + {0, 0, 0, 0, 0, 0.3225890045, 0.4968009397, 0.1806100558, 0.0000000000}, // 10 23 %%% Order / Number of Points - {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, - {0, 1, 0, 0, 0, 0.0678316144, 0.0678316144, 0.0678316144, 0.7965051568}, - {0, 1, 0, 0, 0, 0.1805746957, 0.1805746957, 0.1805746957, 0.4582759129}, - {0, 1, 0, 0, 0, 0.3051527124, 0.3051527124, 0.3051527124, 0.0845418628}, - {0, 0, 1, 0, 0, 0.5000000000, 0.5000000000, 0.0000000000, 0.0000000000}, - {0, 0, 1, 0, 0, 0.3164336236, 0.3164336236, 0.1835663764, 0.1835663764}, - {0, 0, 1, 0, 0, 0.4219543801, 0.4219543801, 0.0780456199, 0.0780456199}, + {0, 1, 0, 0, 0, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000}, + {0, 1, 0, 0, 0, 0.0678316144, 0.0678316144, 0.0678316144, 0.7965051568}, + {0, 1, 0, 0, 0, 0.1805746957, 0.1805746957, 0.1805746957, 0.4582759129}, + {0, 1, 0, 0, 0, 0.3051527124, 0.3051527124, 0.3051527124, 0.0845418628}, + {0, 0, 1, 0, 0, 0.5000000000, 0.5000000000, 0.0000000000, 0.0000000000}, + {0, 0, 1, 0, 0, 0.3164336236, 0.3164336236, 0.1835663764, 0.1835663764}, + {0, 0, 1, 0, 0, 0.4219543801, 0.4219543801, 0.0780456199, 0.0780456199}, {0, 0, 0, 2, 0, 0.9670007152, 0.0329992848, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.8922417368, 0.1077582632, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.7826176635, 0.2173823365, 0.0000000000, 0.0000000000}, {0, 0, 0, 2, 0, 0.6478790678, 0.3521209322, 0.0000000000, 0.0000000000}, - {0, 0, 0, 1, 0, 0.0265250690, 0.0265250690, 0.9469498620, 0.0000000000}, - {0, 0, 0, 1, 0, 0.1330857076, 0.1330857076, 0.7338285848, 0.0000000000}, - {0, 0, 0, 1, 0, 0.4232062312, 0.4232062312, 0.1535875376, 0.0000000000}, - {0, 0, 0, 1, 0, 0.2833924371, 0.2833924371, 0.4332151258, 0.0000000000}, - {0, 0, 0, 1, 0, 0.1734555313, 0.1734555313, 0.5762731177, 0.0768158196}, - {0, 0, 0, 1, 0, 0.0724033935, 0.0724033935, 0.6893564961, 0.1658367169}, - {0, 0, 0, 1, 0, 0.0768451848, 0.0768451848, 0.5573732958, 0.2889363346}, - {0, 0, 0, 0, 1, 0.3934913008, 0.5472380443, 0.0592706549, 0.0000000000}, - {0, 0, 0, 0, 1, 0.2462883939, 0.6991456238, 0.0545659823, 0.0000000000}, - {0, 0, 0, 0, 1, 0.1163195334, 0.8427538829, 0.0409265838, 0.0000000000}, - {0, 0, 0, 0, 1, 0.2707097521, 0.5811217960, 0.1481684519, 0.0000000000}, - {0, 0, 0, 0, 1, 0.3019928872, 0.4393774966, 0.1776946096, 0.0809350066}}; + {0, 0, 0, 1, 0, 0.0265250690, 0.0265250690, 0.9469498620, 0.0000000000}, + {0, 0, 0, 1, 0, 0.1330857076, 0.1330857076, 0.7338285848, 0.0000000000}, + {0, 0, 0, 1, 0, 0.4232062312, 0.4232062312, 0.1535875376, 0.0000000000}, + {0, 0, 0, 1, 0, 0.2833924371, 0.2833924371, 0.4332151258, 0.0000000000}, + {0, 0, 0, 1, 0, 0.1734555313, 0.1734555313, 0.5762731177, 0.0768158196}, + {0, 0, 0, 1, 0, 0.0724033935, 0.0724033935, 0.6893564961, 0.1658367169}, + {0, 0, 0, 1, 0, 0.0768451848, 0.0768451848, 0.5573732958, 0.2889363346}, + {0, 0, 0, 0, 1, 0.3934913008, 0.5472380443, 0.0592706549, 0.0000000000}, + {0, 0, 0, 0, 1, 0.2462883939, 0.6991456238, 0.0545659823, 0.0000000000}, + {0, 0, 0, 0, 1, 0.1163195334, 0.8427538829, 0.0409265838, 0.0000000000}, + {0, 0, 0, 0, 1, 0.2707097521, 0.5811217960, 0.1481684519, 0.0000000000}, + {0, 0, 0, 0, 1, 0.3019928872, 0.4393774966, 0.1776946096, 0.0809350066}}; } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index c23f86544..19541cb47 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -565,7 +565,7 @@ void ProcessVarOpti::Process() } res->startE = 0.0; - for(int i = 0; i < m_mesh->m_element[2].size(); i++) + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { res->startE += GetElFunctional(dataSet[i]); } @@ -631,7 +631,7 @@ void ProcessVarOpti::Process() } res->endE = 0.0; - for(int i = 0; i < m_mesh->m_element[2].size(); i++) + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { res->endE += GetElFunctional(dataSet[i]); } @@ -1476,6 +1476,12 @@ void ProcessVarOpti::FillQuadPoints() Array u, v, w; LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); + for(int j = 0; j < u.num_elements(); j++) + { + cout << u[j] << " " << v[j] << " " << w[j] << endl; + } + exit(-1); + Array coeffs0 = geom->GetCoeffs(0); Array coeffs1 = geom->GetCoeffs(1); Array coeffs2 = geom->GetCoeffs(2); @@ -1490,10 +1496,7 @@ void ProcessVarOpti::FillQuadPoints() vector hons; - ASSERTL0(4 + 6*(nq-2) + 4 * ((nq-2)*(nq-3) / 2) <= u.num_elements(), - "volume interior nodes in tet"); - - /*//need to finish for tet + //need to finish for tet for(int j = 4 + 6*(nq-2) + 4 * ((nq-2)*(nq-3) / 2); j < u.num_elements(); j++) { @@ -1502,13 +1505,15 @@ void ProcessVarOpti::FillQuadPoints() xp[1] = v[j]; xp[2] = w[j]; + cout << u[j] << " " << v[j] << " " << w[j] << endl; + hons.push_back(boost::shared_ptr(new Node( id++,xmap->PhysEvaluate(xp,xc), xmap->PhysEvaluate(xp,yc), xmap->PhysEvaluate(xp,zc)))); } - el->SetVolumeNodes(hons);*/ + el->SetVolumeNodes(hons); el->SetCurveType(LibUtilities::eNodalTetElec); } } -- GitLab From e09bead16502b582d3c2b17758124cf2b47a514b Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 9 May 2016 17:22:02 +0100 Subject: [PATCH 031/236] working code --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 43 ------------------- 1 file changed, 43 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 19541cb47..a1068ae2a 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -1476,12 +1476,6 @@ void ProcessVarOpti::FillQuadPoints() Array u, v, w; LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); - for(int j = 0; j < u.num_elements(); j++) - { - cout << u[j] << " " << v[j] << " " << w[j] << endl; - } - exit(-1); - Array coeffs0 = geom->GetCoeffs(0); Array coeffs1 = geom->GetCoeffs(1); Array coeffs2 = geom->GetCoeffs(2); @@ -1505,8 +1499,6 @@ void ProcessVarOpti::FillQuadPoints() xp[1] = v[j]; xp[2] = w[j]; - cout << u[j] << " " << v[j] << " " << w[j] << endl; - hons.push_back(boost::shared_ptr(new Node( id++,xmap->PhysEvaluate(xp,xc), xmap->PhysEvaluate(xp,yc), @@ -1533,41 +1525,6 @@ void ProcessVarOpti::FillQuadPoints() res->startInv++; } } - - - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - - SpatialDomains::GeometrySharedPtr geom = el->GetGeom(el->GetDim()); - geom->FillGeom(); - StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); - - LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTetElec); - Array u, v, w; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); - - Array xc(chi->GetTotPoints()); - Array yc(chi->GetTotPoints()); - Array zc(chi->GetTotPoints()); - - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - Array coeffs2 = geom->GetCoeffs(2); - - chi->BwdTrans(coeffs0,xc); - chi->BwdTrans(coeffs1,yc); - chi->BwdTrans(coeffs2,zc); - - for(int j = 0; j < u.num_elements(); j++) - { - Array xp(3); - xp[0] = u[j]; - xp[1] = v[j]; - xp[2] = w[j]; - } - } } void ProcessVarOpti::WriteStats(string file) -- GitLab From 30efe6415b30c84e4a06586881a738a77e85ffd9 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Tue, 10 May 2016 14:50:02 +0100 Subject: [PATCH 032/236] matrix mul and res --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 137 ++++++------------ 1 file changed, 47 insertions(+), 90 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index a1068ae2a..e3f6837d0 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -56,7 +56,6 @@ namespace Utilities { boost::mutex mtx; -NekMatrix interp; int ptsLow; int ptsHigh; int dim; @@ -77,9 +76,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d) if(dim == 2) { - NekVector X(ptsLow),Y(ptsLow), - x1(ptsLow),y1(ptsLow), - x2(ptsLow),y2(ptsLow); + NekVector X(ptsLow),Y(ptsLow); for(int i = 0; i < ptsLow; i++) { X(i) = ns[i]->m_x; @@ -89,15 +86,10 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d) NekVector x1i(ptsHigh),y1i(ptsHigh), x2i(ptsHigh),y2i(ptsHigh); - x1 = VdmDx*X; - y1 = VdmDx*Y; - x2 = VdmDy*X; - y2 = VdmDy*Y; - - x1i = interp * x1; - x2i = interp * x2; - y1i = interp * y1; - y2i = interp * y2; + x1i = VdmDx*X; + y1i = VdmDx*Y; + x2i = VdmDy*X; + y2i = VdmDy*Y; for(int i = 0; i < ptsHigh; i++) { @@ -113,10 +105,7 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d) } else { - NekVector X(ptsLow),Y(ptsLow),Z(ptsLow), - x1(ptsHigh),y1(ptsHigh),z1(ptsHigh), - x2(ptsHigh),y2(ptsHigh),z2(ptsHigh), - x3(ptsHigh),y3(ptsHigh),z3(ptsHigh); + NekVector X(ptsLow),Y(ptsLow),Z(ptsLow); for(int i = 0; i < ptsLow; i++) { X(i) = ns[i]->m_x; @@ -124,29 +113,19 @@ inline NekDouble GetElFunctional(ElDataSharedPtr d) Z(i) = ns[i]->m_z; } - x1 = VdmDx*X; - y1 = VdmDx*Y; - z1 = VdmDx*Z; - x2 = VdmDy*X; - y2 = VdmDy*Y; - z2 = VdmDy*Z; - x3 = VdmDz*X; - y3 = VdmDz*Y; - z3 = VdmDz*Z; - NekVector x1i(ptsHigh),y1i(ptsHigh),z1i(ptsHigh), x2i(ptsHigh),y2i(ptsHigh),z2i(ptsHigh), x3i(ptsHigh),y3i(ptsHigh),z3i(ptsHigh); - x1i = interp * x1; - x2i = interp * x2; - x3i = interp * x3; - y1i = interp * y1; - y2i = interp * y2; - y3i = interp * y3; - z1i = interp * z1; - z2i = interp * z2; - z3i = interp * z3; + x1i = VdmDx*X; + y1i = VdmDx*Y; + z1i = VdmDx*Z; + x2i = VdmDy*X; + y2i = VdmDy*Y; + z2i = VdmDy*Z; + x3i = VdmDz*X; + y3i = VdmDz*Y; + z3i = VdmDz*Z; for(int i = 0; i < ptsHigh; i++) { @@ -499,15 +478,15 @@ void ProcessVarOpti::Process() NekVector U2(u2), V2(v2); ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); - interp = LibUtilities::GetInterpolationMatrix(U1, V1, U2, V2); + NekMatrix interp = LibUtilities::GetInterpolationMatrix(U1, V1, U2, V2); NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); - VdmDx = LibUtilities::GetVandermondeForXDerivative(U1,V1) * - VandermondeI; - VdmDy = LibUtilities::GetVandermondeForYDerivative(U1,V1) * - VandermondeI; + VdmDx = interp * ( + LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI); + VdmDy = interp * ( + LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI); //quadW = LibUtilities::MakeQuadratureWeights(U2,V1); Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); NekVector quadWi(qds); @@ -528,19 +507,20 @@ void ProcessVarOpti::Process() NekVector U2(u2), V2(v2), W2(w2); ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); - interp = LibUtilities::GetTetInterpolationMatrix(U1, V1, W1, - U2, V2, W2); + NekMatrix interp = + LibUtilities::GetTetInterpolationMatrix(U1, V1, W1, + U2, V2, W2); NekMatrix Vandermonde = LibUtilities::GetTetVandermonde(U1,V1,W1); NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); - VdmDx = LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * - VandermondeI; - VdmDy = LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * - VandermondeI; - VdmDz = LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * - VandermondeI; + VdmDx = interp * ( + LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI); + VdmDy = interp * ( + LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI); + VdmDz = interp * ( + LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI); Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); NekVector quadWi(qds); quadW = quadWi; @@ -600,7 +580,7 @@ void ProcessVarOpti::Process() Thread::ThreadManagerSharedPtr tm = tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads); - while (res->val > 1e-5) + while (res->val > 1e-6) { ctr++; res->val = 0.0; @@ -625,8 +605,6 @@ void ProcessVarOpti::Process() }*/ } - res->val = sqrt(res->val / res->n); - cout << ctr << "\tResidual: " << res->val << endl; } @@ -716,8 +694,8 @@ void ProcessVarOpti::NodeOpti::Optimise() // cout << G[0] << " " << G[1] << " " << G[2] << " " << node->m_id << endl; } mtx.lock(); - res->val += (node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ - (node->m_z-zc)*(node->m_z-zc); + res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ + (node->m_z-zc)*(node->m_z-zc)),res->val); mtx.unlock(); } } @@ -1081,9 +1059,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP chi->BwdTrans(coeffs0,xc); chi->BwdTrans(coeffs1,yc); - NekVector X(ptsLow),Y(ptsLow), - x1(ptsLow),y1(ptsLow), - x2(ptsLow),y2(ptsLow); + NekVector X(ptsLow),Y(ptsLow); for(int j = 0; j < u.num_elements(); j++) { Array xp(2); @@ -1097,16 +1073,10 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP NekVector x1i(ptsHigh),y1i(ptsHigh), x2i(ptsHigh),y2i(ptsHigh); - x1 = VdmDx*X; - y1 = VdmDx*Y; - x2 = VdmDy*X; - y2 = VdmDy*Y; - - x1i = interp * x1; - x2i = interp * x2; - y1i = interp * y1; - y2i = interp * y2; - + x1i = VdmDx*X; + y1i = VdmDx*Y; + x2i = VdmDy*X; + y2i = VdmDy*Y; for(int i = 0 ; i < ptsHigh; i++) { @@ -1147,10 +1117,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP chi->BwdTrans(coeffs1,yc); chi->BwdTrans(coeffs2,zc); - NekVector X(ptsLow),Y(ptsLow),Z(ptsLow), - x1(ptsLow),y1(ptsLow),z1(ptsLow), - x2(ptsLow),y2(ptsLow),z2(ptsLow), - x3(ptsLow),y3(ptsLow),z3(ptsLow); + NekVector X(ptsLow),Y(ptsLow),Z(ptsLow); for(int j = 0; j < u.num_elements(); j++) { Array xp(3); @@ -1167,25 +1134,15 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP x2i(ptsHigh),y2i(ptsHigh),z2i(ptsHigh), x3i(ptsHigh),y3i(ptsHigh),z3i(ptsHigh); - x1 = VdmDx*X; - y1 = VdmDx*Y; - x2 = VdmDy*X; - y2 = VdmDy*Y; - z1 = VdmDx*Z; - z2 = VdmDy*Z; - x3 = VdmDz*X; - y3 = VdmDz*Y; - z3 = VdmDz*Z; - - x1i = interp * x1; - x2i = interp * x2; - x3i = interp * x3; - y1i = interp * y1; - y2i = interp * y2; - y3i = interp * y3; - z1i = interp * z1; - z2i = interp * z2; - z3i = interp * z3; + x1i = VdmDx*X; + y1i = VdmDx*Y; + x2i = VdmDy*X; + y2i = VdmDy*Y; + z1i = VdmDx*Z; + z2i = VdmDy*Z; + x3i = VdmDz*X; + y3i = VdmDz*Y; + z3i = VdmDz*Z; for(int i = 0 ; i < ptsHigh; i++) { -- GitLab From fad4e318c8c13eaa7942e95e75ad8dfd235ed97a Mon Sep 17 00:00:00 2001 From: David Moxey Date: Tue, 10 May 2016 15:46:18 +0100 Subject: [PATCH 033/236] Add volume node support. Gmsh input currently still broken, needs a reordering strategy. --- library/NekMeshUtils/MeshElements/Element.h | 201 ++---------------- library/NekMeshUtils/MeshElements/Line.cpp | 10 + library/NekMeshUtils/MeshElements/Line.h | 3 + .../MeshElements/Quadrilateral.cpp | 48 +++++ .../NekMeshUtils/MeshElements/Quadrilateral.h | 3 +- .../NekMeshUtils/MeshElements/Tetrahedron.cpp | 89 ++++++++ .../NekMeshUtils/MeshElements/Tetrahedron.h | 3 +- .../NekMeshUtils/MeshElements/Triangle.cpp | 27 +++ library/NekMeshUtils/MeshElements/Triangle.h | 3 +- library/SpatialDomains/Geometry3D.cpp | 76 ++++++- library/SpatialDomains/Geometry3D.h | 1 + library/SpatialDomains/MeshGraph.cpp | 138 +++++++++++- library/SpatialDomains/MeshGraph.h | 2 + library/SpatialDomains/MeshGraph3D.cpp | 15 +- library/SpatialDomains/TetGeom.cpp | 4 +- library/SpatialDomains/TetGeom.h | 11 +- utilities/NekMesh/InputModules/InputGmsh.cpp | 16 +- .../NekMesh/OutputModules/OutputNekpp.cpp | 45 ++-- 18 files changed, 481 insertions(+), 214 deletions(-) diff --git a/library/NekMeshUtils/MeshElements/Element.h b/library/NekMeshUtils/MeshElements/Element.h index d94e8e856..d79cb17f8 100644 --- a/library/NekMeshUtils/MeshElements/Element.h +++ b/library/NekMeshUtils/MeshElements/Element.h @@ -219,19 +219,18 @@ struct ElmtConfig /// Element type (e.g. triangle, quad, etc). LibUtilities::ShapeType m_e; - /// Denotes whether the element contains face nodes. For 2D - /// elements, if this is true then the element contains interior - /// nodes. + /// Denotes whether the element contains face nodes. For 2D elements, if + /// this is true then the element contains interior nodes. bool m_faceNodes; - /// Denotes whether the element contains volume (i.e. interior) - /// nodes. These are not supported by either the mesh converter or - /// Nektar++ but are included for completeness and are required - /// for some output modules (e.g. Gmsh). + /// Denotes whether the element contains volume (i.e. interior) nodes. These + /// are not supported by either the mesh converter or Nektar++ but are + /// included for completeness and are required for some output modules + /// (e.g. Gmsh). bool m_volumeNodes; /// Order of the element. unsigned int m_order; - /// Denotes whether the element needs to be re-orientated for a - /// spectral element framework. + /// Denotes whether the element needs to be re-orientated for a spectral + /// element framework. bool m_reorient; /// Distribution of points in edges. LibUtilities::PointsType m_edgeCurveType; @@ -349,8 +348,15 @@ public: } else { - cerr << "Not supported." << endl; - exit(1); + for (int i = 0; i < m_face.size(); ++i) + { + n += m_face[i]->GetNodeCount(); + } + for (int i = 0; i < m_edge.size(); ++i) + { + n -= m_edge[i]->GetNodeCount(); + } + n += m_vertex.size(); } return n; } @@ -459,178 +465,11 @@ public: return s.str(); } - NEKMESHUTILS_EXPORT void GetCurvedNodes( + NEKMESHUTILS_EXPORT virtual void GetCurvedNodes( std::vector &nodeList) const { - // Node orderings are different for different elements. - // Triangle - if (m_vertex.size() == 2) - { - nodeList.push_back(m_vertex[0]); - for (int i = 0; i < m_volumeNodes.size(); ++i) - { - nodeList.push_back(m_volumeNodes[i]); - } - nodeList.push_back(m_vertex[1]); - } - else if (m_vertex.size() == 3) - { - int n = m_edge[0]->GetNodeCount(); - nodeList.resize(n * (n + 1) / 2); - - // Populate nodelist - std::copy(m_vertex.begin(), m_vertex.end(), nodeList.begin()); - for (int i = 0; i < 3; ++i) - { - std::copy(m_edge[i]->m_edgeNodes.begin(), - m_edge[i]->m_edgeNodes.end(), - nodeList.begin() + 3 + i * (n - 2)); - if (m_edge[i]->m_n1 != m_vertex[i]) - { - // If edge orientation is reversed relative to node - // ordering, we need to reverse order of nodes. - std::reverse(nodeList.begin() + 3 + i * (n - 2), - nodeList.begin() + 3 + (i + 1) * (n - 2)); - } - } - - // Copy volume nodes. - std::copy(m_volumeNodes.begin(), - m_volumeNodes.end(), - nodeList.begin() + 3 * (n - 1)); - } - // Quad - else if (m_dim == 2 && m_vertex.size() == 4) - { - int n = m_edge[0]->GetNodeCount(); - nodeList.resize(n * n); - - // Write vertices - nodeList[0] = m_vertex[0]; - nodeList[n - 1] = m_vertex[1]; - nodeList[n * n - 1] = m_vertex[2]; - nodeList[n * (n - 1)] = m_vertex[3]; - - // Write edge-interior - int skips[4][2] = { - {0, 1}, {n - 1, n}, {n * n - 1, -1}, {n * (n - 1), -n}}; - for (int i = 0; i < 4; ++i) - { - bool reverseEdge = m_edge[i]->m_n1 == m_vertex[i]; - - if (!reverseEdge) - { - for (int j = 1; j < n - 1; ++j) - { - nodeList[skips[i][0] + j * skips[i][1]] = - m_edge[i]->m_edgeNodes[n - 2 - j]; - } - } - else - { - for (int j = 1; j < n - 1; ++j) - { - nodeList[skips[i][0] + j * skips[i][1]] = - m_edge[i]->m_edgeNodes[j - 1]; - } - } - } - - // Write interior - for (int i = 1; i < n - 1; ++i) - { - for (int j = 1; j < n - 1; ++j) - { - nodeList[i * n + j] = - m_volumeNodes[(i - 1) * (n - 2) + (j - 1)]; - } - } - } - else if (m_dim == 3 && m_vertex.size() == 4) - { - int n = m_edge[0]->GetNodeCount(); - nodeList.resize(n*(n+1)*(n+2)/6); - - nodeList[0] = m_vertex[0]; - nodeList[1] = m_vertex[1]; - nodeList[2] = m_vertex[2]; - nodeList[3] = m_vertex[3]; - int k = 4; - - for(int i = 0; i < 6; i++) - { - bool reverseEdge = false; - if(i < 3) - { - reverseEdge = m_edge[i]->m_n1 == m_vertex[i]; - } - else - { - reverseEdge = m_edge[i]->m_n1 == m_vertex[i-3]; - } - - if (reverseEdge) - { - for(int j = 0; j < n-2; j++) - { - nodeList[k++] = m_edge[i]->m_edgeNodes[j]; - } - } - else - { - for(int j = n-3; j >= 0; j--) - { - nodeList[k++] = m_edge[i]->m_edgeNodes[j]; - } - } - } - - vector > ts; - vector t(3); - t[0] = m_vertex[0]->m_id; - t[1] = m_vertex[1]->m_id; - t[2] = m_vertex[2]->m_id; - ts.push_back(t); - t[0] = m_vertex[0]->m_id; - t[1] = m_vertex[1]->m_id; - t[2] = m_vertex[3]->m_id; - ts.push_back(t); - t[0] = m_vertex[1]->m_id; - t[1] = m_vertex[2]->m_id; - t[2] = m_vertex[3]->m_id; - ts.push_back(t); - t[0] = m_vertex[0]->m_id; - t[1] = m_vertex[2]->m_id; - t[2] = m_vertex[3]->m_id; - ts.push_back(t); - - for(int i = 0; i < 4; i++) - { - vector fcid; - fcid.push_back(m_face[i]->m_vertexList[0]->m_id); - fcid.push_back(m_face[i]->m_vertexList[1]->m_id); - fcid.push_back(m_face[i]->m_vertexList[2]->m_id); - - HOTriangle hot(fcid, m_face[i]->m_faceNodes); - - hot.Align(ts[i]); - - std::copy(hot.surfVerts.begin(), - hot.surfVerts.end(), - nodeList.begin() + k); - k+= hot.surfVerts.size(); - } - - std::copy(m_volumeNodes.begin(), - m_volumeNodes.end(), - nodeList.begin() + k); - - } - else - { - cerr << "GetXmlCurveString for a " << m_vertex.size() - << "-vertex element is not yet implemented." << endl; - } + cerr << "WARNING: Unsupported curvature for a " << m_vertex.size() + << "-vertex element is not yet implemented." << endl; } /// Generates a string listing the coordinates of all nodes diff --git a/library/NekMeshUtils/MeshElements/Line.cpp b/library/NekMeshUtils/MeshElements/Line.cpp index 862838530..915ce2705 100644 --- a/library/NekMeshUtils/MeshElements/Line.cpp +++ b/library/NekMeshUtils/MeshElements/Line.cpp @@ -109,6 +109,16 @@ SpatialDomains::GeometrySharedPtr Line::GetGeom(int coordDim) return ret; } +void Line::GetCurvedNodes(std::vector &nodeList) const +{ + nodeList.push_back(m_vertex[0]); + for (int i = 0; i < m_volumeNodes.size(); ++i) + { + nodeList.push_back(m_volumeNodes[i]); + } + nodeList.push_back(m_vertex[1]); +} + /** * @brief Return the number of nodes defining a line. */ diff --git a/library/NekMeshUtils/MeshElements/Line.h b/library/NekMeshUtils/MeshElements/Line.h index 158475be6..b38d83120 100644 --- a/library/NekMeshUtils/MeshElements/Line.h +++ b/library/NekMeshUtils/MeshElements/Line.h @@ -66,6 +66,9 @@ public: { } + NEKMESHUTILS_EXPORT virtual void GetCurvedNodes( + std::vector &nodeList) const; + NEKMESHUTILS_EXPORT virtual SpatialDomains::GeometrySharedPtr GetGeom( int coordDim); diff --git a/library/NekMeshUtils/MeshElements/Quadrilateral.cpp b/library/NekMeshUtils/MeshElements/Quadrilateral.cpp index 8a7fa70f8..95adcd5a9 100644 --- a/library/NekMeshUtils/MeshElements/Quadrilateral.cpp +++ b/library/NekMeshUtils/MeshElements/Quadrilateral.cpp @@ -197,6 +197,54 @@ SpatialDomains::GeometrySharedPtr Quadrilateral::GetGeom(int coordDim) return ret; } +void Quadrilateral::GetCurvedNodes(std::vector &nodeList) const +{ + int n = m_edge[0]->GetNodeCount(); + nodeList.resize(n * n); + + // Write vertices + nodeList[0] = m_vertex[0]; + nodeList[n - 1] = m_vertex[1]; + nodeList[n * n - 1] = m_vertex[2]; + nodeList[n * (n - 1)] = m_vertex[3]; + + // Write edge-interior + int skips[4][2] = { + {0, 1}, {n - 1, n}, {n * n - 1, -1}, {n * (n - 1), -n}}; + for (int i = 0; i < 4; ++i) + { + bool reverseEdge = m_edge[i]->m_n1 == m_vertex[i]; + + if (!reverseEdge) + { + for (int j = 1; j < n - 1; ++j) + { + nodeList[skips[i][0] + j * skips[i][1]] = + m_edge[i]->m_edgeNodes[n - 2 - j]; + } + } + else + { + for (int j = 1; j < n - 1; ++j) + { + nodeList[skips[i][0] + j * skips[i][1]] = + m_edge[i]->m_edgeNodes[j - 1]; + } + } + } + + // Write interior + for (int i = 1; i < n - 1; ++i) + { + for (int j = 1; j < n - 1; ++j) + { + nodeList[i * n + j] = + m_volumeNodes[(i - 1) * (n - 2) + (j - 1)]; + } + } +} + + /** * @brief Return the number of nodes defining a quadrilateral. */ diff --git a/library/NekMeshUtils/MeshElements/Quadrilateral.h b/library/NekMeshUtils/MeshElements/Quadrilateral.h index d5f36eae1..086b25400 100644 --- a/library/NekMeshUtils/MeshElements/Quadrilateral.h +++ b/library/NekMeshUtils/MeshElements/Quadrilateral.h @@ -77,7 +77,8 @@ public: NEKMESHUTILS_EXPORT virtual SpatialDomains::GeometrySharedPtr GetGeom( int coordDim); NEKMESHUTILS_EXPORT virtual void Complete(int order); - + NEKMESHUTILS_EXPORT virtual void GetCurvedNodes( + std::vector &nodeList) const; NEKMESHUTILS_EXPORT static unsigned int GetNumNodes(ElmtConfig pConf); }; } diff --git a/library/NekMeshUtils/MeshElements/Tetrahedron.cpp b/library/NekMeshUtils/MeshElements/Tetrahedron.cpp index 27e66c931..b580e4290 100644 --- a/library/NekMeshUtils/MeshElements/Tetrahedron.cpp +++ b/library/NekMeshUtils/MeshElements/Tetrahedron.cpp @@ -204,6 +204,15 @@ Tetrahedron::Tetrahedron(ElmtConfig pConf, faceVertices, faceNodes, faceEdges, m_conf.m_faceCurveType))); } + if (m_conf.m_volumeNodes) + { + const int nFaceNodes = n * (n - 1) / 2; + for (int i = 4 + 6 * n + 4 * nFaceNodes; i < pNodeList.size(); ++i) + { + m_volumeNodes.push_back(pNodeList[i]); + } + } + vector tmp(6); tmp[0] = m_edge[face_edges[0][0]]; tmp[1] = m_edge[face_edges[0][1]]; @@ -398,6 +407,86 @@ bool operator==(const struct TetOrient &a, const struct TetOrient &b) return true; } +void Tetrahedron::GetCurvedNodes(std::vector &nodeList) const +{ + int n = m_edge[0]->GetNodeCount(); + nodeList.resize(n*(n+1)*(n+2)/6); + + nodeList[0] = m_vertex[0]; + nodeList[1] = m_vertex[1]; + nodeList[2] = m_vertex[2]; + nodeList[3] = m_vertex[3]; + int k = 4; + + for(int i = 0; i < 6; i++) + { + bool reverseEdge = false; + if(i < 3) + { + reverseEdge = m_edge[i]->m_n1 == m_vertex[i]; + } + else + { + reverseEdge = m_edge[i]->m_n1 == m_vertex[i-3]; + } + + if (reverseEdge) + { + for(int j = 0; j < n-2; j++) + { + nodeList[k++] = m_edge[i]->m_edgeNodes[j]; + } + } + else + { + for(int j = n-3; j >= 0; j--) + { + nodeList[k++] = m_edge[i]->m_edgeNodes[j]; + } + } + } + + vector > ts; + vector t(3); + t[0] = m_vertex[0]->m_id; + t[1] = m_vertex[1]->m_id; + t[2] = m_vertex[2]->m_id; + ts.push_back(t); + t[0] = m_vertex[0]->m_id; + t[1] = m_vertex[1]->m_id; + t[2] = m_vertex[3]->m_id; + ts.push_back(t); + t[0] = m_vertex[1]->m_id; + t[1] = m_vertex[2]->m_id; + t[2] = m_vertex[3]->m_id; + ts.push_back(t); + t[0] = m_vertex[0]->m_id; + t[1] = m_vertex[2]->m_id; + t[2] = m_vertex[3]->m_id; + ts.push_back(t); + + for(int i = 0; i < 4; i++) + { + vector fcid; + fcid.push_back(m_face[i]->m_vertexList[0]->m_id); + fcid.push_back(m_face[i]->m_vertexList[1]->m_id); + fcid.push_back(m_face[i]->m_vertexList[2]->m_id); + + HOTriangle hot(fcid, m_face[i]->m_faceNodes); + + hot.Align(ts[i]); + + std::copy(hot.surfVerts.begin(), + hot.surfVerts.end(), + nodeList.begin() + k); + k+= hot.surfVerts.size(); + } + + std::copy(m_volumeNodes.begin(), + m_volumeNodes.end(), + nodeList.begin() + k); +} + /** * @brief Orient tetrahedron to align degenerate vertices. * diff --git a/library/NekMeshUtils/MeshElements/Tetrahedron.h b/library/NekMeshUtils/MeshElements/Tetrahedron.h index d4324ce19..91e21ce59 100644 --- a/library/NekMeshUtils/MeshElements/Tetrahedron.h +++ b/library/NekMeshUtils/MeshElements/Tetrahedron.h @@ -78,7 +78,8 @@ public: NEKMESHUTILS_EXPORT virtual SpatialDomains::GeometrySharedPtr GetGeom( int coordDim); NEKMESHUTILS_EXPORT virtual void Complete(int order); - + NEKMESHUTILS_EXPORT virtual void GetCurvedNodes( + std::vector &nodeList) const; NEKMESHUTILS_EXPORT static unsigned int GetNumNodes(ElmtConfig pConf); int m_orientationMap[4]; diff --git a/library/NekMeshUtils/MeshElements/Triangle.cpp b/library/NekMeshUtils/MeshElements/Triangle.cpp index 3bf09f50d..ba767ea9b 100644 --- a/library/NekMeshUtils/MeshElements/Triangle.cpp +++ b/library/NekMeshUtils/MeshElements/Triangle.cpp @@ -150,6 +150,33 @@ unsigned int Triangle::GetNumNodes(ElmtConfig pConf) return (n + 1) * (n + 2) / 2; } +void Triangle::GetCurvedNodes(std::vector &nodeList) const +{ + int n = m_edge[0]->GetNodeCount(); + nodeList.resize(n * (n + 1) / 2); + + // Populate nodelist + std::copy(m_vertex.begin(), m_vertex.end(), nodeList.begin()); + for (int i = 0; i < 3; ++i) + { + std::copy(m_edge[i]->m_edgeNodes.begin(), + m_edge[i]->m_edgeNodes.end(), + nodeList.begin() + 3 + i * (n - 2)); + if (m_edge[i]->m_n1 != m_vertex[i]) + { + // If edge orientation is reversed relative to node ordering, we + // need to reverse order of nodes. + std::reverse(nodeList.begin() + 3 + i * (n - 2), + nodeList.begin() + 3 + (i + 1) * (n - 2)); + } + } + + // Copy volume nodes. + std::copy(m_volumeNodes.begin(), + m_volumeNodes.end(), + nodeList.begin() + 3 * (n - 1)); +} + void Triangle::Complete(int order) { int i, j; diff --git a/library/NekMeshUtils/MeshElements/Triangle.h b/library/NekMeshUtils/MeshElements/Triangle.h index af9e38982..178098eb6 100644 --- a/library/NekMeshUtils/MeshElements/Triangle.h +++ b/library/NekMeshUtils/MeshElements/Triangle.h @@ -73,7 +73,8 @@ public: NEKMESHUTILS_EXPORT virtual SpatialDomains::GeometrySharedPtr GetGeom( int coordDim); NEKMESHUTILS_EXPORT virtual void Complete(int order); - + NEKMESHUTILS_EXPORT virtual void GetCurvedNodes( + std::vector &nodeList) const; NEKMESHUTILS_EXPORT static unsigned int GetNumNodes(ElmtConfig pConf); }; diff --git a/library/SpatialDomains/Geometry3D.cpp b/library/SpatialDomains/Geometry3D.cpp index a710596e4..606a0ff37 100644 --- a/library/SpatialDomains/Geometry3D.cpp +++ b/library/SpatialDomains/Geometry3D.cpp @@ -33,8 +33,12 @@ // //////////////////////////////////////////////////////////////////////////////// -#include +#include +#include + +#include +#include #include #include #include @@ -248,6 +252,76 @@ namespace SpatialDomains int i,j,k; + if (m_curve) + { + int pdim = LibUtilities::PointsManager()[ + LibUtilities::PointsKey(3, m_curve->m_ptype)] + ->GetPointsDim(); + + // Deal with 2D points type separately + // (e.g. electrostatic or Fekete points) to 1D tensor + // product. + if (pdim == 3) + { + int N = m_curve->m_points.size(); + + // Need the cubic formula to solve for nEdgePts + NekDouble tmp1 = pow(sqrt(3.0*(243.0*N*N - 1.0)) + 27.0*N, 1.0/3.0); + int nEdgePts = round(tmp1 / pow(3.0, 2.0/3.0) + + 1.0 / tmp1 / pow(3.0, 1.0/3.0) - 2.0) + 1; + + ASSERTL0(nEdgePts*(nEdgePts+1)*(nEdgePts+2) / 6 == N, + "NUMPOINTS should be a tetrahedral number for" + " tetrahedron " + + boost::lexical_cast(m_globalID)); + + const LibUtilities::PointsKey P0( + nEdgePts, LibUtilities::eGaussLobattoLegendre); + const LibUtilities::PointsKey P1( + nEdgePts, LibUtilities::eGaussRadauMAlpha1Beta0); + const LibUtilities::PointsKey P2( + nEdgePts, LibUtilities::eGaussRadauMAlpha2Beta0); + const LibUtilities::BasisKey T0( + LibUtilities::eOrtho_A, nEdgePts, P0); + const LibUtilities::BasisKey T1( + LibUtilities::eOrtho_B, nEdgePts, P1); + const LibUtilities::BasisKey T2( + LibUtilities::eOrtho_C, nEdgePts, P2); + Array phys(max(N, m_xmap->GetTotPoints())); + Array tmp(m_xmap->GetTotPoints()); + + for(i = 0; i < m_coordim; ++i) + { + // Create a StdNodalTetExp. + StdRegions::StdNodalTetExpSharedPtr t = + MemoryManager + ::AllocateSharedPtr(T0, T1, T2, m_curve->m_ptype); + + for (j = 0; j < N; ++j) + { + phys[j] = (m_curve->m_points[j]->GetPtr())[i]; + } + + t->BwdTrans(phys, tmp); + + // Interpolate points to standard region. + LibUtilities::Interp3D( + P0, P1, P2, tmp, + m_xmap->GetBasis(0)->GetPointsKey(), + m_xmap->GetBasis(1)->GetPointsKey(), + m_xmap->GetBasis(2)->GetPointsKey(), + phys); + + // Forwards transform to get coefficient space. + m_xmap->FwdTrans(phys, m_coeffs[i]); + } + } + else + { + ASSERTL0(false, "Only 3D points distributions supported."); + } + } + for(i = 0; i < m_forient.size(); i++) { m_faces[i]->FillGeom(); diff --git a/library/SpatialDomains/Geometry3D.h b/library/SpatialDomains/Geometry3D.h index bbf2f3d11..fa8c258b5 100644 --- a/library/SpatialDomains/Geometry3D.h +++ b/library/SpatialDomains/Geometry3D.h @@ -95,6 +95,7 @@ namespace Nektar bool m_owndata; int m_eid; bool m_ownverts; + CurveSharedPtr m_curve; //--------------------------------------- // 3D Geometry Methods diff --git a/library/SpatialDomains/MeshGraph.cpp b/library/SpatialDomains/MeshGraph.cpp index d0f2f1d27..8d64f018d 100644 --- a/library/SpatialDomains/MeshGraph.cpp +++ b/library/SpatialDomains/MeshGraph.cpp @@ -1272,6 +1272,7 @@ namespace Nektar std::vector edginfo; std::vector facinfo; + std::vector volinfo; LibUtilities::MeshCurvedPts cpts; // read edge, face info and curved poitns. @@ -1308,6 +1309,20 @@ namespace Nektar LibUtilities::CompressData::ZlibDecodeFromBase64Str( elmtStr,facinfo); } + else if(boost::iequals(entitytype,"V")) + { + // read in data + std::string elmtStr; + TiXmlNode* child = x->FirstChild(); + + if (child->Type() == TiXmlNode::TINYXML_TEXT) + { + elmtStr += child->ToText()->ValueStr(); + } + + LibUtilities::CompressData::ZlibDecodeFromBase64Str( + elmtStr,volinfo); + } else if(boost::iequals(entitytype,"DATAPOINTS")) { NekInt id; @@ -1416,6 +1431,33 @@ namespace Nektar m_curvedFaces[faceid] = curve; } + + for(int i = 0; i < volinfo.size(); ++i) + { + int volid = volinfo[i].entityid; + LibUtilities::PointsType ptype; + + CurveSharedPtr curve( + MemoryManager::AllocateSharedPtr( + volid, ptype = (LibUtilities::PointsType) + volinfo[i].ptype)); + + int offset = volinfo[i].ptoffset; + for(int j = 0; j < volinfo[i].npoints; ++j) + { + int idx = cpts.index[offset+j]; + + PointGeomSharedPtr vert(MemoryManager:: + AllocateSharedPtr(m_meshDimension, + volinfo[i].id, + cpts.pts[idx].x, + cpts.pts[idx].y, + cpts.pts[idx].z)); + curve->m_points.push_back(vert); + } + + m_curvedVolumes[volid] = curve; + } } else { @@ -1553,7 +1595,7 @@ namespace Nektar elementStr += " "; } elementChild = elementChild->NextSibling(); - } + } ASSERTL0(!elementStr.empty(), "Unable to read curve description body."); @@ -1618,6 +1660,100 @@ namespace Nektar } // end if-loop } // end while-loop + + TiXmlElement *volelement = field->FirstChildElement("V"); + int volindx, volid; + + while(volelement) + { + std::string vol(volelement->ValueStr()); + ASSERTL0(vol == "V", (std::string("Unknown 3D curve type: ") + vol).c_str()); + + /// Read id attribute. + err = volelement->QueryIntAttribute("ID", &volindx); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute ID."); + + /// Read vol id attribute. + err = volelement->QueryIntAttribute("VOLID", &volid); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute VOLID."); + + /// Read text vol element description. + std::string elementStr; + TiXmlNode* elementChild = volelement->FirstChild(); + + while(elementChild) + { + // Accumulate all non-comment element data + if (elementChild->Type() == TiXmlNode::TINYXML_TEXT) + { + elementStr += elementChild->ToText()->ValueStr(); + elementStr += " "; + } + elementChild = elementChild->NextSibling(); + } + + ASSERTL0(!elementStr.empty(), "Unable to read curve description body."); + + /// Parse out the element components corresponding to type of element. + if(vol == "V") + { + std::string typeStr = volelement->Attribute("TYPE"); + ASSERTL0(!typeStr.empty(), "TYPE must be specified in points definition"); + LibUtilities::PointsType type; + const std::string* begStr = LibUtilities::kPointsTypeStr; + const std::string* endStr = LibUtilities::kPointsTypeStr + LibUtilities::SIZE_PointsType; + const std::string* ptsStr = std::find(begStr, endStr, typeStr); + + ASSERTL0(ptsStr != endStr, "Invalid points type."); + type = (LibUtilities::PointsType)(ptsStr - begStr); + + std::string numptsStr = volelement->Attribute("NUMPOINTS"); + ASSERTL0(!numptsStr.empty(), "NUMPOINTS must be specified in points definition"); + int numPts=0; + std::stringstream s; + s << numptsStr; + s >> numPts; + + CurveSharedPtr curve(MemoryManager::AllocateSharedPtr(volid, type)); + + ASSERTL0(numPts >= 4, "NUMPOINTS for vol must be greater than 4"); + + if(numPts == 3) + { + ASSERTL0(ptsStr != endStr, "Invalid points type."); + } + + // Read points (x, y, z) + NekDouble xval, yval, zval; + std::istringstream elementDataStrm(elementStr.c_str()); + try + { + while(!elementDataStrm.fail()) + { + elementDataStrm >> xval >> yval >> zval; + + // Need to check it here because we + // may not be good after the read + // indicating that there was nothing + // to read. + if (!elementDataStrm.fail()) + { + PointGeomSharedPtr vert(MemoryManager::AllocateSharedPtr(m_meshDimension, volindx, xval, yval, zval)); + curve->m_points.push_back(vert); + } + } + } + catch(...) + { + NEKERROR(ErrorUtil::efatal, + (std::string("Unable to read curve data for VOLUME: ") + + elementStr).c_str()); + } + m_curvedVolumes[volid] = curve; + + volelement = volelement->NextSiblingElement("V"); + } // end if-loop + } // end while-loop } // end of compressed else } // end of ReadCurves() diff --git a/library/SpatialDomains/MeshGraph.h b/library/SpatialDomains/MeshGraph.h index a9044f7c2..4f18c8faa 100644 --- a/library/SpatialDomains/MeshGraph.h +++ b/library/SpatialDomains/MeshGraph.h @@ -383,6 +383,7 @@ namespace Nektar SPATIAL_DOMAINS_EXPORT CurveMap& GetCurvedEdges() { return m_curvedEdges; } SPATIAL_DOMAINS_EXPORT CurveMap& GetCurvedFaces() { return m_curvedFaces; } + SPATIAL_DOMAINS_EXPORT CurveMap& GetCurvedVolumes() { return m_curvedVolumes; } // void AddExpansion(ExpansionShPtr expansion) { m_expansions[expansion->m_geomShPtr->GetGlobalID()] = expansion; } SPATIAL_DOMAINS_EXPORT const PointGeomMap& GetAllPointGeoms() const { return m_vertSet; } @@ -405,6 +406,7 @@ namespace Nektar CurveMap m_curvedEdges; CurveMap m_curvedFaces; + CurveMap m_curvedVolumes; SegGeomMap m_segGeoms; diff --git a/library/SpatialDomains/MeshGraph3D.cpp b/library/SpatialDomains/MeshGraph3D.cpp index fdf4223b1..048cb4ba6 100644 --- a/library/SpatialDomains/MeshGraph3D.cpp +++ b/library/SpatialDomains/MeshGraph3D.cpp @@ -511,6 +511,8 @@ namespace Nektar TiXmlElement* mesh = docHandle.FirstChildElement("NEKTAR").FirstChildElement("GEOMETRY").Element(); TiXmlElement* field = NULL; + CurveMap::iterator it; + /// Look for elements in ELEMENT block. field = mesh->FirstChildElement("ELEMENT"); @@ -570,8 +572,11 @@ namespace Nektar boost::static_pointer_cast(face); } - TetGeomSharedPtr tetgeom(MemoryManager - ::AllocateSharedPtr(tfaces)); + it = m_curvedVolumes.find(indx); + TetGeomSharedPtr tetgeom( + MemoryManager::AllocateSharedPtr( + tfaces, it == m_curvedVolumes.end() ? + CurveSharedPtr() : it->second)); tetgeom->SetGlobalID(indx); m_tetGeoms[indx] = tetgeom; PopulateFaceToElMap(tetgeom, 4); @@ -780,7 +785,11 @@ namespace Nektar ASSERTL0(Ntfaces == kNtfaces, errorstring.str().c_str()); ASSERTL0(Nqfaces == kNqfaces, errorstring.str().c_str()); - TetGeomSharedPtr tetgeom(MemoryManager::AllocateSharedPtr(tfaces)); + it = m_curvedVolumes.find(indx); + TetGeomSharedPtr tetgeom( + MemoryManager::AllocateSharedPtr( + tfaces, it == m_curvedVolumes.end() ? + CurveSharedPtr() : it->second)); tetgeom->SetGlobalID(indx); m_tetGeoms[indx] = tetgeom; diff --git a/library/SpatialDomains/TetGeom.cpp b/library/SpatialDomains/TetGeom.cpp index 7bcbbdb21..e78d9dd08 100644 --- a/library/SpatialDomains/TetGeom.cpp +++ b/library/SpatialDomains/TetGeom.cpp @@ -55,10 +55,12 @@ namespace Nektar m_shapeType = LibUtilities::eTetrahedron; } - TetGeom::TetGeom(const TriGeomSharedPtr faces[]) : + TetGeom::TetGeom(const TriGeomSharedPtr faces[], + CurveSharedPtr curve) : Geometry3D(faces[0]->GetEdge(0)->GetVertex(0)->GetCoordim()) { m_shapeType = LibUtilities::eTetrahedron; + m_curve = curve; /// Copy the face shared pointers m_faces.insert(m_faces.begin(), faces, faces+TetGeom::kNfaces); diff --git a/library/SpatialDomains/TetGeom.h b/library/SpatialDomains/TetGeom.h index 54ea50eff..4d4489e40 100644 --- a/library/SpatialDomains/TetGeom.h +++ b/library/SpatialDomains/TetGeom.h @@ -44,15 +44,16 @@ namespace Nektar { namespace SpatialDomains { - - class TetGeom: public LibUtilities::GraphVertexObject, + class TetGeom: public LibUtilities::GraphVertexObject, public Geometry3D { public: - SPATIAL_DOMAINS_EXPORT TetGeom (); - SPATIAL_DOMAINS_EXPORT TetGeom (const TriGeomSharedPtr faces[]); + SPATIAL_DOMAINS_EXPORT TetGeom(); + SPATIAL_DOMAINS_EXPORT TetGeom( + const TriGeomSharedPtr faces[], + CurveSharedPtr curve = CurveSharedPtr()); SPATIAL_DOMAINS_EXPORT ~TetGeom(); - + SPATIAL_DOMAINS_EXPORT static const int kNverts = 4; SPATIAL_DOMAINS_EXPORT static const int kNedges = 6; SPATIAL_DOMAINS_EXPORT static const int kNqfaces = 0; diff --git a/utilities/NekMesh/InputModules/InputGmsh.cpp b/utilities/NekMesh/InputModules/InputGmsh.cpp index fd2fbf40e..b7b8bd010 100644 --- a/utilities/NekMesh/InputModules/InputGmsh.cpp +++ b/utilities/NekMesh/InputModules/InputGmsh.cpp @@ -728,6 +728,20 @@ vector InputGmsh::TetReordering(ElmtConfig conf) } } + if (conf.m_volumeNodes == false) + { + return mapping; + } + + const int totPoints = (order + 1) * (order + 2) * (order + 3) / 6; + mapping.resize(totPoints); + + // TODO: Fix ordering of volume nodes. + for (i = 4 + 6 * n + 4 * n2; i < totPoints; ++i) + { + mapping[i] = i; + } + return mapping; } @@ -966,7 +980,7 @@ std::map InputGmsh::GenElmMap() using namespace LibUtilities; std::map tmp; - // Elmt type, order, face, volume + // Elmt type, order, facet, volume tmp[ 1] = ElmtConfig(eSegment, 1, true, true); tmp[ 2] = ElmtConfig(eTriangle, 1, true, true); tmp[ 3] = ElmtConfig(eQuadrilateral, 1, true, true); diff --git a/utilities/NekMesh/OutputModules/OutputNekpp.cpp b/utilities/NekMesh/OutputModules/OutputNekpp.cpp index ce05412a5..8da13a542 100644 --- a/utilities/NekMesh/OutputModules/OutputNekpp.cpp +++ b/utilities/NekMesh/OutputModules/OutputNekpp.cpp @@ -628,8 +628,11 @@ void OutputNekpp::WriteXmlCurves(TiXmlElement *pRoot) } } } + if (!curve) + { return; + } TiXmlElement *curved = new TiXmlElement("CURVED"); @@ -678,28 +681,34 @@ void OutputNekpp::WriteXmlCurves(TiXmlElement *pRoot) } } } - // 2D elements in 3-space, output face curvature information - else if (m_mesh->m_expDim == 2 && m_mesh->m_spaceDim >= 2) + // 2D elements in 2- or 3-space, output face curvature information + else if (m_mesh->m_expDim >= 2 && + m_mesh->m_spaceDim >= m_mesh->m_expDim) { vector::iterator it; - for (it = m_mesh->m_element[m_mesh->m_expDim].begin(); - it != m_mesh->m_element[m_mesh->m_expDim].end(); - ++it) + for (int d = 2; d <= 3; ++d) { - // Only generate face curve if there are volume nodes - if ((*it)->GetVolumeNodes().size() > 0) - { - TiXmlElement *e = new TiXmlElement("F"); - e->SetAttribute("ID", facecnt++); - e->SetAttribute("FACEID", (*it)->GetId()); - e->SetAttribute("NUMPOINTS", (*it)->GetNodeCount()); - e->SetAttribute( - "TYPE", - LibUtilities::kPointsTypeStr[(*it)->GetCurveType()]); + std::string tag = d == 2 ? "F" : "V"; + std::string attr = d == 2 ? "FACEID" : "VOLID"; - TiXmlText *t0 = new TiXmlText((*it)->GetXmlCurveString()); - e->LinkEndChild(t0); - curved->LinkEndChild(e); + for (it = m_mesh->m_element[d].begin(); + it != m_mesh->m_element[d].end(); + ++it) + { + // Only generate face curve if there are volume nodes + if ((*it)->GetVolumeNodes().size() > 0) + { + TiXmlElement *e = new TiXmlElement(tag); + e->SetAttribute("ID", facecnt++); + e->SetAttribute(attr, (*it)->GetId()); + e->SetAttribute("NUMPOINTS", (*it)->GetNodeCount()); + e->SetAttribute( + "TYPE", + LibUtilities::kPointsTypeStr[(*it)->GetCurveType()]); + TiXmlText *t0 = new TiXmlText((*it)->GetXmlCurveString()); + e->LinkEndChild(t0); + curved->LinkEndChild(e); + } } } } -- GitLab From a526c15e938731b2a3ace0fb9c3528cd4e7ca1b6 Mon Sep 17 00:00:00 2001 From: David Moxey Date: Wed, 11 May 2016 15:18:26 +0100 Subject: [PATCH 034/236] Add templating optimisation trickery --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 797 +++++++++--------- .../NekMesh/ProcessModules/ProcessVarOpti.h | 16 +- 2 files changed, 388 insertions(+), 425 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index e3f6837d0..e20636eab 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -58,337 +58,10 @@ namespace Utilities boost::mutex mtx; int ptsLow; int ptsHigh; -int dim; -NekMatrix VdmDx; -NekMatrix VdmDy; -NekMatrix VdmDz; +NekMatrix VdmD[3]; NekVector quadW; optimiser opti; -inline NekDouble GetElFunctional(ElDataSharedPtr d) -{ - vector ns; - d->el->GetCurvedNodes(ns); - - ASSERTL0(ptsHigh == d->maps.size(), "what"); - - Array > jac(ptsHigh); - - if(dim == 2) - { - NekVector X(ptsLow),Y(ptsLow); - for(int i = 0; i < ptsLow; i++) - { - X(i) = ns[i]->m_x; - Y(i) = ns[i]->m_y; - } - - NekVector x1i(ptsHigh),y1i(ptsHigh), - x2i(ptsHigh),y2i(ptsHigh); - - x1i = VdmDx*X; - y1i = VdmDx*Y; - x2i = VdmDy*X; - y2i = VdmDy*Y; - - for(int i = 0; i < ptsHigh; i++) - { - Array jaci(9,0.0); - jaci[0] = x1i(i); - jaci[1] = y1i(i); - jaci[3] = x2i(i); - jaci[4] = y2i(i); - jac[i] = jaci; - - } - - } - else - { - NekVector X(ptsLow),Y(ptsLow),Z(ptsLow); - for(int i = 0; i < ptsLow; i++) - { - X(i) = ns[i]->m_x; - Y(i) = ns[i]->m_y; - Z(i) = ns[i]->m_z; - } - - NekVector x1i(ptsHigh),y1i(ptsHigh),z1i(ptsHigh), - x2i(ptsHigh),y2i(ptsHigh),z2i(ptsHigh), - x3i(ptsHigh),y3i(ptsHigh),z3i(ptsHigh); - - x1i = VdmDx*X; - y1i = VdmDx*Y; - z1i = VdmDx*Z; - x2i = VdmDy*X; - y2i = VdmDy*Y; - z2i = VdmDy*Z; - x3i = VdmDz*X; - y3i = VdmDz*Y; - z3i = VdmDz*Z; - - for(int i = 0; i < ptsHigh; i++) - { - Array jaci(9,0.0); - jaci[0] = x1i(i); - jaci[1] = y1i(i); - jaci[2] = z1i(i); - jaci[3] = x2i(i); - jaci[4] = y2i(i); - jaci[5] = z2i(i); - jaci[6] = x3i(i); - jaci[7] = y3i(i); - jaci[8] = z3i(i); - jac[i] = jaci; - - } - } - - Array dW(ptsHigh); - - switch (opti) - { - case eLinEl: - { - for(int k = 0; k < ptsHigh; k++) - { - Array jacIdeal(9,0.0); - jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; - jacIdeal[1] = jac[k][1]*d->maps[k][0] + jac[k][4]*d->maps[k][1] + jac[k][7]*d->maps[k][2]; - jacIdeal[2] = jac[k][2]*d->maps[k][0] + jac[k][5]*d->maps[k][1] + jac[k][8]*d->maps[k][2]; - - jacIdeal[3] = jac[k][0]*d->maps[k][3] + jac[k][3]*d->maps[k][4] + jac[k][6]*d->maps[k][5]; - jacIdeal[4] = jac[k][1]*d->maps[k][3] + jac[k][4]*d->maps[k][4] + jac[k][7]*d->maps[k][5]; - jacIdeal[5] = jac[k][2]*d->maps[k][3] + jac[k][5]*d->maps[k][4] + jac[k][8]*d->maps[k][5]; - - jacIdeal[6] = jac[k][0]*d->maps[k][6] + jac[k][3]*d->maps[k][7] + jac[k][6]*d->maps[k][8]; - jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; - jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; - - NekDouble a = (jacIdeal[0]*jacIdeal[0]+jacIdeal[1]*jacIdeal[1]+jacIdeal[2]*jacIdeal[2]-1.0)* - (jacIdeal[0]*jacIdeal[0]+jacIdeal[1]*jacIdeal[1]+jacIdeal[2]*jacIdeal[2]-1.0); - NekDouble b = (jacIdeal[3]*jacIdeal[3]+jacIdeal[4]*jacIdeal[4]+jacIdeal[5]*jacIdeal[5]-1.0)* - (jacIdeal[3]*jacIdeal[3]+jacIdeal[4]*jacIdeal[4]+jacIdeal[5]*jacIdeal[5]-1.0); - NekDouble c = (jacIdeal[6]*jacIdeal[6]+jacIdeal[7]*jacIdeal[7]+jacIdeal[8]*jacIdeal[8]-1.0)* - (jacIdeal[6]*jacIdeal[6]+jacIdeal[7]*jacIdeal[7]+jacIdeal[8]*jacIdeal[8]-1.0); - NekDouble D = (jacIdeal[0]*jacIdeal[6]+jacIdeal[1]*jacIdeal[7]+jacIdeal[2]*jacIdeal[8])* - (jacIdeal[0]*jacIdeal[6]+jacIdeal[1]*jacIdeal[7]+jacIdeal[2]*jacIdeal[8]); - NekDouble e = (jacIdeal[3]*jacIdeal[6]+jacIdeal[4]*jacIdeal[7]+jacIdeal[5]*jacIdeal[8])* - (jacIdeal[3]*jacIdeal[6]+jacIdeal[4]*jacIdeal[7]+jacIdeal[5]*jacIdeal[8]); - NekDouble f = (jacIdeal[0]*jacIdeal[3]+jacIdeal[1]*jacIdeal[4]+jacIdeal[3]*jacIdeal[5])* - (jacIdeal[0]*jacIdeal[3]+jacIdeal[1]*jacIdeal[4]+jacIdeal[3]*jacIdeal[5]); - - NekDouble trEtE = 0.25 * (a+b+c) + 0.5 * (D+e+f); - - NekDouble jacDet; - if(dim == 2) - { - jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; - } - else - { - jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) - -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) - +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - } - - NekDouble ljacDet = log(jacDet); - NekDouble nu = 0.45; - NekDouble mu = 1.0/2.0/(1.0+nu); - NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); - - if(jacDet > 0) - { - dW[k] = K *0.5 * ljacDet * ljacDet + mu * trEtE; - } - else - { - NekDouble de = fabs(d->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - NekDouble lsigma = log(sigma); - dW[k] = K *0.5 * lsigma * lsigma + mu * trEtE; - } - - } - break; - } - case eHypEl: - { - for(int k = 0; k < ptsHigh; k++) - { - Array jacIdeal(9,0.0); - jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; - jacIdeal[1] = jac[k][1]*d->maps[k][0] + jac[k][4]*d->maps[k][1] + jac[k][7]*d->maps[k][2]; - jacIdeal[2] = jac[k][2]*d->maps[k][0] + jac[k][5]*d->maps[k][1] + jac[k][8]*d->maps[k][2]; - - jacIdeal[3] = jac[k][0]*d->maps[k][3] + jac[k][3]*d->maps[k][4] + jac[k][6]*d->maps[k][5]; - jacIdeal[4] = jac[k][1]*d->maps[k][3] + jac[k][4]*d->maps[k][4] + jac[k][7]*d->maps[k][5]; - jacIdeal[5] = jac[k][2]*d->maps[k][3] + jac[k][5]*d->maps[k][4] + jac[k][8]*d->maps[k][5]; - - jacIdeal[6] = jac[k][0]*d->maps[k][6] + jac[k][3]*d->maps[k][7] + jac[k][6]*d->maps[k][8]; - jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; - jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; - - NekDouble I1 = jacIdeal[0]*jacIdeal[0] + - jacIdeal[1]*jacIdeal[1] + - jacIdeal[2]*jacIdeal[2] + - jacIdeal[3]*jacIdeal[3] + - jacIdeal[4]*jacIdeal[4] + - jacIdeal[5]*jacIdeal[5] + - jacIdeal[6]*jacIdeal[6] + - jacIdeal[7]*jacIdeal[7] + - jacIdeal[8]*jacIdeal[8]; - - NekDouble jacDet; - if(dim == 2) - { - jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; - } - else - { - jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) - -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) - +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - } - - NekDouble ljacDet = log(jacDet); - NekDouble nu = 0.45; - NekDouble mu = 1.0/2.0/(1.0+nu); - NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); - - if(jacDet > 0) - { - dW[k] = 0.5 * mu * (I1 - 3.0 - 2.0*ljacDet) + 0.5 * K * ljacDet * ljacDet; - } - else - { - NekDouble de = fabs(d->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - NekDouble lsigma = log(sigma); - dW[k] = 0.5 * mu * (I1 - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma; - } - - } - break; - } - case eRoca: - { - for(int k = 0; k < ptsHigh; k++) - { - Array jacIdeal(9,0.0); - jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; - jacIdeal[1] = jac[k][1]*d->maps[k][0] + jac[k][4]*d->maps[k][1] + jac[k][7]*d->maps[k][2]; - jacIdeal[2] = jac[k][2]*d->maps[k][0] + jac[k][5]*d->maps[k][1] + jac[k][8]*d->maps[k][2]; - - jacIdeal[3] = jac[k][0]*d->maps[k][3] + jac[k][3]*d->maps[k][4] + jac[k][6]*d->maps[k][5]; - jacIdeal[4] = jac[k][1]*d->maps[k][3] + jac[k][4]*d->maps[k][4] + jac[k][7]*d->maps[k][5]; - jacIdeal[5] = jac[k][2]*d->maps[k][3] + jac[k][5]*d->maps[k][4] + jac[k][8]*d->maps[k][5]; - - jacIdeal[6] = jac[k][0]*d->maps[k][6] + jac[k][3]*d->maps[k][7] + jac[k][6]*d->maps[k][8]; - jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; - jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; - - NekDouble jacDet; - if(dim == 2) - { - jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; - } - else - { - jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) - -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) - +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - } - - NekDouble frob = 0.0; - - frob += jacIdeal[0] * jacIdeal[0]; - frob += jacIdeal[1] * jacIdeal[1]; - frob += jacIdeal[2] * jacIdeal[2]; - frob += jacIdeal[3] * jacIdeal[3]; - frob += jacIdeal[4] * jacIdeal[4]; - frob += jacIdeal[5] * jacIdeal[5]; - frob += jacIdeal[6] * jacIdeal[6]; - frob += jacIdeal[7] * jacIdeal[7]; - frob += jacIdeal[8] * jacIdeal[8]; - - if(jacDet > 0) - { - dW[k] = frob / dim / pow(fabs(jacDet), 2.0/dim); - } - else - { - NekDouble de = fabs(d->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - dW[k] = frob / dim / pow(fabs(sigma), 2.0/dim) -1.0; - } - } - break; - } - case eWins: - { - for(int k = 0; k < ptsHigh; k++) - { - Array jacIdeal(9,0.0); - jacIdeal[0] = jac[k][0]*d->maps[k][0] + jac[k][3]*d->maps[k][1] + jac[k][6]*d->maps[k][2]; - jacIdeal[1] = jac[k][1]*d->maps[k][0] + jac[k][4]*d->maps[k][1] + jac[k][7]*d->maps[k][2]; - jacIdeal[2] = jac[k][2]*d->maps[k][0] + jac[k][5]*d->maps[k][1] + jac[k][8]*d->maps[k][2]; - - jacIdeal[3] = jac[k][0]*d->maps[k][3] + jac[k][3]*d->maps[k][4] + jac[k][6]*d->maps[k][5]; - jacIdeal[4] = jac[k][1]*d->maps[k][3] + jac[k][4]*d->maps[k][4] + jac[k][7]*d->maps[k][5]; - jacIdeal[5] = jac[k][2]*d->maps[k][3] + jac[k][5]*d->maps[k][4] + jac[k][8]*d->maps[k][5]; - - jacIdeal[6] = jac[k][0]*d->maps[k][6] + jac[k][3]*d->maps[k][7] + jac[k][6]*d->maps[k][8]; - jacIdeal[7] = jac[k][1]*d->maps[k][6] + jac[k][4]*d->maps[k][7] + jac[k][7]*d->maps[k][8]; - jacIdeal[8] = jac[k][2]*d->maps[k][6] + jac[k][5]*d->maps[k][7] + jac[k][8]*d->maps[k][8]; - - NekDouble jacDet; - if(dim == 2) - { - jacDet = jacIdeal[0] * jacIdeal[4] - jacIdeal[3]*jacIdeal[1]; - } - else - { - jacDet = jacIdeal[0]*(jacIdeal[4]*jacIdeal[8]-jacIdeal[5]*jacIdeal[7]) - -jacIdeal[3]*(jacIdeal[1]*jacIdeal[8]-jacIdeal[2]*jacIdeal[7]) - +jacIdeal[6]*(jacIdeal[1]*jacIdeal[5]-jacIdeal[2]*jacIdeal[4]); - } - - NekDouble frob = 0.0; - - frob += jacIdeal[0] * jacIdeal[0]; - frob += jacIdeal[1] * jacIdeal[1]; - frob += jacIdeal[2] * jacIdeal[2]; - frob += jacIdeal[3] * jacIdeal[3]; - frob += jacIdeal[4] * jacIdeal[4]; - frob += jacIdeal[5] * jacIdeal[5]; - frob += jacIdeal[6] * jacIdeal[6]; - frob += jacIdeal[7] * jacIdeal[7]; - frob += jacIdeal[8] * jacIdeal[8]; - - if(jacDet > 0) - { - dW[k] = frob / jacDet; - } - else - { - NekDouble de = fabs(d->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - dW[k] = frob / sigma; - } - } - break; - } - } - - NekDouble integral = 0.0; - for(int i = 0; i < ptsHigh; i++) - { - integral += quadW[i] * dW[i]; - } - return integral; -} - ModuleKey ProcessVarOpti::className = GetModuleFactory().RegisterCreatorFunction( ModuleKey(eProcessModule, "varopti"), ProcessVarOpti::create, @@ -459,7 +132,6 @@ void ProcessVarOpti::Process() FillQuadPoints(); //build Vandermonde information - dim = m_mesh->m_spaceDim; switch (m_mesh->m_spaceDim) { case 2: @@ -483,9 +155,9 @@ void ProcessVarOpti::Process() NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); - VdmDx = interp * ( + VdmD[0] = interp * ( LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI); - VdmDy = interp * ( + VdmD[1] = interp * ( LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI); //quadW = LibUtilities::MakeQuadratureWeights(U2,V1); Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); @@ -515,11 +187,11 @@ void ProcessVarOpti::Process() LibUtilities::GetTetVandermonde(U1,V1,W1); NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); - VdmDx = interp * ( + VdmD[0] = interp * ( LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI); - VdmDy = interp * ( + VdmD[1] = interp * ( LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI); - VdmDz = interp * ( + VdmD[2] = interp * ( LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI); Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); NekVector quadWi(qds); @@ -530,25 +202,27 @@ void ProcessVarOpti::Process() GetElementMap(); vector > freenodes = GetColouredNodes(); - vector > optiNodes; + for(int i = 0; i < freenodes.size(); i++) { vector ns; for(int j = 0; j < freenodes[i].size(); j++) { NodeElMap::iterator it = nodeElMap.find(freenodes[i][j]->m_id); - ASSERTL0(it != nodeElMap.end(),"could not find"); + ASSERTL0(it != nodeElMap.end(), "could not find"); ns.push_back(NodeOpti(freenodes[i][j],it->second,res)); } optiNodes.push_back(ns); } + /* res->startE = 0.0; for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { res->startE += GetElFunctional(dataSet[i]); } + */ int nset = optiNodes.size(); int p = 0; @@ -586,34 +260,39 @@ void ProcessVarOpti::Process() res->val = 0.0; for(int i = 0; i < optiNodes.size(); i++) { - vector jobs; - for(int j = 0; j < optiNodes[i].size(); j++) + vector jobs(optiNodes[i].size()); + if (m_mesh->m_spaceDim == 2) { - jobs.push_back(optiNodes[i][j].GetJob()); + for(int j = 0; j < optiNodes[i].size(); j++) + { + jobs[j] = optiNodes[i][j].GetJob<2>(); + } + } + else + { + for(int j = 0; j < optiNodes[i].size(); j++) + { + jobs[j] = optiNodes[i][j].GetJob<3>(); + } } - //cout << " -- inner loop " << i+1 << "/" << optiNodes.size() - // << " of size: " << jobs.size() << endl; tm->SetNumWorkers(0); tm->QueueJobs(jobs); tm->SetNumWorkers(nThreads); tm->Wait(); - - /*for(int j = 0; j < optiNodes[i].size(); j++) - { - optiNodes[i][j].Run(); - }*/ } cout << ctr << "\tResidual: " << res->val << endl; } + /* res->endE = 0.0; for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { res->endE += GetElFunctional(dataSet[i]); } cout << "end energy: " << res->endE << endl; + */ if(m_config["stats"].beenSet) { @@ -623,25 +302,27 @@ void ProcessVarOpti::Process() } } +template void ProcessVarOpti::NodeOpti::Optimise() { //it doesnt matter at this point what the dim is so long that //in the 2d case z is left as zero - Array G = GetGrad(); + Array G = GetGrad(); if(sqrt(G[0]*G[0] + G[1]*G[1] + G[2]*G[2]) > 1e-6) { //needs to optimise - NekDouble currentW = GetFunctional(); - NekDouble xc = node->m_x; - NekDouble yc = node->m_y; - NekDouble zc = node->m_z; - NekDouble alpha = 1.0; - NekDouble delX=0.0; - NekDouble delY=0.0; - NekDouble delZ=0.0; - if(dim == 2) + NekDouble currentW = GetFunctional(); + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble zc = node->m_z; + NekDouble alpha = 1.0; + NekDouble delX = 0.0; + NekDouble delY = 0.0; + NekDouble delZ = 0.0; + + if(DIM == 2) { delX = 1.0/(G[3]*G[4]-G[6]*G[6])*(G[4]*G[0] - G[6]*G[1]); delY = 1.0/(G[3]*G[4]-G[6]*G[6])*(G[3]*G[1] - G[6]*G[0]); @@ -654,10 +335,10 @@ void ProcessVarOpti::NodeOpti::Optimise() H(2,2) = G[5]; H(0,1) = G[6]; H(1,0) = G[6]; - H(0,2) = G[8]; - H(2,0) = G[8]; - H(2,1) = G[7]; - H(1,2) = G[7]; + H(0,2) = G[7]; + H(2,0) = G[7]; + H(2,1) = G[8]; + H(1,2) = G[8]; H.Invert(); NekVector g(3); g[0] = G[0]; @@ -675,7 +356,7 @@ void ProcessVarOpti::NodeOpti::Optimise() node->m_x = xc - alpha * delX; node->m_y = yc - alpha * delY; node->m_z = zc - alpha * delZ; - if(GetFunctional() < currentW) + if(GetFunctional() < currentW) { found = true; break; @@ -690,51 +371,97 @@ void ProcessVarOpti::NodeOpti::Optimise() node->m_x = xc; node->m_y = yc; node->m_z = zc; - // cout << "warning: had to reset node" << endl; - // cout << G[0] << " " << G[1] << " " << G[2] << " " << node->m_id << endl; + // cout << "warning: had to reset node" << endl; + // cout << G[0] << " " << G[1] << " " << G[2] << " " << node->m_id << endl; } mtx.lock(); res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ - (node->m_z-zc)*(node->m_z-zc)),res->val); + (node->m_z-zc)*(node->m_z-zc)),res->val); mtx.unlock(); } } -NekDouble dir[19][3] = {{0.0,0.0,0.0}, - {1.0,0.0,0.0}, - {1.0,1.0,0.0}, - {0.0,1.0,0.0}, - {-1.0,1.0,0.0}, - {-1.0,0.0,0.0}, - {-1.0,-1.0,0.0}, - {0.0,-1.0,0.0}, - {1.0,-1.0,0.0}, - {-1.0,0.0,-1.0}, - {0.0,0.0,-1.0}, - {1.0,0.0,-1.0}, - {-1.0,0.0,1.0}, - {0.0,0.0,1.0}, - {1.0,0.0,1.0}, - {0.0,1.0,-1.0}, - {0.0,1.0,1.0}, - {0.0,-1.0,-1.0}, - {0.0,-1.0,1.0}}; - +NekDouble dir[19][3] = {{ 0.0, 0.0, 0.0 }, // 0 (x , y , z ) + { 1.0, 0.0, 0.0 }, // 1 (x+dx, y , z ) + { 1.0, 1.0, 0.0 }, // 2 (x+dx, y+dy, z ) + { 0.0, 1.0, 0.0 }, // 3 (x , y+dy, z ) + { -1.0, 1.0, 0.0 }, // 4 (x-dx, y+dy, z ) + { -1.0, 0.0, 0.0 }, // 5 (x-dx, y , z ) + { -1.0, -1.0, 0.0 }, // 6 (x-dx, y-dy, z ) + { 0.0, -1.0, 0.0 }, // 7 (x , y-dy, z ) + { 1.0, -1.0, 0.0 }, // 8 (x+dx, y-dy, z ) + { -1.0, 0.0, -1.0 }, // 9 (x-dx, y , z-dz) + { 0.0, 0.0, -1.0 }, // 10 (x , y , z-dz) + { 1.0, 0.0, -1.0 }, // 11 (x+dx, y , z-dz) + { -1.0, 0.0, 1.0 }, // 12 (x-dx, y , z+dz) + { 0.0, 0.0, 1.0 }, // 13 (x , y , z+dz) + { 1.0, 0.0, 1.0 }, // 14 (x+dx, y , z+dz) + { 0.0, 1.0, -1.0 }, // 15 (x , y+dy, z-dz) + { 0.0, 1.0, 1.0 }, // 16 (x , y+dy, z+dz) + { 0.0, -1.0, -1.0 }, // 17 (x , y-dy, z-dz) + { 0.0, -1.0, 1.0 }}; // 18 (x , y-dy, z+dz) + +template Array ProcessVarOpti::NodeOpti::GetGrad() +{ + return Array(); +} + +template<> +Array ProcessVarOpti::NodeOpti::GetGrad<2>() +{ + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble dx = 1e-4; + vector w(9); + + for(int i = 0; i < 9; i++) + { + node->m_x = xc + dir[i][0] * dx; + node->m_y = yc + dir[i][1] * dx; + w[i] = GetFunctional<2>(); + } + node->m_x = xc; + node->m_y = yc; + + Array ret(9,0.0); + + //ret[0] d/dx + //ret[1] d/dy + //ret[2] d/dz + + //ret[3] d2/dx2 + //ret[4] d2/dy2 + //ret[5] d2/dz2 + //ret[6] d2/dxdy + //ret[7] d2/dxdz + //ret[8] d2/dydz + + ret[0] = (w[1] - w[5]) / 2.0 / dx; + ret[1] = (w[3] - w[7]) / 2.0 / dx; + ret[3] = (w[1] + w[5] - 2.0*w[0]) / dx / dx; + ret[4] = (w[3] + w[7] - 2.0*w[0]) / dx / dx; + ret[6] = (w[2] + w[6] - w[4] - w[8]) / 4.0 / dx / dx; + + return ret; +} + +template<> +Array ProcessVarOpti::NodeOpti::GetGrad<3>() { NekDouble xc = node->m_x; NekDouble yc = node->m_y; NekDouble zc = node->m_z; - NekDouble dx = 1e-3; + NekDouble dx = 1e-4; vector w; - for(int i = 0; i < (dim == 2 ? 9 : 19); i++) + for(int i = 0; i < 19; i++) { node->m_x = xc + dir[i][0] * dx; node->m_y = yc + dir[i][1] * dx; node->m_z = zc + dir[i][2] * dx; - w.push_back(GetFunctional()); + w.push_back(GetFunctional<3>()); } node->m_x = xc; node->m_y = yc; @@ -753,31 +480,263 @@ Array ProcessVarOpti::NodeOpti::GetGrad() //ret[7] d2/dxdz //ret[8] d2/dydz - ret[0] = (w[1] - w[5]) / 2.0 / dx; ret[1] = (w[3] - w[7]) / 2.0 / dx; + ret[2] = (w[13] - w[10]) / 2.0 / dx; + ret[3] = (w[1] + w[5] - 2.0*w[0]) / dx / dx; ret[4] = (w[3] + w[7] - 2.0*w[0]) / dx / dx; + ret[5] = (w[13] + w[10] - 2.0*w[0]) / dx / dx; + ret[6] = (w[2] + w[6] - w[4] - w[8]) / 4.0 / dx /dx; - if(dim == 3) - { - ret[2] = (w[13] - w[10]) / 2.0 / dx; - ret[5] = (w[13] + w[10] - 2.0*w[0]) / dx / dx; - ret[7] = (w[14] + w[9] - w[11] - w[12]) / 4.0 / dx /dx; - ret[8] = (w[16] + w[17] - w[15] - w[18]) / 4.0 / dx /dx; - } + ret[7] = (w[14] + w[9] - w[11] - w[12]) / 4.0 / dx /dx; + ret[8] = (w[16] + w[17] - w[15] - w[18]) / 4.0 / dx /dx; return ret; } +template inline NekDouble JacDet(NekDouble *jac) +{ + return 0.0; +} + +template<> inline NekDouble JacDet<2>(NekDouble *jac) +{ + return jac[0] * jac[3] - jac[2] * jac[1]; +} + +template<> inline NekDouble JacDet<3>(NekDouble *jac) +{ + return jac[0]*(jac[4]*jac[8]-jac[5]*jac[7]) + -jac[3]*(jac[1]*jac[8]-jac[2]*jac[7]) + +jac[6]*(jac[1]*jac[5]-jac[2]*jac[4]); +} + +template inline NekDouble LinElasTrace(NekDouble *jac) +{ + return 0.0; +} + +template<> inline NekDouble LinElasTrace<2>(NekDouble *jac) +{ + return 0.25 * ( + (jac[0]*jac[0]+jac[1]*jac[1]-1.0)*(jac[0]*jac[0]+jac[1]*jac[1]-1.0) + + (jac[2]*jac[2]+jac[3]*jac[3]-1.0)*(jac[2]*jac[2]+jac[3]*jac[3]-1.0)); +} + +template<> inline NekDouble LinElasTrace<3>(NekDouble *jac) +{ + return 0.25 *( + (jac[0]*jac[0]+jac[1]*jac[1]+jac[2]*jac[2]-1.0)* + (jac[0]*jac[0]+jac[1]*jac[1]+jac[2]*jac[2]-1.0) + + (jac[3]*jac[3]+jac[4]*jac[4]+jac[5]*jac[5]-1.0)* + (jac[3]*jac[3]+jac[4]*jac[4]+jac[5]*jac[5]-1.0) + + (jac[6]*jac[6]+jac[7]*jac[7]+jac[8]*jac[8]-1.0)* + (jac[6]*jac[6]+jac[7]*jac[7]+jac[8]*jac[8]-1.0)) + + 0.5 * ( + (jac[0]*jac[6]+jac[1]*jac[7]+jac[2]*jac[8])* + (jac[0]*jac[6]+jac[1]*jac[7]+jac[2]*jac[8])+ + (jac[3]*jac[6]+jac[4]*jac[7]+jac[5]*jac[8])* + (jac[3]*jac[6]+jac[4]*jac[7]+jac[5]*jac[8])+ + (jac[0]*jac[3]+jac[1]*jac[4]+jac[3]*jac[5])* + (jac[0]*jac[3]+jac[1]*jac[4]+jac[3]*jac[5])); +} + +template NekDouble ProcessVarOpti::NodeOpti::GetFunctional() { - NekDouble r = 0.0; - for(int i = 0; i < data.size(); i++) + const int nElmt = data.size(); + const int totPtsLow = ptsLow * nElmt; + NekDouble X[DIM * totPtsLow]; + + // Store x/y components of each element sequentially in memory + for (int i = 0, cnt = 0; i < nElmt; ++i) { - r += GetElFunctional(data[i]); + for (int j = 0; j < ptsLow; ++j, ++cnt) + { + //Array loc = data[i]->nodes[j]->GetLoc(); + //for (int d = 0; d < DIM; ++d) + //{ + X[cnt] = data[i]->nodes[j]->m_x; + X[cnt + ptsLow] = data[i]->nodes[j]->m_y; + X[cnt + 2*ptsLow] = data[i]->nodes[j]->m_z; + //} + } + + cnt += ptsLow; } - return r; + + // Storage for derivatives, ordered by: + // - standard coordinate direction + // - number of elements + // - cartesian coordinate direction + // - quadrature points + NekDouble deriv[DIM][nElmt][DIM][ptsHigh]; + + // Calculate x- and y-gradients + for (int d = 0; d < DIM; ++d) + { + Blas::Dgemm('N', 'N', ptsHigh, DIM * nElmt, ptsLow, 1.0, + VdmD[d].GetRawPtr(), ptsHigh, X, ptsLow, 0.0, + &deriv[d][0][0][0], ptsHigh); + } + + NekDouble integral = 0.0; + + switch(opti) + { + case eLinEl: + { + for (int i = 0; i < nElmt; ++i) + { + for(int k = 0; k < ptsHigh; ++k) + { + NekDouble jacIdeal[DIM*DIM]; + int cnt = 0; + for (int m = 0; m < DIM; ++m) + { + for (int n = 0; n < DIM; ++n, ++cnt) + { + jacIdeal[cnt] = 0.0; + for (int l = 0; l < DIM; ++l) + { + jacIdeal[cnt] += + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + } + } + } + + NekDouble jacDet = JacDet(jacIdeal); + NekDouble trEtE = LinElasTrace(jacIdeal); + + const NekDouble nu = 0.45; + const NekDouble mu = 1.0 / 2.0 / (1.0+nu); + const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + + NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); + NekDouble lsigma = log(sigma); + integral += quadW[k] * (K * 0.5 * lsigma * lsigma + mu * trEtE); + } + } + break; + } + + case eHypEl: + { + for (int i = 0; i < nElmt; ++i) + { + for(int k = 0; k < ptsHigh; ++k) + { + NekDouble jacIdeal[DIM*DIM]; + int cnt = 0; + for (int m = 0; m < DIM; ++m) + { + for (int n = 0; n < DIM; ++n, ++cnt) + { + jacIdeal[cnt] = 0.0; + for (int l = 0; l < DIM; ++l) + { + jacIdeal[cnt] += + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + } + } + } + + NekDouble I1 = 0.0; + for (int m = 0; m < DIM*DIM; ++m) + { + I1 += jacIdeal[m]*jacIdeal[m]; + } + + const NekDouble nu = 0.45; + const NekDouble mu = 1.0 / 2.0 / (1.0+nu); + const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + + NekDouble jacDet = JacDet(jacIdeal); + NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); + NekDouble lsigma = log(sigma); + integral += quadW[k]*(0.5 * mu * (I1 - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); + } + } + break; + } + + case eRoca: + { + for (int i = 0; i < nElmt; ++i) + { + for(int k = 0; k < ptsHigh; ++k) + { + NekDouble jacIdeal[DIM*DIM]; + int cnt = 0; + for (int m = 0; m < DIM; ++m) + { + for (int n = 0; n < DIM; ++n, ++cnt) + { + jacIdeal[cnt] = 0.0; + for (int l = 0; l < DIM; ++l) + { + jacIdeal[cnt] += + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + } + } + } + + NekDouble frob = 0.0; + for (int m = 0; m < DIM*DIM; ++m) + { + frob += jacIdeal[m] * jacIdeal[m]; + } + NekDouble jacDet = JacDet(jacIdeal); + + NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); + integral += quadW[k]*(frob / DIM / pow(fabs(sigma), 2.0/DIM) -1.0); + } + } + break; + } + + case eWins: + { + for (int i = 0; i < nElmt; ++i) + { + for(int k = 0; k < ptsHigh; ++k) + { + NekDouble jacIdeal[DIM*DIM]; + int cnt = 0; + for (int m = 0; m < DIM; ++m) + { + for (int n = 0; n < DIM; ++n, ++cnt) + { + jacIdeal[cnt] = 0.0; + for (int l = 0; l < DIM; ++l) + { + jacIdeal[cnt] += + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + } + } + } + + NekDouble frob = 0.0; + for (int m = 0; m < DIM*DIM; ++m) + { + frob += jacIdeal[m] * jacIdeal[m]; + } + NekDouble jacDet = JacDet(jacIdeal); + + NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); + NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); + integral += quadW[k]*(frob / sigma); + } + } + break; + } + } + + return integral; } vector > ProcessVarOpti::GetColouredNodes() @@ -907,7 +866,7 @@ vector > ProcessVarOpti::GetColouredNodes() } res->n = remain.size(); - res->nDoF = res->n * dim; + res->nDoF = res->n * m_mesh->m_spaceDim; vector > ret; @@ -963,9 +922,9 @@ void ProcessVarOpti::GetElementMap() { ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; ElDataSharedPtr d = boost::shared_ptr(new ElData); - d->el = el; - + d->el = el; d->maps = MappingIdealToRef(el); + el->GetCurvedNodes(d->nodes); dataSet.push_back(d); } @@ -1073,10 +1032,10 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP NekVector x1i(ptsHigh),y1i(ptsHigh), x2i(ptsHigh),y2i(ptsHigh); - x1i = VdmDx*X; - y1i = VdmDx*Y; - x2i = VdmDy*X; - y2i = VdmDy*Y; + x1i = VdmD[0]*X; + y1i = VdmD[0]*Y; + x2i = VdmD[1]*X; + y2i = VdmD[1]*Y; for(int i = 0 ; i < ptsHigh; i++) { @@ -1134,15 +1093,15 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP x2i(ptsHigh),y2i(ptsHigh),z2i(ptsHigh), x3i(ptsHigh),y3i(ptsHigh),z3i(ptsHigh); - x1i = VdmDx*X; - y1i = VdmDx*Y; - x2i = VdmDy*X; - y2i = VdmDy*Y; - z1i = VdmDx*Z; - z2i = VdmDy*Z; - x3i = VdmDz*X; - y3i = VdmDz*Y; - z3i = VdmDz*Z; + x1i = VdmD[0]*X; + y1i = VdmD[0]*Y; + x2i = VdmD[1]*X; + y2i = VdmD[1]*Y; + z1i = VdmD[0]*Z; + z2i = VdmD[1]*Z; + x3i = VdmD[2]*X; + y3i = VdmD[2]*Y; + z3i = VdmD[2]*Z; for(int i = 0 ; i < ptsHigh; i++) { @@ -1513,10 +1472,10 @@ void ProcessVarOpti::WriteStats(string file) Y(i) = ns[i]->m_y; } - x1 = VdmDx*X; - y1 = VdmDx*Y; - x2 = VdmDy*X; - y2 = VdmDy*Y; + x1 = VdmD[0]*X; + y1 = VdmD[0]*Y; + x2 = VdmD[0]*X; + y2 = VdmD[0]*Y; for(int i = 0; i < pts; i++) { diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index a43fab4b8..4457e1183 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -47,6 +47,7 @@ namespace Utilities struct ElData { ElementSharedPtr el; + vector nodes; vector > maps; }; typedef boost::shared_ptr ElDataSharedPtr; @@ -106,6 +107,7 @@ private: vector dataSet; ResidualSharedPtr res; + template class NodeOptiJob; class NodeOpti @@ -119,26 +121,28 @@ private: ~NodeOpti(){}; - void Optimise(); - NodeOptiJob *GetJob() + template void Optimise(); + template NodeOptiJob *GetJob() { - return new NodeOptiJob(*this); + return new NodeOptiJob(*this); } private: - Array GetGrad(); - NekDouble GetFunctional(); + template Array GetGrad(); + template NekDouble GetFunctional(); NodeSharedPtr node; vector data; ResidualSharedPtr res; }; + template class NodeOptiJob : public Thread::ThreadJob { public: NodeOptiJob(NodeOpti no) : node(no) {} + void Run() { - node.Optimise(); + node.Optimise(); } private: NodeOpti node; -- GitLab From ef04b46d708b06ea4934274b2b01ae1d0407883e Mon Sep 17 00:00:00 2001 From: mike turner Date: Thu, 12 May 2016 16:02:23 +0100 Subject: [PATCH 035/236] fix linear elastic formulation --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 183 +++++++++++++++--- .../NekMesh/ProcessModules/ProcessVarOpti.h | 3 +- 2 files changed, 157 insertions(+), 29 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index e20636eab..91ba396c0 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -216,14 +216,6 @@ void ProcessVarOpti::Process() optiNodes.push_back(ns); } - /* - res->startE = 0.0; - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - res->startE += GetElFunctional(dataSet[i]); - } - */ - int nset = optiNodes.size(); int p = 0; int mn = numeric_limits::max(); @@ -238,13 +230,13 @@ void ProcessVarOpti::Process() cout << scientific << endl; cout << "N elements:\t\t" << m_mesh->m_element[m_mesh->m_expDim].size() << endl << "N elements invalid:\t" << res->startInv << endl + << "Worst jacobian:\t\t" << res->worstJac << endl << "N free nodes:\t\t" << res->n << endl << "N Dof:\t\t\t" << res->nDoF << endl << "N color sets:\t\t" << nset << endl << "Avg set colors:\t\t" << p/nset << endl << "Min set:\t\t" << mn << endl << "Max set:\t\t" << mx << endl; - cout << "Starting energy:\t" << res->startE << endl; int nThreads = m_config["numthreads"].as(); @@ -283,16 +275,14 @@ void ProcessVarOpti::Process() } cout << ctr << "\tResidual: " << res->val << endl; + if(ctr > 5000) + break; } - /* - res->endE = 0.0; - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - res->endE += GetElFunctional(dataSet[i]); - } - cout << "end energy: " << res->endE << endl; - */ + EvaluateMesh(); + + cout << "Invalid at end:\t\t" << res->startInv << endl; + cout << "Worst at end:\t\t" << res->worstJac << endl; if(m_config["stats"].beenSet) { @@ -310,7 +300,7 @@ void ProcessVarOpti::NodeOpti::Optimise() Array G = GetGrad(); - if(sqrt(G[0]*G[0] + G[1]*G[1] + G[2]*G[2]) > 1e-6) + if(sqrt(G[0]*G[0] + G[1]*G[1] + G[2]*G[2]) > 1e-10) { //needs to optimise NekDouble currentW = GetFunctional(); @@ -351,7 +341,7 @@ void ProcessVarOpti::NodeOpti::Optimise() } bool found = false; - while(alpha > 1e-6) + while(alpha > 1e-10) { node->m_x = xc - alpha * delX; node->m_y = yc - alpha * delY; @@ -521,7 +511,9 @@ template<> inline NekDouble LinElasTrace<2>(NekDouble *jac) { return 0.25 * ( (jac[0]*jac[0]+jac[1]*jac[1]-1.0)*(jac[0]*jac[0]+jac[1]*jac[1]-1.0) + - (jac[2]*jac[2]+jac[3]*jac[3]-1.0)*(jac[2]*jac[2]+jac[3]*jac[3]-1.0)); + (jac[2]*jac[2]+jac[3]*jac[3]-1.0)*(jac[2]*jac[2]+jac[3]*jac[3]-1.0)) + + 0.5 * ( + (jac[0]*jac[2]+jac[1]*jac[3])*(jac[0]*jac[2]+jac[1]*jac[3])); } template<> inline NekDouble LinElasTrace<3>(NekDouble *jac) @@ -1426,19 +1418,156 @@ void ProcessVarOpti::FillQuadPoints() } } + EvaluateMesh(); +} + +void ProcessVarOpti::EvaluateMesh() +{ res->startInv =0; res->worstJac = numeric_limits::max(); - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + if(m_mesh->m_expDim == 2) { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + LibUtilities::PointsKey pkey1(m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + Array u1, v1; - SpatialDomains::GeometrySharedPtr geom = - el->GetGeom(m_mesh->m_spaceDim); - SpatialDomains::GeomFactorsSharedPtr gfac = geom->GetGeomFactors(); - if(!gfac->IsValid()) + LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); + + NekVector U1(u1), V1(v1); + + NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); + NekMatrix VandermondeI = Vandermonde; + VandermondeI.Invert(); + NekMatrix VdmDxt = ( + LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI); + NekMatrix VdmDyt = ( + LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI); + + + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { - res->startInv++; + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + + vector ns; + el->GetCurvedNodes(ns); + + NekDouble mx = -1.0 * numeric_limits::max(); + NekDouble mn = numeric_limits::max(); + + + NekVector X(u1.num_elements()),Y(u1.num_elements()); + for(int j = 0; j < u1.num_elements(); j++) + { + X(j) = ns[j]->m_x; + Y(j) = ns[j]->m_y; + } + + NekVector x1i(u1.num_elements()),y1i(u1.num_elements()), + x2i(u1.num_elements()),y2i(u1.num_elements()); + + x1i = VdmDxt*X; + y1i = VdmDxt*Y; + x2i = VdmDyt*X; + y2i = VdmDyt*Y; + + for(int j = 0; j < u1.num_elements(); j++) + { + NekDouble jacDet = x1i(j) * y2i(j) - x2i(j)*y1i(j); + mx = max(mx,jacDet); + mn = min(mn,jacDet); + } + + if(mn < 0) + { + res->startInv++; + } + res->worstJac = min(res->worstJac,mn/mx); + } + } + else + { + LibUtilities::PointsKey pkey1(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + Array u1, v1,w1; + + LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1,w1); + + NekVector U1(u1), V1(v1), W1(w1); + + NekMatrix Vandermonde = LibUtilities::GetTetVandermonde(U1,V1,W1); + NekMatrix VandermondeI = Vandermonde; + VandermondeI.Invert(); + NekMatrix VdmDxt = ( + LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI); + NekMatrix VdmDyt = ( + LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI); + NekMatrix VdmDzt = ( + LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI); + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + + vector ns; + el->GetCurvedNodes(ns); + + NekDouble mx = -1.0 * numeric_limits::max(); + NekDouble mn = numeric_limits::max(); + + NekVector X(u1.num_elements()),Y(u1.num_elements()),Z(u1.num_elements()); + for(int j = 0; j < u1.num_elements(); j++) + { + X(j) = ns[j]->m_x; + Y(j) = ns[j]->m_y; + Z(j) = ns[j]->m_z; + } + + NekVector x1i(u1.num_elements()),y1i(u1.num_elements()),z1i(u1.num_elements()), + x2i(u1.num_elements()),y2i(u1.num_elements()),z2i(u1.num_elements()), + x3i(u1.num_elements()),y3i(u1.num_elements()),z3i(u1.num_elements()); + + x1i = VdmDxt*X; + y1i = VdmDxt*Y; + z1i = VdmDxt*Z; + x2i = VdmDyt*X; + y2i = VdmDyt*Y; + z2i = VdmDyt*Z; + x3i = VdmDzt*X; + y3i = VdmDzt*Y; + z3i = VdmDzt*Z; + + for(int j = 0; j < u1.num_elements(); j++) + { + + DNekMat dxdz(3,3,1.0,eFULL); + dxdz(0,0) = x1i(j); + dxdz(0,1) = x2i(j); + dxdz(0,2) = x3i(j); + dxdz(1,0) = y1i(j); + dxdz(1,1) = y2i(j); + dxdz(1,2) = y3i(j); + dxdz(2,0) = z1i(j); + dxdz(2,1) = z2i(j); + dxdz(2,2) = z3i(j); + + NekDouble jacDet = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) + -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) + +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); + + mx = max(mx,jacDet); + mn = min(mn,jacDet); + } + + + + if(mn < 0) + { + res->startInv++; + } + + res->worstJac = min(res->worstJac,mn/mx); } } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index 4457e1183..151d1cd5b 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -65,8 +65,6 @@ struct Residual NekDouble val; int n; int nDoF; - NekDouble startE; - NekDouble endE; int startInv; NekDouble worstJac; }; @@ -102,6 +100,7 @@ private: vector > MappingIdealToRef(ElementSharedPtr el); vector > GetColouredNodes(); void WriteStats(string file); + void EvaluateMesh(); NodeElMap nodeElMap; vector dataSet; -- GitLab From 6e427c21528ae63ba571021f576c49a0d3f9ab6e Mon Sep 17 00:00:00 2001 From: David Moxey Date: Thu, 12 May 2016 18:43:47 +0100 Subject: [PATCH 036/236] Fixes for 3D issues --- .../NekMeshUtils/MeshElements/Tetrahedron.h | 8 +----- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 27 ++++++++++--------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/library/NekMeshUtils/MeshElements/Tetrahedron.h b/library/NekMeshUtils/MeshElements/Tetrahedron.h index 91e21ce59..f77159978 100644 --- a/library/NekMeshUtils/MeshElements/Tetrahedron.h +++ b/library/NekMeshUtils/MeshElements/Tetrahedron.h @@ -55,14 +55,8 @@ public: std::vector pNodeList, std::vector pTagList) { - ElementSharedPtr e = boost::shared_ptr( + return boost::shared_ptr( new Tetrahedron(pConf, pNodeList, pTagList)); - vector faces = e->GetFaceList(); - for (int i = 0; i < faces.size(); ++i) - { - faces[i]->m_elLink.push_back(pair(e, i)); - } - return e; } /// Element type static LibUtilities::ShapeType m_type; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 91ba396c0..b9048d7df 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -171,7 +171,7 @@ void ProcessVarOpti::Process() LibUtilities::PointsKey pkey1(m_mesh->m_nummode, LibUtilities::eNodalTetElec); LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, - LibUtilities::eNodalTetSPI); + LibUtilities::eNodalTetElec); Array u1, v1, u2, v2, w1, w2; LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1, w1); LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2, w2); @@ -361,7 +361,8 @@ void ProcessVarOpti::NodeOpti::Optimise() node->m_x = xc; node->m_y = yc; node->m_z = zc; - // cout << "warning: had to reset node" << endl; + //cout << "warning: had to reset node" << endl; + //cout << delX << " " << delY << " " << delZ << endl; // cout << G[0] << " " << G[1] << " " << G[2] << " " << node->m_id << endl; } mtx.lock(); @@ -453,6 +454,7 @@ Array ProcessVarOpti::NodeOpti::GetGrad<3>() node->m_z = zc + dir[i][2] * dx; w.push_back(GetFunctional<3>()); } + node->m_x = xc; node->m_y = yc; node->m_z = zc; @@ -544,18 +546,19 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() // Store x/y components of each element sequentially in memory for (int i = 0, cnt = 0; i < nElmt; ++i) { - for (int j = 0; j < ptsLow; ++j, ++cnt) + for (int j = 0; j < ptsLow; ++j) { - //Array loc = data[i]->nodes[j]->GetLoc(); - //for (int d = 0; d < DIM; ++d) - //{ - X[cnt] = data[i]->nodes[j]->m_x; - X[cnt + ptsLow] = data[i]->nodes[j]->m_y; - X[cnt + 2*ptsLow] = data[i]->nodes[j]->m_z; - //} + Array loc = data[i]->nodes[j]->GetLoc(); + for (int d = 0; d < DIM; ++d) + { + X[cnt + d*ptsLow + j] = loc[d]; + //X[cnt + d*ptsLow] = data[i]->nodes[j]->m_x; + //X[cnt + ptsLow] = data[i]->nodes[j]->m_y; + //X[cnt + 2*ptsLow] = data[i]->nodes[j]->m_z; + } } - cnt += ptsLow; + cnt += DIM*ptsLow; } // Storage for derivatives, ordered by: @@ -1087,9 +1090,9 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP x1i = VdmD[0]*X; y1i = VdmD[0]*Y; + z1i = VdmD[0]*Z; x2i = VdmD[1]*X; y2i = VdmD[1]*Y; - z1i = VdmD[0]*Z; z2i = VdmD[1]*Z; x3i = VdmD[2]*X; y3i = VdmD[2]*Y; -- GitLab From 2323a0cfaa853bafd82a119730f71f1ce4113e07 Mon Sep 17 00:00:00 2001 From: mike turner Date: Fri, 13 May 2016 12:51:11 +0100 Subject: [PATCH 037/236] small 3D changes in preprocesing --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 123 +++++++++--------- .../NekMesh/ProcessModules/ProcessVarOpti.h | 1 + 2 files changed, 60 insertions(+), 64 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index b9048d7df..0528cc96a 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -171,7 +171,7 @@ void ProcessVarOpti::Process() LibUtilities::PointsKey pkey1(m_mesh->m_nummode, LibUtilities::eNodalTetElec); LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, - LibUtilities::eNodalTetElec); + LibUtilities::eNodalTetSPI); Array u1, v1, u2, v2, w1, w2; LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1, w1); LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2, w2); @@ -233,6 +233,7 @@ void ProcessVarOpti::Process() << "Worst jacobian:\t\t" << res->worstJac << endl << "N free nodes:\t\t" << res->n << endl << "N Dof:\t\t\t" << res->nDoF << endl + << "N Dirclet:\t\t" << res->nDirc << endl << "N color sets:\t\t" << nset << endl << "Avg set colors:\t\t" << p/nset << endl << "Min set:\t\t" << mn << endl @@ -340,6 +341,8 @@ void ProcessVarOpti::NodeOpti::Optimise() delZ = del[2]; } + cout << delX << " " << delY << " " << delZ << endl; + bool found = false; while(alpha > 1e-10) { @@ -361,8 +364,7 @@ void ProcessVarOpti::NodeOpti::Optimise() node->m_x = xc; node->m_y = yc; node->m_z = zc; - //cout << "warning: had to reset node" << endl; - //cout << delX << " " << delY << " " << delZ << endl; + // cout << "warning: had to reset node" << endl; // cout << G[0] << " " << G[1] << " " << G[2] << " " << node->m_id << endl; } mtx.lock(); @@ -372,25 +374,19 @@ void ProcessVarOpti::NodeOpti::Optimise() } } -NekDouble dir[19][3] = {{ 0.0, 0.0, 0.0 }, // 0 (x , y , z ) +NekDouble dir[13][3] = {{ 0.0, 0.0, 0.0 }, // 0 (x , y , z ) { 1.0, 0.0, 0.0 }, // 1 (x+dx, y , z ) { 1.0, 1.0, 0.0 }, // 2 (x+dx, y+dy, z ) { 0.0, 1.0, 0.0 }, // 3 (x , y+dy, z ) - { -1.0, 1.0, 0.0 }, // 4 (x-dx, y+dy, z ) - { -1.0, 0.0, 0.0 }, // 5 (x-dx, y , z ) - { -1.0, -1.0, 0.0 }, // 6 (x-dx, y-dy, z ) - { 0.0, -1.0, 0.0 }, // 7 (x , y-dy, z ) - { 1.0, -1.0, 0.0 }, // 8 (x+dx, y-dy, z ) - { -1.0, 0.0, -1.0 }, // 9 (x-dx, y , z-dz) - { 0.0, 0.0, -1.0 }, // 10 (x , y , z-dz) - { 1.0, 0.0, -1.0 }, // 11 (x+dx, y , z-dz) - { -1.0, 0.0, 1.0 }, // 12 (x-dx, y , z+dz) - { 0.0, 0.0, 1.0 }, // 13 (x , y , z+dz) - { 1.0, 0.0, 1.0 }, // 14 (x+dx, y , z+dz) - { 0.0, 1.0, -1.0 }, // 15 (x , y+dy, z-dz) - { 0.0, 1.0, 1.0 }, // 16 (x , y+dy, z+dz) - { 0.0, -1.0, -1.0 }, // 17 (x , y-dy, z-dz) - { 0.0, -1.0, 1.0 }}; // 18 (x , y-dy, z+dz) + { -1.0, 0.0, 0.0 }, // 4 (x-dx, y , z ) + { -1.0, -1.0, 0.0 }, // 5 (x-dx, y-dy, z ) + { 0.0, -1.0, 0.0 }, // 6 (x , y-dy, z ) + { -1.0, 0.0, -1.0 }, // 7 (x-dx, y , z-dz) + { 0.0, 0.0, -1.0 }, // 8 (x , y , z-dz) + { 0.0, 0.0, 1.0 }, // 9 (x , y , z+dz) + { 1.0, 0.0, 1.0 }, // 10 (x+dx, y , z+dz) + { 0.0, 1.0, 1.0 }, // 11 (x , y+dy, z+dz) + { 0.0, -1.0, -1.0 }}; // 12 (x , y-dy, z-dz) template Array ProcessVarOpti::NodeOpti::GetGrad() @@ -406,7 +402,7 @@ Array ProcessVarOpti::NodeOpti::GetGrad<2>() NekDouble dx = 1e-4; vector w(9); - for(int i = 0; i < 9; i++) + for(int i = 0; i < 7; i++) { node->m_x = xc + dir[i][0] * dx; node->m_y = yc + dir[i][1] * dx; @@ -428,11 +424,11 @@ Array ProcessVarOpti::NodeOpti::GetGrad<2>() //ret[7] d2/dxdz //ret[8] d2/dydz - ret[0] = (w[1] - w[5]) / 2.0 / dx; - ret[1] = (w[3] - w[7]) / 2.0 / dx; - ret[3] = (w[1] + w[5] - 2.0*w[0]) / dx / dx; - ret[4] = (w[3] + w[7] - 2.0*w[0]) / dx / dx; - ret[6] = (w[2] + w[6] - w[4] - w[8]) / 4.0 / dx / dx; + ret[0] = (w[1] - w[4]) / 2.0 / dx; + ret[1] = (w[3] - w[6]) / 2.0 / dx; + ret[3] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; + ret[4] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; + ret[6] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / dx / dx; return ret; } @@ -447,14 +443,13 @@ Array ProcessVarOpti::NodeOpti::GetGrad<3>() vector w; - for(int i = 0; i < 19; i++) + for(int i = 0; i < 13; i++) { node->m_x = xc + dir[i][0] * dx; node->m_y = yc + dir[i][1] * dx; node->m_z = zc + dir[i][2] * dx; w.push_back(GetFunctional<3>()); } - node->m_x = xc; node->m_y = yc; node->m_z = zc; @@ -472,17 +467,17 @@ Array ProcessVarOpti::NodeOpti::GetGrad<3>() //ret[7] d2/dxdz //ret[8] d2/dydz - ret[0] = (w[1] - w[5]) / 2.0 / dx; - ret[1] = (w[3] - w[7]) / 2.0 / dx; - ret[2] = (w[13] - w[10]) / 2.0 / dx; + ret[0] = (w[1] - w[4]) / 2.0 / dx; + ret[1] = (w[3] - w[6]) / 2.0 / dx; + ret[2] = (w[9] - w[8]) / 2.0 / dx; - ret[3] = (w[1] + w[5] - 2.0*w[0]) / dx / dx; - ret[4] = (w[3] + w[7] - 2.0*w[0]) / dx / dx; - ret[5] = (w[13] + w[10] - 2.0*w[0]) / dx / dx; + ret[3] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; + ret[4] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; + ret[5] = (w[9] + w[8] - 2.0*w[0]) / dx / dx; - ret[6] = (w[2] + w[6] - w[4] - w[8]) / 4.0 / dx /dx; - ret[7] = (w[14] + w[9] - w[11] - w[12]) / 4.0 / dx /dx; - ret[8] = (w[16] + w[17] - w[15] - w[18]) / 4.0 / dx /dx; + ret[6] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / dx / dx; + ret[7] = (w[10] - w[1] - w[9] + 2.0*w[0] - w[4] - w[8] + w[7]) / 2.0 / dx / dx; + ret[8] = (w[11] - w[3] - w[9] + 2.0*w[0] - w[6] - w[8] + w[12]) / 2.0 / dx / dx; return ret; } @@ -546,19 +541,18 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() // Store x/y components of each element sequentially in memory for (int i = 0, cnt = 0; i < nElmt; ++i) { - for (int j = 0; j < ptsLow; ++j) + for (int j = 0; j < ptsLow; ++j, ++cnt) { - Array loc = data[i]->nodes[j]->GetLoc(); - for (int d = 0; d < DIM; ++d) - { - X[cnt + d*ptsLow + j] = loc[d]; - //X[cnt + d*ptsLow] = data[i]->nodes[j]->m_x; - //X[cnt + ptsLow] = data[i]->nodes[j]->m_y; - //X[cnt + 2*ptsLow] = data[i]->nodes[j]->m_z; - } + //Array loc = data[i]->nodes[j]->GetLoc(); + //for (int d = 0; d < DIM; ++d) + //{ + X[cnt] = data[i]->nodes[j]->m_x; + X[cnt + ptsLow] = data[i]->nodes[j]->m_y; + X[cnt + 2*ptsLow] = data[i]->nodes[j]->m_z; + //} } - cnt += DIM*ptsLow; + cnt += ptsLow; } // Storage for derivatives, ordered by: @@ -796,25 +790,28 @@ vector > ProcessVarOpti::GetColouredNodes() ASSERTL0(false,"space dim issue"); } + res->nDirc = boundaryNodes.size(); + vector remain; - if(m_mesh->m_expDim == 2) + EdgeSet::iterator eit; + for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) { - EdgeSet::iterator eit; - for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) + vector n = (*eit)->m_edgeNodes; + n.push_back((*eit)->m_n1); + n.push_back((*eit)->m_n2); + for(int j = 0; j < n.size(); j++) { - vector n = (*eit)->m_edgeNodes; - n.push_back((*eit)->m_n1); - n.push_back((*eit)->m_n2); - for(int j = 0; j < n.size(); j++) + NodeSet::iterator nit = boundaryNodes.find(n[j]); + if(nit == boundaryNodes.end()) { - NodeSet::iterator nit = boundaryNodes.find(n[j]); - if(nit == boundaryNodes.end()) - { - remain.push_back(n[j]); - } + remain.push_back(n[j]); } } + } + + if(m_mesh->m_expDim == 2) + { for(int i = 0; i < m_mesh->m_element[2].size(); i++) { @@ -834,14 +831,12 @@ vector > ProcessVarOpti::GetColouredNodes() FaceSet::iterator fit; for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) { - vector n; - (*fit)->GetCurvedNodes(n); - for(int j = 0; j < n.size(); j++) + for(int j = 0; j < (*fit)->m_faceNodes.size(); j++) { - NodeSet::iterator nit = boundaryNodes.find(n[j]); + NodeSet::iterator nit = boundaryNodes.find((*fit)->m_faceNodes[j]); if(nit == boundaryNodes.end()) { - remain.push_back(n[j]); + remain.push_back((*fit)->m_faceNodes[j]); } } } @@ -1090,9 +1085,9 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP x1i = VdmD[0]*X; y1i = VdmD[0]*Y; - z1i = VdmD[0]*Z; x2i = VdmD[1]*X; y2i = VdmD[1]*Y; + z1i = VdmD[0]*Z; z2i = VdmD[1]*Z; x3i = VdmD[2]*X; y3i = VdmD[2]*Y; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index 151d1cd5b..5f31ca4a2 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -64,6 +64,7 @@ struct Residual { NekDouble val; int n; + int nDirc; int nDoF; int startInv; NekDouble worstJac; -- GitLab From 696f5ff1a023df3cf2fe4b87e1851dfe0bd85a14 Mon Sep 17 00:00:00 2001 From: mike turner Date: Fri, 13 May 2016 14:56:18 +0100 Subject: [PATCH 038/236] 3d fixes, not really fixed --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 0528cc96a..f8b1212d0 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -278,6 +278,8 @@ void ProcessVarOpti::Process() cout << ctr << "\tResidual: " << res->val << endl; if(ctr > 5000) break; + + break; } EvaluateMesh(); @@ -301,6 +303,11 @@ void ProcessVarOpti::NodeOpti::Optimise() Array G = GetGrad(); + for(int i = 0; i < 9; i++) + { + cout << "G[" << i << "] " << G[i] << endl; + } + if(sqrt(G[0]*G[0] + G[1]*G[1] + G[2]*G[2]) > 1e-10) { //needs to optimise @@ -342,6 +349,7 @@ void ProcessVarOpti::NodeOpti::Optimise() } cout << delX << " " << delY << " " << delZ << endl; + exit(-1); bool found = false; while(alpha > 1e-10) @@ -439,7 +447,7 @@ Array ProcessVarOpti::NodeOpti::GetGrad<3>() NekDouble xc = node->m_x; NekDouble yc = node->m_y; NekDouble zc = node->m_z; - NekDouble dx = 1e-4; + NekDouble dx = 1e-6; vector w; @@ -541,18 +549,19 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() // Store x/y components of each element sequentially in memory for (int i = 0, cnt = 0; i < nElmt; ++i) { - for (int j = 0; j < ptsLow; ++j, ++cnt) + for (int j = 0; j < ptsLow; ++j) { - //Array loc = data[i]->nodes[j]->GetLoc(); - //for (int d = 0; d < DIM; ++d) - //{ - X[cnt] = data[i]->nodes[j]->m_x; - X[cnt + ptsLow] = data[i]->nodes[j]->m_y; - X[cnt + 2*ptsLow] = data[i]->nodes[j]->m_z; - //} + Array loc = data[i]->nodes[j]->GetLoc(); + for (int d = 0; d < DIM; ++d) + { + X[cnt + d*ptsLow + j] = loc[d]; + //X[cnt + d*ptsLow] = data[i]->nodes[j]->m_x; + //X[cnt + ptsLow] = data[i]->nodes[j]->m_y; + //X[cnt + 2*ptsLow] = data[i]->nodes[j]->m_z; + } } - cnt += ptsLow; + cnt += DIM*ptsLow; } // Storage for derivatives, ordered by: @@ -594,7 +603,6 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() } } } - NekDouble jacDet = JacDet(jacIdeal); NekDouble trEtE = LinElasTrace(jacIdeal); @@ -608,6 +616,7 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() integral += quadW[k] * (K * 0.5 * lsigma * lsigma + mu * trEtE); } } + cout << endl << endl; break; } -- GitLab From de477817c47631d6a667a034f97a68d186c366c2 Mon Sep 17 00:00:00 2001 From: mike turner Date: Fri, 13 May 2016 17:50:25 +0100 Subject: [PATCH 039/236] annoyingly easy fix is very annoying --- utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index f8b1212d0..bab084ab6 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -303,11 +303,6 @@ void ProcessVarOpti::NodeOpti::Optimise() Array G = GetGrad(); - for(int i = 0; i < 9; i++) - { - cout << "G[" << i << "] " << G[i] << endl; - } - if(sqrt(G[0]*G[0] + G[1]*G[1] + G[2]*G[2]) > 1e-10) { //needs to optimise @@ -348,9 +343,6 @@ void ProcessVarOpti::NodeOpti::Optimise() delZ = del[2]; } - cout << delX << " " << delY << " " << delZ << endl; - exit(-1); - bool found = false; while(alpha > 1e-10) { @@ -616,7 +608,6 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() integral += quadW[k] * (K * 0.5 * lsigma * lsigma + mu * trEtE); } } - cout << endl << endl; break; } @@ -948,6 +939,7 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP ec.m_order = 1; ec.m_faceNodes = false; ec.m_volumeNodes = false; + ec.m_reorient = false; ElementSharedPtr E = GetElementFactory().CreateInstance( ec.m_e, ec, el->GetVertexList(), -- GitLab From 636e497df994f05b3fd7b4af40fbe6d4ca7a60d3 Mon Sep 17 00:00:00 2001 From: David Moxey Date: Mon, 16 May 2016 15:20:24 +0100 Subject: [PATCH 040/236] Add optimisation for node coordinates, add config for tolerance/iteration count --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 28 ++++++++++--------- .../NekMesh/ProcessModules/ProcessVarOpti.h | 23 ++++++++++++++- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index bab084ab6..97ee642f4 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -83,6 +83,10 @@ ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) ConfigOption(false, "0", "Number of quad points"); m_config["stats"] = ConfigOption(false, "", "Write a file with list of scaled jacobians"); + m_config["restol"] = + ConfigOption(false, "1e-6", "Tolerance criterion"); + m_config["maxiter"] = + ConfigOption(false, "500", "Maximum number of iterations"); } ProcessVarOpti::~ProcessVarOpti() @@ -117,6 +121,9 @@ void ProcessVarOpti::Process() ASSERTL0(false,"not opti type set"); } + const int maxIter = m_config["maxiter"].as(); + const NekDouble restol = m_config["restol"].as(); + m_mesh->m_nummode = m_config["nq"].as(); ASSERTL0(m_mesh->m_nummode > 2,"not specified high-order"); @@ -237,7 +244,8 @@ void ProcessVarOpti::Process() << "N color sets:\t\t" << nset << endl << "Avg set colors:\t\t" << p/nset << endl << "Min set:\t\t" << mn << endl - << "Max set:\t\t" << mx << endl; + << "Max set:\t\t" << mx << endl + << "Residual tolerance:\t\t" << restol << endl; int nThreads = m_config["numthreads"].as(); @@ -247,7 +255,7 @@ void ProcessVarOpti::Process() Thread::ThreadManagerSharedPtr tm = tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads); - while (res->val > 1e-6) + while (res->val > restol) { ctr++; res->val = 0.0; @@ -276,10 +284,8 @@ void ProcessVarOpti::Process() } cout << ctr << "\tResidual: " << res->val << endl; - if(ctr > 5000) + if(ctr > maxIter) break; - - break; } EvaluateMesh(); @@ -543,13 +549,9 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() { for (int j = 0; j < ptsLow; ++j) { - Array loc = data[i]->nodes[j]->GetLoc(); for (int d = 0; d < DIM; ++d) { - X[cnt + d*ptsLow + j] = loc[d]; - //X[cnt + d*ptsLow] = data[i]->nodes[j]->m_x; - //X[cnt + ptsLow] = data[i]->nodes[j]->m_y; - //X[cnt + 2*ptsLow] = data[i]->nodes[j]->m_z; + X[cnt + d*ptsLow + j] = *(data[i]->nodes[j][d]); } } @@ -911,11 +913,11 @@ void ProcessVarOpti::GetElementMap() for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - ElDataSharedPtr d = boost::shared_ptr(new ElData); + vector ns; + el->GetCurvedNodes(ns); + ElDataSharedPtr d = boost::shared_ptr(new ElData(ns, m_mesh->m_spaceDim)); d->el = el; d->maps = MappingIdealToRef(el); - el->GetCurvedNodes(d->nodes); - dataSet.push_back(d); } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h index 5f31ca4a2..415904ee2 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.h @@ -44,10 +44,31 @@ namespace Nektar { namespace Utilities { + struct ElData { + ElData(vector innodes, int spaceDim) + { + nodes.resize(innodes.size()); + for (int i = 0; i < innodes.size(); ++i) + { + nodes[i].resize(spaceDim); + nodes[i][0] = &innodes[i]->m_x; + + if (spaceDim >= 2) + { + nodes[i][1] = &innodes[i]->m_y; + } + + if (spaceDim >= 3) + { + nodes[i][2] = &innodes[i]->m_z; + } + } + } + ElementSharedPtr el; - vector nodes; + vector > nodes; vector > maps; }; typedef boost::shared_ptr ElDataSharedPtr; -- GitLab From e3c0134e5989f02ce767ce9e3a9a4e3502698b0a Mon Sep 17 00:00:00 2001 From: David Moxey Date: Fri, 20 May 2016 09:11:36 +0100 Subject: [PATCH 041/236] Add some fixes for varopti in separate branch to avoid conflicts --- .../LibUtilities/Foundations/NodalTetSPI.cpp | 14 +- .../Foundations/NodalTetSPIData.h | 113 +++++++++++++- .../NekMesh/OutputModules/OutputNekpp.cpp | 47 +++--- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 140 ++++++++++-------- 4 files changed, 216 insertions(+), 98 deletions(-) diff --git a/library/LibUtilities/Foundations/NodalTetSPI.cpp b/library/LibUtilities/Foundations/NodalTetSPI.cpp index 3a2fd9e03..e00cb01ea 100644 --- a/library/LibUtilities/Foundations/NodalTetSPI.cpp +++ b/library/LibUtilities/Foundations/NodalTetSPI.cpp @@ -52,18 +52,18 @@ namespace Nektar for(int i = 0; i < 3; i++) { - m_points[i] = Array(NodalTetSPINPTS[numPoints-2]); + m_points[i] = Array(NodalTetSPINPTS[numPoints-1]); } int index=0; // initialize values - for(unsigned int i=0; i < numPoints-2; ++i) + for(unsigned int i=0; i < numPoints-1; ++i) { index += NodalTetSPINPTS[i]; } - for(int i = 0; i < NodalTetSPINPTS[numPoints-2]; i++) + for(int i = 0; i < NodalTetSPINPTS[numPoints-1]; i++) { m_points[0][i] = NodalTetSPIData[index][0]; m_points[1][i] = NodalTetSPIData[index][1]; @@ -79,7 +79,7 @@ namespace Nektar { unsigned int numPoints = GetNumPoints(); - m_weights = Array(NodalTetSPINPTS[numPoints-2]); + m_weights = Array(NodalTetSPINPTS[numPoints-1]); int index=0; @@ -89,7 +89,7 @@ namespace Nektar index += NodalTetSPINPTS[i]; } - for(int i = 0; i < NodalTetSPINPTS[numPoints-2]; i++) + for(int i = 0; i < NodalTetSPINPTS[numPoints-1]; i++) { m_weights[i] = NodalTetSPIData[index][3]; index++; @@ -110,11 +110,9 @@ namespace Nektar int NodalTetSPI::GetNumPointsAlt() { - return NodalTetSPINPTS[GetNumPoints()-2]; + return NodalTetSPINPTS[GetNumPoints()-1]; } } // end of namespace stdregion } // end of namespace stdregion - - diff --git a/library/LibUtilities/Foundations/NodalTetSPIData.h b/library/LibUtilities/Foundations/NodalTetSPIData.h index f61eaa559..93230e6cf 100644 --- a/library/LibUtilities/Foundations/NodalTetSPIData.h +++ b/library/LibUtilities/Foundations/NodalTetSPIData.h @@ -3,8 +3,8 @@ namespace Nektar { namespace LibUtilities { - const unsigned int NodalTetSPIAvailable = 7; - static const unsigned int NodalTetSPINPTS[NodalTetSPIAvailable] = {1,4,8,14,14,24,35}; + const unsigned int NodalTetSPIAvailable = 9; + static const unsigned int NodalTetSPINPTS[NodalTetSPIAvailable] = {1,4,8,14,14,24,35,46,59}; static const NekDouble NodalTetSPIData[][4] = { // %%% x y w @@ -114,7 +114,114 @@ namespace Nektar {-0.95746905491703350802232779700036011785, -0.95746905491703350802232779700036011785, -0.70672237236303010619155516569574455189, 0.010814361106537788754804577988128720209}, {-0.95746905491703350802232779700036011785, 0.62166048219709712223621075969646478759, -0.70672237236303010619155516569574455189, 0.010814361106537788754804577988128720209}, {-0.70672237236303010619155516569574455189, -0.95746905491703350802232779700036011785, -0.95746905491703350802232779700036011785, 0.010814361106537788754804577988128720209}, - {0.62166048219709712223621075969646478759, -0.70672237236303010619155516569574455189, -0.95746905491703350802232779700036011785, 0.010814361106537788754804577988128720209}}; + {0.62166048219709712223621075969646478759, -0.70672237236303010619155516569574455189, -0.95746905491703350802232779700036011785, 0.010814361106537788754804577988128720209}, + // 8 46 %%% Order / Number of Points + {-0.78409455007557830303561343854585276851, -0.78409455007557830303561343854585276851, 0.35228365022673490910684031563755830553, 0.035235534544545108539097313565645827902}, + {-0.78409455007557830303561343854585276851, 0.35228365022673490910684031563755830553, -0.78409455007557830303561343854585276851, 0.035235534544545108539097313565645827902}, + {0.35228365022673490910684031563755830553, -0.78409455007557830303561343854585276851, -0.78409455007557830303561343854585276851, 0.035235534544545108539097313565645827902}, + {-0.78409455007557830303561343854585276851, -0.78409455007557830303561343854585276851, -0.78409455007557830303561343854585276851, 0.035235534544545108539097313565645827902}, + {-0.629781024434826859446183999496503797, -0.629781024434826859446183999496503797, -0.110656926695519421661448001510488609, 0.069375663418318043619861410028472677606}, + {-0.629781024434826859446183999496503797, -0.110656926695519421661448001510488609, -0.629781024434826859446183999496503797, 0.069375663418318043619861410028472677606}, + {-0.110656926695519421661448001510488609, -0.629781024434826859446183999496503797, -0.629781024434826859446183999496503797, 0.069375663418318043619861410028472677606}, + {-0.629781024434826859446183999496503797, -0.629781024434826859446183999496503797, -0.629781024434826859446183999496503797, 0.069375663418318043619861410028472677606}, + {-0.91536691263046543675183591431855057189, -0.91536691263046543675183591431855057189, 0.74610073789139631025550774295565171568, 0.010033674871386933040967405110292766211}, + {-0.91536691263046543675183591431855057189, 0.74610073789139631025550774295565171568, -0.91536691263046543675183591431855057189, 0.010033674871386933040967405110292766211}, + {0.74610073789139631025550774295565171568, -0.91536691263046543675183591431855057189, -0.91536691263046543675183591431855057189, 0.010033674871386933040967405110292766211}, + {-0.91536691263046543675183591431855057189, -0.91536691263046543675183591431855057189, -0.91536691263046543675183591431855057189, 0.010033674871386933040967405110292766211}, + {-0.37163658175192200927334245312373662702, -0.37163658175192200927334245312373662702, -0.88509025474423397217997264062879011895, 0.055685043809246530275971813171748834223}, + {-0.37163658175192200927334245312373662702, -0.88509025474423397217997264062879011895, -0.37163658175192200927334245312373662702, 0.055685043809246530275971813171748834223}, + {-0.88509025474423397217997264062879011895, -0.37163658175192200927334245312373662702, -0.37163658175192200927334245312373662702, 0.055685043809246530275971813171748834223}, + {-0.37163658175192200927334245312373662702, -0.37163658175192200927334245312373662702, -0.37163658175192200927334245312373662702, 0.055685043809246530275971813171748834223}, + {-0.12881734283233958954373367640680593526, -0.87118265716766041045626632359319406474, -0.87118265716766041045626632359319406474, 0.048374573681745097334959362864457783412}, + {-0.87118265716766041045626632359319406474, -0.12881734283233958954373367640680593526, -0.87118265716766041045626632359319406474, 0.048374573681745097334959362864457783412}, + {-0.12881734283233958954373367640680593526, -0.12881734283233958954373367640680593526, -0.87118265716766041045626632359319406474, 0.048374573681745097334959362864457783412}, + {-0.12881734283233958954373367640680593526, -0.87118265716766041045626632359319406474, -0.12881734283233958954373367640680593526, 0.048374573681745097334959362864457783412}, + {-0.87118265716766041045626632359319406474, -0.12881734283233958954373367640680593526, -0.12881734283233958954373367640680593526, 0.048374573681745097334959362864457783412}, + {-0.87118265716766041045626632359319406474, -0.87118265716766041045626632359319406474, -0.12881734283233958954373367640680593526, 0.048374573681745097334959362864457783412}, + {0.43492812685261664658005711425116290088, -0.95713213974573885031100182115353118963, -0.52066384736113894595805347194410052161, 0.0095425371877925775336250150191510735196}, + {0.43492812685261664658005711425116290088, -0.95713213974573885031100182115353118963, -0.95713213974573885031100182115353118963, 0.0095425371877925775336250150191510735196}, + {-0.95713213974573885031100182115353118963, -0.95713213974573885031100182115353118963, 0.43492812685261664658005711425116290088, 0.0095425371877925775336250150191510735196}, + {-0.52066384736113894595805347194410052161, 0.43492812685261664658005711425116290088, -0.95713213974573885031100182115353118963, 0.0095425371877925775336250150191510735196}, + {-0.95713213974573885031100182115353118963, -0.52066384736113894595805347194410052161, 0.43492812685261664658005711425116290088, 0.0095425371877925775336250150191510735196}, + {-0.95713213974573885031100182115353118963, 0.43492812685261664658005711425116290088, -0.95713213974573885031100182115353118963, 0.0095425371877925775336250150191510735196}, + {-0.52066384736113894595805347194410052161, -0.95713213974573885031100182115353118963, 0.43492812685261664658005711425116290088, 0.0095425371877925775336250150191510735196}, + {-0.95713213974573885031100182115353118963, -0.52066384736113894595805347194410052161, -0.95713213974573885031100182115353118963, 0.0095425371877925775336250150191510735196}, + {-0.95713213974573885031100182115353118963, -0.95713213974573885031100182115353118963, -0.52066384736113894595805347194410052161, 0.0095425371877925775336250150191510735196}, + {-0.95713213974573885031100182115353118963, 0.43492812685261664658005711425116290088, -0.52066384736113894595805347194410052161, 0.0095425371877925775336250150191510735196}, + {-0.52066384736113894595805347194410052161, -0.95713213974573885031100182115353118963, -0.95713213974573885031100182115353118963, 0.0095425371877925775336250150191510735196}, + {0.43492812685261664658005711425116290088, -0.52066384736113894595805347194410052161, -0.95713213974573885031100182115353118963, 0.0095425371877925775336250150191510735196}, + {0.16759475660428881185333950841466005283, -0.59172133224794175913941940243963088242, -0.98415209210840529357450070353539828799, 0.020604648201280446418040434034344443905}, + {0.16759475660428881185333950841466005283, -0.59172133224794175913941940243963088242, -0.59172133224794175913941940243963088242, 0.020604648201280446418040434034344443905}, + {-0.59172133224794175913941940243963088242, -0.59172133224794175913941940243963088242, 0.16759475660428881185333950841466005283, 0.020604648201280446418040434034344443905}, + {-0.98415209210840529357450070353539828799, 0.16759475660428881185333950841466005283, -0.59172133224794175913941940243963088242, 0.020604648201280446418040434034344443905}, + {-0.59172133224794175913941940243963088242, -0.98415209210840529357450070353539828799, 0.16759475660428881185333950841466005283, 0.020604648201280446418040434034344443905}, + {-0.59172133224794175913941940243963088242, 0.16759475660428881185333950841466005283, -0.59172133224794175913941940243963088242, 0.020604648201280446418040434034344443905}, + {-0.98415209210840529357450070353539828799, -0.59172133224794175913941940243963088242, 0.16759475660428881185333950841466005283, 0.020604648201280446418040434034344443905}, + {-0.59172133224794175913941940243963088242, -0.98415209210840529357450070353539828799, -0.59172133224794175913941940243963088242, 0.020604648201280446418040434034344443905}, + {-0.59172133224794175913941940243963088242, -0.59172133224794175913941940243963088242, -0.98415209210840529357450070353539828799, 0.020604648201280446418040434034344443905}, + {-0.59172133224794175913941940243963088242, 0.16759475660428881185333950841466005283, -0.98415209210840529357450070353539828799, 0.020604648201280446418040434034344443905}, + {-0.98415209210840529357450070353539828799, -0.59172133224794175913941940243963088242, -0.59172133224794175913941940243963088242, 0.020604648201280446418040434034344443905}, + {0.16759475660428881185333950841466005283, -0.98415209210840529357450070353539828799, -0.59172133224794175913941940243963088242, 0.020604648201280446418040434034344443905}, + // 9 59 %%% Order / Number of Points + { -0.5, -0.5, -0.5, 0.07734739854997367644741906257553729918}, + {-0.99999999876036601109069831529161985423, -0.99999999876036601109069831529161985423 , 0.9999999962810980332720949458748595627, 8.5759042345675186085903030258742437834e-05}, + {-0.99999999876036601109069831529161985423, 0.9999999962810980332720949458748595627, -0.99999999876036601109069831529161985423, 8.5759042345675186085903030258742437834e-05}, + {0.9999999962810980332720949458748595627, -0.99999999876036601109069831529161985423 , -0.99999999876036601109069831529161985423 ,8.5759042345675186085903030258742437834e-05}, + {-0.99999999876036601109069831529161985423, -0.99999999876036601109069831529161985423, -0.99999999876036601109069831529161985423, 8.5759042345675186085903030258742437834e-05}, + {-0.67845092920947681169601712222921603853, -0.67845092920947681169601712222921603853, 0.035352787628430435088051366687648115583, 0.030897784616567277310532826869162311937}, + {-0.67845092920947681169601712222921603853, 0.035352787628430435088051366687648115583, -0.67845092920947681169601712222921603853, 0.030897784616567277310532826869162311937}, + {0.035352787628430435088051366687648115583, -0.67845092920947681169601712222921603853, -0.67845092920947681169601712222921603853, 0.030897784616567277310532826869162311937}, + {-0.67845092920947681169601712222921603853, -0.67845092920947681169601712222921603853, -0.67845092920947681169601712222921603853, 0.030897784616567277310532826869162311937}, + {-0.35544695635715805159186380319222134027, -0.35544695635715805159186380319222134027, -0.93365913092852584522440859042333597919, 0.039417216447239047523644877985518239107}, + {-0.35544695635715805159186380319222134027, -0.93365913092852584522440859042333597919, -0.35544695635715805159186380319222134027, 0.039417216447239047523644877985518239107}, + {-0.93365913092852584522440859042333597919, -0.35544695635715805159186380319222134027, -0.35544695635715805159186380319222134027, 0.039417216447239047523644877985518239107}, + {-0.35544695635715805159186380319222134027, -0.35544695635715805159186380319222134027, -0.35544695635715805159186380319222134027, 0.039417216447239047523644877985518239107}, + {-0.90978216330917283407807385501200614331, -0.90978216330917283407807385501200614331, 0.72934648992751850223422156503601842994, 0.010751973306154910354337519688619045729}, + {-0.90978216330917283407807385501200614331, 0.72934648992751850223422156503601842994, -0.90978216330917283407807385501200614331, 0.010751973306154910354337519688619045729}, + {0.72934648992751850223422156503601842994 , -0.90978216330917283407807385501200614331 , -0.90978216330917283407807385501200614331 , 0.010751973306154910354337519688619045729}, + {-0.90978216330917283407807385501200614331, -0.90978216330917283407807385501200614331, -0.90978216330917283407807385501200614331, 0.010751973306154910354337519688619045729}, + {-0.77540690799124790934402070093968875729, -0.22459309200875209065597929906031124271, -0.22459309200875209065597929906031124271, 0.05084544013826995406889748131136091475}, + {-0.22459309200875209065597929906031124271, -0.77540690799124790934402070093968875729, -0.22459309200875209065597929906031124271, 0.05084544013826995406889748131136091475}, + {-0.77540690799124790934402070093968875729, -0.77540690799124790934402070093968875729, -0.22459309200875209065597929906031124271, 0.05084544013826995406889748131136091475}, + {-0.77540690799124790934402070093968875729, -0.22459309200875209065597929906031124271, -0.77540690799124790934402070093968875729, 0.05084544013826995406889748131136091475}, + {-0.22459309200875209065597929906031124271, -0.77540690799124790934402070093968875729, -0.77540690799124790934402070093968875729, 0.05084544013826995406889748131136091475}, + {-0.22459309200875209065597929906031124271, -0.22459309200875209065597929906031124271, -0.77540690799124790934402070093968875729, 0.05084544013826995406889748131136091475}, + {-0.994890841533917338064711949103255315, -0.082257102495081453456435781598997046246 , -0.84059495347591975502241648769875059251 , 0.011179229597731402927583520512290878612}, + {-0.994890841533917338064711949103255315, -0.082257102495081453456435781598997046246 , -0.082257102495081453456435781598997046246 , 0.011179229597731402927583520512290878612}, + {-0.082257102495081453456435781598997046246, -0.082257102495081453456435781598997046246, -0.994890841533917338064711949103255315, 0.011179229597731402927583520512290878612}, + {-0.84059495347591975502241648769875059251 , -0.994890841533917338064711949103255315 , -0.082257102495081453456435781598997046246 , 0.011179229597731402927583520512290878612}, + {-0.082257102495081453456435781598997046246, -0.84059495347591975502241648769875059251, -0.994890841533917338064711949103255315, 0.011179229597731402927583520512290878612}, + {-0.082257102495081453456435781598997046246, -0.994890841533917338064711949103255315, -0.082257102495081453456435781598997046246, 0.011179229597731402927583520512290878612}, + {-0.84059495347591975502241648769875059251 , -0.082257102495081453456435781598997046246 , -0.994890841533917338064711949103255315 , 0.011179229597731402927583520512290878612}, + {-0.082257102495081453456435781598997046246, -0.84059495347591975502241648769875059251, -0.082257102495081453456435781598997046246, 0.011179229597731402927583520512290878612}, + {-0.082257102495081453456435781598997046246, -0.082257102495081453456435781598997046246, -0.84059495347591975502241648769875059251, 0.011179229597731402927583520512290878612}, + {-0.082257102495081453456435781598997046246, -0.994890841533917338064711949103255315, -0.84059495347591975502241648769875059251, 0.011179229597731402927583520512290878612}, + {-0.84059495347591975502241648769875059251, -0.082257102495081453456435781598997046246, -0.082257102495081453456435781598997046246 , 0.011179229597731402927583520512290878612}, + {-0.994890841533917338064711949103255315, -0.84059495347591975502241648769875059251 , -0.082257102495081453456435781598997046246 , 0.011179229597731402927583520512290878612}, + {0.43670065288414901811354448912928750012, -0.93244825862932284418902737202159413719 , -0.57180413562550332973548974508609922574 , 0.013646079136993770600501763121325612648}, + {0.43670065288414901811354448912928750012, -0.93244825862932284418902737202159413719 , -0.93244825862932284418902737202159413719 , 0.013646079136993770600501763121325612648}, + {-0.93244825862932284418902737202159413719, -0.93244825862932284418902737202159413719, 0.43670065288414901811354448912928750012 , 0.013646079136993770600501763121325612648}, + {-0.57180413562550332973548974508609922574, 0.43670065288414901811354448912928750012, -0.93244825862932284418902737202159413719 , 0.013646079136993770600501763121325612648}, + {-0.93244825862932284418902737202159413719, -0.57180413562550332973548974508609922574, 0.43670065288414901811354448912928750012 , 0.013646079136993770600501763121325612648}, + {-0.93244825862932284418902737202159413719, 0.43670065288414901811354448912928750012, -0.93244825862932284418902737202159413719 , 0.013646079136993770600501763121325612648}, + {-0.57180413562550332973548974508609922574, -0.93244825862932284418902737202159413719, 0.43670065288414901811354448912928750012 , 0.013646079136993770600501763121325612648}, + {-0.93244825862932284418902737202159413719, -0.57180413562550332973548974508609922574, -0.93244825862932284418902737202159413719 , 0.013646079136993770600501763121325612648}, + {-0.93244825862932284418902737202159413719, -0.93244825862932284418902737202159413719, -0.57180413562550332973548974508609922574 , 0.013646079136993770600501763121325612648}, + {-0.93244825862932284418902737202159413719, 0.43670065288414901811354448912928750012, -0.57180413562550332973548974508609922574 , 0.013646079136993770600501763121325612648}, + {-0.57180413562550332973548974508609922574, -0.93244825862932284418902737202159413719, -0.93244825862932284418902737202159413719 , 0.013646079136993770600501763121325612648}, + {0.43670065288414901811354448912928750012 , -0.57180413562550332973548974508609922574 , -0.93244825862932284418902737202159413719 , 0.013646079136993770600501763121325612648}, + {-0.93116817884364945982158957577713628669, -0.63271726038014422042206258028726154683, 0.19660269960393790066571473635165938035 , 0.027366554623984184053091789082666607808}, + {-0.93116817884364945982158957577713628669, -0.63271726038014422042206258028726154683, -0.63271726038014422042206258028726154683 , 0.027366554623984184053091789082666607808}, + {-0.63271726038014422042206258028726154683, -0.63271726038014422042206258028726154683, -0.93116817884364945982158957577713628669 , 0.027366554623984184053091789082666607808}, + {0.19660269960393790066571473635165938035 , -0.93116817884364945982158957577713628669 , -0.63271726038014422042206258028726154683 , 0.027366554623984184053091789082666607808}, + {-0.63271726038014422042206258028726154683, 0.19660269960393790066571473635165938035, -0.93116817884364945982158957577713628669 , 0.027366554623984184053091789082666607808}, + {-0.63271726038014422042206258028726154683, -0.93116817884364945982158957577713628669, -0.63271726038014422042206258028726154683 , 0.027366554623984184053091789082666607808}, + {0.19660269960393790066571473635165938035 , -0.63271726038014422042206258028726154683 , -0.93116817884364945982158957577713628669 , 0.027366554623984184053091789082666607808}, + {-0.63271726038014422042206258028726154683, 0.19660269960393790066571473635165938035, -0.63271726038014422042206258028726154683 , 0.027366554623984184053091789082666607808}, + {-0.63271726038014422042206258028726154683, -0.63271726038014422042206258028726154683, 0.19660269960393790066571473635165938035 , 0.027366554623984184053091789082666607808}, + {-0.63271726038014422042206258028726154683, -0.93116817884364945982158957577713628669, 0.19660269960393790066571473635165938035 , 0.027366554623984184053091789082666607808}, + {0.19660269960393790066571473635165938035 , -0.63271726038014422042206258028726154683 , -0.63271726038014422042206258028726154683 , 0.027366554623984184053091789082666607808}, + {-0.93116817884364945982158957577713628669, 0.19660269960393790066571473635165938035, -0.63271726038014422042206258028726154683 , 0.027366554623984184053091789082666607808}}; } diff --git a/utilities/NekMesh/OutputModules/OutputNekpp.cpp b/utilities/NekMesh/OutputModules/OutputNekpp.cpp index 8da13a542..5e7a0dcc2 100644 --- a/utilities/NekMesh/OutputModules/OutputNekpp.cpp +++ b/utilities/NekMesh/OutputModules/OutputNekpp.cpp @@ -681,38 +681,37 @@ void OutputNekpp::WriteXmlCurves(TiXmlElement *pRoot) } } } + // 2D elements in 2- or 3-space, output face curvature information - else if (m_mesh->m_expDim >= 2 && - m_mesh->m_spaceDim >= m_mesh->m_expDim) + if (m_mesh->m_expDim >= 2 && m_mesh->m_spaceDim >= m_mesh->m_expDim) { vector::iterator it; - for (int d = 2; d <= 3; ++d) - { - std::string tag = d == 2 ? "F" : "V"; - std::string attr = d == 2 ? "FACEID" : "VOLID"; + int d = m_mesh->m_expDim; + std::string tag = d == 2 ? "F" : "V"; + std::string attr = d == 2 ? "FACEID" : "VOLID"; - for (it = m_mesh->m_element[d].begin(); - it != m_mesh->m_element[d].end(); - ++it) + for (it = m_mesh->m_element[d].begin(); + it != m_mesh->m_element[d].end(); + ++it) + { + // Only generate face curve if there are volume nodes + if ((*it)->GetVolumeNodes().size() > 0) { - // Only generate face curve if there are volume nodes - if ((*it)->GetVolumeNodes().size() > 0) - { - TiXmlElement *e = new TiXmlElement(tag); - e->SetAttribute("ID", facecnt++); - e->SetAttribute(attr, (*it)->GetId()); - e->SetAttribute("NUMPOINTS", (*it)->GetNodeCount()); - e->SetAttribute( - "TYPE", - LibUtilities::kPointsTypeStr[(*it)->GetCurveType()]); - TiXmlText *t0 = new TiXmlText((*it)->GetXmlCurveString()); - e->LinkEndChild(t0); - curved->LinkEndChild(e); - } + TiXmlElement *e = new TiXmlElement(tag); + e->SetAttribute("ID", facecnt++); + e->SetAttribute(attr, (*it)->GetId()); + e->SetAttribute("NUMPOINTS", (*it)->GetNodeCount()); + e->SetAttribute( + "TYPE", + LibUtilities::kPointsTypeStr[(*it)->GetCurveType()]); + TiXmlText *t0 = new TiXmlText((*it)->GetXmlCurveString()); + e->LinkEndChild(t0); + curved->LinkEndChild(e); } } } - else if (m_mesh->m_expDim == 3) + + if (m_mesh->m_expDim == 3) { FaceSet::iterator it2; for (it2 = m_mesh->m_faceSet.begin(); diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 97ee642f4..5d58d4b2f 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -45,6 +45,7 @@ #include #include +#include #include using namespace std; @@ -245,7 +246,7 @@ void ProcessVarOpti::Process() << "Avg set colors:\t\t" << p/nset << endl << "Min set:\t\t" << mn << endl << "Max set:\t\t" << mx << endl - << "Residual tolerance:\t\t" << restol << endl; + << "Residual tolerance:\t" << restol << endl; int nThreads = m_config["numthreads"].as(); @@ -255,6 +256,9 @@ void ProcessVarOpti::Process() Thread::ThreadManagerSharedPtr tm = tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads); + Timer t; + t.Start(); + while (res->val > restol) { ctr++; @@ -288,6 +292,9 @@ void ProcessVarOpti::Process() break; } + t.Stop(); + cout << "Time to compute: " << t.TimePerTest(1) << endl; + EvaluateMesh(); cout << "Invalid at end:\t\t" << res->startInv << endl; @@ -607,7 +614,7 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); NekDouble lsigma = log(sigma); - integral += quadW[k] * (K * 0.5 * lsigma * lsigma + mu * trEtE); + integral += quadW[k] * (data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE); } } break; @@ -645,10 +652,11 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); NekDouble jacDet = JacDet(jacIdeal); - NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); + //NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-1*1E-1 + 1E-1); + NekDouble de = 1e-1; NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); NekDouble lsigma = log(sigma); - integral += quadW[k]*(0.5 * mu * (I1 - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); + integral += quadW[k]*fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1 - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); } } break; @@ -680,6 +688,7 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() { frob += jacIdeal[m] * jacIdeal[m]; } + frob *= fabs(data[i]->maps[k][9]); NekDouble jacDet = JacDet(jacIdeal); NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); @@ -716,9 +725,10 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() { frob += jacIdeal[m] * jacIdeal[m]; } + frob *= fabs(data[i]->maps[k][9]); NekDouble jacDet = JacDet(jacIdeal); - - NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); + NekDouble de = 1e-2; + //NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); integral += quadW[k]*(frob / sigma); } @@ -796,12 +806,20 @@ vector > ProcessVarOpti::GetColouredNodes() vector remain; + NodeSet::iterator nit; + for (nit = m_mesh->m_vertexSet.begin(); nit != m_mesh->m_vertexSet.end(); ++nit) + { + NodeSet::iterator nit2 = boundaryNodes.find(*nit); + if(nit2 == boundaryNodes.end()) + { + remain.push_back(*nit); + } + } + EdgeSet::iterator eit; for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) { vector n = (*eit)->m_edgeNodes; - n.push_back((*eit)->m_n1); - n.push_back((*eit)->m_n2); for(int j = 0; j < n.size(); j++) { NodeSet::iterator nit = boundaryNodes.find(n[j]); @@ -812,47 +830,29 @@ vector > ProcessVarOpti::GetColouredNodes() } } - if(m_mesh->m_expDim == 2) + FaceSet::iterator fit; + for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) { - - for(int i = 0; i < m_mesh->m_element[2].size(); i++) + for(int j = 0; j < (*fit)->m_faceNodes.size(); j++) { - vector ns = m_mesh->m_element[2][i]->GetVolumeNodes(); - for(int j = 0; j < ns.size(); j++) + NodeSet::iterator nit = boundaryNodes.find((*fit)->m_faceNodes[j]); + if(nit == boundaryNodes.end()) { - NodeSet::iterator nit = boundaryNodes.find(ns[j]); - if(nit == boundaryNodes.end()) - { - remain.push_back(ns[j]); - } + remain.push_back((*fit)->m_faceNodes[j]); } } } - else - { - FaceSet::iterator fit; - for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) - { - for(int j = 0; j < (*fit)->m_faceNodes.size(); j++) - { - NodeSet::iterator nit = boundaryNodes.find((*fit)->m_faceNodes[j]); - if(nit == boundaryNodes.end()) - { - remain.push_back((*fit)->m_faceNodes[j]); - } - } - } - for(int i = 0; i < m_mesh->m_element[3].size(); i++) + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + vector ns = + m_mesh->m_element[m_mesh->m_expDim][i]->GetVolumeNodes(); + for(int j = 0; j < ns.size(); j++) { - vector ns = m_mesh->m_element[3][i]->GetVolumeNodes(); - for(int j = 0; j < ns.size(); j++) + NodeSet::iterator nit = boundaryNodes.find(ns[j]); + if(nit == boundaryNodes.end()) { - NodeSet::iterator nit = boundaryNodes.find(ns[j]); - if(nit == boundaryNodes.end()) - { - remain.push_back(ns[j]); - } + remain.push_back(ns[j]); } } } @@ -1088,9 +1088,9 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP x1i = VdmD[0]*X; y1i = VdmD[0]*Y; + z1i = VdmD[0]*Z; x2i = VdmD[1]*X; y2i = VdmD[1]*Y; - z1i = VdmD[0]*Z; z2i = VdmD[1]*Z; x3i = VdmD[2]*X; y3i = VdmD[2]*Y; @@ -1112,8 +1112,8 @@ vector > ProcessVarOpti::MappingIdealToRef(ElementSharedP Array r(10,0.0); //store det in 10th entry r[9] = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) - -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) - +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); + -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) + +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); dxdz.Invert(); @@ -1207,12 +1207,40 @@ void ProcessVarOpti::FillQuadPoints() LibUtilities::PointsManager()[ekey]->GetPoints(gll); EdgeSet::iterator eit; + FaceSet::iterator fit; + + boost::unordered_map edgeGeoms; + boost::unordered_map faceGeoms; + boost::unordered_map volGeoms; for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) { SpatialDomains::Geometry1DSharedPtr geom = - (*eit)->GetGeom(m_mesh->m_spaceDim); + (*eit)->GetGeom(m_mesh->m_spaceDim); + geom->FillGeom(); + edgeGeoms[(*eit)->m_id] = geom; + } + + for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) + { + SpatialDomains::Geometry2DSharedPtr geom = + (*fit)->GetGeom(m_mesh->m_spaceDim); + geom->FillGeom(); + faceGeoms[(*fit)->m_id] = geom; + } + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + SpatialDomains::GeometrySharedPtr geom = + el->GetGeom(m_mesh->m_spaceDim); geom->FillGeom(); + volGeoms[el->GetId()] = geom; + } + + for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) + { + SpatialDomains::Geometry1DSharedPtr geom = edgeGeoms[(*eit)->m_id]; StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); vector hons; @@ -1283,9 +1311,7 @@ void ProcessVarOpti::FillQuadPoints() { ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - SpatialDomains::GeometrySharedPtr geom = - el->GetGeom(m_mesh->m_spaceDim); - geom->FillGeom(); + SpatialDomains::GeometrySharedPtr geom = volGeoms[el->GetId()]; StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); LibUtilities::PointsKey pkey(m_mesh->m_nummode, @@ -1304,8 +1330,7 @@ void ProcessVarOpti::FillQuadPoints() vector hons; - for(int j = nq * (nq + 1) / 2 - (nq-2)*(nq-3) / 2; - j < u.num_elements(); j++) + for(int j = 3 + 3*(nq-2); j < u.num_elements(); j++) { Array xp(2); xp[0] = u[j]; @@ -1325,15 +1350,7 @@ void ProcessVarOpti::FillQuadPoints() FaceSet::iterator it; for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) { - //this is a hack and needs to be fixed - //it really should take the get geom of the whole element and - //then pick the correct parts - ///////// - (*it)->m_faceNodes.clear(); - //////// - SpatialDomains::Geometry2DSharedPtr geom = - (*it)->GetGeom(m_mesh->m_spaceDim); - geom->FillGeom(); + SpatialDomains::Geometry2DSharedPtr geom = faceGeoms[(*it)->m_id]; StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); LibUtilities::PointsKey pkey(m_mesh->m_nummode, @@ -1355,8 +1372,7 @@ void ProcessVarOpti::FillQuadPoints() xmap->BwdTrans(coeffs1,yc); xmap->BwdTrans(coeffs2,zc); - for(int j = nq * (nq + 1) / 2 - (nq-2)*(nq-3) / 2; - j < u.num_elements(); j++) + for(int j = 3 + 3*(nq-2); j < u.num_elements(); j++) { Array xp(2); xp[0] = u[j]; @@ -1375,9 +1391,7 @@ void ProcessVarOpti::FillQuadPoints() { ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - SpatialDomains::GeometrySharedPtr geom = - el->GetGeom(m_mesh->m_spaceDim); - geom->FillGeom(); + SpatialDomains::GeometrySharedPtr geom = volGeoms[el->GetId()]; StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); LibUtilities::PointsKey pkey(m_mesh->m_nummode, -- GitLab From 5b71cc0ef4be289abb51441c446c42e21acab222 Mon Sep 17 00:00:00 2001 From: David Moxey Date: Fri, 20 May 2016 15:34:41 +0100 Subject: [PATCH 042/236] Change regularization parameter to a constant --- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 147 +++++++++++++----- 1 file changed, 108 insertions(+), 39 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp index 5d58d4b2f..555e9a5b9 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp @@ -287,8 +287,10 @@ void ProcessVarOpti::Process() tm->Wait(); } - cout << ctr << "\tResidual: " << res->val << endl; - if(ctr > maxIter) + EvaluateMesh(); + + cout << ctr << "\tResidual: " << res->val << " " << res->worstJac << endl; + if(ctr >= maxIter) break; } @@ -586,8 +588,15 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() { case eLinEl: { + const NekDouble nu = 0.45; + const NekDouble mu = 1.0 / 2.0 / (1.0+nu); + const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + for (int i = 0; i < nElmt; ++i) { + bool valid = true; + NekDouble jacDet[ptsHigh], trEtE[ptsHigh]; + for(int k = 0; k < ptsHigh; ++k) { NekDouble jacIdeal[DIM*DIM]; @@ -604,17 +613,28 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() } } } - NekDouble jacDet = JacDet(jacIdeal); - NekDouble trEtE = LinElasTrace(jacIdeal); - - const NekDouble nu = 0.45; - const NekDouble mu = 1.0 / 2.0 / (1.0+nu); - const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + jacDet[k] = JacDet(jacIdeal); + trEtE[k] = LinElasTrace(jacIdeal); + valid = valid ? jacDet[k] > 0.0 : false; + } - NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - NekDouble lsigma = log(sigma); - integral += quadW[k] * (data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE); + if (!valid) + { + for(int k = 0; k < ptsHigh; ++k) + { + NekDouble de = 1e-2; + NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + NekDouble lsigma = log(sigma); + integral += quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); + } + } + else + { + for(int k = 0; k < ptsHigh; ++k) + { + NekDouble lsigma = log(jacDet[k]); + integral += quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); + } } } break; @@ -622,8 +642,15 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() case eHypEl: { + const NekDouble nu = 0.45; + const NekDouble mu = 1.0 / 2.0 / (1.0+nu); + const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + for (int i = 0; i < nElmt; ++i) { + bool valid = true; + NekDouble jacDet[ptsHigh], I1[ptsHigh]; + for(int k = 0; k < ptsHigh; ++k) { NekDouble jacIdeal[DIM*DIM]; @@ -641,22 +668,32 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() } } - NekDouble I1 = 0.0; + jacDet[k] = JacDet(jacIdeal); + I1[k] = 0.0; for (int m = 0; m < DIM*DIM; ++m) { - I1 += jacIdeal[m]*jacIdeal[m]; + I1[k] += jacIdeal[m]*jacIdeal[m]; } + valid = valid ? jacDet[k] > 0.0 : false; + } - const NekDouble nu = 0.45; - const NekDouble mu = 1.0 / 2.0 / (1.0+nu); - const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); - - NekDouble jacDet = JacDet(jacIdeal); - //NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-1*1E-1 + 1E-1); - NekDouble de = 1e-1; - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - NekDouble lsigma = log(sigma); - integral += quadW[k]*fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1 - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); + if (!valid) + { + for(int k = 0; k < ptsHigh; ++k) + { + NekDouble de = 1e-1; + NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + NekDouble lsigma = log(sigma); + integral += quadW[k]*fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1[k] - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); + } + } + else + { + for(int k = 0; k < ptsHigh; ++k) + { + NekDouble lsigma = log(jacDet[k]); + integral += quadW[k]*fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1[k] - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); + } } } break; @@ -666,6 +703,9 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() { for (int i = 0; i < nElmt; ++i) { + bool valid = true; + NekDouble jacDet[ptsHigh], frob[ptsHigh]; + for(int k = 0; k < ptsHigh; ++k) { NekDouble jacIdeal[DIM*DIM]; @@ -683,17 +723,30 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() } } - NekDouble frob = 0.0; + frob[k] = 0.0; for (int m = 0; m < DIM*DIM; ++m) { - frob += jacIdeal[m] * jacIdeal[m]; + frob[k] += jacIdeal[m] * jacIdeal[m]; } - frob *= fabs(data[i]->maps[k][9]); - NekDouble jacDet = JacDet(jacIdeal); + jacDet[k] = JacDet(jacIdeal); + valid = valid ? jacDet[k] > 0.0 : false; + } - NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - integral += quadW[k]*(frob / DIM / pow(fabs(sigma), 2.0/DIM) -1.0); + if (!valid) + { + for(int k = 0; k < ptsHigh; ++k) + { + NekDouble de = 1e-2; + NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + integral += quadW[k] * fabs(data[i]->maps[k][9]) * (frob[k] / DIM / pow(fabs(sigma), 2.0/DIM) -1.0); + } + } + else + { + for(int k = 0; k < ptsHigh; ++k) + { + integral += quadW[k] * fabs(data[i]->maps[k][9]) * (frob[k] / DIM / pow(fabs(jacDet[k]), 2.0/DIM) -1.0); + } } } break; @@ -703,6 +756,9 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() { for (int i = 0; i < nElmt; ++i) { + bool valid = true; + NekDouble jacDet[ptsHigh], frob[ptsHigh]; + for(int k = 0; k < ptsHigh; ++k) { NekDouble jacIdeal[DIM*DIM]; @@ -720,17 +776,30 @@ NekDouble ProcessVarOpti::NodeOpti::GetFunctional() } } - NekDouble frob = 0.0; + frob[k] = 0.0; for (int m = 0; m < DIM*DIM; ++m) { - frob += jacIdeal[m] * jacIdeal[m]; + frob[k] += jacIdeal[m] * jacIdeal[m]; + } + jacDet[k] = JacDet(jacIdeal); + valid = valid ? jacDet[k] > 0.0 : false; + } + + if (!valid) + { + for(int k = 0; k < ptsHigh; ++k) + { + NekDouble de = 1e-2; + NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + integral += quadW[k]*fabs(data[i]->maps[k][9])*(frob[k] / sigma); + } + } + else + { + for(int k = 0; k < ptsHigh; ++k) + { + integral += quadW[k]*fabs(data[i]->maps[k][9])*(frob[k] / jacDet[k]); } - frob *= fabs(data[i]->maps[k][9]); - NekDouble jacDet = JacDet(jacIdeal); - NekDouble de = 1e-2; - //NekDouble de = fabs(data[i]->maps[k][9]) * sqrt(1E-3*1E-3 + 1E-3); - NekDouble sigma = 0.5*(jacDet + sqrt(jacDet*jacDet + 4.0*de*de)); - integral += quadW[k]*(frob / sigma); } } break; -- GitLab From 8b40bc82b96afb0d6c08a3f999c9ad4dafd443f8 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Sun, 26 Jun 2016 10:26:22 +0100 Subject: [PATCH 043/236] start of CADIO --- library/NekMeshUtils/MeshElements/Mesh.h | 4 ++ library/NekMeshUtils/MeshElements/Node.h | 12 ++++ .../NekMesh/OutputModules/OutputNekpp.cpp | 62 +++++++++++++++++++ utilities/NekMesh/OutputModules/OutputNekpp.h | 2 + 4 files changed, 80 insertions(+) diff --git a/library/NekMeshUtils/MeshElements/Mesh.h b/library/NekMeshUtils/MeshElements/Mesh.h index ac3d0b805..56ca08e5f 100644 --- a/library/NekMeshUtils/MeshElements/Mesh.h +++ b/library/NekMeshUtils/MeshElements/Mesh.h @@ -123,6 +123,10 @@ public: set > m_spherigonSurfs; /// List of face labels for composite annotation map m_faceLabels; + /// Whether the mesh has CAD + bool m_hasCAD; + /// CAD file ID + string m_CADId; /// Returns the total number of elements in the mesh with /// dimension expDim. diff --git a/library/NekMeshUtils/MeshElements/Node.h b/library/NekMeshUtils/MeshElements/Node.h index 8792b27ba..3f48886fe 100644 --- a/library/NekMeshUtils/MeshElements/Node.h +++ b/library/NekMeshUtils/MeshElements/Node.h @@ -279,6 +279,18 @@ public: std::vector > GetCADSurfs() { std::vector > lst; + std::map >::iterator c; + for (c = CADCurveList.begin(); c != CADCurveList.end(); s++) + { + lst.push_back( + std::pair(c->first, c->second.first)); + } + return lst; + } + + std::vector > GetCADCurves() + { + std::vector > lst; std::map > >:: iterator s; for (s = CADSurfList.begin(); s != CADSurfList.end(); s++) diff --git a/utilities/NekMesh/OutputModules/OutputNekpp.cpp b/utilities/NekMesh/OutputModules/OutputNekpp.cpp index 5e7a0dcc2..767766fe6 100644 --- a/utilities/NekMesh/OutputModules/OutputNekpp.cpp +++ b/utilities/NekMesh/OutputModules/OutputNekpp.cpp @@ -116,6 +116,11 @@ void OutputNekpp::Process() WriteXmlFaces(geomTag); WriteXmlElements(geomTag); WriteXmlCurves(geomTag); + if(m_mesh->m_hasCAD) + { + WriteXmlCADId(geomTag); + WriteXmlCAD(geomTag); + } WriteXmlComposites(geomTag); WriteXmlDomain(geomTag); WriteXmlExpansions(root); @@ -987,6 +992,63 @@ void OutputNekpp::WriteXmlCurves(TiXmlElement *pRoot) pRoot->LinkEndChild(curved); } +void OutputNekpp::WriteXmlCAD(TiXmlElement *pRoot) +{ + int vertcnt = 0; + int edgecnt = 0; + int facecnt = 0; + + TiXmlElement *cad = new TiXmlElement("CAD"); + + { + NodeSet::iterator it; + for (it = m_mesh->m_vertexSet.begin(); it != m_mesh->m_vertexSet.end(); + ++it) + { + if((*it)->GetNumCadCurve() > 0) + { + vector > cs = (*it)->GetCADCurves(); + for(int i = 0; i < cs.size(); i++) + { + NekDouble ti = (*it)->GetCADCurveInfo(cs[i].first); + TiXmlElement *v = new TiXmlElement("V"); + v->SetAttribute("ID", vertcnt++); + v->SetAttribute("VERTID", (*it)->m_id); + v->SetAttribute("TYPE", "CADCURVE"); + v->SetAttribute("CURVEID", cs[i].first); + TiXmlText *t = new TiXmlText(ti); + v->LinkEndChild(t); + curved->LinkEndChild(v); + } + } + + if((*it)->GetNumCADSurf() > 0) + { + vector > ss = (*it)->GetCADSurfs(); + for(int i = 0; i < ss.size(); i++) + { + NekDouble ti = (*it)->GetCADCurveInfo(ss[i].first); + TiXmlElement *v = new TiXmlElement("V"); + v->SetAttribute("ID", vertcnt++); + v->SetAttribute("VERTID", (*it)->m_id); + v->SetAttribute("TYPE", "CADCURVE"); + v->SetAttribute("CURVEID", ss[i].first); + TiXmlText *t = new TiXmlText(ti); + v->LinkEndChild(t); + curved->LinkEndChild(v); + } + } + } + } +} + +void OutputNekpp::WriteXmlCADId(TiXmlElement *pRoot) +{ + TiXmlElement *cadTag = new TiXmlElement("CADID"); + cadTag->LinkEndChild(new TiXmlText(" FILE =" + m_mesh->m_CADId + " ")); + pRoot->LinkEndChild(cadTag); +} + void OutputNekpp::WriteXmlComposites(TiXmlElement *pRoot) { TiXmlElement *verTag = new TiXmlElement("COMPOSITE"); diff --git a/utilities/NekMesh/OutputModules/OutputNekpp.h b/utilities/NekMesh/OutputModules/OutputNekpp.h index 936d2929a..4547a05d0 100644 --- a/utilities/NekMesh/OutputModules/OutputNekpp.h +++ b/utilities/NekMesh/OutputModules/OutputNekpp.h @@ -75,6 +75,8 @@ private: void WriteXmlCurves(TiXmlElement *pRoot); /// Writes the section of the XML file. void WriteXmlComposites(TiXmlElement *pRoot); + void WriteXmlCADId(TiXmlElement *pRoot); + void WriteXmlCAD(TiXmlElement *pRoot); /// Writes the section of the XML file. void WriteXmlDomain(TiXmlElement *pRoot); /// Writes the section of the XML file. -- GitLab From 343c7541b70f07d5184f216544a44b8b13e04ae2 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Sun, 26 Jun 2016 12:14:49 +0100 Subject: [PATCH 044/236] added cad string to xml output, needs input and grab from session reader --- library/NekMeshUtils/MeshElements/Node.h | 40 ++++++++-- utilities/NekMesh/InputModules/InputCAD.cpp | 3 + .../NekMesh/OutputModules/OutputNekpp.cpp | 79 +++++++++++++------ 3 files changed, 94 insertions(+), 28 deletions(-) diff --git a/library/NekMeshUtils/MeshElements/Node.h b/library/NekMeshUtils/MeshElements/Node.h index 3f48886fe..4f4afdf05 100644 --- a/library/NekMeshUtils/MeshElements/Node.h +++ b/library/NekMeshUtils/MeshElements/Node.h @@ -276,11 +276,11 @@ public: return search->second.second; } - std::vector > GetCADSurfs() + std::vector > GetCADCurves() { - std::vector > lst; + std::vector > lst; std::map >::iterator c; - for (c = CADCurveList.begin(); c != CADCurveList.end(); s++) + for (c = CADCurveList.begin(); c != CADCurveList.end(); c++) { lst.push_back( std::pair(c->first, c->second.first)); @@ -288,9 +288,9 @@ public: return lst; } - std::vector > GetCADCurves() + std::vector > GetCADSurfs() { - std::vector > lst; + std::vector > lst; std::map > >:: iterator s; for (s = CADSurfList.begin(); s != CADSurfList.end(); s++) @@ -321,6 +321,36 @@ public: std::pair >(su, uv); } + string GetCADString() + { + int made = 0; + stringstream ss; + ss << std::scientific << std::setprecision(8); + std::map >::iterator c; + for (c = CADCurveList.begin(); c != CADCurveList.end(); c++) + { + if(made > 0) + { + ss << " :"; + } + ss << " C " << c->first << " " << c->second.second; + made++; + } + std::map > >:: + iterator s; + for (s = CADSurfList.begin(); s != CADSurfList.end(); s++) + { + if(made > 0) + { + ss << " :"; + } + ss << " S " << s->first << " " << s->second.second[0] << + " " << s->second.second[1]; + made++; + } + return ss.str(); + } + #endif /// ID of node. diff --git a/utilities/NekMesh/InputModules/InputCAD.cpp b/utilities/NekMesh/InputModules/InputCAD.cpp index 0c551df34..59c41f7ab 100644 --- a/utilities/NekMesh/InputModules/InputCAD.cpp +++ b/utilities/NekMesh/InputModules/InputCAD.cpp @@ -126,6 +126,9 @@ void InputCAD::Process() "No surfaces selected to make boundary layer on"); } + m_mesh->m_hasCAD = true; + m_mesh->m_CADId = m_CADName; + CADSystemSharedPtr m_cad = MemoryManager::AllocateSharedPtr(m_CADName); diff --git a/utilities/NekMesh/OutputModules/OutputNekpp.cpp b/utilities/NekMesh/OutputModules/OutputNekpp.cpp index 767766fe6..0ba11e332 100644 --- a/utilities/NekMesh/OutputModules/OutputNekpp.cpp +++ b/utilities/NekMesh/OutputModules/OutputNekpp.cpp @@ -1005,47 +1005,80 @@ void OutputNekpp::WriteXmlCAD(TiXmlElement *pRoot) for (it = m_mesh->m_vertexSet.begin(); it != m_mesh->m_vertexSet.end(); ++it) { - if((*it)->GetNumCadCurve() > 0) + if((*it)->GetNumCadCurve() > 0 || (*it)->GetNumCADSurf() > 0) { - vector > cs = (*it)->GetCADCurves(); - for(int i = 0; i < cs.size(); i++) + TiXmlElement *v = new TiXmlElement("V"); + v->SetAttribute("ID", vertcnt++); + v->SetAttribute("VERTID", (*it)->m_id); + TiXmlText *t = new TiXmlText((*it)->GetCADString()); + v->LinkEndChild(t); + cad->LinkEndChild(v); + } + } + } + + { + EdgeSet::iterator it; + for (it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); + ++it) + { + if((*it)->m_edgeNodes.size() == 0) + { + continue; + } + + if((*it)->m_edgeNodes[0]->GetNumCadCurve() > 0 || + (*it)->m_edgeNodes[0]->GetNumCADSurf() > 0) + { + for(int i = 0; i < (*it)->m_edgeNodes.size(); i++) { - NekDouble ti = (*it)->GetCADCurveInfo(cs[i].first); - TiXmlElement *v = new TiXmlElement("V"); - v->SetAttribute("ID", vertcnt++); - v->SetAttribute("VERTID", (*it)->m_id); - v->SetAttribute("TYPE", "CADCURVE"); - v->SetAttribute("CURVEID", cs[i].first); - TiXmlText *t = new TiXmlText(ti); + TiXmlElement *v = new TiXmlElement("E"); + v->SetAttribute("ID", edgecnt++); + v->SetAttribute("EDGEID", (*it)->m_id); + v->SetAttribute("NUMNODE", (*it)->m_edgeNodes.size()); + v->SetAttribute("NODE", i+1); + TiXmlText *t = new TiXmlText((*it)->m_edgeNodes[i]->GetCADString()); v->LinkEndChild(t); - curved->LinkEndChild(v); + cad->LinkEndChild(v); } } + } + } + + { + FaceSet::iterator it; + for (it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); + ++it) + { + if((*it)->m_faceNodes.size() == 0) + { + continue; + } - if((*it)->GetNumCADSurf() > 0) + if((*it)->m_faceNodes[0]->GetNumCADSurf() > 0) { - vector > ss = (*it)->GetCADSurfs(); - for(int i = 0; i < ss.size(); i++) + for(int i = 0; i < (*it)->m_faceNodes.size(); i++) { - NekDouble ti = (*it)->GetCADCurveInfo(ss[i].first); - TiXmlElement *v = new TiXmlElement("V"); - v->SetAttribute("ID", vertcnt++); - v->SetAttribute("VERTID", (*it)->m_id); - v->SetAttribute("TYPE", "CADCURVE"); - v->SetAttribute("CURVEID", ss[i].first); - TiXmlText *t = new TiXmlText(ti); + TiXmlElement *v = new TiXmlElement("F"); + v->SetAttribute("ID", facecnt++); + v->SetAttribute("FACEID", (*it)->m_id); + v->SetAttribute("NUMNODE", (*it)->m_faceNodes.size()); + v->SetAttribute("NODE", i+1); + TiXmlText *t = new TiXmlText((*it)->m_faceNodes[i]->GetCADString()); v->LinkEndChild(t); - curved->LinkEndChild(v); + cad->LinkEndChild(v); } } } } + + pRoot->LinkEndChild(cad); } void OutputNekpp::WriteXmlCADId(TiXmlElement *pRoot) { TiXmlElement *cadTag = new TiXmlElement("CADID"); - cadTag->LinkEndChild(new TiXmlText(" FILE =" + m_mesh->m_CADId + " ")); + cadTag->LinkEndChild(new TiXmlText(" FILE=" + m_mesh->m_CADId + " ")); pRoot->LinkEndChild(cadTag); } -- GitLab From b0daaa0a83bf0a6c5529399fa8f61782c3bd105f Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Sun, 26 Jun 2016 14:50:49 +0100 Subject: [PATCH 045/236] basic read --- library/SpatialDomains/MeshGraph.cpp | 123 +++++++++--------- utilities/NekMesh/InputModules/InputNekpp.cpp | 22 ++++ .../NekMesh/OutputModules/OutputNekpp.cpp | 2 +- 3 files changed, 84 insertions(+), 63 deletions(-) diff --git a/library/SpatialDomains/MeshGraph.cpp b/library/SpatialDomains/MeshGraph.cpp index 8d64f018d..6eb07f7a9 100644 --- a/library/SpatialDomains/MeshGraph.cpp +++ b/library/SpatialDomains/MeshGraph.cpp @@ -391,9 +391,9 @@ namespace Nektar } string IsCompressed; - element->QueryStringAttribute("COMPRESSED",&IsCompressed); + element->QueryStringAttribute("COMPRESSED",&IsCompressed); - if(IsCompressed.size()) + if(IsCompressed.size()) { if(boost::iequals(IsCompressed, LibUtilities::CompressData::GetCompressString())) @@ -445,27 +445,27 @@ namespace Nektar else { TiXmlElement *vertex = element->FirstChildElement("V"); - + int indx; int nextVertexNumber = -1; - + while (vertex) { nextVertexNumber++; - + TiXmlAttribute *vertexAttr = vertex->FirstAttribute(); std::string attrName(vertexAttr->Name()); - + ASSERTL0(attrName == "ID", (std::string("Unknown attribute name: ") + attrName).c_str()); - + err = vertexAttr->QueryIntValue(&indx); ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID."); // Now read body of vertex std::string vertexBodyStr; - + TiXmlNode *vertexBody = vertex->FirstChild(); - + while (vertexBody) { // Accumulate all non-comment body data. @@ -474,26 +474,26 @@ namespace Nektar vertexBodyStr += vertexBody->ToText()->Value(); vertexBodyStr += " "; } - + vertexBody = vertexBody->NextSibling(); } - + ASSERTL0(!vertexBodyStr.empty(), "Vertex definitions must contain vertex data."); - + // Get vertex data from the data string. NekDouble xval, yval, zval; std::istringstream vertexDataStrm(vertexBodyStr.c_str()); - + try { while(!vertexDataStrm.fail()) { vertexDataStrm >> xval >> yval >> zval; - + xval = xval*xscale + xmove; yval = yval*yscale + ymove; zval = zval*zscale + zmove; - + // Need to check it here because we may not be // good after the read indicating that there // was nothing to read. @@ -509,7 +509,7 @@ namespace Nektar { ASSERTL0(false, "Unable to read VERTEX data."); } - + vertex = vertex->NextSiblingElement("V"); } } @@ -1151,7 +1151,6 @@ namespace Nektar } } - /** * */ @@ -1259,9 +1258,9 @@ namespace Nektar } string IsCompressed; - field->QueryStringAttribute("COMPRESSED",&IsCompressed); - - if(IsCompressed.size()) + field->QueryStringAttribute("COMPRESSED",&IsCompressed); + + if(IsCompressed.size()) { ASSERTL0(boost::iequals(IsCompressed, LibUtilities::CompressData::GetCompressString()), @@ -1464,24 +1463,24 @@ namespace Nektar /// All curves are of the form: " ... ", with ? being an /// element type (either E or F). - + TiXmlElement *edgelement = field->FirstChildElement("E"); - + int edgeindx, edgeid; int nextEdgeNumber = -1; - + while(edgelement) { /// These should be ordered. nextEdgeNumber++; - + std::string edge(edgelement->ValueStr()); ASSERTL0(edge == "E", (std::string("Unknown 3D curve type:") + edge).c_str()); - + /// Read id attribute. err = edgelement->QueryIntAttribute("ID", &edgeindx); ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute ID."); - + /// Read edge id attribute. err = edgelement->QueryIntAttribute("EDGEID", &edgeid); ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute EDGEID."); @@ -1489,7 +1488,7 @@ namespace Nektar /// Read text edgelement description. std::string elementStr; TiXmlNode* elementChild = edgelement->FirstChild(); - + while(elementChild) { // Accumulate all non-comment element data @@ -1500,9 +1499,9 @@ namespace Nektar } elementChild = elementChild->NextSibling(); } - + ASSERTL0(!elementStr.empty(), "Unable to read curve description body."); - + /// Parse out the element components corresponding to type of element. if (edge == "E") { @@ -1510,20 +1509,20 @@ namespace Nektar // Determine the points type std::string typeStr = edgelement->Attribute("TYPE"); ASSERTL0(!typeStr.empty(), "TYPE must be specified in " "points definition"); - + LibUtilities::PointsType type; const std::string* begStr = LibUtilities::kPointsTypeStr; const std::string* endStr = LibUtilities::kPointsTypeStr + LibUtilities::SIZE_PointsType; const std::string* ptsStr = std::find(begStr, endStr, typeStr); - + ASSERTL0(ptsStr != endStr, "Invalid points type."); type = (LibUtilities::PointsType)(ptsStr - begStr); - + //Determine the number of points err = edgelement->QueryIntAttribute("NUMPOINTS", &numPts); ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute NUMPOINTS."); CurveSharedPtr curve(MemoryManager::AllocateSharedPtr(edgeid, type)); - + // Read points (x, y, z) NekDouble xval, yval, zval; std::istringstream elementDataStrm(elementStr.c_str()); @@ -1532,34 +1531,34 @@ namespace Nektar while(!elementDataStrm.fail()) { elementDataStrm >> xval >> yval >> zval; - + xval = xval*xscale + xmove; yval = yval*yscale + ymove; zval = zval*zscale + zmove; - + // Need to check it here because we may not be // good after the read indicating that there // was nothing to read. if (!elementDataStrm.fail()) { PointGeomSharedPtr vert(MemoryManager::AllocateSharedPtr(m_meshDimension, edgeindx, xval, yval, zval)); - + curve->m_points.push_back(vert); } - + } } catch(...) { NEKERROR(ErrorUtil::efatal, (std::string("Unable to read curve data for EDGE: ") + elementStr).c_str()); - + } - + ASSERTL0(curve->m_points.size() == numPts,"Number of points specificed by attribute NUMPOINTS is different from number of points in list"); m_curvedEdges[edgeid] = curve; - + edgelement = edgelement->NextSiblingElement("E"); } // end if-loop @@ -1568,24 +1567,24 @@ namespace Nektar TiXmlElement *facelement = field->FirstChildElement("F"); int faceindx, faceid; - + while(facelement) { std::string face(facelement->ValueStr()); ASSERTL0(face == "F", (std::string("Unknown 3D curve type: ") + face).c_str()); - + /// Read id attribute. err = facelement->QueryIntAttribute("ID", &faceindx); ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute ID."); - + /// Read face id attribute. err = facelement->QueryIntAttribute("FACEID", &faceid); ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute FACEID."); - + /// Read text face element description. std::string elementStr; TiXmlNode* elementChild = facelement->FirstChild(); - + while(elementChild) { // Accumulate all non-comment element data @@ -1596,9 +1595,9 @@ namespace Nektar } elementChild = elementChild->NextSibling(); } - + ASSERTL0(!elementStr.empty(), "Unable to read curve description body."); - + /// Parse out the element components corresponding to type of element. if(face == "F") { @@ -1608,26 +1607,26 @@ namespace Nektar const std::string* begStr = LibUtilities::kPointsTypeStr; const std::string* endStr = LibUtilities::kPointsTypeStr + LibUtilities::SIZE_PointsType; const std::string* ptsStr = std::find(begStr, endStr, typeStr); - + ASSERTL0(ptsStr != endStr, "Invalid points type."); type = (LibUtilities::PointsType)(ptsStr - begStr); - + std::string numptsStr = facelement->Attribute("NUMPOINTS"); ASSERTL0(!numptsStr.empty(), "NUMPOINTS must be specified in points definition"); int numPts=0; std::stringstream s; s << numptsStr; s >> numPts; - + CurveSharedPtr curve(MemoryManager::AllocateSharedPtr(faceid, type)); - + ASSERTL0(numPts >= 3, "NUMPOINTS for face must be greater than 2"); - + if(numPts == 3) { ASSERTL0(ptsStr != endStr, "Invalid points type."); } - + // Read points (x, y, z) NekDouble xval, yval, zval; std::istringstream elementDataStrm(elementStr.c_str()); @@ -1655,9 +1654,9 @@ namespace Nektar + elementStr).c_str()); } m_curvedFaces[faceid] = curve; - + facelement = facelement->NextSiblingElement("F"); - + } // end if-loop } // end while-loop @@ -3250,7 +3249,7 @@ namespace Nektar } } - /** + /** * \brief Reset all points keys to have expansion order of \a * nmodes. we keep the point distribution the same and make * the number of points the same difference from the number @@ -3264,19 +3263,19 @@ namespace Nektar for(it = m_expansionMapShPtrMap.begin(); it != m_expansionMapShPtrMap.end(); ++it) { ExpansionMapIter expIt; - + for(expIt = it->second->begin(); expIt != it->second->end(); ++expIt) { for(int i = 0; i < expIt->second->m_basisKeyVector.size(); ++i) { - LibUtilities::BasisKey bkeyold = expIt->second->m_basisKeyVector[i]; - + LibUtilities::BasisKey bkeyold = expIt->second->m_basisKeyVector[i]; + int npts = nmodes + (bkeyold.GetNumPoints() - bkeyold.GetNumModes()); - + const LibUtilities::PointsKey pkey(npts,bkeyold.GetPointsType()); LibUtilities::BasisKey bkeynew(bkeyold.GetBasisType(),nmodes, pkey); - expIt->second->m_basisKeyVector[i] = bkeynew; - + expIt->second->m_basisKeyVector[i] = bkeynew; + } } } diff --git a/utilities/NekMesh/InputModules/InputNekpp.cpp b/utilities/NekMesh/InputModules/InputNekpp.cpp index 2229e1b84..3f5a0c7fc 100644 --- a/utilities/NekMesh/InputModules/InputNekpp.cpp +++ b/utilities/NekMesh/InputModules/InputNekpp.cpp @@ -37,6 +37,8 @@ #include using namespace std; +#include + #include #include #include "InputNekpp.h" @@ -334,6 +336,26 @@ void InputNekpp::Process() SpatialDomains::ExpansionMap em = graph->GetExpansions(); m_mesh->m_nummode = em[0]->m_basisKeyVector[1].GetNumPoints(); + if(pSession->DefinesElement("NEKTAR/GEOMETRY/CADID")) + { + m_mesh->m_hasCAD = true; + TiXmlElement* id = pSession->GetElement("NEKTAR/GEOMETRY/CADID"); + + id->QueryStringAttribute("NAME",&m_mesh->m_CADId); + } + + if(m_mesh->m_CADId && !pSession->DefinesElement("NEKTAR/GEOMETRY/CAD")) + { + ASSERTL0(false, "CAD file but no data"); + } + + if(pSession->DefinesElement("NEKTAR/GEOMETRY/CAD")) + { + TiXmlElement* cad = pSession->GetElement("NEKTAR/GEOMETRY/CAD"); + } + + exit(-1); + ProcessEdges(false); ProcessFaces(false); ProcessComposites(); diff --git a/utilities/NekMesh/OutputModules/OutputNekpp.cpp b/utilities/NekMesh/OutputModules/OutputNekpp.cpp index 0ba11e332..ed35fdea4 100644 --- a/utilities/NekMesh/OutputModules/OutputNekpp.cpp +++ b/utilities/NekMesh/OutputModules/OutputNekpp.cpp @@ -1078,7 +1078,7 @@ void OutputNekpp::WriteXmlCAD(TiXmlElement *pRoot) void OutputNekpp::WriteXmlCADId(TiXmlElement *pRoot) { TiXmlElement *cadTag = new TiXmlElement("CADID"); - cadTag->LinkEndChild(new TiXmlText(" FILE=" + m_mesh->m_CADId + " ")); + cadTag->SetAttribute("NAME", m_mesh->m_CADId); pRoot->LinkEndChild(cadTag); } -- GitLab From cb75048f44195b9abfcb0b5d578c70c5e41d2e62 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 27 Jun 2016 12:47:57 +0100 Subject: [PATCH 046/236] hacky CAD I/O in mesh convert : --- library/NekMeshUtils/MeshElements/Mesh.h | 7 + library/NekMeshUtils/MeshElements/Node.h | 28 +-- utilities/NekMesh/InputModules/InputNekpp.cpp | 224 +++++++++++++++++- .../NekMesh/OutputModules/OutputNekpp.cpp | 45 +++- 4 files changed, 275 insertions(+), 29 deletions(-) diff --git a/library/NekMeshUtils/MeshElements/Mesh.h b/library/NekMeshUtils/MeshElements/Mesh.h index 56ca08e5f..a87ba5b51 100644 --- a/library/NekMeshUtils/MeshElements/Mesh.h +++ b/library/NekMeshUtils/MeshElements/Mesh.h @@ -40,6 +40,10 @@ #include #include +#ifdef NEKTAR_USE_MESHGEN +#include +#endif + namespace Nektar { namespace NekMeshUtils @@ -127,6 +131,9 @@ public: bool m_hasCAD; /// CAD file ID string m_CADId; +#ifdef NEKTAR_USE_MESHGEN + CADSystemSharedPtr m_cad; +#endif /// Returns the total number of elements in the mesh with /// dimension expDim. diff --git a/library/NekMeshUtils/MeshElements/Node.h b/library/NekMeshUtils/MeshElements/Node.h index 4f4afdf05..43f941d92 100644 --- a/library/NekMeshUtils/MeshElements/Node.h +++ b/library/NekMeshUtils/MeshElements/Node.h @@ -321,34 +321,28 @@ public: std::pair >(su, uv); } - string GetCADString() + vector GetCADString() { - int made = 0; - stringstream ss; - ss << std::scientific << std::setprecision(8); + vector ret; std::map >::iterator c; for (c = CADCurveList.begin(); c != CADCurveList.end(); c++) { - if(made > 0) - { - ss << " :"; - } - ss << " C " << c->first << " " << c->second.second; - made++; + stringstream ss; + ss << std::scientific << std::setprecision(8); + ss << "C " << c->first << " " << c->second.second << " " << 0.0; + ret.push_back(ss.str()); } std::map > >:: iterator s; for (s = CADSurfList.begin(); s != CADSurfList.end(); s++) { - if(made > 0) - { - ss << " :"; - } - ss << " S " << s->first << " " << s->second.second[0] << + stringstream ss; + ss << std::scientific << std::setprecision(8); + ss << "S " << s->first << " " << s->second.second[0] << " " << s->second.second[1]; - made++; + ret.push_back(ss.str()); } - return ss.str(); + return ret; } #endif diff --git a/utilities/NekMesh/InputModules/InputNekpp.cpp b/utilities/NekMesh/InputModules/InputNekpp.cpp index 3f5a0c7fc..f6c58acad 100644 --- a/utilities/NekMesh/InputModules/InputNekpp.cpp +++ b/utilities/NekMesh/InputModules/InputNekpp.cpp @@ -38,6 +38,11 @@ using namespace std; #include +#include + +#ifdef NEKTAR_USE_MESHGEN +#include +#endif #include #include @@ -336,29 +341,244 @@ void InputNekpp::Process() SpatialDomains::ExpansionMap em = graph->GetExpansions(); m_mesh->m_nummode = em[0]->m_basisKeyVector[1].GetNumPoints(); +#ifdef NEKTAR_USE_MESHGEN + if(pSession->DefinesElement("NEKTAR/GEOMETRY/CADID")) { m_mesh->m_hasCAD = true; TiXmlElement* id = pSession->GetElement("NEKTAR/GEOMETRY/CADID"); id->QueryStringAttribute("NAME",&m_mesh->m_CADId); + + m_mesh->m_cad = + MemoryManager::AllocateSharedPtr(m_mesh->m_CADId); + ASSERTL0(m_mesh->m_cad->LoadCAD(), "Failed to load CAD"); } - if(m_mesh->m_CADId && !pSession->DefinesElement("NEKTAR/GEOMETRY/CAD")) + if(m_mesh->m_hasCAD && !pSession->DefinesElement("NEKTAR/GEOMETRY/CAD")) { ASSERTL0(false, "CAD file but no data"); } + map > vertToString; + map, vector > edgeToString; + map, vector > faceToString; + if(pSession->DefinesElement("NEKTAR/GEOMETRY/CAD")) { + int err; + TiXmlElement* cad = pSession->GetElement("NEKTAR/GEOMETRY/CAD"); + + TiXmlElement *vertex = cad->FirstChildElement("V"); + + int vid; + + while(vertex) + { + std::string vert(vertex->ValueStr()); + ASSERTL0(vert == "V", (std::string("Unknown CAD type:") + vert).c_str()); + + /// Read edge id attribute. + err = vertex->QueryIntAttribute("VERTID", &vid); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute VERTID."); + + /// Read text edgelement description. + TiXmlNode* elementChild = vertex->FirstChild(); + + vector strs; + string str = elementChild->ToText()->ValueStr(); + boost::split(strs, str, boost::is_any_of(":")); + + vertToString[vid] = strs; + + vertex = vertex->NextSiblingElement("V"); + } + + TiXmlElement *edge = cad->FirstChildElement("E"); + + int eid; + int node; + + while(edge) + { + std::string e(edge->ValueStr()); + ASSERTL0(e == "E", (std::string("Unknown CAD type:") + e).c_str()); + + /// Read edge id attribute. + err = edge->QueryIntAttribute("EDGEID", &eid); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute EDGEID."); + + /// Read edge node attribute. + err = edge->QueryIntAttribute("NODE", &node); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute EDGEID."); + + /// Read text edgelement description. + TiXmlNode* elementChild = edge->FirstChild(); + + vector strs; + string str = elementChild->ToText()->ValueStr(); + boost::split(strs, str, boost::is_any_of(":")); + + edgeToString[pair(eid,node)] = strs; + + edge = edge->NextSiblingElement("E"); + } + + TiXmlElement *face = cad->FirstChildElement("F"); + + int fid; + + while(edge) + { + std::string f(edge->ValueStr()); + ASSERTL0(f == "F", (std::string("Unknown CAD type:") + f).c_str()); + + /// Read edge id attribute. + err = face->QueryIntAttribute("FACEID", &fid); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute FACEID."); + + /// Read edge node attribute. + err = face->QueryIntAttribute("NODE", &node); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute FACEID."); + + /// Read text edgelement description. + TiXmlNode* elementChild = face->FirstChild(); + + vector strs; + string str = elementChild->ToText()->ValueStr(); + boost::split(strs, str, boost::is_any_of(":")); + + faceToString[pair(fid,node)] = strs; + + face = face->NextSiblingElement("F"); + } } - exit(-1); +#endif ProcessEdges(false); ProcessFaces(false); ProcessComposites(); + +#ifdef NEKTAR_USE_MESHGEN + + map >::iterator vsit; + map, vector >::iterator esit; + map, vector >::iterator fsit; + + { + NodeSet::iterator it; + for(it = m_mesh->m_vertexSet.begin(); it != m_mesh->m_vertexSet.end(); + it++) + { + vsit = vertToString.find((*it)->m_id); + if(vsit != vertToString.end()) + { + for(int i = 0; i < vsit->second.size(); i++) + { + istringstream iss(vsit->second[i]); + string t; + int id; + NekDouble u, v; + iss >> t >> id >> u >> v; + if(t == "C") + { + (*it)->SetCADCurve(id,m_mesh->m_cad->GetCurve(id),u); + } + else if(t == "S") + { + Array uv(2); + uv[0] = u; + uv[1] = v; + (*it)->SetCADSurf(id,m_mesh->m_cad->GetSurf(id),uv); + } + else + { + ASSERTL0(false,"unsure on type"); + } + } + } + } + } + + { + EdgeSet::iterator it; + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); + it++) + { + for(int j = 0; j < (*it)->m_edgeNodes.size(); j++) + { + esit = edgeToString.find(pair((*it)->m_id,j)); + if(esit != edgeToString.end()) + { + for(int i = 0; i < esit->second.size(); i++) + { + istringstream iss(esit->second[i]); + string t; + int id; + NekDouble u, v; + iss >> t >> id >> u >> v; + if(t == "C") + { + (*it)->m_edgeNodes[j]->SetCADCurve(id,m_mesh->m_cad->GetCurve(id),u); + } + else if(t == "S") + { + Array uv(2); + uv[0] = u; + uv[1] = v; + (*it)->m_edgeNodes[j]->SetCADSurf(id,m_mesh->m_cad->GetSurf(id),uv); + } + else + { + ASSERTL0(false,"unsure on type"); + } + } + } + } + } + } + + { + FaceSet::iterator it; + for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); + it++) + { + for(int j = 0; j < (*it)->m_faceNodes.size(); j++) + { + fsit = faceToString.find(pair((*it)->m_id,j)); + if(fsit != faceToString.end()) + { + for(int i = 0; i < fsit->second.size(); i++) + { + istringstream iss(fsit->second[i]); + string t; + int id; + NekDouble u, v; + iss >> t >> id >> u >> v; + if(t == "C") + { + (*it)->m_faceNodes[j]->SetCADCurve(id,m_mesh->m_cad->GetCurve(id),u); + } + else if(t == "S") + { + Array uv(2); + uv[0] = u; + uv[1] = v; + (*it)->m_faceNodes[j]->SetCADSurf(id,m_mesh->m_cad->GetSurf(id),uv); + } + else + { + ASSERTL0(false,"unsure on type"); + } + } + } + } + } + } +#endif + } } } diff --git a/utilities/NekMesh/OutputModules/OutputNekpp.cpp b/utilities/NekMesh/OutputModules/OutputNekpp.cpp index ed35fdea4..535ced287 100644 --- a/utilities/NekMesh/OutputModules/OutputNekpp.cpp +++ b/utilities/NekMesh/OutputModules/OutputNekpp.cpp @@ -1010,8 +1010,17 @@ void OutputNekpp::WriteXmlCAD(TiXmlElement *pRoot) TiXmlElement *v = new TiXmlElement("V"); v->SetAttribute("ID", vertcnt++); v->SetAttribute("VERTID", (*it)->m_id); - TiXmlText *t = new TiXmlText((*it)->GetCADString()); - v->LinkEndChild(t); + vector str = (*it)->GetCADString(); + for(int i = 0; i < str.size(); i++) + { + TiXmlText *t = new TiXmlText(str[i]); + v->LinkEndChild(t); + if(i != str.size() - 1) + { + TiXmlText *t = new TiXmlText(":"); + v->LinkEndChild(t); + } + } cad->LinkEndChild(v); } } @@ -1035,10 +1044,18 @@ void OutputNekpp::WriteXmlCAD(TiXmlElement *pRoot) TiXmlElement *v = new TiXmlElement("E"); v->SetAttribute("ID", edgecnt++); v->SetAttribute("EDGEID", (*it)->m_id); - v->SetAttribute("NUMNODE", (*it)->m_edgeNodes.size()); - v->SetAttribute("NODE", i+1); - TiXmlText *t = new TiXmlText((*it)->m_edgeNodes[i]->GetCADString()); - v->LinkEndChild(t); + v->SetAttribute("NODE", i); + vector str = (*it)->m_edgeNodes[i]->GetCADString(); + for(int i = 0; i < str.size(); i++) + { + TiXmlText *t = new TiXmlText(str[i]); + v->LinkEndChild(t); + if(i != str.size() - 1) + { + TiXmlText *t = new TiXmlText(":"); + v->LinkEndChild(t); + } + } cad->LinkEndChild(v); } } @@ -1062,10 +1079,18 @@ void OutputNekpp::WriteXmlCAD(TiXmlElement *pRoot) TiXmlElement *v = new TiXmlElement("F"); v->SetAttribute("ID", facecnt++); v->SetAttribute("FACEID", (*it)->m_id); - v->SetAttribute("NUMNODE", (*it)->m_faceNodes.size()); - v->SetAttribute("NODE", i+1); - TiXmlText *t = new TiXmlText((*it)->m_faceNodes[i]->GetCADString()); - v->LinkEndChild(t); + v->SetAttribute("NODE", i); + vector str = (*it)->m_faceNodes[i]->GetCADString(); + for(int i = 0; i < str.size(); i++) + { + TiXmlText *t = new TiXmlText(str[i]); + v->LinkEndChild(t); + if(i != str.size() - 1) + { + TiXmlText *t = new TiXmlText(":"); + v->LinkEndChild(t); + } + } cad->LinkEndChild(v); } } -- GitLab From 1038e7248798ba371262fadc603c1ba965850b26 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 27 Jun 2016 16:23:56 +0100 Subject: [PATCH 047/236] replaced a lot of templating with polymorphic classes in preperation of CAD sliding nodes --- utilities/NekMesh/CMakeLists.txt | 8 +- .../NekMesh/ProcessModules/ProcessVarOpti.cpp | 1709 ----------------- .../ProcessVarOpti/ProcessVarOpti.cpp | 302 +++ .../{ => ProcessVarOpti}/ProcessVarOpti.h | 64 +- 4 files changed, 327 insertions(+), 1756 deletions(-) delete mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp create mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp rename utilities/NekMesh/ProcessModules/{ => ProcessVarOpti}/ProcessVarOpti.h (79%) diff --git a/utilities/NekMesh/CMakeLists.txt b/utilities/NekMesh/CMakeLists.txt index b6091bc3f..8395e2cb3 100644 --- a/utilities/NekMesh/CMakeLists.txt +++ b/utilities/NekMesh/CMakeLists.txt @@ -21,7 +21,9 @@ SET(NekMeshHeaders ProcessModules/ProcessSpherigon.h ProcessModules/ProcessTetSplit.h ProcessModules/ProcessOptiExtract.h - ProcessModules/ProcessVarOpti.h + ProcessModules/ProcessVarOpti/ProcessVarOpti.h + ProcessModules/ProcessVarOpti/NodeOpti.h + ProcessModules/ProcessVarOpti/NodeOptiJob.h ) SET(NekMeshSources @@ -48,7 +50,9 @@ SET(NekMeshSources ProcessModules/ProcessSpherigon.cpp ProcessModules/ProcessTetSplit.cpp ProcessModules/ProcessOptiExtract.cpp - ProcessModules/ProcessVarOpti.cpp + ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp + ProcessModules/ProcessVarOpti/Utils.cpp + ProcessModules/ProcessVarOpti/NodeOpti.cpp ) IF (NEKTAR_USE_CCM) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp deleted file mode 100644 index 555e9a5b9..000000000 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.cpp +++ /dev/null @@ -1,1709 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// File: ProcessJac.cpp -// -// For more information, please see: http://www.nektar.info/ -// -// The MIT License -// -// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), -// Department of Aeronautics, Imperial College London (UK), and Scientific -// Computing and Imaging Institute, University of Utah (USA). -// -// License for the specific language governing rights and limitations under -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// Description: Calculate Jacobians of elements. -// -//////////////////////////////////////////////////////////////////////////////// - -#include - -#include -#include "ProcessVarOpti.h" - -#include - -#include -#include -#include -#include - -#include -#include - -using namespace std; -using namespace Nektar::NekMeshUtils; - -namespace Nektar -{ -namespace Utilities -{ - -boost::mutex mtx; -int ptsLow; -int ptsHigh; -NekMatrix VdmD[3]; -NekVector quadW; -optimiser opti; - -ModuleKey ProcessVarOpti::className = GetModuleFactory().RegisterCreatorFunction( - ModuleKey(eProcessModule, "varopti"), - ProcessVarOpti::create, - "Optimise mesh locations."); - -ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) -{ - m_config["linearelastic"] = - ConfigOption(true, "", "Optimise for linear elasticity"); - m_config["winslow"] = - ConfigOption(true, "", "Optimise for winslow"); - m_config["roca"] = - ConfigOption(true, "", "Optimise for roca method"); - m_config["hyperelastic"] = - ConfigOption(true, "", "Optimise for hyper elasticity"); - m_config["numthreads"] = - ConfigOption(false, "1", "Number of threads"); - m_config["nq"] = - ConfigOption(false, "0", "Number of quad points"); - m_config["stats"] = - ConfigOption(false, "", "Write a file with list of scaled jacobians"); - m_config["restol"] = - ConfigOption(false, "1e-6", "Tolerance criterion"); - m_config["maxiter"] = - ConfigOption(false, "500", "Maximum number of iterations"); -} - -ProcessVarOpti::~ProcessVarOpti() -{ -} - -void ProcessVarOpti::Process() -{ - if (m_mesh->m_verbose) - { - cout << "ProcessVarOpti: Optimising... " << endl; - } - - if(m_config["linearelastic"].beenSet) - { - opti = eLinEl; - } - else if(m_config["winslow"].beenSet) - { - opti = eWins; - } - else if(m_config["roca"].beenSet) - { - opti = eRoca; - } - else if(m_config["hyperelastic"].beenSet) - { - opti = eHypEl; - } - else - { - ASSERTL0(false,"not opti type set"); - } - - const int maxIter = m_config["maxiter"].as(); - const NekDouble restol = m_config["restol"].as(); - - m_mesh->m_nummode = m_config["nq"].as(); - - ASSERTL0(m_mesh->m_nummode > 2,"not specified high-order"); - - if(m_mesh->m_expDim == 2 && m_mesh->m_spaceDim == 3) - { - ASSERTL0(false,"cannot deal with manifolds"); - } - - res = boost::shared_ptr(new Residual); - res->val = 1.0; - - FillQuadPoints(); - - //build Vandermonde information - switch (m_mesh->m_spaceDim) - { - case 2: - { - ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)/2; - - LibUtilities::PointsKey pkey1(m_mesh->m_nummode, - LibUtilities::eNodalTriElec); - LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, - LibUtilities::eNodalTriSPI); - Array u1, v1, u2, v2; - - LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); - LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2); - NekVector U1(u1), V1(v1); - NekVector U2(u2), V2(v2); - ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); - - NekMatrix interp = LibUtilities::GetInterpolationMatrix(U1, V1, U2, V2); - - NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); - NekMatrix VandermondeI = Vandermonde; - VandermondeI.Invert(); - VdmD[0] = interp * ( - LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI); - VdmD[1] = interp * ( - LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI); - //quadW = LibUtilities::MakeQuadratureWeights(U2,V1); - Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); - NekVector quadWi(qds); - quadW = quadWi; - } - break; - case 3: - { - ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)*(m_mesh->m_nummode+2)/6; - LibUtilities::PointsKey pkey1(m_mesh->m_nummode, - LibUtilities::eNodalTetElec); - LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, - LibUtilities::eNodalTetSPI); - Array u1, v1, u2, v2, w1, w2; - LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1, w1); - LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2, w2); - NekVector U1(u1), V1(v1), W1(w1); - NekVector U2(u2), V2(v2), W2(w2); - ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); - - NekMatrix interp = - LibUtilities::GetTetInterpolationMatrix(U1, V1, W1, - U2, V2, W2); - - NekMatrix Vandermonde = - LibUtilities::GetTetVandermonde(U1,V1,W1); - NekMatrix VandermondeI = Vandermonde; - VandermondeI.Invert(); - VdmD[0] = interp * ( - LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI); - VdmD[1] = interp * ( - LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI); - VdmD[2] = interp * ( - LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI); - Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); - NekVector quadWi(qds); - quadW = quadWi; - } - } - - GetElementMap(); - - vector > freenodes = GetColouredNodes(); - vector > optiNodes; - - for(int i = 0; i < freenodes.size(); i++) - { - vector ns; - for(int j = 0; j < freenodes[i].size(); j++) - { - NodeElMap::iterator it = nodeElMap.find(freenodes[i][j]->m_id); - ASSERTL0(it != nodeElMap.end(), "could not find"); - ns.push_back(NodeOpti(freenodes[i][j],it->second,res)); - } - optiNodes.push_back(ns); - } - - int nset = optiNodes.size(); - int p = 0; - int mn = numeric_limits::max(); - int mx = 0; - for(int i = 0; i < nset; i++) - { - p += optiNodes[i].size(); - mn = min(mn, int(optiNodes[i].size())); - mx = max(mx, int(optiNodes[i].size())); - } - - cout << scientific << endl; - cout << "N elements:\t\t" << m_mesh->m_element[m_mesh->m_expDim].size() << endl - << "N elements invalid:\t" << res->startInv << endl - << "Worst jacobian:\t\t" << res->worstJac << endl - << "N free nodes:\t\t" << res->n << endl - << "N Dof:\t\t\t" << res->nDoF << endl - << "N Dirclet:\t\t" << res->nDirc << endl - << "N color sets:\t\t" << nset << endl - << "Avg set colors:\t\t" << p/nset << endl - << "Min set:\t\t" << mn << endl - << "Max set:\t\t" << mx << endl - << "Residual tolerance:\t" << restol << endl; - - int nThreads = m_config["numthreads"].as(); - - int ctr = 0; - Thread::ThreadMaster tms; - tms.SetThreadingType("ThreadManagerBoost"); - Thread::ThreadManagerSharedPtr tm = - tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads); - - Timer t; - t.Start(); - - while (res->val > restol) - { - ctr++; - res->val = 0.0; - for(int i = 0; i < optiNodes.size(); i++) - { - vector jobs(optiNodes[i].size()); - if (m_mesh->m_spaceDim == 2) - { - for(int j = 0; j < optiNodes[i].size(); j++) - { - jobs[j] = optiNodes[i][j].GetJob<2>(); - } - } - else - { - for(int j = 0; j < optiNodes[i].size(); j++) - { - jobs[j] = optiNodes[i][j].GetJob<3>(); - } - } - - tm->SetNumWorkers(0); - tm->QueueJobs(jobs); - tm->SetNumWorkers(nThreads); - tm->Wait(); - } - - EvaluateMesh(); - - cout << ctr << "\tResidual: " << res->val << " " << res->worstJac << endl; - if(ctr >= maxIter) - break; - } - - t.Stop(); - cout << "Time to compute: " << t.TimePerTest(1) << endl; - - EvaluateMesh(); - - cout << "Invalid at end:\t\t" << res->startInv << endl; - cout << "Worst at end:\t\t" << res->worstJac << endl; - - if(m_config["stats"].beenSet) - { - string file = m_config["stats"].as(); - cout << "writing stats to " << file.c_str() << endl; - WriteStats(file); - } -} - -template -void ProcessVarOpti::NodeOpti::Optimise() -{ - //it doesnt matter at this point what the dim is so long that - //in the 2d case z is left as zero - - Array G = GetGrad(); - - if(sqrt(G[0]*G[0] + G[1]*G[1] + G[2]*G[2]) > 1e-10) - { - //needs to optimise - NekDouble currentW = GetFunctional(); - NekDouble xc = node->m_x; - NekDouble yc = node->m_y; - NekDouble zc = node->m_z; - NekDouble alpha = 1.0; - NekDouble delX = 0.0; - NekDouble delY = 0.0; - NekDouble delZ = 0.0; - - if(DIM == 2) - { - delX = 1.0/(G[3]*G[4]-G[6]*G[6])*(G[4]*G[0] - G[6]*G[1]); - delY = 1.0/(G[3]*G[4]-G[6]*G[6])*(G[3]*G[1] - G[6]*G[0]); - } - else - { - DNekMat H(3,3,0.0); - H(0,0) = G[3]; - H(1,1) = G[4]; - H(2,2) = G[5]; - H(0,1) = G[6]; - H(1,0) = G[6]; - H(0,2) = G[7]; - H(2,0) = G[7]; - H(2,1) = G[8]; - H(1,2) = G[8]; - H.Invert(); - NekVector g(3); - g[0] = G[0]; - g[1] = G[1]; - g[2] = G[2]; - NekVector del = H * g; - delX = del[0]; - delY = del[1]; - delZ = del[2]; - } - - bool found = false; - while(alpha > 1e-10) - { - node->m_x = xc - alpha * delX; - node->m_y = yc - alpha * delY; - node->m_z = zc - alpha * delZ; - if(GetFunctional() < currentW) - { - found = true; - break; - } - - alpha /= 2.0; - } - - if(!found) - { - //reset the node - node->m_x = xc; - node->m_y = yc; - node->m_z = zc; - // cout << "warning: had to reset node" << endl; - // cout << G[0] << " " << G[1] << " " << G[2] << " " << node->m_id << endl; - } - mtx.lock(); - res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ - (node->m_z-zc)*(node->m_z-zc)),res->val); - mtx.unlock(); - } -} - -NekDouble dir[13][3] = {{ 0.0, 0.0, 0.0 }, // 0 (x , y , z ) - { 1.0, 0.0, 0.0 }, // 1 (x+dx, y , z ) - { 1.0, 1.0, 0.0 }, // 2 (x+dx, y+dy, z ) - { 0.0, 1.0, 0.0 }, // 3 (x , y+dy, z ) - { -1.0, 0.0, 0.0 }, // 4 (x-dx, y , z ) - { -1.0, -1.0, 0.0 }, // 5 (x-dx, y-dy, z ) - { 0.0, -1.0, 0.0 }, // 6 (x , y-dy, z ) - { -1.0, 0.0, -1.0 }, // 7 (x-dx, y , z-dz) - { 0.0, 0.0, -1.0 }, // 8 (x , y , z-dz) - { 0.0, 0.0, 1.0 }, // 9 (x , y , z+dz) - { 1.0, 0.0, 1.0 }, // 10 (x+dx, y , z+dz) - { 0.0, 1.0, 1.0 }, // 11 (x , y+dy, z+dz) - { 0.0, -1.0, -1.0 }}; // 12 (x , y-dy, z-dz) - -template -Array ProcessVarOpti::NodeOpti::GetGrad() -{ - return Array(); -} - -template<> -Array ProcessVarOpti::NodeOpti::GetGrad<2>() -{ - NekDouble xc = node->m_x; - NekDouble yc = node->m_y; - NekDouble dx = 1e-4; - vector w(9); - - for(int i = 0; i < 7; i++) - { - node->m_x = xc + dir[i][0] * dx; - node->m_y = yc + dir[i][1] * dx; - w[i] = GetFunctional<2>(); - } - node->m_x = xc; - node->m_y = yc; - - Array ret(9,0.0); - - //ret[0] d/dx - //ret[1] d/dy - //ret[2] d/dz - - //ret[3] d2/dx2 - //ret[4] d2/dy2 - //ret[5] d2/dz2 - //ret[6] d2/dxdy - //ret[7] d2/dxdz - //ret[8] d2/dydz - - ret[0] = (w[1] - w[4]) / 2.0 / dx; - ret[1] = (w[3] - w[6]) / 2.0 / dx; - ret[3] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; - ret[4] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; - ret[6] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / dx / dx; - - return ret; -} - -template<> -Array ProcessVarOpti::NodeOpti::GetGrad<3>() -{ - NekDouble xc = node->m_x; - NekDouble yc = node->m_y; - NekDouble zc = node->m_z; - NekDouble dx = 1e-6; - - vector w; - - for(int i = 0; i < 13; i++) - { - node->m_x = xc + dir[i][0] * dx; - node->m_y = yc + dir[i][1] * dx; - node->m_z = zc + dir[i][2] * dx; - w.push_back(GetFunctional<3>()); - } - node->m_x = xc; - node->m_y = yc; - node->m_z = zc; - - Array ret(9,0.0); - - //ret[0] d/dx - //ret[1] d/dy - //ret[2] d/dz - - //ret[3] d2/dx2 - //ret[4] d2/dy2 - //ret[5] d2/dz2 - //ret[6] d2/dxdy - //ret[7] d2/dxdz - //ret[8] d2/dydz - - ret[0] = (w[1] - w[4]) / 2.0 / dx; - ret[1] = (w[3] - w[6]) / 2.0 / dx; - ret[2] = (w[9] - w[8]) / 2.0 / dx; - - ret[3] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; - ret[4] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; - ret[5] = (w[9] + w[8] - 2.0*w[0]) / dx / dx; - - ret[6] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / dx / dx; - ret[7] = (w[10] - w[1] - w[9] + 2.0*w[0] - w[4] - w[8] + w[7]) / 2.0 / dx / dx; - ret[8] = (w[11] - w[3] - w[9] + 2.0*w[0] - w[6] - w[8] + w[12]) / 2.0 / dx / dx; - - return ret; -} - -template inline NekDouble JacDet(NekDouble *jac) -{ - return 0.0; -} - -template<> inline NekDouble JacDet<2>(NekDouble *jac) -{ - return jac[0] * jac[3] - jac[2] * jac[1]; -} - -template<> inline NekDouble JacDet<3>(NekDouble *jac) -{ - return jac[0]*(jac[4]*jac[8]-jac[5]*jac[7]) - -jac[3]*(jac[1]*jac[8]-jac[2]*jac[7]) - +jac[6]*(jac[1]*jac[5]-jac[2]*jac[4]); -} - -template inline NekDouble LinElasTrace(NekDouble *jac) -{ - return 0.0; -} - -template<> inline NekDouble LinElasTrace<2>(NekDouble *jac) -{ - return 0.25 * ( - (jac[0]*jac[0]+jac[1]*jac[1]-1.0)*(jac[0]*jac[0]+jac[1]*jac[1]-1.0) + - (jac[2]*jac[2]+jac[3]*jac[3]-1.0)*(jac[2]*jac[2]+jac[3]*jac[3]-1.0)) - + 0.5 * ( - (jac[0]*jac[2]+jac[1]*jac[3])*(jac[0]*jac[2]+jac[1]*jac[3])); -} - -template<> inline NekDouble LinElasTrace<3>(NekDouble *jac) -{ - return 0.25 *( - (jac[0]*jac[0]+jac[1]*jac[1]+jac[2]*jac[2]-1.0)* - (jac[0]*jac[0]+jac[1]*jac[1]+jac[2]*jac[2]-1.0) + - (jac[3]*jac[3]+jac[4]*jac[4]+jac[5]*jac[5]-1.0)* - (jac[3]*jac[3]+jac[4]*jac[4]+jac[5]*jac[5]-1.0) + - (jac[6]*jac[6]+jac[7]*jac[7]+jac[8]*jac[8]-1.0)* - (jac[6]*jac[6]+jac[7]*jac[7]+jac[8]*jac[8]-1.0)) - + 0.5 * ( - (jac[0]*jac[6]+jac[1]*jac[7]+jac[2]*jac[8])* - (jac[0]*jac[6]+jac[1]*jac[7]+jac[2]*jac[8])+ - (jac[3]*jac[6]+jac[4]*jac[7]+jac[5]*jac[8])* - (jac[3]*jac[6]+jac[4]*jac[7]+jac[5]*jac[8])+ - (jac[0]*jac[3]+jac[1]*jac[4]+jac[3]*jac[5])* - (jac[0]*jac[3]+jac[1]*jac[4]+jac[3]*jac[5])); -} - -template -NekDouble ProcessVarOpti::NodeOpti::GetFunctional() -{ - const int nElmt = data.size(); - const int totPtsLow = ptsLow * nElmt; - NekDouble X[DIM * totPtsLow]; - - // Store x/y components of each element sequentially in memory - for (int i = 0, cnt = 0; i < nElmt; ++i) - { - for (int j = 0; j < ptsLow; ++j) - { - for (int d = 0; d < DIM; ++d) - { - X[cnt + d*ptsLow + j] = *(data[i]->nodes[j][d]); - } - } - - cnt += DIM*ptsLow; - } - - // Storage for derivatives, ordered by: - // - standard coordinate direction - // - number of elements - // - cartesian coordinate direction - // - quadrature points - NekDouble deriv[DIM][nElmt][DIM][ptsHigh]; - - // Calculate x- and y-gradients - for (int d = 0; d < DIM; ++d) - { - Blas::Dgemm('N', 'N', ptsHigh, DIM * nElmt, ptsLow, 1.0, - VdmD[d].GetRawPtr(), ptsHigh, X, ptsLow, 0.0, - &deriv[d][0][0][0], ptsHigh); - } - - NekDouble integral = 0.0; - - switch(opti) - { - case eLinEl: - { - const NekDouble nu = 0.45; - const NekDouble mu = 1.0 / 2.0 / (1.0+nu); - const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); - - for (int i = 0; i < nElmt; ++i) - { - bool valid = true; - NekDouble jacDet[ptsHigh], trEtE[ptsHigh]; - - for(int k = 0; k < ptsHigh; ++k) - { - NekDouble jacIdeal[DIM*DIM]; - int cnt = 0; - for (int m = 0; m < DIM; ++m) - { - for (int n = 0; n < DIM; ++n, ++cnt) - { - jacIdeal[cnt] = 0.0; - for (int l = 0; l < DIM; ++l) - { - jacIdeal[cnt] += - deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; - } - } - } - jacDet[k] = JacDet(jacIdeal); - trEtE[k] = LinElasTrace(jacIdeal); - valid = valid ? jacDet[k] > 0.0 : false; - } - - if (!valid) - { - for(int k = 0; k < ptsHigh; ++k) - { - NekDouble de = 1e-2; - NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); - NekDouble lsigma = log(sigma); - integral += quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); - } - } - else - { - for(int k = 0; k < ptsHigh; ++k) - { - NekDouble lsigma = log(jacDet[k]); - integral += quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); - } - } - } - break; - } - - case eHypEl: - { - const NekDouble nu = 0.45; - const NekDouble mu = 1.0 / 2.0 / (1.0+nu); - const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); - - for (int i = 0; i < nElmt; ++i) - { - bool valid = true; - NekDouble jacDet[ptsHigh], I1[ptsHigh]; - - for(int k = 0; k < ptsHigh; ++k) - { - NekDouble jacIdeal[DIM*DIM]; - int cnt = 0; - for (int m = 0; m < DIM; ++m) - { - for (int n = 0; n < DIM; ++n, ++cnt) - { - jacIdeal[cnt] = 0.0; - for (int l = 0; l < DIM; ++l) - { - jacIdeal[cnt] += - deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; - } - } - } - - jacDet[k] = JacDet(jacIdeal); - I1[k] = 0.0; - for (int m = 0; m < DIM*DIM; ++m) - { - I1[k] += jacIdeal[m]*jacIdeal[m]; - } - valid = valid ? jacDet[k] > 0.0 : false; - } - - if (!valid) - { - for(int k = 0; k < ptsHigh; ++k) - { - NekDouble de = 1e-1; - NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); - NekDouble lsigma = log(sigma); - integral += quadW[k]*fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1[k] - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); - } - } - else - { - for(int k = 0; k < ptsHigh; ++k) - { - NekDouble lsigma = log(jacDet[k]); - integral += quadW[k]*fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1[k] - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); - } - } - } - break; - } - - case eRoca: - { - for (int i = 0; i < nElmt; ++i) - { - bool valid = true; - NekDouble jacDet[ptsHigh], frob[ptsHigh]; - - for(int k = 0; k < ptsHigh; ++k) - { - NekDouble jacIdeal[DIM*DIM]; - int cnt = 0; - for (int m = 0; m < DIM; ++m) - { - for (int n = 0; n < DIM; ++n, ++cnt) - { - jacIdeal[cnt] = 0.0; - for (int l = 0; l < DIM; ++l) - { - jacIdeal[cnt] += - deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; - } - } - } - - frob[k] = 0.0; - for (int m = 0; m < DIM*DIM; ++m) - { - frob[k] += jacIdeal[m] * jacIdeal[m]; - } - jacDet[k] = JacDet(jacIdeal); - valid = valid ? jacDet[k] > 0.0 : false; - } - - if (!valid) - { - for(int k = 0; k < ptsHigh; ++k) - { - NekDouble de = 1e-2; - NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); - integral += quadW[k] * fabs(data[i]->maps[k][9]) * (frob[k] / DIM / pow(fabs(sigma), 2.0/DIM) -1.0); - } - } - else - { - for(int k = 0; k < ptsHigh; ++k) - { - integral += quadW[k] * fabs(data[i]->maps[k][9]) * (frob[k] / DIM / pow(fabs(jacDet[k]), 2.0/DIM) -1.0); - } - } - } - break; - } - - case eWins: - { - for (int i = 0; i < nElmt; ++i) - { - bool valid = true; - NekDouble jacDet[ptsHigh], frob[ptsHigh]; - - for(int k = 0; k < ptsHigh; ++k) - { - NekDouble jacIdeal[DIM*DIM]; - int cnt = 0; - for (int m = 0; m < DIM; ++m) - { - for (int n = 0; n < DIM; ++n, ++cnt) - { - jacIdeal[cnt] = 0.0; - for (int l = 0; l < DIM; ++l) - { - jacIdeal[cnt] += - deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; - } - } - } - - frob[k] = 0.0; - for (int m = 0; m < DIM*DIM; ++m) - { - frob[k] += jacIdeal[m] * jacIdeal[m]; - } - jacDet[k] = JacDet(jacIdeal); - valid = valid ? jacDet[k] > 0.0 : false; - } - - if (!valid) - { - for(int k = 0; k < ptsHigh; ++k) - { - NekDouble de = 1e-2; - NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); - integral += quadW[k]*fabs(data[i]->maps[k][9])*(frob[k] / sigma); - } - } - else - { - for(int k = 0; k < ptsHigh; ++k) - { - integral += quadW[k]*fabs(data[i]->maps[k][9])*(frob[k] / jacDet[k]); - } - } - } - break; - } - } - - return integral; -} - -vector > ProcessVarOpti::GetColouredNodes() -{ - //this figures out the dirclet nodes and colors the others into paralell sets - NodeSet boundaryNodes; - - switch (m_mesh->m_spaceDim) - { - case 2: - { - EdgeSet::iterator it; - for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) - { - if((*it)->m_elLink.size() == 2) - { - continue; - } - - boundaryNodes.insert((*it)->m_n1); - boundaryNodes.insert((*it)->m_n2); - for(int i = 0; i < (*it)->m_edgeNodes.size(); i++) - { - boundaryNodes.insert((*it)->m_edgeNodes[i]); - } - } - break; - } - case 3: - { - FaceSet::iterator it; - for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) - { - if((*it)->m_elLink.size() == 2) - { - continue; - } - - vector vs = (*it)->m_vertexList; - for(int j = 0; j < vs.size(); j++) - { - boundaryNodes.insert(vs[j]); - } - - vector es = (*it)->m_edgeList; - for(int j = 0; j < es.size(); j++) - { - for(int k = 0; k < es[j]->m_edgeNodes.size(); k++) - { - boundaryNodes.insert(es[j]->m_edgeNodes[k]); - } - } - - for(int i = 0; i < (*it)->m_faceNodes.size(); i++) - { - boundaryNodes.insert((*it)->m_faceNodes[i]); - } - } - break; - } - default: - ASSERTL0(false,"space dim issue"); - } - - res->nDirc = boundaryNodes.size(); - - vector remain; - - NodeSet::iterator nit; - for (nit = m_mesh->m_vertexSet.begin(); nit != m_mesh->m_vertexSet.end(); ++nit) - { - NodeSet::iterator nit2 = boundaryNodes.find(*nit); - if(nit2 == boundaryNodes.end()) - { - remain.push_back(*nit); - } - } - - EdgeSet::iterator eit; - for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) - { - vector n = (*eit)->m_edgeNodes; - for(int j = 0; j < n.size(); j++) - { - NodeSet::iterator nit = boundaryNodes.find(n[j]); - if(nit == boundaryNodes.end()) - { - remain.push_back(n[j]); - } - } - } - - FaceSet::iterator fit; - for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) - { - for(int j = 0; j < (*fit)->m_faceNodes.size(); j++) - { - NodeSet::iterator nit = boundaryNodes.find((*fit)->m_faceNodes[j]); - if(nit == boundaryNodes.end()) - { - remain.push_back((*fit)->m_faceNodes[j]); - } - } - } - - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - vector ns = - m_mesh->m_element[m_mesh->m_expDim][i]->GetVolumeNodes(); - for(int j = 0; j < ns.size(); j++) - { - NodeSet::iterator nit = boundaryNodes.find(ns[j]); - if(nit == boundaryNodes.end()) - { - remain.push_back(ns[j]); - } - } - } - - res->n = remain.size(); - res->nDoF = res->n * m_mesh->m_spaceDim; - - vector > ret; - - while (remain.size() > 0) - { - vector layer; - set locked; - set completed; - for(int i = 0; i < remain.size(); i++) - { - NodeElMap::iterator it = nodeElMap.find(remain[i]->m_id); - ASSERTL0(it != nodeElMap.end(),"could not find"); - bool islocked = false; - for(int j = 0; j < it->second.size(); j++) - { - set::iterator sit = locked.find(it->second[j]->el->GetId()); - if(sit != locked.end()) - { - islocked = true; - break; - } - } - if(!islocked) - { - layer.push_back(remain[i]); - completed.insert(remain[i]->m_id); - for(int j = 0; j < it->second.size(); j++) - { - locked.insert(it->second[j]->el->GetId()); - } - } - } - - vector tmp = remain; - remain.clear(); - for(int i = 0; i < tmp.size(); i++) - { - set::iterator sit = completed.find(tmp[i]->m_id); - if(sit == completed.end()) - { - remain.push_back(tmp[i]); - } - } - ret.push_back(layer); - } - return ret; -} - -void ProcessVarOpti::GetElementMap() -{ - //build ideal maps and structs; - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - vector ns; - el->GetCurvedNodes(ns); - ElDataSharedPtr d = boost::shared_ptr(new ElData(ns, m_mesh->m_spaceDim)); - d->el = el; - d->maps = MappingIdealToRef(el); - dataSet.push_back(d); - } - - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - vector ns; - el->GetCurvedNodes(ns); - - for(int j = 0; j < ns.size(); j++) - { - nodeElMap[ns[j]->m_id].push_back(dataSet[i]); - } - } -} - -vector > ProcessVarOpti::MappingIdealToRef(ElementSharedPtr el) -{ - //need to make ideal element out of old element - ElmtConfig ec = el->GetConf(); - ec.m_order = 1; - ec.m_faceNodes = false; - ec.m_volumeNodes = false; - ec.m_reorient = false; - - ElementSharedPtr E = GetElementFactory().CreateInstance( - ec.m_e, ec, el->GetVertexList(), - el->GetTagList()); - - SpatialDomains::GeometrySharedPtr geom = E->GetGeom(el->GetDim()); - geom->FillGeom(); - StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); - - vector > ret; - - if(geom->GetShapeType() == LibUtilities::eQuadrilateral) - { - ASSERTL0(false,"Not coded"); - /*vector > xy; - for(int i = 0; i < geom->GetNumVerts(); i++) - { - Array loc(2); - SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); - p->GetCoords(loc); - xy.push_back(loc); - } - - Array b = chi->GetBase(); - Array u = b[0]->GetZ(); - Array v = b[1]->GetZ(); - - for(int j = 0; j < b[1]->GetNumPoints(); j++) - { - for(int i = 0; i < b[0]->GetNumPoints(); i++) - { - NekDouble a1 = 0.5*(1.0-u[i]), a2 = 0.5*(1.0+u[i]); - NekDouble b1 = 0.5*(1.0-v[j]), b2 = 0.5*(1.0+v[j]); - DNekMat dxdz(2,2,1.0,eFULL); - - dxdz(0,0) = 0.5*(-b1*xy[0][0] + b1*xy[1][0] + b2*xy[2][0] - b2*xy[3][0]); - dxdz(1,0) = 0.5*(-b1*xy[0][1] + b1*xy[1][1] + b2*xy[2][1] - b2*xy[3][1]); - - dxdz(0,1) = 0.5*(-a1*xy[0][0] - a2*xy[1][0] + a2*xy[2][0] + a1*xy[3][0]); - dxdz(1,1) = 0.5*(-a1*xy[0][1] - a2*xy[1][1] + a2*xy[2][1] + a1*xy[3][1]); - - NekDouble det = 1.0/(dxdz(0,0)*dxdz(1,1) - dxdz(1,0)*dxdz(0,1)); - - dxdz.Invert(); - Array r(9,0.0); - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - ret.push_back(r); - } - }*/ - } - else if(geom->GetShapeType() == LibUtilities::eTriangle) - { - LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriElec); - Array u, v; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v); - - Array xc(chi->GetTotPoints()); - Array yc(chi->GetTotPoints()); - - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - - chi->BwdTrans(coeffs0,xc); - chi->BwdTrans(coeffs1,yc); - - NekVector X(ptsLow),Y(ptsLow); - for(int j = 0; j < u.num_elements(); j++) - { - Array xp(2); - xp[0] = u[j]; - xp[1] = v[j]; - - X(j) = chi->PhysEvaluate(xp, xc); - Y(j) = chi->PhysEvaluate(xp, yc); - } - - NekVector x1i(ptsHigh),y1i(ptsHigh), - x2i(ptsHigh),y2i(ptsHigh); - - x1i = VdmD[0]*X; - y1i = VdmD[0]*Y; - x2i = VdmD[1]*X; - y2i = VdmD[1]*Y; - - for(int i = 0 ; i < ptsHigh; i++) - { - DNekMat dxdz(2,2,1.0,eFULL); - dxdz(0,0) = x1i(i); - dxdz(0,1) = x2i(i); - dxdz(1,0) = y1i(i); - dxdz(1,1) = y2i(i); - - Array r(10,0.0); - r[9] = dxdz(0,0)*dxdz(1,1)-dxdz(1,0)*dxdz(0,1); - - dxdz.Invert(); - - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - ret.push_back(r); - } - } - else if(geom->GetShapeType() == LibUtilities::eTetrahedron) - { - LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTetElec); - Array u, v, w; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); - - Array xc(chi->GetTotPoints()); - Array yc(chi->GetTotPoints()); - Array zc(chi->GetTotPoints()); - - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - Array coeffs2 = geom->GetCoeffs(2); - - chi->BwdTrans(coeffs0,xc); - chi->BwdTrans(coeffs1,yc); - chi->BwdTrans(coeffs2,zc); - - NekVector X(ptsLow),Y(ptsLow),Z(ptsLow); - for(int j = 0; j < u.num_elements(); j++) - { - Array xp(3); - xp[0] = u[j]; - xp[1] = v[j]; - xp[2] = w[j]; - - X(j) = chi->PhysEvaluate(xp, xc); - Y(j) = chi->PhysEvaluate(xp, yc); - Z(j) = chi->PhysEvaluate(xp, zc); - } - - NekVector x1i(ptsHigh),y1i(ptsHigh),z1i(ptsHigh), - x2i(ptsHigh),y2i(ptsHigh),z2i(ptsHigh), - x3i(ptsHigh),y3i(ptsHigh),z3i(ptsHigh); - - x1i = VdmD[0]*X; - y1i = VdmD[0]*Y; - z1i = VdmD[0]*Z; - x2i = VdmD[1]*X; - y2i = VdmD[1]*Y; - z2i = VdmD[1]*Z; - x3i = VdmD[2]*X; - y3i = VdmD[2]*Y; - z3i = VdmD[2]*Z; - - for(int i = 0 ; i < ptsHigh; i++) - { - DNekMat dxdz(3,3,1.0,eFULL); - dxdz(0,0) = x1i(i); - dxdz(0,1) = x2i(i); - dxdz(0,2) = x3i(i); - dxdz(1,0) = y1i(i); - dxdz(1,1) = y2i(i); - dxdz(1,2) = y3i(i); - dxdz(2,0) = z1i(i); - dxdz(2,1) = z2i(i); - dxdz(2,2) = z3i(i); - - Array r(10,0.0); //store det in 10th entry - - r[9] = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) - -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) - +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); - - dxdz.Invert(); - - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[2] = dxdz(2,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - r[5] = dxdz(2,1); - r[6] = dxdz(0,2); - r[7] = dxdz(1,2); - r[8] = dxdz(2,2); - ret.push_back(r); - } - } - else if(geom->GetShapeType() == LibUtilities::ePrism) - { - ASSERTL0(false, "not coded"); - /*vector > xyz; - for(int i = 0; i < geom->GetNumVerts(); i++) - { - Array loc(3); - SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); - p->GetCoords(loc); - xyz.push_back(loc); - } - - Array b = chi->GetBase(); - Array eta1 = b[0]->GetZ(); - Array eta2 = b[1]->GetZ(); - Array eta3 = b[2]->GetZ(); - - for(int k = 0; k < b[2]->GetNumPoints(); k++) - { - - for(int j = 0; j < b[1]->GetNumPoints(); j++) - { - for(int i = 0; i < b[0]->GetNumPoints(); i++) - { - NekDouble xi1 = 0.5*(1+eta1[i])*(1-eta3[k])-1.0; - NekDouble a1 = 0.5*(1-xi1), a2 = 0.5*(1+xi1); - NekDouble b1 = 0.5*(1-eta2[j]), b2 = 0.5*(1+eta2[j]); - NekDouble c1 = 0.5*(1-eta3[k]), c2 = 0.5*(1+eta3[k]); - - DNekMat dxdz(3,3,1.0,eFULL); - - dxdz(0,0) = 0.5*(-b1*xyz[0][0] + b1*xyz[1][0] + b2*xyz[2][0] - b2*xyz[3][0]); - dxdz(1,0) = 0.5*(-b1*xyz[0][1] + b1*xyz[1][1] + b2*xyz[2][1] - b2*xyz[3][1]); - dxdz(2,0) = 0.5*(-b1*xyz[0][2] + b1*xyz[1][2] + b2*xyz[2][2] - b2*xyz[3][2]); - - dxdz(0,1) = 0.5*((a2-c1)*xyz[0][0] - a2*xyz[1][0] + a2*xyz[2][0] + (c1-a2)*xyz[3][0] - c2*xyz[4][0] + c2*xyz[5][0]); - dxdz(1,1) = 0.5*((a2-c1)*xyz[0][1] - a2*xyz[1][1] + a2*xyz[2][1] + (c1-a2)*xyz[3][1] - c2*xyz[4][1] + c2*xyz[5][1]); - dxdz(2,1) = 0.5*((a2-c1)*xyz[0][2] - a2*xyz[1][2] + a2*xyz[2][2] + (c1-a2)*xyz[3][2] - c2*xyz[4][2] + c2*xyz[5][2]); - - dxdz(0,2) = 0.5*(-b1*xyz[0][0] - b2*xyz[3][0] + b1*xyz[4][0] + b2*xyz[5][0]); - dxdz(1,2) = 0.5*(-b1*xyz[0][1] - b2*xyz[3][1] + b1*xyz[4][1] + b2*xyz[5][1]); - dxdz(2,2) = 0.5*(-b1*xyz[0][2] - b2*xyz[3][2] + b1*xyz[4][2] + b2*xyz[5][2]); - - dxdz.Invert(); - Array r(9,0.0); - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - r[2] = dxdz(2,0); - r[5] = dxdz(2,1); - r[6] = dxdz(0,2); - r[7] = dxdz(1,2); - r[8] = dxdz(2,2); - ret.push_back(r); - } - } - }*/ - } - else - { - ASSERTL0(false,"not coded"); - } - - return ret; -} - -void ProcessVarOpti::FillQuadPoints() -{ - int nq = m_mesh->m_nummode; - int id = m_mesh->m_vertexSet.size(); - - LibUtilities::PointsKey ekey(m_mesh->m_nummode, - LibUtilities::eGaussLobattoLegendre); - Array gll; - LibUtilities::PointsManager()[ekey]->GetPoints(gll); - - EdgeSet::iterator eit; - FaceSet::iterator fit; - - boost::unordered_map edgeGeoms; - boost::unordered_map faceGeoms; - boost::unordered_map volGeoms; - - for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) - { - SpatialDomains::Geometry1DSharedPtr geom = - (*eit)->GetGeom(m_mesh->m_spaceDim); - geom->FillGeom(); - edgeGeoms[(*eit)->m_id] = geom; - } - - for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) - { - SpatialDomains::Geometry2DSharedPtr geom = - (*fit)->GetGeom(m_mesh->m_spaceDim); - geom->FillGeom(); - faceGeoms[(*fit)->m_id] = geom; - } - - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - SpatialDomains::GeometrySharedPtr geom = - el->GetGeom(m_mesh->m_spaceDim); - geom->FillGeom(); - volGeoms[el->GetId()] = geom; - } - - for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) - { - SpatialDomains::Geometry1DSharedPtr geom = edgeGeoms[(*eit)->m_id]; - StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); - - vector hons; - - switch (m_mesh->m_spaceDim) - { - case 2: - { - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - - Array xc(xmap->GetTotPoints()); - Array yc(xmap->GetTotPoints()); - - xmap->BwdTrans(coeffs0,xc); - xmap->BwdTrans(coeffs1,yc); - - for(int j = 1; j < m_mesh->m_nummode - 1; j++) - { - Array xp(2); - xp[0] = gll[j]; - - hons.push_back(boost::shared_ptr(new Node( - id++,xmap->PhysEvaluate(xp,xc), - xmap->PhysEvaluate(xp,yc),0.0))); - } - (*eit)->m_edgeNodes.clear(); - (*eit)->m_edgeNodes = hons; - (*eit)->m_curveType = LibUtilities::eGaussLobattoLegendre; - } - break; - case 3: - { - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - Array coeffs2 = geom->GetCoeffs(2); - - Array xc(xmap->GetTotPoints()); - Array yc(xmap->GetTotPoints()); - Array zc(xmap->GetTotPoints()); - - xmap->BwdTrans(coeffs0,xc); - xmap->BwdTrans(coeffs1,yc); - xmap->BwdTrans(coeffs2,zc); - - for(int j = 1; j < m_mesh->m_nummode - 1; j++) - { - Array xp(2); - xp[0] = gll[j]; - - hons.push_back(boost::shared_ptr(new Node( - id++,xmap->PhysEvaluate(xp,xc), - xmap->PhysEvaluate(xp,yc), - xmap->PhysEvaluate(xp,zc)))); - } - (*eit)->m_edgeNodes.clear(); - (*eit)->m_edgeNodes = hons; - (*eit)->m_curveType = LibUtilities::eGaussLobattoLegendre; - } - break; - } - } - - if(m_mesh->m_expDim == 2) - { - //for faces need to do volume nodes - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - - SpatialDomains::GeometrySharedPtr geom = volGeoms[el->GetId()]; - StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); - - LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriElec); - Array u, v; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v); - - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - - Array xc(xmap->GetTotPoints()); - Array yc(xmap->GetTotPoints()); - - xmap->BwdTrans(coeffs0,xc); - xmap->BwdTrans(coeffs1,yc); - - vector hons; - - for(int j = 3 + 3*(nq-2); j < u.num_elements(); j++) - { - Array xp(2); - xp[0] = u[j]; - xp[1] = v[j]; - - hons.push_back(boost::shared_ptr(new Node( - id++,xmap->PhysEvaluate(xp,xc), - xmap->PhysEvaluate(xp,yc),0.0))); - } - - el->SetVolumeNodes(hons); - el->SetCurveType(LibUtilities::eNodalTriElec); - } - } - else - { - FaceSet::iterator it; - for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) - { - SpatialDomains::Geometry2DSharedPtr geom = faceGeoms[(*it)->m_id]; - StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); - - LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriElec); - Array u, v; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v); - - vector hons; - - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - Array coeffs2 = geom->GetCoeffs(2); - - Array xc(xmap->GetTotPoints()); - Array yc(xmap->GetTotPoints()); - Array zc(xmap->GetTotPoints()); - - xmap->BwdTrans(coeffs0,xc); - xmap->BwdTrans(coeffs1,yc); - xmap->BwdTrans(coeffs2,zc); - - for(int j = 3 + 3*(nq-2); j < u.num_elements(); j++) - { - Array xp(2); - xp[0] = u[j]; - xp[1] = v[j]; - - hons.push_back(boost::shared_ptr(new Node( - id++,xmap->PhysEvaluate(xp,xc), - xmap->PhysEvaluate(xp,yc), - xmap->PhysEvaluate(xp,zc)))); - } - (*it)->m_faceNodes.clear(); - (*it)->m_faceNodes = hons; - (*it)->m_curveType = LibUtilities::eNodalTriElec; - } - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - - SpatialDomains::GeometrySharedPtr geom = volGeoms[el->GetId()]; - StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); - - LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTetElec); - Array u, v, w; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); - - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - Array coeffs2 = geom->GetCoeffs(2); - - Array xc(xmap->GetTotPoints()); - Array yc(xmap->GetTotPoints()); - Array zc(xmap->GetTotPoints()); - - xmap->BwdTrans(coeffs0,xc); - xmap->BwdTrans(coeffs1,yc); - xmap->BwdTrans(coeffs2,zc); - - vector hons; - - //need to finish for tet - for(int j = 4 + 6*(nq-2) + 4 * ((nq-2)*(nq-3) / 2); - j < u.num_elements(); j++) - { - Array xp(3); - xp[0] = u[j]; - xp[1] = v[j]; - xp[2] = w[j]; - - hons.push_back(boost::shared_ptr(new Node( - id++,xmap->PhysEvaluate(xp,xc), - xmap->PhysEvaluate(xp,yc), - xmap->PhysEvaluate(xp,zc)))); - } - - el->SetVolumeNodes(hons); - el->SetCurveType(LibUtilities::eNodalTetElec); - } - } - - EvaluateMesh(); -} - -void ProcessVarOpti::EvaluateMesh() -{ - res->startInv =0; - res->worstJac = numeric_limits::max(); - - if(m_mesh->m_expDim == 2) - { - LibUtilities::PointsKey pkey1(m_mesh->m_nummode, - LibUtilities::eNodalTriElec); - Array u1, v1; - - LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); - - NekVector U1(u1), V1(v1); - - NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); - NekMatrix VandermondeI = Vandermonde; - VandermondeI.Invert(); - NekMatrix VdmDxt = ( - LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI); - NekMatrix VdmDyt = ( - LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI); - - - - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - - vector ns; - el->GetCurvedNodes(ns); - - NekDouble mx = -1.0 * numeric_limits::max(); - NekDouble mn = numeric_limits::max(); - - - NekVector X(u1.num_elements()),Y(u1.num_elements()); - for(int j = 0; j < u1.num_elements(); j++) - { - X(j) = ns[j]->m_x; - Y(j) = ns[j]->m_y; - } - - NekVector x1i(u1.num_elements()),y1i(u1.num_elements()), - x2i(u1.num_elements()),y2i(u1.num_elements()); - - x1i = VdmDxt*X; - y1i = VdmDxt*Y; - x2i = VdmDyt*X; - y2i = VdmDyt*Y; - - for(int j = 0; j < u1.num_elements(); j++) - { - NekDouble jacDet = x1i(j) * y2i(j) - x2i(j)*y1i(j); - mx = max(mx,jacDet); - mn = min(mn,jacDet); - } - - if(mn < 0) - { - res->startInv++; - } - res->worstJac = min(res->worstJac,mn/mx); - } - } - else - { - LibUtilities::PointsKey pkey1(m_mesh->m_nummode, - LibUtilities::eNodalTetElec); - Array u1, v1,w1; - - LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1,w1); - - NekVector U1(u1), V1(v1), W1(w1); - - NekMatrix Vandermonde = LibUtilities::GetTetVandermonde(U1,V1,W1); - NekMatrix VandermondeI = Vandermonde; - VandermondeI.Invert(); - NekMatrix VdmDxt = ( - LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI); - NekMatrix VdmDyt = ( - LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI); - NekMatrix VdmDzt = ( - LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI); - - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - - vector ns; - el->GetCurvedNodes(ns); - - NekDouble mx = -1.0 * numeric_limits::max(); - NekDouble mn = numeric_limits::max(); - - NekVector X(u1.num_elements()),Y(u1.num_elements()),Z(u1.num_elements()); - for(int j = 0; j < u1.num_elements(); j++) - { - X(j) = ns[j]->m_x; - Y(j) = ns[j]->m_y; - Z(j) = ns[j]->m_z; - } - - NekVector x1i(u1.num_elements()),y1i(u1.num_elements()),z1i(u1.num_elements()), - x2i(u1.num_elements()),y2i(u1.num_elements()),z2i(u1.num_elements()), - x3i(u1.num_elements()),y3i(u1.num_elements()),z3i(u1.num_elements()); - - x1i = VdmDxt*X; - y1i = VdmDxt*Y; - z1i = VdmDxt*Z; - x2i = VdmDyt*X; - y2i = VdmDyt*Y; - z2i = VdmDyt*Z; - x3i = VdmDzt*X; - y3i = VdmDzt*Y; - z3i = VdmDzt*Z; - - for(int j = 0; j < u1.num_elements(); j++) - { - - DNekMat dxdz(3,3,1.0,eFULL); - dxdz(0,0) = x1i(j); - dxdz(0,1) = x2i(j); - dxdz(0,2) = x3i(j); - dxdz(1,0) = y1i(j); - dxdz(1,1) = y2i(j); - dxdz(1,2) = y3i(j); - dxdz(2,0) = z1i(j); - dxdz(2,1) = z2i(j); - dxdz(2,2) = z3i(j); - - NekDouble jacDet = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) - -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) - +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); - - mx = max(mx,jacDet); - mn = min(mn,jacDet); - } - - - - if(mn < 0) - { - res->startInv++; - } - - res->worstJac = min(res->worstJac,mn/mx); - } - } -} - -void ProcessVarOpti::WriteStats(string file) -{ - ASSERTL0(file != "", "no file name given"); - - ofstream out; - out.open(file.c_str()); - out << scientific; - - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - vector ns; - m_mesh->m_element[m_mesh->m_expDim][i]->GetCurvedNodes(ns); - int pts = ns.size(); - int dim = m_mesh->m_element[m_mesh->m_expDim][i]->GetDim(); - - NekDouble mx = -1.0 * numeric_limits::max(); - NekDouble mn = numeric_limits::max(); - - if(dim == 2) - { - NekVector X(pts),Y(pts),Z(pts), - x1(pts),y1(pts), - x2(pts),y2(pts); - for(int i = 0; i < pts; i++) - { - X(i) = ns[i]->m_x; - Y(i) = ns[i]->m_y; - } - - x1 = VdmD[0]*X; - y1 = VdmD[0]*Y; - x2 = VdmD[0]*X; - y2 = VdmD[0]*Y; - - for(int i = 0; i < pts; i++) - { - mx = max(mx, x1(i)*y2(i)-y1(i)*x2(i)); - mn = min(mn, x1(i)*y2(i)-y1(i)*x2(i)); - } - - } - else - { - ASSERTL0(false,"not coded"); - } - out << mn / mx << endl; - } -} - -} -} diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp new file mode 100644 index 000000000..9dc92a02e --- /dev/null +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp @@ -0,0 +1,302 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessJac.cpp +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Calculate Jacobians of elements. +// +//////////////////////////////////////////////////////////////////////////////// + +#include + +#include +#include "ProcessVarOpti.h" +#include "NodeOpti.h" +#include "NodeOptiJob.h" + +#include + +#include +#include +#include +#include + +#include +#include + +using namespace std; +using namespace Nektar::NekMeshUtils; + +namespace Nektar +{ +namespace Utilities +{ + +ModuleKey ProcessVarOpti::className = GetModuleFactory().RegisterCreatorFunction( + ModuleKey(eProcessModule, "varopti"), + ProcessVarOpti::create, + "Optimise mesh locations."); + +ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) +{ + m_config["linearelastic"] = + ConfigOption(true, "", "Optimise for linear elasticity"); + m_config["winslow"] = + ConfigOption(true, "", "Optimise for winslow"); + m_config["roca"] = + ConfigOption(true, "", "Optimise for roca method"); + m_config["hyperelastic"] = + ConfigOption(true, "", "Optimise for hyper elasticity"); + m_config["numthreads"] = + ConfigOption(false, "1", "Number of threads"); + m_config["nq"] = + ConfigOption(false, "0", "Number of quad points"); + m_config["stats"] = + ConfigOption(false, "", "Write a file with list of scaled jacobians"); + m_config["restol"] = + ConfigOption(false, "1e-6", "Tolerance criterion"); + m_config["maxiter"] = + ConfigOption(false, "500", "Maximum number of iterations"); +} + +ProcessVarOpti::~ProcessVarOpti() +{ +} + +void ProcessVarOpti::Process() +{ + if (m_mesh->m_verbose) + { + cout << "ProcessVarOpti: Optimising... " << endl; + } + + if(m_config["linearelastic"].beenSet) + { + opti = eLinEl; + } + else if(m_config["winslow"].beenSet) + { + opti = eWins; + } + else if(m_config["roca"].beenSet) + { + opti = eRoca; + } + else if(m_config["hyperelastic"].beenSet) + { + opti = eHypEl; + } + else + { + ASSERTL0(false,"not opti type set"); + } + + const int maxIter = m_config["maxiter"].as(); + const NekDouble restol = m_config["restol"].as(); + + m_mesh->m_nummode = m_config["nq"].as(); + + ASSERTL0(m_mesh->m_nummode > 2,"not specified high-order"); + + if(m_mesh->m_expDim == 2 && m_mesh->m_spaceDim == 3) + { + ASSERTL0(false,"cannot deal with manifolds"); + } + + res = boost::shared_ptr(new Residual); + res->val = 1.0; + + derivUtil = boost::shared_ptr(new DerivUtil); + ptsHelp = boost::shared_ptr(new PtsHelper); + + FillQuadPoints(); + + //build Vandermonde information + switch (m_mesh->m_spaceDim) + { + case 2: + { + ptsHelp->ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)/2; + + LibUtilities::PointsKey pkey1(m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, + LibUtilities::eNodalTriSPI); + Array u1, v1, u2, v2; + + LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); + LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2); + NekVector U1(u1), V1(v1); + NekVector U2(u2), V2(v2); + ptsHelp->ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); + + NekMatrix interp = LibUtilities::GetInterpolationMatrix(U1, V1, U2, V2); + + NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); + NekMatrix VandermondeI = Vandermonde; + VandermondeI.Invert(); + derivUtil->VdmD[0] = interp * ( + LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI); + derivUtil->VdmD[1] = interp * ( + LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI); + //derivUtil->quadW = LibUtilities::MakeQuadratureWeights(U2,V1); + Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); + NekVector quadWi(qds); + derivUtil->quadW = quadWi; + } + break; + case 3: + { + ptsHelp->ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)*(m_mesh->m_nummode+2)/6; + LibUtilities::PointsKey pkey1(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, + LibUtilities::eNodalTetSPI); + Array u1, v1, u2, v2, w1, w2; + LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1, w1); + LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2, w2); + NekVector U1(u1), V1(v1), W1(w1); + NekVector U2(u2), V2(v2), W2(w2); + ptsHelp->ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); + + NekMatrix interp = + LibUtilities::GetTetInterpolationMatrix(U1, V1, W1, + U2, V2, W2); + + NekMatrix Vandermonde = + LibUtilities::GetTetVandermonde(U1,V1,W1); + NekMatrix VandermondeI = Vandermonde; + VandermondeI.Invert(); + derivUtil->VdmD[0] = interp * ( + LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI); + derivUtil->VdmD[1] = interp * ( + LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI); + derivUtil->VdmD[2] = interp * ( + LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI); + Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); + NekVector quadWi(qds); + derivUtil->quadW = quadWi; + } + } + + GetElementMap(); + + vector > freenodes = GetColouredNodes(); + vector > optiNodes; + + for(int i = 0; i < freenodes.size(); i++) + { + vector ns; + for(int j = 0; j < freenodes[i].size(); j++) + { + NodeElMap::iterator it = nodeElMap.find(freenodes[i][j]->m_id); + ASSERTL0(it != nodeElMap.end(), "could not find"); + ns.push_back(NodeOpti(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti)); + } + optiNodes.push_back(ns); + } + + int nset = optiNodes.size(); + int p = 0; + int mn = numeric_limits::max(); + int mx = 0; + for(int i = 0; i < nset; i++) + { + p += optiNodes[i].size(); + mn = min(mn, int(optiNodes[i].size())); + mx = max(mx, int(optiNodes[i].size())); + } + + cout << scientific << endl; + cout << "N elements:\t\t" << m_mesh->m_element[m_mesh->m_expDim].size() << endl + << "N elements invalid:\t" << res->startInv << endl + << "Worst jacobian:\t\t" << res->worstJac << endl + << "N free nodes:\t\t" << res->n << endl + << "N Dof:\t\t\t" << res->nDoF << endl + << "N Dirclet:\t\t" << res->nDirc << endl + << "N color sets:\t\t" << nset << endl + << "Avg set colors:\t\t" << p/nset << endl + << "Min set:\t\t" << mn << endl + << "Max set:\t\t" << mx << endl + << "Residual tolerance:\t" << restol << endl; + + int nThreads = m_config["numthreads"].as(); + + int ctr = 0; + Thread::ThreadMaster tms; + tms.SetThreadingType("ThreadManagerBoost"); + Thread::ThreadManagerSharedPtr tm = + tms.CreateInstance(Thread::ThreadMaster::SessionJob, nThreads); + + Timer t; + t.Start(); + + while (res->val > restol) + { + ctr++; + res->val = 0.0; + for(int i = 0; i < optiNodes.size(); i++) + { + vector jobs(optiNodes[i].size()); + for(int j = 0; j < optiNodes[i].size(); j++) + { + jobs[j] = optiNodes[i][j].GetJob(); + } + + tm->SetNumWorkers(0); + tm->QueueJobs(jobs); + tm->SetNumWorkers(nThreads); + tm->Wait(); + } + + EvaluateMesh(); + + cout << ctr << "\tResidual: " << res->val << " " << res->worstJac << endl; + if(ctr >= maxIter) + break; + } + + t.Stop(); + cout << "Time to compute: " << t.TimePerTest(1) << endl; + + EvaluateMesh(); + + cout << "Invalid at end:\t\t" << res->startInv << endl; + cout << "Worst at end:\t\t" << res->worstJac << endl; + + if(m_config["stats"].beenSet) + { + string file = m_config["stats"].as(); + cout << "writing stats to " << file.c_str() << endl; + WriteStats(file); + } +} + +} +} diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h similarity index 79% rename from utilities/NekMesh/ProcessModules/ProcessVarOpti.h rename to utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h index 415904ee2..43a8c7513 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h @@ -36,9 +36,7 @@ #ifndef UTILITIES_NEKMESH_PROCESSVAROPTI #define UTILITIES_NEKMESH_PROCESSVAROPTI -#include "../Module.h" - -#include +#include "../../Module.h" namespace Nektar { @@ -73,6 +71,20 @@ struct ElData }; typedef boost::shared_ptr ElDataSharedPtr; +struct DerivUtil +{ + NekMatrix VdmD[3]; + NekVector quadW; +}; +typedef boost::shared_ptr DerivUtilSharedPtr; + +struct PtsHelper +{ + int ptsHigh; + int ptsLow; +}; +typedef boost::shared_ptr PtsHelperSharedPtr; + enum optimiser { eLinEl, @@ -126,49 +138,11 @@ private: NodeElMap nodeElMap; vector dataSet; - ResidualSharedPtr res; - - template - class NodeOptiJob; - - class NodeOpti - { - public: - NodeOpti(NodeSharedPtr n, vector e, - ResidualSharedPtr r) - : node(n), data(e), res(r) - { - } - - ~NodeOpti(){}; - - template void Optimise(); - template NodeOptiJob *GetJob() - { - return new NodeOptiJob(*this); - } - private: - template Array GetGrad(); - template NekDouble GetFunctional(); - NodeSharedPtr node; - vector data; - ResidualSharedPtr res; - }; - - template - class NodeOptiJob : public Thread::ThreadJob - { - public: - NodeOptiJob(NodeOpti no) : node(no) {} - - void Run() - { - node.Optimise(); - } - private: - NodeOpti node; - }; + ResidualSharedPtr res; + DerivUtilSharedPtr derivUtil; + PtsHelperSharedPtr ptsHelp; + optimiser opti; }; } -- GitLab From a056a580f6c42104193dd1c49d55ece260c49263 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 27 Jun 2016 16:24:16 +0100 Subject: [PATCH 048/236] missing files --- .../ProcessVarOpti/NodeOpti.cpp | 564 +++++++++++ .../ProcessModules/ProcessVarOpti/NodeOpti.h | 155 +++ .../ProcessVarOpti/NodeOptiJob.h | 65 ++ .../ProcessModules/ProcessVarOpti/Utils.cpp | 948 ++++++++++++++++++ 4 files changed, 1732 insertions(+) create mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp create mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h create mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h create mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp new file mode 100644 index 000000000..d9e68ccc8 --- /dev/null +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -0,0 +1,564 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessJac.h +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Calculate jacobians of elements. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "NodeOpti.h" +#include "NodeOptiJob.h" + +namespace Nektar +{ +namespace Utilities +{ + +boost::mutex mtx; + +void NodeOpti2D2D::Optimise() +{ + Array G = GetGrad(); + + if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-10) + { + //needs to optimise + NekDouble currentW = GetFunctional<2>(); + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble alpha = 1.0; + NekDouble delX = 1.0/(G[2]*G[3]-G[4]*G[4])*(G[3]*G[0] - G[4]*G[1]); + NekDouble delY = 1.0/(G[2]*G[3]-G[4]*G[4])*(G[2]*G[1] - G[4]*G[0]); + + bool found = false; + while(alpha > 1e-10) + { + node->m_x = xc - alpha * delX; + node->m_y = yc - alpha * delY; + if(GetFunctional<2>() < currentW) + { + found = true; + break; + } + + alpha /= 2.0; + } + + if(!found) + { + //reset the node + node->m_x = xc; + node->m_y = yc; + // cout << "warning: had to reset node" << endl; + } + mtx.lock(); + res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)),res->val); + mtx.unlock(); + } +} + + +void NodeOpti3D3D::Optimise() +{ + Array G = GetGrad(); + + if(sqrt(G[0]*G[0] + G[1]*G[1] + G[2]*G[2]) > 1e-10) + { + //needs to optimise + NekDouble currentW = GetFunctional<3>(); + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble zc = node->m_z; + NekDouble alpha = 1.0; + NekDouble delX; + NekDouble delY; + NekDouble delZ; + + NekDouble det = G[3]*(G[4]*G[5]-G[8]*G[8]) + -G[6]*(G[6]*G[5]-G[7]*G[8]) + +G[7]*(G[6]*G[8]-G[7]*G[4]); + + delX = G[0]*(G[4]*G[5]-G[8]*G[8]) + G[1]*(G[7]*G[8]-G[6]*G[5]) + G[2]*(G[6]*G[8]-G[7]*G[4]); + delX /= det; + delY = G[0]*(G[8]*G[7]-G[6]*G[5]) + G[1]*(G[3]*G[5]-G[7]*G[7]) + G[2]*(G[6]*G[7]-G[3]*G[8]); + delY /= det; + delZ = G[0]*(G[6]*G[8]-G[4]*G[7]) + G[1]*(G[6]*G[7]-G[3]*G[8]) + G[2]*(G[3]*G[4]-G[6]*G[6]); + delZ /= det; + + + bool found = false; + while(alpha > 1e-10) + { + node->m_x = xc - alpha * delX; + node->m_y = yc - alpha * delY; + node->m_z = zc - alpha * delZ; + if(GetFunctional<3>() < currentW) + { + found = true; + break; + } + + alpha /= 2.0; + } + + if(!found) + { + //reset the node + node->m_x = xc; + node->m_y = yc; + node->m_z = zc; + // cout << "warning: had to reset node" << endl; + } + mtx.lock(); + res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ + (node->m_z-zc)*(node->m_z-zc)),res->val); + mtx.unlock(); + } +} + +NekDouble dir[13][3] = {{ 0.0, 0.0, 0.0 }, // 0 (x , y , z ) + { 1.0, 0.0, 0.0 }, // 1 (x+dx, y , z ) + { 1.0, 1.0, 0.0 }, // 2 (x+dx, y+dy, z ) + { 0.0, 1.0, 0.0 }, // 3 (x , y+dy, z ) + { -1.0, 0.0, 0.0 }, // 4 (x-dx, y , z ) + { -1.0, -1.0, 0.0 }, // 5 (x-dx, y-dy, z ) + { 0.0, -1.0, 0.0 }, // 6 (x , y-dy, z ) + { -1.0, 0.0, -1.0 }, // 7 (x-dx, y , z-dz) + { 0.0, 0.0, -1.0 }, // 8 (x , y , z-dz) + { 0.0, 0.0, 1.0 }, // 9 (x , y , z+dz) + { 1.0, 0.0, 1.0 }, // 10 (x+dx, y , z+dz) + { 0.0, 1.0, 1.0 }, // 11 (x , y+dy, z+dz) + { 0.0, -1.0, -1.0 }}; // 12 (x , y-dy, z-dz) + +Array NodeOpti2D2D::GetGrad() +{ + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble dx = 1e-4; + vector w(9); + + for(int i = 0; i < 7; i++) + { + node->m_x = xc + dir[i][0] * dx; + node->m_y = yc + dir[i][1] * dx; + w[i] = GetFunctional<2>(); + } + node->m_x = xc; + node->m_y = yc; + + Array ret(9,0.0); + + //ret[0] d/dx + //ret[1] d/dy + //ret[2] d/dz + + //ret[3] d2/dx2 + //ret[4] d2/dy2 + //ret[5] d2/dz2 + //ret[6] d2/dxdy + //ret[7] d2/dxdz + //ret[8] d2/dydz + + ret[0] = (w[1] - w[4]) / 2.0 / dx; + ret[1] = (w[3] - w[6]) / 2.0 / dx; + ret[3] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; + ret[4] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; + ret[6] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / dx / dx; + + return ret; +} + +Array NodeOpti3D3D::GetGrad() +{ + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble zc = node->m_z; + NekDouble dx = 1e-6; + + vector w; + + for(int i = 0; i < 13; i++) + { + node->m_x = xc + dir[i][0] * dx; + node->m_y = yc + dir[i][1] * dx; + node->m_z = zc + dir[i][2] * dx; + w.push_back(GetFunctional<3>()); + } + node->m_x = xc; + node->m_y = yc; + node->m_z = zc; + + Array ret(9,0.0); + + //ret[0] d/dx + //ret[1] d/dy + //ret[2] d/dz + + //ret[3] d2/dx2 + //ret[4] d2/dy2 + //ret[5] d2/dz2 + //ret[6] d2/dxdy + //ret[7] d2/dxdz + //ret[8] d2/dydz + + ret[0] = (w[1] - w[4]) / 2.0 / dx; + ret[1] = (w[3] - w[6]) / 2.0 / dx; + ret[2] = (w[9] - w[8]) / 2.0 / dx; + + ret[3] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; + ret[4] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; + ret[5] = (w[9] + w[8] - 2.0*w[0]) / dx / dx; + + ret[6] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / dx / dx; + ret[7] = (w[10] - w[1] - w[9] + 2.0*w[0] - w[4] - w[8] + w[7]) / 2.0 / dx / dx; + ret[8] = (w[11] - w[3] - w[9] + 2.0*w[0] - w[6] - w[8] + w[12]) / 2.0 / dx / dx; + + return ret; +} + +template inline NekDouble JacDet(NekDouble *jac) +{ + return 0.0; +} + +template<> inline NekDouble JacDet<2>(NekDouble *jac) +{ + return jac[0] * jac[3] - jac[2] * jac[1]; +} + +template<> inline NekDouble JacDet<3>(NekDouble *jac) +{ + return jac[0]*(jac[4]*jac[8]-jac[5]*jac[7]) + -jac[3]*(jac[1]*jac[8]-jac[2]*jac[7]) + +jac[6]*(jac[1]*jac[5]-jac[2]*jac[4]); +} + +template inline NekDouble LinElasTrace(NekDouble *jac) +{ + return 0.0; +} + +template<> inline NekDouble LinElasTrace<2>(NekDouble *jac) +{ + return 0.25 * ( + (jac[0]*jac[0]+jac[1]*jac[1]-1.0)*(jac[0]*jac[0]+jac[1]*jac[1]-1.0) + + (jac[2]*jac[2]+jac[3]*jac[3]-1.0)*(jac[2]*jac[2]+jac[3]*jac[3]-1.0)) + + 0.5 * ( + (jac[0]*jac[2]+jac[1]*jac[3])*(jac[0]*jac[2]+jac[1]*jac[3])); +} + +template<> inline NekDouble LinElasTrace<3>(NekDouble *jac) +{ + return 0.25 *( + (jac[0]*jac[0]+jac[1]*jac[1]+jac[2]*jac[2]-1.0)* + (jac[0]*jac[0]+jac[1]*jac[1]+jac[2]*jac[2]-1.0) + + (jac[3]*jac[3]+jac[4]*jac[4]+jac[5]*jac[5]-1.0)* + (jac[3]*jac[3]+jac[4]*jac[4]+jac[5]*jac[5]-1.0) + + (jac[6]*jac[6]+jac[7]*jac[7]+jac[8]*jac[8]-1.0)* + (jac[6]*jac[6]+jac[7]*jac[7]+jac[8]*jac[8]-1.0)) + + 0.5 * ( + (jac[0]*jac[6]+jac[1]*jac[7]+jac[2]*jac[8])* + (jac[0]*jac[6]+jac[1]*jac[7]+jac[2]*jac[8])+ + (jac[3]*jac[6]+jac[4]*jac[7]+jac[5]*jac[8])* + (jac[3]*jac[6]+jac[4]*jac[7]+jac[5]*jac[8])+ + (jac[0]*jac[3]+jac[1]*jac[4]+jac[3]*jac[5])* + (jac[0]*jac[3]+jac[1]*jac[4]+jac[3]*jac[5])); +} + +template +NekDouble NodeOpti::GetFunctional() +{ + const int nElmt = data.size(); + const int totpts = ptsHelp->ptsLow * nElmt; + NekDouble X[DIM * totpts]; + + // Store x/y components of each element sequentially in memory + for (int i = 0, cnt = 0; i < nElmt; ++i) + { + for (int j = 0; j < ptsHelp->ptsLow; ++j) + { + for (int d = 0; d < DIM; ++d) + { + X[cnt + d*ptsHelp->ptsLow + j] = *(data[i]->nodes[j][d]); + } + } + + cnt += DIM*ptsHelp->ptsLow; + } + + // Storage for derivatives, ordered by: + // - standard coordinate direction + // - number of elements + // - cartesian coordinate direction + // - quadrature points + NekDouble deriv[DIM][nElmt][DIM][ptsHelp->ptsHigh]; + + // Calculate x- and y-gradients + for (int d = 0; d < DIM; ++d) + { + Blas::Dgemm('N', 'N', ptsHelp->ptsHigh, DIM * nElmt, ptsHelp->ptsLow, 1.0, + derivUtil->VdmD[d].GetRawPtr(), ptsHelp->ptsHigh, X, ptsHelp->ptsLow, 0.0, + &deriv[d][0][0][0], ptsHelp->ptsHigh); + } + + NekDouble integral = 0.0; + + switch(opti) + { + case eLinEl: + { + const NekDouble nu = 0.45; + const NekDouble mu = 1.0 / 2.0 / (1.0+nu); + const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + + for (int i = 0; i < nElmt; ++i) + { + bool valid = true; + NekDouble jacDet[ptsHelp->ptsHigh], trEtE[ptsHelp->ptsHigh]; + + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + NekDouble jacIdeal[DIM*DIM]; + int cnt = 0; + for (int m = 0; m < DIM; ++m) + { + for (int n = 0; n < DIM; ++n, ++cnt) + { + jacIdeal[cnt] = 0.0; + for (int l = 0; l < DIM; ++l) + { + jacIdeal[cnt] += + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + } + } + } + jacDet[k] = JacDet(jacIdeal); + trEtE[k] = LinElasTrace(jacIdeal); + valid = valid ? jacDet[k] > 0.0 : false; + } + + if (!valid) + { + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + NekDouble de = 1e-2; + NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + NekDouble lsigma = log(sigma); + integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); + } + } + else + { + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + NekDouble lsigma = log(jacDet[k]); + integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); + } + } + } + break; + } + + case eHypEl: + { + const NekDouble nu = 0.45; + const NekDouble mu = 1.0 / 2.0 / (1.0+nu); + const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + + for (int i = 0; i < nElmt; ++i) + { + bool valid = true; + NekDouble jacDet[ptsHelp->ptsHigh], I1[ptsHelp->ptsHigh]; + + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + NekDouble jacIdeal[DIM*DIM]; + int cnt = 0; + for (int m = 0; m < DIM; ++m) + { + for (int n = 0; n < DIM; ++n, ++cnt) + { + jacIdeal[cnt] = 0.0; + for (int l = 0; l < DIM; ++l) + { + jacIdeal[cnt] += + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + } + } + } + + jacDet[k] = JacDet(jacIdeal); + I1[k] = 0.0; + for (int m = 0; m < DIM*DIM; ++m) + { + I1[k] += jacIdeal[m]*jacIdeal[m]; + } + valid = valid ? jacDet[k] > 0.0 : false; + } + + if (!valid) + { + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + NekDouble de = 1e-1; + NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + NekDouble lsigma = log(sigma); + integral += derivUtil->quadW[k]*fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1[k] - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); + } + } + else + { + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + NekDouble lsigma = log(jacDet[k]); + integral += derivUtil->quadW[k]*fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1[k] - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); + } + } + } + break; + } + + case eRoca: + { + for (int i = 0; i < nElmt; ++i) + { + bool valid = true; + NekDouble jacDet[ptsHelp->ptsHigh], frob[ptsHelp->ptsHigh]; + + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + NekDouble jacIdeal[DIM*DIM]; + int cnt = 0; + for (int m = 0; m < DIM; ++m) + { + for (int n = 0; n < DIM; ++n, ++cnt) + { + jacIdeal[cnt] = 0.0; + for (int l = 0; l < DIM; ++l) + { + jacIdeal[cnt] += + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + } + } + } + + frob[k] = 0.0; + for (int m = 0; m < DIM*DIM; ++m) + { + frob[k] += jacIdeal[m] * jacIdeal[m]; + } + jacDet[k] = JacDet(jacIdeal); + valid = valid ? jacDet[k] > 0.0 : false; + } + + if (!valid) + { + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + NekDouble de = 1e-2; + NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (frob[k] / DIM / pow(fabs(sigma), 2.0/DIM) -1.0); + } + } + else + { + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (frob[k] / DIM / pow(fabs(jacDet[k]), 2.0/DIM) -1.0); + } + } + } + break; + } + + case eWins: + { + for (int i = 0; i < nElmt; ++i) + { + bool valid = true; + NekDouble jacDet[ptsHelp->ptsHigh], frob[ptsHelp->ptsHigh]; + + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + NekDouble jacIdeal[DIM*DIM]; + int cnt = 0; + for (int m = 0; m < DIM; ++m) + { + for (int n = 0; n < DIM; ++n, ++cnt) + { + jacIdeal[cnt] = 0.0; + for (int l = 0; l < DIM; ++l) + { + jacIdeal[cnt] += + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + } + } + } + + frob[k] = 0.0; + for (int m = 0; m < DIM*DIM; ++m) + { + frob[k] += jacIdeal[m] * jacIdeal[m]; + } + jacDet[k] = JacDet(jacIdeal); + valid = valid ? jacDet[k] > 0.0 : false; + } + + if (!valid) + { + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + NekDouble de = 1e-2; + NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + integral += derivUtil->quadW[k]*fabs(data[i]->maps[k][9])*(frob[k] / sigma); + } + } + else + { + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + integral += derivUtil->quadW[k]*fabs(data[i]->maps[k][9])*(frob[k] / jacDet[k]); + } + } + } + break; + } + } + + return integral; +} + +NodeOptiJob* NodeOpti::GetJob() +{ + return new NodeOptiJob(*this); +} + +} +} diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h new file mode 100644 index 000000000..f72f424ff --- /dev/null +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h @@ -0,0 +1,155 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessJac.h +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Calculate jacobians of elements. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTILITIES_NEKMESH_NODEOPTI +#define UTILITIES_NEKMESH_NODEOPTI + +#include "../../Module.h" +#include "ProcessVarOpti.h" + +namespace Nektar +{ +namespace Utilities +{ + +class NodeOptiJob; + +class NodeOpti +{ +public: + NodeOpti(NodeSharedPtr n, vector e, + ResidualSharedPtr r, DerivUtilSharedPtr d, + PtsHelperSharedPtr p, optimiser o) + : node(n), data(e), res(r), derivUtil(d), ptsHelp(p), opti(o) + { + } + + virtual ~NodeOpti(){}; + + virtual void Optimise(){}; + NodeOptiJob *GetJob(); +protected: + virtual Array GetGrad() + { + return Array(); + } + template NekDouble GetFunctional(); + NodeSharedPtr node; + vector data; + + ResidualSharedPtr res; + DerivUtilSharedPtr derivUtil; + PtsHelperSharedPtr ptsHelp; + optimiser opti; +}; + +/*class NodeOpti1D3D : public NodeOpti //1D optimsation in 3D space +{ +public: + NodeOpti1D3D(NodeSharedPtr n, vector e, + ResidualSharedPtr r, DerivUtilSharedPtr d, + PtsHelperSharedPtr p, optimiser o) + : node(n), data(e), res(r), derivUtil(d), ptsHelp(p), opti(o) + { + } + + ~NodeOpti1D3D(){}; + + void Optimise(); + +private: + NekDouble GetFunctional(); + Array GetGrad(); +}; + +class NodeOpti2D3D : public NodeOpti //1D optimsation in 3D space +{ +public: + NodeOpti2D3D(NodeSharedPtr n, vector e, + ResidualSharedPtr r, DerivUtilSharedPtr d, + PtsHelperSharedPtr p, optimiser o) + : node(n), data(e), res(r), derivUtil(d), ptsHelp(p), opti(o) + { + } + + ~NodeOpti2D3D(){}; + + void Optimise(); + +private: + NekDouble GetFunctional(); + Array GetGrad(); +};*/ + +class NodeOpti3D3D : public NodeOpti //1D optimsation in 3D space +{ +public: + NodeOpti3D3D(NodeSharedPtr n, vector e, + ResidualSharedPtr r, DerivUtilSharedPtr d, + PtsHelperSharedPtr p, optimiser o) + : NodeOpti(n,e,r,d,p,o) + { + } + + ~NodeOpti3D3D(){}; + + void Optimise(); + +private: + Array GetGrad(); +}; + +class NodeOpti2D2D : public NodeOpti //1D optimsation in 3D space +{ +public: + NodeOpti2D2D(NodeSharedPtr n, vector e, + ResidualSharedPtr r, DerivUtilSharedPtr d, + PtsHelperSharedPtr p, optimiser o) + : NodeOpti(n,e,r,d,p,o) + { + } + + ~NodeOpti2D2D(){}; + + void Optimise(); + +private: + Array GetGrad(); +}; + +} +} + +#endif diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h new file mode 100644 index 000000000..aaace2065 --- /dev/null +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h @@ -0,0 +1,65 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessJac.h +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Calculate jacobians of elements. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTILITIES_NEKMESH_NODEOPTIJOB +#define UTILITIES_NEKMESH_NODEOPTIJOB + +#include "../../Module.h" +#include "NodeOpti.h" + +#include + +namespace Nektar +{ +namespace Utilities +{ + +class NodeOptiJob : public Thread::ThreadJob +{ +public: + NodeOptiJob(NodeOpti no) : node(no) {} + + void Run() + { + node.Optimise(); + } +private: + NodeOpti node; +}; + +} +} + +#endif diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp new file mode 100644 index 000000000..89b0f5c0e --- /dev/null +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp @@ -0,0 +1,948 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessJac.h +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Calculate jacobians of elements. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "ProcessVarOpti.h" + +#include +#include +#include +#include + +#include +#include + +namespace Nektar +{ +namespace Utilities +{ + +vector > ProcessVarOpti::GetColouredNodes() +{ + //this figures out the dirclet nodes and colors the others into paralell sets + NodeSet boundaryNodes; + + switch (m_mesh->m_spaceDim) + { + case 2: + { + EdgeSet::iterator it; + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + { + if((*it)->m_elLink.size() == 2) + { + continue; + } + + boundaryNodes.insert((*it)->m_n1); + boundaryNodes.insert((*it)->m_n2); + for(int i = 0; i < (*it)->m_edgeNodes.size(); i++) + { + boundaryNodes.insert((*it)->m_edgeNodes[i]); + } + } + break; + } + case 3: + { + FaceSet::iterator it; + for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) + { + if((*it)->m_elLink.size() == 2) + { + continue; + } + + vector vs = (*it)->m_vertexList; + for(int j = 0; j < vs.size(); j++) + { + boundaryNodes.insert(vs[j]); + } + + vector es = (*it)->m_edgeList; + for(int j = 0; j < es.size(); j++) + { + for(int k = 0; k < es[j]->m_edgeNodes.size(); k++) + { + boundaryNodes.insert(es[j]->m_edgeNodes[k]); + } + } + + for(int i = 0; i < (*it)->m_faceNodes.size(); i++) + { + boundaryNodes.insert((*it)->m_faceNodes[i]); + } + } + break; + } + default: + ASSERTL0(false,"space dim issue"); + } + + res->nDirc = boundaryNodes.size(); + + vector remain; + + NodeSet::iterator nit; + for (nit = m_mesh->m_vertexSet.begin(); nit != m_mesh->m_vertexSet.end(); ++nit) + { + NodeSet::iterator nit2 = boundaryNodes.find(*nit); + if(nit2 == boundaryNodes.end()) + { + remain.push_back(*nit); + } + } + + EdgeSet::iterator eit; + for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) + { + vector n = (*eit)->m_edgeNodes; + for(int j = 0; j < n.size(); j++) + { + NodeSet::iterator nit = boundaryNodes.find(n[j]); + if(nit == boundaryNodes.end()) + { + remain.push_back(n[j]); + } + } + } + + FaceSet::iterator fit; + for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) + { + for(int j = 0; j < (*fit)->m_faceNodes.size(); j++) + { + NodeSet::iterator nit = boundaryNodes.find((*fit)->m_faceNodes[j]); + if(nit == boundaryNodes.end()) + { + remain.push_back((*fit)->m_faceNodes[j]); + } + } + } + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + vector ns = + m_mesh->m_element[m_mesh->m_expDim][i]->GetVolumeNodes(); + for(int j = 0; j < ns.size(); j++) + { + NodeSet::iterator nit = boundaryNodes.find(ns[j]); + if(nit == boundaryNodes.end()) + { + remain.push_back(ns[j]); + } + } + } + + res->n = remain.size(); + res->nDoF = res->n * m_mesh->m_spaceDim; + + vector > ret; + + while (remain.size() > 0) + { + vector layer; + set locked; + set completed; + for(int i = 0; i < remain.size(); i++) + { + NodeElMap::iterator it = nodeElMap.find(remain[i]->m_id); + ASSERTL0(it != nodeElMap.end(),"could not find"); + bool islocked = false; + for(int j = 0; j < it->second.size(); j++) + { + set::iterator sit = locked.find(it->second[j]->el->GetId()); + if(sit != locked.end()) + { + islocked = true; + break; + } + } + if(!islocked) + { + layer.push_back(remain[i]); + completed.insert(remain[i]->m_id); + for(int j = 0; j < it->second.size(); j++) + { + locked.insert(it->second[j]->el->GetId()); + } + } + } + + vector tmp = remain; + remain.clear(); + for(int i = 0; i < tmp.size(); i++) + { + set::iterator sit = completed.find(tmp[i]->m_id); + if(sit == completed.end()) + { + remain.push_back(tmp[i]); + } + } + ret.push_back(layer); + } + return ret; +} + +void ProcessVarOpti::GetElementMap() +{ + //build ideal maps and structs; + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + vector ns; + el->GetCurvedNodes(ns); + ElDataSharedPtr d = boost::shared_ptr(new ElData(ns, m_mesh->m_spaceDim)); + d->el = el; + d->maps = MappingIdealToRef(el); + dataSet.push_back(d); + } + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + vector ns; + el->GetCurvedNodes(ns); + + for(int j = 0; j < ns.size(); j++) + { + nodeElMap[ns[j]->m_id].push_back(dataSet[i]); + } + } +} + +vector > ProcessVarOpti::MappingIdealToRef(ElementSharedPtr el) +{ + //need to make ideal element out of old element + ElmtConfig ec = el->GetConf(); + ec.m_order = 1; + ec.m_faceNodes = false; + ec.m_volumeNodes = false; + ec.m_reorient = false; + + ElementSharedPtr E = GetElementFactory().CreateInstance( + ec.m_e, ec, el->GetVertexList(), + el->GetTagList()); + + SpatialDomains::GeometrySharedPtr geom = E->GetGeom(el->GetDim()); + geom->FillGeom(); + StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); + + vector > ret; + + if(geom->GetShapeType() == LibUtilities::eQuadrilateral) + { + ASSERTL0(false,"Not coded"); + /*vector > xy; + for(int i = 0; i < geom->GetNumVerts(); i++) + { + Array loc(2); + SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); + p->GetCoords(loc); + xy.push_back(loc); + } + + Array b = chi->GetBase(); + Array u = b[0]->GetZ(); + Array v = b[1]->GetZ(); + + for(int j = 0; j < b[1]->GetNumPoints(); j++) + { + for(int i = 0; i < b[0]->GetNumPoints(); i++) + { + NekDouble a1 = 0.5*(1.0-u[i]), a2 = 0.5*(1.0+u[i]); + NekDouble b1 = 0.5*(1.0-v[j]), b2 = 0.5*(1.0+v[j]); + DNekMat dxdz(2,2,1.0,eFULL); + + dxdz(0,0) = 0.5*(-b1*xy[0][0] + b1*xy[1][0] + b2*xy[2][0] - b2*xy[3][0]); + dxdz(1,0) = 0.5*(-b1*xy[0][1] + b1*xy[1][1] + b2*xy[2][1] - b2*xy[3][1]); + + dxdz(0,1) = 0.5*(-a1*xy[0][0] - a2*xy[1][0] + a2*xy[2][0] + a1*xy[3][0]); + dxdz(1,1) = 0.5*(-a1*xy[0][1] - a2*xy[1][1] + a2*xy[2][1] + a1*xy[3][1]); + + NekDouble det = 1.0/(dxdz(0,0)*dxdz(1,1) - dxdz(1,0)*dxdz(0,1)); + + dxdz.Invert(); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + ret.push_back(r); + } + }*/ + } + else if(geom->GetShapeType() == LibUtilities::eTriangle) + { + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + Array u, v; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v); + + Array xc(chi->GetTotPoints()); + Array yc(chi->GetTotPoints()); + + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + + chi->BwdTrans(coeffs0,xc); + chi->BwdTrans(coeffs1,yc); + + NekVector X(ptsHelp->ptsLow),Y(ptsHelp->ptsLow); + for(int j = 0; j < u.num_elements(); j++) + { + Array xp(2); + xp[0] = u[j]; + xp[1] = v[j]; + + X(j) = chi->PhysEvaluate(xp, xc); + Y(j) = chi->PhysEvaluate(xp, yc); + } + + NekVector x1i(ptsHelp->ptsHigh),y1i(ptsHelp->ptsHigh), + x2i(ptsHelp->ptsHigh),y2i(ptsHelp->ptsHigh); + + x1i = derivUtil->VdmD[0]*X; + y1i = derivUtil->VdmD[0]*Y; + x2i = derivUtil->VdmD[1]*X; + y2i = derivUtil->VdmD[1]*Y; + + for(int i = 0 ; i < ptsHelp->ptsHigh; i++) + { + DNekMat dxdz(2,2,1.0,eFULL); + dxdz(0,0) = x1i(i); + dxdz(0,1) = x2i(i); + dxdz(1,0) = y1i(i); + dxdz(1,1) = y2i(i); + + Array r(10,0.0); + r[9] = dxdz(0,0)*dxdz(1,1)-dxdz(1,0)*dxdz(0,1); + + dxdz.Invert(); + + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + ret.push_back(r); + } + } + else if(geom->GetShapeType() == LibUtilities::eTetrahedron) + { + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + Array u, v, w; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); + + Array xc(chi->GetTotPoints()); + Array yc(chi->GetTotPoints()); + Array zc(chi->GetTotPoints()); + + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); + + chi->BwdTrans(coeffs0,xc); + chi->BwdTrans(coeffs1,yc); + chi->BwdTrans(coeffs2,zc); + + NekVector X(ptsHelp->ptsLow),Y(ptsHelp->ptsLow),Z(ptsHelp->ptsLow); + for(int j = 0; j < u.num_elements(); j++) + { + Array xp(3); + xp[0] = u[j]; + xp[1] = v[j]; + xp[2] = w[j]; + + X(j) = chi->PhysEvaluate(xp, xc); + Y(j) = chi->PhysEvaluate(xp, yc); + Z(j) = chi->PhysEvaluate(xp, zc); + } + + NekVector x1i(ptsHelp->ptsHigh),y1i(ptsHelp->ptsHigh),z1i(ptsHelp->ptsHigh), + x2i(ptsHelp->ptsHigh),y2i(ptsHelp->ptsHigh),z2i(ptsHelp->ptsHigh), + x3i(ptsHelp->ptsHigh),y3i(ptsHelp->ptsHigh),z3i(ptsHelp->ptsHigh); + + x1i = derivUtil->VdmD[0]*X; + y1i = derivUtil->VdmD[0]*Y; + z1i = derivUtil->VdmD[0]*Z; + x2i = derivUtil->VdmD[1]*X; + y2i = derivUtil->VdmD[1]*Y; + z2i = derivUtil->VdmD[1]*Z; + x3i = derivUtil->VdmD[2]*X; + y3i = derivUtil->VdmD[2]*Y; + z3i = derivUtil->VdmD[2]*Z; + + for(int i = 0 ; i < ptsHelp->ptsHigh; i++) + { + DNekMat dxdz(3,3,1.0,eFULL); + dxdz(0,0) = x1i(i); + dxdz(0,1) = x2i(i); + dxdz(0,2) = x3i(i); + dxdz(1,0) = y1i(i); + dxdz(1,1) = y2i(i); + dxdz(1,2) = y3i(i); + dxdz(2,0) = z1i(i); + dxdz(2,1) = z2i(i); + dxdz(2,2) = z3i(i); + + Array r(10,0.0); //store det in 10th entry + + r[9] = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) + -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) + +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); + + dxdz.Invert(); + + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[2] = dxdz(2,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + r[5] = dxdz(2,1); + r[6] = dxdz(0,2); + r[7] = dxdz(1,2); + r[8] = dxdz(2,2); + ret.push_back(r); + } + } + else if(geom->GetShapeType() == LibUtilities::ePrism) + { + ASSERTL0(false, "not coded"); + /*vector > xyz; + for(int i = 0; i < geom->GetNumVerts(); i++) + { + Array loc(3); + SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); + p->GetCoords(loc); + xyz.push_back(loc); + } + + Array b = chi->GetBase(); + Array eta1 = b[0]->GetZ(); + Array eta2 = b[1]->GetZ(); + Array eta3 = b[2]->GetZ(); + + for(int k = 0; k < b[2]->GetNumPoints(); k++) + { + + for(int j = 0; j < b[1]->GetNumPoints(); j++) + { + for(int i = 0; i < b[0]->GetNumPoints(); i++) + { + NekDouble xi1 = 0.5*(1+eta1[i])*(1-eta3[k])-1.0; + NekDouble a1 = 0.5*(1-xi1), a2 = 0.5*(1+xi1); + NekDouble b1 = 0.5*(1-eta2[j]), b2 = 0.5*(1+eta2[j]); + NekDouble c1 = 0.5*(1-eta3[k]), c2 = 0.5*(1+eta3[k]); + + DNekMat dxdz(3,3,1.0,eFULL); + + dxdz(0,0) = 0.5*(-b1*xyz[0][0] + b1*xyz[1][0] + b2*xyz[2][0] - b2*xyz[3][0]); + dxdz(1,0) = 0.5*(-b1*xyz[0][1] + b1*xyz[1][1] + b2*xyz[2][1] - b2*xyz[3][1]); + dxdz(2,0) = 0.5*(-b1*xyz[0][2] + b1*xyz[1][2] + b2*xyz[2][2] - b2*xyz[3][2]); + + dxdz(0,1) = 0.5*((a2-c1)*xyz[0][0] - a2*xyz[1][0] + a2*xyz[2][0] + (c1-a2)*xyz[3][0] - c2*xyz[4][0] + c2*xyz[5][0]); + dxdz(1,1) = 0.5*((a2-c1)*xyz[0][1] - a2*xyz[1][1] + a2*xyz[2][1] + (c1-a2)*xyz[3][1] - c2*xyz[4][1] + c2*xyz[5][1]); + dxdz(2,1) = 0.5*((a2-c1)*xyz[0][2] - a2*xyz[1][2] + a2*xyz[2][2] + (c1-a2)*xyz[3][2] - c2*xyz[4][2] + c2*xyz[5][2]); + + dxdz(0,2) = 0.5*(-b1*xyz[0][0] - b2*xyz[3][0] + b1*xyz[4][0] + b2*xyz[5][0]); + dxdz(1,2) = 0.5*(-b1*xyz[0][1] - b2*xyz[3][1] + b1*xyz[4][1] + b2*xyz[5][1]); + dxdz(2,2) = 0.5*(-b1*xyz[0][2] - b2*xyz[3][2] + b1*xyz[4][2] + b2*xyz[5][2]); + + dxdz.Invert(); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + r[2] = dxdz(2,0); + r[5] = dxdz(2,1); + r[6] = dxdz(0,2); + r[7] = dxdz(1,2); + r[8] = dxdz(2,2); + ret.push_back(r); + } + } + }*/ + } + else + { + ASSERTL0(false,"not coded"); + } + + return ret; +} + +void ProcessVarOpti::FillQuadPoints() +{ + int nq = m_mesh->m_nummode; + int id = m_mesh->m_vertexSet.size(); + + LibUtilities::PointsKey ekey(m_mesh->m_nummode, + LibUtilities::eGaussLobattoLegendre); + Array gll; + LibUtilities::PointsManager()[ekey]->GetPoints(gll); + + EdgeSet::iterator eit; + FaceSet::iterator fit; + + boost::unordered_map edgeGeoms; + boost::unordered_map faceGeoms; + boost::unordered_map volGeoms; + + for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) + { + SpatialDomains::Geometry1DSharedPtr geom = + (*eit)->GetGeom(m_mesh->m_spaceDim); + geom->FillGeom(); + edgeGeoms[(*eit)->m_id] = geom; + } + + for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++) + { + SpatialDomains::Geometry2DSharedPtr geom = + (*fit)->GetGeom(m_mesh->m_spaceDim); + geom->FillGeom(); + faceGeoms[(*fit)->m_id] = geom; + } + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + SpatialDomains::GeometrySharedPtr geom = + el->GetGeom(m_mesh->m_spaceDim); + geom->FillGeom(); + volGeoms[el->GetId()] = geom; + } + + for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) + { + SpatialDomains::Geometry1DSharedPtr geom = edgeGeoms[(*eit)->m_id]; + StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); + + vector hons; + + switch (m_mesh->m_spaceDim) + { + case 2: + { + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + + for(int j = 1; j < m_mesh->m_nummode - 1; j++) + { + Array xp(2); + xp[0] = gll[j]; + + hons.push_back(boost::shared_ptr(new Node( + id++,xmap->PhysEvaluate(xp,xc), + xmap->PhysEvaluate(xp,yc),0.0))); + } + (*eit)->m_edgeNodes.clear(); + (*eit)->m_edgeNodes = hons; + (*eit)->m_curveType = LibUtilities::eGaussLobattoLegendre; + } + break; + case 3: + { + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); + + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); + Array zc(xmap->GetTotPoints()); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + xmap->BwdTrans(coeffs2,zc); + + for(int j = 1; j < m_mesh->m_nummode - 1; j++) + { + Array xp(2); + xp[0] = gll[j]; + + hons.push_back(boost::shared_ptr(new Node( + id++,xmap->PhysEvaluate(xp,xc), + xmap->PhysEvaluate(xp,yc), + xmap->PhysEvaluate(xp,zc)))); + } + (*eit)->m_edgeNodes.clear(); + (*eit)->m_edgeNodes = hons; + (*eit)->m_curveType = LibUtilities::eGaussLobattoLegendre; + } + break; + } + } + + if(m_mesh->m_expDim == 2) + { + //for faces need to do volume nodes + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + + SpatialDomains::GeometrySharedPtr geom = volGeoms[el->GetId()]; + StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); + + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + Array u, v; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v); + + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + + vector hons; + + for(int j = 3 + 3*(nq-2); j < u.num_elements(); j++) + { + Array xp(2); + xp[0] = u[j]; + xp[1] = v[j]; + + hons.push_back(boost::shared_ptr(new Node( + id++,xmap->PhysEvaluate(xp,xc), + xmap->PhysEvaluate(xp,yc),0.0))); + } + + el->SetVolumeNodes(hons); + el->SetCurveType(LibUtilities::eNodalTriElec); + } + } + else + { + FaceSet::iterator it; + for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) + { + SpatialDomains::Geometry2DSharedPtr geom = faceGeoms[(*it)->m_id]; + StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); + + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + Array u, v; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v); + + vector hons; + + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); + + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); + Array zc(xmap->GetTotPoints()); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + xmap->BwdTrans(coeffs2,zc); + + for(int j = 3 + 3*(nq-2); j < u.num_elements(); j++) + { + Array xp(2); + xp[0] = u[j]; + xp[1] = v[j]; + + hons.push_back(boost::shared_ptr(new Node( + id++,xmap->PhysEvaluate(xp,xc), + xmap->PhysEvaluate(xp,yc), + xmap->PhysEvaluate(xp,zc)))); + } + (*it)->m_faceNodes.clear(); + (*it)->m_faceNodes = hons; + (*it)->m_curveType = LibUtilities::eNodalTriElec; + } + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + + SpatialDomains::GeometrySharedPtr geom = volGeoms[el->GetId()]; + StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); + + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + Array u, v, w; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); + + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); + + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); + Array zc(xmap->GetTotPoints()); + + xmap->BwdTrans(coeffs0,xc); + xmap->BwdTrans(coeffs1,yc); + xmap->BwdTrans(coeffs2,zc); + + vector hons; + + //need to finish for tet + for(int j = 4 + 6*(nq-2) + 4 * ((nq-2)*(nq-3) / 2); + j < u.num_elements(); j++) + { + Array xp(3); + xp[0] = u[j]; + xp[1] = v[j]; + xp[2] = w[j]; + + hons.push_back(boost::shared_ptr(new Node( + id++,xmap->PhysEvaluate(xp,xc), + xmap->PhysEvaluate(xp,yc), + xmap->PhysEvaluate(xp,zc)))); + } + + el->SetVolumeNodes(hons); + el->SetCurveType(LibUtilities::eNodalTetElec); + } + } + + EvaluateMesh(); +} + +void ProcessVarOpti::EvaluateMesh() +{ + res->startInv =0; + res->worstJac = numeric_limits::max(); + + if(m_mesh->m_expDim == 2) + { + LibUtilities::PointsKey pkey1(m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + Array u1, v1; + + LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); + + NekVector U1(u1), V1(v1); + + NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); + NekMatrix VandermondeI = Vandermonde; + VandermondeI.Invert(); + NekMatrix VdmDxt = ( + LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI); + NekMatrix VdmDyt = ( + LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI); + + + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + + vector ns; + el->GetCurvedNodes(ns); + + NekDouble mx = -1.0 * numeric_limits::max(); + NekDouble mn = numeric_limits::max(); + + + NekVector X(u1.num_elements()),Y(u1.num_elements()); + for(int j = 0; j < u1.num_elements(); j++) + { + X(j) = ns[j]->m_x; + Y(j) = ns[j]->m_y; + } + + NekVector x1i(u1.num_elements()),y1i(u1.num_elements()), + x2i(u1.num_elements()),y2i(u1.num_elements()); + + x1i = VdmDxt*X; + y1i = VdmDxt*Y; + x2i = VdmDyt*X; + y2i = VdmDyt*Y; + + for(int j = 0; j < u1.num_elements(); j++) + { + NekDouble jacDet = x1i(j) * y2i(j) - x2i(j)*y1i(j); + mx = max(mx,jacDet); + mn = min(mn,jacDet); + } + + if(mn < 0) + { + res->startInv++; + } + res->worstJac = min(res->worstJac,mn/mx); + } + } + else + { + LibUtilities::PointsKey pkey1(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + Array u1, v1,w1; + + LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1,w1); + + NekVector U1(u1), V1(v1), W1(w1); + + NekMatrix Vandermonde = LibUtilities::GetTetVandermonde(U1,V1,W1); + NekMatrix VandermondeI = Vandermonde; + VandermondeI.Invert(); + NekMatrix VdmDxt = ( + LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI); + NekMatrix VdmDyt = ( + LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI); + NekMatrix VdmDzt = ( + LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI); + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; + + vector ns; + el->GetCurvedNodes(ns); + + NekDouble mx = -1.0 * numeric_limits::max(); + NekDouble mn = numeric_limits::max(); + + NekVector X(u1.num_elements()),Y(u1.num_elements()),Z(u1.num_elements()); + for(int j = 0; j < u1.num_elements(); j++) + { + X(j) = ns[j]->m_x; + Y(j) = ns[j]->m_y; + Z(j) = ns[j]->m_z; + } + + NekVector x1i(u1.num_elements()),y1i(u1.num_elements()),z1i(u1.num_elements()), + x2i(u1.num_elements()),y2i(u1.num_elements()),z2i(u1.num_elements()), + x3i(u1.num_elements()),y3i(u1.num_elements()),z3i(u1.num_elements()); + + x1i = VdmDxt*X; + y1i = VdmDxt*Y; + z1i = VdmDxt*Z; + x2i = VdmDyt*X; + y2i = VdmDyt*Y; + z2i = VdmDyt*Z; + x3i = VdmDzt*X; + y3i = VdmDzt*Y; + z3i = VdmDzt*Z; + + for(int j = 0; j < u1.num_elements(); j++) + { + + DNekMat dxdz(3,3,1.0,eFULL); + dxdz(0,0) = x1i(j); + dxdz(0,1) = x2i(j); + dxdz(0,2) = x3i(j); + dxdz(1,0) = y1i(j); + dxdz(1,1) = y2i(j); + dxdz(1,2) = y3i(j); + dxdz(2,0) = z1i(j); + dxdz(2,1) = z2i(j); + dxdz(2,2) = z3i(j); + + NekDouble jacDet = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) + -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) + +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); + + mx = max(mx,jacDet); + mn = min(mn,jacDet); + } + + + + if(mn < 0) + { + res->startInv++; + } + + res->worstJac = min(res->worstJac,mn/mx); + } + } +} + +void ProcessVarOpti::WriteStats(string file) +{ + ASSERTL0(file != "", "no file name given"); + + ofstream out; + out.open(file.c_str()); + out << scientific; + + for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) + { + vector ns; + m_mesh->m_element[m_mesh->m_expDim][i]->GetCurvedNodes(ns); + int pts = ns.size(); + int dim = m_mesh->m_element[m_mesh->m_expDim][i]->GetDim(); + + NekDouble mx = -1.0 * numeric_limits::max(); + NekDouble mn = numeric_limits::max(); + + if(dim == 2) + { + NekVector X(pts),Y(pts),Z(pts), + x1(pts),y1(pts), + x2(pts),y2(pts); + for(int i = 0; i < pts; i++) + { + X(i) = ns[i]->m_x; + Y(i) = ns[i]->m_y; + } + + x1 = derivUtil->VdmD[0]*X; + y1 = derivUtil->VdmD[0]*Y; + x2 = derivUtil->VdmD[0]*X; + y2 = derivUtil->VdmD[0]*Y; + + for(int i = 0; i < pts; i++) + { + mx = max(mx, x1(i)*y2(i)-y1(i)*x2(i)); + mn = min(mn, x1(i)*y2(i)-y1(i)*x2(i)); + } + + } + else + { + ASSERTL0(false,"not coded"); + } + out << mn / mx << endl; + } +} + +} +} -- GitLab From 67292065563fe94dda0385a51a6543d31f4912f1 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 27 Jun 2016 17:27:02 +0100 Subject: [PATCH 049/236] included cad logic to free node filtering and colouring --- .../ProcessVarOpti/ProcessVarOpti.cpp | 1 - .../ProcessVarOpti/ProcessVarOpti.h | 1 - .../ProcessModules/ProcessVarOpti/Utils.cpp | 129 ++++++++++++------ 3 files changed, 87 insertions(+), 44 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp index 9dc92a02e..f0ed8d8d6 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp @@ -239,7 +239,6 @@ void ProcessVarOpti::Process() << "Worst jacobian:\t\t" << res->worstJac << endl << "N free nodes:\t\t" << res->n << endl << "N Dof:\t\t\t" << res->nDoF << endl - << "N Dirclet:\t\t" << res->nDirc << endl << "N color sets:\t\t" << nset << endl << "Avg set colors:\t\t" << p/nset << endl << "Min set:\t\t" << mn << endl diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h index 43a8c7513..de5512b7d 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h @@ -97,7 +97,6 @@ struct Residual { NekDouble val; int n; - int nDirc; int nDoF; int startInv; NekDouble worstJac; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp index 89b0f5c0e..18f505f03 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp @@ -53,66 +53,80 @@ vector > ProcessVarOpti::GetColouredNodes() //this figures out the dirclet nodes and colors the others into paralell sets NodeSet boundaryNodes; - switch (m_mesh->m_spaceDim) + if(!m_mesh->m_hasCAD) { - case 2: + switch (m_mesh->m_spaceDim) { - EdgeSet::iterator it; - for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) + case 2: { - if((*it)->m_elLink.size() == 2) + EdgeSet::iterator it; + for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) { - continue; - } + if((*it)->m_elLink.size() == 2) + { + continue; + } - boundaryNodes.insert((*it)->m_n1); - boundaryNodes.insert((*it)->m_n2); - for(int i = 0; i < (*it)->m_edgeNodes.size(); i++) - { - boundaryNodes.insert((*it)->m_edgeNodes[i]); + boundaryNodes.insert((*it)->m_n1); + boundaryNodes.insert((*it)->m_n2); + for(int i = 0; i < (*it)->m_edgeNodes.size(); i++) + { + boundaryNodes.insert((*it)->m_edgeNodes[i]); + } } + break; } - break; - } - case 3: - { - FaceSet::iterator it; - for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) + case 3: { - if((*it)->m_elLink.size() == 2) + FaceSet::iterator it; + for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) { - continue; - } + if((*it)->m_elLink.size() == 2) + { + continue; + } - vector vs = (*it)->m_vertexList; - for(int j = 0; j < vs.size(); j++) - { - boundaryNodes.insert(vs[j]); - } + vector vs = (*it)->m_vertexList; + for(int j = 0; j < vs.size(); j++) + { + boundaryNodes.insert(vs[j]); + } - vector es = (*it)->m_edgeList; - for(int j = 0; j < es.size(); j++) - { - for(int k = 0; k < es[j]->m_edgeNodes.size(); k++) + vector es = (*it)->m_edgeList; + for(int j = 0; j < es.size(); j++) { - boundaryNodes.insert(es[j]->m_edgeNodes[k]); + for(int k = 0; k < es[j]->m_edgeNodes.size(); k++) + { + boundaryNodes.insert(es[j]->m_edgeNodes[k]); + } } - } - for(int i = 0; i < (*it)->m_faceNodes.size(); i++) - { - boundaryNodes.insert((*it)->m_faceNodes[i]); + for(int i = 0; i < (*it)->m_faceNodes.size(); i++) + { + boundaryNodes.insert((*it)->m_faceNodes[i]); + } } + break; + } + default: + ASSERTL0(false,"space dim issue"); + } + } + else + { + //if we have CAD we are 3D and therefore the only fixed nodes exist on vertices only + NodeSet::iterator nit; + for (nit = m_mesh->m_vertexSet.begin(); nit != m_mesh->m_vertexSet.end(); ++nit) + { + if((*nit)->GetNumCadCurve() > 1) + { + boundaryNodes.insert((*nit)); } - break; } - default: - ASSERTL0(false,"space dim issue"); } - - res->nDirc = boundaryNodes.size(); vector remain; + res->nDoF = 0; NodeSet::iterator nit; for (nit = m_mesh->m_vertexSet.begin(); nit != m_mesh->m_vertexSet.end(); ++nit) @@ -121,6 +135,18 @@ vector > ProcessVarOpti::GetColouredNodes() if(nit2 == boundaryNodes.end()) { remain.push_back(*nit); + if((*nit)->GetNumCadCurve() == 1) + { + res->nDoF++; + } + else if((*nit)->GetNumCADSurf() == 1) + { + res->nDoF += 2; + } + else + { + res->nDoF += 3; + } } } @@ -134,6 +160,18 @@ vector > ProcessVarOpti::GetColouredNodes() if(nit == boundaryNodes.end()) { remain.push_back(n[j]); + if(n[j]->GetNumCadCurve() == 1) + { + res->nDoF++; + } + else if(n[j]->GetNumCADSurf() == 1) + { + res->nDoF += 2; + } + else + { + res->nDoF += 3; + } } } } @@ -147,6 +185,14 @@ vector > ProcessVarOpti::GetColouredNodes() if(nit == boundaryNodes.end()) { remain.push_back((*fit)->m_faceNodes[j]); + if((*fit)->m_faceNodes[j]->GetNumCADSurf() == 1) + { + res->nDoF += 2; + } + else + { + res->nDoF += 3; + } } } } @@ -161,12 +207,12 @@ vector > ProcessVarOpti::GetColouredNodes() if(nit == boundaryNodes.end()) { remain.push_back(ns[j]); + res->nDoF += 3; } } } res->n = remain.size(); - res->nDoF = res->n * m_mesh->m_spaceDim; vector > ret; @@ -217,7 +263,6 @@ vector > ProcessVarOpti::GetColouredNodes() void ProcessVarOpti::GetElementMap() { - //build ideal maps and structs; for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) { ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; -- GitLab From 66172f888237d89c4936f056282640e382fc03ff Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Tue, 28 Jun 2016 15:55:31 +0100 Subject: [PATCH 050/236] fill code, didnt work --- library/NekMeshUtils/MeshElements/Node.h | 10 + .../ProcessVarOpti/NodeOpti.cpp | 205 +++++++++++++++++- .../ProcessModules/ProcessVarOpti/NodeOpti.h | 18 +- .../ProcessVarOpti/ProcessVarOpti.cpp | 26 ++- .../ProcessVarOpti/ProcessVarOpti.h | 6 - 5 files changed, 241 insertions(+), 24 deletions(-) diff --git a/library/NekMeshUtils/MeshElements/Node.h b/library/NekMeshUtils/MeshElements/Node.h index 43f941d92..538205f82 100644 --- a/library/NekMeshUtils/MeshElements/Node.h +++ b/library/NekMeshUtils/MeshElements/Node.h @@ -321,6 +321,16 @@ public: std::pair >(su, uv); } + void MoveCurve(Array l, int s, NekDouble t) + { + m_x = l[0]; + m_y = l[1]; + m_z = l[2]; + CADCurveSharedPtr cu = CADCurveList[s].first; + CADCurveList[s] = + std::pair(cu, t); + } + vector GetCADString() { vector ret; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index d9e68ccc8..bd73d4303 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -36,6 +36,9 @@ #include "NodeOpti.h" #include "NodeOptiJob.h" +using namespace std; +using namespace Nektar::NekMeshUtils; + namespace Nektar { namespace Utilities @@ -143,6 +146,119 @@ void NodeOpti3D3D::Optimise() } } +void NodeOpti1D3D::Optimise() +{ + Array G = GetGrad(); + + if(sqrt(G[0]*G[0]) > 1e-10) + { + //needs to optimise + NekDouble tc = node->GetCADCurveInfo(curve->GetId()); + NekDouble currentW = GetFunctional<3>(); + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble zc = node->m_z; + NekDouble alpha = 1.0; + NekDouble delT; + NekDouble nt; + Array p; + + delT = G[0] / G[1]; + + bool found = false; + while(alpha > 1e-10) + { + nt = tc - alpha * delT; + p = curve->P(nt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + if(GetFunctional<3>() < currentW) + { + found = true; + break; + } + + alpha /= 2.0; + } + + if(!found) + { + //reset the node + nt = tc; + p = curve->P(nt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + // cout << "warning: had to reset node" << endl; + } + else + { + node->MoveCurve(p,curve->GetId(),nt); + } + mtx.lock(); + res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ + (node->m_z-zc)*(node->m_z-zc)),res->val); + mtx.unlock(); + } +} + +void NodeOpti2D3D::Optimise() +{ + Array G = GetGrad(); + + if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-10) + { + //needs to optimise + Array uvc = node->GetCADSurfInfo(surf->GetId()); + NekDouble currentW = GetFunctional<3>(); + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble zc = node->m_z; + NekDouble alpha = 1.0; + Array uvt(2); + Array p; + NekDouble delU = 1.0/(G[2]*G[3]-G[4]*G[4])*(G[3]*G[0] - G[4]*G[1]); + NekDouble delV = 1.0/(G[2]*G[3]-G[4]*G[4])*(G[2]*G[1] - G[4]*G[0]); + + bool found = false; + while(alpha > 1e-10) + { + uvt[0] = uvc[0] - alpha * delU; + uvt[1] = uvc[1] - alpha * delV; + p = surf->P(uvt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + if(GetFunctional<3>() < currentW) + { + found = true; + break; + } + + alpha /= 2.0; + } + + if(!found) + { + //reset the node + p = surf->P(uvc); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + // cout << "warning: had to reset node" << endl; + } + else + { + node->Move(p,surf->GetId(),uvt); + } + mtx.lock(); + res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ + (node->m_z-zc)*(node->m_z-zc)),res->val); + mtx.unlock(); + } +} + NekDouble dir[13][3] = {{ 0.0, 0.0, 0.0 }, // 0 (x , y , z ) { 1.0, 0.0, 0.0 }, // 1 (x+dx, y , z ) { 1.0, 1.0, 0.0 }, // 2 (x+dx, y+dy, z ) @@ -157,6 +273,80 @@ NekDouble dir[13][3] = {{ 0.0, 0.0, 0.0 }, // 0 (x , y , z ) { 0.0, 1.0, 1.0 }, // 11 (x , y+dy, z+dz) { 0.0, -1.0, -1.0 }}; // 12 (x , y-dy, z-dz) +Array NodeOpti1D3D::GetGrad() +{ + NekDouble tc = node->GetCADCurveInfo(curve->GetId()); + NekDouble dx = 1e-4; + vector w(3); + + w[0] = GetFunctional<3>(); + + NekDouble nt = tc + dx; + Array p = curve->P(nt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + w[1] = GetFunctional<3>(); + + nt = tc - dx; + p = curve->P(nt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + w[2] = GetFunctional<3>(); + + nt = tc; + p = curve->P(nt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + + Array ret(2,0.0); + + ret[0] = (w[1] - w[2]) / 2.0 / dx; + ret[1] = (w[1] + w[2] - 2.0*w[0]) / dx / dx; + + return ret; +} + +Array NodeOpti2D3D::GetGrad() +{ + Array uvc = node->GetCADSurfInfo(surf->GetId()); + NekDouble dx = 1e-4; + vector w(9); + + for(int i = 0; i < 7; i++) + { + Array uvt(2); + uvt[0] = uvc[0] + dir[i][0] * dx; + uvt[1] = uvc[1] + dir[i][1] * dx; + Array p = surf->P(uvt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + w[i] = GetFunctional<3>(); + } + + Array ret(5,0.0); + + //ret[0] d/dx + //ret[1] d/dy + //ret[2] d/dz + + //ret[3] d2/dx2 + //ret[4] d2/dy2 + //ret[5] d2/dxdy + + + ret[0] = (w[1] - w[4]) / 2.0 / dx; + ret[1] = (w[3] - w[6]) / 2.0 / dx; + ret[2] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; + ret[3] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; + ret[4] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / dx / dx; + + return ret; +} + Array NodeOpti2D2D::GetGrad() { NekDouble xc = node->m_x; @@ -173,24 +363,21 @@ Array NodeOpti2D2D::GetGrad() node->m_x = xc; node->m_y = yc; - Array ret(9,0.0); + Array ret(5,0.0); //ret[0] d/dx //ret[1] d/dy - //ret[2] d/dz //ret[3] d2/dx2 //ret[4] d2/dy2 - //ret[5] d2/dz2 - //ret[6] d2/dxdy - //ret[7] d2/dxdz - //ret[8] d2/dydz + //ret[5] d2/dxdy + ret[0] = (w[1] - w[4]) / 2.0 / dx; ret[1] = (w[3] - w[6]) / 2.0 / dx; - ret[3] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; - ret[4] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; - ret[6] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / dx / dx; + ret[2] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; + ret[3] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; + ret[4] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / dx / dx; return ret; } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h index f72f424ff..ad22fc675 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h @@ -39,6 +39,8 @@ #include "../../Module.h" #include "ProcessVarOpti.h" +#include + namespace Nektar { namespace Utilities @@ -75,13 +77,13 @@ protected: optimiser opti; }; -/*class NodeOpti1D3D : public NodeOpti //1D optimsation in 3D space +class NodeOpti1D3D : public NodeOpti //1D optimsation in 3D space { public: NodeOpti1D3D(NodeSharedPtr n, vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, - PtsHelperSharedPtr p, optimiser o) - : node(n), data(e), res(r), derivUtil(d), ptsHelp(p), opti(o) + PtsHelperSharedPtr p, optimiser o, CADCurveSharedPtr c) + : NodeOpti(n,e,r,d,p,o), curve(c) { } @@ -90,8 +92,8 @@ public: void Optimise(); private: - NekDouble GetFunctional(); Array GetGrad(); + CADCurveSharedPtr curve; }; class NodeOpti2D3D : public NodeOpti //1D optimsation in 3D space @@ -99,8 +101,8 @@ class NodeOpti2D3D : public NodeOpti //1D optimsation in 3D space public: NodeOpti2D3D(NodeSharedPtr n, vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, - PtsHelperSharedPtr p, optimiser o) - : node(n), data(e), res(r), derivUtil(d), ptsHelp(p), opti(o) + PtsHelperSharedPtr p, optimiser o, CADSurfSharedPtr s) + : NodeOpti(n,e,r,d,p,o), surf(s) { } @@ -109,9 +111,9 @@ public: void Optimise(); private: - NekDouble GetFunctional(); Array GetGrad(); -};*/ + CADSurfSharedPtr surf; +}; class NodeOpti3D3D : public NodeOpti //1D optimsation in 3D space { diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp index f0ed8d8d6..9cdbd5f36 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp @@ -217,7 +217,31 @@ void ProcessVarOpti::Process() { NodeElMap::iterator it = nodeElMap.find(freenodes[i][j]->m_id); ASSERTL0(it != nodeElMap.end(), "could not find"); - ns.push_back(NodeOpti(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti)); + if(freenodes[i][j]->GetNumCadCurve() == 0 && freenodes[i][j]->GetNumCadCurve() == 0) + { + if(m_mesh->m_spaceDim == 3) + { + ns.push_back(NodeOpti3D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti)); + } + else + { + ns.push_back(NodeOpti2D2D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti)); + } + } + else if(freenodes[i][j]->GetNumCadCurve() == 1) + { + vector > cs = freenodes[i][j]->GetCADCurves(); + ns.push_back(NodeOpti1D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti,cs[0].second)); + } + else if(freenodes[i][j]->GetNumCADSurf() == 1) + { + vector > ss = freenodes[i][j]->GetCADSurfs(); + ns.push_back(NodeOpti2D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti,ss[0].second)); + } + else + { + ASSERTL0(false,"unsure"); + } } optiNodes.push_back(ns); } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h index de5512b7d..f4415d990 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h @@ -104,12 +104,6 @@ struct Residual typedef boost::shared_ptr ResidualSharedPtr; -/** - * @brief This processing module calculates the Jacobian of elements - * using %SpatialDomains::GeomFactors and the %Element::GetGeom - * method. For now it simply prints a list of elements which have - * negative Jacobian. - */ class ProcessVarOpti : public ProcessModule { public: -- GitLab From dac83348ca2ece43a99fec61099827aeb1f670e5 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Sat, 2 Jul 2016 12:15:27 +0100 Subject: [PATCH 051/236] preprocessing logic now working, needs parameterisation logic for reverse line search --- utilities/NekMesh/InputModules/InputCAD.cpp | 1 + utilities/NekMesh/InputModules/InputNekpp.cpp | 14 ++++++-- .../NekMesh/OutputModules/OutputNekpp.cpp | 13 ++++--- .../ProcessVarOpti/NodeOpti.cpp | 2 +- .../ProcessModules/ProcessVarOpti/NodeOpti.h | 3 +- .../ProcessVarOpti/NodeOptiJob.h | 6 ++-- .../ProcessVarOpti/ProcessVarOpti.cpp | 34 ++++++++++++------- .../ProcessModules/ProcessVarOpti/Utils.cpp | 17 ++++++++++ 8 files changed, 66 insertions(+), 24 deletions(-) diff --git a/utilities/NekMesh/InputModules/InputCAD.cpp b/utilities/NekMesh/InputModules/InputCAD.cpp index 59c41f7ab..3ad2902f7 100644 --- a/utilities/NekMesh/InputModules/InputCAD.cpp +++ b/utilities/NekMesh/InputModules/InputCAD.cpp @@ -306,6 +306,7 @@ void InputCAD::Process() cout << endl; cout << m_mesh->m_element[3].size() << endl; } + } } } diff --git a/utilities/NekMesh/InputModules/InputNekpp.cpp b/utilities/NekMesh/InputModules/InputNekpp.cpp index f6c58acad..37c704d72 100644 --- a/utilities/NekMesh/InputModules/InputNekpp.cpp +++ b/utilities/NekMesh/InputModules/InputNekpp.cpp @@ -393,6 +393,7 @@ void InputNekpp::Process() vertToString[vid] = strs; vertex = vertex->NextSiblingElement("V"); + } TiXmlElement *edge = cad->FirstChildElement("E"); @@ -429,9 +430,9 @@ void InputNekpp::Process() int fid; - while(edge) + while(face) { - std::string f(edge->ValueStr()); + std::string f(face->ValueStr()); ASSERTL0(f == "F", (std::string("Unknown CAD type:") + f).c_str()); /// Read edge id attribute. @@ -468,6 +469,7 @@ void InputNekpp::Process() map, vector >::iterator fsit; { + int ct= 0; NodeSet::iterator it; for(it = m_mesh->m_vertexSet.begin(); it != m_mesh->m_vertexSet.end(); it++) @@ -475,6 +477,7 @@ void InputNekpp::Process() vsit = vertToString.find((*it)->m_id); if(vsit != vertToString.end()) { + ct++; for(int i = 0; i < vsit->second.size(); i++) { istringstream iss(vsit->second[i]); @@ -500,9 +503,11 @@ void InputNekpp::Process() } } } + ASSERTL0(ct == vertToString.size(), "did not find all CAD information"); } { + int ct = 0; EdgeSet::iterator it; for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++) @@ -512,6 +517,7 @@ void InputNekpp::Process() esit = edgeToString.find(pair((*it)->m_id,j)); if(esit != edgeToString.end()) { + ct++; for(int i = 0; i < esit->second.size(); i++) { istringstream iss(esit->second[i]); @@ -538,9 +544,11 @@ void InputNekpp::Process() } } } + ASSERTL0(ct == edgeToString.size(), "did not find all CAD information"); } { + int ct = 0; FaceSet::iterator it; for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) @@ -550,6 +558,7 @@ void InputNekpp::Process() fsit = faceToString.find(pair((*it)->m_id,j)); if(fsit != faceToString.end()) { + ct++; for(int i = 0; i < fsit->second.size(); i++) { istringstream iss(fsit->second[i]); @@ -576,6 +585,7 @@ void InputNekpp::Process() } } } + ASSERTL0(ct == faceToString.size(), "did not find all CAD information"); } #endif diff --git a/utilities/NekMesh/OutputModules/OutputNekpp.cpp b/utilities/NekMesh/OutputModules/OutputNekpp.cpp index 535ced287..80eaf250e 100644 --- a/utilities/NekMesh/OutputModules/OutputNekpp.cpp +++ b/utilities/NekMesh/OutputModules/OutputNekpp.cpp @@ -115,12 +115,12 @@ void OutputNekpp::Process() WriteXmlEdges(geomTag); WriteXmlFaces(geomTag); WriteXmlElements(geomTag); - WriteXmlCurves(geomTag); if(m_mesh->m_hasCAD) { WriteXmlCADId(geomTag); WriteXmlCAD(geomTag); } + WriteXmlCurves(geomTag); WriteXmlComposites(geomTag); WriteXmlDomain(geomTag); WriteXmlExpansions(root); @@ -1001,9 +1001,12 @@ void OutputNekpp::WriteXmlCAD(TiXmlElement *pRoot) TiXmlElement *cad = new TiXmlElement("CAD"); { - NodeSet::iterator it; - for (it = m_mesh->m_vertexSet.begin(); it != m_mesh->m_vertexSet.end(); - ++it) + std::set::iterator it; + + std::set tmp(m_mesh->m_vertexSet.begin(), + m_mesh->m_vertexSet.end()); + + for (it = tmp.begin(); it != tmp.end(); ++it) { if((*it)->GetNumCadCurve() > 0 || (*it)->GetNumCADSurf() > 0) { @@ -1025,7 +1028,7 @@ void OutputNekpp::WriteXmlCAD(TiXmlElement *pRoot) } } } - + { EdgeSet::iterator it; for (it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index bd73d4303..c6dee0bea 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -744,7 +744,7 @@ NekDouble NodeOpti::GetFunctional() NodeOptiJob* NodeOpti::GetJob() { - return new NodeOptiJob(*this); + return new NodeOptiJob(this); } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h index ad22fc675..f6dcbe9df 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h @@ -60,7 +60,7 @@ public: virtual ~NodeOpti(){}; - virtual void Optimise(){}; + virtual void Optimise() = 0; NodeOptiJob *GetJob(); protected: virtual Array GetGrad() @@ -80,6 +80,7 @@ protected: class NodeOpti1D3D : public NodeOpti //1D optimsation in 3D space { public: + NodeOpti1D3D(NodeSharedPtr n, vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, PtsHelperSharedPtr p, optimiser o, CADCurveSharedPtr c) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h index aaace2065..3b2fcf8a0 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h @@ -49,14 +49,14 @@ namespace Utilities class NodeOptiJob : public Thread::ThreadJob { public: - NodeOptiJob(NodeOpti no) : node(no) {} + NodeOptiJob(NodeOpti* no) : node(no) {} void Run() { - node.Optimise(); + node->Optimise(); } private: - NodeOpti node; + NodeOpti* node; }; } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp index 9cdbd5f36..51b1384f0 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp @@ -75,8 +75,6 @@ ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) ConfigOption(true, "", "Optimise for hyper elasticity"); m_config["numthreads"] = ConfigOption(false, "1", "Number of threads"); - m_config["nq"] = - ConfigOption(false, "0", "Number of quad points"); m_config["stats"] = ConfigOption(false, "", "Write a file with list of scaled jacobians"); m_config["restol"] = @@ -120,9 +118,20 @@ void ProcessVarOpti::Process() const int maxIter = m_config["maxiter"].as(); const NekDouble restol = m_config["restol"].as(); - m_mesh->m_nummode = m_config["nq"].as(); + EdgeSet::iterator eit; + bool fd = false; + for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) + { + if((*eit)->m_edgeNodes.size() > 0) + { + m_mesh->m_nummode = (*eit)->m_edgeNodes.size() + 2; + fd = true; + break; + } + } + ASSERTL0(fd,"failed to find order of mesh") - ASSERTL0(m_mesh->m_nummode > 2,"not specified high-order"); + cout << "Indentified order as: " << m_mesh->m_nummode - 1 << endl; if(m_mesh->m_expDim == 2 && m_mesh->m_spaceDim == 3) { @@ -208,35 +217,36 @@ void ProcessVarOpti::Process() GetElementMap(); vector > freenodes = GetColouredNodes(); - vector > optiNodes; + vector > optiNodes; for(int i = 0; i < freenodes.size(); i++) { - vector ns; + vector ns; for(int j = 0; j < freenodes[i].size(); j++) { NodeElMap::iterator it = nodeElMap.find(freenodes[i][j]->m_id); ASSERTL0(it != nodeElMap.end(), "could not find"); - if(freenodes[i][j]->GetNumCadCurve() == 0 && freenodes[i][j]->GetNumCadCurve() == 0) + + if(freenodes[i][j]->GetNumCadCurve() == 0 && freenodes[i][j]->GetNumCADSurf() == 0) { if(m_mesh->m_spaceDim == 3) { - ns.push_back(NodeOpti3D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti)); + ns.push_back(new NodeOpti3D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti)); } else { - ns.push_back(NodeOpti2D2D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti)); + ns.push_back(new NodeOpti2D2D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti)); } } else if(freenodes[i][j]->GetNumCadCurve() == 1) { vector > cs = freenodes[i][j]->GetCADCurves(); - ns.push_back(NodeOpti1D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti,cs[0].second)); + ns.push_back(new NodeOpti1D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti,cs[0].second)); } else if(freenodes[i][j]->GetNumCADSurf() == 1) { vector > ss = freenodes[i][j]->GetCADSurfs(); - ns.push_back(NodeOpti2D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti,ss[0].second)); + ns.push_back(new NodeOpti2D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti,ss[0].second)); } else { @@ -289,7 +299,7 @@ void ProcessVarOpti::Process() vector jobs(optiNodes[i].size()); for(int j = 0; j < optiNodes[i].size(); j++) { - jobs[j] = optiNodes[i][j].GetJob(); + jobs[j] = optiNodes[i][j]->GetJob(); } tm->SetNumWorkers(0); diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp index 18f505f03..404d214c5 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp @@ -593,6 +593,15 @@ void ProcessVarOpti::FillQuadPoints() for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) { + if((*eit)->m_edgeNodes.size() > 0) + { + //already high-order just need to Id + for(int i = 0; i < (*eit)->m_edgeNodes.size(); i++) + { + (*eit)->m_edgeNodes[i]->m_id = id++; + } + continue; + } SpatialDomains::Geometry1DSharedPtr geom = edgeGeoms[(*eit)->m_id]; StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); @@ -703,6 +712,14 @@ void ProcessVarOpti::FillQuadPoints() FaceSet::iterator it; for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) { + if((*it)->m_faceNodes.size() > 0) + { + for(int i = 0; i < (*it)->m_faceNodes.size(); i++) + { + (*it)->m_faceNodes[i]->m_id = id++; + } + continue; + } SpatialDomains::Geometry2DSharedPtr geom = faceGeoms[(*it)->m_id]; StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); -- GitLab From d2fa8970fb04157bb005c5974bd5fae7b5cdabc5 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 4 Jul 2016 10:32:24 +0100 Subject: [PATCH 052/236] CAD sliding workingmake install -j4! --- .../SurfaceMeshing/SurfaceMeshHOMesh.cpp | 4 +-- .../ProcessVarOpti/NodeOpti.cpp | 26 +++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp b/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp index 66b9a57d3..65109c7c2 100644 --- a/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp +++ b/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp @@ -253,7 +253,7 @@ void SurfaceMesh::HOSurf() LibUtilities::PointsManager()[ekey]->GetPoints(gll); LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriFekete); + LibUtilities::eNodalTriElec); Array u, v; int nq = m_mesh->m_nummode; @@ -692,7 +692,7 @@ void SurfaceMesh::HOSurf() } f->m_faceNodes = honodes; - f->m_curveType = LibUtilities::eNodalTriFekete; + f->m_curveType = LibUtilities::eNodalTriElec; } if (m_mesh->m_verbose) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index c6dee0bea..95e44a1ab 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -165,10 +165,17 @@ void NodeOpti1D3D::Optimise() delT = G[0] / G[1]; + Array bd = curve->Bounds(); + bool found = false; while(alpha > 1e-10) { nt = tc - alpha * delT; + if(nt < bd[0] || nt > bd[1]) + { + alpha /= 2.0; + continue; + } p = curve->P(nt); node->m_x = p[0]; node->m_y = p[1]; @@ -221,11 +228,21 @@ void NodeOpti2D3D::Optimise() NekDouble delU = 1.0/(G[2]*G[3]-G[4]*G[4])*(G[3]*G[0] - G[4]*G[1]); NekDouble delV = 1.0/(G[2]*G[3]-G[4]*G[4])*(G[2]*G[1] - G[4]*G[0]); + Array bd = surf->GetBounds(); + bool found = false; while(alpha > 1e-10) { uvt[0] = uvc[0] - alpha * delU; uvt[1] = uvc[1] - alpha * delV; + + if(uvt[0] < bd[0] || uvt[0] > bd[1] || + uvt[1] < bd[2] || uvt[1] > bd[3]) + { + alpha /= 2.0; + continue; + } + p = surf->P(uvt); node->m_x = p[0]; node->m_y = p[1]; @@ -313,7 +330,7 @@ Array NodeOpti2D3D::GetGrad() { Array uvc = node->GetCADSurfInfo(surf->GetId()); NekDouble dx = 1e-4; - vector w(9); + vector w(7); for(int i = 0; i < 7; i++) { @@ -331,11 +348,10 @@ Array NodeOpti2D3D::GetGrad() //ret[0] d/dx //ret[1] d/dy - //ret[2] d/dz - //ret[3] d2/dx2 - //ret[4] d2/dy2 - //ret[5] d2/dxdy + //ret[2] d2/dx2 + //ret[3] d2/dy2 + //ret[4] d2/dxdy ret[0] = (w[1] - w[4]) / 2.0 / dx; -- GitLab From 143266184b4571adcd8b721e55810de082088ce4 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Wed, 6 Jul 2016 13:26:06 +0100 Subject: [PATCH 053/236] CAD sliding working, few tweaks --- .../SurfaceMeshing/SurfaceMeshHOMesh.cpp | 101 +++--------------- .../NekMesh/ProcessModules/ProcessJac.cpp | 30 ++++++ .../ProcessVarOpti/NodeOpti.cpp | 4 +- 3 files changed, 47 insertions(+), 88 deletions(-) diff --git a/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp b/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp index 65109c7c2..e7459f3c7 100644 --- a/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp +++ b/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp @@ -456,8 +456,8 @@ void SurfaceMesh::HOSurf() uvi[k] = uv; } - Array bnds = s->GetBounds(); - Array all(2 * nq); + //Array bnds = s->GetBounds(); + /*Array all(2 * nq); for (int k = 0; k < nq; k++) { all[k * 2 + 0] = uvi[k][0]; @@ -553,7 +553,7 @@ void SurfaceMesh::HOSurf() { uvi[k][0] = all[k * 2 + 0]; uvi[k][1] = all[k * 2 + 1]; - } + }*/ vector honodes(nq - 2); for (int k = 1; k < nq - 1; k++) @@ -576,112 +576,41 @@ void SurfaceMesh::HOSurf() vector vertices = f->m_vertexList; - SpatialDomains::Geometry2DSharedPtr geom = f->GetGeom(3); + SpatialDomains::GeometrySharedPtr geom = f->GetGeom(3); geom->FillGeom(); StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); Array coeffs0 = geom->GetCoeffs(0); Array coeffs1 = geom->GetCoeffs(1); Array coeffs2 = geom->GetCoeffs(2); - Array xc(nq*nq); - Array yc(nq*nq); - Array zc(nq*nq); + Array xc(xmap->GetTotPoints()); + Array yc(xmap->GetTotPoints()); + Array zc(xmap->GetTotPoints()); xmap->BwdTrans(coeffs0,xc); xmap->BwdTrans(coeffs1,yc); xmap->BwdTrans(coeffs2,zc); - //build an array of all uvs - Array > uvi(np); - int ctr = 0; - for(int j = 0; j < vertices.size(); j++) - { - uvi[ctr++] = vertices[j]->GetCADSurfInfo(surf); - } - for(int j = 0; j < edges.size(); j++) - { - vector ns = edges[j]->m_edgeNodes; - if(!(edges[j]->m_n1 == vertices[j])) - { - reverse(ns.begin(),ns.end()); - } - for(int k = 0; k < ns.size(); k++) - { - uvi[ctr++] = ns[k]->GetCADSurfInfo(surf); - } - } + vector > uvi; for(int j = np-ni; j < np; j++) { Array xp(2); xp[0] = u[j]; xp[1] = v[j]; - Array xyz(3); - xyz[0] = xmap->PhysEvaluate(xp, xc); - xyz[1] = xmap->PhysEvaluate(xp, yc); - xyz[2] = xmap->PhysEvaluate(xp, zc); + Array loc(3); + loc[0] = xmap->PhysEvaluate(xp, xc); + loc[1] = xmap->PhysEvaluate(xp, yc); + loc[2] = xmap->PhysEvaluate(xp, zc); Array uv(2); - s->ProjectTo(xyz,uv); - uvi[ctr++] = uv; - }/* - - OptiFaceSharedPtr opti = MemoryManager:: - AllocateSharedPtr(uvi, z, springs, s); - - DNekMat B(2*ni,2*ni,0.0); //approximate hessian (I to start) - for(int k = 0; k < 2*ni; k++) - { - B(k,k) = 1.0; - } - DNekMat H(2*ni,2*ni,0.0); //approximate inverse hessian (I to start) - for(int k = 0; k < 2*ni; k++) - { - H(k,k) = 1.0; + s->ProjectTo(loc,uv); + uvi.push_back(uv); } - Array xi(ni*2); - for(int k = np - ni; k < np; k++) - { - xi[(k-np+ni)*2+0] = uvi[k][0]; - xi[(k-np+ni)*2+1] = uvi[k][1]; - } - - DNekMat J = opti->dF(xi); - - bool repeat = true; - int itct = 0; - while(repeat) - { - NekDouble Norm = 0; - for(int k = 0; k < nq - 2; k++) - { - Norm += J(k,0)*J(k,0); - } - Norm = sqrt(Norm); - - if(Norm < 1E-8) - { - repeat = false; - break; - } - if(itct > 100) - { - cout << "failed to optimise on face " << s->GetId() << endl; - exit(-1); - break; - } - itct++; - cout << "Norm " << Norm << endl; - - BGFSUpdate(opti, J, B, H); //all will be updated - } - - uvi = opti->GetSolution();*/ - vector honodes; - for(int j = np - ni; j < np; j++) + for(int j = 0; j < ni; j++) { Array loc; loc = s->P(uvi[j]); diff --git a/utilities/NekMesh/ProcessModules/ProcessJac.cpp b/utilities/NekMesh/ProcessModules/ProcessJac.cpp index 9ea3e7dc9..b5c22ba94 100644 --- a/utilities/NekMesh/ProcessModules/ProcessJac.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessJac.cpp @@ -105,8 +105,38 @@ void ProcessJac::Process() if (printList) { + LibUtilities::PointsKeyVector p = geom->GetPointsKeys(); + SpatialDomains::DerivStorage deriv = gfac->GetDeriv(p); + const int pts = deriv[0][0].num_elements(); + Array jc(pts); + for (int k = 0; k < pts; ++k) + { + DNekMat jac(m_mesh->m_expDim, m_mesh->m_expDim, 0.0, eFULL); + + for (int l = 0; l < m_mesh->m_expDim; ++l) + { + for (int j = 0; j < m_mesh->m_expDim; ++j) + { + jac(j,l) = deriv[l][j][k]; + } + } + + if(m_mesh->m_expDim == 2) + { + jc[k] = jac(0,0) * jac(1,1) - jac(0,1)*jac(1,0); + } + else if(m_mesh->m_expDim == 3) + { + jc[k] = jac(0,0) * (jac(1,1)*jac(2,2) - jac(2,1)*jac(1,2)) - + jac(0,1) * (jac(1,0)*jac(2,2) - jac(2,0)*jac(1,2)) + + jac(0,2) * (jac(1,0)*jac(2,1) - jac(2,0)*jac(1,1)); + } + } + cout << " - " << el[i]->GetId() << " (" << LibUtilities::ShapeTypeMap[el[i]->GetConf().m_e] << ")" + << " " << Vmath::Vmin(jc.num_elements(),jc,1) / + Vmath::Vmax(jc.num_elements(),jc,1) << endl; } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index 95e44a1ab..081694f59 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -537,7 +537,7 @@ NekDouble NodeOpti::GetFunctional() { case eLinEl: { - const NekDouble nu = 0.45; + const NekDouble nu = 0.4; const NekDouble mu = 1.0 / 2.0 / (1.0+nu); const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); @@ -591,7 +591,7 @@ NekDouble NodeOpti::GetFunctional() case eHypEl: { - const NekDouble nu = 0.45; + const NekDouble nu = 0.4; const NekDouble mu = 1.0 / 2.0 / (1.0+nu); const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); -- GitLab From a889a1deb55e5eac67774f9b1cea6c4317da6822 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Fri, 8 Jul 2016 17:07:22 +0100 Subject: [PATCH 054/236] more tweaks --- cmake/FindOCC.cmake | 4 +++- cmake/ThirdPartyOCC.cmake | 3 +++ library/NekMeshUtils/CMakeLists.txt | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cmake/FindOCC.cmake b/cmake/FindOCC.cmake index 93dfa4b4e..2a4e503bc 100644 --- a/cmake/FindOCC.cmake +++ b/cmake/FindOCC.cmake @@ -23,7 +23,7 @@ if(NOT DEFINED OCE_DIR) endif() endif() -find_package(OCE QUIET) +find_package(OCE QUIET HINTS) if(OCE_FOUND) message(STATUS "-- OpenCASCADE Community Edition has been found.") # Disable this define. For more details see bug #0001872 @@ -61,12 +61,14 @@ else(OCE_FOUND) #look for OpenCASCADE /usr/local/opt/opencascade/include /opt/opencascade/include /opt/opencascade/inc +# /opt/local/include/oce ) FIND_LIBRARY(OCC_LIBRARY TKernel /usr/lib /usr/local/lib /usr/local/opt/opencascade/lib /opt/opencascade/lib +# /opt/local/lib ) endif(WIN32) if(OCC_LIBRARY) diff --git a/cmake/ThirdPartyOCC.cmake b/cmake/ThirdPartyOCC.cmake index ec2ee6853..09a8959e5 100644 --- a/cmake/ThirdPartyOCC.cmake +++ b/cmake/ThirdPartyOCC.cmake @@ -72,6 +72,8 @@ IF(NEKTAR_USE_MESHGEN) -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} -DINSTALL_DIR:PATH=${TPBUILD}/opencascade-6.9 -DCMAKE_CXX_FLAGS:STRING=-DTIXML_USE_STL + -DBUILD_Draw=OFF + -DBUILD_Visualization=OFF ${TPSRC}/opencascade-6.9 ) @@ -103,5 +105,6 @@ IF(NEKTAR_USE_MESHGEN) ADD_CUSTOM_TARGET(opencascade-6.9 ALL) MESSAGE(STATUS "Found OpenCASCADE: ${OCC_LIBRARY_DIR}") SET(OPENCASCADE_CONFIG_INCLUDE_DIR ${OCC_INCLUDE_DIR}) + INCLUDE_DIRECTORIES(SYSTEM ${OCC_INCLUDE_DIR}) ENDIF() ENDIF() diff --git a/library/NekMeshUtils/CMakeLists.txt b/library/NekMeshUtils/CMakeLists.txt index 3c852f861..d68ca17d4 100644 --- a/library/NekMeshUtils/CMakeLists.txt +++ b/library/NekMeshUtils/CMakeLists.txt @@ -87,8 +87,8 @@ IF(NEKTAR_USE_MESHGEN) TARGET_LINK_LIBRARIES(NekMeshUtils LINK_PRIVATE ${ANN_LIBRARY}) TARGET_LINK_LIBRARIES(NekMeshUtils LINK_PUBLIC ${OCC_LIBRARIES}) - SET(OCC_DEF LIN LININTEL HAVE_WOK_CONFIG_H HAVE_CONFIG_H CSFDB) - SET_PROPERTY(TARGET NekMeshUtils APPEND PROPERTY COMPILE_DEFINITIONS ${OCC_DEF}) + #SET(OCC_DEF LIN LININTEL HAVE_WOK_CONFIG_H HAVE_CONFIG_H CSFDB) + #SET_PROPERTY(TARGET NekMeshUtils APPEND PROPERTY COMPILE_DEFINITIONS ${OCC_DEF}) ADD_DEPENDENCIES(NekMeshUtils opencascade-6.9 tetgen-1.5) ENDIF() -- GitLab From 1455101eba24bb1f2f549cea842d4a3209c4fb1f Mon Sep 17 00:00:00 2001 From: mike turner Date: Sat, 9 Jul 2016 10:10:31 +0100 Subject: [PATCH 055/236] start of optimsiation of mappings and qualities --- cmake/FindOCC.cmake | 2 +- cmake/ThirdPartyOCC.cmake | 2 +- utilities/NekMesh/CMakeLists.txt | 1 + .../ProcessModules/ProcessVarOpti/ElUtil.cpp | 333 ++++++++++++++++++ .../ProcessModules/ProcessVarOpti/ElUtil.h | 61 ++++ .../ProcessVarOpti/ProcessVarOpti.cpp | 1 + .../ProcessVarOpti/ProcessVarOpti.h | 32 +- .../ProcessModules/ProcessVarOpti/Utils.cpp | 266 +------------- 8 files changed, 401 insertions(+), 297 deletions(-) create mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp create mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h diff --git a/cmake/FindOCC.cmake b/cmake/FindOCC.cmake index 9da9d464c..8ce595c0d 100644 --- a/cmake/FindOCC.cmake +++ b/cmake/FindOCC.cmake @@ -115,7 +115,7 @@ if(OCC_FOUND) TKSTL TKShHealing TKXSBase - TKBin + TKBinL TKBool TKBO TKBRep diff --git a/cmake/ThirdPartyOCC.cmake b/cmake/ThirdPartyOCC.cmake index e51f84973..6cc181fc8 100644 --- a/cmake/ThirdPartyOCC.cmake +++ b/cmake/ThirdPartyOCC.cmake @@ -33,7 +33,7 @@ IF(NEKTAR_USE_MESHGEN) TKSTL TKShHealing TKXSBase - TKBin + TKBinL TKBool TKBO TKBRep diff --git a/utilities/NekMesh/CMakeLists.txt b/utilities/NekMesh/CMakeLists.txt index 0e33827e4..e82a06a91 100644 --- a/utilities/NekMesh/CMakeLists.txt +++ b/utilities/NekMesh/CMakeLists.txt @@ -26,6 +26,7 @@ SET(NekMeshHeaders ProcessModules/ProcessVarOpti/ProcessVarOpti.h ProcessModules/ProcessVarOpti/NodeOpti.h ProcessModules/ProcessVarOpti/NodeOptiJob.h + ProcessModules/ProcessVarOpti/ElUtil.h ) SET(NekMeshSources diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp new file mode 100644 index 000000000..3364a13c8 --- /dev/null +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp @@ -0,0 +1,333 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessJac.h +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Calculate jacobians of elements. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "ElUtil.h" + +using namespace std; + +namespace Nektar +{ +namespace Utilities +{ + +ElUtil::ElUtil(ElementSharedPtr e) +{ + m_el = el; + m_dim = m_el->GetDim(); + m_maps = MappingIdealToRef(); + m_nodes.resize(innodes.size()); + vector ns; + m_el->GetCurvedNodes(ns); + for (int i = 0; i < ns.size(); ++i) + { + nodes[i].resize(m_dim); + nodes[i][0] = &ns[i]->m_x; + + if (m_dim >= 2) + { + nodes[i][1] = &ns[i]->m_y; + } + + if (m_dim >= 3) + { + nodes[i][2] = &ns[i]->m_z; + } + } +} + +vector > ElUtil::MappingIdealToRef() +{ + //need to make ideal element out of old element + ElmtConfig ec = m_el->GetConf(); + ec.m_order = 1; + ec.m_faceNodes = false; + ec.m_volumeNodes = false; + ec.m_reorient = false; + + ElementSharedPtr E = GetElementFactory().CreateInstance( + ec.m_e, ec, m_el->GetVertexList(), + el->GetTagList()); + + SpatialDomains::GeometrySharedPtr geom = E->GetGeom(m_dim); + geom->FillGeom(); + StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); + + vector > ret; + + if(geom->GetShapeType() == LibUtilities::eQuadrilateral) + { + ASSERTL0(false,"Not coded"); + /*vector > xy; + for(int i = 0; i < geom->GetNumVerts(); i++) + { + Array loc(2); + SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); + p->GetCoords(loc); + xy.push_back(loc); + } + + Array b = chi->GetBase(); + Array u = b[0]->GetZ(); + Array v = b[1]->GetZ(); + + for(int j = 0; j < b[1]->GetNumPoints(); j++) + { + for(int i = 0; i < b[0]->GetNumPoints(); i++) + { + NekDouble a1 = 0.5*(1.0-u[i]), a2 = 0.5*(1.0+u[i]); + NekDouble b1 = 0.5*(1.0-v[j]), b2 = 0.5*(1.0+v[j]); + DNekMat dxdz(2,2,1.0,eFULL); + + dxdz(0,0) = 0.5*(-b1*xy[0][0] + b1*xy[1][0] + b2*xy[2][0] - b2*xy[3][0]); + dxdz(1,0) = 0.5*(-b1*xy[0][1] + b1*xy[1][1] + b2*xy[2][1] - b2*xy[3][1]); + + dxdz(0,1) = 0.5*(-a1*xy[0][0] - a2*xy[1][0] + a2*xy[2][0] + a1*xy[3][0]); + dxdz(1,1) = 0.5*(-a1*xy[0][1] - a2*xy[1][1] + a2*xy[2][1] + a1*xy[3][1]); + + NekDouble det = 1.0/(dxdz(0,0)*dxdz(1,1) - dxdz(1,0)*dxdz(0,1)); + + dxdz.Invert(); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + ret.push_back(r); + } + }*/ + } + else if(geom->GetShapeType() == LibUtilities::eTriangle) + { + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + Array u, v; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v); + + Array xc(chi->GetTotPoints()); + Array yc(chi->GetTotPoints()); + + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + + chi->BwdTrans(coeffs0,xc); + chi->BwdTrans(coeffs1,yc); + + NekVector X(ptsHelp->ptsLow),Y(ptsHelp->ptsLow); + for(int j = 0; j < u.num_elements(); j++) + { + Array xp(2); + xp[0] = u[j]; + xp[1] = v[j]; + + X(j) = chi->PhysEvaluate(xp, xc); + Y(j) = chi->PhysEvaluate(xp, yc); + } + + NekVector x1i(ptsHelp->ptsHigh),y1i(ptsHelp->ptsHigh), + x2i(ptsHelp->ptsHigh),y2i(ptsHelp->ptsHigh); + + x1i = derivUtil->VdmD[0]*X; + y1i = derivUtil->VdmD[0]*Y; + x2i = derivUtil->VdmD[1]*X; + y2i = derivUtil->VdmD[1]*Y; + + for(int i = 0 ; i < ptsHelp->ptsHigh; i++) + { + DNekMat dxdz(2,2,1.0,eFULL); + dxdz(0,0) = x1i(i); + dxdz(0,1) = x2i(i); + dxdz(1,0) = y1i(i); + dxdz(1,1) = y2i(i); + + Array r(10,0.0); + r[9] = dxdz(0,0)*dxdz(1,1)-dxdz(1,0)*dxdz(0,1); + + dxdz.Invert(); + + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + ret.push_back(r); + } + } + else if(geom->GetShapeType() == LibUtilities::eTetrahedron) + { + LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + Array u, v, w; + LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); + + Array xc(chi->GetTotPoints()); + Array yc(chi->GetTotPoints()); + Array zc(chi->GetTotPoints()); + + Array coeffs0 = geom->GetCoeffs(0); + Array coeffs1 = geom->GetCoeffs(1); + Array coeffs2 = geom->GetCoeffs(2); + + chi->BwdTrans(coeffs0,xc); + chi->BwdTrans(coeffs1,yc); + chi->BwdTrans(coeffs2,zc); + + NekVector X(ptsHelp->ptsLow),Y(ptsHelp->ptsLow),Z(ptsHelp->ptsLow); + for(int j = 0; j < u.num_elements(); j++) + { + Array xp(3); + xp[0] = u[j]; + xp[1] = v[j]; + xp[2] = w[j]; + + X(j) = chi->PhysEvaluate(xp, xc); + Y(j) = chi->PhysEvaluate(xp, yc); + Z(j) = chi->PhysEvaluate(xp, zc); + } + + NekVector x1i(ptsHelp->ptsHigh),y1i(ptsHelp->ptsHigh),z1i(ptsHelp->ptsHigh), + x2i(ptsHelp->ptsHigh),y2i(ptsHelp->ptsHigh),z2i(ptsHelp->ptsHigh), + x3i(ptsHelp->ptsHigh),y3i(ptsHelp->ptsHigh),z3i(ptsHelp->ptsHigh); + + x1i = derivUtil->VdmD[0]*X; + y1i = derivUtil->VdmD[0]*Y; + z1i = derivUtil->VdmD[0]*Z; + x2i = derivUtil->VdmD[1]*X; + y2i = derivUtil->VdmD[1]*Y; + z2i = derivUtil->VdmD[1]*Z; + x3i = derivUtil->VdmD[2]*X; + y3i = derivUtil->VdmD[2]*Y; + z3i = derivUtil->VdmD[2]*Z; + + for(int i = 0 ; i < ptsHelp->ptsHigh; i++) + { + DNekMat dxdz(3,3,1.0,eFULL); + dxdz(0,0) = x1i(i); + dxdz(0,1) = x2i(i); + dxdz(0,2) = x3i(i); + dxdz(1,0) = y1i(i); + dxdz(1,1) = y2i(i); + dxdz(1,2) = y3i(i); + dxdz(2,0) = z1i(i); + dxdz(2,1) = z2i(i); + dxdz(2,2) = z3i(i); + + Array r(10,0.0); //store det in 10th entry + + r[9] = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) + -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) + +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); + + dxdz.Invert(); + + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[2] = dxdz(2,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + r[5] = dxdz(2,1); + r[6] = dxdz(0,2); + r[7] = dxdz(1,2); + r[8] = dxdz(2,2); + ret.push_back(r); + } + } + else if(geom->GetShapeType() == LibUtilities::ePrism) + { + ASSERTL0(false, "not coded"); + /*vector > xyz; + for(int i = 0; i < geom->GetNumVerts(); i++) + { + Array loc(3); + SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); + p->GetCoords(loc); + xyz.push_back(loc); + } + + Array b = chi->GetBase(); + Array eta1 = b[0]->GetZ(); + Array eta2 = b[1]->GetZ(); + Array eta3 = b[2]->GetZ(); + + for(int k = 0; k < b[2]->GetNumPoints(); k++) + { + + for(int j = 0; j < b[1]->GetNumPoints(); j++) + { + for(int i = 0; i < b[0]->GetNumPoints(); i++) + { + NekDouble xi1 = 0.5*(1+eta1[i])*(1-eta3[k])-1.0; + NekDouble a1 = 0.5*(1-xi1), a2 = 0.5*(1+xi1); + NekDouble b1 = 0.5*(1-eta2[j]), b2 = 0.5*(1+eta2[j]); + NekDouble c1 = 0.5*(1-eta3[k]), c2 = 0.5*(1+eta3[k]); + + DNekMat dxdz(3,3,1.0,eFULL); + + dxdz(0,0) = 0.5*(-b1*xyz[0][0] + b1*xyz[1][0] + b2*xyz[2][0] - b2*xyz[3][0]); + dxdz(1,0) = 0.5*(-b1*xyz[0][1] + b1*xyz[1][1] + b2*xyz[2][1] - b2*xyz[3][1]); + dxdz(2,0) = 0.5*(-b1*xyz[0][2] + b1*xyz[1][2] + b2*xyz[2][2] - b2*xyz[3][2]); + + dxdz(0,1) = 0.5*((a2-c1)*xyz[0][0] - a2*xyz[1][0] + a2*xyz[2][0] + (c1-a2)*xyz[3][0] - c2*xyz[4][0] + c2*xyz[5][0]); + dxdz(1,1) = 0.5*((a2-c1)*xyz[0][1] - a2*xyz[1][1] + a2*xyz[2][1] + (c1-a2)*xyz[3][1] - c2*xyz[4][1] + c2*xyz[5][1]); + dxdz(2,1) = 0.5*((a2-c1)*xyz[0][2] - a2*xyz[1][2] + a2*xyz[2][2] + (c1-a2)*xyz[3][2] - c2*xyz[4][2] + c2*xyz[5][2]); + + dxdz(0,2) = 0.5*(-b1*xyz[0][0] - b2*xyz[3][0] + b1*xyz[4][0] + b2*xyz[5][0]); + dxdz(1,2) = 0.5*(-b1*xyz[0][1] - b2*xyz[3][1] + b1*xyz[4][1] + b2*xyz[5][1]); + dxdz(2,2) = 0.5*(-b1*xyz[0][2] - b2*xyz[3][2] + b1*xyz[4][2] + b2*xyz[5][2]); + + dxdz.Invert(); + Array r(9,0.0); + r[0] = dxdz(0,0); + r[1] = dxdz(1,0); + r[3] = dxdz(0,1); + r[4] = dxdz(1,1); + r[2] = dxdz(2,0); + r[5] = dxdz(2,1); + r[6] = dxdz(0,2); + r[7] = dxdz(1,2); + r[8] = dxdz(2,2); + ret.push_back(r); + } + } + }*/ + } + else + { + ASSERTL0(false,"not coded"); + } + + return ret; +} + +} +} diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h new file mode 100644 index 000000000..84e69fde4 --- /dev/null +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h @@ -0,0 +1,61 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessJac.h +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Calculate jacobians of elements. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTILITIES_NEKMESH_PROCESSVAROPTI_ELUTIL +#define UTILITIES_NEKMESH_PROCESSVAROPTI_ELUTIL + +namespace Nektar +{ +namespace Utilities +{ + +class ElUtil +{ +public: + ElUtil(ElementSharedPtr e) + +private: + ElementSharedPtr m_el; + std::vector > m_nodes; + std::vector > m_maps; + int m_dim; +}; + +typedef boost::shared_ptr ElUtilSharedPtr; + +} +} + +#endif diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp index 51b1384f0..1b8c4320e 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp @@ -39,6 +39,7 @@ #include "ProcessVarOpti.h" #include "NodeOpti.h" #include "NodeOptiJob.h" +#include "ElUtil.h" #include diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h index 9df25a519..e455bfcf9 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h @@ -43,34 +43,6 @@ namespace Nektar namespace Utilities { -struct ElData -{ - ElData(std::vector innodes, int spaceDim) - { - nodes.resize(innodes.size()); - for (int i = 0; i < innodes.size(); ++i) - { - nodes[i].resize(spaceDim); - nodes[i][0] = &innodes[i]->m_x; - - if (spaceDim >= 2) - { - nodes[i][1] = &innodes[i]->m_y; - } - - if (spaceDim >= 3) - { - nodes[i][2] = &innodes[i]->m_z; - } - } - } - - ElementSharedPtr el; - std::vector > nodes; - std::vector > maps; -}; -typedef boost::shared_ptr ElDataSharedPtr; - struct DerivUtil { NekMatrix VdmD[3]; @@ -120,7 +92,7 @@ public: /// Write mesh to output file. virtual void Process(); private: - typedef std::map > NodeElMap; + typedef std::map > NodeElMap; void FillQuadPoints(); void GetElementMap(); @@ -130,7 +102,7 @@ private: void EvaluateMesh(); NodeElMap nodeElMap; - std::vector dataSet; + std::vector dataSet; ResidualSharedPtr res; DerivUtilSharedPtr derivUtil; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp index f14b217c0..33e1a6014 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp @@ -270,9 +270,7 @@ void ProcessVarOpti::GetElementMap() ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; vector ns; el->GetCurvedNodes(ns); - ElDataSharedPtr d = boost::shared_ptr(new ElData(ns, m_mesh->m_spaceDim)); - d->el = el; - d->maps = MappingIdealToRef(el); + ElUtilSharedPtr d = boost::shared_ptr(new ElUtil(el)); dataSet.push_back(d); } @@ -289,268 +287,6 @@ void ProcessVarOpti::GetElementMap() } } -vector > ProcessVarOpti::MappingIdealToRef(ElementSharedPtr el) -{ - //need to make ideal element out of old element - ElmtConfig ec = el->GetConf(); - ec.m_order = 1; - ec.m_faceNodes = false; - ec.m_volumeNodes = false; - ec.m_reorient = false; - - ElementSharedPtr E = GetElementFactory().CreateInstance( - ec.m_e, ec, el->GetVertexList(), - el->GetTagList()); - - SpatialDomains::GeometrySharedPtr geom = E->GetGeom(el->GetDim()); - geom->FillGeom(); - StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); - - vector > ret; - - if(geom->GetShapeType() == LibUtilities::eQuadrilateral) - { - ASSERTL0(false,"Not coded"); - /*vector > xy; - for(int i = 0; i < geom->GetNumVerts(); i++) - { - Array loc(2); - SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); - p->GetCoords(loc); - xy.push_back(loc); - } - - Array b = chi->GetBase(); - Array u = b[0]->GetZ(); - Array v = b[1]->GetZ(); - - for(int j = 0; j < b[1]->GetNumPoints(); j++) - { - for(int i = 0; i < b[0]->GetNumPoints(); i++) - { - NekDouble a1 = 0.5*(1.0-u[i]), a2 = 0.5*(1.0+u[i]); - NekDouble b1 = 0.5*(1.0-v[j]), b2 = 0.5*(1.0+v[j]); - DNekMat dxdz(2,2,1.0,eFULL); - - dxdz(0,0) = 0.5*(-b1*xy[0][0] + b1*xy[1][0] + b2*xy[2][0] - b2*xy[3][0]); - dxdz(1,0) = 0.5*(-b1*xy[0][1] + b1*xy[1][1] + b2*xy[2][1] - b2*xy[3][1]); - - dxdz(0,1) = 0.5*(-a1*xy[0][0] - a2*xy[1][0] + a2*xy[2][0] + a1*xy[3][0]); - dxdz(1,1) = 0.5*(-a1*xy[0][1] - a2*xy[1][1] + a2*xy[2][1] + a1*xy[3][1]); - - NekDouble det = 1.0/(dxdz(0,0)*dxdz(1,1) - dxdz(1,0)*dxdz(0,1)); - - dxdz.Invert(); - Array r(9,0.0); - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - ret.push_back(r); - } - }*/ - } - else if(geom->GetShapeType() == LibUtilities::eTriangle) - { - LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTriElec); - Array u, v; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v); - - Array xc(chi->GetTotPoints()); - Array yc(chi->GetTotPoints()); - - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - - chi->BwdTrans(coeffs0,xc); - chi->BwdTrans(coeffs1,yc); - - NekVector X(ptsHelp->ptsLow),Y(ptsHelp->ptsLow); - for(int j = 0; j < u.num_elements(); j++) - { - Array xp(2); - xp[0] = u[j]; - xp[1] = v[j]; - - X(j) = chi->PhysEvaluate(xp, xc); - Y(j) = chi->PhysEvaluate(xp, yc); - } - - NekVector x1i(ptsHelp->ptsHigh),y1i(ptsHelp->ptsHigh), - x2i(ptsHelp->ptsHigh),y2i(ptsHelp->ptsHigh); - - x1i = derivUtil->VdmD[0]*X; - y1i = derivUtil->VdmD[0]*Y; - x2i = derivUtil->VdmD[1]*X; - y2i = derivUtil->VdmD[1]*Y; - - for(int i = 0 ; i < ptsHelp->ptsHigh; i++) - { - DNekMat dxdz(2,2,1.0,eFULL); - dxdz(0,0) = x1i(i); - dxdz(0,1) = x2i(i); - dxdz(1,0) = y1i(i); - dxdz(1,1) = y2i(i); - - Array r(10,0.0); - r[9] = dxdz(0,0)*dxdz(1,1)-dxdz(1,0)*dxdz(0,1); - - dxdz.Invert(); - - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - ret.push_back(r); - } - } - else if(geom->GetShapeType() == LibUtilities::eTetrahedron) - { - LibUtilities::PointsKey pkey(m_mesh->m_nummode, - LibUtilities::eNodalTetElec); - Array u, v, w; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); - - Array xc(chi->GetTotPoints()); - Array yc(chi->GetTotPoints()); - Array zc(chi->GetTotPoints()); - - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - Array coeffs2 = geom->GetCoeffs(2); - - chi->BwdTrans(coeffs0,xc); - chi->BwdTrans(coeffs1,yc); - chi->BwdTrans(coeffs2,zc); - - NekVector X(ptsHelp->ptsLow),Y(ptsHelp->ptsLow),Z(ptsHelp->ptsLow); - for(int j = 0; j < u.num_elements(); j++) - { - Array xp(3); - xp[0] = u[j]; - xp[1] = v[j]; - xp[2] = w[j]; - - X(j) = chi->PhysEvaluate(xp, xc); - Y(j) = chi->PhysEvaluate(xp, yc); - Z(j) = chi->PhysEvaluate(xp, zc); - } - - NekVector x1i(ptsHelp->ptsHigh),y1i(ptsHelp->ptsHigh),z1i(ptsHelp->ptsHigh), - x2i(ptsHelp->ptsHigh),y2i(ptsHelp->ptsHigh),z2i(ptsHelp->ptsHigh), - x3i(ptsHelp->ptsHigh),y3i(ptsHelp->ptsHigh),z3i(ptsHelp->ptsHigh); - - x1i = derivUtil->VdmD[0]*X; - y1i = derivUtil->VdmD[0]*Y; - z1i = derivUtil->VdmD[0]*Z; - x2i = derivUtil->VdmD[1]*X; - y2i = derivUtil->VdmD[1]*Y; - z2i = derivUtil->VdmD[1]*Z; - x3i = derivUtil->VdmD[2]*X; - y3i = derivUtil->VdmD[2]*Y; - z3i = derivUtil->VdmD[2]*Z; - - for(int i = 0 ; i < ptsHelp->ptsHigh; i++) - { - DNekMat dxdz(3,3,1.0,eFULL); - dxdz(0,0) = x1i(i); - dxdz(0,1) = x2i(i); - dxdz(0,2) = x3i(i); - dxdz(1,0) = y1i(i); - dxdz(1,1) = y2i(i); - dxdz(1,2) = y3i(i); - dxdz(2,0) = z1i(i); - dxdz(2,1) = z2i(i); - dxdz(2,2) = z3i(i); - - Array r(10,0.0); //store det in 10th entry - - r[9] = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) - -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) - +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); - - dxdz.Invert(); - - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[2] = dxdz(2,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - r[5] = dxdz(2,1); - r[6] = dxdz(0,2); - r[7] = dxdz(1,2); - r[8] = dxdz(2,2); - ret.push_back(r); - } - } - else if(geom->GetShapeType() == LibUtilities::ePrism) - { - ASSERTL0(false, "not coded"); - /*vector > xyz; - for(int i = 0; i < geom->GetNumVerts(); i++) - { - Array loc(3); - SpatialDomains::PointGeomSharedPtr p = geom->GetVertex(i); - p->GetCoords(loc); - xyz.push_back(loc); - } - - Array b = chi->GetBase(); - Array eta1 = b[0]->GetZ(); - Array eta2 = b[1]->GetZ(); - Array eta3 = b[2]->GetZ(); - - for(int k = 0; k < b[2]->GetNumPoints(); k++) - { - - for(int j = 0; j < b[1]->GetNumPoints(); j++) - { - for(int i = 0; i < b[0]->GetNumPoints(); i++) - { - NekDouble xi1 = 0.5*(1+eta1[i])*(1-eta3[k])-1.0; - NekDouble a1 = 0.5*(1-xi1), a2 = 0.5*(1+xi1); - NekDouble b1 = 0.5*(1-eta2[j]), b2 = 0.5*(1+eta2[j]); - NekDouble c1 = 0.5*(1-eta3[k]), c2 = 0.5*(1+eta3[k]); - - DNekMat dxdz(3,3,1.0,eFULL); - - dxdz(0,0) = 0.5*(-b1*xyz[0][0] + b1*xyz[1][0] + b2*xyz[2][0] - b2*xyz[3][0]); - dxdz(1,0) = 0.5*(-b1*xyz[0][1] + b1*xyz[1][1] + b2*xyz[2][1] - b2*xyz[3][1]); - dxdz(2,0) = 0.5*(-b1*xyz[0][2] + b1*xyz[1][2] + b2*xyz[2][2] - b2*xyz[3][2]); - - dxdz(0,1) = 0.5*((a2-c1)*xyz[0][0] - a2*xyz[1][0] + a2*xyz[2][0] + (c1-a2)*xyz[3][0] - c2*xyz[4][0] + c2*xyz[5][0]); - dxdz(1,1) = 0.5*((a2-c1)*xyz[0][1] - a2*xyz[1][1] + a2*xyz[2][1] + (c1-a2)*xyz[3][1] - c2*xyz[4][1] + c2*xyz[5][1]); - dxdz(2,1) = 0.5*((a2-c1)*xyz[0][2] - a2*xyz[1][2] + a2*xyz[2][2] + (c1-a2)*xyz[3][2] - c2*xyz[4][2] + c2*xyz[5][2]); - - dxdz(0,2) = 0.5*(-b1*xyz[0][0] - b2*xyz[3][0] + b1*xyz[4][0] + b2*xyz[5][0]); - dxdz(1,2) = 0.5*(-b1*xyz[0][1] - b2*xyz[3][1] + b1*xyz[4][1] + b2*xyz[5][1]); - dxdz(2,2) = 0.5*(-b1*xyz[0][2] - b2*xyz[3][2] + b1*xyz[4][2] + b2*xyz[5][2]); - - dxdz.Invert(); - Array r(9,0.0); - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - r[2] = dxdz(2,0); - r[5] = dxdz(2,1); - r[6] = dxdz(0,2); - r[7] = dxdz(1,2); - r[8] = dxdz(2,2); - ret.push_back(r); - } - } - }*/ - } - else - { - ASSERTL0(false,"not coded"); - } - - return ret; -} - void ProcessVarOpti::FillQuadPoints() { int nq = m_mesh->m_nummode; -- GitLab From e6b11bbf6db9ba863714b3611a99f37363259b63 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Sat, 9 Jul 2016 14:54:45 +0100 Subject: [PATCH 056/236] parralleise jacobian evaulations --- utilities/NekMesh/CMakeLists.txt | 2 +- .../ProcessModules/ProcessVarOpti/ElUtil.cpp | 113 ++++++++- .../ProcessModules/ProcessVarOpti/ElUtil.h | 55 ++++- .../ProcessVarOpti/NodeOpti.cpp | 1 - .../ProcessModules/ProcessVarOpti/NodeOpti.h | 27 ++- .../ProcessVarOpti/NodeOptiJob.h | 65 ------ .../ProcessVarOpti/ProcessVarOpti.cpp | 53 +++-- .../ProcessVarOpti/ProcessVarOpti.h | 5 +- .../ProcessModules/ProcessVarOpti/Utils.cpp | 214 +----------------- 9 files changed, 215 insertions(+), 320 deletions(-) delete mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h diff --git a/utilities/NekMesh/CMakeLists.txt b/utilities/NekMesh/CMakeLists.txt index e82a06a91..f9aeddf18 100644 --- a/utilities/NekMesh/CMakeLists.txt +++ b/utilities/NekMesh/CMakeLists.txt @@ -25,7 +25,6 @@ SET(NekMeshHeaders ProcessModules/ProcessOptiExtract.h ProcessModules/ProcessVarOpti/ProcessVarOpti.h ProcessModules/ProcessVarOpti/NodeOpti.h - ProcessModules/ProcessVarOpti/NodeOptiJob.h ProcessModules/ProcessVarOpti/ElUtil.h ) @@ -58,6 +57,7 @@ SET(NekMeshSources ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp ProcessModules/ProcessVarOpti/Utils.cpp ProcessModules/ProcessVarOpti/NodeOpti.cpp + ProcessModules/ProcessVarOpti/ElUtil.cpp ) IF (NEKTAR_USE_CCM) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp index 3364a13c8..1ed914dca 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp @@ -34,6 +34,9 @@ //////////////////////////////////////////////////////////////////////////////// #include "ElUtil.h" +#include "ProcessVarOpti.h" + +#include using namespace std; @@ -42,14 +45,21 @@ namespace Nektar namespace Utilities { -ElUtil::ElUtil(ElementSharedPtr e) +boost::mutex mtx2; + +ElUtil::ElUtil(ElementSharedPtr e, DerivUtilSharedPtr d, PtsHelperSharedPtr p, + ResidualSharedPtr r, int n) { - m_el = el; + m_el = e; + derivUtil = d; + ptsHelp = p; + res = r; + m_mode = n; m_dim = m_el->GetDim(); - m_maps = MappingIdealToRef(); - m_nodes.resize(innodes.size()); + maps = MappingIdealToRef(); vector ns; m_el->GetCurvedNodes(ns); + nodes.resize(ns.size()); for (int i = 0; i < ns.size(); ++i) { nodes[i].resize(m_dim); @@ -78,7 +88,7 @@ vector > ElUtil::MappingIdealToRef() ElementSharedPtr E = GetElementFactory().CreateInstance( ec.m_e, ec, m_el->GetVertexList(), - el->GetTagList()); + m_el->GetTagList()); SpatialDomains::GeometrySharedPtr geom = E->GetGeom(m_dim); geom->FillGeom(); @@ -130,7 +140,7 @@ vector > ElUtil::MappingIdealToRef() } else if(geom->GetShapeType() == LibUtilities::eTriangle) { - LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::PointsKey pkey(m_mode, LibUtilities::eNodalTriElec); Array u, v; LibUtilities::PointsManager()[pkey]->GetPoints(u, v); @@ -185,7 +195,7 @@ vector > ElUtil::MappingIdealToRef() } else if(geom->GetShapeType() == LibUtilities::eTetrahedron) { - LibUtilities::PointsKey pkey(m_mesh->m_nummode, + LibUtilities::PointsKey pkey(m_mode, LibUtilities::eNodalTetElec); Array u, v, w; LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); @@ -329,5 +339,94 @@ vector > ElUtil::MappingIdealToRef() return ret; } +void ElUtil::Evaluate() +{ + NekDouble mx = -1.0 * numeric_limits::max(); + NekDouble mn = numeric_limits::max(); + + if(m_dim == 2) + { + NekVector X(nodes.size()),Y(nodes.size()); + for(int j = 0; j < nodes.size(); j++) + { + X(j) = *nodes[j][0]; + Y(j) = *nodes[j][1]; + } + + NekVector x1i(nodes.size()),y1i(nodes.size()), + x2i(nodes.size()),y2i(nodes.size()); + + x1i = derivUtil->VdmDL[0]*X; + y1i = derivUtil->VdmDL[0]*Y; + x2i = derivUtil->VdmDL[1]*X; + y2i = derivUtil->VdmDL[1]*Y; + + for(int j = 0; j < nodes.size(); j++) + { + NekDouble jacDet = x1i(j) * y2i(j) - x2i(j)*y1i(j); + mx = max(mx,jacDet); + mn = min(mn,jacDet); + } + } + else if(m_dim == 3) + { + NekVector X(nodes.size()),Y(nodes.size()),Z(nodes.size()); + for(int j = 0; j < nodes.size(); j++) + { + X(j) = *nodes[j][0]; + Y(j) = *nodes[j][1]; + Z(j) = *nodes[j][2]; + } + + NekVector x1i(nodes.size()),y1i(nodes.size()),z1i(nodes.size()), + x2i(nodes.size()),y2i(nodes.size()),z2i(nodes.size()), + x3i(nodes.size()),y3i(nodes.size()),z3i(nodes.size()); + + x1i = derivUtil->VdmDL[0]*X; + y1i = derivUtil->VdmDL[0]*Y; + z1i = derivUtil->VdmDL[0]*Z; + x2i = derivUtil->VdmDL[1]*X; + y2i = derivUtil->VdmDL[1]*Y; + z2i = derivUtil->VdmDL[1]*Z; + x3i = derivUtil->VdmDL[2]*X; + y3i = derivUtil->VdmDL[2]*Y; + z3i = derivUtil->VdmDL[2]*Z; + + for(int j = 0; j < nodes.size(); j++) + { + DNekMat dxdz(3,3,1.0,eFULL); + dxdz(0,0) = x1i(j); + dxdz(0,1) = x2i(j); + dxdz(0,2) = x3i(j); + dxdz(1,0) = y1i(j); + dxdz(1,1) = y2i(j); + dxdz(1,2) = y3i(j); + dxdz(2,0) = z1i(j); + dxdz(2,1) = z2i(j); + dxdz(2,2) = z3i(j); + + NekDouble jacDet = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) + -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) + +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); + + mx = max(mx,jacDet); + mn = min(mn,jacDet); + } + } + + mtx2.lock(); + if(mn < 0) + { + res->startInv++; + } + res->worstJac = min(res->worstJac,mn/mx); + mtx2.unlock(); +} + +ElUtilJob* ElUtil::GetJob() +{ + return new ElUtilJob(this); +} + } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h index 84e69fde4..e17d3b2ce 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h @@ -36,25 +36,70 @@ #ifndef UTILITIES_NEKMESH_PROCESSVAROPTI_ELUTIL #define UTILITIES_NEKMESH_PROCESSVAROPTI_ELUTIL +#include "../../Module.h" + +#include + namespace Nektar { namespace Utilities { -class ElUtil +struct DerivUtil; +struct PtsHelper; +struct Residual; + +typedef boost::shared_ptr DerivUtilSharedPtr; +typedef boost::shared_ptr PtsHelperSharedPtr; +typedef boost::shared_ptr ResidualSharedPtr; + +class ElUtilJob; + +class ElUtil : public boost::enable_shared_from_this { public: - ElUtil(ElementSharedPtr e) + ElUtil(ElementSharedPtr e, DerivUtilSharedPtr d, PtsHelperSharedPtr p, + ResidualSharedPtr, int n); + + ElUtilJob *GetJob(); + + int GetId() + { + return m_el->GetId(); + } + + std::vector > nodes; + std::vector > maps; + + void Evaluate(); private: + + std::vector > MappingIdealToRef(); + ElementSharedPtr m_el; - std::vector > m_nodes; - std::vector > m_maps; int m_dim; -}; + int m_mode; + DerivUtilSharedPtr derivUtil; + PtsHelperSharedPtr ptsHelp; + ResidualSharedPtr res; +}; typedef boost::shared_ptr ElUtilSharedPtr; +class ElUtilJob : public Thread::ThreadJob +{ +public: + ElUtilJob(ElUtil* e) : el(e) {} + + void Run() + { + el->Evaluate(); + } +private: + ElUtil* el; +}; + } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index 081694f59..6fd074711 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -34,7 +34,6 @@ //////////////////////////////////////////////////////////////////////////////// #include "NodeOpti.h" -#include "NodeOptiJob.h" using namespace std; using namespace Nektar::NekMeshUtils; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h index e33a96519..d6b7f48e4 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h @@ -41,6 +41,8 @@ #include +#include + namespace Nektar { namespace Utilities @@ -51,7 +53,7 @@ class NodeOptiJob; class NodeOpti { public: - NodeOpti(NodeSharedPtr n, std::vector e, + NodeOpti(NodeSharedPtr n, std::vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, PtsHelperSharedPtr p, optimiser o) : node(n), data(e), res(r), derivUtil(d), ptsHelp(p), opti(o) @@ -69,7 +71,7 @@ protected: } template NekDouble GetFunctional(); NodeSharedPtr node; - std::vector data; + std::vector data; ResidualSharedPtr res; DerivUtilSharedPtr derivUtil; @@ -81,7 +83,7 @@ class NodeOpti1D3D : public NodeOpti //1D optimsation in 3D space { public: - NodeOpti1D3D(NodeSharedPtr n, std::vector e, + NodeOpti1D3D(NodeSharedPtr n, std::vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, PtsHelperSharedPtr p, optimiser o, CADCurveSharedPtr c) : NodeOpti(n,e,r,d,p,o), curve(c) @@ -100,7 +102,7 @@ private: class NodeOpti2D3D : public NodeOpti //1D optimsation in 3D space { public: - NodeOpti2D3D(NodeSharedPtr n, std::vector e, + NodeOpti2D3D(NodeSharedPtr n, std::vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, PtsHelperSharedPtr p, optimiser o, CADSurfSharedPtr s) : NodeOpti(n,e,r,d,p,o), surf(s) @@ -119,7 +121,7 @@ private: class NodeOpti3D3D : public NodeOpti //1D optimsation in 3D space { public: - NodeOpti3D3D(NodeSharedPtr n, std::vector e, + NodeOpti3D3D(NodeSharedPtr n, std::vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, PtsHelperSharedPtr p, optimiser o) : NodeOpti(n,e,r,d,p,o) @@ -137,7 +139,7 @@ private: class NodeOpti2D2D : public NodeOpti //1D optimsation in 3D space { public: - NodeOpti2D2D(NodeSharedPtr n, std::vector e, + NodeOpti2D2D(NodeSharedPtr n, std::vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, PtsHelperSharedPtr p, optimiser o) : NodeOpti(n,e,r,d,p,o) @@ -152,6 +154,19 @@ private: Array GetGrad(); }; +class NodeOptiJob : public Thread::ThreadJob +{ +public: + NodeOptiJob(NodeOpti* no) : node(no) {} + + void Run() + { + node->Optimise(); + } +private: + NodeOpti* node; +}; + } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h deleted file mode 100644 index 3b2fcf8a0..000000000 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiJob.h +++ /dev/null @@ -1,65 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// File: ProcessJac.h -// -// For more information, please see: http://www.nektar.info/ -// -// The MIT License -// -// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), -// Department of Aeronautics, Imperial College London (UK), and Scientific -// Computing and Imaging Institute, University of Utah (USA). -// -// License for the specific language governing rights and limitations under -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// Description: Calculate jacobians of elements. -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef UTILITIES_NEKMESH_NODEOPTIJOB -#define UTILITIES_NEKMESH_NODEOPTIJOB - -#include "../../Module.h" -#include "NodeOpti.h" - -#include - -namespace Nektar -{ -namespace Utilities -{ - -class NodeOptiJob : public Thread::ThreadJob -{ -public: - NodeOptiJob(NodeOpti* no) : node(no) {} - - void Run() - { - node->Optimise(); - } -private: - NodeOpti* node; -}; - -} -} - -#endif diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp index 1b8c4320e..0e0c9f50f 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp @@ -38,7 +38,6 @@ #include #include "ProcessVarOpti.h" #include "NodeOpti.h" -#include "NodeOptiJob.h" #include "ElUtil.h" #include @@ -76,8 +75,6 @@ ProcessVarOpti::ProcessVarOpti(MeshSharedPtr m) : ProcessModule(m) ConfigOption(true, "", "Optimise for hyper elasticity"); m_config["numthreads"] = ConfigOption(false, "1", "Number of threads"); - m_config["stats"] = - ConfigOption(false, "", "Write a file with list of scaled jacobians"); m_config["restol"] = ConfigOption(false, "1e-6", "Tolerance criterion"); m_config["maxiter"] = @@ -171,10 +168,10 @@ void ProcessVarOpti::Process() NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); - derivUtil->VdmD[0] = interp * ( - LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI); - derivUtil->VdmD[1] = interp * ( - LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI); + derivUtil->VdmDL[0] = LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI; + derivUtil->VdmDL[1] = LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI; + derivUtil->VdmD[0] = interp * derivUtil->VdmDL[0]; + derivUtil->VdmD[1] = interp * derivUtil->VdmDL[1]; //derivUtil->quadW = LibUtilities::MakeQuadratureWeights(U2,V1); Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); NekVector quadWi(qds); @@ -203,12 +200,12 @@ void ProcessVarOpti::Process() LibUtilities::GetTetVandermonde(U1,V1,W1); NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); - derivUtil->VdmD[0] = interp * ( - LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI); - derivUtil->VdmD[1] = interp * ( - LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI); - derivUtil->VdmD[2] = interp * ( - LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI); + derivUtil->VdmDL[0] = LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI; + derivUtil->VdmDL[1] = LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI; + derivUtil->VdmDL[2] = LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI; + derivUtil->VdmD[0] = interp * derivUtil->VdmDL[0]; + derivUtil->VdmD[1] = interp * derivUtil->VdmDL[1]; + derivUtil->VdmD[2] = interp * derivUtil->VdmDL[2]; Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); NekVector quadWi(qds); derivUtil->quadW = quadWi; @@ -268,6 +265,13 @@ void ProcessVarOpti::Process() mx = max(mx, int(optiNodes[i].size())); } + res->startInv =0; + res->worstJac = numeric_limits::max(); + for(int i = 0; i < dataSet.size(); i++) + { + dataSet[i]->Evaluate(); + } + cout << scientific << endl; cout << "N elements:\t\t" << m_mesh->m_element[m_mesh->m_expDim].size() << endl << "N elements invalid:\t" << res->startInv << endl @@ -309,7 +313,19 @@ void ProcessVarOpti::Process() tm->Wait(); } - EvaluateMesh(); + res->startInv =0; + res->worstJac = numeric_limits::max(); + + vector elJobs(dataSet.size()); + for(int i = 0; i < dataSet.size(); i++) + { + elJobs[i] = dataSet[i]->GetJob(); + } + + tm->SetNumWorkers(0); + tm->QueueJobs(elJobs); + tm->SetNumWorkers(nThreads); + tm->Wait(); cout << ctr << "\tResidual: " << res->val << " " << res->worstJac << endl; if(ctr >= maxIter) @@ -319,17 +335,8 @@ void ProcessVarOpti::Process() t.Stop(); cout << "Time to compute: " << t.TimePerTest(1) << endl; - EvaluateMesh(); - cout << "Invalid at end:\t\t" << res->startInv << endl; cout << "Worst at end:\t\t" << res->worstJac << endl; - - if(m_config["stats"].beenSet) - { - string file = m_config["stats"].as(); - cout << "writing stats to " << file.c_str() << endl; - WriteStats(file); - } } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h index e455bfcf9..b11d35652 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h @@ -38,6 +38,8 @@ #include "../../Module.h" +#include "ElUtil.h" + namespace Nektar { namespace Utilities @@ -46,6 +48,7 @@ namespace Utilities struct DerivUtil { NekMatrix VdmD[3]; + NekMatrix VdmDL[3]; //deriv matrix without interp NekVector quadW; }; typedef boost::shared_ptr DerivUtilSharedPtr; @@ -98,8 +101,6 @@ private: void GetElementMap(); std::vector > MappingIdealToRef(ElementSharedPtr el); std::vector > GetColouredNodes(); - void WriteStats(std::string file); - void EvaluateMesh(); NodeElMap nodeElMap; std::vector dataSet; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp index 33e1a6014..ef45d7e4e 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp @@ -35,11 +35,6 @@ #include "ProcessVarOpti.h" -#include -#include -#include -#include - #include #include @@ -230,7 +225,7 @@ vector > ProcessVarOpti::GetColouredNodes() bool islocked = false; for(int j = 0; j < it->second.size(); j++) { - set::iterator sit = locked.find(it->second[j]->el->GetId()); + set::iterator sit = locked.find(it->second[j]->GetId()); if(sit != locked.end()) { islocked = true; @@ -243,7 +238,7 @@ vector > ProcessVarOpti::GetColouredNodes() completed.insert(remain[i]->m_id); for(int j = 0; j < it->second.size(); j++) { - locked.insert(it->second[j]->el->GetId()); + locked.insert(it->second[j]->GetId()); } } } @@ -270,7 +265,8 @@ void ProcessVarOpti::GetElementMap() ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; vector ns; el->GetCurvedNodes(ns); - ElUtilSharedPtr d = boost::shared_ptr(new ElUtil(el)); + ElUtilSharedPtr d = boost::shared_ptr(new ElUtil(el, derivUtil, + ptsHelp, res, m_mesh->m_nummode)); dataSet.push_back(d); } @@ -540,208 +536,6 @@ void ProcessVarOpti::FillQuadPoints() el->SetCurveType(LibUtilities::eNodalTetElec); } } - - EvaluateMesh(); -} - -void ProcessVarOpti::EvaluateMesh() -{ - res->startInv =0; - res->worstJac = numeric_limits::max(); - - if(m_mesh->m_expDim == 2) - { - LibUtilities::PointsKey pkey1(m_mesh->m_nummode, - LibUtilities::eNodalTriElec); - Array u1, v1; - - LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); - - NekVector U1(u1), V1(v1); - - NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); - NekMatrix VandermondeI = Vandermonde; - VandermondeI.Invert(); - NekMatrix VdmDxt = ( - LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI); - NekMatrix VdmDyt = ( - LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI); - - - - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - - vector ns; - el->GetCurvedNodes(ns); - - NekDouble mx = -1.0 * numeric_limits::max(); - NekDouble mn = numeric_limits::max(); - - - NekVector X(u1.num_elements()),Y(u1.num_elements()); - for(int j = 0; j < u1.num_elements(); j++) - { - X(j) = ns[j]->m_x; - Y(j) = ns[j]->m_y; - } - - NekVector x1i(u1.num_elements()),y1i(u1.num_elements()), - x2i(u1.num_elements()),y2i(u1.num_elements()); - - x1i = VdmDxt*X; - y1i = VdmDxt*Y; - x2i = VdmDyt*X; - y2i = VdmDyt*Y; - - for(int j = 0; j < u1.num_elements(); j++) - { - NekDouble jacDet = x1i(j) * y2i(j) - x2i(j)*y1i(j); - mx = max(mx,jacDet); - mn = min(mn,jacDet); - } - - if(mn < 0) - { - res->startInv++; - } - res->worstJac = min(res->worstJac,mn/mx); - } - } - else - { - LibUtilities::PointsKey pkey1(m_mesh->m_nummode, - LibUtilities::eNodalTetElec); - Array u1, v1,w1; - - LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1,w1); - - NekVector U1(u1), V1(v1), W1(w1); - - NekMatrix Vandermonde = LibUtilities::GetTetVandermonde(U1,V1,W1); - NekMatrix VandermondeI = Vandermonde; - VandermondeI.Invert(); - NekMatrix VdmDxt = ( - LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI); - NekMatrix VdmDyt = ( - LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI); - NekMatrix VdmDzt = ( - LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI); - - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i]; - - vector ns; - el->GetCurvedNodes(ns); - - NekDouble mx = -1.0 * numeric_limits::max(); - NekDouble mn = numeric_limits::max(); - - NekVector X(u1.num_elements()),Y(u1.num_elements()),Z(u1.num_elements()); - for(int j = 0; j < u1.num_elements(); j++) - { - X(j) = ns[j]->m_x; - Y(j) = ns[j]->m_y; - Z(j) = ns[j]->m_z; - } - - NekVector x1i(u1.num_elements()),y1i(u1.num_elements()),z1i(u1.num_elements()), - x2i(u1.num_elements()),y2i(u1.num_elements()),z2i(u1.num_elements()), - x3i(u1.num_elements()),y3i(u1.num_elements()),z3i(u1.num_elements()); - - x1i = VdmDxt*X; - y1i = VdmDxt*Y; - z1i = VdmDxt*Z; - x2i = VdmDyt*X; - y2i = VdmDyt*Y; - z2i = VdmDyt*Z; - x3i = VdmDzt*X; - y3i = VdmDzt*Y; - z3i = VdmDzt*Z; - - for(int j = 0; j < u1.num_elements(); j++) - { - - DNekMat dxdz(3,3,1.0,eFULL); - dxdz(0,0) = x1i(j); - dxdz(0,1) = x2i(j); - dxdz(0,2) = x3i(j); - dxdz(1,0) = y1i(j); - dxdz(1,1) = y2i(j); - dxdz(1,2) = y3i(j); - dxdz(2,0) = z1i(j); - dxdz(2,1) = z2i(j); - dxdz(2,2) = z3i(j); - - NekDouble jacDet = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) - -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) - +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); - - mx = max(mx,jacDet); - mn = min(mn,jacDet); - } - - - - if(mn < 0) - { - res->startInv++; - } - - res->worstJac = min(res->worstJac,mn/mx); - } - } -} - -void ProcessVarOpti::WriteStats(string file) -{ - ASSERTL0(file != "", "no file name given"); - - ofstream out; - out.open(file.c_str()); - out << scientific; - - for(int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++) - { - vector ns; - m_mesh->m_element[m_mesh->m_expDim][i]->GetCurvedNodes(ns); - int pts = ns.size(); - int dim = m_mesh->m_element[m_mesh->m_expDim][i]->GetDim(); - - NekDouble mx = -1.0 * numeric_limits::max(); - NekDouble mn = numeric_limits::max(); - - if(dim == 2) - { - NekVector X(pts),Y(pts),Z(pts), - x1(pts),y1(pts), - x2(pts),y2(pts); - for(int i = 0; i < pts; i++) - { - X(i) = ns[i]->m_x; - Y(i) = ns[i]->m_y; - } - - x1 = derivUtil->VdmD[0]*X; - y1 = derivUtil->VdmD[0]*Y; - x2 = derivUtil->VdmD[0]*X; - y2 = derivUtil->VdmD[0]*Y; - - for(int i = 0; i < pts; i++) - { - mx = max(mx, x1(i)*y2(i)-y1(i)*x2(i)); - mn = min(mn, x1(i)*y2(i)-y1(i)*x2(i)); - } - - } - else - { - ASSERTL0(false,"not coded"); - } - out << mn / mx << endl; - } } } -- GitLab From 72dfac11902f78021cd282e51af168f6f008535a Mon Sep 17 00:00:00 2001 From: mike turner Date: Sat, 9 Jul 2016 15:46:30 +0100 Subject: [PATCH 057/236] update reference map with each iteration --- utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp | 5 ++++- .../NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp index 1ed914dca..3d7394a43 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp @@ -56,7 +56,6 @@ ElUtil::ElUtil(ElementSharedPtr e, DerivUtilSharedPtr d, PtsHelperSharedPtr p, res = r; m_mode = n; m_dim = m_el->GetDim(); - maps = MappingIdealToRef(); vector ns; m_el->GetCurvedNodes(ns); nodes.resize(ns.size()); @@ -421,6 +420,10 @@ void ElUtil::Evaluate() } res->worstJac = min(res->worstJac,mn/mx); mtx2.unlock(); + + mtx2.lock(); + maps = MappingIdealToRef(); + mtx2.unlock(); } ElUtilJob* ElUtil::GetJob() diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp index 0e0c9f50f..dc1714525 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp @@ -327,7 +327,7 @@ void ProcessVarOpti::Process() tm->SetNumWorkers(nThreads); tm->Wait(); - cout << ctr << "\tResidual: " << res->val << " " << res->worstJac << endl; + cout << ctr << "\tResidual: " << res->val << " " << res->worstJac << " " << res->startInv << endl; if(ctr >= maxIter) break; } -- GitLab From c6a9d185f937e763e162ff3b4464051f6420aab3 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Sun, 10 Jul 2016 14:12:19 +0100 Subject: [PATCH 058/236] remove some mutex around mappings --- .../ProcessModules/ProcessVarOpti/ElUtil.cpp | 122 ++++++------------ 1 file changed, 43 insertions(+), 79 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp index 3d7394a43..3074cad6b 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp @@ -74,12 +74,13 @@ ElUtil::ElUtil(ElementSharedPtr e, DerivUtilSharedPtr d, PtsHelperSharedPtr p, nodes[i][2] = &ns[i]->m_z; } } + maps = MappingIdealToRef(); } vector > ElUtil::MappingIdealToRef() { //need to make ideal element out of old element - ElmtConfig ec = m_el->GetConf(); + /*ElmtConfig ec = m_el->GetConf(); ec.m_order = 1; ec.m_faceNodes = false; ec.m_volumeNodes = false; @@ -91,11 +92,11 @@ vector > ElUtil::MappingIdealToRef() SpatialDomains::GeometrySharedPtr geom = E->GetGeom(m_dim); geom->FillGeom(); - StdRegions::StdExpansionSharedPtr chi = geom->GetXmap(); + StdRegions::StdExpansionSharedPtr chi = geom->GetXmap();*/ vector > ret; - if(geom->GetShapeType() == LibUtilities::eQuadrilateral) + if(m_el->GetConf().m_e == LibUtilities::eQuadrilateral) { ASSERTL0(false,"Not coded"); /*vector > xy; @@ -137,9 +138,9 @@ vector > ElUtil::MappingIdealToRef() } }*/ } - else if(geom->GetShapeType() == LibUtilities::eTriangle) + else if(m_el->GetConf().m_e == LibUtilities::eTriangle) { - LibUtilities::PointsKey pkey(m_mode, + /*LibUtilities::PointsKey pkey(m_mode, LibUtilities::eNodalTriElec); Array u, v; LibUtilities::PointsManager()[pkey]->GetPoints(u, v); @@ -190,88 +191,51 @@ vector > ElUtil::MappingIdealToRef() r[3] = dxdz(0,1); r[4] = dxdz(1,1); ret.push_back(r); - } + }*/ } - else if(geom->GetShapeType() == LibUtilities::eTetrahedron) + else if(m_el->GetConf().m_e == LibUtilities::eTetrahedron) { - LibUtilities::PointsKey pkey(m_mode, - LibUtilities::eNodalTetElec); - Array u, v, w; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v, w); - - Array xc(chi->GetTotPoints()); - Array yc(chi->GetTotPoints()); - Array zc(chi->GetTotPoints()); - - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - Array coeffs2 = geom->GetCoeffs(2); - - chi->BwdTrans(coeffs0,xc); - chi->BwdTrans(coeffs1,yc); - chi->BwdTrans(coeffs2,zc); - - NekVector X(ptsHelp->ptsLow),Y(ptsHelp->ptsLow),Z(ptsHelp->ptsLow); - for(int j = 0; j < u.num_elements(); j++) - { - Array xp(3); - xp[0] = u[j]; - xp[1] = v[j]; - xp[2] = w[j]; - - X(j) = chi->PhysEvaluate(xp, xc); - Y(j) = chi->PhysEvaluate(xp, yc); - Z(j) = chi->PhysEvaluate(xp, zc); - } - - NekVector x1i(ptsHelp->ptsHigh),y1i(ptsHelp->ptsHigh),z1i(ptsHelp->ptsHigh), - x2i(ptsHelp->ptsHigh),y2i(ptsHelp->ptsHigh),z2i(ptsHelp->ptsHigh), - x3i(ptsHelp->ptsHigh),y3i(ptsHelp->ptsHigh),z3i(ptsHelp->ptsHigh); - - x1i = derivUtil->VdmD[0]*X; - y1i = derivUtil->VdmD[0]*Y; - z1i = derivUtil->VdmD[0]*Z; - x2i = derivUtil->VdmD[1]*X; - y2i = derivUtil->VdmD[1]*Y; - z2i = derivUtil->VdmD[1]*Z; - x3i = derivUtil->VdmD[2]*X; - y3i = derivUtil->VdmD[2]*Y; - z3i = derivUtil->VdmD[2]*Z; + DNekMat J(3,3,0.0); + J(0,0) = (*nodes[1][0] - *nodes[0][0]); + J(1,0) = (*nodes[1][1] - *nodes[0][1]); + J(2,0) = (*nodes[1][2] - *nodes[0][2]); + J(0,1) = (*nodes[2][0] - *nodes[0][0]); + J(1,1) = (*nodes[2][1] - *nodes[0][1]); + J(2,1) = (*nodes[2][2] - *nodes[0][2]); + J(0,2) = (*nodes[3][0] - *nodes[0][0]); + J(1,2) = (*nodes[3][1] - *nodes[0][1]); + J(2,2) = (*nodes[3][2] - *nodes[0][2]); + + J.Invert(); + + DNekMat R(3,3,0.0); + R(0,0) = 2.0; + R(1,1) = 2.0; + R(2,2) = 2.0; + + J = J * R; for(int i = 0 ; i < ptsHelp->ptsHigh; i++) { - DNekMat dxdz(3,3,1.0,eFULL); - dxdz(0,0) = x1i(i); - dxdz(0,1) = x2i(i); - dxdz(0,2) = x3i(i); - dxdz(1,0) = y1i(i); - dxdz(1,1) = y2i(i); - dxdz(1,2) = y3i(i); - dxdz(2,0) = z1i(i); - dxdz(2,1) = z2i(i); - dxdz(2,2) = z3i(i); - Array r(10,0.0); //store det in 10th entry - r[9] = dxdz(0,0)*(dxdz(1,1)*dxdz(2,2)-dxdz(2,1)*dxdz(1,2)) - -dxdz(0,1)*(dxdz(1,0)*dxdz(2,2)-dxdz(2,0)*dxdz(1,2)) - +dxdz(0,2)*(dxdz(1,0)*dxdz(2,1)-dxdz(2,0)*dxdz(1,1)); - - dxdz.Invert(); - - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[2] = dxdz(2,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); - r[5] = dxdz(2,1); - r[6] = dxdz(0,2); - r[7] = dxdz(1,2); - r[8] = dxdz(2,2); + r[9] = 1.0/(J(0,0)*(J(1,1)*J(2,2)-J(2,1)*J(1,2)) + -J(0,1)*(J(1,0)*J(2,2)-J(2,0)*J(1,2)) + +J(0,2)*(J(1,0)*J(2,1)-J(2,0)*J(1,1))); + + r[0] = J(0,0); + r[1] = J(1,0); + r[2] = J(2,0); + r[3] = J(0,1); + r[4] = J(1,1); + r[5] = J(2,1); + r[6] = J(0,2); + r[7] = J(1,2); + r[8] = J(2,2); ret.push_back(r); } } - else if(geom->GetShapeType() == LibUtilities::ePrism) + else if(m_el->GetConf().m_e == LibUtilities::ePrism) { ASSERTL0(false, "not coded"); /*vector > xyz; @@ -421,9 +385,9 @@ void ElUtil::Evaluate() res->worstJac = min(res->worstJac,mn/mx); mtx2.unlock(); - mtx2.lock(); + //mtx2.lock(); maps = MappingIdealToRef(); - mtx2.unlock(); + //mtx2.unlock(); } ElUtilJob* ElUtil::GetJob() -- GitLab From deba5f5c656380b95fd5f2de844da309b169ebbd Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Sun, 10 Jul 2016 14:20:57 +0100 Subject: [PATCH 059/236] put senstivity switch into linear elastic --- .../ProcessVarOpti/NodeOpti.cpp | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index 6fd074711..6e8975936 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -542,7 +542,7 @@ NekDouble NodeOpti::GetFunctional() for (int i = 0; i < nElmt; ++i) { - bool valid = true; + //bool valid = true; NekDouble jacDet[ptsHelp->ptsHigh], trEtE[ptsHelp->ptsHigh]; for(int k = 0; k < ptsHelp->ptsHigh; ++k) @@ -563,27 +563,37 @@ NekDouble NodeOpti::GetFunctional() } jacDet[k] = JacDet(jacIdeal); trEtE[k] = LinElasTrace(jacIdeal); - valid = valid ? jacDet[k] > 0.0 : false; + //valid = valid ? jacDet[k] > 0.0 : false; } - if (!valid) - { + NekDouble de = 1e-4; + + //if (!valid) + //{ for(int k = 0; k < ptsHelp->ptsHigh; ++k) { - NekDouble de = 1e-2; - NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + NekDouble sigma; + if(jacDet[k] < de*1e3) + { + sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + } + else + { + sigma = jacDet[k]; + } + NekDouble lsigma = log(sigma); integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); } - } - else - { - for(int k = 0; k < ptsHelp->ptsHigh; ++k) - { - NekDouble lsigma = log(jacDet[k]); - integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); - } - } + //} + //else + //{ + // for(int k = 0; k < ptsHelp->ptsHigh; ++k) + // { + // NekDouble lsigma = log(jacDet[k]); + // integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); + // } + //} } break; } -- GitLab From a3852576cc261889a65cf3d6aec136cb2b815cb2 Mon Sep 17 00:00:00 2001 From: mike turner Date: Mon, 11 Jul 2016 17:25:09 +0100 Subject: [PATCH 060/236] alterations which dont work --- .../ProcessVarOpti/NodeOpti.cpp | 59 ++++++++++--------- .../ProcessVarOpti/ProcessVarOpti.cpp | 6 +- .../ProcessVarOpti/ProcessVarOpti.h | 1 + 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index 6e8975936..0f3d929b6 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -95,6 +95,7 @@ void NodeOpti3D3D::Optimise() { //needs to optimise NekDouble currentW = GetFunctional<3>(); + NekDouble functional; NekDouble xc = node->m_x; NekDouble yc = node->m_y; NekDouble zc = node->m_z; @@ -121,7 +122,8 @@ void NodeOpti3D3D::Optimise() node->m_x = xc - alpha * delX; node->m_y = yc - alpha * delY; node->m_z = zc - alpha * delZ; - if(GetFunctional<3>() < currentW) + functional = GetFunctional<3>(); + if(functional < currentW) { found = true; break; @@ -136,11 +138,13 @@ void NodeOpti3D3D::Optimise() node->m_x = xc; node->m_y = yc; node->m_z = zc; + functional = currentW; // cout << "warning: had to reset node" << endl; } mtx.lock(); res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ (node->m_z-zc)*(node->m_z-zc)),res->val); + res->func += functional; mtx.unlock(); } } @@ -154,6 +158,7 @@ void NodeOpti1D3D::Optimise() //needs to optimise NekDouble tc = node->GetCADCurveInfo(curve->GetId()); NekDouble currentW = GetFunctional<3>(); + NekDouble functional; NekDouble xc = node->m_x; NekDouble yc = node->m_y; NekDouble zc = node->m_z; @@ -179,7 +184,8 @@ void NodeOpti1D3D::Optimise() node->m_x = p[0]; node->m_y = p[1]; node->m_z = p[2]; - if(GetFunctional<3>() < currentW) + functional = GetFunctional<3>(); + if(functional < currentW) { found = true; break; @@ -196,6 +202,7 @@ void NodeOpti1D3D::Optimise() node->m_x = p[0]; node->m_y = p[1]; node->m_z = p[2]; + functional = currentW; // cout << "warning: had to reset node" << endl; } else @@ -205,6 +212,7 @@ void NodeOpti1D3D::Optimise() mtx.lock(); res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ (node->m_z-zc)*(node->m_z-zc)),res->val); + res->func += functional; mtx.unlock(); } } @@ -218,6 +226,7 @@ void NodeOpti2D3D::Optimise() //needs to optimise Array uvc = node->GetCADSurfInfo(surf->GetId()); NekDouble currentW = GetFunctional<3>(); + NekDouble functional; NekDouble xc = node->m_x; NekDouble yc = node->m_y; NekDouble zc = node->m_z; @@ -246,7 +255,8 @@ void NodeOpti2D3D::Optimise() node->m_x = p[0]; node->m_y = p[1]; node->m_z = p[2]; - if(GetFunctional<3>() < currentW) + functional = GetFunctional<3>(); + if(functional < currentW) { found = true; break; @@ -262,6 +272,7 @@ void NodeOpti2D3D::Optimise() node->m_x = p[0]; node->m_y = p[1]; node->m_z = p[2]; + functional = currentW; // cout << "warning: had to reset node" << endl; } else @@ -271,6 +282,7 @@ void NodeOpti2D3D::Optimise() mtx.lock(); res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ (node->m_z-zc)*(node->m_z-zc)),res->val); + res->func += functional; mtx.unlock(); } } @@ -536,13 +548,13 @@ NekDouble NodeOpti::GetFunctional() { case eLinEl: { - const NekDouble nu = 0.4; + const NekDouble nu = 0.45; const NekDouble mu = 1.0 / 2.0 / (1.0+nu); const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); for (int i = 0; i < nElmt; ++i) { - //bool valid = true; + bool valid = true; NekDouble jacDet[ptsHelp->ptsHigh], trEtE[ptsHelp->ptsHigh]; for(int k = 0; k < ptsHelp->ptsHigh; ++k) @@ -563,37 +575,28 @@ NekDouble NodeOpti::GetFunctional() } jacDet[k] = JacDet(jacIdeal); trEtE[k] = LinElasTrace(jacIdeal); - //valid = valid ? jacDet[k] > 0.0 : false; + valid = valid ? jacDet[k] > 0.0 : false; } - NekDouble de = 1e-4; + NekDouble de = 1e-2; - //if (!valid) - //{ + if (!valid) + { for(int k = 0; k < ptsHelp->ptsHigh; ++k) { - NekDouble sigma; - if(jacDet[k] < de*1e3) - { - sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); - } - else - { - sigma = jacDet[k]; - } - + NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); NekDouble lsigma = log(sigma); integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); } - //} - //else - //{ - // for(int k = 0; k < ptsHelp->ptsHigh; ++k) - // { - // NekDouble lsigma = log(jacDet[k]); - // integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); - // } - //} + } + else + { + for(int k = 0; k < ptsHelp->ptsHigh; ++k) + { + NekDouble lsigma = log(jacDet[k]); + integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); + } + } } break; } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp index dc1714525..621bf67b4 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp @@ -299,6 +299,7 @@ void ProcessVarOpti::Process() { ctr++; res->val = 0.0; + res->func = 0.0; for(int i = 0; i < optiNodes.size(); i++) { vector jobs(optiNodes[i].size()); @@ -327,7 +328,10 @@ void ProcessVarOpti::Process() tm->SetNumWorkers(nThreads); tm->Wait(); - cout << ctr << "\tResidual: " << res->val << " " << res->worstJac << " " << res->startInv << endl; + cout << ctr << "\tResidual: " << res->val + << "\tEnergy: " << res->func + << "\tMin Jac: " << res->worstJac + << "\tInvalid: " << res->startInv << endl; if(ctr >= maxIter) break; } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h index b11d35652..2bd4bd6d6 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h @@ -75,6 +75,7 @@ struct Residual int nDoF; int startInv; NekDouble worstJac; + NekDouble func; }; typedef boost::shared_ptr ResidualSharedPtr; -- GitLab From cedb546edefc52938b55aeac654a2e304b5bbf84 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Mon, 11 Jul 2016 18:15:50 +0100 Subject: [PATCH 061/236] something untangled --- utilities/NekMesh/InputModules/InputGmsh.cpp | 1 + .../ProcessVarOpti/NodeOpti.cpp | 40 ++++++++++++------- .../ProcessModules/ProcessVarOpti/Utils.cpp | 6 +-- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/utilities/NekMesh/InputModules/InputGmsh.cpp b/utilities/NekMesh/InputModules/InputGmsh.cpp index b7b8bd010..8323abb77 100644 --- a/utilities/NekMesh/InputModules/InputGmsh.cpp +++ b/utilities/NekMesh/InputModules/InputGmsh.cpp @@ -191,6 +191,7 @@ void InputGmsh::Process() // Open the file stream. OpenStream(); + m_mesh->m_hasCAD = false; m_mesh->m_expDim = 0; m_mesh->m_spaceDim = 0; string line; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index 0f3d929b6..dc29506b2 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -548,13 +548,13 @@ NekDouble NodeOpti::GetFunctional() { case eLinEl: { - const NekDouble nu = 0.45; + const NekDouble nu = 0.4; const NekDouble mu = 1.0 / 2.0 / (1.0+nu); const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); for (int i = 0; i < nElmt; ++i) { - bool valid = true; + //bool valid = true; NekDouble jacDet[ptsHelp->ptsHigh], trEtE[ptsHelp->ptsHigh]; for(int k = 0; k < ptsHelp->ptsHigh; ++k) @@ -575,32 +575,42 @@ NekDouble NodeOpti::GetFunctional() } jacDet[k] = JacDet(jacIdeal); trEtE[k] = LinElasTrace(jacIdeal); - valid = valid ? jacDet[k] > 0.0 : false; + //valid = valid ? jacDet[k] > 0.0 : false; } NekDouble de = 1e-2; - if (!valid) - { + //if (!valid) + //{ for(int k = 0; k < ptsHelp->ptsHigh; ++k) { - NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + NekDouble sigma; + if(jacDet[k] < de*1e3) + { + sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); + } + else + { + sigma = jacDet[k]; + } + NekDouble lsigma = log(sigma); integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); } - } - else - { - for(int k = 0; k < ptsHelp->ptsHigh; ++k) - { - NekDouble lsigma = log(jacDet[k]); - integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); - } - } + //} + //else + //{ + // for(int k = 0; k < ptsHelp->ptsHigh; ++k) + // { + // NekDouble lsigma = log(jacDet[k]); + // integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[k]); + // } + //} } break; } + case eHypEl: { const NekDouble nu = 0.4; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp index ef45d7e4e..b2115f2bb 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp @@ -327,9 +327,9 @@ void ProcessVarOpti::FillQuadPoints() for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) { - if((*eit)->m_edgeNodes.size() > 0) + if((*eit)->m_edgeNodes.size() > 0 && (*eit)->m_curveType == LibUtilities::eGaussLobattoLegendre) { - //already high-order just need to Id + //already high-order just need to Id and double check type for(int i = 0; i < (*eit)->m_edgeNodes.size(); i++) { (*eit)->m_edgeNodes[i]->m_id = id++; @@ -446,7 +446,7 @@ void ProcessVarOpti::FillQuadPoints() FaceSet::iterator it; for(it = m_mesh->m_faceSet.begin(); it != m_mesh->m_faceSet.end(); it++) { - if((*it)->m_faceNodes.size() > 0) + if((*it)->m_faceNodes.size() > 0 && (*it)->m_curveType == LibUtilities::eNodalTriElec) { for(int i = 0; i < (*it)->m_faceNodes.size(); i++) { -- GitLab From 984d0199239527be7f8ed8d9cb4f7e7af7a1991e Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Wed, 13 Jul 2016 13:03:09 +0100 Subject: [PATCH 062/236] small fix to cad output --- library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp | 6 +++--- utilities/NekMesh/InputModules/InputCAD.cpp | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp b/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp index ef7ecd32f..573b18a9e 100644 --- a/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp +++ b/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp @@ -455,8 +455,8 @@ void SurfaceMesh::HOSurf() uvi[k] = uv; } - //Array bnds = s->GetBounds(); - /*Array all(2 * nq); + Array bnds = s->GetBounds(); + Array all(2 * nq); for (int k = 0; k < nq; k++) { all[k * 2 + 0] = uvi[k][0]; @@ -551,7 +551,7 @@ void SurfaceMesh::HOSurf() { uvi[k][0] = all[k * 2 + 0]; uvi[k][1] = all[k * 2 + 1]; - }*/ + } vector honodes(nq - 2); for (int k = 1; k < nq - 1; k++) diff --git a/utilities/NekMesh/InputModules/InputCAD.cpp b/utilities/NekMesh/InputModules/InputCAD.cpp index e0fe2515b..a38701970 100644 --- a/utilities/NekMesh/InputModules/InputCAD.cpp +++ b/utilities/NekMesh/InputModules/InputCAD.cpp @@ -121,6 +121,9 @@ void InputCAD::Process() cout << "Building mesh for: " << m_CADName << endl; } + m_mesh->m_hasCAD = true; + m_mesh->m_CADId = m_CADName; + ASSERTL0(m_cad->LoadCAD(), "Failed to load CAD"); -- GitLab From 2c9c2a4245fdf2024047de509dff9f18cd8c2428 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Wed, 13 Jul 2016 14:26:00 +0100 Subject: [PATCH 063/236] scale dependant reg --- .../NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp | 10 +++++----- .../NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp b/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp index 573b18a9e..c7f744600 100644 --- a/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp +++ b/library/NekMeshUtils/SurfaceMeshing/SurfaceMeshHOMesh.cpp @@ -345,7 +345,7 @@ void SurfaceMesh::HOSurf() tb * (1.0 - gll[k]) / 2.0 + te * (1.0 + gll[k]) / 2.0; } - Array xi(nq - 2); + /*Array xi(nq - 2); for (int k = 1; k < nq - 1; k++) { xi[k - 1] = ti[k]; @@ -412,12 +412,12 @@ void SurfaceMesh::HOSurf() } } // need to pull the solution out of opti - ti = opti->GetSolution(); + ti = opti->GetSolution();*/ vector s = c->GetAdjSurf(); ASSERTL0(s.size() == 2, "Number of common surfs should be 2"); - + vector honodes(m_mesh->m_nummode - 2); for (int k = 1; k < m_mesh->m_nummode - 1; k++) { @@ -455,7 +455,7 @@ void SurfaceMesh::HOSurf() uvi[k] = uv; } - Array bnds = s->GetBounds(); + /*Array bnds = s->GetBounds(); Array all(2 * nq); for (int k = 0; k < nq; k++) { @@ -551,7 +551,7 @@ void SurfaceMesh::HOSurf() { uvi[k][0] = all[k * 2 + 0]; uvi[k][1] = all[k * 2 + 1]; - } + }*/ vector honodes(nq - 2); for (int k = 1; k < nq - 1; k++) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index dc29506b2..c46d9c288 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -578,12 +578,11 @@ NekDouble NodeOpti::GetFunctional() //valid = valid ? jacDet[k] > 0.0 : false; } - NekDouble de = 1e-2; - //if (!valid) //{ for(int k = 0; k < ptsHelp->ptsHigh; ++k) { + NekDouble de = 1e-3 * data[i]->maps[k][9]; NekDouble sigma; if(jacDet[k] < de*1e3) { -- GitLab From 54e5b0bda4ad309fc0922ada2d16880b9d12f5b1 Mon Sep 17 00:00:00 2001 From: mike turner Date: Wed, 20 Jul 2016 14:36:11 +0100 Subject: [PATCH 064/236] Revert to CMake files on feature/bl_upgrade --- cmake/FindOCC.cmake | 14 ++++++++++---- cmake/ThirdPartyANN.cmake | 10 +++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/cmake/FindOCC.cmake b/cmake/FindOCC.cmake index 8ce595c0d..935c924aa 100644 --- a/cmake/FindOCC.cmake +++ b/cmake/FindOCC.cmake @@ -6,6 +6,13 @@ # OCC_LIBRARY_DIR - where the OCC library directory can be found # OCC_LIBRARIES - Link this to use OCC # OCC_OCAF_LIBRARIES - Link this to use OCC OCAF framework +# +# Adapted from FreeCAD: http://free-cad.sf.net + +set(TEST_ENV $ENV{OCE_ROOT}) +if(NOT DEFINED OCE_DIR AND DEFINED TEST_ENV) + file(GLOB OCE_DIR $ENV{OCE_ROOT}/lib/oce-*) +endif() # First try to find OpenCASCADE Community Edition if(NOT DEFINED OCE_DIR) @@ -23,7 +30,7 @@ if(NOT DEFINED OCE_DIR) endif() endif() -find_package(OCE QUIET HINTS) +find_package(OCE QUIET) if(OCE_FOUND) message(STATUS "-- OpenCASCADE Community Edition has been found.") # Disable this define. For more details see bug #0001872 @@ -68,7 +75,7 @@ else(OCE_FOUND) #look for OpenCASCADE /usr/local/lib /usr/local/opt/opencascade/lib /opt/opencascade/lib - /opt/local/lib + opt/local/lib ) endif(WIN32) if(OCC_LIBRARY) @@ -115,7 +122,6 @@ if(OCC_FOUND) TKSTL TKShHealing TKXSBase - TKBinL TKBool TKBO TKBRep @@ -146,4 +152,4 @@ if(OCC_FOUND) message(STATUS "-- OCE/OpenCASCADE shared libraries directory: ${OCC_LIBRARY_DIR}") else(OCC_FOUND) #message(SEND_ERROR "Neither OpenCASCADE Community Edition nor OpenCasCade were found: will not build CAD modules!") -endif(OCC_FOUND) \ No newline at end of file +endif(OCC_FOUND) diff --git a/cmake/ThirdPartyANN.cmake b/cmake/ThirdPartyANN.cmake index ebe46849e..b87ecbc14 100644 --- a/cmake/ThirdPartyANN.cmake +++ b/cmake/ThirdPartyANN.cmake @@ -13,9 +13,13 @@ IF (NOT WIN32) ENDIF(NOT WIN32) IF (NEKTAR_USE_ANN) - # First search for system ANN installs. Hint /opt/local for MacPorts. - FIND_LIBRARY(ANN_LIBRARY NAMES ANN PATHS /opt/local/lib /usr/local/opt/ann/lib) - FIND_PATH (ANN_INCLUDE_DIR ANN.h PATHS /opt/local/include /usr/local/opt/ann/include/ANN) + # First search for system ANN installs. Hint /opt/local for MacPorts and + # /usr/local/opt/ann for Homebrew. + FIND_LIBRARY(ANN_LIBRARY NAMES ANN + PATHS /opt/local/lib /usr/local/opt/ann/lib $ENV{ANN_ROOT}/lib) + FIND_PATH (ANN_INCLUDE_DIR ANN.h + PATHS /opt/local/include /usr/local/opt/ann/include $ENV{ANN_ROOT}/include + PATH_SUFFIXES ANN) GET_FILENAME_COMPONENT(ANN_LIBRARY_PATH ${ANN_LIBRARY} PATH) IF (ANN_LIBRARY AND ANN_INCLUDE_DIR) -- GitLab From ac1fc8b69c7574dad6ece56955e82a307d1d1555 Mon Sep 17 00:00:00 2001 From: mike turner Date: Wed, 20 Jul 2016 17:53:34 +0100 Subject: [PATCH 065/236] semi working regularisation --- .../ProcessModules/ProcessVarOpti/ElUtil.cpp | 9 ++++++++- .../ProcessModules/ProcessVarOpti/NodeOpti.cpp | 14 ++++++++++++-- .../ProcessVarOpti/ProcessVarOpti.cpp | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp index c83df8242..4fc19f6d9 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp @@ -389,7 +389,14 @@ void ElUtil::Evaluate() maps = MappingIdealToRef(); //mtx2.unlock(); - delta = pow(maps[0][9]/6.0, 1.0/m_dim) / m_el->GetConf().m_order / 10.0; + NekDouble minEdge = numeric_limits::max(); + vector es = m_el->GetEdgeList(); + for(int i = 0; i < es.size(); i++) + { + minEdge = min(minEdge,es[i]->m_n1->Distance(es[i]->m_n2)); + } + + delta = minEdge / m_el->GetConf().m_order / 500.0; } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index 43f11fe41..1c017538f 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -611,12 +611,22 @@ NekDouble NodeOpti::GetFunctional() jacMin = min(jacMin,jacDet[i][k]); } } - NekDouble ep = sqrt(1e-22 + 0.004*jacMin*jacMin); + NekDouble gam = numeric_limits::epsilon(); + NekDouble ep; + if(jacMin < gam) + { + ep = sqrt(gam*(gam-jacMin)); + } + else + { + ep = 0.0; + } + for (int i = 0; i < nElmt; ++i) { for(int k = 0; k < ptsHelp->ptsHigh; ++k) { - NekDouble sigma = 0.5*(jacDet[i][k] + sqrt(jacDet[i][k]*jacDet[i][k] + ep*ep)); + NekDouble sigma = 0.5*(jacDet[i][k] + sqrt(jacDet[i][k]*jacDet[i][k] + 4.0*ep*ep)); NekDouble lsigma = log(sigma); integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[i][k]); } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp index 5b6948122..621bf67b4 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp @@ -239,7 +239,7 @@ void ProcessVarOpti::Process() else if(freenodes[i][j]->GetNumCadCurve() == 1) { vector > cs = freenodes[i][j]->GetCADCurves(); - //ns.push_back(new NodeOpti1D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti,cs[0].second)); + ns.push_back(new NodeOpti1D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti,cs[0].second)); } else if(freenodes[i][j]->GetNumCADSurf() == 1) { -- GitLab From 417ac3369b1b848dbd85a9e0dc1559412e4d7ea5 Mon Sep 17 00:00:00 2001 From: mike turner Date: Tue, 26 Jul 2016 13:19:34 +0100 Subject: [PATCH 066/236] cleaned up points helper: --- utilities/NekMesh/CMakeLists.txt | 2 +- .../ProcessModules/ProcessVarOpti/ElUtil.cpp | 5 +- .../ProcessModules/ProcessVarOpti/ElUtil.h | 5 +- .../ProcessVarOpti/NodeOpti.cpp | 53 ++++---- .../ProcessModules/ProcessVarOpti/NodeOpti.h | 21 ++-- .../{Utils.cpp => PreProcessing.cpp} | 73 ++++++++++- .../ProcessVarOpti/ProcessVarOpti.cpp | 117 ++++++------------ .../ProcessVarOpti/ProcessVarOpti.h | 11 +- 8 files changed, 151 insertions(+), 136 deletions(-) rename utilities/NekMesh/ProcessModules/ProcessVarOpti/{Utils.cpp => PreProcessing.cpp} (83%) diff --git a/utilities/NekMesh/CMakeLists.txt b/utilities/NekMesh/CMakeLists.txt index 6369c1e6e..065e381f4 100644 --- a/utilities/NekMesh/CMakeLists.txt +++ b/utilities/NekMesh/CMakeLists.txt @@ -55,7 +55,7 @@ SET(NekMeshSources ProcessModules/ProcessTetSplit.cpp ProcessModules/ProcessOptiExtract.cpp ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp - ProcessModules/ProcessVarOpti/Utils.cpp + ProcessModules/ProcessVarOpti/PreProcessing.cpp ProcessModules/ProcessVarOpti/NodeOpti.cpp ProcessModules/ProcessVarOpti/ElUtil.cpp ) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp index 4fc19f6d9..be48e24a9 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp @@ -47,12 +47,11 @@ namespace Utilities boost::mutex mtx2; -ElUtil::ElUtil(ElementSharedPtr e, DerivUtilSharedPtr d, PtsHelperSharedPtr p, +ElUtil::ElUtil(ElementSharedPtr e, DerivUtilSharedPtr d, ResidualSharedPtr r, int n) { m_el = e; derivUtil = d; - ptsHelp = p; res = r; m_mode = n; m_dim = m_el->GetDim(); @@ -215,7 +214,7 @@ vector > ElUtil::MappingIdealToRef() J = J * R; - for(int i = 0 ; i < ptsHelp->ptsHigh; i++) + for(int i = 0 ; i < derivUtil->ptsHigh; i++) { Array r(10,0.0); //store det in 10th entry diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h index 146506fd4..7fb77c075 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h @@ -46,11 +46,9 @@ namespace Utilities { struct DerivUtil; -struct PtsHelper; struct Residual; typedef boost::shared_ptr DerivUtilSharedPtr; -typedef boost::shared_ptr PtsHelperSharedPtr; typedef boost::shared_ptr ResidualSharedPtr; class ElUtilJob; @@ -58,7 +56,7 @@ class ElUtilJob; class ElUtil : public boost::enable_shared_from_this { public: - ElUtil(ElementSharedPtr e, DerivUtilSharedPtr d, PtsHelperSharedPtr p, + ElUtil(ElementSharedPtr e, DerivUtilSharedPtr d, ResidualSharedPtr, int n); ElUtilJob *GetJob(); @@ -83,7 +81,6 @@ private: int m_mode; DerivUtilSharedPtr derivUtil; - PtsHelperSharedPtr ptsHelp; ResidualSharedPtr res; }; typedef boost::shared_ptr ElUtilSharedPtr; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index 1c017538f..96644726c 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// File: ProcessJac.h +// File: NodeOpti.cpp // // For more information, please see: http://www.nektar.info/ // @@ -158,7 +158,6 @@ void NodeOpti3D3D::Optimise() mtx.lock(); res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ (node->m_z-zc)*(node->m_z-zc)),res->val); - res->func = max(res->func, functional); mtx.unlock(); } } @@ -228,7 +227,6 @@ void NodeOpti1D3D::Optimise() mtx.lock(); res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ (node->m_z-zc)*(node->m_z-zc)),res->val); - res->func = max(res->func, functional); mtx.unlock(); } } @@ -300,7 +298,6 @@ void NodeOpti2D3D::Optimise() mtx.lock(); res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ (node->m_z-zc)*(node->m_z-zc)),res->val); - res->func = max(res->func, functional); mtx.unlock(); } } @@ -543,21 +540,21 @@ template NekDouble NodeOpti::GetFunctional() { const int nElmt = data.size(); - const int totpts = ptsHelp->ptsLow * nElmt; + const int totpts = derivUtil->ptsLow * nElmt; NekDouble X[DIM * totpts]; // Store x/y components of each element sequentially in memory for (int i = 0, cnt = 0; i < nElmt; ++i) { - for (int j = 0; j < ptsHelp->ptsLow; ++j) + for (int j = 0; j < derivUtil->ptsLow; ++j) { for (int d = 0; d < DIM; ++d) { - X[cnt + d*ptsHelp->ptsLow + j] = *(data[i]->nodes[j][d]); + X[cnt + d*derivUtil->ptsLow + j] = *(data[i]->nodes[j][d]); } } - cnt += DIM*ptsHelp->ptsLow; + cnt += DIM*derivUtil->ptsLow; } // Storage for derivatives, ordered by: @@ -565,14 +562,14 @@ NekDouble NodeOpti::GetFunctional() // - number of elements // - cartesian coordinate direction // - quadrature points - NekDouble deriv[DIM][nElmt][DIM][ptsHelp->ptsHigh]; + NekDouble deriv[DIM][nElmt][DIM][derivUtil->ptsHigh]; // Calculate x- and y-gradients for (int d = 0; d < DIM; ++d) { - Blas::Dgemm('N', 'N', ptsHelp->ptsHigh, DIM * nElmt, ptsHelp->ptsLow, 1.0, - derivUtil->VdmD[d].GetRawPtr(), ptsHelp->ptsHigh, X, ptsHelp->ptsLow, 0.0, - &deriv[d][0][0][0], ptsHelp->ptsHigh); + Blas::Dgemm('N', 'N', derivUtil->ptsHigh, DIM * nElmt, derivUtil->ptsLow, 1.0, + derivUtil->VdmD[d].GetRawPtr(), derivUtil->ptsHigh, X, derivUtil->ptsLow, 0.0, + &deriv[d][0][0][0], derivUtil->ptsHigh); } NekDouble integral = 0.0; @@ -584,13 +581,13 @@ NekDouble NodeOpti::GetFunctional() const NekDouble nu = 0.4; const NekDouble mu = 1.0 / 2.0 / (1.0+nu); const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); - NekDouble jacDet[nElmt][ptsHelp->ptsHigh], - trEtE[nElmt][ptsHelp->ptsHigh]; + NekDouble jacDet[nElmt][derivUtil->ptsHigh], + trEtE[nElmt][derivUtil->ptsHigh]; NekDouble jacMin = 0.0; for (int i = 0; i < nElmt; ++i) { - for(int k = 0; k < ptsHelp->ptsHigh; ++k) + for(int k = 0; k < derivUtil->ptsHigh; ++k) { NekDouble jacIdeal[DIM*DIM]; int cnt = 0; @@ -624,7 +621,7 @@ NekDouble NodeOpti::GetFunctional() for (int i = 0; i < nElmt; ++i) { - for(int k = 0; k < ptsHelp->ptsHigh; ++k) + for(int k = 0; k < derivUtil->ptsHigh; ++k) { NekDouble sigma = 0.5*(jacDet[i][k] + sqrt(jacDet[i][k]*jacDet[i][k] + 4.0*ep*ep)); NekDouble lsigma = log(sigma); @@ -644,9 +641,9 @@ NekDouble NodeOpti::GetFunctional() for (int i = 0; i < nElmt; ++i) { bool valid = true; - NekDouble jacDet[ptsHelp->ptsHigh], I1[ptsHelp->ptsHigh]; + NekDouble jacDet[derivUtil->ptsHigh], I1[derivUtil->ptsHigh]; - for(int k = 0; k < ptsHelp->ptsHigh; ++k) + for(int k = 0; k < derivUtil->ptsHigh; ++k) { NekDouble jacIdeal[DIM*DIM]; int cnt = 0; @@ -674,7 +671,7 @@ NekDouble NodeOpti::GetFunctional() if (!valid) { - for(int k = 0; k < ptsHelp->ptsHigh; ++k) + for(int k = 0; k < derivUtil->ptsHigh; ++k) { NekDouble de = 1e-1; NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); @@ -684,7 +681,7 @@ NekDouble NodeOpti::GetFunctional() } else { - for(int k = 0; k < ptsHelp->ptsHigh; ++k) + for(int k = 0; k < derivUtil->ptsHigh; ++k) { NekDouble lsigma = log(jacDet[k]); integral += derivUtil->quadW[k]*fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1[k] - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); @@ -699,9 +696,9 @@ NekDouble NodeOpti::GetFunctional() for (int i = 0; i < nElmt; ++i) { bool valid = true; - NekDouble jacDet[ptsHelp->ptsHigh], frob[ptsHelp->ptsHigh]; + NekDouble jacDet[derivUtil->ptsHigh], frob[derivUtil->ptsHigh]; - for(int k = 0; k < ptsHelp->ptsHigh; ++k) + for(int k = 0; k < derivUtil->ptsHigh; ++k) { NekDouble jacIdeal[DIM*DIM]; int cnt = 0; @@ -729,7 +726,7 @@ NekDouble NodeOpti::GetFunctional() if (!valid) { - for(int k = 0; k < ptsHelp->ptsHigh; ++k) + for(int k = 0; k < derivUtil->ptsHigh; ++k) { NekDouble de = 1e-2; NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); @@ -738,7 +735,7 @@ NekDouble NodeOpti::GetFunctional() } else { - for(int k = 0; k < ptsHelp->ptsHigh; ++k) + for(int k = 0; k < derivUtil->ptsHigh; ++k) { integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (frob[k] / DIM / pow(fabs(jacDet[k]), 2.0/DIM) -1.0); } @@ -752,9 +749,9 @@ NekDouble NodeOpti::GetFunctional() for (int i = 0; i < nElmt; ++i) { bool valid = true; - NekDouble jacDet[ptsHelp->ptsHigh], frob[ptsHelp->ptsHigh]; + NekDouble jacDet[derivUtil->ptsHigh], frob[derivUtil->ptsHigh]; - for(int k = 0; k < ptsHelp->ptsHigh; ++k) + for(int k = 0; k < derivUtil->ptsHigh; ++k) { NekDouble jacIdeal[DIM*DIM]; int cnt = 0; @@ -782,7 +779,7 @@ NekDouble NodeOpti::GetFunctional() if (!valid) { - for(int k = 0; k < ptsHelp->ptsHigh; ++k) + for(int k = 0; k < derivUtil->ptsHigh; ++k) { NekDouble de = 1e-2; NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); @@ -791,7 +788,7 @@ NekDouble NodeOpti::GetFunctional() } else { - for(int k = 0; k < ptsHelp->ptsHigh; ++k) + for(int k = 0; k < derivUtil->ptsHigh; ++k) { integral += derivUtil->quadW[k]*fabs(data[i]->maps[k][9])*(frob[k] / jacDet[k]); } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h index 1ef67e21b..ef36f938d 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h @@ -55,8 +55,8 @@ class NodeOpti public: NodeOpti(NodeSharedPtr n, std::vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, - PtsHelperSharedPtr p, optimiser o) - : node(n), data(e), res(r), derivUtil(d), ptsHelp(p), opti(o) + optimiser o) + : node(n), data(e), res(r), derivUtil(d), opti(o) { } @@ -78,7 +78,6 @@ protected: NekDouble dx; ResidualSharedPtr res; DerivUtilSharedPtr derivUtil; - PtsHelperSharedPtr ptsHelp; optimiser opti; }; @@ -88,8 +87,8 @@ public: NodeOpti1D3D(NodeSharedPtr n, std::vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, - PtsHelperSharedPtr p, optimiser o, CADCurveSharedPtr c) - : NodeOpti(n,e,r,d,p,o), curve(c) + optimiser o, CADCurveSharedPtr c) + : NodeOpti(n,e,r,d,o), curve(c) { } @@ -107,8 +106,8 @@ class NodeOpti2D3D : public NodeOpti //1D optimsation in 3D space public: NodeOpti2D3D(NodeSharedPtr n, std::vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, - PtsHelperSharedPtr p, optimiser o, CADSurfSharedPtr s) - : NodeOpti(n,e,r,d,p,o), surf(s) + optimiser o, CADSurfSharedPtr s) + : NodeOpti(n,e,r,d,o), surf(s) { } @@ -126,8 +125,8 @@ class NodeOpti3D3D : public NodeOpti //1D optimsation in 3D space public: NodeOpti3D3D(NodeSharedPtr n, std::vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, - PtsHelperSharedPtr p, optimiser o) - : NodeOpti(n,e,r,d,p,o) + optimiser o) + : NodeOpti(n,e,r,d,o) { } @@ -144,8 +143,8 @@ class NodeOpti2D2D : public NodeOpti //1D optimsation in 3D space public: NodeOpti2D2D(NodeSharedPtr n, std::vector e, ResidualSharedPtr r, DerivUtilSharedPtr d, - PtsHelperSharedPtr p, optimiser o) - : NodeOpti(n,e,r,d,p,o) + optimiser o) + : NodeOpti(n,e,r,d,o) { } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/PreProcessing.cpp similarity index 83% rename from utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp rename to utilities/NekMesh/ProcessModules/ProcessVarOpti/PreProcessing.cpp index b2115f2bb..1c9edb973 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/Utils.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/PreProcessing.cpp @@ -45,6 +45,77 @@ namespace Nektar namespace Utilities { +void ProcessVarOpti::BuildDerivUtil() +{ + //build Vandermonde information + switch (m_mesh->m_spaceDim) + { + case 2: + { + derivUtil->ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)/2; + + LibUtilities::PointsKey pkey1(m_mesh->m_nummode, + LibUtilities::eNodalTriElec); + LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, + LibUtilities::eNodalTriSPI); + Array u1, v1, u2, v2; + + LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); + LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2); + NekVector U1(u1), V1(v1); + NekVector U2(u2), V2(v2); + derivUtil->ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); + + NekMatrix interp = LibUtilities::GetInterpolationMatrix(U1, V1, U2, V2); + + NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); + NekMatrix VandermondeI = Vandermonde; + VandermondeI.Invert(); + derivUtil->VdmDL[0] = LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI; + derivUtil->VdmDL[1] = LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI; + derivUtil->VdmD[0] = interp * derivUtil->VdmDL[0]; + derivUtil->VdmD[1] = interp * derivUtil->VdmDL[1]; + //derivUtil->quadW = LibUtilities::MakeQuadratureWeights(U2,V1); + Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); + NekVector quadWi(qds); + derivUtil->quadW = quadWi; + } + break; + case 3: + { + derivUtil->ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)*(m_mesh->m_nummode+2)/6; + LibUtilities::PointsKey pkey1(m_mesh->m_nummode, + LibUtilities::eNodalTetElec); + LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, + LibUtilities::eNodalTetSPI); + Array u1, v1, u2, v2, w1, w2; + LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1, w1); + LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2, w2); + NekVector U1(u1), V1(v1), W1(w1); + NekVector U2(u2), V2(v2), W2(w2); + derivUtil->ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); + + NekMatrix interp = + LibUtilities::GetTetInterpolationMatrix(U1, V1, W1, + U2, V2, W2); + + NekMatrix Vandermonde = + LibUtilities::GetTetVandermonde(U1,V1,W1); + NekMatrix VandermondeI = Vandermonde; + VandermondeI.Invert(); + derivUtil->VdmDL[0] = LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI; + derivUtil->VdmDL[1] = LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI; + derivUtil->VdmDL[2] = LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI; + derivUtil->VdmD[0] = interp * derivUtil->VdmDL[0]; + derivUtil->VdmD[1] = interp * derivUtil->VdmDL[1]; + derivUtil->VdmD[2] = interp * derivUtil->VdmDL[2]; + Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); + NekVector quadWi(qds); + derivUtil->quadW = quadWi; + } + } +} + vector > ProcessVarOpti::GetColouredNodes() { //this figures out the dirclet nodes and colors the others into paralell sets @@ -266,7 +337,7 @@ void ProcessVarOpti::GetElementMap() vector ns; el->GetCurvedNodes(ns); ElUtilSharedPtr d = boost::shared_ptr(new ElUtil(el, derivUtil, - ptsHelp, res, m_mesh->m_nummode)); + res, m_mesh->m_nummode)); dataSet.push_back(d); } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp index 621bf67b4..944c7ef39 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp @@ -127,9 +127,12 @@ void ProcessVarOpti::Process() break; } } - ASSERTL0(fd,"failed to find order of mesh") + ASSERTL0(fd,"failed to find order of mesh"); - cout << "Indentified order as: " << m_mesh->m_nummode - 1 << endl; + if(m_mesh->m_verbose) + { + cout << "Indentified order as: " << m_mesh->m_nummode - 1 << endl; + } if(m_mesh->m_expDim == 2 && m_mesh->m_spaceDim == 3) { @@ -140,83 +143,17 @@ void ProcessVarOpti::Process() res->val = 1.0; derivUtil = boost::shared_ptr(new DerivUtil); - ptsHelp = boost::shared_ptr(new PtsHelper); FillQuadPoints(); - //build Vandermonde information - switch (m_mesh->m_spaceDim) - { - case 2: - { - ptsHelp->ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)/2; - - LibUtilities::PointsKey pkey1(m_mesh->m_nummode, - LibUtilities::eNodalTriElec); - LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, - LibUtilities::eNodalTriSPI); - Array u1, v1, u2, v2; - - LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); - LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2); - NekVector U1(u1), V1(v1); - NekVector U2(u2), V2(v2); - ptsHelp->ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); - - NekMatrix interp = LibUtilities::GetInterpolationMatrix(U1, V1, U2, V2); - - NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); - NekMatrix VandermondeI = Vandermonde; - VandermondeI.Invert(); - derivUtil->VdmDL[0] = LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI; - derivUtil->VdmDL[1] = LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI; - derivUtil->VdmD[0] = interp * derivUtil->VdmDL[0]; - derivUtil->VdmD[1] = interp * derivUtil->VdmDL[1]; - //derivUtil->quadW = LibUtilities::MakeQuadratureWeights(U2,V1); - Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); - NekVector quadWi(qds); - derivUtil->quadW = quadWi; - } - break; - case 3: - { - ptsHelp->ptsLow = m_mesh->m_nummode*(m_mesh->m_nummode+1)*(m_mesh->m_nummode+2)/6; - LibUtilities::PointsKey pkey1(m_mesh->m_nummode, - LibUtilities::eNodalTetElec); - LibUtilities::PointsKey pkey2(m_mesh->m_nummode+2, - LibUtilities::eNodalTetSPI); - Array u1, v1, u2, v2, w1, w2; - LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1, w1); - LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2, w2); - NekVector U1(u1), V1(v1), W1(w1); - NekVector U2(u2), V2(v2), W2(w2); - ptsHelp->ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); - - NekMatrix interp = - LibUtilities::GetTetInterpolationMatrix(U1, V1, W1, - U2, V2, W2); - - NekMatrix Vandermonde = - LibUtilities::GetTetVandermonde(U1,V1,W1); - NekMatrix VandermondeI = Vandermonde; - VandermondeI.Invert(); - derivUtil->VdmDL[0] = LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI; - derivUtil->VdmDL[1] = LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI; - derivUtil->VdmDL[2] = LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI; - derivUtil->VdmD[0] = interp * derivUtil->VdmDL[0]; - derivUtil->VdmD[1] = interp * derivUtil->VdmDL[1]; - derivUtil->VdmD[2] = interp * derivUtil->VdmDL[2]; - Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); - NekVector quadWi(qds); - derivUtil->quadW = quadWi; - } - } + BuildDerivUtil(); GetElementMap(); vector > freenodes = GetColouredNodes(); vector > optiNodes; + //turn the free nodes into optimisable objects with all required data for(int i = 0; i < freenodes.size(); i++) { vector ns; @@ -225,30 +162,52 @@ void ProcessVarOpti::Process() NodeElMap::iterator it = nodeElMap.find(freenodes[i][j]->m_id); ASSERTL0(it != nodeElMap.end(), "could not find"); - if(freenodes[i][j]->GetNumCadCurve() == 0 && freenodes[i][j]->GetNumCADSurf() == 0) + if(freenodes[i][j]->GetNumCadCurve() == 0 && + freenodes[i][j]->GetNumCADSurf() == 0) { if(m_mesh->m_spaceDim == 3) { - ns.push_back(new NodeOpti3D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti)); + ns.push_back(new NodeOpti3D3D(freenodes[i][j], + it->second, + res, + derivUtil, + opti)); } else { - ns.push_back(new NodeOpti2D2D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti)); + ns.push_back(new NodeOpti2D2D(freenodes[i][j], + it->second, + res, + derivUtil, + opti)); } } else if(freenodes[i][j]->GetNumCadCurve() == 1) { - vector > cs = freenodes[i][j]->GetCADCurves(); - ns.push_back(new NodeOpti1D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti,cs[0].second)); + vector > cs = + freenodes[i][j]->GetCADCurves(); + ns.push_back(new NodeOpti1D3D(freenodes[i][j], + it->second, + res, + derivUtil, + opti, + cs[0].second)); } else if(freenodes[i][j]->GetNumCADSurf() == 1) { - vector > ss = freenodes[i][j]->GetCADSurfs(); - ns.push_back(new NodeOpti2D3D(freenodes[i][j],it->second,res,derivUtil,ptsHelp,opti,ss[0].second)); + vector > ss = + freenodes[i][j]->GetCADSurfs(); + ns.push_back(new NodeOpti2D3D(freenodes[i][j], + it->second, + res, + derivUtil, + opti, + ss[0].second)); } else { - ASSERTL0(false,"unsure"); + ASSERTL0(false, + "cannot resolve type of node optimisation to perform"); } } optiNodes.push_back(ns); @@ -299,7 +258,6 @@ void ProcessVarOpti::Process() { ctr++; res->val = 0.0; - res->func = 0.0; for(int i = 0; i < optiNodes.size(); i++) { vector jobs(optiNodes[i].size()); @@ -329,7 +287,6 @@ void ProcessVarOpti::Process() tm->Wait(); cout << ctr << "\tResidual: " << res->val - << "\tEnergy: " << res->func << "\tMin Jac: " << res->worstJac << "\tInvalid: " << res->startInv << endl; if(ctr >= maxIter) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h index 2bd4bd6d6..09834f0ec 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h @@ -50,15 +50,11 @@ struct DerivUtil NekMatrix VdmD[3]; NekMatrix VdmDL[3]; //deriv matrix without interp NekVector quadW; -}; -typedef boost::shared_ptr DerivUtilSharedPtr; -struct PtsHelper -{ int ptsHigh; int ptsLow; }; -typedef boost::shared_ptr PtsHelperSharedPtr; +typedef boost::shared_ptr DerivUtilSharedPtr; enum optimiser { @@ -75,7 +71,6 @@ struct Residual int nDoF; int startInv; NekDouble worstJac; - NekDouble func; }; typedef boost::shared_ptr ResidualSharedPtr; @@ -93,12 +88,13 @@ public: ProcessVarOpti(MeshSharedPtr m); virtual ~ProcessVarOpti(); - /// Write mesh to output file. virtual void Process(); + private: typedef std::map > NodeElMap; void FillQuadPoints(); + void BuildDerivUtil(); void GetElementMap(); std::vector > MappingIdealToRef(ElementSharedPtr el); std::vector > GetColouredNodes(); @@ -108,7 +104,6 @@ private: ResidualSharedPtr res; DerivUtilSharedPtr derivUtil; - PtsHelperSharedPtr ptsHelp; optimiser opti; }; -- GitLab From 2cbb51d5800839f303e0e419c79e4c13f869f435 Mon Sep 17 00:00:00 2001 From: mike turner Date: Tue, 26 Jul 2016 13:26:44 +0100 Subject: [PATCH 067/236] clean up cmake so that varopti is a dependant on OCE --- utilities/NekMesh/CMakeLists.txt | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/utilities/NekMesh/CMakeLists.txt b/utilities/NekMesh/CMakeLists.txt index 065e381f4..6e1b4da34 100644 --- a/utilities/NekMesh/CMakeLists.txt +++ b/utilities/NekMesh/CMakeLists.txt @@ -22,10 +22,6 @@ SET(NekMeshHeaders ProcessModules/ProcessScalar.h ProcessModules/ProcessSpherigon.h ProcessModules/ProcessTetSplit.h - ProcessModules/ProcessOptiExtract.h - ProcessModules/ProcessVarOpti/ProcessVarOpti.h - ProcessModules/ProcessVarOpti/NodeOpti.h - ProcessModules/ProcessVarOpti/ElUtil.h ) SET(NekMeshSources @@ -54,10 +50,6 @@ SET(NekMeshSources ProcessModules/ProcessSpherigon.cpp ProcessModules/ProcessTetSplit.cpp ProcessModules/ProcessOptiExtract.cpp - ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp - ProcessModules/ProcessVarOpti/PreProcessing.cpp - ProcessModules/ProcessVarOpti/NodeOpti.cpp - ProcessModules/ProcessVarOpti/ElUtil.cpp ) IF (NEKTAR_USE_CCM) @@ -71,8 +63,18 @@ IF (NEKTAR_USE_VTK) ENDIF (NEKTAR_USE_VTK) IF (NEKTAR_USE_MESHGEN) - SET(NekMeshHeaders ${NekMeshHeaders} InputModules/InputCAD.h) - SET(NekMeshSources ${NekMeshSources} InputModules/InputCAD.cpp) + SET(NekMeshHeaders ${NekMeshHeaders} + InputModules/InputCAD.h + ProcessModules/ProcessOptiExtract.h + ProcessModules/ProcessVarOpti/ProcessVarOpti.h + ProcessModules/ProcessVarOpti/NodeOpti.h + ProcessModules/ProcessVarOpti/ElUtil.h) + SET(NekMeshSources ${NekMeshSources} + InputModules/InputCAD.cpp + ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp + ProcessModules/ProcessVarOpti/PreProcessing.cpp + ProcessModules/ProcessVarOpti/NodeOpti.cpp + ProcessModules/ProcessVarOpti/ElUtil.cpp) ENDIF (NEKTAR_USE_MESHGEN) # Don't use macro -- this way we can just link against NekMeshUtils and -- GitLab From 342769c5c2ef6aa0174833ee12051817c79baaef Mon Sep 17 00:00:00 2001 From: mike turner Date: Tue, 26 Jul 2016 14:06:51 +0100 Subject: [PATCH 068/236] sort out regularisation code --- .../ProcessModules/ProcessVarOpti/ElUtil.cpp | 1 + .../ProcessModules/ProcessVarOpti/ElUtil.h | 1 + .../ProcessVarOpti/NodeOpti.cpp | 169 ++++++++---------- .../ProcessModules/ProcessVarOpti/NodeOpti.h | 3 + 4 files changed, 75 insertions(+), 99 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp index be48e24a9..b35b4da86 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp @@ -397,6 +397,7 @@ void ElUtil::Evaluate() delta = minEdge / m_el->GetConf().m_order / 500.0; + minJac = mn; } ElUtilJob* ElUtil::GetJob() diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h index 7fb77c075..14d94dd46 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.h @@ -69,6 +69,7 @@ public: std::vector > nodes; std::vector > maps; NekDouble delta; + NekDouble minJac; void Evaluate(); diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index 96644726c..74031215c 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -55,10 +55,22 @@ void NodeOpti::CalcDX() } } +void NodeOpti::CalcMinJac() +{ + minJac = numeric_limits::max(); + + for(int i = 0; i < data.size(); i++) + { + minJac = min(minJac, data[i]->minJac); + } +} + void NodeOpti2D2D::Optimise() { CalcDX(); + CalcMinJac(); + Array G = GetGrad(); if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-10) @@ -103,6 +115,8 @@ void NodeOpti3D3D::Optimise() { CalcDX(); + CalcMinJac(); + Array G = GetGrad(); if(sqrt(G[0]*G[0] + G[1]*G[1] + G[2]*G[2]) > 1e-10) @@ -166,6 +180,8 @@ void NodeOpti1D3D::Optimise() { CalcDX(); + CalcMinJac(); + Array G = GetGrad(); if(sqrt(G[0]*G[0]) > 1e-10) @@ -235,6 +251,8 @@ void NodeOpti2D3D::Optimise() { CalcDX(); + CalcMinJac(); + Array G = GetGrad(); if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-10) @@ -574,6 +592,17 @@ NekDouble NodeOpti::GetFunctional() NekDouble integral = 0.0; + NekDouble gam = numeric_limits::epsilon(); + NekDouble ep; + if(minJac < gam) + { + ep = sqrt(gam*(gam-minJac)); + } + else + { + ep = 0.0; + } + switch(opti) { case eLinEl: @@ -581,15 +610,13 @@ NekDouble NodeOpti::GetFunctional() const NekDouble nu = 0.4; const NekDouble mu = 1.0 / 2.0 / (1.0+nu); const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); - NekDouble jacDet[nElmt][derivUtil->ptsHigh], - trEtE[nElmt][derivUtil->ptsHigh]; - NekDouble jacMin = 0.0; for (int i = 0; i < nElmt; ++i) { for(int k = 0; k < derivUtil->ptsHigh; ++k) { NekDouble jacIdeal[DIM*DIM]; + NekDouble jacDet, trEtE; int cnt = 0; for (int m = 0; m < DIM; ++m) { @@ -599,33 +626,19 @@ NekDouble NodeOpti::GetFunctional() for (int l = 0; l < DIM; ++l) { jacIdeal[cnt] += - deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; } } } - jacDet[i][k] = JacDet(jacIdeal); - trEtE[i][k] = LinElasTrace(jacIdeal); - jacMin = min(jacMin,jacDet[i][k]); - } - } - NekDouble gam = numeric_limits::epsilon(); - NekDouble ep; - if(jacMin < gam) - { - ep = sqrt(gam*(gam-jacMin)); - } - else - { - ep = 0.0; - } + jacDet = JacDet(jacIdeal); + trEtE = LinElasTrace(jacIdeal); - for (int i = 0; i < nElmt; ++i) - { - for(int k = 0; k < derivUtil->ptsHigh; ++k) - { - NekDouble sigma = 0.5*(jacDet[i][k] + sqrt(jacDet[i][k]*jacDet[i][k] + 4.0*ep*ep)); + NekDouble sigma = 0.5*(jacDet + + sqrt(jacDet*jacDet + 4.0*ep*ep)); NekDouble lsigma = log(sigma); - integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (K * 0.5 * lsigma * lsigma + mu * trEtE[i][k]); + integral += derivUtil->quadW[k] * + fabs(data[i]->maps[k][9]) * + (K * 0.5 * lsigma * lsigma + mu * trEtE); } } break; @@ -640,11 +653,9 @@ NekDouble NodeOpti::GetFunctional() for (int i = 0; i < nElmt; ++i) { - bool valid = true; - NekDouble jacDet[derivUtil->ptsHigh], I1[derivUtil->ptsHigh]; - for(int k = 0; k < derivUtil->ptsHigh; ++k) { + NekDouble jacDet, I1; NekDouble jacIdeal[DIM*DIM]; int cnt = 0; for (int m = 0; m < DIM; ++m) @@ -655,37 +666,25 @@ NekDouble NodeOpti::GetFunctional() for (int l = 0; l < DIM; ++l) { jacIdeal[cnt] += - deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; } } } - jacDet[k] = JacDet(jacIdeal); - I1[k] = 0.0; + jacDet = JacDet(jacIdeal); + I1 = 0.0; for (int m = 0; m < DIM*DIM; ++m) { - I1[k] += jacIdeal[m]*jacIdeal[m]; + I1 += jacIdeal[m]*jacIdeal[m]; } - valid = valid ? jacDet[k] > 0.0 : false; - } - if (!valid) - { - for(int k = 0; k < derivUtil->ptsHigh; ++k) - { - NekDouble de = 1e-1; - NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); - NekDouble lsigma = log(sigma); - integral += derivUtil->quadW[k]*fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1[k] - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); - } - } - else - { - for(int k = 0; k < derivUtil->ptsHigh; ++k) - { - NekDouble lsigma = log(jacDet[k]); - integral += derivUtil->quadW[k]*fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1[k] - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); - } + NekDouble sigma = 0.5*(jacDet + + sqrt(jacDet*jacDet + 4.0*ep*ep)); + NekDouble lsigma = log(sigma); + integral += derivUtil->quadW[k]* + fabs(data[i]->maps[k][9]) * + (0.5 * mu * (I1 - 3.0 - 2.0*lsigma) + + 0.5 * K * lsigma * lsigma); } } break; @@ -695,11 +694,9 @@ NekDouble NodeOpti::GetFunctional() { for (int i = 0; i < nElmt; ++i) { - bool valid = true; - NekDouble jacDet[derivUtil->ptsHigh], frob[derivUtil->ptsHigh]; - for(int k = 0; k < derivUtil->ptsHigh; ++k) { + NekDouble jacDet, frob; NekDouble jacIdeal[DIM*DIM]; int cnt = 0; for (int m = 0; m < DIM; ++m) @@ -710,35 +707,23 @@ NekDouble NodeOpti::GetFunctional() for (int l = 0; l < DIM; ++l) { jacIdeal[cnt] += - deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; } } } - frob[k] = 0.0; + frob = 0.0; for (int m = 0; m < DIM*DIM; ++m) { - frob[k] += jacIdeal[m] * jacIdeal[m]; + frob += jacIdeal[m] * jacIdeal[m]; } - jacDet[k] = JacDet(jacIdeal); - valid = valid ? jacDet[k] > 0.0 : false; - } + jacDet = JacDet(jacIdeal); - if (!valid) - { - for(int k = 0; k < derivUtil->ptsHigh; ++k) - { - NekDouble de = 1e-2; - NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); - integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (frob[k] / DIM / pow(fabs(sigma), 2.0/DIM) -1.0); - } - } - else - { - for(int k = 0; k < derivUtil->ptsHigh; ++k) - { - integral += derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * (frob[k] / DIM / pow(fabs(jacDet[k]), 2.0/DIM) -1.0); - } + NekDouble sigma = 0.5*(jacDet + + sqrt(jacDet*jacDet + 4.0*ep*ep)); + integral += derivUtil->quadW[k] * + fabs(data[i]->maps[k][9]) * + (frob / DIM / pow(fabs(sigma), 2.0/DIM) -1.0); } } break; @@ -748,11 +733,9 @@ NekDouble NodeOpti::GetFunctional() { for (int i = 0; i < nElmt; ++i) { - bool valid = true; - NekDouble jacDet[derivUtil->ptsHigh], frob[derivUtil->ptsHigh]; - for(int k = 0; k < derivUtil->ptsHigh; ++k) { + NekDouble jacDet, frob; NekDouble jacIdeal[DIM*DIM]; int cnt = 0; for (int m = 0; m < DIM; ++m) @@ -763,35 +746,23 @@ NekDouble NodeOpti::GetFunctional() for (int l = 0; l < DIM; ++l) { jacIdeal[cnt] += - deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; } } } - frob[k] = 0.0; + frob = 0.0; for (int m = 0; m < DIM*DIM; ++m) { - frob[k] += jacIdeal[m] * jacIdeal[m]; + frob += jacIdeal[m] * jacIdeal[m]; } - jacDet[k] = JacDet(jacIdeal); - valid = valid ? jacDet[k] > 0.0 : false; - } + jacDet = JacDet(jacIdeal); - if (!valid) - { - for(int k = 0; k < derivUtil->ptsHigh; ++k) - { - NekDouble de = 1e-2; - NekDouble sigma = 0.5*(jacDet[k] + sqrt(jacDet[k]*jacDet[k] + 4.0*de*de)); - integral += derivUtil->quadW[k]*fabs(data[i]->maps[k][9])*(frob[k] / sigma); - } - } - else - { - for(int k = 0; k < derivUtil->ptsHigh; ++k) - { - integral += derivUtil->quadW[k]*fabs(data[i]->maps[k][9])*(frob[k] / jacDet[k]); - } + NekDouble sigma = 0.5*(jacDet + + sqrt(jacDet*jacDet + 4.0*ep*ep)); + integral += derivUtil->quadW[k]* + fabs(data[i]->maps[k][9])* + (frob / sigma); } } break; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h index ef36f938d..255e30ddf 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h @@ -75,7 +75,10 @@ protected: void CalcDX(); + void CalcMinJac(); + NekDouble dx; + NekDouble minJac; ResidualSharedPtr res; DerivUtilSharedPtr derivUtil; optimiser opti; -- GitLab From 1fab5f8c8f3fa22764bef38c8bc6c3e6e8025cca Mon Sep 17 00:00:00 2001 From: mike turner Date: Tue, 26 Jul 2016 14:14:05 +0100 Subject: [PATCH 069/236] clean up elutil --- utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp index b35b4da86..68582a8e0 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// File: ProcessJac.h +// File: ElUtil.cpp // // For more information, please see: http://www.nektar.info/ // -- GitLab From 008706707f2613e670c21fd045681f417ad74e96 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Tue, 9 Aug 2016 13:15:59 +0100 Subject: [PATCH 070/236] need to sort out nodal util --- .../ProcessModules/ProcessQualityMetric.h | 2 +- .../ProcessModules/ProcessQualityMetric.h | 76 ------------------- 2 files changed, 1 insertion(+), 77 deletions(-) delete mode 100644 utilities/FieldConvert/ProcessModules/ProcessQualityMetric.h diff --git a/library/FieldUtils/ProcessModules/ProcessQualityMetric.h b/library/FieldUtils/ProcessModules/ProcessQualityMetric.h index 0281f1a5e..2554925af 100644 --- a/library/FieldUtils/ProcessModules/ProcessQualityMetric.h +++ b/library/FieldUtils/ProcessModules/ProcessQualityMetric.h @@ -66,7 +66,7 @@ public: } private: - Array GetQ(LocalRegions::ExpansionSharedPtr e); + Array GetQ(LocalRegions::ExpansionSharedPtr e, bool s); }; } } diff --git a/utilities/FieldConvert/ProcessModules/ProcessQualityMetric.h b/utilities/FieldConvert/ProcessModules/ProcessQualityMetric.h deleted file mode 100644 index e91ab28cb..000000000 --- a/utilities/FieldConvert/ProcessModules/ProcessQualityMetric.h +++ /dev/null @@ -1,76 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// File: ProcessJacobianEnergy.h -// -// For more information, please see: http://www.nektar.info/ -// -// The MIT License -// -// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), -// Department of Aeronautics, Imperial College London (UK), and Scientific -// Computing and Imaging Institute, University of Utah (USA). -// -// License for the specific language governing rights and limitations under -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// Description: Computes energy of Jacobian. -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef UTILITIES_PREPROCESSING_FIELDCONVERT_PROCESSQUALITYMETRIC -#define UTILITIES_PREPROCESSING_FIELDCONVERT_PROCESSQUALITYMETRIC - -#include "../Module.h" - -namespace Nektar -{ -namespace Utilities -{ - -/// This processing module scales the input fld file -class ProcessQualityMetric : public ProcessModule -{ - public: - /// Creates an instance of this class - static boost::shared_ptr create(FieldSharedPtr f) - { - return MemoryManager::AllocateSharedPtr(f); - } - static ModuleKey className; - - ProcessQualityMetric(FieldSharedPtr f); - virtual ~ProcessQualityMetric(); - - /// Write mesh to output file. - virtual void Process(po::variables_map &vm); - - virtual std::string GetModuleName() - { - return "ProcessQualityMetric"; - } - - private: - Array GetQ(LocalRegions::ExpansionSharedPtr e, - bool s); -}; - -} -} - -#endif -- GitLab From 5f753cb67c73b98155f2d9c118140a91205610f8 Mon Sep 17 00:00:00 2001 From: David Moxey Date: Tue, 9 Aug 2016 14:12:03 +0100 Subject: [PATCH 071/236] Move to new nodal utilities --- .../ProcessModules/ProcessVarOpti/ElUtil.cpp | 4 +- .../ProcessVarOpti/PreProcessing.cpp | 54 ++++++++++++------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp index 68582a8e0..866e47c97 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp @@ -395,8 +395,8 @@ void ElUtil::Evaluate() minEdge = min(minEdge,es[i]->m_n1->Distance(es[i]->m_n2)); } - delta = minEdge / m_el->GetConf().m_order / 500.0; - + //delta = minEdge / m_el->GetConf().m_order / 500.0; + delta = 1e-4; minJac = mn; } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/PreProcessing.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/PreProcessing.cpp index 1c9edb973..2e6c6d164 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/PreProcessing.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/PreProcessing.cpp @@ -62,17 +62,27 @@ void ProcessVarOpti::BuildDerivUtil() LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1); LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2); - NekVector U1(u1), V1(v1); - NekVector U2(u2), V2(v2); - derivUtil->ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); - NekMatrix interp = LibUtilities::GetInterpolationMatrix(U1, V1, U2, V2); + derivUtil->ptsHigh = + LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); - NekMatrix Vandermonde = LibUtilities::GetVandermonde(U1,V1); + LibUtilities::NodalUtilTriangle nodalTri1( + m_mesh->m_nummode - 1, u1, v1); + LibUtilities::NodalUtilTriangle nodalTri2( + m_mesh->m_nummode - 1, u2, v2); + + Array > uv2(2); + uv2[0] = u2; + uv2[1] = v2; + + NekMatrix interp = *nodalTri1.GetInterpolationMatrix(uv2); + + NekMatrix Vandermonde = *nodalTri2.GetVandermonde(); NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); - derivUtil->VdmDL[0] = LibUtilities::GetVandermondeForXDerivative(U1,V1) * VandermondeI; - derivUtil->VdmDL[1] = LibUtilities::GetVandermondeForYDerivative(U1,V1) * VandermondeI; + + derivUtil->VdmDL[0] = *nodalTri1.GetVandermondeForDeriv(0) * VandermondeI; + derivUtil->VdmDL[1] = *nodalTri1.GetVandermondeForDeriv(1) * VandermondeI; derivUtil->VdmD[0] = interp * derivUtil->VdmDL[0]; derivUtil->VdmD[1] = interp * derivUtil->VdmDL[1]; //derivUtil->quadW = LibUtilities::MakeQuadratureWeights(U2,V1); @@ -91,21 +101,29 @@ void ProcessVarOpti::BuildDerivUtil() Array u1, v1, u2, v2, w1, w2; LibUtilities::PointsManager()[pkey1]->GetPoints(u1, v1, w1); LibUtilities::PointsManager()[pkey2]->GetPoints(u2, v2, w2); - NekVector U1(u1), V1(v1), W1(w1); - NekVector U2(u2), V2(v2), W2(w2); - derivUtil->ptsHigh = LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); - NekMatrix interp = - LibUtilities::GetTetInterpolationMatrix(U1, V1, W1, - U2, V2, W2); + derivUtil->ptsHigh = + LibUtilities::PointsManager()[pkey2]->GetNumPointsAlt(); - NekMatrix Vandermonde = - LibUtilities::GetTetVandermonde(U1,V1,W1); + LibUtilities::NodalUtilTetrahedron nodalTet1( + m_mesh->m_nummode - 1, u1, v1, w1); + LibUtilities::NodalUtilTetrahedron nodalTet2( + m_mesh->m_nummode - 1, u2, v2, w2); + + Array > uv2(3); + uv2[0] = u2; + uv2[1] = v2; + uv2[2] = w2; + + NekMatrix interp = *nodalTet1.GetInterpolationMatrix(uv2); + NekMatrix Vandermonde = *nodalTet1.GetVandermonde(); NekMatrix VandermondeI = Vandermonde; VandermondeI.Invert(); - derivUtil->VdmDL[0] = LibUtilities::GetVandermondeForTetXDerivative(U1,V1,W1) * VandermondeI; - derivUtil->VdmDL[1] = LibUtilities::GetVandermondeForTetYDerivative(U1,V1,W1) * VandermondeI; - derivUtil->VdmDL[2] = LibUtilities::GetVandermondeForTetZDerivative(U1,V1,W1) * VandermondeI; + + derivUtil->VdmDL[0] = *nodalTet1.GetVandermondeForDeriv(0) * VandermondeI; + derivUtil->VdmDL[1] = *nodalTet1.GetVandermondeForDeriv(1) * VandermondeI; + derivUtil->VdmDL[2] = *nodalTet1.GetVandermondeForDeriv(2) * VandermondeI; + derivUtil->VdmD[0] = interp * derivUtil->VdmDL[0]; derivUtil->VdmD[1] = interp * derivUtil->VdmDL[1]; derivUtil->VdmD[2] = interp * derivUtil->VdmDL[2]; -- GitLab From f3d6a5de17ea4861258519cad186c65f7d58930b Mon Sep 17 00:00:00 2001 From: David Moxey Date: Tue, 9 Aug 2016 16:50:28 +0100 Subject: [PATCH 072/236] Maybe somewhat working analytic gradients --- .../ProcessVarOpti/NodeOpti.cpp | 111 +++++++++++++++++- .../ProcessModules/ProcessVarOpti/NodeOpti.h | 1 + .../ProcessVarOpti/PreProcessing.cpp | 44 +++++-- .../ProcessVarOpti/ProcessVarOpti.cpp | 24 ++-- .../ProcessVarOpti/ProcessVarOpti.h | 2 + 5 files changed, 156 insertions(+), 26 deletions(-) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index 74031215c..b501755a9 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -167,7 +167,7 @@ void NodeOpti3D3D::Optimise() node->m_y = yc; node->m_z = zc; functional = currentW; - // cout << "warning: had to reset node" << endl; + //cout << "warning: had to reset node" << endl; } mtx.lock(); res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ @@ -477,6 +477,10 @@ Array NodeOpti3D3D::GetGrad() node->m_y = yc; node->m_z = zc; + w[0] = GetFunctional<3>(); + + //cout << "ANALYTIC: " << gradient[0] << " " << gradient[1] << " " << gradient[2] << endl; + Array ret(9,0.0); //ret[0] d/dx @@ -490,9 +494,17 @@ Array NodeOpti3D3D::GetGrad() //ret[7] d2/dxdz //ret[8] d2/dydz - ret[0] = (w[1] - w[4]) / 2.0 / dx; - ret[1] = (w[3] - w[6]) / 2.0 / dx; - ret[2] = (w[9] - w[8]) / 2.0 / dx; + + //ret[0] = (w[1] - w[4]) / 2.0 / dx; + //ret[1] = (w[3] - w[6]) / 2.0 / dx; + //ret[2] = (w[9] - w[8]) / 2.0 / dx; + + ret[0] = gradient[0]; + ret[1] = gradient[1]; + ret[2] = gradient[2]; + + //cout << "APPROX: " << ret[0] << " " << ret[1] << " " << ret[2] << endl; + //cout << endl; ret[3] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; ret[4] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; @@ -554,6 +566,36 @@ template<> inline NekDouble LinElasTrace<3>(NekDouble *jac) (jac[0]*jac[3]+jac[1]*jac[4]+jac[3]*jac[5])); } +template inline void InvTrans(NekDouble in[DIM][DIM], + NekDouble out[DIM][DIM]) +{ +} + +template<> +inline void InvTrans<2>(NekDouble in[2][2], NekDouble out[2][2]) +{ + NekDouble invDet = 1.0 / JacDet<2>(&in[0][0]); + out[0][0] = in[1][1] * invDet; + out[1][0] = -in[0][1] * invDet; + out[0][1] = -in[1][0] * invDet; + out[1][1] = in[0][0] * invDet; +} + +template<> +inline void InvTrans<3>(NekDouble in[3][3], NekDouble out[3][3]) +{ + NekDouble invdet = 1.0 / JacDet<3>(&in[0][0]); + out[0][0] = (in[1][1]*in[2][2]-in[2][1]*in[1][2])*invdet; + out[1][0] = -(in[0][1]*in[2][2]-in[0][2]*in[2][1])*invdet; + out[2][0] = (in[0][1]*in[1][2]-in[0][2]*in[1][1])*invdet; + out[0][1] = -(in[1][0]*in[2][2]-in[1][2]*in[2][0])*invdet; + out[1][1] = (in[0][0]*in[2][2]-in[0][2]*in[2][0])*invdet; + out[2][1] = -(in[0][0]*in[1][2]-in[1][0]*in[0][2])*invdet; + out[0][2] = (in[1][0]*in[2][1]-in[2][0]*in[1][1])*invdet; + out[1][2] = -(in[0][0]*in[2][1]-in[2][0]*in[0][1])*invdet; + out[2][2] = (in[0][0]*in[1][1]-in[1][0]*in[0][1])*invdet; +} + template NekDouble NodeOpti::GetFunctional() { @@ -651,13 +693,17 @@ NekDouble NodeOpti::GetFunctional() const NekDouble mu = 1.0 / 2.0 / (1.0+nu); const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); + gradient.resize(3); + gradient[0] = gradient[1] = gradient[2] = 0.0; + NekDouble jacIdeal[DIM*DIM], jacIdeal2[DIM][DIM]; + for (int i = 0; i < nElmt; ++i) { for(int k = 0; k < derivUtil->ptsHigh; ++k) { NekDouble jacDet, I1; - NekDouble jacIdeal[DIM*DIM]; int cnt = 0; + for (int m = 0; m < DIM; ++m) { for (int n = 0; n < DIM; ++n, ++cnt) @@ -668,6 +714,7 @@ NekDouble NodeOpti::GetFunctional() jacIdeal[cnt] += deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; } + jacIdeal2[m][n] = jacIdeal[cnt]; } } @@ -685,6 +732,60 @@ NekDouble NodeOpti::GetFunctional() fabs(data[i]->maps[k][9]) * (0.5 * mu * (I1 - 3.0 - 2.0*lsigma) + 0.5 * K * lsigma * lsigma); + + NekDouble jacInvTrans[DIM][DIM]; + NekDouble jacDetDeriv[DIM]; + InvTrans(jacIdeal2, jacInvTrans); + + for (int m = 0; m < DIM; ++m) + { + jacDetDeriv[m] = 0.0; + for (int n = 0; n < DIM; ++n) + { + jacDetDeriv[m] += jacInvTrans[m][n] * + derivUtil->basisDeriv[k][n]; + } + jacDetDeriv[m] *= jacDet; + } + + NekDouble jacDeriv[DIM][DIM][DIM]; + for (int m = 0; m < DIM; ++m) + { + for (int n = 0; n < DIM; ++n) + { + NekDouble delta = m == n ? 1.0 : 0.0; + for (int l = 0; l < DIM; ++l) + { + jacDeriv[m][n][l] = delta * derivUtil->basisDeriv[k][l]; + } + } + } + + NekDouble frobProd[DIM]; + for (int m = 0; m < DIM; ++m) + { + frobProd[m] = 0.0; + for (int n = 0; n < DIM; ++n) + { + for (int l = 0; l < DIM; ++l) + { + frobProd[m] += jacIdeal2[n][l] * jacDeriv[m][n][l]; + } + } + } + + for (int j = 0; j < DIM; ++j) + { + // gradient[j] += derivUtil->quadW[k] * + // fabs(data[i]->maps[k][9]) * ( + // mu * frobProd[j] + (K * lsigma - mu) / sigma * + // (0.5 * jacDetDeriv[j] * ( + // 1.0 + jacDet / (2.0 * sigma + jacDet)))); + gradient[j] = derivUtil->quadW[k] * fabs(data[i]->maps[k][9]) * ( + mu * frobProd[j] + ( + 0.5 * jacDetDeriv[j] * (1.0 + jacDet / (2.0*sigma - jacDet)) + / jacDet * (K * log(jacDet) - mu))); + } } } break; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h index 255e30ddf..079646e20 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h @@ -72,6 +72,7 @@ protected: template NekDouble GetFunctional(); NodeSharedPtr node; std::vector data; + std::vector gradient; void CalcDX(); diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/PreProcessing.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/PreProcessing.cpp index 2e6c6d164..1caf0affd 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/PreProcessing.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/PreProcessing.cpp @@ -130,6 +130,32 @@ void ProcessVarOpti::BuildDerivUtil() Array qds = LibUtilities::PointsManager()[pkey2]->GetW(); NekVector quadWi(qds); derivUtil->quadW = quadWi; + + // Set up derivatives + derivUtil->basisDeriv = Array >( + derivUtil->ptsHigh); + + NekVector tmp(derivUtil->ptsHigh); + NekVector derivout[3]; + + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < derivUtil->ptsHigh; ++j) + { + tmp(j) = uv2[i][j]; + } + + derivout[i] = derivUtil->VdmD[i] * tmp; + } + + for (int i = 0; i < derivUtil->ptsHigh; ++i) + { + derivUtil->basisDeriv[i] = Array(3); + for (int j = 0; j < 3; ++j) + { + derivUtil->basisDeriv[i][j] = derivout[j](i); + } + } } } } @@ -416,15 +442,15 @@ void ProcessVarOpti::FillQuadPoints() for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) { - if((*eit)->m_edgeNodes.size() > 0 && (*eit)->m_curveType == LibUtilities::eGaussLobattoLegendre) - { - //already high-order just need to Id and double check type - for(int i = 0; i < (*eit)->m_edgeNodes.size(); i++) - { - (*eit)->m_edgeNodes[i]->m_id = id++; - } - continue; - } + // if((*eit)->m_edgeNodes.size() > 0 && (*eit)->m_curveType == LibUtilities::eGaussLobattoLegendre) + // { + // //already high-order just need to Id and double check type + // for(int i = 0; i < (*eit)->m_edgeNodes.size(); i++) + // { + // (*eit)->m_edgeNodes[i]->m_id = id++; + // } + // continue; + // } SpatialDomains::Geometry1DSharedPtr geom = edgeGeoms[(*eit)->m_id]; StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap(); diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp index 944c7ef39..1c9e6fc56 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp @@ -117,18 +117,18 @@ void ProcessVarOpti::Process() const NekDouble restol = m_config["restol"].as(); EdgeSet::iterator eit; - bool fd = false; - for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) - { - if((*eit)->m_edgeNodes.size() > 0) - { - m_mesh->m_nummode = (*eit)->m_edgeNodes.size() + 2; - fd = true; - break; - } - } - ASSERTL0(fd,"failed to find order of mesh"); - + // bool fd = false; + // for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++) + // { + // if((*eit)->m_edgeNodes.size() > 0) + // { + // m_mesh->m_nummode = (*eit)->m_edgeNodes.size() + 2; + // fd = true; + // break; + // } + // } + // ASSERTL0(fd,"failed to find order of mesh"); + m_mesh->m_nummode = 5; if(m_mesh->m_verbose) { cout << "Indentified order as: " << m_mesh->m_nummode - 1 << endl; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h index 09834f0ec..bdb56a983 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ProcessVarOpti.h @@ -51,6 +51,8 @@ struct DerivUtil NekMatrix VdmDL[3]; //deriv matrix without interp NekVector quadW; + Array > basisDeriv; + int ptsHigh; int ptsLow; }; -- GitLab From 4a3d095259cb6b93788bdf84078c99f614aedf55 Mon Sep 17 00:00:00 2001 From: David Moxey Date: Tue, 9 Aug 2016 22:19:36 +0100 Subject: [PATCH 073/236] Fix some silly errors in the derivative modes setup, move things so that CAD is not required --- library/NekMeshUtils/MeshElements/Element.h | 4 +- library/NekMeshUtils/MeshElements/Node.h | 14 + utilities/NekMesh/CMakeLists.txt | 22 +- .../NekMesh/OutputModules/OutputNekpp.cpp | 7 +- .../ProcessModules/ProcessVarOpti/ElUtil.cpp | 70 ++-- .../ProcessVarOpti/NodeOpti.cpp | 373 ++++-------------- .../ProcessModules/ProcessVarOpti/NodeOpti.h | 86 ++-- .../ProcessVarOpti/NodeOptiCAD.cpp | 289 ++++++++++++++ .../ProcessVarOpti/NodeOptiCAD.h | 101 +++++ .../ProcessVarOpti/PreProcessing.cpp | 39 +- .../ProcessVarOpti/ProcessVarOpti.cpp | 94 ++--- 11 files changed, 619 insertions(+), 480 deletions(-) create mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiCAD.cpp create mode 100644 utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiCAD.h diff --git a/library/NekMeshUtils/MeshElements/Element.h b/library/NekMeshUtils/MeshElements/Element.h index 21afe5157..4c65c6abc 100644 --- a/library/NekMeshUtils/MeshElements/Element.h +++ b/library/NekMeshUtils/MeshElements/Element.h @@ -470,8 +470,8 @@ public: NEKMESHUTILS_EXPORT virtual void GetCurvedNodes( std::vector &nodeList) const { - cerr << "WARNING: Unsupported curvature for a " << m_vertex.size() - << "-vertex element is not yet implemented." << endl; + std::cerr << "WARNING: Unsupported curvature for a " << m_vertex.size() + << "-vertex element is not yet implemented." << std::endl; // Node orderings are different for different elements. // Triangle if (m_vertex.size() == 2) diff --git a/library/NekMeshUtils/MeshElements/Node.h b/library/NekMeshUtils/MeshElements/Node.h index 2d66036b6..90a04117c 100644 --- a/library/NekMeshUtils/MeshElements/Node.h +++ b/library/NekMeshUtils/MeshElements/Node.h @@ -354,7 +354,21 @@ public: } return ret; } +#else + int GetNumCadCurve() + { + return 0; + } + + int GetNumCADSurf() + { + return 0; + } + std::vector GetCADString() + { + return std::vector(); + } #endif /// ID of node. diff --git a/utilities/NekMesh/CMakeLists.txt b/utilities/NekMesh/CMakeLists.txt index 9314930ac..ceaaf6259 100644 --- a/utilities/NekMesh/CMakeLists.txt +++ b/utilities/NekMesh/CMakeLists.txt @@ -23,6 +23,10 @@ SET(NekMeshHeaders ProcessModules/ProcessScalar.h ProcessModules/ProcessSpherigon.h ProcessModules/ProcessTetSplit.h + ProcessModules/ProcessOptiExtract.h + ProcessModules/ProcessVarOpti/ProcessVarOpti.h + ProcessModules/ProcessVarOpti/NodeOpti.h + ProcessModules/ProcessVarOpti/ElUtil.h ) SET(NekMeshSources @@ -52,6 +56,10 @@ SET(NekMeshSources ProcessModules/ProcessSpherigon.cpp ProcessModules/ProcessTetSplit.cpp ProcessModules/ProcessOptiExtract.cpp + ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp + ProcessModules/ProcessVarOpti/PreProcessing.cpp + ProcessModules/ProcessVarOpti/NodeOpti.cpp + ProcessModules/ProcessVarOpti/ElUtil.cpp ) IF (NEKTAR_USE_CCM) @@ -66,17 +74,11 @@ ENDIF (NEKTAR_USE_VTK) IF (NEKTAR_USE_MESHGEN) SET(NekMeshHeaders ${NekMeshHeaders} - InputModules/InputCAD.h - ProcessModules/ProcessOptiExtract.h - ProcessModules/ProcessVarOpti/ProcessVarOpti.h - ProcessModules/ProcessVarOpti/NodeOpti.h - ProcessModules/ProcessVarOpti/ElUtil.h) + ProcessModules/ProcessVarOpti/NodeOptiCAD.h + InputModules/InputCAD.h) SET(NekMeshSources ${NekMeshSources} - InputModules/InputCAD.cpp - ProcessModules/ProcessVarOpti/ProcessVarOpti.cpp - ProcessModules/ProcessVarOpti/PreProcessing.cpp - ProcessModules/ProcessVarOpti/NodeOpti.cpp - ProcessModules/ProcessVarOpti/ElUtil.cpp) + ProcessModules/ProcessVarOpti/NodeOptiCAD.cpp + InputModules/InputCAD.cpp) ENDIF (NEKTAR_USE_MESHGEN) IF (NEKTAR_USE_ANN) diff --git a/utilities/NekMesh/OutputModules/OutputNekpp.cpp b/utilities/NekMesh/OutputModules/OutputNekpp.cpp index 80eaf250e..790374aee 100644 --- a/utilities/NekMesh/OutputModules/OutputNekpp.cpp +++ b/utilities/NekMesh/OutputModules/OutputNekpp.cpp @@ -1028,7 +1028,7 @@ void OutputNekpp::WriteXmlCAD(TiXmlElement *pRoot) } } } - + { EdgeSet::iterator it; for (it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); @@ -1100,7 +1100,10 @@ void OutputNekpp::WriteXmlCAD(TiXmlElement *pRoot) } } - pRoot->LinkEndChild(cad); + if (cad->FirstChild()) + { + pRoot->LinkEndChild(cad); + } } void OutputNekpp::WriteXmlCADId(TiXmlElement *pRoot) diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp index 866e47c97..8074d8fae 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/ElUtil.cpp @@ -139,58 +139,36 @@ vector > ElUtil::MappingIdealToRef() } else if(m_el->GetConf().m_e == LibUtilities::eTriangle) { - /*LibUtilities::PointsKey pkey(m_mode, - LibUtilities::eNodalTriElec); - Array u, v; - LibUtilities::PointsManager()[pkey]->GetPoints(u, v); - - Array xc(chi->GetTotPoints()); - Array yc(chi->GetTotPoints()); - - Array coeffs0 = geom->GetCoeffs(0); - Array coeffs1 = geom->GetCoeffs(1); - - chi->BwdTrans(coeffs0,xc); - chi->BwdTrans(coeffs1,yc); - - NekVector X(ptsHelp->ptsLow),Y(ptsHelp->ptsLow); - for(int j = 0; j < u.num_elements(); j++) - { - Array xp(2); - xp[0] = u[j]; - xp[1] = v[j]; + DNekMat J(2,2,0.0); + J(0,0) = (*nodes[1][0] - *nodes[0][0]); + J(1,0) = (*nodes[1][1] - *nodes[0][1]); + J(0,1) = (*nodes[2][0] - *nodes[0][0]); + J(1,1) = (*nodes[2][1] - *nodes[0][1]); - X(j) = chi->PhysEvaluate(xp, xc); - Y(j) = chi->PhysEvaluate(xp, yc); - } + J.Invert(); - NekVector x1i(ptsHelp->ptsHigh),y1i(ptsHelp->ptsHigh), - x2i(ptsHelp->ptsHigh),y2i(ptsHelp->ptsHigh); + DNekMat R(2,2,0.0); + R(0,0) = 2.0; + R(1,1) = 2.0; - x1i = derivUtil->VdmD[0]*X; - y1i = derivUtil->VdmD[0]*Y; - x2i = derivUtil->VdmD[1]*X; - y2i = derivUtil->VdmD[1]*Y; + J = J * R; - for(int i = 0 ; i < ptsHelp->ptsHigh; i++) + for(int i = 0 ; i < derivUtil->ptsHigh; i++) { - DNekMat dxdz(2,2,1.0,eFULL); - dxdz(0,0) = x1i(i); - dxdz(0,1) = x2i(i); - dxdz(1,0) = y1i(i); - dxdz(1,1) = y2i(i); - - Array r(10,0.0); - r[9] = dxdz(0,0)*dxdz(1,1)-dxdz(1,0)*dxdz(0,1); - - dxdz.Invert(); + Array r(10,0.0); //store det in 10th entry - r[0] = dxdz(0,0); - r[1] = dxdz(1,0); - r[3] = dxdz(0,1); - r[4] = dxdz(1,1); + r[9] = 1.0 / (J(0,0) * J(1,1) - J(0,1) * J(1,0)); + r[0] = J(0,0); + r[1] = J(1,0); + r[2] = 0.0; + r[3] = J(0,1); + r[4] = J(1,1); + r[5] = 0.0; + r[6] = 0.0; + r[7] = 0.0; + r[8] = 0.0; ret.push_back(r); - }*/ + } } else if(m_el->GetConf().m_e == LibUtilities::eTetrahedron) { @@ -396,7 +374,7 @@ void ElUtil::Evaluate() } //delta = minEdge / m_el->GetConf().m_order / 500.0; - delta = 1e-4; + delta = 1e-6; minJac = mn; } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp index b501755a9..621bcabfc 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.cpp @@ -43,7 +43,12 @@ namespace Nektar namespace Utilities { -boost::mutex mtx; +NodeOptiFactory &GetNodeOptiFactory() +{ + typedef Loki::SingletonHolder Type; + return Type::Instance(); +} void NodeOpti::CalcDX() { @@ -65,6 +70,9 @@ void NodeOpti::CalcMinJac() } } +int NodeOpti2D2D::m_type = GetNodeOptiFactory().RegisterCreatorFunction( + 22, NodeOpti2D2D::create, "2D2D"); + void NodeOpti2D2D::Optimise() { CalcDX(); @@ -110,6 +118,42 @@ void NodeOpti2D2D::Optimise() } } +Array NodeOpti2D2D::GetGrad() +{ + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + vector w(9); + + for(int i = 0; i < 7; i++) + { + node->m_x = xc + dir[i][0] * dx; + node->m_y = yc + dir[i][1] * dx; + w[i] = GetFunctional<2>(); + } + node->m_x = xc; + node->m_y = yc; + + Array ret(5,0.0); + + //ret[0] d/dx + //ret[1] d/dy + + //ret[3] d2/dx2 + //ret[4] d2/dy2 + //ret[5] d2/dxdy + + + ret[0] = (w[1] - w[4]) / 2.0 / dx; + ret[1] = (w[3] - w[6]) / 2.0 / dx; + ret[2] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; + ret[3] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; + ret[4] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / dx / dx; + + return ret; +} + +int NodeOpti3D3D::m_type = GetNodeOptiFactory().RegisterCreatorFunction( + 33, NodeOpti3D3D::create, "3D3D"); void NodeOpti3D3D::Optimise() { @@ -136,14 +180,20 @@ void NodeOpti3D3D::Optimise() -G[6]*(G[6]*G[5]-G[7]*G[8]) +G[7]*(G[6]*G[8]-G[7]*G[4]); - delX = G[0]*(G[4]*G[5]-G[8]*G[8]) + G[1]*(G[7]*G[8]-G[6]*G[5]) + G[2]*(G[6]*G[8]-G[7]*G[4]); + delX = G[0]*(G[4]*G[5]-G[8]*G[8]) + + G[1]*(G[7]*G[8]-G[6]*G[5]) + + G[2]*(G[6]*G[8]-G[7]*G[4]); + delY = G[0]*(G[8]*G[7]-G[6]*G[5]) + + G[1]*(G[3]*G[5]-G[7]*G[7]) + + G[2]*(G[6]*G[7]-G[3]*G[8]); + delZ = G[0]*(G[6]*G[8]-G[4]*G[7]) + + G[1]*(G[6]*G[7]-G[3]*G[8]) + + G[2]*(G[3]*G[4]-G[6]*G[6]); + delX /= det; - delY = G[0]*(G[8]*G[7]-G[6]*G[5]) + G[1]*(G[3]*G[5]-G[7]*G[7]) + G[2]*(G[6]*G[7]-G[3]*G[8]); delY /= det; - delZ = G[0]*(G[6]*G[8]-G[4]*G[7]) + G[1]*(G[6]*G[7]-G[3]*G[8]) + G[2]*(G[3]*G[4]-G[6]*G[6]); delZ /= det; - bool found = false; while(alpha > 1e-10) { @@ -166,7 +216,7 @@ void NodeOpti3D3D::Optimise() node->m_x = xc; node->m_y = yc; node->m_z = zc; - functional = currentW; + //functional = currentW; //cout << "warning: had to reset node" << endl; } mtx.lock(); @@ -176,288 +226,6 @@ void NodeOpti3D3D::Optimise() } } -void NodeOpti1D3D::Optimise() -{ - CalcDX(); - - CalcMinJac(); - - Array G = GetGrad(); - - if(sqrt(G[0]*G[0]) > 1e-10) - { - //needs to optimise - NekDouble tc = node->GetCADCurveInfo(curve->GetId()); - NekDouble currentW = GetFunctional<3>(); - NekDouble functional; - NekDouble xc = node->m_x; - NekDouble yc = node->m_y; - NekDouble zc = node->m_z; - NekDouble alpha = 1.0; - NekDouble delT; - NekDouble nt; - Array p; - - delT = G[0] / G[1]; - - Array bd = curve->Bounds(); - - bool found = false; - while(alpha > 1e-10) - { - nt = tc - alpha * delT; - if(nt < bd[0] || nt > bd[1]) - { - alpha /= 2.0; - continue; - } - p = curve->P(nt); - node->m_x = p[0]; - node->m_y = p[1]; - node->m_z = p[2]; - functional = GetFunctional<3>(); - if(functional < currentW) - { - found = true; - break; - } - - alpha /= 2.0; - } - - if(!found) - { - //reset the node - nt = tc; - p = curve->P(nt); - node->m_x = p[0]; - node->m_y = p[1]; - node->m_z = p[2]; - functional = currentW; - // cout << "warning: had to reset node" << endl; - } - else - { - node->MoveCurve(p,curve->GetId(),nt); - } - mtx.lock(); - res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ - (node->m_z-zc)*(node->m_z-zc)),res->val); - mtx.unlock(); - } -} - -void NodeOpti2D3D::Optimise() -{ - CalcDX(); - - CalcMinJac(); - - Array G = GetGrad(); - - if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-10) - { - //needs to optimise - Array uvc = node->GetCADSurfInfo(surf->GetId()); - NekDouble currentW = GetFunctional<3>(); - NekDouble functional; - NekDouble xc = node->m_x; - NekDouble yc = node->m_y; - NekDouble zc = node->m_z; - NekDouble alpha = 1.0; - Array uvt(2); - Array p; - NekDouble delU = 1.0/(G[2]*G[3]-G[4]*G[4])*(G[3]*G[0] - G[4]*G[1]); - NekDouble delV = 1.0/(G[2]*G[3]-G[4]*G[4])*(G[2]*G[1] - G[4]*G[0]); - - Array bd = surf->GetBounds(); - - bool found = false; - while(alpha > 1e-10) - { - uvt[0] = uvc[0] - alpha * delU; - uvt[1] = uvc[1] - alpha * delV; - - if(uvt[0] < bd[0] || uvt[0] > bd[1] || - uvt[1] < bd[2] || uvt[1] > bd[3]) - { - alpha /= 2.0; - continue; - } - - p = surf->P(uvt); - node->m_x = p[0]; - node->m_y = p[1]; - node->m_z = p[2]; - functional = GetFunctional<3>(); - if(functional < currentW) - { - found = true; - break; - } - - alpha /= 2.0; - } - - if(!found) - { - //reset the node - p = surf->P(uvc); - node->m_x = p[0]; - node->m_y = p[1]; - node->m_z = p[2]; - functional = currentW; - // cout << "warning: had to reset node" << endl; - } - else - { - node->Move(p,surf->GetId(),uvt); - } - mtx.lock(); - res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ - (node->m_z-zc)*(node->m_z-zc)),res->val); - mtx.unlock(); - } -} - -NekDouble dir[13][3] = {{ 0.0, 0.0, 0.0 }, // 0 (x , y , z ) - { 1.0, 0.0, 0.0 }, // 1 (x+dx, y , z ) - { 1.0, 1.0, 0.0 }, // 2 (x+dx, y+dy, z ) - { 0.0, 1.0, 0.0 }, // 3 (x , y+dy, z ) - { -1.0, 0.0, 0.0 }, // 4 (x-dx, y , z ) - { -1.0, -1.0, 0.0 }, // 5 (x-dx, y-dy, z ) - { 0.0, -1.0, 0.0 }, // 6 (x , y-dy, z ) - { -1.0, 0.0, -1.0 }, // 7 (x-dx, y , z-dz) - { 0.0, 0.0, -1.0 }, // 8 (x , y , z-dz) - { 0.0, 0.0, 1.0 }, // 9 (x , y , z+dz) - { 1.0, 0.0, 1.0 }, // 10 (x+dx, y , z+dz) - { 0.0, 1.0, 1.0 }, // 11 (x , y+dy, z+dz) - { 0.0, -1.0, -1.0 }}; // 12 (x , y-dy, z-dz) - -Array NodeOpti1D3D::GetGrad() -{ - NekDouble tc = node->GetCADCurveInfo(curve->GetId()); - Array d1 = curve->D1(tc); - - NekDouble dr = sqrt(d1[3]*d1[3] + d1[4]*d1[4] + d1[5]*d1[5]); - - NekDouble dt = dx / dr; - - vector w(3); - - w[0] = GetFunctional<3>(); - - NekDouble nt = tc + dt; - Array p = curve->P(nt); - node->m_x = p[0]; - node->m_y = p[1]; - node->m_z = p[2]; - w[1] = GetFunctional<3>(); - - nt = tc - dt; - p = curve->P(nt); - node->m_x = p[0]; - node->m_y = p[1]; - node->m_z = p[2]; - w[2] = GetFunctional<3>(); - - nt = tc; - p = curve->P(nt); - node->m_x = p[0]; - node->m_y = p[1]; - node->m_z = p[2]; - - Array ret(2,0.0); - - ret[0] = (w[1] - w[2]) / 2.0 / dt; - ret[1] = (w[1] + w[2] - 2.0*w[0]) / dt / dt; - - return ret; -} - -Array NodeOpti2D3D::GetGrad() -{ - Array uvc = node->GetCADSurfInfo(surf->GetId()); - Array d1 = surf->D1(uvc); - - NekDouble dru = sqrt(d1[3]*d1[3] + d1[4]*d1[4] + d1[5]*d1[5]); - NekDouble drv = sqrt(d1[6]*d1[6] + d1[7]*d1[7] + d1[8]*d1[8]); - - NekDouble du = dx / dru; - NekDouble dv = dx / drv; - - vector w(7); - - for(int i = 0; i < 7; i++) - { - Array uvt(2); - uvt[0] = uvc[0] + dir[i][0] * du; - uvt[1] = uvc[1] + dir[i][1] * dv; - Array p = surf->P(uvt); - node->m_x = p[0]; - node->m_y = p[1]; - node->m_z = p[2]; - w[i] = GetFunctional<3>(); - } - - Array p = surf->P(uvc); - node->m_x = p[0]; - node->m_y = p[1]; - node->m_z = p[2]; - - Array ret(5,0.0); - - //ret[0] d/dx - //ret[1] d/dy - - //ret[2] d2/dx2 - //ret[3] d2/dy2 - //ret[4] d2/dxdy - - - ret[0] = (w[1] - w[4]) / 2.0 / du; - ret[1] = (w[3] - w[6]) / 2.0 / dv; - ret[2] = (w[1] + w[4] - 2.0*w[0]) / du / du; - ret[3] = (w[3] + w[6] - 2.0*w[0]) / dv / dv; - ret[4] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / du / dv; - - return ret; -} - -Array NodeOpti2D2D::GetGrad() -{ - NekDouble xc = node->m_x; - NekDouble yc = node->m_y; - vector w(9); - - for(int i = 0; i < 7; i++) - { - node->m_x = xc + dir[i][0] * dx; - node->m_y = yc + dir[i][1] * dx; - w[i] = GetFunctional<2>(); - } - node->m_x = xc; - node->m_y = yc; - - Array ret(5,0.0); - - //ret[0] d/dx - //ret[1] d/dy - - //ret[3] d2/dx2 - //ret[4] d2/dy2 - //ret[5] d2/dxdy - - - ret[0] = (w[1] - w[4]) / 2.0 / dx; - ret[1] = (w[3] - w[6]) / 2.0 / dx; - ret[2] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; - ret[3] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; - ret[4] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / dx / dx; - - return ret; -} - Array NodeOpti3D3D::GetGrad() { NekDouble xc = node->m_x; @@ -494,18 +262,17 @@ Array NodeOpti3D3D::GetGrad() //ret[7] d2/dxdz //ret[8] d2/dydz - - //ret[0] = (w[1] - w[4]) / 2.0 / dx; - //ret[1] = (w[3] - w[6]) / 2.0 / dx; - //ret[2] = (w[9] - w[8]) / 2.0 / dx; - - ret[0] = gradient[0]; - ret[1] = gradient[1]; - ret[2] = gradient[2]; + //ret[0] = gradient[0]; + //ret[1] = gradient[1]; + //ret[2] = gradient[2]; //cout << "APPROX: " << ret[0] << " " << ret[1] << " " << ret[2] << endl; //cout << endl; + ret[0] = (w[1] - w[4]) / 2.0 / dx; + ret[1] = (w[3] - w[6]) / 2.0 / dx; + ret[2] = (w[9] - w[8]) / 2.0 / dx; + ret[3] = (w[1] + w[4] - 2.0*w[0]) / dx / dx; ret[4] = (w[3] + w[6] - 2.0*w[0]) / dx / dx; ret[5] = (w[9] + w[8] - 2.0*w[0]) / dx / dx; @@ -599,7 +366,7 @@ inline void InvTrans<3>(NekDouble in[3][3], NekDouble out[3][3]) template NekDouble NodeOpti::GetFunctional() { - const int nElmt = data.size(); + const int nElmt = data.size(); const int totpts = derivUtil->ptsLow * nElmt; NekDouble X[DIM * totpts]; @@ -627,13 +394,13 @@ NekDouble NodeOpti::GetFunctional() // Calculate x- and y-gradients for (int d = 0; d < DIM; ++d) { - Blas::Dgemm('N', 'N', derivUtil->ptsHigh, DIM * nElmt, derivUtil->ptsLow, 1.0, - derivUtil->VdmD[d].GetRawPtr(), derivUtil->ptsHigh, X, derivUtil->ptsLow, 0.0, - &deriv[d][0][0][0], derivUtil->ptsHigh); + Blas::Dgemm( + 'N', 'N', derivUtil->ptsHigh, DIM * nElmt, derivUtil->ptsLow, 1.0, + derivUtil->VdmD[d].GetRawPtr(), derivUtil->ptsHigh, X, + derivUtil->ptsLow, 0.0, &deriv[d][0][0][0], derivUtil->ptsHigh); } NekDouble integral = 0.0; - NekDouble gam = numeric_limits::epsilon(); NekDouble ep; if(minJac < gam) @@ -649,7 +416,7 @@ NekDouble NodeOpti::GetFunctional() { case eLinEl: { - const NekDouble nu = 0.4; + const NekDouble nu = 0.45; const NekDouble mu = 1.0 / 2.0 / (1.0+nu); const NekDouble K = 1.0 / 3.0 / (1.0 - 2.0 * nu); @@ -668,7 +435,7 @@ NekDouble NodeOpti::GetFunctional() for (int l = 0; l < DIM; ++l) { jacIdeal[cnt] += - deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; + deriv[l][i][n][k] * data[i]->maps[k][m * 3 + l]; } } } diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h index 079646e20..e95f3be2f 100644 --- a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOpti.h @@ -36,11 +36,11 @@ #ifndef UTILITIES_NEKMESH_NODEOPTI #define UTILITIES_NEKMESH_NODEOPTI +#include + #include "../../Module.h" #include "ProcessVarOpti.h" -#include - #include namespace Nektar @@ -48,6 +48,22 @@ namespace Nektar namespace Utilities { +const NekDouble dir[13][3] = { + { 0.0, 0.0, 0.0 }, // 0 (x , y , z ) + { 1.0, 0.0, 0.0 }, // 1 (x+dx, y , z ) + { 1.0, 1.0, 0.0 }, // 2 (x+dx, y+dy, z ) + { 0.0, 1.0, 0.0 }, // 3 (x , y+dy, z ) + { -1.0, 0.0, 0.0 }, // 4 (x-dx, y , z ) + { -1.0, -1.0, 0.0 }, // 5 (x-dx, y-dy, z ) + { 0.0, -1.0, 0.0 }, // 6 (x , y-dy, z ) + { -1.0, 0.0, -1.0 }, // 7 (x-dx, y , z-dz) + { 0.0, 0.0, -1.0 }, // 8 (x , y , z-dz) + { 0.0, 0.0, 1.0 }, // 9 (x , y , z+dz) + { 1.0, 0.0, 1.0 }, // 10 (x+dx, y , z+dz) + { 0.0, 1.0, 1.0 }, // 11 (x , y+dy, z+dz) + { 0.0, -1.0, -1.0 } // 12 (x , y-dy, z-dz) +}; + class NodeOptiJob; class NodeOpti @@ -64,6 +80,7 @@ public: virtual void Optimise() = 0; NodeOptiJob *GetJob(); + protected: virtual Array GetGrad() { @@ -75,9 +92,9 @@ protected: std::vector gradient; void CalcDX(); - void CalcMinJac(); + boost::mutex mtx; NekDouble dx; NekDouble minJac; ResidualSharedPtr res; @@ -85,44 +102,17 @@ protected: optimiser opti; }; -class NodeOpti1D3D : public NodeOpti //1D optimsation in 3D space -{ -public: - - NodeOpti1D3D(NodeSharedPtr n, std::vector e, - ResidualSharedPtr r, DerivUtilSharedPtr d, - optimiser o, CADCurveSharedPtr c) - : NodeOpti(n,e,r,d,o), curve(c) - { - } - - ~NodeOpti1D3D(){}; - - void Optimise(); - -private: - Array GetGrad(); - CADCurveSharedPtr curve; -}; - -class NodeOpti2D3D : public NodeOpti //1D optimsation in 3D space -{ -public: - NodeOpti2D3D(NodeSharedPtr n, std::vector e, - ResidualSharedPtr r, DerivUtilSharedPtr d, - optimiser o, CADSurfSharedPtr s) - : NodeOpti(n,e,r,d,o), surf(s) - { - } +typedef boost::shared_ptr NodeOptiSharedPtr; +typedef LibUtilities::NekFactory, + ResidualSharedPtr, + DerivUtilSharedPtr, + optimiser> NodeOptiFactory; - ~NodeOpti2D3D(){}; - - void Optimise(); +NodeOptiFactory &GetNodeOptiFactory(); -private: - Array GetGrad(); - CADSurfSharedPtr surf; -}; class NodeOpti3D3D : public NodeOpti //1D optimsation in 3D space { @@ -138,6 +128,15 @@ public: void Optimise(); + static int m_type; + static NodeOptiSharedPtr create( + NodeSharedPtr n, std::vector e, + ResidualSharedPtr r, DerivUtilSharedPtr d, + optimiser o) + { + return NodeOptiSharedPtr(new NodeOpti3D3D(n, e, r, d, o)); + } + private: Array GetGrad(); }; @@ -156,6 +155,15 @@ public: void Optimise(); + static int m_type; + static NodeOptiSharedPtr create( + NodeSharedPtr n, std::vector e, + ResidualSharedPtr r, DerivUtilSharedPtr d, + optimiser o) + { + return NodeOptiSharedPtr(new NodeOpti2D2D(n, e, r, d, o)); + } + private: Array GetGrad(); }; diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiCAD.cpp b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiCAD.cpp new file mode 100644 index 000000000..3afb12398 --- /dev/null +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiCAD.cpp @@ -0,0 +1,289 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: NodeOpti.cpp +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Calculate jacobians of elements. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "NodeOptiCAD.h" + +using namespace std; +using namespace Nektar::NekMeshUtils; + +namespace Nektar +{ +namespace Utilities +{ + +boost::mutex mtx; + +int NodeOpti1D3D::m_type = GetNodeOptiFactory().RegisterCreatorFunction( + 13, NodeOpti1D3D::create, "1D3D"); + +void NodeOpti1D3D::Optimise() +{ + CalcDX(); + + CalcMinJac(); + + Array G = GetGrad(); + + if(sqrt(G[0]*G[0]) > 1e-10) + { + //needs to optimise + NekDouble tc = node->GetCADCurveInfo(curve->GetId()); + NekDouble currentW = GetFunctional<3>(); + NekDouble functional; + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble zc = node->m_z; + NekDouble alpha = 1.0; + NekDouble delT; + NekDouble nt; + Array p; + + delT = G[0] / G[1]; + + Array bd = curve->Bounds(); + + bool found = false; + while(alpha > 1e-10) + { + nt = tc - alpha * delT; + if(nt < bd[0] || nt > bd[1]) + { + alpha /= 2.0; + continue; + } + p = curve->P(nt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + functional = GetFunctional<3>(); + if(functional < currentW) + { + found = true; + break; + } + + alpha /= 2.0; + } + + if(!found) + { + //reset the node + nt = tc; + p = curve->P(nt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + functional = currentW; + // cout << "warning: had to reset node" << endl; + } + else + { + node->MoveCurve(p,curve->GetId(),nt); + } + mtx.lock(); + res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ + (node->m_z-zc)*(node->m_z-zc)),res->val); + mtx.unlock(); + } +} + +int NodeOpti2D3D::m_type = GetNodeOptiFactory().RegisterCreatorFunction( + 23, NodeOpti2D3D::create, "1D3D"); + +void NodeOpti2D3D::Optimise() +{ + CalcDX(); + + CalcMinJac(); + + Array G = GetGrad(); + + if(sqrt(G[0]*G[0] + G[1]*G[1]) > 1e-10) + { + //needs to optimise + Array uvc = node->GetCADSurfInfo(surf->GetId()); + NekDouble currentW = GetFunctional<3>(); + NekDouble functional; + NekDouble xc = node->m_x; + NekDouble yc = node->m_y; + NekDouble zc = node->m_z; + NekDouble alpha = 1.0; + Array uvt(2); + Array p; + NekDouble delU = 1.0/(G[2]*G[3]-G[4]*G[4])*(G[3]*G[0] - G[4]*G[1]); + NekDouble delV = 1.0/(G[2]*G[3]-G[4]*G[4])*(G[2]*G[1] - G[4]*G[0]); + + Array bd = surf->GetBounds(); + + bool found = false; + while(alpha > 1e-10) + { + uvt[0] = uvc[0] - alpha * delU; + uvt[1] = uvc[1] - alpha * delV; + + if(uvt[0] < bd[0] || uvt[0] > bd[1] || + uvt[1] < bd[2] || uvt[1] > bd[3]) + { + alpha /= 2.0; + continue; + } + + p = surf->P(uvt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + functional = GetFunctional<3>(); + if(functional < currentW) + { + found = true; + break; + } + + alpha /= 2.0; + } + + if(!found) + { + //reset the node + p = surf->P(uvc); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + functional = currentW; + // cout << "warning: had to reset node" << endl; + } + else + { + node->Move(p,surf->GetId(),uvt); + } + mtx.lock(); + res->val = max(sqrt((node->m_x-xc)*(node->m_x-xc)+(node->m_y-yc)*(node->m_y-yc)+ + (node->m_z-zc)*(node->m_z-zc)),res->val); + mtx.unlock(); + } +} + +Array NodeOpti1D3D::GetGrad() +{ + NekDouble tc = node->GetCADCurveInfo(curve->GetId()); + Array d1 = curve->D1(tc); + + NekDouble dr = sqrt(d1[3]*d1[3] + d1[4]*d1[4] + d1[5]*d1[5]); + + NekDouble dt = dx / dr; + + vector w(3); + + w[0] = GetFunctional<3>(); + + NekDouble nt = tc + dt; + Array p = curve->P(nt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + w[1] = GetFunctional<3>(); + + nt = tc - dt; + p = curve->P(nt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + w[2] = GetFunctional<3>(); + + nt = tc; + p = curve->P(nt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + + Array ret(2,0.0); + + ret[0] = (w[1] - w[2]) / 2.0 / dt; + ret[1] = (w[1] + w[2] - 2.0*w[0]) / dt / dt; + + return ret; +} + +Array NodeOpti2D3D::GetGrad() +{ + Array uvc = node->GetCADSurfInfo(surf->GetId()); + Array d1 = surf->D1(uvc); + + NekDouble dru = sqrt(d1[3]*d1[3] + d1[4]*d1[4] + d1[5]*d1[5]); + NekDouble drv = sqrt(d1[6]*d1[6] + d1[7]*d1[7] + d1[8]*d1[8]); + + NekDouble du = dx / dru; + NekDouble dv = dx / drv; + + vector w(7); + + for(int i = 0; i < 7; i++) + { + Array uvt(2); + uvt[0] = uvc[0] + dir[i][0] * du; + uvt[1] = uvc[1] + dir[i][1] * dv; + Array p = surf->P(uvt); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + w[i] = GetFunctional<3>(); + } + + Array p = surf->P(uvc); + node->m_x = p[0]; + node->m_y = p[1]; + node->m_z = p[2]; + + Array ret(5,0.0); + + //ret[0] d/dx + //ret[1] d/dy + + //ret[2] d2/dx2 + //ret[3] d2/dy2 + //ret[4] d2/dxdy + + + ret[0] = (w[1] - w[4]) / 2.0 / du; + ret[1] = (w[3] - w[6]) / 2.0 / dv; + ret[2] = (w[1] + w[4] - 2.0*w[0]) / du / du; + ret[3] = (w[3] + w[6] - 2.0*w[0]) / dv / dv; + ret[4] = (w[2] - w[1] - w[3] + 2.0*w[0] - w[4] - w[6] + w[5]) / 2.0 / du / dv; + + return ret; +} + +} +} diff --git a/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiCAD.h b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiCAD.h new file mode 100644 index 000000000..6ac6e1cc6 --- /dev/null +++ b/utilities/NekMesh/ProcessModules/ProcessVarOpti/NodeOptiCAD.h @@ -0,0 +1,101 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessJac.h +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Description: Calculate jacobians of elements. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTILITIES_NEKMESH_NODEOPTI +#define UTILITIES_NEKMESH_NODEOPTI + +#include "NodeOpti.h" + +#include + +class NodeOpti1D3D : public NodeOpti //1D optimsation in 3D space +{ +public: + NodeOpti1D3D(NodeSharedPtr n, std::vector e, + ResidualSharedPtr r, DerivUtilSharedPtr d, + optimiser o, CADCurveSharedPtr c) + : NodeOpti(n,e,r,d,o), curve(c) + { + } + + ~NodeOpti1D3D(){}; + + void Optimise(); + + static int m_type; + static NodeOptiSharedPtr create( + NodeSharedPtr n, std::vector e, + ResidualSharedPtr r, DerivUtilSharedPtr d, + optimiser o) + { + vector > cs = n->GetCADCurves(); + return NodeOptiSharedPtr(new NodeOpti1D3D(n, e, r, d, o, cs[0].second)); + } + +private: + Array GetGrad(); + CADCurveSharedPtr curve; +}; + +class NodeOpti2D3D : public NodeOpti //1D optimsation in 3D space +{ +public: + NodeOpti2D3D(NodeSharedPtr n, std::vector e, + ResidualSharedPtr r, DerivUtilSharedPtr d, +