43 #include <boost/core/ignore_unused.hpp> 44 #include <boost/algorithm/string.hpp> 60 ProcessProjectCAD::create,
61 "Projects mesh to CAD");
79 boost::ignore_unused(surf);
81 point q(in[0], in[1], in[2]);
83 rtree.query(bgi::intersects(q), back_inserter(result));
85 if(result.size() == 0)
93 NekDouble minDist = numeric_limits<double>::max();
96 for (
int j = 0; j < result.size(); j++)
98 m_mesh->m_cad->GetSurf(result[j].second)->locuv(in, dist);
103 minsurf = result[j].second;
115 for(
int i = 0; i < els.size(); i++)
119 vector<NodeSharedPtr> ns = els[i]->GetVertexList();
120 for(
int j = 0; j < 6; j++)
126 NekDouble d = 0.5 * (prismU1[j] + prismW1[j]);
130 jac[0] = -0.5 * b1 * ns[0]->m_x + 0.5 * b1 * ns[1]->m_x +
131 0.5 * b2 * ns[2]->m_x - 0.5 * b2 * ns[3]->m_x;
132 jac[1] = -0.5 * b1 * ns[0]->m_y + 0.5 * b1 * ns[1]->m_y +
133 0.5 * b2 * ns[2]->m_y - 0.5 * b2 * ns[3]->m_y;
134 jac[2] = -0.5 * b1 * ns[0]->m_z + 0.5 * b1 * ns[1]->m_z +
135 0.5 * b2 * ns[2]->m_z - 0.5 * b2 * ns[3]->m_z;
137 jac[3] = 0.5 * d * ns[0]->m_x - 0.5 * a2 * ns[1]->m_x +
138 0.5 * a2 * ns[2]->m_x - 0.5 * d * ns[3]->m_x -
139 0.5 * c2 * ns[4]->m_x + 0.5 * c2 * ns[5]->m_x;
140 jac[4] = 0.5 * d * ns[0]->m_y - 0.5 * a2 * ns[1]->m_y +
141 0.5 * a2 * ns[2]->m_y - 0.5 * d * ns[3]->m_y -
142 0.5 * c2 * ns[4]->m_y + 0.5 * c2 * ns[5]->m_y;
143 jac[5] = 0.5 * d * ns[0]->m_z - 0.5 * a2 * ns[1]->m_z +
144 0.5 * a2 * ns[2]->m_z - 0.5 * d * ns[3]->m_z -
145 0.5 * c2 * ns[4]->m_z + 0.5 * c2 * ns[5]->m_z;
147 jac[6] = -0.5 * b1 * ns[0]->m_x - 0.5 * b2 * ns[3]->m_x +
148 0.5 * b1 * ns[4]->m_x + 0.5 * b2 * ns[5]->m_x;
149 jac[7] = -0.5 * b1 * ns[0]->m_y - 0.5 * b2 * ns[3]->m_y +
150 0.5 * b1 * ns[4]->m_y + 0.5 * b2 * ns[5]->m_y;
151 jac[8] = -0.5 * b1 * ns[0]->m_z - 0.5 * b2 * ns[3]->m_z +
152 0.5 * b1 * ns[4]->m_z + 0.5 * b2 * ns[5]->m_z;
154 NekDouble jc = jac[0] * (jac[4] * jac[8] - jac[5] * jac[7]) -
155 jac[3] * (jac[1] * jac[8] - jac[2] * jac[7]) +
156 jac[6] * (jac[1] * jac[5] - jac[2] * jac[4]);
166 vector<NodeSharedPtr> ns = els[i]->GetVertexList();
167 for(
int j = 0; j < 4; j++)
171 jac[0] = 0.5*(ns[1]->m_x - ns[0]->m_x);
172 jac[1] = 0.5*(ns[1]->m_y - ns[0]->m_y);
173 jac[2] = 0.5*(ns[1]->m_z - ns[0]->m_z);
174 jac[3] = 0.5*(ns[2]->m_x - ns[0]->m_x);
175 jac[4] = 0.5*(ns[2]->m_y - ns[0]->m_y);
176 jac[5] = 0.5*(ns[2]->m_z - ns[0]->m_z);
177 jac[6] = 0.5*(ns[3]->m_x - ns[0]->m_x);
178 jac[7] = 0.5*(ns[3]->m_y - ns[0]->m_y);
179 jac[8] = 0.5*(ns[3]->m_z - ns[0]->m_z);
181 NekDouble jc = jac[0] * (jac[4] * jac[8] - jac[5] * jac[7]) -
182 jac[3] * (jac[1] * jac[8] - jac[2] * jac[7]) +
183 jac[6] * (jac[1] * jac[5] - jac[2] * jac[4]);
204 cout <<
"ProcessAssignCAD: Processing... " << endl;
207 cout <<
"ProcessAssignCAD: Warning: This module is designed for use with " 208 "starccm+ meshes only, it also requires that the star mesh was " 209 "created in a certain way" << endl;
213 cout <<
"Mesh order not set will assume 4" << endl;
221 module->RegisterConfig(
"filename",
m_config[
"file"].as<string>());
222 module->SetDefaults();
227 for (
int i = 1; i <=
m_mesh->m_cad->GetNumSurf(); i++)
231 boxes.push_back(make_pair(
box(
point(bx[0], bx[1], bx[2]),
point(bx[3], bx[4], bx[5])), i));
235 cout <<
"building admin data structures" << endl;
237 bgi::rtree<boxI, bgi::quadratic<16> > rtree(boxes);
242 for(
int i = 0; i <
m_mesh->m_element[2].size(); i++)
245 vector<NodeSharedPtr> ns = el->GetVertexList();
246 for(
int j = 0; j < ns.size(); j++)
248 surfNodes.insert(ns[j]);
252 map<NodeSharedPtr, vector<ElementSharedPtr> > surfNodeToEl;
255 for(
int i = 0; i <
m_mesh->m_element[3].size(); i++)
257 if(
m_mesh->m_element[3][i]->HasBoundaryLinks())
259 vector<NodeSharedPtr> ns =
m_mesh->m_element[3][i]->GetVertexList();
260 for(
int j = 0; j < ns.size(); j++)
262 if(surfNodes.count(ns[j]) > 0)
264 surfNodeToEl[ns[j]].push_back(
m_mesh->m_element[3][i]);
271 map<NodeSharedPtr, NekDouble> minConEdge;
272 for (
int i = 0; i <
m_mesh->m_element[2].size(); i++)
275 vector<NodeSharedPtr> ns = el->GetVertexList();
280 if (minConEdge.count(ns[0]))
283 minConEdge[ns[0]] = min(l, min(l1, l3));
287 minConEdge.insert(make_pair(ns[0], min(l1, l3)));
289 if (minConEdge.count(ns[1]))
292 minConEdge[ns[1]] = min(l, min(l1, l1));
296 minConEdge.insert(make_pair(ns[1], min(l1, l1)));
298 if (minConEdge.count(ns[2]))
301 minConEdge[ns[2]] = min(l, min(l2, l3));
305 minConEdge.insert(make_pair(ns[2], min(l2, l3)));
309 map<int, vector<int> > finds;
311 cout <<
"searching tree" << endl;
321 for (
auto i = surfNodes.begin(); i != surfNodes.end(); i++, ct++)
325 point q((*i)->m_x, (*i)->m_y, (*i)->m_z);
327 rtree.query(bgi::intersects(q), back_inserter(result));
329 ASSERTL0(result.size() > 0,
"node thinks its not in any boxes");
332 tol = min(tol, 5e-4);
333 tol = max(tol, 1e-6);
336 vector<NekDouble> distList;
338 for (
int j = 0; j < result.size(); j++)
341 m_mesh->m_cad->GetSurf(result[j].second)->locuv((*i)->GetLoc(), dist);
342 distList.push_back(dist);
343 distId.push_back(result[j].second);
350 for (
int j = 0; j < distId.size() - 1; j++)
352 if (distList[j+1] < distList[j])
355 swap(distList[j+1], distList[j]);
356 swap(distId[j+1], distId[j]);
362 for (
int j = 0; j < distId.size(); j++)
364 if (distList[j] < tol)
372 finds[pos].push_back(0);
376 lockedNodes.insert(*i);
377 cout << endl <<
"WARNING: surface unknown " << distList[0] <<
" " << tol << endl;
383 for (
int j = 0; j < distId.size(); j++)
385 if (distList[j] > tol)
389 if (
m_mesh->m_cad->GetSurf(distId[j])->IsPlanar())
399 uvt = s->locuv(l, dist);
414 cout <<
"reset element projection" << endl;
424 lockedNodes.insert(*i);
428 for (
int j = 0; j < distId.size(); j++)
430 if (distList[j] > tol)
434 if (
m_mesh->m_cad->GetSurf(distId[j])->IsPlanar())
443 uv = s->locuv(loc, dist);
444 (*i)->SetCADSurf(s, uv);
446 maxNodeCor = max(maxNodeCor, shift);
452 cout <<
"max surface node correction " << maxNodeCor << endl;
457 vector<ElementSharedPtr> &elmt =
m_mesh->m_element[2];
458 map<int, int> surfIdToLoc;
459 for (
int i = 0; i < elmt.size(); i++)
461 surfIdToLoc.insert(make_pair(elmt[i]->GetId(), i));
462 for (
int j = 0; j < elmt[i]->GetEdgeCount(); ++j)
464 pair<EdgeSet::iterator,bool> testIns;
466 testIns = surfEdges.insert(ed);
471 ed2->m_elLink.push_back(
472 pair<ElementSharedPtr,int>(elmt[i],j));
477 elmt[i]->SetEdge(j, e2);
480 e2->m_elLink.push_back( pair<ElementSharedPtr,int>(elmt[i],j));
485 int order =
m_config[
"order"].as<
int>();
487 map<int, vector<int> > eds;
494 for (
auto i = surfEdges.begin(); i != surfEdges.end(); i++)
496 if (lockedNodes.count((*i)->m_n1) || lockedNodes.count((*i)->m_n2))
500 vector<CADSurfSharedPtr> v1 = (*i)->m_n1->GetCADSurfs();
501 vector<CADSurfSharedPtr> v2 = (*i)->m_n2->GetCADSurfs();
503 vector<int> vi1, vi2;
504 for (
size_t j = 0; j < v1.size(); ++j)
506 vi1.push_back(v1[j]->GetId());
508 for (
size_t j = 0; j < v2.size(); ++j)
510 vi2.push_back(v2[j]->GetId());
513 sort(vi1.begin(), vi1.end());
514 sort(vi2.begin(), vi2.end());
517 set_intersection(vi1.begin(), vi1.end(), vi2.begin(), vi2.end(), back_inserter(cmn));
518 eds[cmn.size()].push_back(0);
522 if (cmn.size() == 1 || cmn.size() == 2)
524 for (
int j = 0; j < cmn.size(); j++)
526 if (
m_mesh->m_cad->GetSurf(cmn[j])->IsPlanar())
539 NekDouble len = (*i)->m_n1->Distance((*i)->m_n2);
541 for (
int k = 1; k < order+1 - 1; k++)
544 uv[0] = uvb[0] * (1.0 - gll[k]) / 2.0 + uve[0] * (1.0 + gll[k]) / 2.0;
545 uv[1] = uvb[1] * (1.0 - gll[k]) / 2.0 + uve[1] * (1.0 + gll[k]) / 2.0;
547 loc =
m_mesh->m_cad->GetSurf(cmn[j])->P(uv);
549 locT[0] = (*i)->m_n1->m_x * (1.0 - gll[k]) / 2.0 +
550 (*i)->m_n2->m_x * (1.0 + gll[k]) / 2.0;
551 locT[1] = (*i)->m_n1->m_y * (1.0 - gll[k]) / 2.0 +
552 (*i)->m_n2->m_y * (1.0 + gll[k]) / 2.0;
553 locT[2] = (*i)->m_n1->m_z * (1.0 - gll[k]) / 2.0 +
554 (*i)->m_n2->m_z * (1.0 + gll[k]) / 2.0;
556 NekDouble d = sqrt((locT[0] - loc[0]) * (locT[0] - loc[0]) +
557 (locT[1] - loc[1]) * (locT[1] - loc[1]) +
558 (locT[2] - loc[2]) * (locT[2] - loc[2]));
562 (*i)->m_edgeNodes.clear();
567 new Node(0, loc[0], loc[1], loc[2]));
569 (*i)->m_edgeNodes.push_back(nn);
572 if ((*i)->m_edgeNodes.size() != 0)
579 else if (cmn.size() == 0)
586 for (
int k = 1; k < order+1 - 1; k++)
589 locT[0] = (*i)->m_n1->m_x * (1.0 - gll[k]) / 2.0 +
590 (*i)->m_n2->m_x * (1.0 + gll[k]) / 2.0;
591 locT[1] = (*i)->m_n1->m_y * (1.0 - gll[k]) / 2.0 +
592 (*i)->m_n2->m_y * (1.0 + gll[k]) / 2.0;
593 locT[2] = (*i)->m_n1->m_z * (1.0 - gll[k]) / 2.0 +
594 (*i)->m_n2->m_z * (1.0 + gll[k]) / 2.0;
599 (*i)->m_edgeNodes.clear();
604 if (sused.size() > 2)
606 (*i)->m_edgeNodes.clear();
611 new Node(0, locT[0], locT[1], locT[2]));
613 (*i)->m_edgeNodes.push_back(nn);
std::shared_ptr< CADSurf > CADSurfSharedPtr
#define ASSERTL0(condition, msg)
int PrintProgressbar(const int position, const int goal, const std::string message, int lastprogress=-1)
Prints a progressbar.
std::unordered_set< EdgeSharedPtr, EdgeHash > EdgeSet
const NekDouble prismV1[6]
std::shared_ptr< Module > ModuleSharedPtr
const NekDouble prismW1[6]
MeshSharedPtr m_mesh
Mesh object.
std::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
std::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
std::shared_ptr< Node > NodeSharedPtr
bool IsNotValid(std::vector< NekMeshUtils::ElementSharedPtr > &els)
std::unordered_set< NodeSharedPtr, NodeHash > NodeSet
bg::model::box< point > box
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
static const NekDouble kNekZeroTol
std::pair< ModuleType, std::string > ModuleKey
std::shared_ptr< Element > ElementSharedPtr
Represents a command-line configuration option.
PointsManagerT & PointsManager(void)
Defines a specification for a set of points.
std::map< std::string, ConfigOption > m_config
List of configuration values.
virtual NEKMESHUTILS_EXPORT void ClearElementLinks()
bg::model::point< double, 3, bg::cs::cartesian > point
std::pair< box, unsigned int > boxI
virtual ~ProcessProjectCAD()
bool findAndProject(bgi::rtree< boxI, bgi::quadratic< 16 > > &rtree, Array< OneD, NekDouble > in, int &surf)
Abstract base class for processing modules.
const NekDouble prismU1[6]
virtual void Process()
Write mesh to output file.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
std::pair< ModuleType, std::string > ModuleKey
1D Gauss-Lobatto-Legendre quadrature points
ModuleFactory & GetModuleFactory()