34 template<
class Po
intList>
38 const FixedList<label, 4>& pis,
45 return boundSphere(point::uniform(NaN), -vGreat);
48 return boundSphere(ps[pis[0]], 0);
54 const point c = (ps[pis[0]] + ps[pis[1]])/2;
77 const boundSphere
s = crSqr(tri.circumCircleSqr());
80 static const scalar ratio = small*3.0/4.0*
sqrt(scalar(3));
117 const boundSphere
s = crSqr(tet.circumSphereSqr());
120 static const scalar ratio = small*8.0/27.0*
sqrt(scalar(3));
121 if (!
s.valid() ||
sqr(tet.mag()) <
sqr(ratio)*
pow3(
s.rSqr_))
123 return boundSphere();
151 <<
"Cannot compute the intersect bounding sphere of more than "
153 return boundSphere(point::uniform(NaN), NaN);
158 template<
class Po
intList>
162 const FixedList<label, 4>& pis,
164 FixedList<label, 4>& boundaryPis
179 for (
label i = 0; i < 3; ++ i)
181 const label pi0 = pis[i];
182 const label pi1 = pis[(i + 1) % 3];
183 const label piOpp = pis[(i + 2) % 3];
185 const boundSphere
s = intersect(ps, {pi0, pi1, -1, -1}, 2);
187 if (
s.contains(ps[piOpp]))
189 boundaryPis[0] = pis[i];
190 boundaryPis[1] = pis[(i + 1) % 3];
201 static const FixedList<labelPair, 6> p01s =
202 {{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}};
203 static const FixedList<labelPair, 6> pOpp01s =
204 {{2, 3}, {1, 3}, {1, 2}, {0, 3}, {0, 2}, {0, 1}};
205 for (
label i = 0; i < 6; ++ i)
207 const label pi0 = pis[p01s[i].first()];
208 const label pi1 = pis[p01s[i].second()];
209 const label piOpp0 = pis[pOpp01s[i].first()];
210 const label piOpp1 = pis[pOpp01s[i].second()];
212 const boundSphere
s = intersect(ps, {pi0, pi1, -1, -1}, 2);
214 if (
s.contains(ps[piOpp0]) &&
s.contains(ps[piOpp1]))
216 boundaryPis[0] = pis[p01s[i].first()];
217 boundaryPis[1] = pis[p01s[i].second()];
223 boundSphere minS(point::uniform(NaN), vGreat);
225 for (
label i = 0; i < 4; ++ i)
227 const label pi0 = pis[i];
228 const label pi1 = pis[(i + 1) % 4];
229 const label pi2 = pis[(i + 2) % 4];
230 const label piOpp = pis[(i + 3) % 4];
232 const boundSphere
s = intersect(ps, {pi0, pi1, pi2, -1}, 3);
234 if (
s.contains(ps[piOpp]) &&
s.rSqr_ < minS.rSqr_)
243 boundaryPis[0] = pis[minSi];
244 boundaryPis[1] = pis[(minSi + 1) % 4];
245 boundaryPis[2] = pis[(minSi + 2) % 4];
254 <<
"Cannot compute the trivial bounding sphere of more than "
256 return boundSphere();
260 for (
label i = 0; i < nPs; ++ i)
262 boundaryPis[i] = pis[i];
264 sortBoundaryPis(boundaryPis);
267 return intersect(ps, pis, nPs);
271 template<
class Po
intList>
275 FixedList<label, 4>& boundaryPis
283 const FixedList<label, 4>& pis,
286 FixedList<label, 4>& boundaryPis
290 const boundSphere sStar = intersect(ps, pis, nPs);
295 for (
label pi = 0; bounds &&
pi < ps.size(); ++
pi)
298 for (; i < nPs; ++ i)
if (
pi == pis[i])
break;
299 if (i != nPs)
continue;
301 if (!sStar.contains(ps[
pi])) bounds =
false;
306 if (bounds && sStar.rSqr() <
s.rSqr())
314 if (ps.size() == 0)
return boundSphere();
317 boundSphere
s = boundSphere::crSqr(point::uniform(NaN), vGreat);
321 FixedList<label, 4> pis({-1, -1, -1, -1});
322 for (pis[0] = 0; pis[0] < ps.size(); ++ pis[0])
324 update(ps, pis, 1,
s, boundaryPis);
325 for (pis[1] = pis[0] + 1; pis[1] < ps.size(); ++ pis[1])
327 update(ps, pis, 2,
s, boundaryPis);
328 for (pis[2] = pis[1] + 1; pis[2] < ps.size(); ++ pis[2])
330 update(ps, pis, 3,
s, boundaryPis);
331 for (pis[3] = pis[2] + 1; pis[3] < ps.size(); ++ pis[3])
333 update(ps, pis, 4,
s, boundaryPis);
346 template<
class Po
intList,
class DLPermutation>
351 const typename DLPermutation::const_iterator& pisEnd,
352 FixedList<label, 4>& boundaryPis,
353 const label nBoundaryPs
356 boundSphere
s = intersect(ps, boundaryPis, nBoundaryPs);
358 if (pisEnd == pis.rend() || nBoundaryPs == 4)
return s;
360 for (
label boundaryi = nBoundaryPs; boundaryi < 4; ++ boundaryi)
362 boundaryPis[boundaryi] = -1;
367 typename DLPermutation::const_iterator piIter = pis.begin();
372 if (
s.contains(ps[*piIter]))
continue;
374 boundaryPis[nBoundaryPs] = *piIter;
376 s = Welzl(ps, pis, piIter, boundaryPis, nBoundaryPs + 1);
379 if (piIter != pis.begin())
381 const label i = *piIter;
382 piIter = piIter.previous();
391 template<
class Po
intList>
396 FixedList<label, 4>& boundaryPis
401 static const FixedList<label, 4> pis({0, 1, 2, 3});
403 return trivial(ps, pis, ps.size(), boundaryPis);
409 boundSphere
s = Welzl(ps, pis, pis.end(), boundaryPis, 0);
410 sortBoundaryPis(boundaryPis);
416 template<
class Po
intList>
421 FixedList<RemoteData<point>, 4>& boundaryPs,
426 if (!Pstream::parRun())
428 FixedList<label, 4> boundaryPis({-1, -1, -1, -1});
430 const boundSphere
s = local(ps,
rndGen, boundaryPis);
432 forAll(boundaryPis, boundaryi)
434 if (boundaryPis[boundaryi] != -1)
436 boundaryPs[boundaryi] =
440 boundaryPis[boundaryi],
441 ps[boundaryPis[boundaryi]]
449 LocalAndRemotePoints<PointList> larps(ps);
452 FixedList<label, 4> boundaryPis({-1, -1, -1, -1});
457 const boundSphere
s = Welzl(larps, pis, pis.end(), boundaryPis, 0);
463 for (; boundaryi < 4 && boundaryPis[boundaryi] != -1; ++ boundaryi)
465 procBoundaryPs[Pstream::myProcNo()][boundaryi] =
466 larps(boundaryPis[boundaryi]);
469 sortBoundaryPis(procBoundaryPs[Pstream::myProcNo()]);
471 Pstream::gatherList(procBoundaryPs);
472 Pstream::scatterList(procBoundaryPs);
478 forAll(procBoundaryPs, proci)
480 if (proci == Pstream::myProcNo())
continue;
482 for (
label boundaryi = 0; boundaryi < 4; ++ boundaryi)
484 const remote& r = procBoundaryPs[proci][boundaryi];
486 if (r != procBoundaryPs[Pstream::myProcNo()][boundaryi])
491 if (!complete)
break;
494 if (!complete)
break;
499 boundaryPs = procBoundaryPs[Pstream::myProcNo()];
505 forAll(procBoundaryPs, proci)
507 if (proci == Pstream::myProcNo())
continue;
509 for (
label boundaryi = 0; boundaryi < 4; ++ boundaryi)
511 const RemoteData<point>& rp = procBoundaryPs[proci][boundaryi];
513 if (rp.proci == -1)
break;
514 if (larps.found(rp))
continue;
516 if (
s.contains(rp.data))
continue;
518 larps.insertNoCheck(rp);
538 <<
"Global bound sphere iteration did not converge"
542 boundaryPs = procBoundaryPs[Pstream::master()];
547 return boundSphere();
551 #define InstantiateBoundSphere(PointList) \
553 template Foam::boundSphere Foam::boundSphere::implementation::intersect \
555 const PointList& ps, \
556 const FixedList<label, 4>& pis, \
560 template Foam::boundSphere Foam::boundSphere::implementation::trivial \
562 const PointList& ps, \
563 const FixedList<label, 4>& pis, \
565 FixedList<label, 4>& boundaryPis \
568 template Foam::boundSphere Foam::boundSphere::implementation::bruteForce \
570 const PointList& ps, \
571 FixedList<label, 4>& boundaryPis \
574 template Foam::boundSphere Foam::boundSphere::implementation::local \
576 const PointList& ps, \
577 randomGenerator& rndGen, \
578 FixedList<label, 4>& boundaryPis \
581 template Foam::boundSphere Foam::boundSphere::implementation::global \
583 const PointList& ps, \
584 randomGenerator& rndGen, \
585 FixedList<RemoteData<point>, 4>& boundaryPis, \
594 #undef InstantiateBoundSphere
602 is >>
s.c_ >>
s.rSqr_;
606 is.
check(
"operator>>(Istream&, boundSphere&)");
608 if (is.
format() == IOstream::ASCII &&
s.valid())
610 s.rSqr_ =
sqr(
s.rSqr_);
619 os <<
s.c_ << token::SPACE;
621 if (os.
format() == IOstream::ASCII &&
s.valid())
#define forAll(list, i)
Loop across all elements in list.
#define InstantiateBoundSphere(PointList)
streamFormat format() const
Return current stream format.
virtual bool check(const char *operation) const
Check IOstream status for given operation.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Istream & readEnd(const char *funcName)
Istream & readBegin(const char *funcName)
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
The smallest sphere enclosing a given set of points.
Motion of the mesh specified as a list of pointMeshMovers.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const dimensionedScalar c
Speed of light in a vacuum.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Istream & operator>>(Istream &, pointEdgeDist &)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
vector point
Point is a vector.
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
void pow3(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
DLPermutation< DynamicList< label > > dynamicDLPermutation
Define the type of a permutation based on a dynamic list.
triangle< point, const point & > triPointRef
Ostream & operator<<(Ostream &os, const fvConstraints &constraints)
void sqrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
tetrahedron< point, const point & > tetPointRef
DLPermutation< List< label > > dLPermutation
Define the type of a permutation based on a list.
randomGenerator rndGen(653213)