85 distribution(distribution),
90 enableFixRefinementIntoTheWall(
false),
100 innerRegionFromFinerGrid(
false),
102 qComputationStage(qComputationStageType::ComputeQs)
104 initalNumberOfNodesAndSize();
115void GridImp::initalNumberOfNodesAndSize()
117 const real length = endX - startX;
119 const real height = endZ - startZ;
121 nx = std::lround((length + delta) / delta);
122 ny = std::lround((
width + delta) / delta);
123 nz = std::lround((height + delta) / delta);
125 this->size = nx * ny * nz;
126 this->sparseSize = size;
140 this->sparseIndices =
new int[this->size];
142 this->qIndices =
new uint[this->size];
143 for (
uint i = 0;
i < this->size;
i++)
148#pragma omp parallel for
149 for (
int index = 0; index < (
int)this->size; index++)
152 if( this->innerRegionFromFinerGrid ){
164#pragma omp parallel for
165 for (
int index = 0; index < (
int)this->size; index++)
168 if( enableFixRefinementIntoTheWall )
171#pragma omp parallel for
179#pragma omp parallel for
187#pragma omp parallel for
196#pragma omp parallel for
197 for (
int index = 0; index < (
int)this->size; index++)
200 VF_LOG_INFO(
"Grid created: from ({}, {}, {}) to ({}, {}, {})", this->startX, this->startY, this->startZ, this->endX, this->endY, this->endZ);
201 VF_LOG_INFO(
"nodes: {} x {} x {} = {}", this->nx, this->ny, this->nz, this->size);
206 this->xOddStart = xOddStart;
207 this->yOddStart = yOddStart;
208 this->zOddStart = zOddStart;
221 if( this->sparseIndices !=
nullptr ) {
delete[] this->sparseIndices; this->sparseIndices =
nullptr; }
222 if( this->qIndices !=
nullptr ) {
delete[] this->qIndices; this->qIndices =
nullptr; }
223 if( this->qValues !=
nullptr ) {
delete[] this->qValues; this->qValues =
nullptr; }
224 if( this->qPatches !=
nullptr ) {
delete[] this->qPatches; this->qPatches =
nullptr; }
231#pragma omp parallel for
232 for (
int index = 0; index < (
int)this->size; index++)
238 this->sparseIndices[index] = index;
240 if( this->level != 0 ){
241 const Cell cell = getOddCellFromIndex(index);
261#pragma omp parallel for
262 for (
int index = 0; index < (
int)this->size; index++)
264 this->sparseIndices[index] = index;
280 return object->isCellInObject(
cell);
295Cell GridImp::getOddCellFromIndex(
uint index)
const
321 for(
uint index = 0; index < this->size; index++ ){
328 childIndex[0] =
fineGrid->transCoordToIndex(
x + 0.25 * this->delta,
y + 0.25 * this->delta,
z + 0.25 * this->delta );
329 childIndex[1] =
fineGrid->transCoordToIndex(
x + 0.25 * this->delta,
y + 0.25 * this->delta,
z - 0.25 * this->delta );
330 childIndex[2] =
fineGrid->transCoordToIndex(
x + 0.25 * this->delta,
y - 0.25 * this->delta,
z + 0.25 * this->delta );
331 childIndex[3] =
fineGrid->transCoordToIndex(
x + 0.25 * this->delta,
y - 0.25 * this->delta,
z - 0.25 * this->delta );
332 childIndex[4] =
fineGrid->transCoordToIndex(
x - 0.25 * this->delta,
y + 0.25 * this->delta,
z + 0.25 * this->delta );
333 childIndex[5] =
fineGrid->transCoordToIndex(
x - 0.25 * this->delta,
y + 0.25 * this->delta,
z - 0.25 * this->delta );
334 childIndex[6] =
fineGrid->transCoordToIndex(
x - 0.25 * this->delta,
y - 0.25 * this->delta,
z + 0.25 * this->delta );
335 childIndex[7] =
fineGrid->transCoordToIndex(
x - 0.25 * this->delta,
y - 0.25 * this->delta,
z - 0.25 * this->delta );
349#pragma omp parallel for
350 for (
int index = 0; index < (
int)this->size; index++)
353#pragma omp parallel for
354 for (
int index = 0; index < (
int)this->size; index++)
361 if( this->
field.
is( index, INVALID_OUT_OF_GRID ) ){
371 if( this->
field.
is( index, OVERLAP_TMP ) ){
385 if( !this->xOddStart && ( dir == 1 || dir == -1 ) && (
xIndex % 2 == 1 ||
xIndex == 0 ) )
return;
386 if( !this->yOddStart && ( dir == 2 || dir == -2 ) && (
yIndex % 2 == 1 ||
yIndex == 0 ) )
return;
387 if( !this->zOddStart && ( dir == 3 || dir == -3 ) && (
zIndex % 2 == 1 ||
zIndex == 0 ) )
return;
390 if( this->xOddStart && ( dir == 1 || dir == -1 ) && (
xIndex % 2 == 0 &&
xIndex != 0 ) )
return;
391 if( this->yOddStart && ( dir == 2 || dir == -2 ) && (
yIndex % 2 == 0 &&
yIndex != 0 ) )
return;
392 if( this->zOddStart && ( dir == 3 || dir == -3 ) && (
zIndex % 2 == 0 &&
zIndex != 0 ) )
return;
396 real dx{ 0.0 },
dy{ 0.0 },
dz{ 0.0 };
398 if ( dir == 1 ){ dx = this->delta;
dy = 0.0;
dz = 0.0; }
399 else if ( dir == -1 ){ dx = - this->delta;
dy = 0.0;
dz = 0.0; }
400 else if ( dir == 2 ){ dx = 0.0;
dy = this->delta;
dz = 0.0; }
401 else if ( dir == -2 ){ dx = 0.0;
dy = - this->delta;
dz = 0.0; }
402 else if ( dir == 3 ){ dx = 0.0;
dy = 0.0;
dz = this->delta; }
403 else if ( dir == -3 ){ dx = 0.0;
dy = 0.0;
dz = - this->delta; }
409 char type2 = ( type == FLUID ) ? ( INVALID_OUT_OF_GRID ) : ( FLUID );
437 if(isValidEndOfGridStopper(index))
440 if (isValidSolidStopper(index))
446 if (isValidEndOfGridStopper(index)){
447 if( this->level != 0 )
453 if (isValidEndOfGridBoundaryStopper(index))
459 if (isValidSolidStopper(index))
465 if (shouldBeBoundarySolidNode(index))
468 this->qIndices[index] = this->numberOfSolidBoundaryNodes++;
475 Cell cell = getOddCellFromIndex(index);
476 if (isOutSideOfGrid(
cell))
478 if (contains(
cell, FLUID))
479 setNodeTo(
cell, FLUID);
482bool GridImp::isOutSideOfGrid(
Cell &
cell)
const
493bool GridImp::contains(Cell &
cell,
char type)
const
534void GridImp::setNodeTo(
Cell &
cell,
char type)
544void GridImp::setNodeTo(
uint index,
char type)
555 throw std::runtime_error(
"GridImp::isNode() -> index == INVALID_INDEX not supported.");
558bool GridImp::isValidEndOfGridStopper(
uint index)
const
561 if (!this->
field.
is(index, INVALID_OUT_OF_GRID))
567bool GridImp::isValidEndOfGridBoundaryStopper(
uint index)
const
570 if (!this->
field.
is(index, FLUID))
576bool GridImp::isValidSolidStopper(
uint index)
const
579 if (!this->
field.
is(index, INVALID_SOLID))
585bool GridImp::shouldBeBoundarySolidNode(
uint index)
const
587 if (!this->
field.
is(index, FLUID))
617 if (this->
field.
is(neighborIndex, type))
629 const real neighborX =
x + this->delta > endX ? endX :
x + this->delta;
630 const real neighborY =
y + this->delta > endY ? endY :
y + this->delta;
631 const real neighborZ =
z + this->delta > endZ ? endZ :
z + this->delta;
655bool GridImp::nodeInPreviousCellIs(
int index,
char type)
const
660 const real neighborX =
x - this->delta < startX ? startX :
x - this->delta;
661 const real neighborY =
y - this->delta < startY ? startY :
y - this->delta;
662 const real neighborZ =
z - this->delta < startZ ? startZ :
z - this->delta;
686bool GridImp::nodeInCellIs(Cell&
cell,
char type)
const
688 for (
const auto node :
cell)
706 for (
const auto node :
cell)
722 for (
const auto node :
cell)
728 if( this->
getFieldEntry( nodeIndex ) != STOPPER_OUT_OF_GRID &&
729 this->
getFieldEntry( nodeIndex ) != STOPPER_OUT_OF_GRID_BOUNDARY )
743 this->periodicityX = periodicityX;
744 this->periodicityY = periodicityY;
745 this->periodicityZ = periodicityZ;
750 this->periodicityX = periodicity;
755 this->periodicityY = periodicity;
760 this->periodicityZ = periodicity;
765 return this->periodicityX;
770 return this->periodicityY;
775 return this->periodicityZ;
780 if(!this->periodicityY)
781 throw std::runtime_error(
"Domain needs to be periodic in X and Y to shift periodic boundary!");
783 VF_LOG_INFO(
"Shifting periodicity in X direction by {} in Y direction.",
shift);
784 this->periodicShiftOnXinY =
shift;
788 if(!this->periodicityX || !this->periodicityZ)
789 throw std::runtime_error(
"Domain needs to be periodic in X and Z to shift periodic boundary!");
791 VF_LOG_INFO(
"Shifting periodicity in X direction by {} in Z direction.",
shift);
792 this->periodicShiftOnXinZ =
shift;
796 if(!this->periodicityY || !this->periodicityX)
797 throw std::runtime_error(
"Domain needs to be periodic in Y and X to shift periodic boundary!");
799 VF_LOG_INFO(
"Shifting periodicity in Y direction by {} in X direction.",
shift);
800 this->periodicShiftOnYinX =
shift;
804 if(!this->periodicityY || !this->periodicityZ)
805 throw std::runtime_error(
"Domain needs to be periodic in Y and Z to shift periodic boundary!");
807 VF_LOG_INFO(
"Shifting periodicity in Y direction by {} in Z direction.",
shift);
808 this->periodicShiftOnYinZ =
shift;
812 if(!this->periodicityZ || !this->periodicityX)
813 throw std::runtime_error(
"Domain needs to be periodic in Z and X to shift periodic boundary!");
815 VF_LOG_INFO(
"Shifting periodicity in Z direction by {} in X direction.",
shift);
816 this->periodicShiftOnZinX =
shift;
820 if(!this->periodicityZ || !this->periodicityY)
821 throw std::runtime_error(
"Domain needs to be periodic in Z and Y to shift periodic boundary!");
823 VF_LOG_INFO(
"Shifting periodicity in Z direction by {} in Y direction.",
shift);
824 this->periodicShiftOnZinY =
shift;
829 this->enableFixRefinementIntoTheWall = enableFixRefinementIntoTheWall;
847 printf(
"Function: transIndexToCoords. GridImp Index: %d, size: %d. Exit Program!\n", index, size);
849 x = (
real)(index % nx);
850 y = (
real)((index / nx) % ny);
851 z = (
real)(((index / nx) / ny) % nz);
853 x = (
x * delta) + startX;
854 y = (
y * delta) + startY;
855 z = (
z * delta) + startZ;
861 real delta = this->delta;
877 this->triangularMeshDiscretizationStrategy = triangularMeshDiscretizationStrategy;
882 return this->triangularMeshDiscretizationStrategy;
887 this->activeWindingSurface =
surface;
892 return this->activeWindingSurface;
897 this->qSourceSurfaces.clear();
902 return this->numberOfSolidBoundaryNodes;
908 this->numberOfSolidBoundaryNodes = numberOfSolidBoundaryNodes;
913 const int qIndex = dir * this->numberOfSolidBoundaryNodes + this->qIndices[index];
915 return this->qValues[
qIndex];
920 return this->qPatches[ this->qIndices[index] ];
927 if (index >= this->size)
936 return this->qIndices[index];
955 this->qValues[offset] = value;
960 if (!
hasQIndex(index) || !this->qPatches)
963 this->qPatches[this->qIndices[index]] =
patch;
974 const uint offset = dir * this->numberOfSolidBoundaryNodes +
qIndex;
976 this->qValues[offset] = -1.0;
987 if (!this->qValues || this->numberOfSolidBoundaryNodes == 0)
993#pragma omp parallel for
995 if (this->qValues[
idx] <
real(0.0))
1002 if (!this->qIndices || !this->qValues || this->numberOfSolidBoundaryNodes == 0)
1008 for (
uint index = 0; index < this->size; ++index) {
1009 if (!this->
field.
is(index, BC_SOLID))
1023 if (direction[0] == 0 && direction[1] == 0 && direction[2] == 0)
1030 if (this->qValues[offset] >=
static_cast<real>(0.0))
1033 const real nx =
static_cast<real>(
ox) +
static_cast<real>(direction[0]) * this->delta;
1034 const real ny =
static_cast<real>(
oy) +
static_cast<real>(direction[1]) * this->delta;
1035 const real nz =
static_cast<real>(
oz) +
static_cast<real>(direction[2]) * this->delta;
1051 if (!this->qIndices)
1055 for (
uint index = 0; index < this->size; ++index) {
1056 if (this->
field.
is(index, BC_SOLID)) {
1065 const real dx = this->delta;
1067 for (
uint index = 0; index < this->size; ++index) {
1068 if (!this->
field.
is(index, FLUID))
1079 const int cx = direction[0];
1080 const int cy = direction[1];
1081 const int cz = direction[2];
1082 if (cx == 0 && cy == 0 && cz == 0)
1086 ox +
static_cast<real>(cx) * dx,
1087 oy +
static_cast<real>(cy) * dx,
1088 oz +
static_cast<real>(cz) * dx);
1105 this->numberOfSolidBoundaryNodes =
nextIndex;
1110 const bool capacityMismatch = (this->qCapacity != this->numberOfSolidBoundaryNodes);
1113 delete[] this->qValues;
1114 delete[] this->qPatches;
1115 this->qValues =
nullptr;
1116 this->qPatches =
nullptr;
1117 this->qCapacity = 0;
1125#pragma omp parallel for
1127 this->qValues[
idx] = -1.0;
1129 if (this->qPatches) {
1130#pragma omp parallel for
1137 this->innerRegionFromFinerGrid = innerRegionFromFinerGrid;
1142 this->numberOfLayers = numberOfLayers;
1156#pragma omp parallel for
1157 for (
int index = 0; index < (
int)this->
getSize(); index++)
1166 VF_LOG_TRACE(
"... done. new size: {}, delete nodes: {}", newGridSize, this->
getSize() - newGridSize);
1171#pragma omp parallel for
1175#pragma omp parallel for
1184 for (
uint index = 0; index < size; index++)
1188 sparseIndices[index] = -1;
1203 this->fluidNodeIndices.clear();
1204 for (
uint index = 0; index < this->size; index++) {
1215 std::sort(this->fluidNodeIndices.begin(),
this->fluidNodeIndices.end());
1216 const auto iterator = std::set_difference(this->fluidNodeIndices.begin(),
this->fluidNodeIndices.end(),
1217 this->fluidNodeIndicesBorder.begin(),
this->fluidNodeIndicesBorder.end(),
1218 this->fluidNodeIndices.begin());
1219 this->fluidNodeIndices.resize(iterator - this->fluidNodeIndices.begin());
1225 std::transform(
ci.receiveIndices.begin(),
ci.receiveIndices.end(), std::back_inserter(
receiveNodes),
1226 [&](
uint index) { return this->getSparseIndex(index) + 1; });
1229 const auto iter = std::set_difference(this->fluidNodeIndices.begin(),
this->fluidNodeIndices.end(),
receiveNodes.begin(),
1231 this->fluidNodeIndices.resize(
iter - this->fluidNodeIndices.begin());
1236 this->fluidNodeIndicesBorder.clear();
1240 newSize +=
ci.sendIndices.size();
1241 this->fluidNodeIndicesBorder.reserve(
newSize);
1245 std::copy(
ci.sendIndices.begin(),
ci.sendIndices.end(), std::back_inserter(this->fluidNodeIndicesBorder));
1248 std::sort(this->fluidNodeIndicesBorder.begin(),
this->fluidNodeIndicesBorder.end());
1249 this->fluidNodeIndicesBorder.erase(
1250 std::unique(this->fluidNodeIndicesBorder.begin(),
this->fluidNodeIndicesBorder.end()),
1251 this->fluidNodeIndicesBorder.end());
1254 for (
size_t i = 0;
i < this->fluidNodeIndicesBorder.size();
i++)
1255 this->fluidNodeIndicesBorder[
i] = this->
getSparseIndex(this->fluidNodeIndicesBorder[
i])+1;
1263 if (this->sparseIndices[index] == -1) {
1271 if (this->
field.
isStopper(index) ||
this->field.is(index, STOPPER_OUT_OF_GRID_BOUNDARY)) {
1287 const real length = end - start;
1289 return coord + length;
1291 return coord - length;
1295int GridImp::getStopperNeighborIndex(
real x,
real y,
real z,
int direction)
const
1303 if (isPeriodic(direction) &&
neighborCoords[direction] > getEnd(direction) - c1o2 * delta)
1305 neighborCoords[direction] -= getEnd(direction) - getStart(direction) - delta;
1321 throw std::runtime_error(
"GridImp::getStopperNeighborIndex() -> direction must be 0, 1 or 2.");
1334int GridImp::getNegativeStopperNeighborIndex(
real x,
real y,
real z)
const
1347int GridImp::getNeighborIndex(
real x,
real y,
real z,
int direction)
const
1351 if(isPeriodic(direction))
1383 throw std::runtime_error(
"GridImp::getPeriodicNeighbor() -> direction must be 0, 1 or 2.");
1393 if(periodicityX || periodicityY || periodicityZ)
1402 const bool periodicity[3] = {periodicityX, periodicityY, periodicityZ};
1406 for(
uint direction=0; direction<3; direction++){
1407 if(!periodicity[direction])
continue;
1422 for(
int direction=0; direction<3; direction++){
1455 coords[direction] -= delta;
1458 return coords[direction];
1467 coords[direction] += delta;
1472 return coords[direction];
1490 const auto coarseLevel = this->
getLevel();
1505 for (
uint index = 0; index < this->
getSize(); index++)
1508 for (
uint index = 0; index < this->
getSize(); index++)
1511 for (
uint index = 0; index < this->
getSize(); index++)
1524 for(
uint index = 0; index < this->size; index++ ){
1536 && (
this->getFieldEntry(index) == FLUID ||
1537 this->getFieldEntry(index) == FLUID_CFC ||
1538 this->getFieldEntry(index) == FLUID_CFF ||
1539 this->getFieldEntry(index) == FLUID_FCC ||
1540 this->getFieldEntry(index) == FLUID_FCF ||
1541 this->getFieldEntry(index) == BC_SOLID ) )
1587 bool requiresGridFinalization =
true;
1590 if (
triangularMesh && this->triangularMeshDiscretizationStrategy) {
1591 this->triangularMeshDiscretizationStrategy->discretize(
triangularMesh,
this, INVALID_SOLID, FLUID);
1592 this->triangularMeshDiscretizationStrategy->appendFastWindingQSurfaces(
this, this->qSourceSurfaces);
1593 requiresGridFinalization = this->triangularMeshDiscretizationStrategy->requiresGridFinalization();
1596 this->
discretize(
object, INVALID_SOLID, FLUID);
1600 if (!requiresGridFinalization)
1605 #pragma omp parallel for
1606 for (
int index = 0; index < (
int)this->size; index++)
1610 for (
int index = 0; index < (
int)this->size; index++) {
1620#pragma omp parallel for
1649 if (value == Q_DEPRECATED)
1664#pragma omp parallel for reduction(+ : numberOfClosedNeedleCells)
1665 for (
int index = 0; index < (
int)this->size; index++) {
1677 if( !this->
getField().is( index, FLUID ) )
return false;
1705#pragma omp parallel for reduction(+ : numberOfClosedNeedleCells)
1706 for (
int index = 0; index < (
int)this->size; index++) {
1717 if( !this->
getField().is( index, BC_SOLID ) )
return false;
1736 this->triangularMeshDiscretizationStrategy &&
1737 this->triangularMeshDiscretizationStrategy->usesFastWindingQComputation() &&
1738 this->qComputationStage == qComputationStageType::ComputeQs)
1753 if (!this->triangularMeshDiscretizationStrategy)
1756 if (!this->triangularMeshDiscretizationStrategy->usesFastWindingQComputation())
1759 this->triangularMeshDiscretizationStrategy->computeFastWindingQs(
this, this->qSourceSurfaces);
1762void GridImp::allocateQs()
1768 this->qValues =
nullptr;
1769 this->qPatches =
nullptr;
1780#pragma omp parallel for
1782 this->qValues[
i] = -1.0;
1789 if( this->qComputationStage == qComputationStageType::ComputeQs )
1792#pragma omp parallel for
1821 if( this->qComputationStage == qComputationStageType::ComputeQs ){
1822 if(this->
field.
is(index, BC_SOLID))
1827 else if( this->qComputationStage == qComputationStageType::FindSolidBoundaryNodes )
1829 if( !this->
field.
is(index, FLUID) )
continue;
1834 this->qIndices[index] = this->numberOfSolidBoundaryNodes++;
1845 if( this->qComputationStage == qComputationStageType::ComputeQs )
1849 for(
int index = 0; index < (
int)this->size; index++ )
1860 if( this->qComputationStage == qComputationStageType::ComputeQs ){
1861 if(this->
field.
is(index, BC_SOLID))
1863 calculateQs(index,
point,
object);
1866 else if( this->qComputationStage == qComputationStageType::FindSolidBoundaryNodes )
1868 if( !this->
field.
is(index, FLUID) )
continue;
1870 if( checkIfAtLeastOneValidQ(index,
point,
object) )
1874 this->qIndices[index] = this->numberOfSolidBoundaryNodes++;
1880 if (this->qComputationStage == qComputationStageType::ComputeQs)
1886 Vertex pointOnTriangle, direction;
1908 if ( -0.5 > this->qValues[
i*this->numberOfSolidBoundaryNodes + this->qIndices[index]] ||
1912 this->qValues[
i*this->numberOfSolidBoundaryNodes + this->qIndices[index]] =
subdistance;
1914 this->qPatches[ this->qIndices[index] ] = 0;
1921bool GridImp::checkIfAtLeastOneValidQ(
const uint index,
const Vertex &
point, Object*
object)
const
1960void GridImp::calculateQs(
const Vertex &
point,
const Triangle &
triangle)
const
1965 for (
int i = distribution.dir_start;
i <= distribution.dir_end;
i++)
1967#if defined(__CUDA_ARCH__)
1986void GridImp::calculateQs(
const uint index,
const Vertex &
point,
const Triangle &
triangle)
const
1993#if defined(__CUDA_ARCH__)
2013 if ( -0.5 > this->qValues[
i*this->numberOfSolidBoundaryNodes + this->qIndices[index]] ||
2016 this->qValues[
i*this->numberOfSolidBoundaryNodes + this->qIndices[index]] =
subdistance;
2018 this->qPatches[ this->qIndices[index] ] =
triangle.patchIndex;
2024bool GridImp::checkIfAtLeastOneValidQ(
const uint index,
const Vertex &
point,
const Triangle &
triangle)
const
2031#if defined(__CUDA_ARCH__)
2064 y =
wrapCoord(
y - (this->periodicShiftOnXinY + delta), startY - c1o2*delta, endY + c1o2*delta);
2065 z =
wrapCoord(
z - (this->periodicShiftOnXinZ + delta), startZ - c1o2*delta, endZ + c1o2*delta);
2068 y =
wrapCoord(
y + (this->periodicShiftOnXinY + delta), startY - c1o2*delta, endY + c1o2*delta);
2069 z =
wrapCoord(
z + (this->periodicShiftOnXinZ + delta), startZ - c1o2*delta, endZ + c1o2*delta);
2072 x =
wrapCoord(
x - (this->periodicShiftOnYinX + delta), startX - c1o2*delta, endX + c1o2*delta);
2073 z =
wrapCoord(
z - (this->periodicShiftOnYinZ + delta), startZ - c1o2*delta, endZ + c1o2*delta);
2076 x =
wrapCoord(
x + (this->periodicShiftOnYinX + delta), startX - c1o2*delta, endX + c1o2*delta);
2077 z =
wrapCoord(
z + (this->periodicShiftOnYinZ + delta), startZ - c1o2*delta, endZ + c1o2*delta);
2080 x =
wrapCoord(
x - (this->periodicShiftOnZinX + delta), startX - c1o2*delta, endX + c1o2*delta);
2081 y =
wrapCoord(
y - (this->periodicShiftOnZinY + delta), startY - c1o2*delta, endY + c1o2*delta);
2084 x =
wrapCoord(
x + (this->periodicShiftOnZinX + delta), startX - c1o2*delta, endX + c1o2*delta);
2085 y =
wrapCoord(
y + (this->periodicShiftOnZinY + delta), startY - c1o2*delta, endY + c1o2*delta);
2096 for(
uint index = 0; index < this->size; index++ ){
2106 fieldEntry == STOPPER_OUT_OF_GRID_BOUNDARY ||
2138 this->communicationIndices[direction].sendIndices.end(), index) !=
this->communicationIndices[direction].sendIndices.end())
2148 this->communicationIndices[direction].receiveIndices.end(),
2149 index) !=
this->communicationIndices[direction].receiveIndices.end())
2177 this->communicationIndices[direction+1].sendIndices.begin(),
2178 this->communicationIndices[direction+1].sendIndices.end() );
2183 this->communicationIndices[direction].receiveIndices.begin(),
2184 this->communicationIndices[direction].receiveIndices.end() );
2224 real minX, maxX, minY, maxY, minZ, maxZ;
2227 int minXIndex = std::lround(
floor((minX - this->startX) / this->delta)) - 1;
2228 int minYIndex = std::lround(
floor((minY - this->startY) / this->delta)) - 1;
2229 int minZIndex = std::lround(
floor((minZ - this->startZ) / this->delta)) - 1;
2231 int maxXIndex = std::lround(
ceil((maxX - this->startX) / this->delta)) + 1;
2232 int maxYIndex = std::lround(
ceil((maxY - this->startY) / this->delta)) + 1;
2233 int maxZIndex = std::lround(
ceil((maxZ - this->startZ) / this->delta)) + 1;
2235 minX = this->startX +
minXIndex * this->delta;
2236 minY = this->startY +
minYIndex * this->delta;
2237 minZ = this->startZ +
minZIndex * this->delta;
2239 maxX = this->startX +
maxXIndex * this->delta;
2240 maxY = this->startY +
maxYIndex * this->delta;
2241 maxZ = this->startZ +
maxZIndex * this->delta;
2243 return BoundingBox(minX, maxX, minY, maxY, minZ, maxZ);
2251 return Vertex(minX, minY, minZ);
2271 return Vertex(maxX, maxY, maxZ);
2286 return std::lround((
x - startX) / delta);
2291 return std::lround((
y - startY) / delta);
2296 return std::lround((
z - startZ) / delta);
2311 return this->sparseSize;
2315 return (
uint)this->fluidNodeIndices.size();
2402 if(this->gridInterface)
2409 if (this->gridInterface)
2416 return this->gridInterface->
cf.
coarse;
2421 return this->gridInterface->
cf.
fine;
2426 return this->gridInterface->
cf.
offset;
2431 return this->gridInterface->
fc.
coarse;
2436 return this->gridInterface->
fc.
fine;
2441 return this->gridInterface->
fc.
offset;
2454 for (
uint i = 0;
i < size;
i++)
2460 return std::find(this->fluidNodeIndicesBorder.begin(),
this->fluidNodeIndicesBorder.end(),
sparseIndex) !=
2461 this->fluidNodeIndicesBorder.end();
2478 for (
uint i = 0;
i < this->size;
i++)
2480 if (this->sparseIndices[
i] == -1)
2516 return (
uint)this->fluidNodeIndicesBorder.size();
2527 size_t newSize = this->fluidNodeIndicesMacroVars.size() + fluidNodeIndicesMacroVars.size();
2528 this->fluidNodeIndicesMacroVars.reserve(
newSize);
2529 std::copy(fluidNodeIndicesMacroVars.begin(), fluidNodeIndicesMacroVars.end(),
2530 std::back_inserter(
this->fluidNodeIndicesMacroVars));
2536 size_t newSize = this->fluidNodeIndicesApplyBodyForce.size() + fluidNodeIndicesApplyBodyForce.size();
2537 this->fluidNodeIndicesApplyBodyForce.reserve(
newSize);
2538 std::copy(fluidNodeIndicesApplyBodyForce.begin(), fluidNodeIndicesApplyBodyForce.end(),
2539 std::back_inserter(
this->fluidNodeIndicesApplyBodyForce));
2545 size_t newSize = this->fluidNodeIndicesAllFeatures.size() + fluidNodeIndicesAllFeatures.size();
2546 this->fluidNodeIndicesAllFeatures.reserve(
newSize);
2547 std::copy(fluidNodeIndicesAllFeatures.begin(), fluidNodeIndicesAllFeatures.end(),
2548 std::back_inserter(
this->fluidNodeIndicesAllFeatures));
2553 this->fluidNodeIndicesAllFeatures.clear();
2554 this->fluidNodeIndicesApplyBodyForce.clear();
2555 this->fluidNodeIndicesMacroVars.clear();
2556 this->fluidNodeIndicesAllFeatures.swap(this->fluidNodeIndices);
2561 std::sort(nodes.begin(), nodes.end());
2563 nodes.erase(std::unique(nodes.begin(), nodes.end()), nodes.end());
2571 const auto iter = std::stable_partition(
2572 allNodes.begin(),
allNodes.end(), [&](
auto x) { return !std::binary_search(markedNodes.begin(), markedNodes.end(), x); });
2586 sortFluidNodes(fluidNodeIndices, fluidNodeIndicesApplyBodyForce);
2593 std::set_intersection(fluidNodeIndicesMacroVars.begin(), fluidNodeIndicesMacroVars.end(),
2594 fluidNodeIndicesApplyBodyForce.begin(), fluidNodeIndicesApplyBodyForce.end(),
2595 std::back_inserter(fluidNodeIndicesAllFeatures));
2601 return (
uint)this->fluidNodeIndicesMacroVars.size();
2606 return (
uint)this->fluidNodeIndicesApplyBodyForce.size();
2611 return (
uint)this->fluidNodeIndicesAllFeatures.size();
2616 std::copy(this->fluidNodeIndicesMacroVars.begin(),
this->fluidNodeIndicesMacroVars.end(), fluidNodeIndicesMacroVars);
2620 std::copy(this->fluidNodeIndicesApplyBodyForce.begin(),
this->fluidNodeIndicesApplyBodyForce.end(),
2621 fluidNodeIndicesApplyBodyForce);
2625 std::copy(this->fluidNodeIndicesAllFeatures.begin(),
this->fluidNodeIndicesAllFeatures.end(),
2626 fluidNodeIndicesAllFeatures);
2630 return this->bcAlreadySet;
2635 this->bcAlreadySet.push_back(side);
2639 return this->adBCAlreadySet;
2644 this->adBCAlreadySet.push_back(side);
2650 printf(
"min: (%2.4f, %2.4f, %2.4f), max: (%2.4f, %2.4f, %2.4f), size: %d, delta: %2.4f\n", startX, startY, startZ,
2651 endX, endY, endZ, size, delta);
2652 if(this->gridInterface)
2653 this->gridInterface->
print();
2658 return (this->
getFieldEntry(index) == vf::gpu::STOPPER_OUT_OF_GRID_BOUNDARY ||
2659 this->
getFieldEntry(index) == vf::gpu::STOPPER_OUT_OF_GRID ||
#define VF_LOG_TRACE(...)
static real getDecimalPart(real number)
void setMinMax(const Triangle &t)
static Distribution getDistribution(std::string name)
void setFieldEntry(uint index, char val)
void setFieldEntryToStopperOutOfGridBoundary(uint index)
void setFieldEntryToStopperOutOfGrid(uint index)
void setFieldEntryToInvalidOutOfGrid(uint index)
bool isQ(uint index) const
char getFieldEntry(uint index) const
bool is(uint index, char type) const
bool isFluid(uint index) const
bool isInvalidOutOfGrid(uint index) const
bool isInvalidCoarseUnderFine(uint index) const
bool isStopper(uint index) const
bool isInvalidSolid(uint index) const
void setFieldEntryToFluid(uint index)
SPtr< GbTriFaceMesh3D > getActiveWindingSurface() const
void clearQForIndex(uint index)
void findForGridInterfaceNewIndices(SPtr< GridImp > fineGrid)
void sortFluidNodeIndicesMacroVars() override
void findSparseIndices(SPtr< Grid > fineGrid) override
static SPtr< GridImp > makeShared(SPtr< Object > object, real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, std::string d3Qxx, uint level)
uint getNumberOfFluidNodeIndicesApplyBodyForce() const override
int getEndDirection() const override
void addFluidNodeIndicesApplyBodyForce(std::vector< uint > fluidNodeIndicesApplyBodyForce) override
std::vector< SideType > getADBCAlreadySet() override
uint getNumberOfNodesZ() const override
real getEndY() const override
int getShiftedCommunicationIndex(uint index, int direction)
void addADBCalreadySet(SideType side) override
uint getNumberOfReceiveNodes(int direction) override
void getNodeValues(real *xCoords, real *yCoords, real *zCoords, uint *neighborX, uint *neighborY, uint *neighborZ, uint *neighborNegative, uint *geo) const override
void closeNeedleCells() override
real getEndZ() const override
SPtr< const Object > getObject() const override
void mesh(Object *object) override
bool isStopperForBC(uint index) const override
void setPeriodicityY(bool periodicity) override
SPtr< TriangularMeshDiscretizationStrategy > getTriangularMeshDiscretizationStrategy()
bool hasNeighborOfType(uint index, char type) const
bool isSparseIndexInFluidNodeIndicesBorder(uint &sparseIndex) const override
uint getNumberOfSolidBoundaryNodes() const override
void setOddStart(bool xOddStart, bool yOddStart, bool zOddStart) override
bool isSendNode(int index) const override
uint * getCF_offset() const override
real getLastFluidNode(real coords[3], int direction, real startCoord) const override
void beginQComputation() override
uint getNumberOfNodesX() const override
bool nodeHasBC(uint index) const override
void findQsPrimitive(Object *object)
uint getQPatch(const uint index) const override
real getStartZ() const override
void fillMissingQsWithDefault(real defaultValue=static_cast< real >(vf::grid_winding::defaultMissingQ()))
Distribution distribution
real getFirstFluidNode(real coords[3], int direction, real startCoord) const override
void setInnerBasedOnFinerGrid(const SPtr< Grid > fineGrid)
void setEnableFixRefinementIntoTheWall(bool enableFixRefinementIntoTheWall) override
void findInvalidBoundaryNodes(uint index)
void setPeriodicityZ(bool periodicity) override
void findCommunicationIndex(uint index, real coordinate, real limit, int direction)
uint getNumberOfNodesY() const override
std::array< CommunicationIndices, 6 > communicationIndices
uint getReceiveIndex(int direction, uint index) override
bool isInside(const Cell &cell) const
bool hasQIndex(uint index) const
void findInnerNode(uint index)
void setCellTo(uint index, char type)
uint getSize() const override
void freeMemory() override
void findEndOfGridStopperNode(uint index)
void findStopperNode(uint index)
int getSparseIndex(uint matrixIndex) const override
void ensureQStorageAllocated()
bool isReceiveNode(int index) const override
int getStartDirection() const override
Vertex getMaximumOnNode(Vertex exact) const override
int * getNeighborsZ() const override
const std::vector< int > & getDirection() const override
int * getNeighborsY() const override
void setQValue(uint index, int dir, real value)
void addFluidNodeIndicesAllFeatures(std::vector< uint > fluidNodeIndicesAllFeatures) override
int * getNeighborsX() const override
bool closeCellIfNeedleThinWall(uint index)
void setPeriodicBoundaryShiftsOnXinZ(real shift) override
uint * getCF_fine() const override
uint getNumberOfNodesCF() const override
void getFluidNodeIndicesBorder(uint *fluidNodeIndicesBorder) const override
std::vector< SideType > getBCAlreadySet() override
uint * getCF_coarse() const override
void sortFluidNodeIndicesApplyBodyForce() override
void setPeriodicity(bool periodicityX, bool periodicityY, bool periodicityZ) override
uint * getFC_fine() const override
void setActiveWindingSurface(SPtr< GbTriFaceMesh3D > surface)
uint getNumberOfFluidNodeIndicesMacroVars() const override
void getFluidNodeIndicesMacroVars(uint *fluidNodeIndicesMacroVars) const override
void setPeriodicBoundaryShiftsOnZinX(real shift) override
void findCommunicationIndices(int direction, SPtr< BoundingBox > subDomainBox, bool doShift) override
uint getSendIndex(int direction, uint index) override
void setPeriodicBoundaryShiftsOnXinY(real shift) override
uint * getFC_offset() const override
uint getNumberOfFluidNodesBorder() const override
void getFluidNodeIndices(uint *fluidNodeIndices) const override
void setOverlapTmp(uint index)
void addAllFluidNodeIndicesToAllFeatures() override
void limitToSubDomain(SPtr< BoundingBox > subDomainBox) override
bool hasAllNeighbors(uint index) const
void findGridInterface(SPtr< Grid > grid) override
Vertex getMinimumOnNode(Vertex exact) const override
void setNonStopperOutOfGridCellTo(uint index, char type)
real getStartY() const override
void inital(const SPtr< Grid > fineGrid, uint numberOfLayers) override
uint getSparseSize() const override
uint * getFC_coarse() const override
void setPeriodicityX(bool periodicity) override
void setFieldEntry(uint matrixIndex, char type) override
real getEndX() const override
char getFieldEntry(uint index) const override
void setPeriodicBoundaryShiftsOnYinZ(real shift) override
void fillMissingQsAlongSolidNeighbours(real defaultValue=static_cast< real >(vf::grid_winding::defaultMissingQ()))
void repairGridInterfaceOnMultiGPU(SPtr< Grid > fineGrid) override
bool closeCellIfNeedle(uint index)
void findQs(Object *object) override
void setTriangularMeshDiscretizationStrategy(SPtr< TriangularMeshDiscretizationStrategy > triangularMeshDiscretizationStrategy)
void setNumberOfLayers(uint numberOfLayers) override
void findFluidNodeIndicesBorder() override
uint getNumberOfNodesFC() const override
bool getPeriodicityY() const override
void findGridInterfaceCF(uint index, GridImp &finerGrid)
void setQPatch(uint index, uint patch)
bool getPeriodicityX() const override
bool cellContainsOnly(Cell &cell, char type) const
void repairCommunicationIndices(int direction) override
void setPeriodicBoundaryShiftsOnYinX(real shift) override
void rebuildBoundaryQIndices()
bool getPeriodicityZ() const override
void sortFluidNodeIndicesAllFeatures() override
void updateSparseIndices()
real getStartX() const override
void setNeighborIndices(uint index)
BoundingBox getBoundingBoxOnNodes(Triangle &triangle) const
real getQValue(const uint index, const uint dir) const override
static void getGridInterface(uint *gridInterfaceList, const uint *oldGridInterfaceList, uint size)
void findGridInterfaceFC(uint index, GridImp &finerGrid)
void findBoundarySolidNode(uint index)
void discretize(Object *object, char innerType, char outerType)
void getFluidNodeIndicesAllFeatures(uint *fluidNodeIndicesAllFeatures) const override
int * getNeighborsNegative() const override
void fixOddCell(uint index)
bool isNode(uint index, char type) const
uint getNumberOfFluidNodes() const override
void getFluidNodeIndicesApplyBodyForce(uint *fluidNodeIndicesApplyBodyForce) const override
void setNumberOfSolidBoundaryNodes(uint numberOfSolidBoundaryNodes) override
uint transCoordToIndex(const real &x, const real &y, const real &z) const override
bool nodeInNextCellIs(int index, char type) const
void addBCalreadySet(SideType side) override
void initalNodeToOutOfGrid(uint index)
uint getQIndex(uint index) const
void setPeriodicBoundaryShiftsOnZinY(real shift) override
real * getDistribution() const override
int * neighborIndexNegative
void setOverlapFluid(uint index)
void getGridInterfaceIndices(uint *iCellCfc, uint *iCellCff, uint *iCellFcc, uint *iCellFcf) const override
void findSolidStopperNode(uint index)
void setInnerRegionFromFinerGrid(bool innerRegionFromFinerGrid) override
void findOverlapStopper(uint index, GridImp &finerGrid)
void closeNeedleCellsThinWall() override
real getDelta() const override
void addFluidNodeIndicesMacroVars(std::vector< uint > fluidNodeIndicesMacroVars) override
void finalizeQComputation() override
uint getNumberOfFluidNodeIndicesAllFeatures() const override
uint getNumberOfSendNodes(int direction) override
void findFluidNodeIndices(bool splitDomain) override
void transIndexToCoords(uint index, real &x, real &y, real &z) const override
void fixRefinementIntoWall(uint xIndex, uint yIndex, uint zIndex, int dir)
void findOverlapStopper(const uint &indexOnCoarseGrid, GridImp *coarseGrid, GridImp *fineGrid)
void findForGridInterfaceSparseIndexCF(GridImp *coarseGrid, GridImp *fineGrid, uint index)
void findBoundaryGridInterfaceCF(const uint &indexOnCoarseGrid, GridImp *coarseGrid, GridImp *fineGrid)
void findInvalidBoundaryNodes(const uint &indexOnCoarseGrid, GridImp *coarseGrid)
void findForGridInterfaceSparseIndexFC(GridImp *coarseGrid, GridImp *fineGrid, uint index)
struct vf::gpu::GridInterface::Interface fc
struct vf::gpu::GridInterface::Interface cf
void findInterfaceCF(const uint &indexOnCoarseGrid, GridImp *coarseGrid, GridImp *fineGrid)
void findInterfaceFC(const uint &indexOnCoarseGrid, GridImp *coarseGrid, GridImp *fineGrid)
void repairGridInterfaceOnMultiGPU(SPtr< GridImp > coarseGrid, SPtr< GridImp > fineGrid)
std::shared_ptr< T > SPtr
int DIRECTIONS[DIR_END_MAX][DIMENSION]
static bool lessEqual(const real &val1, const real &val2, real maxRelDiff=EPSILON)
static bool greaterEqual(const real &val1, const real &val2, real maxRelDiff=EPSILON)
static bool equal(const real &val1, const real &val2, real maxRelDiff=EPSILON)
void cleanFluidNodes(std::vector< uint > &nodes)
void sortFluidNodes(std::vector< uint > &allNodes, std::vector< uint > &markedNodes)
real wrapCoord(real coord, real start, real end)
bool pointOnTriangle(const TriangleInfo &triangle, const Vec3 &p, double planeTol, double baryTol=1.0e-8)
std::vector< Direction > directions