20 : m_solverId(solverId_), m_mpiComm(comm), m_geometryContext(comm), m_haloElementOffset(0) {
22 MPI_Comm_rank(mpiComm(), &m_domainId);
23 MPI_Comm_size(mpiComm(), &m_noDomains);
39 m_inOutTest =
"perpOp";
40 m_inOutTest = Context::getSolverProperty<MString>(
"inOutTest", m_solverId, AT_, &m_inOutTest);
42 m_parallelGeometry =
false;
55 m_parallelGeometry = Context::getSolverProperty<MBool>(
"parallelGeometry", m_solverId, AT_, &m_parallelGeometry);
56 if(m_noDomains == 1) m_parallelGeometry = 0;
71 m_debugParGeom = Context::getSolverProperty<MBool>(
"debugParGeom", m_solverId, AT_, &m_debugParGeom);
76 m_flowSolver = Context::getBasicProperty<MBool>(
"flowSolver", AT_, &m_flowSolver);
85 for(
MInt i = 0; i < nDim * 2; i++) {
86 bBox[i] = m_minMax[i];
93 for(
MInt i = 0; i < nDim * 2; i++) {
94 bBox[i] = m_mbminMax[i];
100 m_adt->writeTreeToDx();
116 for(
MInt d = 0; d < nDim; d++)
117 ret = ret &&
approx(
a[d],
b[d], MFloatEps);
136 std::array<MFloat, nDim> edge;
137 for(
MInt i = 0; i < num; i++) {
139 for(
MInt j = 0; j < nDim; j++) {
140 edge[j] = bndVs[(i + 1) % num][j] - bndVs[i][j];
141 tmp_length += edge[j] * edge[j];
143 circ += sqrt(tmp_length);
159 std::array<MInt, nDim> numcutsperdir{};
160 return pointIsInside(coordinates, numcutsperdir.data());
180 const MFloat*
const box = boundingBox();
181 MBool isInside =
true;
182 for(
MInt dir = 0; dir < nDim; dir++) {
184 array<MFloat, 2 * nDim> ray;
185 for(
MInt i = 0; i < nDim; i++) {
186 ray[i] = coordinates[i];
187 ray[i + nDim] = coordinates[i];
189 ray[dir] = box[dir] - (ray[dir] - box[dir]);
192 std::vector<MInt> nodeList;
193 getLineIntersectionElements(&ray[0], nodeList);
194 numcutsperdir[dir] = nodeList.size();
195 isInside = isInside && (numcutsperdir[dir] % 2 == 0);
216 std::vector<MInt> nodeList;
218 const MBool onlyCheck = (numcutsperdir ==
nullptr);
220 MInt spaceDirectionId[3];
222 const MFloat* tmp = boundingBox();
226 for(
MInt j = 0; j < nDim; j++) {
227 target[j] = coordinates[j];
228 target[j + nDim] = coordinates[j];
231 target[0] = tmp[0] - (target[0] - tmp[0]);
233 if(m_inOutTest ==
"perpOp") {
234 getLineIntersectionElements(target, nodeList);
236 spaceDirectionId[0] = 1;
237 spaceDirectionId[1] = 2;
238 spaceDirectionId[2] = 0;
239 getLineIntersectionElementsOld2(target, spaceDirectionId, nodeList);
241 const MInt noNodesX = nodeList.size();
243 for(
MInt j = 0; j < nDim; j++) {
244 target[j] = coordinates[j];
245 target[j + nDim] = coordinates[j];
248 target[1] = tmp[1] - (target[1] - tmp[1]);
250 if(m_inOutTest ==
"perpOp") {
251 getLineIntersectionElements(target, nodeList);
253 spaceDirectionId[0] = 2;
254 spaceDirectionId[1] = 0;
255 spaceDirectionId[2] = 1;
256 getLineIntersectionElementsOld2(target, spaceDirectionId, nodeList);
258 const MInt noNodesY = nodeList.size();
262 if(noNodesX % 2 != noNodesY % 2) {
269 IF_CONSTEXPR(nDim == 3) {
270 for(
MInt j = 0; j < nDim; j++) {
271 target[j] = coordinates[j];
272 target[j + nDim] = coordinates[j];
275 target[2] = tmp[2] - (target[2] - tmp[2]);
278 if(m_inOutTest ==
"perpOp") {
279 getLineIntersectionElements(target, nodeList);
281 spaceDirectionId[0] = 0;
282 spaceDirectionId[1] = 1;
283 spaceDirectionId[2] = 2;
284 getLineIntersectionElementsOld2(target, spaceDirectionId, nodeList);
286 noNodesZ = nodeList.size();
288 if(noNodesX % 2 == noNodesY % 2 && noNodesX % 2 == noNodesZ % 2) {
302 if(noNodesX % 2 == noNodesY % 2) {
311 numcutsperdir[0] = noNodesX;
312 numcutsperdir[1] = noNodesY;
313 numcutsperdir[2] = noNodesZ;
327 MInt* bodyBndryCndIds,
328 MInt* setToBodiesTable,
329 MInt noBodiesInSet) {
333 MInt noNodesX_set = 0;
334 MInt noNodesY_set = 0;
335 MInt noNodesZ_set = 0;
338 std::vector<MInt> nodeList;
340 MFloat target[2 * nDim]{};
342 getBoundingBoxMB(&tmp[0]);
346 for(
MInt j = 0; j < nDim; j++) {
347 target[j] = coordinates[j];
348 target[j + nDim] = coordinates[j];
350 target[0] = tmp[0] - (target[0] - tmp[0]);
351 getLineIntersectionMBElements(target, nodeList);
352 const MInt noNodesX = nodeList.size();
353 for(
MInt node = 0; node < noNodesX; node++) {
354 for(
MInt b = 0;
b < noBodiesInSet;
b++) {
355 body = setToBodiesTable[
b];
356 bcId = bodyBndryCndIds[body];
357 if(mbelements[nodeList[node]].m_bndCndId == bcId) {
364 for(
MInt j = 0; j < nDim; j++) {
365 target[j] = coordinates[j];
366 target[j + nDim] = coordinates[j];
368 target[1] = tmp[1] - (target[1] - tmp[1]);
370 getLineIntersectionMBElements(target, nodeList);
371 const MInt noNodesY = nodeList.size();
372 for(
MInt node = 0; node < noNodesY; node++) {
373 for(
MInt b = 0;
b < noBodiesInSet;
b++) {
374 body = setToBodiesTable[
b];
375 bcId = bodyBndryCndIds[body];
376 if(mbelements[nodeList[node]].m_bndCndId == bcId) {
384 IF_CONSTEXPR(nDim == 3) {
385 for(
MInt j = 0; j < nDim; j++) {
386 target[j] = coordinates[j];
387 target[j + nDim] = coordinates[j];
390 target[2] = tmp[2] - (target[2] - tmp[2]);
393 getLineIntersectionMBElements(target, nodeList);
394 const MInt noNodesZ = nodeList.size();
395 for(
MInt node = 0; node < noNodesZ; node++) {
396 for(
MInt b = 0;
b < noBodiesInSet;
b++) {
397 body = setToBodiesTable[
b];
398 bcId = bodyBndryCndIds[body];
399 if(mbelements[nodeList[node]].m_bndCndId == bcId) {
406 if(noNodesX_set % 2 == noNodesY_set % 2 && noNodesX_set % 2 == noNodesZ_set % 2) {
407 noNodes = noNodesX_set;
420 if(noNodesX_set % 2 == noNodesY_set % 2) {
421 noNodes = noNodesX_set;
443 MInt* bodyBndryCndIds,
444 MInt* setToBodiesTable,
445 MInt noBodiesInSet) {
452 MInt noNodesX_set = 0;
453 MInt noNodesY_set = 0;
454 MInt noNodesZ_set = 0;
458 const MInt maxNoNodesDebug = 1000;
463 MInt spaceDirectionId[3];
468 getBoundingBoxMB(tmpPtr);
472 for(
MInt j = 0; j < nDim; j++) {
473 target[j] = coordinates[j];
474 target[j + nDim] = coordinates[j];
476 spaceDirectionId[0] = 1;
477 spaceDirectionId[1] = 2;
478 spaceDirectionId[2] = 0;
481 target[0] = tmp[0] - (target[0] - tmp[0]);
483 for(
MInt b = 0;
b < noBodiesInSet;
b++) {
484 body = setToBodiesTable[
b];
485 bcId = bodyBndryCndIds[body];
486 std::vector<MInt> nodeList;
487 getLineIntersectionMBElements2(target, spaceDirectionId, nodeList, bcId);
488 noNodesX = nodeList.size();
489 noNodesX_set += noNodesX;
491 if(noNodesX > maxNoNodesDebug)
492 mTerm(1, AT_,
" too many intersecting nodes to debug... please check or increase maxNoNodesDebug! ");
493 for(
MInt n = 0; n < noNodesX; n++) {
494 nodesXBackup[count] = nodeList[n];
500 for(
MInt j = 0; j < nDim; j++) {
501 target[j] = coordinates[j];
502 target[j + nDim] = coordinates[j];
504 spaceDirectionId[0] = 2;
505 spaceDirectionId[1] = 0;
506 spaceDirectionId[2] = 1;
508 target[1] = tmp[1] - (target[1] - tmp[1]);
510 for(
MInt b = 0;
b < noBodiesInSet;
b++) {
511 body = setToBodiesTable[
b];
512 bcId = bodyBndryCndIds[body];
513 std::vector<MInt> nodeList;
514 getLineIntersectionMBElements2(target, spaceDirectionId, nodeList, bcId);
515 noNodesY = nodeList.size();
516 noNodesY_set += noNodesY;
518 if(noNodesY > maxNoNodesDebug)
519 mTerm(1, AT_,
" too many intersecting nodes to debug... please check or increase maxNoNodesDebug! ");
520 for(
MInt n = 0; n < noNodesY; n++) {
521 nodesYBackup[count] = nodeList[n];
528 IF_CONSTEXPR(nDim == 3) {
529 for(
MInt j = 0; j < nDim; j++) {
530 target[j] = coordinates[j];
531 target[j + nDim] = coordinates[j];
533 spaceDirectionId[0] = 0;
534 spaceDirectionId[1] = 1;
535 spaceDirectionId[2] = 2;
538 target[2] = tmp[2] - (target[2] - tmp[2]);
541 for(
MInt b = 0;
b < noBodiesInSet;
b++) {
542 body = setToBodiesTable[
b];
543 bcId = bodyBndryCndIds[body];
544 std::vector<MInt> nodeList;
545 getLineIntersectionMBElements2(target, spaceDirectionId, nodeList, bcId);
546 noNodesZ = nodeList.size();
547 noNodesZ_set += noNodesZ;
549 if(noNodesZ > maxNoNodesDebug)
550 mTerm(1, AT_,
" too many intersecting nodes to debug... please check or increase maxNoNodesDebug! ");
551 for(
MInt n = 0; n < noNodesZ; n++) {
552 nodesZBackup[count] = nodeList[n];
558 if(noNodesX_set % 2 == noNodesY_set % 2 && noNodesX_set % 2 == noNodesZ_set % 2) {
559 noNodes = noNodesX_set;
561 cerr <<
" Different results for ray intersection, continue with most probable result. Please check your "
564 cerr <<
" nodesX: " << noNodesX <<
" " << noNodesX_set <<
" nodesY: " << noNodesY <<
" " << noNodesY_set
565 <<
" nodesZ: " << noNodesZ <<
" " << noNodesZ_set << endl;
566 cerr <<
" write stl of all intersecting nodes, point is " << coordinates[0] <<
" " << coordinates[1];
567 IF_CONSTEXPR(nDim == 3) cerr <<
" " << coordinates[2];
569 cerr <<
" bounding box is " << tmp[0] <<
" " << tmp[1] <<
" " << tmp[2] <<
" " << tmp[3] <<
" " << tmp[4] <<
" "
571 for(
MInt j = 0; j < nDim; j++) {
572 target[j] = coordinates[j];
573 target[j + nDim] = coordinates[j];
577 stringstream filename;
578 filename <<
"IntersectingNodes_D" << domainId() <<
".stl";
579 ofl.open((filename.str()).c_str());
584 ofl <<
"solid intersecting triangles X " << domainId() << endl;
586 for(
MInt i = 0; i < noNodesX_set; i++) {
587 ofl <<
" facet normal";
588 for(
MInt j = 0; j < 3; j++)
589 ofl <<
" " << mbelements[nodesXBackup[i]].m_normal[j];
590 ofl << endl <<
" outer loop" << endl;
592 for(
MInt k = 0; k < 3; k++) {
594 for(
MInt l = 0; l < 3; l++) {
595 ofl <<
" " << mbelements[nodesXBackup[i]].m_vertices[k][l];
600 ofl <<
" endloop" << endl <<
" endfacet" << endl;
602 ofl <<
"endsolid intersecting triangles X " << domainId() << endl;
605 ofl <<
"solid intersecting triangles Y " << domainId() << endl;
607 for(
MInt i = 0; i < noNodesY_set; i++) {
608 ofl <<
" facet normal";
609 for(
MInt j = 0; j < 3; j++)
610 ofl <<
" " << mbelements[nodesYBackup[i]].m_normal[j];
611 ofl << endl <<
" outer loop" << endl;
613 for(
MInt k = 0; k < 3; k++) {
615 for(
MInt l = 0; l < 3; l++) {
616 ofl <<
" " << mbelements[nodesYBackup[i]].m_vertices[k][l];
621 ofl <<
" endloop" << endl <<
" endfacet" << endl;
623 ofl <<
"endsolid intersecting triangles Y " << domainId() << endl;
626 ofl <<
"solid intersecting triangles Z " << domainId() << endl;
628 for(
MInt i = 0; i < noNodesZ_set; i++) {
629 ofl <<
" facet normal";
630 for(
MInt j = 0; j < 3; j++)
631 ofl <<
" " << mbelements[nodesZBackup[i]].m_normal[j];
632 ofl << endl <<
" outer loop" << endl;
634 for(
MInt k = 0; k < 3; k++) {
636 for(
MInt l = 0; l < 3; l++) {
637 ofl <<
" " << mbelements[nodesZBackup[i]].m_vertices[k][l];
642 ofl <<
" endloop" << endl <<
" endfacet" << endl;
644 ofl <<
"endsolid intersecting triangles Z " << domainId() << endl;
649 if(noNodesX % 2 == noNodesY % 2)
651 else if(noNodesX % 2 == noNodesZ % 2)
653 else if(noNodesY % 2 == noNodesZ % 2)
660 if(noNodesX_set % 2 == noNodesY_set % 2) {
661 noNodes = noNodesX_set;
663 cerr <<
" Different results for ray intersection, continue with most probable result. Please check your "
697 vector<vector<MInt>>* resultnodes) {
700 std::vector<MInt> nodeList;
701 const MFloat* bb = boundingBox();
704 std::array<MFloat, nDim * 2> target;
705 for(
MInt j = 0; j < nDim; j++) {
706 target[j] = coordinates[j];
707 target[j + nDim] = coordinates[j];
711 for(
MInt dim = 0; dim < nDim; dim++) {
713 std::array<MFloat, nDim * 2> raybb;
714 for(
MInt j = 0; j < 2 * nDim; j++)
715 raybb[j] = target[j];
716 raybb[dim] = bb[dim] - (target[dim] - bb[dim]);
719 getLineIntersectionElements(raybb.data(), nodeList);
723 for(
MInt i = 0; i < (signed)nodeList.size(); i++)
724 v.push_back(nodeList[i]);
726 resultnodes->push_back(v);
734 std::vector<MInt> nodeList;
735 MFloat tmp_line[2 * nDim];
736 std::copy_n(line, 2 * nDim, tmp_line);
738 getLineIntersectionElements(tmp_line, nodeList);
741 for(
MInt i = 0; i < (signed)nodeList.size(); i++) {
742 const MInt bndCndId = elements[nodeList[i]].m_bndCndId;
743 bcIds.insert(bndCndId);
749 MFloat target[2 * nDim] = {0.0};
750 std::vector<MInt> nodeList;
752 for(
MInt dim = 0; dim < nDim; dim++) {
753 target[dim] = coordinates[dim] - cellHalfLength;
754 target[dim + nDim] = coordinates[dim] + cellHalfLength;
757 if(gridCutTest ==
"SAT") {
758 this->getIntersectionElements(target, nodeList, cellHalfLength, coordinates);
760 this->getIntersectionElements(target, nodeList);
763 return nodeList.size() > 0;
MBool isOnGeometry(const MFloat, const MFloat *, MString)
void getBoundingBox(MFloat *const bBox) const
Returns the bounding box for the geometry.
MFloat calcCircumference(MFloat **bndVs, MInt num)
Returns the circumference of a segment.
MBool pointIsInsideMBElements2(const MFloat *const coordinates, MInt *, MInt *, MInt)
MBool pointIsInsideMBElements(const MFloat *const coordinates, MInt *, MInt *, MInt)
void getLineIntersectingElementsBcIds(const MFloat *const line, std::set< MInt > &bcIds)
Return the set of boundary condition ids of the elements cut by the given line.
virtual void writeSegmentsToDX()
MBool pointIsInside2(const MFloat *const coordinates, MInt *numcutsperdir=nullptr)
Determines if a point is in or outside the geometry.
void getBoundingBoxMB(MFloat *const bBox) const
Geometry(const MInt solverId_, const MPI_Comm comm)
void determineRayIntersectedElements(const MFloat *const coordinates, std::vector< std::vector< MInt > > *resultnodes)
returns the geometry elements that have a cut with rays originating in the provided coordinates
MBool vectorsEqual(MFloat *a, MFloat *b)
Compares two vectors entry by entry.
MBool pointIsInside(const MFloat *const coordinates)
Determines if a point is inside of the geometry.
This class is a ScratchSpace.
void mTerm(const MInt errorCode, const MString &location, const MString &message)
MBool approx(const T &, const U &, const T)
std::basic_string< char > MString