43 #include <boost/algorithm/string.hpp> 48 namespace NekMeshUtils
51 void Octree::Process()
56 CompileSourcePointList();
58 if (m_mesh->m_verbose)
60 cout <<
"\tCurvature samples: " << m_SPList.size() << endl;
64 m_dim = max((boundingBox[1] - boundingBox[0]) / 2.0,
65 (boundingBox[3] - boundingBox[2]) / 2.0);
67 m_dim = max(m_dim, (boundingBox[5] - boundingBox[4]) / 2.0);
70 m_centroid[0] = (boundingBox[1] + boundingBox[0]) / 2.0;
71 m_centroid[1] = (boundingBox[3] + boundingBox[2]) / 2.0;
72 m_centroid[2] = (boundingBox[5] + boundingBox[4]) / 2.0;
75 0, m_centroid[0], m_centroid[1], m_centroid[2], m_dim, m_SPList);
81 m_masteroct->CompileLeaves(m_octants);
83 if (m_mesh->m_verbose)
85 cout <<
"\tOctants: " << m_octants.size() << endl;
88 SmoothSurfaceOctants();
94 if (m_mesh->m_verbose)
96 int elem = CountElemt();
97 cout <<
"\tPredicted mesh: " << elem << endl;
107 NekDouble tmp = numeric_limits<double>::max();
109 for (
int i = 0; i < m_lsources.size(); i++)
111 if (m_lsources[i].withinRange(loc))
113 tmp = min(m_lsources[i].delta, tmp);
126 if (!(loc[0] < octloc[0]) &&
127 !(loc[1] < octloc[1]) &&
128 !(loc[2] < octloc[2]))
132 else if (!(loc[0] < octloc[0]) &&
133 !(loc[1] < octloc[1]) &&
134 !(loc[2] > octloc[2]))
138 else if (!(loc[0] < octloc[0]) &&
139 !(loc[1] > octloc[1]) &&
140 !(loc[2] < octloc[2]))
144 else if (!(loc[0] < octloc[0]) &&
145 !(loc[1] > octloc[1]) &&
146 !(loc[2] > octloc[2]))
150 else if (!(loc[0] > octloc[0]) &&
151 !(loc[1] < octloc[1]) &&
152 !(loc[2] < octloc[2]))
156 else if (!(loc[0] > octloc[0]) &&
157 !(loc[1] < octloc[1]) &&
158 !(loc[2] > octloc[2]))
162 else if (!(loc[0] > octloc[0]) &&
163 !(loc[1] > octloc[1]) &&
164 !(loc[2] < octloc[2]))
168 else if (!(loc[0] > octloc[0]) &&
169 !(loc[1] > octloc[1]) &&
170 !(loc[2] > octloc[2]))
176 ASSERTL0(
false,
"Cannot locate quadrant");
179 n = n->GetChild(quad);
187 return min(n->GetDelta(), tmp);
192 NekDouble tmp = numeric_limits<double>::max();
194 for (
int i = 0; i < m_lsources.size(); i++)
196 tmp = min(m_lsources[i].delta, tmp);
198 return min(m_minDelta, tmp);
201 void Octree::WriteOctree(
string nm)
208 for (
int i = 0; i < m_octants.size(); i++)
215 vector<NodeSharedPtr> ns(8);
217 ns[0] = std::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eBack),
218 m_octants[i]->FX(
eDown),
219 m_octants[i]->FX(
eRight)));
221 ns[1] = std::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eForward),
222 m_octants[i]->FX(
eDown),
223 m_octants[i]->FX(
eRight)));
225 ns[2] = std::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eForward),
226 m_octants[i]->FX(
eUp),
227 m_octants[i]->FX(
eRight)));
229 ns[3] = std::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eBack),
230 m_octants[i]->FX(
eUp),
231 m_octants[i]->FX(
eRight)));
233 ns[4] = std::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eBack),
234 m_octants[i]->FX(
eDown),
235 m_octants[i]->FX(
eLeft)));
237 ns[5] = std::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eForward),
238 m_octants[i]->FX(
eDown),
239 m_octants[i]->FX(
eLeft)));
241 ns[6] = std::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eForward),
242 m_octants[i]->FX(
eUp),
243 m_octants[i]->FX(
eLeft)));
245 ns[7] = std::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eBack),
246 m_octants[i]->FX(
eUp),
247 m_octants[i]->FX(
eLeft)));
254 oct->m_element[3].push_back(E);
259 mod->RegisterConfig(
"outfile", nm);
260 mod->ProcessVertices();
263 mod->ProcessElements();
264 mod->ProcessComposites();
268 void Octree::SubDivide()
274 m_masteroct->Subdivide(m_masteroct, m_numoct);
276 if (m_mesh->m_verbose)
278 cout <<
"\tSubdivide iteration: ";
283 if (m_mesh->m_verbose)
287 cout <<
"\tSubdivide iteration: " << ct;
294 m_masteroct->CompileLeaves(m_octants);
306 vector<vector<OctantSharedPtr> > dividelist;
310 vector<OctantSharedPtr> sublist;
311 for (
int i = 0; i < m_octants.size(); i++)
313 if (m_octants[i]->NeedDivide() &&
314 m_octants[i]->DX() / 4.0 > m_minDelta)
316 sublist.push_back(m_octants[i]);
317 inlist.insert(m_octants[i]->GetId());
322 dividelist.push_back(sublist);
329 vector<OctantSharedPtr> newsublist,
330 previouslist = dividelist.back();
331 for (
int i = 0; i < previouslist.size(); i++)
333 map<OctantFace, vector<OctantSharedPtr> > nlist =
334 previouslist[i]->GetNeigbours();
335 map<OctantFace, vector<OctantSharedPtr> >::iterator it;
336 for (it = nlist.begin(); it != nlist.end(); it++)
338 for (
int j = 0; j < it->second.size(); j++)
340 if (previouslist[i]->DX() < it->second[j]->DX())
342 set<int>::iterator s =
343 inlist.find(it->second[j]->GetId());
344 if (s == inlist.end())
346 inlist.insert(it->second[j]->GetId());
347 newsublist.push_back(it->second[j]);
353 if (newsublist.size() == 0)
359 dividelist.push_back(newsublist);
363 vector<vector<OctantSharedPtr> >::reverse_iterator rit;
364 for (rit = dividelist.rbegin(); rit != dividelist.rend(); rit++)
366 vector<OctantSharedPtr> currentlist = *rit;
367 for (
int i = 0; i < currentlist.size(); i++)
369 currentlist[i]->Subdivide(currentlist[i], m_numoct);
374 if (m_mesh->m_verbose)
380 bool Octree::VerifyNeigbours()
387 for (
int i = 0; i < m_octants.size(); i++)
390 map<OctantFace, vector<OctantSharedPtr> > nlist =
391 m_octants[i]->GetNeigbours();
392 map<OctantFace, vector<OctantSharedPtr> >::iterator it;
393 for (it = nlist.begin(); it != nlist.end(); it++)
395 if (it->second.size() == 0)
401 expectedfx = m_centroid[1] + m_dim;
404 expectedfx = m_centroid[1] - m_dim;
407 expectedfx = m_centroid[2] + m_dim;
410 expectedfx = m_centroid[2] - m_dim;
413 expectedfx = m_centroid[0] + m_dim;
416 expectedfx = m_centroid[0] - m_dim;
419 if (fabs(m_octants[i]->FX(it->first) - expectedfx) > 1E-6)
422 cout <<
"wall neigbour error" << endl;
423 cout << expectedfx <<
" " << m_octants[i]->FX(it->first)
424 <<
" " << it->first << endl;
427 else if (it->second.size() == 1)
429 if (!(m_octants[i]->DX() == it->second[0]->DX() ||
430 it->second[0]->DX() == 2.0 * m_octants[i]->DX()))
433 cout <<
" 1 neigbour error" << endl;
434 cout << m_octants[i]->DX() <<
" " << it->second[0]->DX()
438 else if (it->second.size() == 4)
440 if (!(m_octants[i]->DX() / 2.0 == it->second[0]->DX()))
443 cout <<
"4 neibour error" << endl;
444 cout << m_octants[i]->DX() <<
" " << it->second[0]->DX()
452 cout <<
"invalid neigbour config" << endl;
458 void Octree::SmoothSurfaceOctants()
468 for (
int i = 0; i < m_octants.size(); i++)
472 if (oct->IsDeltaKnown())
474 vector<OctantSharedPtr> check;
475 map<OctantFace, vector<OctantSharedPtr> > nList =
477 map<OctantFace, vector<OctantSharedPtr> >::iterator it;
479 for (it = nList.begin(); it != nList.end(); it++)
481 for (
int j = 0; j < it->second.size(); j++)
483 if (it->second[j]->IsDeltaKnown() &&
484 it->second[j]->GetDelta() < oct->GetDelta() &&
485 ddx(oct, it->second[j]) > 0.2)
487 check.push_back(it->second[j]);
495 if (check.size() > 0)
497 NekDouble deltaSM = numeric_limits<double>::max();
498 for (
int j = 0; j < check.size(); j++)
502 if (0.199 * r + check[j]->GetDelta() < deltaSM)
504 deltaSM = 0.199 * r + check[j]->GetDelta();
507 oct->SetDelta(deltaSM);
515 void Octree::PropagateDomain()
526 for (
int i = 0; i < m_octants.size(); i++)
530 if (!oct->IsDeltaKnown())
532 vector<OctantSharedPtr> known;
533 map<OctantFace, vector<OctantSharedPtr> > nList =
535 map<OctantFace, vector<OctantSharedPtr> >::iterator it;
537 for (it = nList.begin(); it != nList.end(); it++)
539 for (
int j = 0; j < it->second.size(); j++)
541 if (it->second[j]->IsDeltaKnown())
543 known.push_back(it->second[j]);
548 if (known.size() > 0)
550 vector<NekDouble> deltaPrime;
551 for (
int j = 0; j < known.size(); j++)
555 if (0.199 * r + known[j]->GetDelta() < m_maxDelta)
557 deltaPrime.push_back(0.199 * r +
558 known[j]->GetDelta());
562 deltaPrime.push_back(m_maxDelta);
565 NekDouble min = numeric_limits<double>::max();
566 for (
int j = 0; j < deltaPrime.size(); j++)
568 if (deltaPrime[j] < min)
582 vector<OctantSharedPtr> known;
583 map<OctantFace, vector<OctantSharedPtr> > nList =
585 map<OctantFace, vector<OctantSharedPtr> >::iterator it;
587 for (it = nList.begin(); it != nList.end(); it++)
589 for (
int j = 0; j < it->second.size(); j++)
591 if (it->second[j]->GetLocation() !=
eUnknown)
593 known.push_back(it->second[j]);
598 if (known.size() > 0)
600 vector<OctantSharedPtr> isNotOnBound;
601 for (
int j = 0; j < known.size(); j++)
605 isNotOnBound.push_back(known[j]);
609 if (isNotOnBound.size() > 0)
611 oct->SetLocation(isNotOnBound[0]->GetLocation());
615 NekDouble dist = numeric_limits<double>::max();
620 for (
int j = 0; j < known.size(); j++)
622 if (oct->Distance(known[j]) < dist)
625 dist = oct->Distance(known[j]);
635 sp->GetCAD(surf, uv);
636 N = m_mesh->m_cad->GetSurf(surf)->N(uv);
638 octloc = oct->GetLoc();
639 sploc = sp->GetLoc();
641 vec[0] = octloc[0] - sploc[0];
642 vec[1] = octloc[1] - sploc[1];
643 vec[2] = octloc[2] - sploc[2];
646 vec[0] * N[0] + vec[1] * N[1] + vec[2] * N[2];
666 for (
int i = 0; i < m_octants.size(); i++)
668 if (!m_octants[i]->IsDeltaKnown())
670 m_octants[i]->SetDelta(m_maxDelta);
675 void Octree::SmoothAllOctants()
684 for (
int i = 0; i < m_octants.size(); i++)
688 vector<OctantSharedPtr> check;
689 map<OctantFace, vector<OctantSharedPtr> > nList =
691 map<OctantFace, vector<OctantSharedPtr> >::iterator it;
692 for (it = nList.begin(); it != nList.end(); it++)
694 for (
int j = 0; j < it->second.size(); j++)
696 if (it->second[j]->GetDelta() < oct->GetDelta() &&
697 ddx(oct, it->second[j]) > 0.2)
699 check.push_back(it->second[j]);
704 if (check.size() > 0)
706 NekDouble deltaSM = numeric_limits<double>::max();
707 for (
int j = 0; j < check.size(); j++)
711 if (0.199 * r + check[j]->GetDelta() < deltaSM)
713 deltaSM = 0.199 * r + check[j]->GetDelta();
716 oct->SetDelta(deltaSM);
724 int Octree::CountElemt()
733 for (
int i = 0; i < m_octants.size(); i++)
736 if (oct->GetLocation() ==
eInside)
738 total += 8.0 * oct->DX() * oct->DX() * oct->DX() /
739 (oct->GetDelta() * oct->GetDelta() * oct->GetDelta() /
745 if (oct->FX(
eBack) < boundingBox[1] &&
750 if (oct->FX(
eBack) > boundingBox[0])
752 min = oct->FX(
eBack);
756 min = boundingBox[0];
758 if (boundingBox[1] < oct->FX(
eForward))
760 max = boundingBox[1];
773 if (oct->FX(
eDown) < boundingBox[3] &&
774 oct->FX(
eUp) > boundingBox[2])
778 if (oct->FX(
eDown) > boundingBox[2])
780 min = oct->FX(
eDown);
784 min = boundingBox[2];
786 if (boundingBox[3] < oct->FX(
eUp))
788 max = boundingBox[3];
801 if (oct->FX(
eRight) < boundingBox[5] &&
802 oct->FX(
eLeft) > boundingBox[4])
806 if (oct->FX(
eRight) > boundingBox[4])
812 min = boundingBox[4];
814 if (boundingBox[5] < oct->FX(
eLeft))
816 max = boundingBox[5];
820 max = oct->FX(
eLeft);
828 total += vol / 2.0 / (oct->GetDelta() * oct->GetDelta() *
829 oct->GetDelta() / 6.0 / sqrt(2));
836 void Octree::CompileSourcePointList()
839 if(m_mesh->m_cad->Is2D())
841 totalEnt += m_mesh->m_cad->GetNumCurve();
842 for (
int i = 1; i <= m_mesh->m_cad->GetNumCurve(); i++)
844 if (m_mesh->m_verbose)
847 "\tCompiling source points");
853 int samples = ceil(curve->Length(bds[0],bds[1]) / m_minDelta) * 2;
854 samples = max(40, samples);
855 NekDouble dt = (bds[1] - bds[0]) / (samples + 1);
856 for (
int j = 1; j < samples - 1; j++)
863 vector<pair<CADSurfSharedPtr, CADOrientation::Orientation> > ss =
869 NekDouble del = 2.0 * (1.0 / C) * sqrt(m_eps * (2.0 - m_eps));
871 if (del > m_maxDelta)
875 if (del < m_minDelta)
882 ss[0].first->GetId(), uv,
loc, del);
884 m_SPList.push_back(newCPoint);
890 ss[0].first->GetId(), uv,
loc);
892 m_SPList.push_back(newBPoint);
899 totalEnt = m_mesh->m_cad->GetNumSurf();
900 for (
int i = 1; i <= totalEnt; i++)
902 if (m_mesh->m_verbose)
905 "\tCompiling source points");
921 NekDouble du = (bounds[1] - bounds[0]) / (40 - 1);
922 NekDouble dv = (bounds[3] - bounds[2]) / (40 - 1);
929 for (
int j = 0; j < 40; j++)
931 for (
int k = 0; k < 40; k++)
934 uv[0] = k * du + bounds[0];
935 uv[1] = j * dv + bounds[2];
940 samplepoints[k][j] = surf->P(uv);
944 for (
int j = 0; j < 40 - 1; j++)
946 for (
int k = 0; k < 40 - 1; k++)
949 (samplepoints[k][j][0] - samplepoints[k + 1][j][0]) *
950 (samplepoints[k][j][0] - samplepoints[k + 1][j][0]) +
951 (samplepoints[k][j][1] - samplepoints[k + 1][j][1]) *
952 (samplepoints[k][j][1] - samplepoints[k + 1][j][1]) +
953 (samplepoints[k][j][2] - samplepoints[k + 1][j][2]) *
954 (samplepoints[k][j][2] - samplepoints[k + 1][j][2]));
956 (samplepoints[k][j][0] - samplepoints[k][j + 1][0]) *
957 (samplepoints[k][j][0] - samplepoints[k][j + 1][0]) +
958 (samplepoints[k][j][1] - samplepoints[k][j + 1][1]) *
959 (samplepoints[k][j][1] - samplepoints[k][j + 1][1]) +
960 (samplepoints[k][j][2] - samplepoints[k][j + 1][2]) *
961 (samplepoints[k][j][2] - samplepoints[k][j + 1][2]));
972 int nu = ceil(DeltaU * 40 / m_minDelta) * 2;
973 int nv = ceil(DeltaV * 40 / m_minDelta) * 2;
977 for (
int j = 0; j < nu; j++)
979 for (
int k = 0; k < nv; k++)
982 uv[0] = (bounds[1] - bounds[0]) / (nu - 1) * j + bounds[0];
983 uv[1] = (bounds[3] - bounds[2]) / (nv - 1) * k + bounds[2];
999 2.0 * (1.0 / C) * sqrt(m_eps * (2.0 - m_eps));
1001 if (del > m_maxDelta)
1005 if (del < m_minDelta)
1012 surf->GetId(), uv, surf->P(uv), del);
1014 m_SPList.push_back(newCPoint);
1020 surf->GetId(), uv, surf->P(uv));
1022 m_SPList.push_back(newBPoint);
1028 if (m_mesh->m_verbose)
1033 if (m_refinement.size() > 0)
1035 if (m_mesh->m_verbose)
1037 cout <<
"\t\tModifying based on refinement lines" << endl;
1040 vector<string> lines;
1042 boost::split(lines, m_refinement, boost::is_any_of(
":"));
1044 for (
int i = 0; i < lines.size(); i++)
1046 vector<NekDouble> data;
1047 ParseUtils::GenerateVector(lines[i], data);
1058 m_lsources.push_back(
linesource(x1, x2, data[6], data[7]));
1088 return fabs(i->GetDelta() - j->GetDelta()) / i->Distance(j);
std::shared_ptr< CADSurf > CADSurfSharedPtr
#define ASSERTL0(condition, msg)
Basic information about an element.
std::shared_ptr< BPoint > BPointSharedPtr
int PrintProgressbar(const int position, const int goal, const std::string message, int lastprogress=-1)
Prints a progressbar.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
std::shared_ptr< Module > ModuleSharedPtr
std::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
ElementFactory & GetElementFactory()
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
std::pair< ModuleType, std::string > ModuleKey
std::shared_ptr< Element > ElementSharedPtr
std::shared_ptr< CADCurve > CADCurveSharedPtr
std::shared_ptr< CPoint > CPointSharedPtr
std::shared_ptr< Octant > OctantSharedPtr
std::shared_ptr< SPBase > SPBaseSharedPtr
ModuleFactory & GetModuleFactory()