42 for(
MInt i = 0; i < noBodyBndIds; i++) {
51 Context::getSolverProperty<MInt>(
"GFieldInitFromSTLBndCndIds",
solverId(), AT_, i - noBodyBndIds);
70 testcaseDir = Context::getSolverProperty<MString>(
"testcaseDir",
solverId(), AT_, &testcaseDir);
72 inputDir = Context::getSolverProperty<MString>(
"inputDir",
solverId(), AT_, &inputDir);
75 testcaseDir + inputDir + Context::getSolverProperty<MString>(
"geometryInputFileName",
solverId(), AT_);
77 if(tmpFileName.find(
".toml") == MString::npos) {
101 m_log <<
"reading the auxiliary stl " << filename << endl;
150 if(
m_bodyIt->second->name !=
"default") {
151 for(
MInt i = 0; i <
m_bodyIt->second->noSegments; i++) {
155 fileName +=
"." + to_string(segmentId);
173 if(
m_bodyIt->second->name !=
"default") {
174 for(
MInt i = 0; i <
m_bodyIt->second->noSegments; i++) {
175 m_log <<
" Reading Ascii coordinates from file " << endl;
179 fileName +=
"." + to_string(segmentId);
182 allBCs.push_back(bndCndId);
199 MInt mbelem_counter = 0, elem_counter = 0;
200 MBool mbElem =
false;
202 for(
MInt allelem_counter = 0; allelem_counter < m_allelements->size(); allelem_counter++) {
213 for(
MInt j = 0; j < 2; j++) {
214 mbelements[mbelem_counter].m_normal[j] = allelements[allelem_counter].m_normal[j];
215 for(
MInt i = 0; i < 2; i++) {
216 mbelements[mbelem_counter].m_vertices[j][i] = allelements[allelem_counter].m_vertices[j][i];
220 mbelements[mbelem_counter].m_bndCndId = allelements[allelem_counter].m_bndCndId;
221 mbelements[mbelem_counter].m_segmentId = allelements[allelem_counter].m_segmentId;
227 for(
MInt j = 0; j < 2; j++) {
228 elements[elem_counter].m_normal[j] = allelements[allelem_counter].m_normal[j];
229 for(
MInt i = 0; i < 2; i++) {
230 elements[elem_counter].m_vertices[j][i] = allelements[allelem_counter].m_vertices[j][i];
233 elements[elem_counter].boundingBox();
234 elements[elem_counter].m_bndCndId = allelements[allelem_counter].m_bndCndId;
235 elements[elem_counter].m_segmentId = allelements[allelem_counter].m_segmentId;
242 for(
MInt i = 0; i < 2; i++) {
243 mbelements[mbelem_counter].m_normal[i] = allelements[allelem_counter].m_normal[i];
245 for(
MInt j = 0; j < 2; j++) {
246 for(
MInt i = 0; i < 2; i++) {
247 mbelements[mbelem_counter].m_vertices[j][i] = allelements[allelem_counter].m_vertices[j][i];
251 mbelements[mbelem_counter].m_bndCndId = allelements[allelem_counter].m_bndCndId;
252 mbelements[mbelem_counter].m_segmentId = allelements[allelem_counter].m_segmentId;
257 for(
MInt i = 0; i < 2; i++) {
258 elements[elem_counter].m_normal[i] = allelements[allelem_counter].m_normal[i];
260 for(
MInt j = 0; j < 2; j++) {
261 for(
MInt i = 0; i < 2; i++) {
262 elements[elem_counter].m_vertices[j][i] = allelements[allelem_counter].m_vertices[j][i];
265 elements[elem_counter].boundingBox();
266 elements[elem_counter].m_bndCndId = allelements[allelem_counter].m_bndCndId;
267 elements[elem_counter].m_segmentId = allelements[allelem_counter].m_segmentId;
273 delete m_allelements;
315 MInt noReallyIntersectingNodes = 0;
316 m_adt->retrieveNodes(targetRegion, nodeList);
317 const MInt noNodes = nodeList.size();
319 MFloat cos_alpha, sin_alpha, length_diff;
323 diff_vec[i] = numeric_limits<MFloat>::max();
333 for(
MInt n = 0; n < noNodes; n++) {
345 if(
elements[nodeList[n]].m_vertices[0][i] >= targetRegion[i]
346 &&
elements[nodeList[n]].m_vertices[0][i] <= targetRegion[i +
nDim]) {
352 if(
elements[nodeList[n]].m_vertices[1][i] >= targetRegion[i]
353 &&
elements[nodeList[n]].m_vertices[1][i] <= targetRegion[i +
nDim]) {
359 if(
elements[nodeList[n]].m_vertices[0][i] <= targetRegion[i]
360 &&
elements[nodeList[n]].m_vertices[1][i] >= targetRegion[i +
nDim]) {
364 if(
elements[nodeList[n]].m_vertices[1][i] <= targetRegion[i]
365 &&
elements[nodeList[n]].m_vertices[0][i] >= targetRegion[i +
nDim]) {
369 if(!overlap[i])
break;
372 if(!(overlap[0] && overlap[1]))
continue;
375 for(parallel_dim = 0; parallel_dim <
nDim; parallel_dim++) {
378 elements[nodeList[n]].m_vertices[1][parallel_dim], MFloatEps));
383 nodeList[noReallyIntersectingNodes] = nodeList[n];
384 noReallyIntersectingNodes++;
389 diff_vec[i] =
elements[nodeList[n]].m_vertices[1][i] -
elements[nodeList[n]].m_vertices[0][i];
390 length_diff += diff_vec[i] * diff_vec[i];
392 length_diff = sqrt(length_diff);
394 cos_alpha = fabs(diff_vec[0]) / length_diff;
395 sin_alpha = fabs(diff_vec[1]) / length_diff;
397 if((diff_vec[0] * diff_vec[1]) < 0)
400 sin_alpha *
elements[nodeList[n]].m_vertices[0][0] + cos_alpha *
elements[nodeList[n]].m_vertices[0][1];
401 rot_corners[0] = sin_alpha * (targetRegion[2]) + cos_alpha * (targetRegion[3]);
402 rot_corners[1] = sin_alpha * (targetRegion[0]) + cos_alpha * (targetRegion[1]);
405 rot_point = -1 * sin_alpha *
elements[nodeList[n]].m_vertices[0][0]
406 + cos_alpha *
elements[nodeList[n]].m_vertices[0][1];
407 rot_corners[0] = -1 * sin_alpha * (targetRegion[0]) + cos_alpha * (targetRegion[3]);
408 rot_corners[1] = -1 * sin_alpha * (targetRegion[2]) + cos_alpha * (targetRegion[1]);
412 if(rot_corners[0] >= rot_point && rot_corners[1] <= rot_point) {
413 nodeList[noReallyIntersectingNodes] = nodeList[n];
414 noReallyIntersectingNodes++;
418 nodeList.resize(noReallyIntersectingNodes);
420 return noReallyIntersectingNodes;
435 MInt noReallyIntersectingNodes = 0;
439 bitset<4> faceCodes[4];
444 MBool piercePointInside;
445 MBool triviallyAccepted;
452 MInt pointAInPlane[4][2] = {{0, 1}, {2, 1}, {0, 1}, {0, 3}};
454 MInt pointBInPlane[4][2] = {{0, 3}, {2, 3}, {2, 1}, {2, 3}};
456 MFloat a[2] = {numeric_limits<MFloat>::max(),
457 numeric_limits<MFloat>::max()};
458 MFloat b[2] = {numeric_limits<MFloat>::max(),
459 numeric_limits<MFloat>::max()};
460 MFloat c[2] = {numeric_limits<MFloat>::max(),
461 numeric_limits<MFloat>::max()};
462 MFloat d[2] = {numeric_limits<MFloat>::max(),
463 numeric_limits<MFloat>::max()};
465 MFloat pP[2] = {numeric_limits<MFloat>::max(),
466 numeric_limits<MFloat>::max()};
467 faceCodes[0] =
IPOW2(0);
468 faceCodes[1] =
IPOW2(1);
469 faceCodes[2] =
IPOW2(2);
470 faceCodes[3] =
IPOW2(3);
473 m_adt->retrieveNodes(targetRegion, nodeList);
474 const MInt noNodes = nodeList.size();
476 noReallyIntersectingNodes = 0;
478 for(
MInt n = 0; n < noNodes; n++) {
487 if(
elements[nodeList[n]].m_vertices[p][j] < targetRegion[j]) {
488 points[p] |= faceCodes[2 * j];
490 if(
elements[nodeList[n]].m_vertices[p][j] > targetRegion[j +
nDim]) {
491 points[p] |= faceCodes[2 * j + 1];
499 if((points[0] & points[1]) != 0) {
504 triviallyAccepted =
false;
507 triviallyAccepted =
true;
512 if(triviallyAccepted) {
528 result = (points[0] | points[1]);
529 piercePointInside =
false;
530 for(
MInt j = 0; j < 2 *
nDim; j++) {
534 a[k] = targetRegion[pointAInPlane[j][k]];
535 b[k] = targetRegion[pointBInPlane[j][k]];
536 c[k] =
elements[nodeList[n]].m_vertices[0][k];
537 d[k] =
elements[nodeList[n]].m_vertices[1][k];
539 gamma = (
b[0] -
a[0]) * (c[1] - d[1]) - (c[0] - d[0]) * (
b[1] -
a[1]);
541 s1 = ((c[0] - d[0]) * (
a[1] - c[1]) - (c[1] - d[1]) * (
a[0] - c[0])) / gamma;
544 s2 = ((
b[0] -
a[0]) * (c[1] -
a[1]) - (c[0] -
a[0]) * (
b[1] -
a[1])) / gamma;
547 if(s1 * s1 < s2 * s2)
548 pP[k] = c[k] + s2 * (d[k] - c[k]);
550 pP[k] =
a[k] + s1 * (
b[k] -
a[k]);
555 if(pP[k] < targetRegion[k]) {
556 pCode |= faceCodes[2 * k];
558 if(pP[k] > targetRegion[k +
nDim]) {
559 pCode |= faceCodes[2 * k + 1];
567 result = faceCodes[j];
569 result = (result & pCode);
571 piercePointInside =
true;
577 if(!piercePointInside) {
588 nodeList[noReallyIntersectingNodes] = nodeList[n];
589 noReallyIntersectingNodes++;
595 nodeList.resize(noReallyIntersectingNodes);
597 return noReallyIntersectingNodes;
624 a[k] = edgePoint1[k];
625 b[k] = edgePoint2[k];
626 c[k] = trianglePoint1[k];
627 d[k] = trianglePoint2[k];
630 gamma = (
b[0] -
a[0]) * (c[1] - d[1]) - (c[0] - d[0]) * (
b[1] -
a[1]);
634 if(gamma < 0.00000000001) {
639 s1 = ((c[0] - d[0]) * (
a[1] - c[1]) - (c[1] - d[1]) * (
a[0] - c[0])) / gamma;
641 s2 = ((
b[0] -
a[0]) * (c[1] -
a[1]) - (c[0] -
a[0]) * (
b[1] -
a[1])) / gamma;
643 if(s2 < 0 || s2 > 1.0 || s1 < 0 || s1 > 1.0) {
657 MInt noReallyIntersectingNodes = 0;
659 m_adt->retrieveNodes(targetRegion, nodeList);
660 const MInt noNodes = nodeList.size();
664 e1[i] = targetRegion[i];
665 e2[i] = targetRegion[i +
nDim];
668 for(
MInt n = 0; n < noNodes; n++) {
670 nodeList[noReallyIntersectingNodes] = nodeList[n];
671 noReallyIntersectingNodes++;
674 nodeList.resize(noReallyIntersectingNodes);
676 return noReallyIntersectingNodes;
684 std::vector<MInt>& nodeList) {
691 MInt noReallyIntersectingNodes = 0;
695 bitset<4> faceCodes[4];
700 MBool piercePointInside;
701 MBool triviallyAccepted;
708 MInt pointAInPlane[4][2] = {{0, 1}, {2, 1}, {0, 1}, {0, 3}};
710 MInt pointBInPlane[4][2] = {{0, 3}, {2, 3}, {2, 1}, {2, 3}};
712 MFloat a[2] = {numeric_limits<MFloat>::max(),
713 numeric_limits<MFloat>::max()};
714 MFloat b[2] = {numeric_limits<MFloat>::max(),
715 numeric_limits<MFloat>::max()};
716 MFloat c[2] = {numeric_limits<MFloat>::max(),
717 numeric_limits<MFloat>::max()};
718 MFloat d[2] = {numeric_limits<MFloat>::max(),
719 numeric_limits<MFloat>::max()};
721 MFloat pP[2] = {numeric_limits<MFloat>::max(),
722 numeric_limits<MFloat>::max()};
723 faceCodes[0] =
IPOW2(0);
724 faceCodes[1] =
IPOW2(1);
725 faceCodes[2] =
IPOW2(2);
726 faceCodes[3] =
IPOW2(3);
729 m_adt->retrieveNodesMBElements(targetRegion, nodeList);
730 const MInt noNodes = nodeList.size();
732 noReallyIntersectingNodes = 0;
734 for(
MInt n = 0; n < noNodes; n++) {
743 if(
mbelements[nodeList[n]].m_vertices[p][j] < targetRegion[j]) {
744 points[p] |= faceCodes[2 * j];
746 if(
mbelements[nodeList[n]].m_vertices[p][j] > targetRegion[j +
nDim]) {
747 points[p] |= faceCodes[2 * j + 1];
755 if((points[0] & points[1]) != 0) {
760 triviallyAccepted =
false;
763 triviallyAccepted =
true;
768 if(triviallyAccepted) {
784 result = (points[0] | points[1]);
785 piercePointInside =
false;
786 for(
MInt j = 0; j < 2 *
nDim; j++) {
790 a[k] = targetRegion[pointAInPlane[j][k]];
791 b[k] = targetRegion[pointBInPlane[j][k]];
792 c[k] =
mbelements[nodeList[n]].m_vertices[0][k];
793 d[k] =
mbelements[nodeList[n]].m_vertices[1][k];
795 gamma = (
b[0] -
a[0]) * (c[1] - d[1]) - (c[0] - d[0]) * (
b[1] -
a[1]);
797 s1 = ((c[0] - d[0]) * (
a[1] - c[1]) - (c[1] - d[1]) * (
a[0] - c[0])) / gamma;
800 s2 = ((
b[0] -
a[0]) * (c[1] -
a[1]) - (c[0] -
a[0]) * (
b[1] -
a[1])) / gamma;
803 if(s1 * s1 < s2 * s2)
804 pP[k] = c[k] + s2 * (d[k] - c[k]);
806 pP[k] =
a[k] + s1 * (
b[k] -
a[k]);
811 if(pP[k] < targetRegion[k]) {
812 pCode |= faceCodes[2 * k];
814 if(pP[k] > targetRegion[k +
nDim]) {
815 pCode |= faceCodes[2 * k + 1];
823 result = faceCodes[j];
825 result = (result & pCode);
827 piercePointInside =
true;
833 if(!piercePointInside) {
844 nodeList[noReallyIntersectingNodes] = nodeList[n];
845 noReallyIntersectingNodes++;
851 nodeList.resize(noReallyIntersectingNodes);
853 return noReallyIntersectingNodes;
859 MInt noReallyIntersectingNodes = 0;
861 m_adt->retrieveNodesMBElements(targetRegion, nodeList);
862 const MInt noNodes = nodeList.size();
866 e1[i] = targetRegion[i];
867 e2[i] = targetRegion[i +
nDim];
870 for(
MInt n = 0; n < noNodes; n++) {
873 nodeList[noReallyIntersectingNodes] = nodeList[n];
874 noReallyIntersectingNodes++;
877 nodeList.resize(noReallyIntersectingNodes);
879 return noReallyIntersectingNodes;
886 MInt noReallyIntersectingNodes = 0;
889 MFloat target[4] = {0, 0, 0, 0};
890 MFloat enlargeFactor = 1.05;
892 target[i] = P[i] - radius * enlargeFactor;
893 target[i +
nDim] = P[i] + radius * enlargeFactor;
897 m_adt->retrieveNodesMBElements(target, nodeList);
898 const MInt noNodes = nodeList.size();
900 MFloat A[2], B[2], AB[2], Q1[2];
903 for(
MInt n = 0; n < noNodes; n++) {
906 A[i] =
mbelements[nodeList[n]].m_vertices[0][i];
907 B[i] =
mbelements[nodeList[n]].m_vertices[1][i];
916 MFloat rr = radius * radius;
927 MBool sep2 = (aa > rr) && (ab > aa);
928 MBool sep3 = (bb > rr) && (ab > bb);
932 Q1[i] = A[i] * e1 - d1 * AB[i];
933 qq1 += Q1[i] * Q1[i];
935 MBool sep5 = (qq1 > rr * e1 * e1);
937 MBool separated = sep2 || sep3 || sep5;
940 nodeList[noReallyIntersectingNodes] = nodeList[n];
941 noReallyIntersectingNodes++;
944 nodeList.resize(noReallyIntersectingNodes);
946 return noReallyIntersectingNodes;
1000 m_adt->buildTreeMB();
1017 m_log <<
" Counting segment file: " << fileName << endl;
1019 ifstream ifl(fileName);
1021 stringstream errorMessage;
1022 errorMessage <<
" ERROR in segment::readSegment (counting loop), couldn't find file : " << fileName <<
"!";
1023 mTerm(1, AT_, errorMessage.str());
1026 ifl >> (*noElements);
1029 m_log <<
" number of vertices = " << *noElements << endl;
1044 m_log <<
" Reading segment file: " << fileName << endl;
1045 m_log <<
" BC : " << bndCndId << endl;
1048 ifstream ifl(fileName);
1050 stringstream errorMessage;
1051 errorMessage <<
" ERROR in segment::readSegment (reading loop), couldn't find file : " << fileName <<
"!";
1052 mTerm(1, AT_, errorMessage.str());
1060 elemCollector->append();
1061 for(
MInt j = 0; j < 2; j++) {
1062 ifl >> allelements[*offset].
m_vertices[0][j];
1063 allelements[*offset].
m_normal[j] = F0;
1065 MInt fileElementCounter = 0;
1068 for(
MInt j = 0; j < 2; j++) {
1069 ifl >> allelements[*offset].
m_vertices[1][j];
1070 allelements[*offset].
m_normal[j] = F0;
1086 fileElementCounter++;
1089 if(fileElementCounter < tmp - 1) {
1090 elemCollector->append();
1091 for(
MInt j = 0; j < 2; j++) {
1093 allelements[*offset].
m_normal[j] = F0;
1123 m_log <<
" Bounding box for segment :" << endl;
1139 m_log <<
" Bounding box for Moving Boundary segment:" << endl;
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
static MInt propertyLength(const MString &name, MInt solverId=m_noSolvers)
Returns the number of elements of a property.
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
void readSegmentLinesASCII(MString fileName, Collector< element< 2 > > *elemCollector, MInt bndCndId, MInt segmentId, MInt *offset)
reads the lines in an ASCII file
virtual MBool edgeTriangleIntersection(MFloat *trianglePoint1, MFloat *trianglePoint2, MFloat *trianglePoint3, MFloat *edgePoint1, MFloat *edgePoint2)
Determine intersection between an edge and a triangle (in 2D between 2 edges)
MBool m_GFieldInitFromSTL
Geometry2D(const MInt solverId_, const MPI_Comm comm)
virtual MInt getLineIntersectionElementsOld1(MFloat *targetRegion, std::vector< MInt > &nodeList)
virtual MInt getIntersectionMBElements(MFloat *targetRegion, std::vector< MInt > &nodeList)
virtual void ReplaceMBElementVertex(MInt e, MInt v, MFloat *np)
void calculateBoundingBox()
Calculates the global bounding box of the geometry.
static constexpr const MInt nDim
MInt m_noLevelSetIntfBndIds
virtual void MoveAllMBElementVertex(MFloat *dx)
virtual MInt getSphereIntersectionMBElements(MFloat *P, MFloat radius, std::vector< MInt > &nodeList)
virtual MInt getLineIntersectionMBElements(MFloat *targetRegion, std::vector< MInt > &nodeList)
virtual void UpdateMBBoundingBox()
virtual void readSegments()
virtual MInt getLineIntersectionElementsOld2(MFloat *targetRegion, MInt *spaceDirection, std::vector< MInt > &nodeList)
virtual MInt getLineIntersectionElements(MFloat *targetRegion, std::vector< MInt > &nodeList)
Returns the ids of all elements, cut by a orthogonal line (or rectangular region)
virtual void MoveMBElementVertex(MInt e, MInt v, MFloat *dx)
void countSegmentLinesASCII(const MString &fileName, MInt *noElements)
counts the number of lines in an ASCII file, should be the in the first line
MInt * m_levelSetIntfBndIds
virtual MInt getIntersectionElements(MFloat *targetRegion, std::vector< MInt > &nodeList)
Determines all elements that are inside or intersect the target region.
GeometryProperty * getProperty(const MString &name, MInt segment)
void readPropertyFile(FileType, const MChar *fileName)
std::array< MFloat, 2 *nDim > m_minMax
Collector< element< nDim > > * m_elements
element< nDim > * elements
element< nDim > * mbelements
GeometryContext & geometryContext()
Collector< element< nDim > > * m_mbelements
std::array< MFloat, 2 *nDim > m_mbminMax
GeometryAdt< nDim > * m_adt
void mTerm(const MInt errorCode, const MString &location, const MString &message)
MBool approx(const T &, const U &, const T)
constexpr MLong IPOW2(MInt x)
std::basic_string< char > MString