44 #include <boost/algorithm/string.hpp>
49 namespace NekMeshUtils
52 void Octree::Process()
57 CompileSourcePointList();
59 if (m_mesh->m_verbose)
61 cout <<
"\tCurvature samples: " << m_SPList.size() << endl;
65 m_dim = max((boundingBox[1] - boundingBox[0]) / 2.0,
66 (boundingBox[3] - boundingBox[2]) / 2.0);
68 m_dim = max(m_dim, (boundingBox[5] - boundingBox[4]) / 2.0);
71 m_centroid[0] = (boundingBox[1] + boundingBox[0]) / 2.0;
72 m_centroid[1] = (boundingBox[3] + boundingBox[2]) / 2.0;
73 m_centroid[2] = (boundingBox[5] + boundingBox[4]) / 2.0;
76 0, m_centroid[0], m_centroid[1], m_centroid[2], m_dim, m_SPList);
82 m_masteroct->CompileLeaves(m_octants);
84 if (m_mesh->m_verbose)
86 cout <<
"\tOctants: " << m_octants.size() << endl;
89 SmoothSurfaceOctants();
95 if (m_mesh->m_verbose)
97 int elem = CountElemt();
98 cout <<
"\tPredicted mesh: " << elem << endl;
108 NekDouble tmp = numeric_limits<double>::max();
110 for (
int i = 0; i < m_lsources.size(); i++)
112 if (m_lsources[i].withinRange(loc))
114 tmp = min(m_lsources[i].delta, tmp);
127 if (!(loc[0] < octloc[0]) &&
128 !(loc[1] < octloc[1]) &&
129 !(loc[2] < octloc[2]))
133 else if (!(loc[0] < octloc[0]) &&
134 !(loc[1] < octloc[1]) &&
135 !(loc[2] > octloc[2]))
139 else if (!(loc[0] < octloc[0]) &&
140 !(loc[1] > octloc[1]) &&
141 !(loc[2] < octloc[2]))
145 else if (!(loc[0] < octloc[0]) &&
146 !(loc[1] > octloc[1]) &&
147 !(loc[2] > octloc[2]))
151 else if (!(loc[0] > octloc[0]) &&
152 !(loc[1] < octloc[1]) &&
153 !(loc[2] < octloc[2]))
157 else if (!(loc[0] > octloc[0]) &&
158 !(loc[1] < octloc[1]) &&
159 !(loc[2] > octloc[2]))
163 else if (!(loc[0] > octloc[0]) &&
164 !(loc[1] > octloc[1]) &&
165 !(loc[2] < octloc[2]))
169 else if (!(loc[0] > octloc[0]) &&
170 !(loc[1] > octloc[1]) &&
171 !(loc[2] > octloc[2]))
177 ASSERTL0(
false,
"Cannot locate quadrant");
180 n = n->GetChild(quad);
188 return min(n->GetDelta(), tmp);
193 NekDouble tmp = numeric_limits<double>::max();
195 for (
int i = 0; i < m_lsources.size(); i++)
197 tmp = min(m_lsources[i].delta, tmp);
199 return min(m_minDelta, tmp);
202 void Octree::WriteOctree(
string nm)
209 for (
int i = 0; i < m_octants.size(); i++)
216 vector<NodeSharedPtr> ns(8);
218 ns[0] = boost::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eBack),
219 m_octants[i]->FX(
eDown),
220 m_octants[i]->FX(
eRight)));
222 ns[1] = boost::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eForward),
223 m_octants[i]->FX(
eDown),
224 m_octants[i]->FX(
eRight)));
226 ns[2] = boost::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eForward),
227 m_octants[i]->FX(
eUp),
228 m_octants[i]->FX(
eRight)));
230 ns[3] = boost::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eBack),
231 m_octants[i]->FX(
eUp),
232 m_octants[i]->FX(
eRight)));
234 ns[4] = boost::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eBack),
235 m_octants[i]->FX(
eDown),
236 m_octants[i]->FX(
eLeft)));
238 ns[5] = boost::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eForward),
239 m_octants[i]->FX(
eDown),
240 m_octants[i]->FX(
eLeft)));
242 ns[6] = boost::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eForward),
243 m_octants[i]->FX(
eUp),
244 m_octants[i]->FX(
eLeft)));
246 ns[7] = boost::shared_ptr<Node>(
new Node(0, m_octants[i]->FX(
eBack),
247 m_octants[i]->FX(
eUp),
248 m_octants[i]->FX(
eLeft)));
255 oct->m_element[3].push_back(E);
260 mod->RegisterConfig(
"outfile", nm);
261 mod->ProcessVertices();
264 mod->ProcessElements();
265 mod->ProcessComposites();
269 void Octree::SubDivide()
275 m_masteroct->Subdivide(m_masteroct, m_numoct);
277 if (m_mesh->m_verbose)
279 cout <<
"\tSubdivide iteration: ";
284 if (m_mesh->m_verbose)
288 cout <<
"\tSubdivide iteration: " << ct;
295 m_masteroct->CompileLeaves(m_octants);
307 vector<vector<OctantSharedPtr> > dividelist;
311 vector<OctantSharedPtr> sublist;
312 for (
int i = 0; i < m_octants.size(); i++)
314 if (m_octants[i]->NeedDivide() &&
315 m_octants[i]->DX() / 4.0 > m_minDelta)
317 sublist.push_back(m_octants[i]);
318 inlist.insert(m_octants[i]->GetId());
323 dividelist.push_back(sublist);
330 vector<OctantSharedPtr> newsublist,
331 previouslist = dividelist.back();
332 for (
int i = 0; i < previouslist.size(); i++)
334 map<OctantFace, vector<OctantSharedPtr> > nlist =
335 previouslist[i]->GetNeigbours();
336 map<OctantFace, vector<OctantSharedPtr> >
::iterator it;
337 for (it = nlist.begin(); it != nlist.end(); it++)
339 for (
int j = 0; j < it->second.size(); j++)
341 if (previouslist[i]->DX() < it->second[j]->DX())
344 inlist.find(it->second[j]->GetId());
345 if (s == inlist.end())
347 inlist.insert(it->second[j]->GetId());
348 newsublist.push_back(it->second[j]);
354 if (newsublist.size() == 0)
360 dividelist.push_back(newsublist);
364 vector<vector<OctantSharedPtr> >::reverse_iterator rit;
365 for (rit = dividelist.rbegin(); rit != dividelist.rend(); rit++)
367 vector<OctantSharedPtr> currentlist = *rit;
368 for (
int i = 0; i < currentlist.size(); i++)
370 currentlist[i]->Subdivide(currentlist[i], m_numoct);
375 if (m_mesh->m_verbose)
381 bool Octree::VerifyNeigbours()
388 for (
int i = 0; i < m_octants.size(); i++)
391 map<OctantFace, vector<OctantSharedPtr> > nlist =
392 m_octants[i]->GetNeigbours();
393 map<OctantFace, vector<OctantSharedPtr> >
::iterator it;
394 for (it = nlist.begin(); it != nlist.end(); it++)
396 if (it->second.size() == 0)
402 expectedfx = m_centroid[1] + m_dim;
405 expectedfx = m_centroid[1] - m_dim;
408 expectedfx = m_centroid[2] + m_dim;
411 expectedfx = m_centroid[2] - m_dim;
414 expectedfx = m_centroid[0] + m_dim;
417 expectedfx = m_centroid[0] - m_dim;
420 if (fabs(m_octants[i]->FX(it->first) - expectedfx) > 1E-6)
423 cout <<
"wall neigbour error" << endl;
424 cout << expectedfx <<
" " << m_octants[i]->FX(it->first)
425 <<
" " << it->first << endl;
428 else if (it->second.size() == 1)
430 if (!(m_octants[i]->DX() == it->second[0]->DX() ||
431 it->second[0]->DX() == 2.0 * m_octants[i]->DX()))
434 cout <<
" 1 neigbour error" << endl;
435 cout << m_octants[i]->DX() <<
" " << it->second[0]->DX()
439 else if (it->second.size() == 4)
441 if (!(m_octants[i]->DX() / 2.0 == it->second[0]->DX()))
444 cout <<
"4 neibour error" << endl;
445 cout << m_octants[i]->DX() <<
" " << it->second[0]->DX()
453 cout <<
"invalid neigbour config" << endl;
459 void Octree::SmoothSurfaceOctants()
469 for (
int i = 0; i < m_octants.size(); i++)
473 if (oct->IsDeltaKnown())
475 vector<OctantSharedPtr> check;
476 map<OctantFace, vector<OctantSharedPtr> > nList =
478 map<OctantFace, vector<OctantSharedPtr> >
::iterator it;
480 for (it = nList.begin(); it != nList.end(); it++)
482 for (
int j = 0; j < it->second.size(); j++)
484 if (it->second[j]->IsDeltaKnown() &&
485 it->second[j]->GetDelta() < oct->GetDelta() &&
486 ddx(oct, it->second[j]) > 0.2)
488 check.push_back(it->second[j]);
496 if (check.size() > 0)
498 NekDouble deltaSM = numeric_limits<double>::max();
499 for (
int j = 0; j < check.size(); j++)
503 if (0.199 * r + check[j]->GetDelta() < deltaSM)
505 deltaSM = 0.199 * r + check[j]->GetDelta();
508 oct->SetDelta(deltaSM);
516 void Octree::PropagateDomain()
527 for (
int i = 0; i < m_octants.size(); i++)
531 if (!oct->IsDeltaKnown())
533 vector<OctantSharedPtr> known;
534 map<OctantFace, vector<OctantSharedPtr> > nList =
536 map<OctantFace, vector<OctantSharedPtr> >
::iterator it;
538 for (it = nList.begin(); it != nList.end(); it++)
540 for (
int j = 0; j < it->second.size(); j++)
542 if (it->second[j]->IsDeltaKnown())
544 known.push_back(it->second[j]);
549 if (known.size() > 0)
551 vector<NekDouble> deltaPrime;
552 for (
int j = 0; j < known.size(); j++)
556 if (0.199 * r + known[j]->GetDelta() < m_maxDelta)
558 deltaPrime.push_back(0.199 * r +
559 known[j]->GetDelta());
563 deltaPrime.push_back(m_maxDelta);
566 NekDouble min = numeric_limits<double>::max();
567 for (
int j = 0; j < deltaPrime.size(); j++)
569 if (deltaPrime[j] < min)
583 vector<OctantSharedPtr> known;
584 map<OctantFace, vector<OctantSharedPtr> > nList =
586 map<OctantFace, vector<OctantSharedPtr> >
::iterator it;
588 for (it = nList.begin(); it != nList.end(); it++)
590 for (
int j = 0; j < it->second.size(); j++)
592 if (it->second[j]->GetLocation() !=
eUnknown)
594 known.push_back(it->second[j]);
599 if (known.size() > 0)
601 vector<OctantSharedPtr> isNotOnBound;
602 for (
int j = 0; j < known.size(); j++)
606 isNotOnBound.push_back(known[j]);
610 if (isNotOnBound.size() > 0)
612 oct->SetLocation(isNotOnBound[0]->GetLocation());
616 NekDouble dist = numeric_limits<double>::max();
621 for (
int j = 0; j < known.size(); j++)
623 if (oct->Distance(known[j]) < dist)
626 dist = oct->Distance(known[j]);
636 sp->GetCAD(surf, uv);
637 N = m_mesh->m_cad->GetSurf(surf)->N(uv);
639 octloc = oct->GetLoc();
640 sploc = sp->GetLoc();
642 vec[0] = octloc[0] - sploc[0];
643 vec[1] = octloc[1] - sploc[1];
644 vec[2] = octloc[2] - sploc[2];
647 vec[0] * N[0] + vec[1] * N[1] + vec[2] * N[2];
667 for (
int i = 0; i < m_octants.size(); i++)
669 if (!m_octants[i]->IsDeltaKnown())
671 m_octants[i]->SetDelta(m_maxDelta);
676 void Octree::SmoothAllOctants()
685 for (
int i = 0; i < m_octants.size(); i++)
689 vector<OctantSharedPtr> check;
690 map<OctantFace, vector<OctantSharedPtr> > nList =
692 map<OctantFace, vector<OctantSharedPtr> >
::iterator it;
693 for (it = nList.begin(); it != nList.end(); it++)
695 for (
int j = 0; j < it->second.size(); j++)
697 if (it->second[j]->GetDelta() < oct->GetDelta() &&
698 ddx(oct, it->second[j]) > 0.2)
700 check.push_back(it->second[j]);
705 if (check.size() > 0)
707 NekDouble deltaSM = numeric_limits<double>::max();
708 for (
int j = 0; j < check.size(); j++)
712 if (0.199 * r + check[j]->GetDelta() < deltaSM)
714 deltaSM = 0.199 * r + check[j]->GetDelta();
717 oct->SetDelta(deltaSM);
725 int Octree::CountElemt()
734 for (
int i = 0; i < m_octants.size(); i++)
737 if (oct->GetLocation() ==
eInside)
739 total += 8.0 * oct->DX() * oct->DX() * oct->DX() /
740 (oct->GetDelta() * oct->GetDelta() * oct->GetDelta() /
746 if (oct->FX(
eBack) < boundingBox[1] &&
751 if (oct->FX(
eBack) > boundingBox[0])
753 min = oct->FX(
eBack);
757 min = boundingBox[0];
759 if (boundingBox[1] < oct->FX(
eForward))
761 max = boundingBox[1];
774 if (oct->FX(
eDown) < boundingBox[3] &&
775 oct->FX(
eUp) > boundingBox[2])
779 if (oct->FX(
eDown) > boundingBox[2])
781 min = oct->FX(
eDown);
785 min = boundingBox[2];
787 if (boundingBox[3] < oct->FX(
eUp))
789 max = boundingBox[3];
802 if (oct->FX(
eRight) < boundingBox[5] &&
803 oct->FX(
eLeft) > boundingBox[4])
807 if (oct->FX(
eRight) > boundingBox[4])
813 min = boundingBox[4];
815 if (boundingBox[5] < oct->FX(
eLeft))
817 max = boundingBox[5];
821 max = oct->FX(
eLeft);
829 total += vol / 2.0 / (oct->GetDelta() * oct->GetDelta() *
830 oct->GetDelta() / 6.0 / sqrt(2));
837 void Octree::CompileSourcePointList()
840 if(m_mesh->m_cad->Is2D())
842 for (
int i = 1; i <= m_mesh->m_cad->GetNumCurve(); i++)
847 NekDouble dt = (bds[1] - bds[0]) / (samples + 1);
848 for (
int j = 1; j < samples - 1; j++)
855 vector<pair<CADSurfSharedPtr, CADOrientation::Orientation> > ss =
861 NekDouble del = 2.0 * (1.0 / C) * sqrt(m_eps * (2.0 - m_eps));
863 if (del > m_maxDelta)
867 if (del < m_minDelta)
874 ss[0].first->GetId(), uv, loc, del);
876 m_SPList.push_back(newCPoint);
882 ss[0].first->GetId(), uv, loc);
884 m_SPList.push_back(newBPoint);
890 for (
int i = 1; i <= m_mesh->m_cad->GetNumSurf(); i++)
892 if (m_mesh->m_verbose)
895 "\tCompiling source points");
911 NekDouble du = (bounds[1] - bounds[0]) / (40 - 1);
912 NekDouble dv = (bounds[3] - bounds[2]) / (40 - 1);
919 for (
int j = 0; j < 40; j++)
921 for (
int k = 0; k < 40; k++)
924 uv[0] = k * du + bounds[0];
925 uv[1] = j * dv + bounds[2];
930 samplepoints[k][j] = surf->P(uv);
934 for (
int j = 0; j < 40 - 1; j++)
936 for (
int k = 0; k < 40 - 1; k++)
939 (samplepoints[k][j][0] - samplepoints[k + 1][j][0]) *
940 (samplepoints[k][j][0] - samplepoints[k + 1][j][0]) +
941 (samplepoints[k][j][1] - samplepoints[k + 1][j][1]) *
942 (samplepoints[k][j][1] - samplepoints[k + 1][j][1]) +
943 (samplepoints[k][j][2] - samplepoints[k + 1][j][2]) *
944 (samplepoints[k][j][2] - samplepoints[k + 1][j][2]));
946 (samplepoints[k][j][0] - samplepoints[k][j + 1][0]) *
947 (samplepoints[k][j][0] - samplepoints[k][j + 1][0]) +
948 (samplepoints[k][j][1] - samplepoints[k][j + 1][1]) *
949 (samplepoints[k][j][1] - samplepoints[k][j + 1][1]) +
950 (samplepoints[k][j][2] - samplepoints[k][j + 1][2]) *
951 (samplepoints[k][j][2] - samplepoints[k][j + 1][2]));
962 int nu = ceil(DeltaU / m_minDelta) * 2;
963 int nv = ceil(DeltaV / m_minDelta) * 2;
965 for (
int j = 0; j < nu; j++)
967 for (
int k = 0; k < nv; k++)
970 uv[0] = (bounds[1] - bounds[0]) / (nu - 1) * j + bounds[0];
971 uv[1] = (bounds[3] - bounds[2]) / (nv - 1) * k + bounds[2];
987 2.0 * (1.0 / C) * sqrt(m_eps * (2.0 - m_eps));
989 if (del > m_maxDelta)
993 if (del < m_minDelta)
1000 surf->GetId(), uv, surf->P(uv), del);
1002 m_SPList.push_back(newCPoint);
1008 surf->GetId(), uv, surf->P(uv));
1010 m_SPList.push_back(newBPoint);
1015 if (m_mesh->m_verbose)
1020 if (m_refinement.size() > 0)
1022 if (m_mesh->m_verbose)
1024 cout <<
"\t\tModifying based on refinement lines" << endl;
1027 vector<string> lines;
1029 boost::split(lines, m_refinement, boost::is_any_of(
":"));
1031 for (
int i = 0; i < lines.size(); i++)
1033 vector<NekDouble> data;
1034 ParseUtils::GenerateUnOrderedVector(lines[i].c_str(), data);
1045 m_lsources.push_back(
linesource(x1, x2, data[6], data[7]));
1075 return fabs(i->GetDelta() - j->GetDelta()) / i->Distance(j);
#define ASSERTL0(condition, msg)
Basic information about an element.
tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(MAX_PARAM) BOOST_PP_ENUM_BINARY_PARAMS(MAX_PARAM, tParam, x))
Create an instance of the class referred to by idKey.
int PrintProgressbar(const int position, const int goal, const string message, int lastprogress=-1)
Prints a progressbar.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
pair< ModuleType, string > ModuleKey
ElementFactory & GetElementFactory()
boost::shared_ptr< Module > ModuleSharedPtr
boost::shared_ptr< SPBase > SPBaseSharedPtr
boost::shared_ptr< Octant > OctantSharedPtr
boost::shared_ptr< CADSurf > CADSurfSharedPtr
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
boost::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
boost::shared_ptr< Element > ElementSharedPtr
boost::shared_ptr< BPoint > BPointSharedPtr
boost::shared_ptr< CPoint > CPointSharedPtr
boost::shared_ptr< CADCurve > CADCurveSharedPtr
ModuleFactory & GetModuleFactory()