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);
#define ASSERTL0(condition, msg)
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
Represents a point in the domain.
std::pair< ModuleType, std::string > ModuleKey
ModuleFactory & GetModuleFactory()
int PrintProgressbar(const int position, const int goal, const std::string message, int lastprogress=-1)
Prints a progressbar.
std::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
std::shared_ptr< CADSurf > CADSurfSharedPtr
ElementFactory & GetElementFactory()
std::shared_ptr< Octant > OctantSharedPtr
std::shared_ptr< BPoint > BPointSharedPtr
std::shared_ptr< CADCurve > CADCurveSharedPtr
std::shared_ptr< SPBase > SPBaseSharedPtr
std::shared_ptr< Element > ElementSharedPtr
std::shared_ptr< CPoint > CPointSharedPtr
std::shared_ptr< Module > ModuleSharedPtr
Basic information about an element.