24#if defined(MAIA_GCC_COMPILER)
25#pragma GCC diagnostic push
26#pragma GCC diagnostic error "-Wconversion"
140 : m_mpiComm(comm), outStream(nullptr), m_noSolvers(
noSolvers) {
151 std::cout <<
"Parallel grid generator started on process " <<
globalDomainId() << endl;
191 m_log <<
" (8) Cleaning up" << endl;
201 NEW_TIMER_GROUP(tgrp_GG,
"Parallel grid generation");
202 NEW_TIMER(t_comp_GG,
"complete grid generation", tgrp_GG);
203 NEW_SUB_TIMER(t_readProperties,
"(1) read properties", t_comp_GG);
204 NEW_SUB_TIMER(t_initMembers,
"(2) init members", t_comp_GG);
205 NEW_SUB_TIMER(t_initGeometry,
"(3) init geometry", t_comp_GG);
206 NEW_SUB_TIMER(t_createInitialGrid,
"(4) create initial grid", t_comp_GG);
207 NEW_SUB_TIMER(t_parallelizeGrid,
"(5) distribute grid among processes", t_comp_GG);
208 NEW_SUB_TIMER(t_createStartGrid,
"(6) create start grid", t_comp_GG);
209 NEW_SUB_TIMER(t_createComputationalGrid,
"(7) create computational grid", t_comp_GG);
210 NEW_SUB_TIMER(t_finalizeGrid,
"(8) prepare grid for IO", t_comp_GG);
211 NEW_SUB_TIMER(t_saveGrid,
"(9) parallel grid I/O", t_comp_GG);
213 m_t_comp_GG = t_comp_GG;
214 m_t_readProperties = t_readProperties;
215 m_t_initMembers = t_initMembers;
216 m_t_initGeometry = t_initGeometry;
217 m_t_createInitialGrid = t_createInitialGrid;
218 m_t_parallelizeGrid = t_parallelizeGrid;
219 m_t_createStartGrid = t_createStartGrid;
220 m_t_createComputationalGrid = t_createComputationalGrid;
221 m_t_finalizeGrid = t_finalizeGrid;
222 m_t_saveGrid = t_saveGrid;
237 RECORD_TIMER_START(m_t_readProperties);
239 m_log <<
" (1) reading properties" << endl;
240 outStream <<
" (1) reading properties" << endl;
242 mAlloc(m_solverRefinement, m_noSolvers,
"m_solverRefinement", AT_);
270 cerr <<
"Warning: Property initialGeometricalRfnLvl is deprecated. Please rename to minLevel." << endl;
271 m_initialRefinementLevelSerial = Context::getBasicProperty<MInt>(
"initialGeometricalRfnLvl", AT_);
273 m_initialRefinementLevelSerial = Context::getBasicProperty<MInt>(
"minLevel", AT_);
276 m_minLevel = m_initialRefinementLevelSerial;
281 m_maxUniformRefinementLevel = numeric_limits<MInt>::max();
283 m_maxRfnmntLvl = numeric_limits<MInt>::min();
286 m_weightPatchCells = 0;
287 m_weightBndCells = 0;
288 m_weightSolverUniformLevel = 0;
289 m_weightSolverUniformLevel =
290 Context::getBasicProperty<MBool>(
"weightSolverUniformLevel", AT_, &m_weightSolverUniformLevel);
292 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
293 readSolverProperties(solver);
310 m_weightMethod = Context::getBasicProperty<MInt>(
"weightMethod", AT_, &m_weightMethod);
312 m_writeGridInformation = 0;
313 m_writeGridInformation = Context::getBasicProperty<MBool>(
"writeGridInformation", AT_, &m_writeGridInformation);
328 m_reductionFactor = 1.0;
329 m_reductionFactor = Context::getBasicProperty<MFloat>(
"reductionFactor", AT_, &m_reductionFactor);
342 m_gridOutputFileName = Context::getBasicProperty<MString>(
"gridOutputFileName", AT_);
351 m_writeCoordinatesToGridFile =
false;
352 m_writeCoordinatesToGridFile =
353 Context::getBasicProperty<MBool>(
"writeCoordinatesToGridFile", AT_, &m_writeCoordinatesToGridFile);
355 stringstream errorMsg;
356 if(m_reductionFactor < 1.0 || m_reductionFactor >= 2.0) {
357 errorMsg <<
"ERROR: reductionFactor must be between 1.0 and 2.0, but is " << m_reductionFactor << endl;
358 m_log << errorMsg.str();
359 mTerm(1, AT_, errorMsg.str());
362 m_maxNoCells = Context::getBasicProperty<MInt>(
"maxNoCells", AT_, &m_maxNoCells);
364 m_partitionCellOffspringThreshold = 50000;
377 mTerm(1, AT_,
"Error: Property minCellMaxSize is deprecated. Please rename to partitionCellOffspringThreshold.");
379 cerr <<
"Warning: Property partitionCellMaxNoOffspring is deprecated. Please rename to "
380 "partitionCellOffspringThreshold."
382 MInt tmpPartitionCellMaxSize = (
MInt)m_partitionCellOffspringThreshold;
383 m_partitionCellOffspringThreshold =
384 (
MLong)(Context::getBasicProperty<MInt>(
"partitionCellMaxNoOffspring", AT_, &tmpPartitionCellMaxSize));
386 MInt tmpPartitionCellMaxSize = (
MInt)m_partitionCellOffspringThreshold;
387 m_partitionCellOffspringThreshold =
388 (
MLong)(Context::getBasicProperty<MInt>(
"partitionCellOffspringThreshold", AT_, &tmpPartitionCellMaxSize));
391 m_partitionCellWorkloadThreshold = 50000.;
403 m_partitionCellWorkloadThreshold =
404 Context::getBasicProperty<MFloat>(
"partitionCellWorkloadThreshold", AT_, &m_partitionCellWorkloadThreshold);
419 m_targetGridFileName =
"";
420 m_targetGridFileName = Context::getBasicProperty<MString>(
"targetGridFileName", AT_, &m_targetGridFileName);
423 m_hasMultiSolverBoundingBox =
true;
435 TERMM(1,
"multiSolverBoundingBox: wrong number of coordinates for bouding box "
439 m_multiSolverBoundingBox.resize(2 * nDim);
440 for(
MInt i = 0; i < 2 * nDim; i++) {
441 m_multiSolverBoundingBox[i] = Context::getBasicProperty<MFloat>(
"multiSolverBoundingBox", AT_, i);
452 m_multiSolverMinLevel = Context::getBasicProperty<MInt>(
"multiSolverMinLevel", AT_);
454 if(m_multiSolverMinLevel < 0) {
455 TERMM(1,
"ERROR: invalid multiSolverMinLevel " + std::to_string(m_multiSolverMinLevel));
458 m_multiSolverMinLevel = m_minLevel;
461 if(m_targetGridFileName !=
"") {
462 TERMM(1,
"ERROR: multiSolverBoundingBox and targetGridFileName specified.");
479 testcaseDir = Context::getBasicProperty<MString>(
"testcaseDir", AT_, &testcaseDir);
492 m_outputDir = testcaseDir + Context::getBasicProperty<MString>(
"outputDir", AT_);
496 if(stat(m_outputDir.c_str(), &info) != 0) {
497 std::stringstream ss;
498 ss <<
"Output directory is invalid: ";
499 ss << m_outputDir.c_str();
500 mTerm(1, AT_, ss.str());
510 m_checkGridLbValidity =
true;
511 m_checkGridLbValidity = Context::getBasicProperty<MBool>(
"checkGridLbValidity", AT_, &m_checkGridLbValidity);
525 m_keepOutsideBndryCellChildren = 0;
526 m_keepOutsideBndryCellChildren =
527 Context::getBasicProperty<MInt>(
"ggp_keepOutsideBndryCellChildren", AT_, &m_keepOutsideBndryCellChildren);
529 if(m_keepOutsideBndryCellChildren == 3) {
530 if(m_reductionFactor <= 1.0) {
531 mTerm(1, AT_,
"ERROR: m_reductionFactor must be > 1 to use keepOutsideBndryCellChildren in mode 3");
533 if(noDomains() > 1) {
534 mTerm(1, AT_,
"ERROR: keepOutsideBndryCellChildren in mode 3 is not implemented for parallel usage yet!!!");
536 mAlloc(m_noSolidLayer, m_noSolvers,
"noSolidLayer", AT_);
537 for(
MInt s = 0; s < m_noSolvers; s++) {
538 m_noSolidLayer[s] = 1;
539 m_noSolidLayer[s] = Context::getSolverProperty<MInt>(
"noSolidLayer", s, AT_, &m_noSolidLayer[s]);
540 if(domainId() == 0) {
541 cerr <<
"Applying " << m_noSolidLayer[s] <<
" solid layers for solver " << s << endl;
546 RECORD_TIMER_STOP(m_t_readProperties);
558 cerr <<
"Warning: Property maxGeometricalRfnLvl is deprecated. Please rename to maxUniformRefinementLevel." << endl;
569 bp->
maxRfnmntLvl = Context::getSolverProperty<MInt>(
"maxRfnmntLvl", solver, AT_);
572 bp->
maxBoundaryRfnLvl = Context::getSolverProperty<MInt>(
"maxBoundaryRfnLvl", solver, AT_);
575 stringstream errorMsg;
577 errorMsg <<
"ERROR: minLevel is larger than maxUniformRefinementLevel of solver " << solver << endl;
580 errorMsg <<
"ERROR: minLevel is larger than maxRfnmntLvl" << endl;
583 errorMsg <<
"ERROR: maxUniformRefinementLevel is larger than maxRfnmntLvl" << endl;
586 errorMsg <<
"ERROR: maxBoundaryRfnLvl is larger than maxRfnmntLvl" << endl;
589 if(errorMsg.str() !=
"") {
590 m_log << errorMsg.str();
591 mTerm(1, AT_, errorMsg.str());
613 MInt localRfnMethod = 0;
614 localRfnMethod = Context::getSolverProperty<MInt>(
"localRfnMethod", solver, AT_, &localRfnMethod);
627 MString localRfnLevelMethods = Context::getSolverProperty<MString>(
"localRfnLvlMethods", solver, AT_);
641 m_weightPatchCells =
mMax(m_weightPatchCells,
642 Context::getSolverProperty<MInt>(
"weightPatchCells", solver, AT_, &m_weightPatchCells));
645 if(localRfnLevelMethods.front() ==
'-' || localRfnLevelMethods.back() ==
'-')
646 mTerm(1, AT_,
"ERROR: localRfnLvlMethods begins or ends with hyphen!");
648 if(localRfnLevelMethods.find(
" ") != MString::npos)
mTerm(1, AT_,
"ERROR: localRfnLvlMethods contains space!");
650 MString::size_type prev_pos = 0;
651 MString::size_type nextMarker = 0;
654 while(nextMarker != MString::npos) {
658 nextMarker = localRfnLevelMethods.find(
"-", prev_pos);
659 MString substring(localRfnLevelMethods.substr(prev_pos, nextMarker - prev_pos));
661 prev_pos = nextMarker;
664 MBool reducedNoPatches =
false;
667 cerr <<
"WARNING: highest patch level exceeds maxRfnmntLvl in solver " << solver
668 <<
", higher patches will be omitted!" << endl;
670 reducedNoPatches =
true;
689 for(MString::size_type j = 0; j < lvlStr.size(); j++) {
690 const MString patchStr = lvlStr.substr(j, 1);
691 if(patchStr ==
"B") {
693 }
else if(patchStr ==
"R") {
695 }
else if(patchStr ==
"C") {
697 }
else if(patchStr ==
"T") {
699 }
else if(patchStr ==
"O") {
701 }
else if(patchStr ==
"H") {
703 }
else if(patchStr ==
"S") {
705 }
else if(patchStr ==
"W") {
707 }
else if(patchStr ==
"F") {
708 }
else if(patchStr ==
"A") {
710 }
else if(patchStr ==
"N") {
713 TERMM(1,
"Unknown patch type: '" + patchStr +
"'");
741 if(count_prov < count_req || (count_prov != count_req && !reducedNoPatches)) {
743 "ERROR: number of localRfnLevelProperties does not match the requested value! " + std::to_string(count_prov)
744 +
" != " + std::to_string(count_req));
750 for(
MInt i = 0; i < count_req; i++) {
752 Context::getSolverProperty<MFloat>(
"localRfnLevelProperties", solver, AT_, i);
763 if(localRfnMethod == 1 || localRfnMethod == 3) {
764 cerr <<
"WARNING: local patch refinement requested (localRfnMethod = 1 or 3),"
765 <<
" but maxRfnmntLvl is equal to maxUniformRefinementLevel";
783 mMax(m_weightBndCells, Context::getSolverProperty<MInt>(
"weightBndCells", solver, AT_, &m_weightBndCells));
802 Context::getSolverProperty<MInt>(
"localBndRfnMethod", solver, AT_, &(bp->
localBndRfnMethod));
808 mTerm(1, AT_,
"ERROR: localRfnBoundaryIds was requested but is not in property file");
813 bp->
localRfnBoundaryIds[i] = Context::getSolverProperty<MInt>(
"localRfnBoundaryIds", solver, AT_, i);
832 mTerm(1, AT_,
"ERROR: localMinBoundaryThreshold has wrong length");
835 Context::getSolverProperty<MInt>(
"localMinBoundaryThreshold", solver, AT_, noLocalMinBoundaryThreshold - 1),
838 for(
MInt i = 0; i < noLocalMinBoundaryThreshold; i++) {
856 Context::getSolverProperty<MFloat>(
"localBndRfnDistance", solver, AT_, noLocalBndRfnDistance - 1), AT_);
857 for(
MInt i = 0; i < noLocalBndRfnDistance; i++) {
858 bp->
localBndRfnDistance[i] = Context::getSolverProperty<MFloat>(
"localBndRfnDistance", solver, AT_, i);
861 mTerm(1, AT_,
"ERROR: localBndRfnMethod == 2 requires localBndRfnDistance property");
876 Context::getSolverProperty<MInt>(
"localBndRfnMinLvlDiff", solver, AT_, noLocalBndRfnMinLvlDiff - 1),
878 for(
MInt i = 0; i < noLocalBndRfnMinLvlDiff; i++) {
879 bp->
localBndRfnMinLvlDiff[i] = Context::getSolverProperty<MInt>(
"localBndRfnMinLvlDiff", solver, AT_, i);
905 if(noSmoothDistance <= bp->noLocalRfnBoundaryIds && noSmoothDistance > 0) {
907 Context::getSolverProperty<MInt>(
"smoothDistance", solver, AT_, noSmoothDistance - 1), AT_);
909 for(
MInt i = 0; i < noSmoothDistance; i++) {
910 bp->
smoothDistance[i] = Context::getSolverProperty<MInt>(
"smoothDistance", solver, AT_, i);
913 mTerm(1, AT_,
"ERROR: smoothDistance is wrongly defined in property file");
935 if(noLocalRfnLvlDiff <= bp->noLocalRfnBoundaryIds && noLocalRfnLvlDiff > 0) {
937 Context::getSolverProperty<MInt>(
"localRfnLvlDiff", solver, AT_, noLocalRfnLvlDiff - 1), AT_);
939 for(
MInt i = 0; i < noLocalRfnLvlDiff; i++)
940 bp->
localRfnLvlDiff[i] = Context::getSolverProperty<MInt>(
"localRfnLvlDiff", solver, AT_, i);
942 mTerm(1, AT_,
"ERROR: localRfnLvlDiff is wrongly defined in property file");
948 MInt minLocalRfnLvlDiff = numeric_limits<MInt>::max();
953 if(minLocalRfnLvlDiff < 0)
mTerm(1, AT_,
"ERROR: localRfnLvlDiff has negative values");
955 if(bp->
maxRfnmntLvl - minLocalRfnLvlDiff <= bp->maxUniformRefinementLevel) {
956 cerr <<
"WARNING: localRfnLvlDiff of solver " << solver <<
" leads to no further refinement"
957 <<
" boundary refinement is disabled" << endl;
963 if(localRfnMethod == 2 || localRfnMethod == 3) {
964 cerr <<
"WARNING: local boundary refinement requested (localRfnMethod = 2 or 3),"
965 <<
" but maxBoundaryRfnLvl is equal to maxUniformRefinementLevel";
969 m_maxRfnmntLvl =
mMax(m_maxRfnmntLvl, maxRequestedRfnmntLvl);
986 bp->
cutOff = Context::getSolverProperty<MInt>(
"cutOff", solver, AT_, &(bp->
cutOff));
1005 cutOffMethod = Context::getSolverProperty<MString>(
"cutOffMethod", solver, AT_, &cutOffMethod);
1007 if(cutOffMethod ==
"") {
1008 errorMsg <<
"ERROR: cutOffMethod is not defined in property file for solver " << solver << endl;
1009 m_log << errorMsg.str();
1010 mTerm(1, AT_, errorMsg.str());
1013 MString::size_type prev_pos = 0, pos = 0;
1015 while((pos = cutOffMethod.find(
"-", pos)) != MString::npos) {
1016 MString substring(cutOffMethod.substr(prev_pos, pos - prev_pos));
1021 bp->
cutOffMethods.push_back(cutOffMethod.substr(prev_pos, pos - prev_pos));
1024 MInt* tmpPointer = nmbrValuesPerMethod.begin();
1029 nmbrValuesPerMethod[i] = 2 * nDim;
1031 nmbrValuesPerMethod[i] = 2 * nDim;
1033 nmbrValuesPerMethod[i] = 2 * nDim;
1035 nmbrValuesPerMethod[i] = 4;
1037 count_req += nmbrValuesPerMethod[i];
1049 if(count_req == count_prov) {
1054 for(
MInt j = 0; j < nmbrValuesPerMethod[i]; j++, pos2++) {
1055 bp->
cutOffCoordinates[i][j] = Context::getSolverProperty<MFloat>(
"cutOffCoordinates", solver, AT_, pos2);
1059 errorMsg <<
"ERROR: cutOffCoordinates are not defined or not properly defined in property file for solver "
1061 m_log << errorMsg.str();
1062 mTerm(1, AT_, errorMsg.str());
1067 tmpPointer = nmbrLayersPerMethod.begin();
1072 nmbrLayersPerMethod[i] = 1;
1074 nmbrLayersPerMethod[i] = 2 * nDim;
1076 nmbrLayersPerMethod[i] = 2 * nDim;
1078 nmbrLayersPerMethod[i] = 1;
1080 count_req += nmbrLayersPerMethod[i];
1095 if(count_prov == count_req) {
1098 for(
MInt j = 0; j < nmbrLayersPerMethod[i]; j++, pos2++) {
1099 bp->
cutOffNmbrLayers[i][j] = Context::getSolverProperty<MInt>(
"cutOffNmbrLayers", solver, AT_, pos2);
1103 errorMsg <<
"ERROR: cutOffNmbrLayers are not properly defined in property file for solver " << solver << endl;
1104 m_log << errorMsg.str();
1105 mTerm(1, AT_, errorMsg.str());
1109 for(
MInt j = 0; j < nmbrLayersPerMethod[i]; j++)
1125 RECORD_TIMER_START(m_t_initMembers);
1127 m_log <<
" (2) initializing member variables" << endl;
1128 outStream <<
" (2) initializing member variables" << endl;
1130 mAlloc(m_boundingBox, 2 * nDim,
"m_boundingBox", AT_);
1131 mAlloc(m_geometryExtents, nDim,
"m_geometryExtents", AT_);
1132 mAlloc(m_centerOfGravity, nDim,
"m_centerOfGravity", AT_);
1134 mAlloc(m_cells, m_maxNoCells, nDim, 0,
"m_cells", AT_);
1135 m_pCells = m_cells->a;
1138 m_noTotalCells = -1;
1139 m_noPartitionCells = -1;
1140 m_noTotalPartitionCells = -1;
1141 m_noTotalHaloCells = -1;
1142 m_decisiveDirection = 0;
1143 m_noNeighborDomains = 0;
1144 m_maxNoChildren =
IPOW2(nDim);
1146 m_noNeighbors = 2 * nDim;
1147 m_cellOffsetPar = 0;
1150 mAlloc(m_levelOffsets, m_maxRfnmntLvl + 1, 2,
"m_levelOffsets", -1, AT_);
1151 mAlloc(m_haloCellOffsetsLevel, m_maxRfnmntLvl + 1, 2,
"m_haloCellOffsetsLevel", -1, AT_);
1152 mAlloc(m_noHaloCellsOnLevel, m_maxRfnmntLvl + 1,
"m_noHaloCellsOnLevel", 0, AT_);
1153 mAlloc(m_noCellsPerDomain, noDomains(),
"m_noCellsPerDomain", 0, AT_);
1156 mAlloc(m_lengthOnLevel, m_maxLevels,
"m_lengthOnLevel", 0.0, AT_);
1158 if(m_minLevel % 2 == 0) {
1159 m_levelOffsets[0][0] = 0;
1160 m_levelOffsets[0][1] = 1;
1161 m_levelOffsets[1][0] = m_maxNoCells - m_maxNoChildren;
1162 m_levelOffsets[1][1] = m_maxNoCells;
1164 m_levelOffsets[0][0] = m_maxNoCells - 1;
1165 m_levelOffsets[0][1] = m_maxNoCells;
1166 m_levelOffsets[1][0] = 0;
1167 m_levelOffsets[1][1] = m_maxNoChildren;
1171 m_noMissingParents = 0;
1172 m_hasBeenLoadBalanced =
false;
1174 RECORD_TIMER_STOP(m_t_initMembers);
1206 RECORD_TIMER_START(m_t_initGeometry);
1208 m_log <<
" (3) initializing geometry" << endl;
1209 outStream <<
" (3) initializing geometry" << endl;
1211 m_geometry =
new GeometryRoot(m_noSolvers, nDim, mpiComm());
1213 mAlloc(m_noBndIdsPerSolver, m_geometry->noNodes(), AT_, 0,
"noBndIds");
1214 for(
MInt solver = 0; solver < m_geometry->noNodes(); solver++) {
1215 m_noBndIdsPerSolver[solver] = m_geometry->noSegmentsOfNode(solver);
1217 mAlloc(m_bndCutInfo, m_geometry->noNodes(), m_noBndIdsPerSolver, AT_,
"bndCutInfo");
1219 m_geometry->boundingBox(m_boundingBox);
1224 if(m_hasMultiSolverBoundingBox && m_multiSolverMinLevel == m_minLevel) {
1225 m_log <<
"Using multisolver bounding box information from property file" << std::endl;
1226 for(
MInt i = 0; i < nDim; i++) {
1227 TERMM_IF_COND(m_boundingBox[i] < m_multiSolverBoundingBox[i],
1228 "Multisolver bounding box error (dim: " + std::to_string(i) +
"): "
1229 + std::to_string(m_boundingBox[i]) +
" < " + std::to_string(m_multiSolverBoundingBox[i]));
1230 TERMM_IF_COND(m_boundingBox[nDim + i] > m_multiSolverBoundingBox[nDim + i],
1231 "Multisolver bounding box error (dim: " + std::to_string(i)
1232 +
"): " + std::to_string(m_boundingBox[nDim + i]) +
" > "
1233 + std::to_string(m_multiSolverBoundingBox[nDim + i]));
1234 m_boundingBox[i] = m_multiSolverBoundingBox[i];
1235 m_boundingBox[nDim + i] = m_multiSolverBoundingBox[nDim + i];
1240 for(
MInt dir = 0; dir < nDim; dir++) {
1241 m_geometryExtents[dir] = m_boundingBox[dir + nDim] - m_boundingBox[dir];
1242 m_decisiveDirection = m_geometryExtents[dir] > m_geometryExtents[m_decisiveDirection] ? dir : m_decisiveDirection;
1243 m_centerOfGravity[dir] = m_boundingBox[dir] + 0.5 * (m_boundingBox[dir + nDim] - m_boundingBox[dir]);
1246 m_lengthOnLevel[0] = (F1 + F1 /
FPOW2(30)) * m_reductionFactor * m_geometryExtents[m_decisiveDirection];
1247 for(
MInt l = 1; l < m_maxLevels; l++)
1248 m_lengthOnLevel[l] = m_lengthOnLevel[l - 1] * 0.5;
1250 m_log <<
" + center of gravity: ";
1251 for(
MInt dir = 0; dir < nDim; dir++)
1252 m_log << m_centerOfGravity[dir] <<
" ";
1254 m_log <<
" + decisive direction: " << m_decisiveDirection <<
"\n";
1255 m_log <<
" + geometry extents: ";
1256 for(
MInt dir = 0; dir < nDim; dir++)
1257 m_log << m_geometryExtents[dir] <<
" ";
1259 m_log <<
" + bounding box: ";
1260 for(
MInt dir = 0; dir < m_noNeighbors; dir++)
1261 m_log << m_boundingBox[dir] <<
" ";
1264 outStream <<
" + center of gravity: ";
1265 for(
MInt dir = 0; dir < nDim; dir++)
1266 outStream << m_centerOfGravity[dir] <<
" ";
1268 outStream <<
" + decisive direction: " << m_decisiveDirection <<
"\n";
1269 outStream <<
" + geometry extents: ";
1270 for(
MInt dir = 0; dir < nDim; dir++)
1271 outStream << m_geometryExtents[dir] <<
" ";
1273 outStream <<
" + bounding box: ";
1274 for(
MInt dir = 0; dir < m_noNeighbors; dir++)
1275 outStream << m_boundingBox[dir] <<
" ";
1278 RECORD_TIMER_STOP(m_t_initGeometry);
1295 MFloat cellLength = m_lengthOnLevel[m_minLevel];
1296 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
1300 for(
MInt dim = 0; dim < nDim; dim++) {
1301 for(
MInt dir = 0; dir < 2; dir++) {
1305 n = (
MInt)floor(relCoord / cellLength + 0.5);
1307 n = (
MInt)ceil(relCoord / cellLength + 0.5);
1309 bp->
cutOffCoordinates[c][dim + dir * nDim] = n * cellLength + m_centerOfGravity[dim];
1355 RECORD_TIMER_START(m_t_createInitialGrid);
1357 m_log <<
" (4) creating initial grid" << endl;
1358 outStream <<
" (4) creating initial grid" << endl;
1360 m_log <<
" + refining from: 0 to " << m_minLevel << endl;
1361 outStream <<
" + refining from: 0 to " << m_minLevel << endl;
1363 m_log <<
" + initial cube size: " << m_lengthOnLevel[0] << endl;
1364 outStream <<
" + initial cube size: " << m_lengthOnLevel[0] << endl;
1366 MInt in_id = m_levelOffsets[0][0];
1369 for(
MInt d = 0; d < nDim; d++)
1370 a_coordinate(in_id, d) = m_centerOfGravity[d];
1372 for(
MInt d = 0; d < m_noNeighbors; d++)
1373 a_neighborId(in_id, d) = -1;
1375 for(
MInt c = 0; c < m_maxNoChildren; c++)
1376 a_childId(in_id, c) = -1;
1378 a_parentId(in_id) = -1;
1380 a_globalId(in_id) = (
MLong)in_id;
1381 a_noChildren(in_id) = 0;
1382 for(
MInt s = 0; s < m_noSolvers; s++) {
1383 a_noSolidLayer(in_id, s) = -1;
1386 for(
MInt i = 0; i < 8; i++)
1387 a_hasProperty(in_id, i) = 0;
1390 a_hasProperty(in_id, 1) = 1;
1393 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
1394 a_isSolverBoundary(in_id, solver) = 1;
1395 a_isInSolver(in_id, solver) = 1;
1396 a_isToRefineForSolver(in_id, solver) = 1;
1402 for(
MInt l = 0; l < m_minLevel; l++) {
1404 if(m_levelOffsets[l][0] == 0) {
1405 m_levelOffsets[l + 1][0] = m_maxNoCells - (m_levelOffsets[l][1] - m_levelOffsets[l][0]) * m_maxNoChildren;
1406 m_levelOffsets[l + 1][1] = m_maxNoCells;
1408 m_levelOffsets[l + 1][0] = 0;
1409 m_levelOffsets[l + 1][1] = (m_levelOffsets[l][1] - m_levelOffsets[l][0]) * m_maxNoChildren;
1413 checkMemoryAvailability(0, l + 1);
1415 for(
MInt solver = 0; solver < m_noSolvers; solver++)
1416 markSolverForRefinement(l, solver);
1419 refineGrid(m_levelOffsets, l, 0);
1422 m_log <<
" * finding the neighbors for the new level" << endl;
1423 outStream <<
" * finding the neighbors for the new level" << endl;
1424 findChildLevelNeighbors(m_levelOffsets, l);
1427 deleteOutsideCellsSerial(l + 1);
1430 for(
MInt i = m_levelOffsets[m_minLevel][0]; i < m_levelOffsets[m_minLevel][1]; i++)
1434 m_noCells = m_levelOffsets[m_minLevel][1] - m_levelOffsets[m_minLevel][0];
1435 m_log <<
" + created " << m_noCells <<
" cells for level " << m_minLevel << endl;
1436 outStream <<
" + created " << m_noCells <<
" cells for level " << m_minLevel << endl;
1439 reorderCellsHilbert();
1441 RECORD_TIMER_STOP(m_t_createInitialGrid);
1463 for(
MInt i = offsets[level_][1] - 1; i >= offsets[level_][0]; i--) {
1464 if(a_isInSolver(i, solver)) {
1465 a_hasProperty(i, 6) = 0;
1467 a_hasProperty(i, 6) = 1;
1488 for(
MInt i = offsets[level_][1] - 1; i >= offsets[level_][0]; i--) {
1490 if(a_hasProperty(i, 6))
continue;
1493 if(a_isSolverBoundary(i, solver)) {
1494 a_isInSolver(i, solver) = 1;
1495 a_hasProperty(i, 6) = 1;
1500 if(pointIsInsideSolver(&a_coordinate(i, 0), solver)) {
1501 stack<MInt> fillStack;
1502 a_isInSolver(i, solver) = 1;
1503 a_hasProperty(i, 6) = 1;
1505 floodCells(&fillStack, 1, solver);
1508 stack<MInt> fillStack;
1509 a_isInSolver(i, solver) = 0;
1510 a_hasProperty(i, 6) = 1;
1512 floodCells(&fillStack, 0, solver);
1534 if((m_levelOffsets[level_ - 1][0] > m_levelOffsets[level_][0]
1535 && m_levelOffsets[level_][1] > m_levelOffsets[level_ - 1][0])
1536 || (m_levelOffsets[level_ - 1][0] < m_levelOffsets[level_][0]
1537 && m_levelOffsets[level_][0] < m_levelOffsets[level_ - 1][1])) {
1538 stringstream errorMsg;
1539 errorMsg <<
"Not enough memory - normal cells overlap:\n"
1540 <<
" - cell offsets current level: " << m_levelOffsets[level_][0] <<
" " << m_levelOffsets[level_][1]
1542 <<
" - cell offset last level: " << m_levelOffsets[level_ - 1][0] <<
" "
1543 << m_levelOffsets[level_ - 1][1] <<
"\n"
1544 <<
" - max. no of available cells: " << m_maxNoCells << endl;
1545 m_log << errorMsg.str();
1546 mTerm(1, AT_, errorMsg.str());
1551 if(noDomains() > 1) {
1552 if(m_levelOffsets[level_][1] > m_haloCellOffsetsLevel[level_][0]) {
1553 stringstream errorMsg;
1554 errorMsg <<
"Not enough memory - normal and halo cells overlap:\n"
1555 <<
" - upper normal cell offset: " << m_levelOffsets[level_][1] <<
"\n"
1556 <<
" - lower halo cell offset: " << m_haloCellOffsetsLevel[level_][0] <<
"\n"
1557 <<
" - max. no of available cells: " << m_maxNoCells << endl;
1558 m_log << errorMsg.str();
1559 mTerm(1, AT_, errorMsg.str());
1562 if(m_levelOffsets[level_][1] > m_maxNoCells - 1) {
1563 stringstream errorMsg;
1564 errorMsg <<
"Not enough memory:\n"
1565 <<
" - upper cell offset: " << m_levelOffsets[level_][1] <<
"\n"
1566 <<
" - max. no of available cells: " << m_maxNoCells << endl;
1567 m_log << errorMsg.str();
1568 mTerm(1, AT_, errorMsg.str());
1600 MInt t_refineGrid = 0;
1601 if(level_ < m_minLevel) {
1602 NEW_SUB_TIMER_STATIC(t_rfnGrid,
"refine Grid", m_t_createInitialGrid);
1603 t_refineGrid = t_rfnGrid;
1604 }
else if(level_ < m_maxUniformRefinementLevel) {
1605 NEW_SUB_TIMER_STATIC(t_rfnGrid,
"refine Grid", m_t_createStartGrid);
1606 t_refineGrid = t_rfnGrid;
1609 RECORD_TIMER_START(t_refineGrid);
1612 m_log <<
" + refining halo grid on level " << level_ <<
": " << endl;
1613 outStream <<
" + refining halo grid on level " << level_ <<
": " << endl;
1615 m_log <<
" + refining grid on level " << level_ <<
": " << endl;
1616 outStream <<
" + refining grid on level " << level_ <<
": " << endl;
1621 MInt offsetLevelStart = offsets[level_ + 1][0];
1623 MInt diff = offsets[level_][1] - offsets[level_][0];
1626 for(
MInt i = offsets[level_][0]; i < offsets[level_][1]; i++) {
1627 MInt current = i - offsets[level_][0];
1630 if(diff > 100 && current % (diff / 100) == 0) {
1631 if(100 * current / diff < 11)
1632 outStream <<
"\b\b\b" << 100 * current / diff <<
"% ";
1634 outStream <<
"\b\b\b\b" << 100 * current / diff <<
"% ";
1639 if(level_ > m_minLevel && noDomains() > 1) {
1640 refineCell(m_cellIdLUT[i], &offsetLevelStart);
1642 refineCell(i, &offsetLevelStart);
1646 outStream <<
"\b\b\b\b\b 100% done." << endl;
1648 RECORD_TIMER_STOP(t_refineGrid);
1668 NEW_SUB_TIMER_STATIC(t_refineGridPatch,
"refine Grid", m_t_createComputationalGrid);
1669 RECORD_TIMER_START(t_refineGridPatch);
1672 m_log <<
" + refining halo grid on level " << level_ <<
": ";
1673 outStream <<
" + refining halo grid on level " << level_ <<
": ";
1675 m_log <<
" + refining grid on level " << level_ <<
": ";
1676 outStream <<
" + refining grid on level " << level_ <<
": ";
1681 MInt startchildId = offsets[level_ + 1][0];
1683 size_t diff = offsets[level_][1] - offsets[level_][0];
1686 for(
MInt i = offsets[level_][0]; i < offsets[level_][1]; i++) {
1688 if(level_ > m_minLevel && noDomains() > 1) {
1689 cellId = m_cellIdLUT[i];
1691 MInt current = i - offsets[level_][0];
1692 if(diff > 100 && current % (diff / 100) == 0) {
1693 if(100 * (
size_t)current / diff < 11)
1694 outStream <<
"\b\b\b" << 100 * (size_t)current / diff <<
"% ";
1696 outStream <<
"\b\b\b\b" << 100 * (size_t)current / diff <<
"% ";
1700 if(a_hasProperty(cellId, 5)) {
1701 MInt currentNoCells = (offsets[level_][1] - offsets[level_][0]) + m_maxNoChildren;
1702 if(currentNoCells > m_maxNoCells) {
1703 stringstream errorMsg;
1704 errorMsg <<
"Max. no. cells reached: " << m_maxNoCells << endl;
1705 m_log << errorMsg.str();
1706 mTerm(1, AT_, errorMsg.str());
1709 refineCell(cellId, &startchildId);
1713 outStream <<
"\b\b\b\b\b 100% done." << endl;
1715 RECORD_TIMER_STOP(t_refineGridPatch);
1738 RECORD_TIMER_START(m_t_createComputationalGrid);
1740 m_log <<
" createComputationalMultisolverGrid" << endl;
1743 for(
MInt l = m_maxUniformRefinementLevel; l < m_maxRfnmntLvl; l++) {
1745 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
1746 markLocalSolverRefinement(l, solver);
1750 concludeSolverRefinement(l);
1755 if(noDomains() > 1) {
1756 updateHaloOffsets(l, m_rfnCountHalos, m_rfnCountHalosDom);
1760 refineComputationalGrid(l);
1764 if(m_keepOutsideBndryCellChildren == 3) {
1765 if(noDomains() > 1) {
1766 mTerm(1, AT_,
"ERROR: keepOutsideBndryCellChildren in mode 3 is not implemented for parallel usage yet!!!");
1767 deleteCoarseSolidCellsParallel();
1769 deleteCoarseSolidCellsSerial();
1773 RECORD_TIMER_STOP(m_t_createComputationalGrid);
1782 m_rfnCountHalos = 0;
1783 if(noDomains() > 1) {
1784 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
1785 m_rfnCountHalosDom[dom] = 0;
1790 for(
MInt k = m_levelOffsets[gridLvl][0]; k < m_levelOffsets[gridLvl][1]; k++) {
1791 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
1792 if(a_isToRefineForSolver(k, solver) || a_noSolidLayer(k, solver) > 0) {
1794 a_hasProperty(k, 5) = 1;
1801 if(noDomains() > 1) {
1802 MInt lev_pos = 2 * (gridLvl - m_minLevel);
1803 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
1804 for(
MInt k = m_haloCellOffsets[dom][lev_pos]; k < m_haloCellOffsets[dom][lev_pos + 1]; k++) {
1805 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
1806 if(a_isToRefineForSolver(k, solver)) {
1808 m_rfnCountHalosDom[dom]++;
1809 a_hasProperty(k, 5) = 1;
1824 if(level_ < bp->maxUniformRefinementLevel) {
1825 markSolverForRefinement(level_, solver);
1828 if(refLevel < bp->noLocalPatchRfnLvls()) markPatchForSolverRefinement(level_, solver);
1829 if(refLevel < bp->noLocalBndRfnLvls) markBndForSolverRefinement(level_, solver);
1843 if(patchStr ==
"B") {
1844 markLocalBox(refLevel, patch, solver);
1845 }
else if(patchStr ==
"R") {
1846 markLocalRadius(refLevel, patch, solver);
1847 }
else if(patchStr ==
"C" || patchStr ==
"T") {
1848 markLocalCylinder(refLevel, patch, solver, patchStr);
1849 }
else if(patchStr ==
"O") {
1850 markLocalCone(refLevel, patch, solver);
1851 }
else if(patchStr ==
"H") {
1852 markLocalHat(refLevel, patch, solver);
1853 }
else if(patchStr ==
"S") {
1854 markLocalRectangleAngled(refLevel, patch, solver);
1855 }
else if(patchStr ==
"W") {
1856 markLocalCartesianWedge(refLevel, patch, solver);
1857 }
else if(patchStr ==
"A" || patchStr ==
"N") {
1858 markLocalSlicedCone(refLevel, patch, solver, patchStr);
1860 TERMM(1,
"Unknown patch type: '" + patchStr +
"'");
1873 m_log <<
" + running boundary refinement for solver " << solver << endl;
1890 dists(lvl, i) = ((
MInt)pow(2, refLevel)) * dists(lvl, i);
1912 distsStlUnits.
fill(F0);
1920 for(
MInt lvl = localRfnMaxLvl - 1; lvl >= localRfnMinLvl; lvl--) {
1921 distsStlUnits(lvl, i) = distsStlUnits(lvl + 1, i)
1925 constexpr MInt defaultSmoothDistance = 2;
1926 for(
MInt lvl = localRfnMinLvl - 1; lvl > -1; lvl--) {
1927 distsStlUnits(lvl, i) = distsStlUnits(lvl + 1, i)
1934 for(
MInt lvl = localRfnMaxLvl; lvl >= 0; lvl--)
1939 mTerm(1,
"no valid localBndRfnMethod");
1943 set<MInt> rfnBoundaryGroupDist;
1945 rfnBoundaryGroupDist.insert(dists(refLevel, bId));
1947 vector<vector<MInt>> rfnBoundaryGroupMemberIds(rfnBoundaryGroupDist.size(), vector<MInt>(0));
1950 set<MInt>::iterator setIt = rfnBoundaryGroupDist.find(dists(refLevel, bId));
1951 rfnBoundaryGroupMemberIds[distance(rfnBoundaryGroupDist.begin(), setIt)].push_back(bp->
localRfnBoundaryIds[bId]);
1954 m_log <<
" * refinement groups (distance: Ids)" << endl;
1956 for(
MInt gId = 0; gId < (
MInt)rfnBoundaryGroupDist.size(); gId++) {
1957 set<MInt>::iterator setIt = rfnBoundaryGroupDist.begin();
1958 advance(setIt, gId);
1959 if(*setIt == 0)
continue;
1961 m_log <<
" - group " << *setIt <<
" :";
1962 for(
MInt mId = 0; mId < (
MInt)rfnBoundaryGroupMemberIds[gId].size(); mId++) {
1963 m_log <<
" " << rfnBoundaryGroupMemberIds[gId][mId];
1969 propagateDistance(level_, *setIt, rfnBoundaryGroupMemberIds[gId], solver);
1973 markBndDistance(level_, solver);
1981 for(
MInt k = m_levelOffsets[level_][0]; k < m_levelOffsets[level_][1]; k++) {
1982 if(a_isInSolver(k, solver)) {
1983 a_isToRefineForSolver(k, solver) = 1;
1987 if(noDomains() > 1) {
1988 MInt lev_pos = 2 * (level_ - m_minLevel);
1989 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
1990 for(
MInt k = m_haloCellOffsets[dom][lev_pos]; k < m_haloCellOffsets[dom][lev_pos + 1]; k++) {
1991 if(a_isInSolver(k, solver)) {
1992 a_isToRefineForSolver(k, solver) = 1;
2003 RECORD_TIMER_START(m_t_finalizeGrid);
2007 if(m_checkGridLbValidity) {
2008 checkLBRefinementValidity();
2010 outStream <<
" + NOTE: Skipping mesh validity check for LB" << endl;
2011 m_log <<
" + NOTE: Skipping mesh validity check for LB" << endl;
2015 if(noDomains() > 1) {
2016 if(m_hasBeenLoadBalanced) {
2017 communicateHaloGlobalIds(m_maxRfnmntLvl);
2019 updateInterRankNeighbors();
2023 for(
MInt d = 0; d < noDomains(); d++) {
2024 m_noTotalCells += (
MLong)m_noCellsPerDomain[d];
2027 m_noTotalCells = (
MLong)m_noCells;
2028 reorderGlobalIdsDF();
2029 updateGlobalIdsReferences();
2032 RECORD_TIMER_STOP(m_t_finalizeGrid);
2057 MInt level_ = a_level(
id);
2058 const MInt childLevel = level_ + 1;
2059 const MFloat childCellLength = m_lengthOnLevel[childLevel];
2061 static const MFloat signStencil[8][3] = {{-F1, -F1, -F1}, {F1, -F1, -F1}, {-F1, F1, -F1}, {F1, F1, -F1},
2062 {-F1, -F1, F1}, {F1, -F1, F1}, {-F1, F1, F1}, {F1, F1, F1}};
2064 a_noChildren(
id) = 0;
2066 for(
MInt c = 0; c < m_maxNoChildren; c++) {
2068 for(
MInt i = 0; i < nDim; i++) {
2069 a_coordinate(*currentChildId, i) = a_coordinate(
id, i) + F1B2 * signStencil[c][i] * childCellLength;
2073 a_level(*currentChildId) = childLevel;
2074 a_parentId(*currentChildId) = (
MLong)
id;
2075 a_noChildren(*currentChildId) = 0;
2076 a_globalId(*currentChildId) = (
MLong)(*currentChildId);
2077 for(
MInt s = 0; s < m_noSolvers; s++) {
2078 a_noSolidLayer(*currentChildId, s) = -1;
2082 for(
MInt i = 0; i < 8; i++)
2083 a_hasProperty(*currentChildId, i) = 0;
2085 for(
MInt solver = 0; solver < m_noSolvers; solver++)
2086 a_isSolverBoundary(*currentChildId, solver) = 0;
2088 for(
MInt solver = 0; solver < m_noSolvers; solver++)
2089 a_isToRefineForSolver(*currentChildId, solver) = 0;
2095 for(
MInt solver = 0; solver < m_noSolvers; solver++)
2096 a_isInSolver(*currentChildId, solver) = a_isToRefineForSolver(
id, solver) ? 1 : 0;
2099 for(
MInt k = 0; k < m_maxNoChildren; k++)
2100 a_childId(*currentChildId, k) = -1;
2103 for(
MInt i = 0; i < nDim; i++) {
2104 a_neighborId(*currentChildId, i) = -1;
2105 a_neighborId(*currentChildId, i + nDim) = -1;
2109 if(a_hasProperty(
id, 1)) {
2110 a_hasProperty(*currentChildId, 1) = checkCellForCut(*currentChildId);
2111 if(a_hasProperty(*currentChildId, 1)) {
2112 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
2113 if(!a_isToRefineForSolver(
id, solver))
continue;
2114 for(
MInt srfc = 0; srfc < m_noBndIdsPerSolver[solver]; srfc++) {
2115 if(m_bndCutInfo[solver][srfc]) {
2116 a_isSolverBoundary(*currentChildId, solver) = 1;
2125 a_childId(
id, c) = *currentChildId;
2126 a_noChildren(
id) = a_noChildren(
id) + 1;
2129 (*currentChildId)++;
2152 return m_geometry->getCellIntersectingSurfaces(&a_coordinate(
id, 0), m_lengthOnLevel[a_level(
id) + 1], m_bndCutInfo);
2180 MInt t_refineGrid = 0;
2181 if(level_ < m_minLevel) {
2182 NEW_SUB_TIMER_STATIC(t_rfnGrid,
"find new neighborhood", m_t_createInitialGrid);
2183 t_refineGrid = t_rfnGrid;
2184 }
else if(level_ < m_maxUniformRefinementLevel) {
2185 NEW_SUB_TIMER_STATIC(t_rfnGrid,
"find new neighborhood", m_t_createStartGrid);
2186 t_refineGrid = t_rfnGrid;
2187 }
else if(level_ < m_maxRfnmntLvl) {
2188 NEW_SUB_TIMER_STATIC(t_rfnGrid,
"find new neighborhood", m_t_createComputationalGrid);
2189 t_refineGrid = t_rfnGrid;
2192 RECORD_TIMER_START(t_refineGrid);
2195 for(
MInt i = offsets[level_][0]; i < offsets[level_][1]; i++) {
2197 MLong* childIds = &a_childId(parent, 0);
2200 for(
MInt c = 0; c < m_maxNoChildren; c++) {
2201 if(childIds[c] < 0)
continue;
2205 for(
MInt dir = 0; dir < m_noNeighbors; dir++) {
2206 if(a_neighborId(child, dir) == -1) {
2208 if(nghInside3D[c][dir] >= 0) {
2209 a_neighborId(child, dir) = childIds[nghInside3D[c][dir]];
2212 const MInt chdir = (nDim == 3) ? nghAcrossCell3D[c][dir] : nghAcrossCell2D[c][dir];
2214 if(a_neighborId(parent, dir) >= 0 && a_childId((
MInt)a_neighborId(parent, dir), chdir) >= 0)
2215 a_neighborId(child, dir) = a_childId((
MInt)a_neighborId(parent, dir), chdir);
2222 RECORD_TIMER_STOP(t_refineGrid);
2248 for(
MInt i = offsets[level_][1] - 1; i >= offsets[level_][0]; i--)
2249 a_hasProperty(i, 6) = 0;
2251 for(
MInt i = offsets[level_][1] - 1; i >= offsets[level_][0]; i--) {
2253 if(a_hasProperty(i, 6))
continue;
2256 if(a_hasProperty(i, 1)) {
2257 a_hasProperty(i, 0) = 1;
2258 a_hasProperty(i, 6) = 1;
2263 if(pointIsInside(&a_coordinate(i, 0)) && !(a_hasProperty(i, 1))) {
2264 stack<MInt> fillStack;
2265 a_hasProperty(i, 0) = 1;
2266 a_hasProperty(i, 6) = 1;
2268 floodCells(&fillStack, 1);
2271 stack<MInt> fillStack;
2272 a_hasProperty(i, 0) = 0;
2273 a_hasProperty(i, 6) = 1;
2275 floodCells(&fillStack, 0);
2296 while(!fillStack->empty()) {
2297 MInt currentId = fillStack->top();
2300 for(
MInt n = 0; n < m_noNeighbors; n++)
2301 if(a_neighborId(currentId, n) >= 0) {
2302 MInt nghbr = (
MInt)a_neighborId(currentId, n);
2305 if(!(a_hasProperty(nghbr, 6))) {
2306 if(!(a_hasProperty(nghbr, 1))) {
2307 fillStack->push(nghbr);
2308 a_hasProperty(nghbr, 0) = marker;
2309 a_hasProperty(nghbr, 6) = 1;
2311 a_hasProperty(nghbr, 0) = 1;
2312 a_hasProperty(nghbr, 6) = 1;
2323 while(!fillStack->empty()) {
2324 MInt currentId = fillStack->top();
2327 for(
MInt n = 0; n < m_noNeighbors; n++)
2328 if(a_neighborId(currentId, n) >= 0) {
2329 MInt nghbr = (
MInt)a_neighborId(currentId, n);
2332 if(!(a_hasProperty(nghbr, 6))) {
2333 if(!(a_isSolverBoundary(nghbr, solver))) {
2334 fillStack->push(nghbr);
2335 a_isInSolver(nghbr, solver) = marker;
2336 a_hasProperty(nghbr, 6) = 1;
2338 a_isInSolver(nghbr, solver) = 1;
2339 a_hasProperty(nghbr, 6) = 1;
2373 MInt t_deleteOutsideCellsSerial = 0;
2374 if(level_ <= m_minLevel) {
2375 NEW_SUB_TIMER_STATIC(t_delSer,
"delete outside cells serial", m_t_createInitialGrid);
2376 t_deleteOutsideCellsSerial = t_delSer;
2377 }
else if(level_ <= m_maxUniformRefinementLevel) {
2378 NEW_SUB_TIMER_STATIC(t_delSer,
"delete outside cells serial", m_t_createStartGrid);
2379 t_deleteOutsideCellsSerial = t_delSer;
2380 }
else if(level_ <= m_maxRfnmntLvl) {
2381 NEW_SUB_TIMER_STATIC(t_delSer,
"delete outside cells serial", m_t_createComputationalGrid);
2382 t_deleteOutsideCellsSerial = t_delSer;
2385 RECORD_TIMER_START(t_deleteOutsideCellsSerial);
2387 MInt num = m_levelOffsets[level_][1] - m_levelOffsets[level_][0];
2389 m_log <<
" * detecting outside cells to delete:" << endl;
2390 outStream <<
" * detecting outside cells to delete:" << endl;
2393 markInsideOutside(m_levelOffsets, level_);
2396 if(m_cutOff && level_ >= m_minLevel) performCutOff(m_levelOffsets, level_);
2399 markSolverAffiliation(level_);
2402 if(m_keepOutsideBndryCellChildren) {
2403 keepOutsideBndryCellChildrenSerial(m_levelOffsets[level_], level_);
2406 if(m_keepOutsideBndryCellChildren == 3 && m_cutOff && level_ >= m_minLevel) {
2407 performCutOff(m_levelOffsets, level_,
true);
2412 for(
MInt i = m_levelOffsets[level_][1] - 1; i >= m_levelOffsets[level_][0]; i--) {
2423 MBool inSolidLayer =
false;
2424 for(
MInt s = 0; s < m_noSolvers; s++) {
2425 if(a_noSolidLayer(cell, s) >= 0) {
2426 inSolidLayer =
true;
2431 if(!(a_hasProperty(cell, 0)) && !(a_hasProperty(cell, 1)) && !inSolidLayer) {
2433 if(a_parentId(cell) > -1) {
2434 for(
MInt c = 0; c < m_maxNoChildren; c++)
2435 if(a_childId((
MInt)a_parentId(cell), c) == i) {
2436 a_childId((
MInt)a_parentId(cell), c) = -1;
2439 a_noChildren((
MInt)a_parentId(cell)) = a_noChildren((
MInt)a_parentId(cell)) - 1;
2443 for(
MInt dir = 0; dir < m_noNeighbors; dir++) {
2444 MInt dirNeighborId = (
MInt)a_neighborId(cell, dir);
2447 if(dirNeighborId >= 0) {
2449 a_neighborId(dirNeighborId, oppositeDirGrid[dir]) = -1;
2454 if(i != m_levelOffsets[level_][1] - 1) copyCell(m_levelOffsets[level_][1] - 1, i);
2455 m_levelOffsets[level_][1]--;
2459 m_noCells = m_levelOffsets[level_][1];
2461 m_log <<
" - outside cells deleted: " << num - (m_levelOffsets[level_][1] - m_levelOffsets[level_][0])
2463 m_log <<
" - new offsets: " << m_levelOffsets[level_][0] <<
" " << m_levelOffsets[level_][1] << endl;
2464 outStream <<
" - outside cells deleted: " << num - (m_levelOffsets[level_][1] - m_levelOffsets[level_][0])
2466 outStream <<
" - new offsets: " << m_levelOffsets[level_][0] <<
" " << m_levelOffsets[level_][1] << endl;
2468 RECORD_TIMER_STOP(t_deleteOutsideCellsSerial);
2487 m_log <<
" * detecting coarse solid cells to delete:" << endl;
2488 cout <<
" * detecting coarse solid cells to delete:" << endl;
2490 MInt noDeletedCellsTotal = 0;
2492 for(
MInt level = m_maxRfnmntLvl - 1; level >= m_minLevel; level--) {
2493 MInt noDeletedCellsPerLevel = 0;
2494 cout <<
"m_levelOffsets[level][0] " << m_levelOffsets[level][0] <<
" m_levelOffsets[level][1] "
2495 << m_levelOffsets[level][1] << endl;
2496 for(
MInt cell = m_levelOffsets[level][1] - 1; cell >= m_levelOffsets[level][0]; cell--) {
2497 if(!(a_hasProperty(cell, 0)) && !(a_hasProperty(cell, 1)) && a_noChildren(cell) == 0) {
2499 if(a_parentId(cell) > -1) {
2500 for(
MInt c = 0; c < m_maxNoChildren; c++)
2501 if(a_childId((
MInt)a_parentId(cell), c) == cell) {
2502 a_childId((
MInt)a_parentId(cell), c) = -1;
2505 a_noChildren((
MInt)a_parentId(cell)) = a_noChildren((
MInt)a_parentId(cell)) - 1;
2508 for(
MInt dir = 0; dir < m_noNeighbors; dir++) {
2509 MInt dirNeighborId = (
MInt)a_neighborId(cell, dir);
2511 if(dirNeighborId >= 0) {
2513 a_neighborId(dirNeighborId, oppositeDirGrid[dir]) = -1;
2517 if(cell != m_levelOffsets[level][1] - 1) copyCell(m_levelOffsets[level][1] - 1, cell);
2518 m_levelOffsets[level][1]--;
2519 noDeletedCellsPerLevel++;
2522 noDeletedCellsTotal += noDeletedCellsPerLevel;
2523 for(
MInt re = level + 1; re <= m_maxRfnmntLvl; re++) {
2524 for(
MInt i = 0; i < noDeletedCellsPerLevel; i++) {
2525 copyCell(m_levelOffsets[re][1] - 1 - i, m_levelOffsets[re][0] - 1 - i);
2527 m_levelOffsets[re][0] = m_levelOffsets[re][0] - noDeletedCellsPerLevel;
2528 m_levelOffsets[re][1] = m_levelOffsets[re][1] - noDeletedCellsPerLevel;
2531 m_noCells = m_levelOffsets[m_maxRfnmntLvl][1];
2533 m_log <<
" - coarse solid cells deleted: " << noDeletedCellsTotal << endl;
2534 cout <<
" - coarse solid cells deleted: " << noDeletedCellsTotal << endl;
2536 for(
MInt j = m_minLevel; j <= m_maxRfnmntLvl; j++) {
2537 m_log <<
" Level: " << j <<
"- new offsets: " << m_levelOffsets[j][0] <<
" " << m_levelOffsets[j][1]
2539 cout <<
" Level: " << j <<
"- new offsets: " << m_levelOffsets[j][0] <<
" " << m_levelOffsets[j][1] << endl;
2560 auto neighborExists = [&](
MInt haloCellId) {
2561 for(
MInt n = 0; n < m_noNeighbors; n++) {
2562 if(a_neighborId(haloCellId, n) >= 0 && a_neighborId(haloCellId, n) < m_noCells) {
2569 for(
MInt j = m_minLevel; j <= m_maxRfnmntLvl; j++) {
2570 m_log <<
" Level: " << j <<
"- old offsets: " << m_levelOffsets[j][0] <<
" " << m_levelOffsets[j][1]
2572 cout <<
" Level: " << j <<
"- old offsets: " << m_levelOffsets[j][0] <<
" " << m_levelOffsets[j][1] << endl;
2575 for(
MInt j = m_minLevel; j <= m_maxRfnmntLvl; j++) {
2576 MInt levPos = 2 * (j - m_minLevel);
2577 for(
MInt dom = m_noNeighborDomains - 1; dom >= 0; dom--) {
2578 m_log <<
" Level: " << j <<
"- old offsets: " << m_haloCellOffsets[dom][levPos + 1] <<
" "
2579 << m_haloCellOffsets[dom][levPos] << endl;
2580 cout <<
" Level: " << j <<
"- old offsets: " << m_haloCellOffsets[dom][levPos + 1] <<
" "
2581 << m_haloCellOffsets[dom][levPos] << endl;
2584 m_log <<
" * detecting coarse solid cells to delete:" << endl;
2585 cout <<
" * detecting coarse solid cells to delete:" << endl;
2587 MInt noDeletedCellsTotal = 0;
2588 MInt noDeletedHalosTotal = 0;
2589 for(
MInt level = m_maxRfnmntLvl - 1; level >= m_minLevel; level--) {
2590 MInt noDeletedCellsPerLevel = 0;
2592 for(
MInt cell = m_levelOffsets[level][1] - 1; cell >= m_levelOffsets[level][0]; cell--) {
2593 if(!(a_hasProperty(cell, 0)) && !(a_hasProperty(cell, 1)) && a_noChildren(cell) == 0) {
2595 if(a_parentId(cell) > -1) {
2596 for(
MInt c = 0; c < m_maxNoChildren; c++)
2597 if(a_childId((
MInt)a_parentId(cell), c) == cell) {
2598 a_childId((
MInt)a_parentId(cell), c) = -1;
2601 a_noChildren((
MInt)a_parentId(cell)) = a_noChildren((
MInt)a_parentId(cell)) - 1;
2604 for(
MInt dir = 0; dir < m_noNeighbors; dir++) {
2605 MInt dirNeighborId = (
MInt)a_neighborId(cell, dir);
2607 if(dirNeighborId >= 0) {
2609 a_neighborId(dirNeighborId, oppositeDirGrid[dir]) = -1;
2613 if(cell != m_levelOffsets[level][1] - 1) copyCell(m_levelOffsets[level][1] - 1, cell);
2614 m_levelOffsets[level][1]--;
2615 noDeletedCellsPerLevel++;
2618 noDeletedCellsTotal += noDeletedCellsPerLevel;
2619 for(
MInt re = level + 1; re <= m_maxRfnmntLvl; re++) {
2620 for(
MInt i = 0; i < noDeletedCellsPerLevel; i++) {
2621 copyCell(m_levelOffsets[re][1] - 1 - i, m_levelOffsets[re][0] - 1 - i);
2623 m_levelOffsets[re][0] = m_levelOffsets[re][0] - noDeletedCellsPerLevel;
2624 m_levelOffsets[re][1] = m_levelOffsets[re][1] - noDeletedCellsPerLevel;
2627 const MInt levelPos = 2 * (level - m_minLevel);
2628 MInt noDeletedHalosPerLevel = 0;
2630 for(
MInt dom = m_noNeighborDomains - 1; dom >= 0; dom--) {
2631 for(
MInt haloCellId = m_haloCellOffsets[dom][levelPos + 1] - 1; haloCellId >= m_haloCellOffsets[dom][levelPos];
2634 if(!a_hasProperty(haloCellId, 7)) {
2637 if(a_hasProperty(haloCellId, 0) || a_hasProperty(haloCellId, 1) || (a_noSolidLayer(haloCellId, 0) > 0)) {
2638 if(neighborExists(haloCellId)) {
2644 cout <<
" x-dir " << a_coordinate(haloCellId, 0) <<
" y-dir " << a_coordinate(haloCellId, 1) <<
" z-dir "
2645 << a_coordinate(haloCellId, 2) << endl;
2646 a_hasProperty(haloCellId, 7) = 1;
2647 deleteCellReferences(haloCellId, haloCellId);
2648 noDeletedHalosPerLevel++;
2652 while(m_haloCellOffsets[dom][levelPos] < haloCellId && a_hasProperty(m_haloCellOffsets[dom][levelPos], 7)) {
2653 m_haloCellOffsets[dom][levelPos]++;
2657 if(haloCellId > m_haloCellOffsets[dom][levelPos]) {
2658 copyCell(m_haloCellOffsets[dom][levelPos], haloCellId);
2661 a_hasProperty(m_haloCellOffsets[dom][levelPos], 7) = 1;
2668 m_haloCellOffsets[dom][levelPos]++;
2673 m_haloCellOffsets[dom - 1][levelPos + 1] = m_haloCellOffsets[dom][levelPos];
2676 noDeletedHalosTotal += noDeletedHalosPerLevel;
2678 for(
MInt re = level + 1; re <= m_maxRfnmntLvl; re++) {
2679 const MInt levPos = 2 * (re - m_minLevel);
2680 for(
MInt dom = m_noNeighborDomains - 1; dom >= 0; dom--) {
2681 for(
MInt i = m_haloCellOffsets[dom][levPos + 1] - 1; i >= m_haloCellOffsets[dom][levPos]; i--) {
2682 copyCell(i, i + noDeletedHalosPerLevel);
2684 m_haloCellOffsets[dom][levPos] = m_haloCellOffsets[dom][levPos] + noDeletedCellsPerLevel;
2685 m_haloCellOffsets[dom][levPos + 1] = m_haloCellOffsets[dom][levPos + 1] + noDeletedCellsPerLevel;
2689 m_noCells = m_levelOffsets[m_maxRfnmntLvl][1];
2691 m_log <<
" - coarse solid cells deleted: " << noDeletedCellsTotal << endl;
2692 cout <<
" - coarse solid cells deleted: " << noDeletedCellsTotal << endl;
2694 for(
MInt j = m_minLevel; j <= m_maxRfnmntLvl; j++) {
2695 m_log <<
" Level: " << j <<
"- new offsets: " << m_levelOffsets[j][0] <<
" " << m_levelOffsets[j][1]
2697 cout <<
" Level: " << j <<
"- new offsets: " << m_levelOffsets[j][0] <<
" " << m_levelOffsets[j][1] << endl;
2699 m_log <<
" - coarse solid halos deleted: " << noDeletedHalosTotal << endl;
2700 cout <<
" - coarse solid halos deleted: " << noDeletedHalosTotal << endl;
2702 for(
MInt j = m_minLevel; j <= m_maxRfnmntLvl; j++) {
2703 MInt levPos = 2 * (j - m_minLevel);
2704 for(
MInt dom = m_noNeighborDomains - 1; dom >= 0; dom--) {
2705 m_log <<
" Level: " << j <<
"- new offsets: " << m_haloCellOffsets[dom][levPos + 1] <<
" "
2706 << m_haloCellOffsets[dom][levPos] << endl;
2707 cout <<
" Level: " << j <<
"- new offsets: " << m_haloCellOffsets[dom][levPos + 1] <<
" "
2708 << m_haloCellOffsets[dom][levPos] << endl;
2716 if(m_keepOutsideBndryCellChildren == 1) {
2719 for(
MInt cellId = offsets[0]; cellId < offsets[1]; cellId++) {
2720 MInt pId = (
MInt)a_parentId(cellId);
2721 for(
MInt n = 0; n < m_noNeighbors; n++) {
2722 MInt nId = (
MInt)a_neighborId(pId, n);
2723 if(nId < 0)
continue;
2724 if(!(a_hasProperty(nId, 1)))
continue;
2725 if(a_noChildren(nId) > 0)
continue;
2726 a_hasProperty(cellId, 0) = 1;
2730 }
else if(m_keepOutsideBndryCellChildren == 2) {
2733 for(
MInt cellId = offsets[0]; cellId < offsets[1]; cellId++) {
2734 MInt pId = (
MInt)a_parentId(cellId);
2735 if(a_hasProperty(pId, 1)) a_hasProperty(cellId, 0) = 1;
2737 }
else if(m_keepOutsideBndryCellChildren == 3) {
2738#ifdef MAIA_EXTRA_DEBUG
2746 for(
MInt s = 0; s < m_noSolvers; s++) {
2747#ifdef MAIA_EXTRA_DEBUG
2754 for(
MInt cellId = offsets[0]; cellId < offsets[1]; cellId++) {
2755 if(a_hasProperty(cellId, 0) && !a_hasProperty(cellId, 1)) {
2756 a_noSolidLayer(cellId, s) = -1;
2757#ifdef MAIA_EXTRA_DEBUG
2761 if(a_hasProperty(cellId, 1)) {
2762 a_noSolidLayer(cellId, s) = m_noSolidLayer[s] * 2;
2763#ifdef MAIA_EXTRA_DEBUG
2767 if(!a_hasProperty(cellId, 0) && !a_hasProperty(cellId, 1)) {
2768 a_noSolidLayer(cellId, s) = m_noSolidLayer[s] * 2;
2769#ifdef MAIA_EXTRA_DEBUG
2774#ifdef MAIA_EXTRA_DEBUG
2775 cout << s <<
" FLUID " << FLUID <<
" bndry " << SOLID0 <<
" outside " << SOLID1 << endl;
2778 for(
MInt cellId = offsets[0]; cellId < offsets[1]; cellId++) {
2779 if(!a_hasProperty(cellId, 1))
continue;
2780 createSolidCellLayer(cellId, 0, s);
2785 for(
MInt s = 0; s < m_noSolvers; s++) {
2786#ifdef MAIA_EXTRA_DEBUG
2795 for(
MInt cellId = offsets[0]; cellId < offsets[1]; cellId++) {
2796 if(a_noSolidLayer(cellId, s) > m_noSolidLayer[s]) {
2797 a_noSolidLayer(cellId, s) = -1;
2800#ifdef MAIA_EXTRA_DEBUG
2801 if(a_noSolidLayer(cellId, s) > m_noSolidLayer[s]) DELETE++;
2802 if(a_noSolidLayer(cellId, s) == -1) FLUID++;
2803 if(a_noSolidLayer(cellId, s) == 0) SOLID0++;
2804 if(a_noSolidLayer(cellId, s) == 1) SOLID1++;
2807#ifdef MAIA_EXTRA_DEBUG
2808 cout << s <<
" FLUID " << FLUID <<
" bndry " << SOLID0 <<
" SOLID1 " << SOLID1 <<
" TODELETE " << DELETE << endl;
2811 for(
MInt cellId = m_levelOffsets[level_][0]; cellId < m_levelOffsets[level_][1]; cellId++) {
2812 for(
MInt s = 0; s < m_noSolvers; s++) {
2813 if(a_noSolidLayer(cellId, s) >= 0) {
2814 a_isToRefineForSolver(cellId, s) = 1;
2815 a_isInSolver(cellId, s) = 1;
2820 mTerm(1, AT_,
"unknown keepOutsideBndryCellChildren option");
2826 static constexpr MInt nghborStencil3d[26][3] = {
2827 {0, -1, -1}, {1, -1, -1}, {2, -1, -1}, {3, -1, -1}, {4, -1, -1}, {5, -1, -1}, {0, 2, -1}, {0, 3, -1}, {0, 4, -1},
2828 {0, 5, -1}, {1, 2, -1}, {1, 3, -1}, {1, 4, -1}, {1, 5, -1}, {2, 4, -1}, {2, 5, -1}, {3, 4, -1}, {3, 5, -1},
2829 {0, 2, 4}, {0, 2, 5}, {0, 3, 4}, {0, 3, 5}, {1, 2, 4}, {1, 2, 5}, {1, 3, 4}, {1, 3, 5}};
2831 static constexpr MInt nghborStencil2d[26][3] = {
2832 {0, -1, -1}, {1, -1, -1}, {2, -1, -1}, {3, -1, -1}, {0, 2, -1}, {1, 3, -1}, {2, 1, -1},
2833 {3, 0, -1}, {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1},
2834 {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1},
2835 {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}};
2837 IF_CONSTEXPR(nDim == 3)
return nghborStencil3d[neighbor][dir];
2838 return nghborStencil2d[neighbor][dir];
2845 MInt totalNoNeighbors = (nDim == 3) ? 26 : 8;
2846 if(a_noSolidLayer(cellId, solver) > layer) {
2847 a_noSolidLayer(cellId, solver) = layer;
2849 if(layer < m_noSolidLayer[solver]) {
2850 for(
MInt n = 0; n < totalNoNeighbors; n++) {
2852 MInt nghborId = cellId;
2853 for(
MInt d = 0; d < nDim; d++) {
2854 if(nghborStencil(n, d) == -1)
break;
2855 nghborId = (
MInt)a_neighborId(nghborId, nghborStencil(n, d));
2856 if(nghborId == -1)
break;
2858 if(nghborId == -1)
continue;
2861 createSolidCellLayer(nghborId, layer + 1, solver);
2885 m_log <<
" - performing cut-off on level " << level_ <<
" with the following options: " << endl;
2887 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
2889 if(((bp->
cutOff == 1) && (level_ == m_minLevel)) || ((bp->
cutOff == 2) && (level_ <= m_minLevel))
2890 || ((bp->
cutOff == 3) && (level_ >= m_minLevel)) || (bp->
cutOff == 4)) {
2891 m_log <<
" - solver " << solver << endl;
2896 m_log <<
" : plane point: ";
2897 for(
MInt d = 0; d < nDim; d++) {
2901 m_log <<
" : normal: ";
2902 for(
MInt d = 0; d < nDim; d++) {
2906 m_log <<
" : layers: ";
2910 m_log <<
" : minimal point: ";
2911 for(
MInt d = 0; d < nDim; d++) {
2915 m_log <<
" : layers: ";
2916 for(
MInt d = 0; d < nDim; d++) {
2920 m_log <<
" : maximal point: ";
2921 for(
MInt d = 0; d < nDim; d++) {
2925 m_log <<
" : layers: ";
2926 for(
MInt d = 0; d < nDim; d++) {
2931 m_log <<
" : minimal point: ";
2932 for(
MInt d = 0; d < nDim; d++) {
2936 m_log <<
" : layers: ";
2937 for(
MInt d = 0; d < nDim; d++) {
2941 m_log <<
" : maximal point: ";
2942 for(
MInt d = 0; d < nDim; d++) {
2946 m_log <<
" : layers: ";
2947 for(
MInt d = 0; d < nDim; d++) {
2952 m_log <<
" : rot axis: ";
2953 for(
MInt d = 0; d < 2; d++) {
2957 m_log <<
" : rot angle: ";
2960 m_log <<
" : rot axis case: ";
2963 m_log <<
" : layers: ";
2970 for(
MInt i = offsets[level_][0]; i < offsets[level_][1]; i++) {
2972 if(!a_isInSolver(i, solver))
continue;
2975 if(!deleteMode && a_hasProperty(i, 0) == 0)
continue;
2978 MFloat* coords = &a_coordinate(i, 0);
2979 if(level_ > m_minLevel) coords = &a_coordinate((
MInt)a_parentId(i), 0);
2980 if(level_ < m_minLevel) preCut = 1;
2988 for(
MInt d = 0; d < nDim; d++) {
2993 if((s / sqrt(n)) < -(bp->
cutOffNmbrLayers[c][0] + preCut) * m_lengthOnLevel[level_]) {
2994 keep = keep &&
false;
2998 for(
MInt d = 0; d < nDim; d++)
3003 keep = keep &&
false;
3013 + m_lengthOnLevel[level_] * (bp->
cutOffNmbrLayers[c][1 + nDim] + preCut)) {
3014 keep = keep &&
false;
3016 }
else if(nDim == 3) {
3028 + m_lengthOnLevel[level_] * (bp->
cutOffNmbrLayers[c][2 + nDim] + preCut)) {
3029 keep = keep &&
false;
3033 MFloat cornerStencil[8][3] = {{1, 1, 1}, {1, -1, 1}, {-1, 1, 1}, {-1, -1, 1},
3034 {1, 1, -1}, {1, -1, -1}, {-1, 1, -1}, {-1, -1, -1}};
3036 MFloat cellLength = m_lengthOnLevel[level_ + 1];
3037 if(level_ > m_minLevel)
continue;
3040 center[0] = coords[0];
3049 normal[1] = sin(phi);
3050 normal[2] = cos(phi);
3053 for(
MInt d = 0; d < nDim; d++) {
3054 s += (coords[d] - center[d]) * normal[d];
3055 n +=
POW2(normal[d]);
3058 if(s / sqrt(n) < -(bp->
cutOffNmbrLayers[c][0] + preCut) * m_lengthOnLevel[level_]) {
3059 keep = keep &&
false;
3061 if(keep ==
false)
break;
3065 MFloat sgn[2] = {-1.0, 1.0};
3066 for(
MInt p = 0; p < 2; p++) {
3067 MFloat angle = phi + (sgn[p] * dAlpha / 2.0);
3068 if(angle < F0) angle = 2 * PI + angle;
3069 if(angle > 2 * PI) angle = angle - (2 * PI);
3071 normal[1] = -F1 * sgn[p] * cos(angle);
3072 normal[2] = sgn[p] * sin(angle);
3075 for(
MInt corn = 0; corn <
IPOW2(nDim); corn++) {
3077 for(
MInt d = 0; d < nDim; d++) {
3078 dummyCoords[d] = coords[d] + cornerStencil[corn][d] * cellLength;
3082 for(
MInt d = 0; d < nDim; d++) {
3083 s += (dummyCoords[d] - center[d]) * normal[d];
3084 n +=
POW2(normal[d]);
3086 if((s / sqrt(n)) < -(bp->
cutOffNmbrLayers[c][0] + preCut) * m_lengthOnLevel[level_]) {
3090 if(cnt >=
IPOW2(nDim)) {
3091 keep = keep &&
false;
3099 a_isInSolver(i, solver) = 0;
3101 a_noSolidLayer(i, solver) = -1;
3103 if(solver == m_noSolvers - 1) {
3105 for(
MInt s = 0; s < m_noSolvers; s++) {
3106 if(a_noSolidLayer(i, s) > 0) {
3112 a_hasProperty(i, 0) =
false;
3113 a_hasProperty(i, 1) =
false;
3145 for(
MInt dir = 0; dir < m_noNeighbors; dir++) {
3146 MInt dirNeighborId = (
MInt)a_neighborId(cell, dir);
3149 if(dirNeighborId >= 0) a_neighborId(dirNeighborId, oppositeDirGrid[dir]) = -1;
3153 if(a_parentId(cell) >= 0) {
3154 MInt parent = (
MInt)a_parentId(cell);
3155 for(
MInt c = 0; c < m_maxNoChildren; c++)
3156 if((
MInt)a_childId((
MInt)parent, c) == pos) a_childId((
MInt)parent, c) = -1;
3158 a_noChildren((
MInt)parent) = a_noChildren((
MInt)parent) - 1;
3188 MInt t_deleteOutsideCellsParallel = 0;
3189 if(level_ <= m_maxUniformRefinementLevel) {
3190 NEW_SUB_TIMER_STATIC(t_delPar,
"delete outside cells parallel", m_t_createStartGrid);
3191 t_deleteOutsideCellsParallel = t_delPar;
3192 }
else if(level_ <= m_maxRfnmntLvl) {
3193 NEW_SUB_TIMER_STATIC(t_delPar,
"delete outside cells parallel", m_t_createComputationalGrid);
3194 t_deleteOutsideCellsParallel = t_delPar;
3198 RECORD_TIMER_START(t_deleteOutsideCellsParallel);
3200 m_log <<
" * detecting outside cells to delete:" << endl;
3201 outStream <<
" * detecting outside cells to delete:" << endl;
3204 markInsideOutside(m_levelOffsets, level_);
3205 markInsideOutside(m_haloCellOffsetsLevel, level_);
3208 if(m_cutOff && level_ >= m_minLevel) {
3209 performCutOff(m_levelOffsets, level_);
3210 performCutOff(m_haloCellOffsetsLevel, level_);
3214 markSolverAffiliation(level_);
3217 const MInt levelPos = 2 * (level_ - m_minLevel);
3218 const MInt num = m_levelOffsets[level_][1] - m_levelOffsets[level_][0];
3219 MInt noDeletedCells = 0;
3222 if(m_keepOutsideBndryCellChildren) keepOutsideBndryCellChildrenParallel(level_);
3224 const MInt numHalo = m_haloCellOffsetsLevel[level_][1] - m_haloCellOffsetsLevel[level_][0];
3226 for(
MInt cellId = m_levelOffsets[level_][0]; cellId < m_levelOffsets[level_][1]; cellId++) {
3227 MBool anySolver =
false;
3228 for(
MInt s = 0; s < m_noSolvers; s++) {
3229 if(a_noSolidLayer(cellId, s) > 0) {
3236 if(!a_hasProperty(cellId, 0) && !a_hasProperty(cellId, 1) && !anySolver) {
3238 if(!a_hasProperty(cellId, 7)) {
3239 a_hasProperty(cellId, 7) = 1;
3240 deleteCellReferences(cellId, cellId);
3246 m_levelOffsets[level_][1]--;
3247 }
while(m_levelOffsets[level_][1] > cellId && a_hasProperty(m_levelOffsets[level_][1], 7));
3250 if(cellId < m_levelOffsets[level_][1]) {
3251 copyCell(m_levelOffsets[level_][1], cellId);
3254 a_hasProperty(m_levelOffsets[level_][1], 7) = 1;
3261 m_noCells -= noDeletedCells;
3263 m_log <<
" =deleted " << noDeletedCells <<
" cells" << endl;
3264 outStream <<
" =deleted " << noDeletedCells <<
" cells" << endl;
3267 m_log <<
" - halo cell deletion:" << endl;
3268 outStream <<
" - halo cell deletion:" << endl;
3269 m_log <<
" = outside halo cells per domain deleted [new offsets]:" << endl;
3270 outStream <<
" = outside halo cells per domain deleted [new offsets]:" << endl;
3272 MInt noDeletedHalos = 0;
3275 auto neighborExists = [&](
MInt haloCellId) {
3276 for(
MInt n = 0; n < m_noNeighbors; n++) {
3277 if(a_neighborId(haloCellId, n) >= 0 && a_neighborId(haloCellId, n) < m_noCells) {
3284 for(
MInt dom = m_noNeighborDomains - 1; dom >= 0; dom--) {
3285 for(
MInt haloCellId = m_haloCellOffsets[dom][levelPos + 1] - 1; haloCellId >= m_haloCellOffsets[dom][levelPos];
3288 if(!a_hasProperty(haloCellId, 7)) {
3291 if(a_hasProperty(haloCellId, 0) || a_hasProperty(haloCellId, 1) || (a_noSolidLayer(haloCellId, 0) > 0)) {
3292 if(neighborExists(haloCellId)) {
3298 a_hasProperty(haloCellId, 7) = 1;
3299 deleteCellReferences(haloCellId, haloCellId);
3304 while(m_haloCellOffsets[dom][levelPos] < haloCellId && a_hasProperty(m_haloCellOffsets[dom][levelPos], 7)) {
3305 m_haloCellOffsets[dom][levelPos]++;
3309 if(haloCellId > m_haloCellOffsets[dom][levelPos]) {
3310 copyCell(m_haloCellOffsets[dom][levelPos], haloCellId);
3313 a_hasProperty(m_haloCellOffsets[dom][levelPos], 7) = 1;
3320 m_haloCellOffsets[dom][levelPos]++;
3325 m_haloCellOffsets[dom - 1][levelPos + 1] = m_haloCellOffsets[dom][levelPos];
3328 m_log <<
" . " << m_neighborDomains[dom] <<
": "
3329 <<
" [" << m_haloCellOffsets[dom][levelPos] <<
" " << m_haloCellOffsets[dom][levelPos + 1] <<
"]" << endl;
3330 outStream <<
" . " << m_neighborDomains[dom] <<
": "
3331 <<
" [" << m_haloCellOffsets[dom][levelPos] <<
" " << m_haloCellOffsets[dom][levelPos + 1] <<
"]" << endl;
3335 m_haloCellOffsetsLevel[level_][0] += noDeletedHalos;
3336 m_noTotalHaloCells -= noDeletedHalos;
3337 m_noHaloCellsOnLevel[level_] -= noDeletedHalos;
3342 map<MLong, MInt> lut;
3343 for(
MInt cellId = m_levelOffsets[level_][0]; cellId < m_levelOffsets[level_][1]; cellId++) {
3344 lut.insert(make_pair(a_globalId(cellId), cellId));
3346 for(
MInt cellId = m_haloCellOffsets[0][levelPos]; cellId < m_haloCellOffsets[m_noNeighborDomains - 1][levelPos + 1];
3348 lut.insert(make_pair(a_globalId(cellId), cellId));
3352 auto lutIt = lut.begin();
3353 for(
MInt cellId = m_levelOffsets[level_][0]; cellId < m_levelOffsets[level_][1]; cellId++) {
3354 m_cellIdLUT.insert(make_pair(cellId, lutIt->second));
3357 for(
MInt cellId = m_haloCellOffsets[0][levelPos]; cellId < m_haloCellOffsets[m_noNeighborDomains - 1][levelPos + 1];
3359 m_cellIdLUT.insert(make_pair(cellId, lutIt->second));
3363 m_log <<
" = outside and unreferenced halo cells deleted [deleted]: "
3364 << numHalo - (m_haloCellOffsetsLevel[level_][1] - m_haloCellOffsetsLevel[level_][0]) <<
" [" << noDeletedHalos
3366 m_log <<
" = new halo offsets: " << m_haloCellOffsetsLevel[level_][0] <<
" "
3367 << m_haloCellOffsetsLevel[level_][1] << endl;
3368 m_log <<
" = new halo cells per domain on this level " << level_ <<
":" << endl;
3370 outStream <<
" = outside and unreferenced halo cells deleted [deleted]: "
3371 << numHalo - (m_haloCellOffsetsLevel[level_][1] - m_haloCellOffsetsLevel[level_][0]) <<
" ["
3372 << noDeletedHalos <<
"]" << endl;
3373 outStream <<
" = new halo offsets: " << m_haloCellOffsetsLevel[level_][0] <<
" "
3374 << m_haloCellOffsetsLevel[level_][1] << endl;
3375 outStream <<
" = new halo cells per domain on this level " << level_ <<
":" << endl;
3377 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
3378 m_log <<
" . " << m_neighborDomains[dom] <<
" "
3379 << m_haloCellOffsets[dom][levelPos + 1] - m_haloCellOffsets[dom][levelPos] << endl;
3381 outStream <<
" . " << m_neighborDomains[dom] <<
" "
3382 << m_haloCellOffsets[dom][levelPos + 1] - m_haloCellOffsets[dom][levelPos] << endl;
3385 m_log <<
" - outside cells deleted: " << num - (m_levelOffsets[level_][1] - m_levelOffsets[level_][0])
3387 m_log <<
" = new offsets: " << m_levelOffsets[level_][0] <<
" " << m_levelOffsets[level_][1] << endl;
3389 outStream <<
" - outside cells deleted: " << num - (m_levelOffsets[level_][1] - m_levelOffsets[level_][0])
3391 outStream <<
" = new offsets: " << m_levelOffsets[level_][0] <<
" " << m_levelOffsets[level_][1] << endl;
3393 RECORD_TIMER_STOP(t_deleteOutsideCellsParallel);
3411 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
3412 excludeInsideOutside(m_levelOffsets, level_, solver);
3413 if(noDomains() > 1) {
3414 excludeInsideOutside(m_haloCellOffsetsLevel, level_, solver);
3416 markInsideOutside(m_levelOffsets, level_, solver);
3417 if(noDomains() > 1) {
3418 markInsideOutside(m_haloCellOffsetsLevel, level_, solver);
3422 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
3424 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
3425 if(a_isInSolver(i, solver)) {
3431 a_hasProperty(i, 0) = 0;
3432 a_hasProperty(i, 1) = 0;
3436 if(noDomains() > 1) {
3437 MInt lev_pos = 2 * (level_ - m_minLevel);
3439 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
3440 for(
MInt i = m_haloCellOffsets[dom][lev_pos]; i < m_haloCellOffsets[dom][lev_pos + 1]; i++) {
3442 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
3443 if(a_isInSolver(i, solver)) {
3449 a_hasProperty(i, 0) = 0;
3450 a_hasProperty(i, 1) = 0;
3460 if(m_keepOutsideBndryCellChildren == 1) {
3461 keepOutsideBndryCellChildrenSerial(m_levelOffsets[level_], level_);
3463 const MInt levelPos = 2 * (level_ - m_minLevel);
3466 auto neighborExists = [&](
MInt haloCellId) {
3467 for(
MInt n = 0; n < m_noNeighbors; n++) {
3468 if(a_neighborId(haloCellId, n) >= 0 && a_neighborId(haloCellId, n) < m_noCells) {
3476 MInt noDeletedHalos = 0;
3478 for(
MInt dom = m_noNeighborDomains - 1; dom >= 0; dom--) {
3479 for(
MInt haloCellId = m_haloCellOffsets[dom][levelPos + 1] - 1; haloCellId >= m_haloCellOffsets[dom][levelPos];
3482 if(!a_hasProperty(haloCellId, 7)) {
3484 if(neighborExists(haloCellId)) {
3489 a_hasProperty(haloCellId, 7) = 1;
3490 deleteCellReferences(haloCellId, haloCellId);
3495 while(m_haloCellOffsets[dom][levelPos] < haloCellId && a_hasProperty(m_haloCellOffsets[dom][levelPos], 7)) {
3496 m_haloCellOffsets[dom][levelPos]++;
3500 if(haloCellId > m_haloCellOffsets[dom][levelPos]) {
3501 copyCell(m_haloCellOffsets[dom][levelPos], haloCellId);
3504 a_hasProperty(m_haloCellOffsets[dom][levelPos], 7) = 1;
3511 m_haloCellOffsets[dom][levelPos]++;
3516 m_haloCellOffsets[dom - 1][levelPos + 1] = m_haloCellOffsets[dom][levelPos];
3521 m_haloCellOffsetsLevel[level_][0] += noDeletedHalos;
3522 m_noTotalHaloCells -= noDeletedHalos;
3523 m_noHaloCellsOnLevel[level_] -= noDeletedHalos;
3526 map<MInt, MInt> lut;
3527 map<MInt, MInt> LUT;
3528 for(
MInt cellId = m_haloCellOffsets[0][levelPos]; cellId < m_haloCellOffsets[m_noNeighborDomains - 1][levelPos + 1];
3530 lut.insert(make_pair(
static_cast<MInt>(a_globalId(cellId)), cellId));
3532 auto lutIt = lut.begin();
3533 for(
MInt cellId = m_haloCellOffsets[0][levelPos]; cellId < m_haloCellOffsets[m_noNeighborDomains - 1][levelPos + 1];
3535 LUT.insert(make_pair(cellId, lutIt->second));
3540 vector<vector<MInt>> winCellIdsPerDomain(m_noNeighborDomains, vector<MInt>(0));
3541 vector<vector<MInt>> haloCellIdsPerDomain(m_noNeighborDomains, vector<MInt>(0));
3543 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
3544 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
3545 a_hasProperty(i, 3) = 0;
3548 for(
MInt p = m_haloCellOffsets[dom][levelPos]; p < m_haloCellOffsets[dom][levelPos + 1]; p++) {
3549 const MInt cellId = LUT[p];
3550 haloCellIdsPerDomain[dom].push_back(cellId);
3551 for(
MInt n = 0; n < m_noNeighbors; n++) {
3552 if(a_neighborId(cellId, n) < m_noCells && a_neighborId(cellId, n) > -1) {
3553 a_hasProperty((
MInt)a_neighborId(cellId, n), 3) = 1;
3557 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
3558 if(a_hasProperty(i, 3)) {
3559 winCellIdsPerDomain[dom].push_back(i);
3565 MIntScratchSpace noSendWindowPerDomain(m_noNeighborDomains, AT_,
"noSendWindowPerDomain");
3566 MIntScratchSpace noReceiveHaloPerDomain(m_noNeighborDomains, AT_,
"noReceiveHaloPerDomain");
3568 MInt allReceive = 0;
3570 for(
MInt d = 0; d < m_noNeighborDomains; ++d) {
3571 noReceiveHaloPerDomain[d] = (
MInt)haloCellIdsPerDomain[d].size();
3572 allReceive += noReceiveHaloPerDomain[d];
3573 noSendWindowPerDomain[d] = (
MInt)winCellIdsPerDomain[d].size();
3574 allSend += noSendWindowPerDomain[d];
3581 for(
MInt d = 0; d < m_noNeighborDomains; ++d) {
3582 for(
MInt c = 0; c < noSendWindowPerDomain[d]; c++)
3583 myWindowInt(offset + c) = a_hasProperty(winCellIdsPerDomain[d][c], 0);
3584 offset += noSendWindowPerDomain[d];
3587 communicateIntToNeighbors(myHaloInt, noReceiveHaloPerDomain, myWindowInt, noSendWindowPerDomain, 1);
3591 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
3592 for(
MInt c = 0; c < noReceiveHaloPerDomain[d]; c++) {
3593 a_hasProperty(haloCellIdsPerDomain[d][c], 0) = (
MBool)myHaloInt(offset + c);
3595 offset += noReceiveHaloPerDomain[d];
3599 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++)
3600 for(
MInt p = m_haloCellOffsets[dom][levelPos]; p < m_haloCellOffsets[dom][levelPos + 1]; p++)
3601 a_hasProperty(p, 7) = 0;
3602 }
else if(m_keepOutsideBndryCellChildren == 2) {
3603 keepOutsideBndryCellChildrenSerial(m_levelOffsets[level_], level_);
3604 keepOutsideBndryCellChildrenSerial(m_haloCellOffsets[level_], level_);
3605 }
else if(m_keepOutsideBndryCellChildren == 3) {
3606 mTerm(1, AT_,
"ERROR: keepOutsideBndryCellChildren in mode 3 is not implemented for parallel usage yet!!!");
3614 for(
MInt s = 0; s < m_noSolvers; s++) {
3616 for(
MInt cellId = m_levelOffsets[level_][0]; cellId < m_levelOffsets[level_][1]; cellId++) {
3618 if(a_isInSolver(cellId, s) == 0)
continue;
3619 if(a_hasProperty(cellId, 0) && !a_hasProperty(cellId, 1)) {
3620 a_noSolidLayer(cellId, s) = -1;
3623 if(a_hasProperty(cellId, 1)) {
3624 a_noSolidLayer(cellId, s) = m_noSolidLayer[s] * 2;
3627 if(!a_hasProperty(cellId, 0) && !a_hasProperty(cellId, 1)) {
3628 a_noSolidLayer(cellId, s) = m_noSolidLayer[s] * 2;
3632 cout <<
"## FLUID " << FLUID <<
" SOLID0 " << SOLID0 <<
" SOLID1 " << SOLID1 <<
" TODELETE " << DELETE << endl;
3635 const MInt lev_pos = 2 * (level_ - m_minLevel);
3636 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
3637 for(
MInt i = m_haloCellOffsets[dom][lev_pos]; i < m_haloCellOffsets[dom][lev_pos + 1]; i++) {
3638 if(a_hasProperty(i, 0)) a_noSolidLayer(i, s) = -1;
3639 if(a_hasProperty(i, 1)) a_noSolidLayer(i, s) = m_noSolidLayer[s] * 2;
3640 if(!a_hasProperty(i, 0) && !a_hasProperty(i, 1)) a_noSolidLayer(i, s) = m_noSolidLayer[s] * 2;
3646 for(
MInt cellId = m_levelOffsets[level_][0]; cellId < m_levelOffsets[level_][1]; cellId++) {
3647 if(a_isInSolver(cellId, s) == 0)
continue;
3648 if(!a_hasProperty(cellId, 1))
continue;
3649 createSolidCellLayer(cellId, 0, m_noSolidLayer[s]);
3657 map<MInt, MInt> lut;
3658 map<MInt, MInt> LUT;
3659 for(
MInt cellId = m_haloCellOffsets[0][lev_pos]; cellId < m_haloCellOffsets[m_noNeighborDomains - 1][lev_pos + 1];
3661 lut.insert(make_pair(
static_cast<MInt>(a_globalId(cellId)), cellId));
3663 auto lutIt = lut.begin();
3664 for(
MInt cellId = m_haloCellOffsets[0][lev_pos]; cellId < m_haloCellOffsets[m_noNeighborDomains - 1][lev_pos + 1];
3666 LUT.insert(make_pair(cellId, lutIt->second));
3671 vector<vector<MInt>> winCellIdsPerDomain(m_noNeighborDomains, vector<MInt>(0));
3672 vector<vector<MInt>> haloCellIdsPerDomain(m_noNeighborDomains, vector<MInt>(0));
3675 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
3676 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
3677 a_hasProperty(i, 3) = 0;
3680 for(
MInt p = m_haloCellOffsets[dom][lev_pos]; p < m_haloCellOffsets[dom][lev_pos + 1]; p++) {
3681 const MInt cellId = LUT[p];
3682 haloCellIdsPerDomain[dom].push_back(cellId);
3683 for(
MInt n = 0; n < m_noNeighbors; n++) {
3684 if(a_neighborId(cellId, n) < m_noCells && a_neighborId(cellId, n) > -1) {
3685 a_hasProperty((
MInt)a_neighborId(cellId, n), 3) = 1;
3689 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
3690 if(a_hasProperty(i, 3)) {
3691 winCellIdsPerDomain[dom].push_back(i);
3697 MIntScratchSpace noSendWindowPerDomain(m_noNeighborDomains, AT_,
"noSendWindowPerDomain");
3698 MIntScratchSpace noReceiveHaloPerDomain(m_noNeighborDomains, AT_,
"noReceiveHaloPerDomain");
3700 m_log <<
" - process " << domainId() <<
" needs to transfer to domain [no. cells to transfer]: ";
3701 cout <<
" - process " << domainId() <<
" needs to transfer to domain [no. cells to transfer]: ";
3702 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
3703 noSendWindowPerDomain[d] = (
MInt)winCellIdsPerDomain[d].size();
3704 m_log << m_neighborDomains[d] <<
" [" << noSendWindowPerDomain[d] <<
"] ";
3705 cout << m_neighborDomains[d] <<
" [" << noSendWindowPerDomain[d] <<
"] ";
3710 m_log <<
" - process " << domainId() <<
" needs to receive from domain [no. cells to receive]: ";
3711 cout <<
" - process " << domainId() <<
" needs to receive from domain [no. cells to receive]: ";
3712 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
3713 noReceiveHaloPerDomain[d] = (
MInt)haloCellIdsPerDomain[d].size();
3714 m_log << m_neighborDomains[d] <<
" [" << noReceiveHaloPerDomain[d] <<
"] ";
3715 cout << m_neighborDomains[d] <<
" [" << noReceiveHaloPerDomain[d] <<
"] ";
3721 MInt allReceive = 0;
3722 vector<MInt> offsetsSend;
3723 vector<MInt> offsetsReceive;
3724 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
3725 offsetsSend.push_back(allSend);
3726 offsetsReceive.push_back(allReceive);
3727 allSend += noSendWindowPerDomain[dom];
3728 allReceive += noReceiveHaloPerDomain[dom];
3744 MPI_Request* mpi_request_;
3745 mAlloc(mpi_request_, m_noNeighborDomains,
"mpi_request_", AT_);
3746 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
3747 for(
MInt c = 0; c < noSendWindowPerDomain[d]; c++) {
3748 sndBufWin[offsetsSend[d] + c] = a_noSolidLayer(winCellIdsPerDomain[d][c], 0);
3750 MPI_Issend(&(sndBufWin[offsetsSend[d]]), noSendWindowPerDomain[d], MPI_INT, m_neighborDomains[d], 0,
3751 mpiComm(), &mpi_request_[d], AT_,
"(sndBufWin[offsetsSend[d]])");
3755 for(
MInt d = 0; d < m_noNeighborDomains; d++)
3756 MPI_Recv(&(rcvBufHalo[offsetsReceive[d]]), noReceiveHaloPerDomain[d], MPI_INT, m_neighborDomains[d], 0,
3757 mpiComm(), &status_, AT_,
"(rcvBufHalo[offsetsReceive[d]])");
3759 for(
MInt d = 0; d < m_noNeighborDomains; d++)
3760 MPI_Wait(&mpi_request_[d], &status_, AT_);
3762 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
3763 for(
MInt c = 0; c < noReceiveHaloPerDomain[d]; c++) {
3764 const MInt halo = haloCellIdsPerDomain[d][c];
3765 if(a_isInSolver(halo, s) == 0)
continue;
3766 if(a_noSolidLayer(halo, 0) == -1) {
3767 for(
MInt n = 0; n < m_noNeighbors; n++) {
3768 MInt nghborId = (
MInt)a_neighborId(halo, n);
3769 if((nghborId < 0) || (nghborId > m_noCells))
continue;
3770 if((a_noSolidLayer(nghborId, 0) > (rcvBufHalo[c + offsetsReceive[d]] + 1))
3771 && (rcvBufHalo[c + offsetsReceive[d]] > -1)) {
3772 if(rcvBufHalo[c + offsetsReceive[d]] < m_noSolidLayer[s]) {
3773 createSolidCellLayer(nghborId, (rcvBufHalo[c + offsetsReceive[d]] + 1), m_noSolidLayer[s]);
3781 MPI_Allreduce(MPI_IN_PLACE, &finished, 1, MPI_UNSIGNED_SHORT, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
3786 cout <<
" - communication rounds required: " << rounds << endl;
3790 for(
MInt s = 0; s < m_noSolvers; s++) {
3797 for(
MInt cellId = m_levelOffsets[level_][0]; cellId < m_levelOffsets[level_][1]; cellId++) {
3798 if(a_isInSolver(cellId, s) == 0)
continue;
3799 if(a_noSolidLayer(cellId, s) == -1) FLUID++;
3801 if(a_noSolidLayer(cellId, s) > m_noSolidLayer[s]) {
3802 a_noSolidLayer(cellId, s) = -1;
3806 if(a_noSolidLayer(cellId, s) == 0) SOLID0++;
3808 if(a_noSolidLayer(cellId, s) == 1) SOLID1++;
3811 cout <<
" FLUID " << FLUID <<
" SOLID0 " << SOLID0 <<
" SOLID1 " << SOLID1 <<
" TODELETE " << DELETE << endl;
3812 const MInt lev_pos = 2 * (level_ - m_minLevel);
3813 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
3814 for(
MInt i = m_haloCellOffsets[dom][lev_pos]; i < m_haloCellOffsets[dom][lev_pos + 1]; i++) {
3815 if(a_noSolidLayer(i, s) > m_noSolidLayer[s]) a_noSolidLayer(i, s) = -1;
3820 for(
MInt cellId = m_levelOffsets[level_][0]; cellId < m_levelOffsets[level_][1]; cellId++) {
3821 for(
MInt s = 0; s < m_noSolvers; s++) {
3822 if(a_noSolidLayer(cellId, s) >= 0) {
3823 a_isToRefineForSolver(cellId, s) = 1;
3824 a_isInSolver(cellId, s) = 1;
3840 mTerm(1, AT_,
"unknown keepOutsideBndryCellChildren option");
3865 NEW_SUB_TIMER(t_reorderCellsHilbert,
"reordering cells after Hilbert id", m_t_createInitialGrid);
3866 RECORD_TIMER_START(t_reorderCellsHilbert);
3868 m_log <<
" + creating Hilbert curve" << endl;
3869 outStream <<
" + creating Hilbert curve" << endl;
3872 std::array<MFloat, MAX_SPACE_DIMENSIONS> centerOfGravity;
3873 copy_n(m_centerOfGravity, nDim, ¢erOfGravity[0]);
3874 MFloat lengthLevel0 = m_lengthOnLevel[0];
3875 MInt hilbertLevel = m_minLevel;
3879 if(m_targetGridFileName !=
"") {
3880 TERMM(1,
"deprecated");
3881 m_log <<
" * reading grid information from target grid (" << m_targetGridFileName <<
")" << endl;
3882 outStream <<
" * reading grid information from target grid (" << m_targetGridFileName <<
")" << endl;
3886 ParallelIo file(m_targetGridFileName, PIO_READ, mpiComm());
3887 file.getAttribute(¢erOfGravity[0],
"centerOfGravity", nDim);
3888 file.getAttribute(&lengthLevel0,
"lengthLevel0");
3889 file.getAttribute(&hilbertLevel,
"minLevel");
3890 }
else if(m_multiSolverMinLevel > -1) {
3891 hilbertLevel = m_multiSolverMinLevel;
3895 for(
MInt i = 0; i < nDim; i++) {
3896 centerOfGravity[i] = 0.5 * (m_multiSolverBoundingBox[nDim + i] + m_multiSolverBoundingBox[i]);
3899 (F1 + F1 /
FPOW2(30)) * fabs(m_multiSolverBoundingBox[nDim + i] - m_multiSolverBoundingBox[i]);
3900 lengthLevel0 = std::max(lengthLevel0,
dist);
3904 m_multiSolverLengthLevel0 = lengthLevel0;
3905 m_multiSolverCenterOfGravity.resize(nDim);
3906 std::copy_n(¢erOfGravity[0], nDim, &m_multiSolverCenterOfGravity[0]);
3910 lengthLevel0, m_multiSolverMinLevel);
3913 msg <<
" * using multisolver grid information from property file:" << endl
3914 <<
" - minLevel = " << hilbertLevel << endl
3915 <<
" - boundingBox = ";
3916 for(
MInt i = 0; i < nDim; i++) {
3917 msg <<
"[" << m_multiSolverBoundingBox[i] <<
", " << m_multiSolverBoundingBox[nDim + i] <<
"]";
3922 msg << endl <<
" - centerOfGravity = [";
3923 for(
MInt i = 0; i < nDim; i++) {
3924 msg << centerOfGravity[i];
3929 msg <<
"]" << endl <<
" - lengthLevel0 = " << lengthLevel0 << endl;
3932 if(domainId() == 0) {
3933 outStream << msg.str();
3942 for(
MInt i = 0; i < m_noCells; ++i) {
3943 MFloat* c = &a_coordinate(i, 0);
3947 x[0] = (c[0] - centerOfGravity[0] + lengthLevel0 * 0.5) / lengthLevel0;
3948 x[1] = (c[1] - centerOfGravity[1] + lengthLevel0 * 0.5) / lengthLevel0;
3949 IF_CONSTEXPR(nDim == 3) { x[2] = (c[2] - centerOfGravity[2] + lengthLevel0 * 0.5) / lengthLevel0; }
3951 IF_CONSTEXPR(nDim == 2) { hilbertIds[i] = maia::grid::hilbert::index<2>(&x[0],
static_cast<MLong>(hilbertLevel)); }
3952 else IF_CONSTEXPR(nDim == 3) {
3953 hilbertIds[i] = maia::grid::hilbert::index<3>(&x[0],
static_cast<MLong>(hilbertLevel));
3956 TERMM(1,
"Bad number of dimensions: " + to_string(nDim));
3959 hilbert_lookup[i] = i;
3961 revPosTracker[i] = i;
3964 m_log <<
" * resorting cells after Hilbert id" << endl;
3965 outStream <<
" * resorting cells after Hilbert id" << endl;
3971 for(
MInt i = 0; i < m_noCells; ++i) {
3972 if(i != hilbert_lookup[i]) {
3973 if(i != posTracker[hilbert_lookup[i]]) swapCells(i, posTracker[hilbert_lookup[i]]);
3974 MInt iTmp = revPosTracker[i];
3975 revPosTracker[posTracker[hilbert_lookup[i]]] = iTmp;
3976 posTracker[iTmp] = posTracker[hilbert_lookup[i]];
3981 for(
MInt i = 0; i < m_noCells; ++i) {
3984 RECORD_TIMER_STOP(t_reorderCellsHilbert);
4012 T pivot = globalIdArray[startIndex];
4013 MInt splitPoint = 0;
4015 if(endIndex > startIndex) {
4016 MInt leftBoundary = startIndex;
4017 MInt rightBoundary = endIndex;
4019 while(leftBoundary < rightBoundary) {
4020 while(pivot < globalIdArray[rightBoundary] && rightBoundary > leftBoundary)
4023 swap(globalIdArray[leftBoundary], globalIdArray[rightBoundary]);
4024 swap(lookup[leftBoundary], lookup[rightBoundary]);
4026 while(pivot >= globalIdArray[leftBoundary] && leftBoundary < rightBoundary)
4029 swap(globalIdArray[rightBoundary], globalIdArray[leftBoundary]);
4030 swap(lookup[rightBoundary], lookup[leftBoundary]);
4033 splitPoint = leftBoundary;
4035 globalIdArray[splitPoint] = pivot;
4037 quickSort(globalIdArray, lookup, startIndex, splitPoint - 1);
4038 quickSort(globalIdArray, lookup, splitPoint + 1, endIndex);
4058 ASSERT(a_hasProperty(from, 7) != 1,
"" <<
globalDomainId() <<
": Invalid cell " << from <<
" copied!");
4060 for(
MInt i = 0; i < 8; i++) {
4061 a_hasProperty(to, i) = a_hasProperty(from, i);
4062 a_isInSolver(to, i) = a_isInSolver(from, i);
4063 a_isSolverBoundary(to, i) = a_isSolverBoundary(from, i);
4064 a_isToRefineForSolver(to, i) = a_isToRefineForSolver(from, i);
4067 a_level(to) = a_level(from);
4068 a_noChildren(to) = a_noChildren(from);
4069 a_globalId(to) = a_globalId(from);
4070 a_parentId(to) = a_parentId(from);
4071 for(
MInt s = 0; s < 8; s++) {
4072 a_noSolidLayer(to, s) = a_noSolidLayer(from, s);
4075 copy(&a_coordinate(from, 0), &a_coordinate(from, nDim), &a_coordinate(to, 0));
4076 copy(&a_neighborId(from, 0), &a_neighborId(from, m_noNeighbors), &a_neighborId(to, 0));
4077 copy(&a_childId(from, 0), &a_childId(from, m_maxNoChildren), &a_childId(to, 0));
4080 for(
MInt i = 0; i < m_noNeighbors; i++)
4081 if(a_neighborId(to, i) >= 0) a_neighborId((
MInt)a_neighborId(to, i), oppositeDirGrid[i]) = (
MLong)to;
4084 if(a_parentId(to) >= 0)
4085 for(
MInt c = 0; c < m_maxNoChildren; c++)
4086 if(a_childId((
MInt)a_parentId(to), c) == (
MLong)from) {
4087 a_childId((
MInt)a_parentId(to), c) = (
MLong)to;
4092 for(
MInt c = 0; c < m_maxNoChildren; c++)
4093 if(a_childId(to, c) >= 0) a_parentId((
MInt)a_childId(to, c)) = (
MLong)to;
4113 copyCell(cellId1, m_maxNoCells - 1);
4114 copyCell(cellId2, cellId1);
4115 copyCell(m_maxNoCells - 1, cellId2);
4139 return m_geometry->isPointInside(coordinates);
4145 return m_geometry->isPointInsideNode(coordinates, solver);
4183 RECORD_TIMER_START(m_t_createStartGrid);
4186 for(
MInt l = m_minLevel; l < m_maxUniformRefinementLevel; l++) {
4188 m_levelOffsets[l + 1][0] = m_noCells;
4189 m_levelOffsets[l + 1][1] = m_noCells + (m_levelOffsets[l][1] - m_levelOffsets[l][0]) * m_maxNoChildren;
4192 if(noDomains() > 1) updateHaloOffsets(l, m_noHaloCellsOnLevel[l],
nullptr);
4194 for(
MInt solver = 0; solver < m_noSolvers; solver++)
4195 markSolverForRefinement(l, solver);
4198 checkMemoryAvailability(1, l + 1);
4201 refineGrid(m_levelOffsets, l, 0);
4202 if(noDomains() > 1) {
4203 refineGrid(m_haloCellOffsetsLevel, l, 1);
4207 m_noCells = m_levelOffsets[l + 1][1];
4210 findChildLevelNeighbors(m_levelOffsets, l);
4211 if(noDomains() > 1) {
4212 findChildLevelNeighbors(m_haloCellOffsetsLevel, l);
4216 if(noDomains() > 1) {
4217 deleteOutsideCellsParallel(l + 1);
4219 deleteOutsideCellsSerial(l + 1);
4223 m_noCells = m_levelOffsets[l + 1][1];
4226 RECORD_TIMER_STOP(m_t_createStartGrid);
4242 for(
MInt i = 0; i < m_noCells; i++) {
4243 for(
MInt n = 0; n < m_noNeighbors; n++) {
4244 if(a_neighborId(i, n) >= 0 && a_neighborId(i, n) < m_noCells) {
4245 a_neighborId(i, n) = a_globalId((
MInt)a_neighborId(i, n));
4249 for(
MInt c = 0; c < m_maxNoChildren; c++)
4250 if(a_childId(i, c) >= 0) a_childId(i, c) = a_globalId((
MInt)a_childId(i, c));
4252 if(a_parentId(i) >= 0) a_parentId(i) = a_globalId((
MInt)a_parentId(i));
4268 m_levelOffsets[gridLevel + 1][0] = m_noCells;
4269 m_levelOffsets[gridLevel + 1][1] = m_noCells + m_rfnCount * m_maxNoChildren;
4271 m_log <<
" * cells on level " << gridLevel <<
" to refine: " << m_rfnCount << endl;
4272 m_log <<
" - new cells to create: " << m_rfnCount * m_maxNoChildren << endl;
4273 m_log <<
" - new no. of cells: " << m_noCells + m_rfnCount * m_maxNoChildren << endl;
4274 outStream <<
" * cells on level " << gridLevel <<
" to refine: " << m_rfnCount << endl;
4275 outStream <<
" - new cells to create: " << m_rfnCount * m_maxNoChildren << endl;
4276 outStream <<
" - new no. of cells: " << m_noCells + m_rfnCount * m_maxNoChildren << endl;
4299 m_log <<
" + updating the halo offsets for the new level for " << noHalos <<
" halos" << endl;
4300 outStream <<
" + updating the halo offsets for the new level for " << noHalos <<
" halos" << endl;
4302 m_haloCellOffsetsLevel[l + 1][0] = m_haloCellOffsetsLevel[l][0] - noHalos * m_maxNoChildren;
4303 m_haloCellOffsetsLevel[l + 1][1] = m_haloCellOffsetsLevel[l][0];
4304 m_noHaloCellsOnLevel[l + 1] = m_haloCellOffsetsLevel[l + 1][1] - m_haloCellOffsetsLevel[l + 1][0];
4305 m_noTotalHaloCells += m_noHaloCellsOnLevel[l + 1];
4307 MInt lev_pos = 2 * (l - m_minLevel);
4308 MInt lev_pos_newlevel = 2 * ((l + 1) - m_minLevel);
4310 m_log <<
" * halo cells on this level for processes [offsets]: " << endl;
4311 outStream <<
" * halo cells on this level for processes [offsets]: " << endl;
4312 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
4313 MInt diff_on_level = 0;
4314 if(noHalos == m_noHaloCellsOnLevel[l])
4315 diff_on_level = m_haloCellOffsets[dom][lev_pos + 1] - m_haloCellOffsets[dom][lev_pos];
4317 diff_on_level = rfnCountHalosDom[dom];
4320 m_haloCellOffsets[dom][lev_pos_newlevel] = m_haloCellOffsetsLevel[l + 1][0];
4322 m_haloCellOffsets[dom][lev_pos_newlevel] = m_haloCellOffsets[dom - 1][lev_pos_newlevel + 1];
4324 m_haloCellOffsets[dom][lev_pos_newlevel + 1] =
4325 m_haloCellOffsets[dom][lev_pos_newlevel] + diff_on_level * m_maxNoChildren;
4326 m_log <<
" - " << m_neighborDomains[dom] <<
": "
4327 <<
" " << m_haloCellOffsets[dom][lev_pos_newlevel + 1] - m_haloCellOffsets[dom][lev_pos_newlevel] <<
" ["
4328 << m_haloCellOffsets[dom][lev_pos_newlevel] <<
" " << m_haloCellOffsets[dom][lev_pos_newlevel + 1] <<
"] "
4330 outStream <<
" - " << m_neighborDomains[dom] <<
": "
4331 <<
" " << m_haloCellOffsets[dom][lev_pos_newlevel + 1] - m_haloCellOffsets[dom][lev_pos_newlevel] <<
" ["
4332 << m_haloCellOffsets[dom][lev_pos_newlevel] <<
" " << m_haloCellOffsets[dom][lev_pos_newlevel + 1]
4375 RECORD_TIMER_START(m_t_parallelizeGrid);
4377 m_log <<
" + parallelizing grid" << endl;
4378 outStream <<
" + parallelizing grid" << endl;
4381 m_log <<
" * calculating rank offsets" << endl;
4382 outStream <<
" * calculating rank offsets" << endl;
4385 determineRankOffsets(rank_offsets);
4387 m_log <<
" - rank offsets are : ";
4388 outStream <<
" - rank offsets are : ";
4389 for(
MInt dom = 0; dom < noDomains() + 1; dom++) {
4390 m_log << rank_offsets[dom] <<
" ";
4391 outStream << rank_offsets[dom] <<
" ";
4398 m_log <<
" * finding communication partners" << endl;
4399 outStream <<
" * finding communication partners" << endl;
4405 set<MInt> neighbor_domains_set;
4409 no_haloPerDomain.
fill(0);
4412 for(
MInt i = my_lower_off; i < my_upper_off; i++) {
4413 for(
MInt dir = 0; dir < m_noNeighbors; dir++) {
4414 const MInt nghbrId = (
MInt)a_neighborId(i, dir);
4417 if(nghbrId >= 0 && (nghbrId < my_lower_off || nghbrId >= my_upper_off)) {
4419 a_hasProperty(i, 3) = 1;
4423 while(nghbrId >= rank_offsets[l + 1]) {
4427 neighbor_domains_set.insert(l);
4430 if(!a_hasProperty(nghbrId, 4)) {
4431 no_haloPerDomain[l]++;
4432 a_hasProperty(nghbrId, 4) = 1;
4438 m_noNeighborDomains = (
MInt)neighbor_domains_set.
size();
4439 mAlloc(m_neighborDomains, m_noNeighborDomains,
"m_neighborDomains", -1, AT_);
4440 mAlloc(m_rfnCountHalosDom, m_noNeighborDomains,
"m_rfnCountHalosDom", 0, AT_);
4443 <<
" neighbor(s) [number of halos]: ";
4444 outStream <<
" - domain " <<
globalDomainId() <<
" has " << m_noNeighborDomains
4445 <<
" neighbor(s) [number of halos]: ";
4446 set<MInt>::iterator it = neighbor_domains_set.begin();
4447 for(
MInt j = 0; j < m_noNeighborDomains; j++) {
4448 m_neighborDomains[j] = *it;
4451 m_log << m_neighborDomains[j] <<
" [" << no_haloPerDomain[m_neighborDomains[j]] <<
"] ";
4452 outStream << m_neighborDomains[j] <<
" [" << no_haloPerDomain[m_neighborDomains[j]] <<
"] ";
4459 m_log <<
" * finding and moving halo cells that we want to keep" << endl;
4460 outStream <<
" * finding and moving halo cells that we want to keep" << endl;
4463 mAlloc(m_haloCellOffsets, m_noNeighborDomains, 2 * (m_maxRfnmntLvl - m_minLevel + 1),
"m_haloCellOffsets", 0, AT_);
4464 const MInt lastNeighborDomPos = m_noNeighborDomains - 1;
4465 const MInt lastNeighborDomId = m_neighborDomains[lastNeighborDomPos];
4467 m_haloCellOffsets[lastNeighborDomPos][1] = m_maxNoCells - 1;
4468 m_haloCellOffsets[lastNeighborDomPos][0] =
4469 m_haloCellOffsets[lastNeighborDomPos][1] - no_haloPerDomain[lastNeighborDomId];
4471 for(
MInt j = m_noNeighborDomains - 2; j >= 0; j--) {
4472 m_haloCellOffsets[j][1] = m_haloCellOffsets[j + 1][0];
4473 m_haloCellOffsets[j][0] = m_haloCellOffsets[j][1] - no_haloPerDomain[m_neighborDomains[j]];
4476 m_log <<
" - haloCellOffsets on this level for processes [offsets]: " << endl;
4477 outStream <<
" - haloCellOffsets on this level for processes [offsets]: " << endl;
4478 for(
MInt j = 0; j < m_noNeighborDomains; j++) {
4479 m_log <<
" = " << m_neighborDomains[j] <<
": " << m_haloCellOffsets[j][1] - m_haloCellOffsets[j][0]
4480 <<
" [" << m_haloCellOffsets[j][0] <<
" " << m_haloCellOffsets[j][1] <<
"]" << endl;
4481 outStream <<
" = " << m_neighborDomains[j] <<
": " << m_haloCellOffsets[j][1] - m_haloCellOffsets[j][0]
4482 <<
" [" << m_haloCellOffsets[j][0] <<
" " << m_haloCellOffsets[j][1] <<
"]" << endl;
4485 MInt shift = my_lower_off;
4488 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
4489 MInt domain = m_neighborDomains[dom];
4490 MInt haloPos = m_haloCellOffsets[dom][0];
4493 for(
MInt i = rank_offsets[domain]; i < rank_offsets[domain + 1]; i++) {
4495 if(a_hasProperty(i, 4)) {
4496 copyCell(i, haloPos);
4503 m_haloCellOffsetsLevel[m_minLevel][0] = m_haloCellOffsets[0][0];
4504 m_haloCellOffsetsLevel[m_minLevel][1] = m_maxNoCells - 1;
4506 m_noTotalHaloCells = m_haloCellOffsetsLevel[m_minLevel][1] - m_haloCellOffsetsLevel[m_minLevel][0];
4507 m_noHaloCellsOnLevel[m_minLevel] = m_noTotalHaloCells;
4511 for(
MInt h = m_haloCellOffsetsLevel[m_minLevel][0]; h < m_haloCellOffsetsLevel[m_minLevel][1]; h++) {
4512 MLong* neigh = &a_neighborId(h, 0);
4513 for(
MInt n = 0; n < m_noNeighbors; n++) {
4514 if(neigh[n] < my_lower_off || (neigh[n] >= my_upper_off && neigh[n] < m_haloCellOffsetsLevel[m_minLevel][0])) {
4516 }
else if(neigh[n] >= my_lower_off && neigh[n] < my_upper_off) {
4523 MInt noCellsInMyDomain = my_upper_off - my_lower_off;
4525 m_log <<
" * shifting my cell array of size " << noCellsInMyDomain <<
" by " << my_lower_off <<
" units"
4527 outStream <<
" * shifting my cell array of size " << noCellsInMyDomain <<
" by " << my_lower_off <<
" units"
4530 m_log <<
" - moving memory for pointers in cells" << endl;
4531 outStream <<
" - moving memory for pointers in cells" << endl;
4534 copy(&a_parentId(my_lower_off), &a_parentId(my_lower_off + noCellsInMyDomain), &a_parentId(0));
4535 copy(&a_globalId(my_lower_off), &a_globalId(my_lower_off + noCellsInMyDomain), &a_globalId(0));
4536 copy(&a_level(my_lower_off), &a_level(my_lower_off + noCellsInMyDomain), &a_level(0));
4537 copy(&a_noChildren(my_lower_off), &a_noChildren(my_lower_off + noCellsInMyDomain), &a_noChildren(0));
4538 copy(&a_neighborId(my_lower_off, 0), &a_neighborId(my_lower_off + noCellsInMyDomain, m_noNeighbors),
4539 &a_neighborId(0, 0));
4540 copy(&a_childId(my_lower_off, 0), &a_childId(my_lower_off + noCellsInMyDomain, m_maxNoChildren), &a_childId(0, 0));
4541 copy(&a_coordinate(my_lower_off, 0), &a_coordinate(my_lower_off + noCellsInMyDomain, nDim), &a_coordinate(0, 0));
4543 m_log <<
" - moving bitsets and updating the neighbors" << endl;
4544 outStream <<
" - moving bitsets and updating the neighbors" << endl;
4547 for(
MInt i = 0; i < noCellsInMyDomain; i++) {
4549 MInt former_cell = i + my_lower_off;
4551 a_hasProperty(cell,
b) = a_hasProperty(former_cell,
b);
4552 a_isInSolver(cell,
b) = a_isInSolver(former_cell,
b);
4553 a_isSolverBoundary(cell,
b) = a_isSolverBoundary(former_cell,
b);
4554 a_isToRefineForSolver(cell,
b) = a_isToRefineForSolver(former_cell,
b);
4556 for(
MInt s = 0; s < m_noSolvers; s++) {
4557 a_noSolidLayer(cell, s) = a_noSolidLayer(former_cell, s);
4561 MLong* neigh = &a_neighborId(cell, 0);
4562 for(
MInt n = 0; n < m_noNeighbors; n++)
4563 if(neigh[n] >= 0 && neigh[n] < m_haloCellOffsets[0][0]) neigh[n] -= shift;
4567 m_noTotalCells = (
MLong)m_noCells;
4568 m_noCells = noCellsInMyDomain;
4570 for(
MInt l = 0; l < m_minLevel; l++) {
4571 m_levelOffsets[l][0] = -1;
4572 m_levelOffsets[l][1] = -1;
4575 m_levelOffsets[m_minLevel][0] = 0;
4576 m_levelOffsets[m_minLevel][1] = m_noCells;
4580 for(
MInt cellId = m_haloCellOffsets[0][0]; cellId < m_haloCellOffsets[m_noNeighborDomains - 1][1]; cellId++) {
4581 m_cellIdLUT.insert(make_pair(cellId, cellId));
4585 for(
MInt cellId = 0; cellId < m_levelOffsets[m_minLevel][1]; cellId++) {
4586 m_cellIdLUT.insert(make_pair(cellId, cellId));
4589 RECORD_TIMER_STOP(m_t_parallelizeGrid);
4596 rank_offsets.
fill(0);
4597 rank_offsets[noDomains()] = m_noCells;
4598 if(m_weightBndCells || m_weightPatchCells || m_weightSolverUniformLevel) {
4600 m_log <<
" * using further refinement information" << endl;
4601 MInt sumOfWeights = 0;
4603 cellWeights.
fill((
MInt)pow(
IPOW2(m_maxUniformRefinementLevel - m_minLevel), nDim));
4604 for(
MInt cId = 0; cId < m_noCells; cId++) {
4606 if(m_weightSolverUniformLevel) {
4607 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
4609 if(a_isInSolver(cId, solver)) {
4611 cellWeights[cId] =
mMax(cellWeights[cId], tmpWeight);
4616 if(m_weightBndCells) {
4618 if(checkCellForCut(cId)) {
4620 MInt maxCutLevel = 0;
4621 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
4632 MInt cutWeight = (
MInt)pow(
IPOW2(maxCutLevel - m_minLevel), nDim);
4633 cellWeights[cId] =
mMax(cellWeights(cId), cutWeight);
4637 if(m_weightPatchCells) {
4640 for(
MInt dim = 0; dim < nDim; dim++) {
4641 bbox[dim] = a_coordinate(cId, dim) - m_lengthOnLevel[m_minLevel] * 0.5;
4642 bbox[dim + nDim] = a_coordinate(cId, dim) + m_lengthOnLevel[m_minLevel] * 0.5;
4644 MInt maxCutLevel = 0;
4645 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
4646 if(a_isInSolver(cId, solver)) {
4650 for(; patchLvl >= 0; patchLvl--) {
4651 MBool intersect =
false;
4655 if(patchStr ==
"B") {
4657 }
else if(patchStr ==
"R") {
4661 m_log <<
"weighting not implemented for patches other than the BOX and sphere, sorry" << endl;
4664 if(intersect)
break;
4668 maxCutLevel =
mMax(maxCutLevel, patchLvl);
4674 MInt patchWeight = (
MInt)pow(
IPOW2(maxCutLevel - m_minLevel), nDim);
4675 cellWeights[cId] =
mMax(cellWeights(cId), patchWeight);
4678 sumOfWeights += cellWeights[cId];
4682 MInt avgLoad = (
MInt)ceil(sumOfWeights / noDomains());
4684 MInt tmpSumLoad = 0;
4686 for(
MInt cId = 0; cId < m_noCells && dom < noDomains(); cId++) {
4687 if(tmpLoad < avgLoad) {
4689 tmpLoad += cellWeights[cId];
4692 rank_offsets[dom] = cId;
4693 tmpSumLoad += tmpLoad;
4695 avgLoad = (
MInt)ceil((sumOfWeights - tmpSumLoad) / (noDomains() - dom));
4696 tmpLoad = cellWeights[cId];
4701 rank_offsets[1] = (
MInt)ceil(m_noCells / noDomains());
4702 for(
MInt dom = 2; dom < noDomains(); dom++)
4704 rank_offsets[dom - 1] + (
MInt)ceil((m_noCells - rank_offsets[dom - 1]) / (noDomains() - dom + 1));
4762 NEW_SUB_TIMER(t_updateInterRankNeighbors,
"update inter rank neighbors", m_t_finalizeGrid);
4763 m_t_updateInterRankNeighbors = t_updateInterRankNeighbors;
4764 RECORD_TIMER_START(m_t_updateInterRankNeighbors);
4766 m_log <<
" + updating the inter rank neighbors" << endl;
4767 outStream <<
" + updating the inter rank neighbors" << endl;
4770 MInt* sndBuf = &m_noCells;
4771 MPI_Allgather(sndBuf, 1, MPI_INT, m_noCellsPerDomain, 1, MPI_INT, mpiComm(), AT_,
"sndBuf",
"m_noCellsPerDomain");
4775 m_cellOffsetPar += (
MLong)m_noCellsPerDomain[d];
4778 vector<vector<MInt>> winCellIdsPerDomain(m_noNeighborDomains, vector<MInt>(0));
4779 vector<vector<MInt>> haloCellIdsPerDomain(m_noNeighborDomains, vector<MInt>(0));
4782 if(m_hasBeenLoadBalanced)
4783 findHaloAndWindowCellsKD(winCellIdsPerDomain, haloCellIdsPerDomain);
4785 findHaloAndWindowCells(winCellIdsPerDomain, haloCellIdsPerDomain);
4788 reorderGlobalIdsDF();
4791 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
4792 if(m_geometry->nodeSurfaceType(solver) ==
STL) {
4793 m_geometry->setGeometryPointerToNode(m_STLgeometry, solver);
4794 if(m_STLgeometry->m_parallelGeometry) writeParallelGeometry();
4799 MIntScratchSpace noSendWindowPerDomain(m_noNeighborDomains, AT_,
"noSendWindowPerDomain");
4800 MIntScratchSpace noReceiveHaloPerDomain(m_noNeighborDomains, AT_,
"noReceiveHaloPerDomain");
4802 m_log <<
" * we need to transfer to domain [no. cells to transfer]: ";
4803 outStream <<
" * we need to transfer to domain [no. cells to transfer]: ";
4804 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
4805 noSendWindowPerDomain[d] = (signed)winCellIdsPerDomain[d].size();
4806 m_log << m_neighborDomains[d] <<
" [" << noSendWindowPerDomain[d] <<
"] ";
4807 outStream << m_neighborDomains[d] <<
" [" << noSendWindowPerDomain[d] <<
"] ";
4812 m_log <<
" * we need to receive from domain [no. cells to receive]: ";
4813 outStream <<
" * we need to receive from domain [no. cells to receive]: ";
4814 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
4815 noReceiveHaloPerDomain[d] = (signed)haloCellIdsPerDomain[d].size();
4816 m_log << m_neighborDomains[d] <<
" [" << noReceiveHaloPerDomain[d] <<
"] ";
4817 outStream << m_neighborDomains[d] <<
" [" << noReceiveHaloPerDomain[d] <<
"] ";
4824 MInt allReceive = 0;
4825 vector<MInt> offsetsSend;
4826 vector<MInt> offsetsReceive;
4827 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
4828 offsetsSend.push_back(allSend);
4829 offsetsReceive.push_back(allReceive);
4830 allSend += noSendWindowPerDomain[dom];
4831 allReceive += noReceiveHaloPerDomain[dom];
4838 MPI_Request* mpi_request =
nullptr;
4839 mAlloc(mpi_request, m_noNeighborDomains,
"mpi_request", AT_);
4840 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
4841 for(
MInt c = 0; c < noSendWindowPerDomain[d]; c++)
4842 sndBufWin[offsetsSend[d] + c] = a_globalId(winCellIdsPerDomain[d][c]);
4844 MPI_Issend(&(sndBufWin[offsetsSend[d]]), noSendWindowPerDomain[d], MPI_LONG, m_neighborDomains[d], 0, mpiComm(),
4845 &mpi_request[d], AT_,
"(sndBufWin[offsetsSend[d]])");
4850 for(
MInt d = 0; d < m_noNeighborDomains; d++)
4851 MPI_Recv(&(rcvBufHalo[offsetsReceive[d]]), noReceiveHaloPerDomain[d], MPI_LONG, m_neighborDomains[d], 0, mpiComm(),
4852 &status, AT_,
"(rcvBufHalo[offsetsReceive[d]])");
4855 for(
MInt d = 0; d < m_noNeighborDomains; d++)
4856 MPI_Wait(&mpi_request[d], &status, AT_);
4859 updateGlobalIdsReferences();
4862 for(
MInt d = 0; d < m_noNeighborDomains; d++)
4863 for(
MInt c = 0; c < noReceiveHaloPerDomain[d]; c++) {
4864 MInt halo = haloCellIdsPerDomain[d][c];
4865 a_globalId(halo) = rcvBufHalo[c + offsetsReceive[d]];
4866 for(
MInt n = 0; n < m_noNeighbors; n++) {
4867 if(a_neighborId(halo, n) >= 0 && a_neighborId(halo, n) < m_noCells) {
4868 a_neighborId((
MInt)a_neighborId(halo, n), oppositeDirGrid[n]) = a_globalId(halo);
4873 RECORD_TIMER_STOP(m_t_updateInterRankNeighbors);
4893 for(
MInt c = 0; c < m_maxNoChildren; c++) {
4894 if(a_childId(parentId_, c) >= 0 && a_hasProperty((
MInt)a_childId(parentId_, c), 4)) {
4895 cellIdsPerDomain->push_back((
MInt)a_childId(parentId_, c));
4896 collectHaloChildren((
MInt)a_childId(parentId_, c), cellIdsPerDomain);
4918 for(
MInt c = 0; c < m_maxNoChildren; c++) {
4919 if(a_childId(parentId_, c) >= 0 && a_hasProperty((
MInt)a_childId(parentId_, c), 3)) {
4920 cellIdsPerDomain->push_back((
MInt)a_childId(parentId_, c));
4921 collectWindowChildren((
MInt)a_childId(parentId_, c), cellIdsPerDomain);
4931 NEW_SUB_TIMER(t_parGeom,
"parallel geometry", m_t_updateInterRankNeighbors);
4932 RECORD_TIMER_START(t_parGeom);
4934 vector<MInt> cutting_tris;
4935 MInt noBndCells = 0;
4936 MIntScratchSpace noTrisPerPartitionCell((
MInt)m_partitionCellList.size(), AT_,
"noTrisPerPartitionCell");
4942 for(
MInt i = 0; i < (signed)m_partitionCellList.size(); i++) {
4943 MInt partitionCellId = get<0>(m_partitionCellList[i]);
4944 noTrisPerPartitionCell[i] = 0;
4947 if(a_hasProperty(partitionCellId, 1)) {
4950 MFloat cellHalfLength = m_lengthOnLevel[a_level(partitionCellId) + 1];
4953 cellHalfLength += cellHalfLength * 0.005;
4955 std::vector<MInt> nodeList;
4957 for(
MInt j = 0; j < nDim; j++) {
4958 target[j] = a_coordinate(partitionCellId, j) - cellHalfLength;
4959 target[j + nDim] = a_coordinate(partitionCellId, j) + cellHalfLength;
4963 m_STLgeometry->getIntersectionElements(target, nodeList, cellHalfLength, &a_coordinate(partitionCellId, 0));
4964 const MInt noNodes = (signed)nodeList.
size();
4966 noTrisPerPartitionCell[i] = noNodes;
4968 for(
MInt t = 0; t < noNodes; t++)
4969 cutting_tris.push_back(nodeList[t]);
4977 MIntScratchSpace noTrianglesPerDomain(noDomains(), AT_,
"noTrianglesPerDomain");
4979 "noTrianglesPerDomain.getPointer()");
4981 MInt noLocalPartitionCells = (
MInt)m_partitionCellList.size();
4982 MIntScratchSpace noPartitionCellsPerDomain(noDomains(), AT_,
"noPartitionCellsPerDomain");
4983 MPI_Allgather(&noLocalPartitionCells, 1, MPI_INT, noPartitionCellsPerDomain.
getPointer(), 1, MPI_INT, mpiComm(), AT_,
4984 "noLocalPartitionCells",
"noPartitionCellsPerDomain.getPointer()");
4986 MInt sumAllTris = 0;
4987 MInt sumAllPartitionCells = 0;
4988 for(
MInt d = 0; d < noDomains(); d++) {
4989 sumAllTris += noTrianglesPerDomain[d];
4990 sumAllPartitionCells += noPartitionCellsPerDomain[d];
4992 MInt myTriOffset = 0;
4993 MInt myPartitionCellOffset = 0;
4994 for(
MInt d = 0; d < domainId(); d++) {
4995 myTriOffset += noTrianglesPerDomain[d];
4996 myPartitionCellOffset += noPartitionCellsPerDomain[d];
5000 ParallelIo geomIO(m_STLgeometry->m_parallelGeomFileName, PIO_REPLACE, mpiComm());
5002 geomIO.defineScalar(PIO_INT,
"noTriangles");
5003 geomIO.defineScalar(PIO_INT,
"noRealTriangles");
5004 geomIO.defineScalar(PIO_FLOAT,
"memIncreaseFactor");
5005 geomIO.defineArray(PIO_INT,
"noTrisPerPartitionCell", sumAllPartitionCells);
5006 geomIO.defineArray(PIO_INT,
"originalTriId", sumAllTris);
5007 geomIO.defineArray(PIO_INT,
"segmentId", sumAllTris);
5009 MString normalNames[3] = {
"normals0",
"normals1",
"normals2"};
5010 for(
MInt d = 0; d < nDim; d++)
5011 geomIO.defineArray(PIO_FLOAT, normalNames[d], sumAllTris);
5013 MString vertexNames[3][3] = {{
"vertices00",
"vertices01",
"vertices02"},
5014 {
"vertices10",
"vertices11",
"vertices12"},
5015 {
"vertices20",
"vertices21",
"vertices22"}};
5016 for(
MInt v = 0; v < nDim; v++)
5017 for(
MInt d = 0; d < nDim; d++)
5018 geomIO.defineArray(PIO_FLOAT, vertexNames[v][d], sumAllTris);
5020 geomIO.writeScalar(sumAllTris,
"noTriangles");
5021 geomIO.writeScalar(m_STLgeometry->GetNoElements(),
"noRealTriangles");
5022 geomIO.writeScalar((
MFloat)(sumAllTris) / ((
MFloat)(m_STLgeometry->GetNoElements())),
"memIncreaseFactor");
5024 geomIO.setOffset(noLocalPartitionCells, myPartitionCellOffset);
5025 if(noLocalPartitionCells == 0)
5026 geomIO.writeArray(dummyInt.
getPointer(),
"noTrisPerPartitionCell");
5028 geomIO.writeArray(noTrisPerPartitionCell.
getPointer(),
"noTrisPerPartitionCell");
5030 geomIO.setOffset(sumTris, myTriOffset);
5032 geomIO.writeArray(dummyInt.
getPointer(),
"originalTriId");
5034 geomIO.writeArray(cutting_tris.data(),
"originalTriId");
5038 for(
MInt i = 0; i < sumTris; i++) {
5039 MInt tri = cutting_tris[i];
5040 segmentIdEntry[i] = m_STLgeometry->elements[tri].m_segmentId;
5043 geomIO.writeArray(dummyInt.
getPointer(),
"segmentId");
5045 geomIO.writeArray(segmentIdEntry.
getPointer(),
"segmentId");
5049 for(
MInt d = 0; d < nDim; d++) {
5051 for(
MInt i = 0; i < sumTris; i++) {
5052 MInt tri = cutting_tris[i];
5053 normalEntry[i] = m_STLgeometry->elements[tri].m_normal[d];
5056 geomIO.writeArray(dummyFloat.
getPointer(), normalNames[d]);
5058 geomIO.writeArray(normalEntry.
getPointer(), normalNames[d]);
5061 for(
MInt v = 0; v < nDim; v++)
5062 for(
MInt d = 0; d < nDim; d++) {
5064 for(
MInt i = 0; i < sumTris; i++) {
5065 MInt tri = cutting_tris[i];
5066 vertexEntry[i] = m_STLgeometry->elements[tri].m_vertices[v][d];
5069 geomIO.writeArray(dummyFloat.
getPointer(), vertexNames[v][d]);
5071 geomIO.writeArray(vertexEntry.
getPointer(), vertexNames[v][d]);
5074 RECORD_TIMER_STOP(t_parGeom);
5099 NEW_SUB_TIMER_STATIC(t_ro,
"reorder global ids DF", m_t_finalizeGrid);
5100 RECORD_TIMER_START(t_ro);
5102 m_log <<
" + reordering global ids" << endl;
5103 outStream <<
" + reordering global ids" << endl;
5106 m_log <<
" * traversing all cells depth-first" << endl;
5107 outStream <<
" * traversing all cells depth-first" << endl;
5109 MLong currentGlobalId = m_cellOffsetPar - 1;
5121 if(m_weightMethod > 0)
5122 setCellWeights(weight);
5136 MInt noMissingParents = m_noMissingParents;
5137 while(noMissingParents > 0) {
5139 MInt cellId = m_levelOffsets[m_minLevel + noMissingParents][0];
5140 while((a_hasProperty((
MInt)a_parentId(cellId), 4) == 1) && (a_level(cellId) == (m_minLevel + noMissingParents))) {
5142 a_globalId(cellId) = currentGlobalId;
5143 partitionCellList(j, 0) = cellId;
5145 MFloat currentWorkload = weight(cellId);
5150 traverseDFGlobalId(cellId, ¤tGlobalId, partitionCellList, workloadPerCell, ¤tWorkload, weight,
5153 MLong noOffsprings = 0;
5155 noOffsprings = currentGlobalId - m_cellOffsetPar;
5157 noOffsprings = currentGlobalId - a_globalId(cellId);
5160 partitionCellList(last, 1) = noOffsprings;
5161 workloadPerCell(last) = currentWorkload;
5165 cellId = m_levelOffsets[m_minLevel + noMissingParents][0] + k;
5174 for(
MInt i = m_levelOffsets[m_minLevel][0]; i < m_levelOffsets[m_minLevel][1]; i++, j++) {
5176 a_globalId(i) = currentGlobalId;
5177 partitionCellList(j, 0) = i;
5179 MFloat currentWorkload = weight(i);
5184 traverseDFGlobalId(i, ¤tGlobalId, partitionCellList, workloadPerCell, ¤tWorkload, weight, workload, &j);
5186 MLong noOffsprings = 0;
5187 if((i == 0) && (0 == m_noMissingParents))
5188 noOffsprings = currentGlobalId - m_cellOffsetPar;
5190 noOffsprings = currentGlobalId - a_globalId(i);
5193 partitionCellList(last, 1) = noOffsprings;
5194 workloadPerCell(last) = currentWorkload;
5197 m_log <<
" * finding partition cells" << endl;
5198 outStream <<
" * finding partition cells" << endl;
5201 for(
MInt i = 0; i < m_noCells; i++) {
5202 MLong noOffsprings = partitionCellList(i, 1);
5205 MBool hasHaloChilds =
false;
5206 for(
MInt child = 0; child < m_maxNoChildren; ++child) {
5207 MInt t_child = (
MInt)a_childId(i, child);
5211 if(a_hasProperty(t_child, 4) == 1) {
5212 hasHaloChilds =
true;
5221 const MFloat work = workloadPerCell(i);
5223 MBool isSolverLeafCell =
false;
5227 if(m_noSolvers > 1) {
5228 const MLong tmpCellId = partitionCellList(i, 0);
5229 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
5230 if(!a_isInSolver((
MInt)tmpCellId, solver)) {
5235 MBool hasSolverChild =
false;
5236 for(
MInt child = 0; child < m_maxNoChildren; ++child) {
5237 const MInt t_child = (
MInt)a_childId((
MInt)tmpCellId, child);
5241 if(a_isInSolver(t_child, solver)) {
5242 hasSolverChild =
true;
5248 if(!hasSolverChild) {
5249 m_log <<
"found solver leaf cell " << i <<
" id" << tmpCellId <<
" b" << solver <<
" l" << a_level(i) <<
" l"
5250 << a_level((
MInt)tmpCellId) << std::endl;
5251 isSolverLeafCell =
true;
5257 if((noOffsprings <= m_partitionCellOffspringThreshold && work <= (
MFloat)m_partitionCellWorkloadThreshold)
5258 || isSolverLeafCell) {
5259 if(isSolverLeafCell) {
5260 m_log <<
"partition solver leaf cell " << i <<
" " << partitionCellList(i, 0) <<
" l" << a_level(i) <<
" o"
5261 << noOffsprings << std::endl;
5263 m_partitionCellList.push_back(make_tuple(partitionCellList(i, 0), noOffsprings, work));
5264 i += (
MInt)noOffsprings;
5269 m_noPartitionCells = (
MInt)m_partitionCellList.
size();
5271 m_log <<
" - found " << m_noPartitionCells << endl;
5272 outStream <<
" - found " << m_noPartitionCells << endl;
5274 RECORD_TIMER_STOP(t_ro);
5302 MLong* children = &a_childId(parentId_, 0);
5304 for(
MInt c = 0; c < m_maxNoChildren; c++) {
5305 if(children[c] > -1) {
5307 && (a_hasProperty((
MInt)children[c], 4)
5313 *currentWorkload = *currentWorkload + weight((
MInt)children[c]);
5315 *globalId_ = *globalId_ + 1;
5317 a_globalId((
MInt)children[c]) = *globalId_;
5319 workload((
MInt)children[c]) = *currentWorkload;
5322 partitionCellList(*j, 0) = children[c];
5327 traverseDFGlobalId((
MInt)children[c], globalId_, partitionCellList, workloadPerCell, currentWorkload, weight,
5330 MLong noOffsprings = 0;
5331 noOffsprings = *(globalId_)-a_globalId((
MInt)children[c]);
5334 MFloat work = *currentWorkload - workload((
MInt)children[c]) + weight((
MInt)children[c]);
5337 partitionCellList(last, 1) = noOffsprings;
5339 workloadPerCell(last) = work;
5360 m_log <<
"applying weight method " << m_weightMethod << endl;
5361 switch(m_weightMethod) {
5367 for(
MInt i = 0; i < noWeightCoordinates; i++) {
5368 if((i + 1) % 2 == 0)
5369 weightCoordinates[i] = 10000;
5371 weightCoordinates[i] = -10000;
5374 for(
MInt i = 0; i < noWeightCoordinates; i++) {
5386 weightCoordinates[i] = Context::getBasicProperty<MFloat>(
"weightCoordinates", AT_, &weightCoordinates.p[i], i);
5387 m_log <<
"weight coordinate [" << i <<
"] = " << weightCoordinates[i] << endl;
5391 if(noWeightValues != (m_maxRfnmntLvl - m_minLevel + 1)) {
5392 stringstream errorMsg;
5393 errorMsg <<
"ERROR: noWeightValues not correct = " << noWeightValues;
5394 m_log << errorMsg.str() << endl;
5395 mTerm(1, AT_, errorMsg.str());
5398 setWeightValue.fill(1);
5399 MInt levelCnt = m_maxRfnmntLvl;
5400 for(
MInt i = 0; i < noWeightValues; i++) {
5411 setWeightValue(i) = Context::getBasicProperty<MFloat>(
"setWeightValue", AT_, &setWeightValue(i), i);
5412 m_log <<
"weight values [" << i <<
"] = " << setWeightValue(i) <<
" on level " << levelCnt << endl;
5416 for(
MInt level_ = m_maxRfnmntLvl; level_ >= m_minLevel; --level_) {
5417 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
5418 if(a_coordinate(i, 0) > weightCoordinates[0] && a_coordinate(i, 0) < weightCoordinates[1]
5419 && a_coordinate(i, 1) > weightCoordinates[2] && a_coordinate(i, 1) < weightCoordinates[3]
5420 && a_coordinate(i, 2) > weightCoordinates[4] && a_coordinate(i, 2) < weightCoordinates[5]) {
5421 weight(i) = setWeightValue(m_maxRfnmntLvl - level_);
5432 for(
MInt i = 0; i < noWeightCoordinates; i++) {
5433 if((i + 1) % 2 == 0)
5434 weightCoordinates[i] = 10000;
5436 weightCoordinates[i] = -10000;
5439 for(
MInt i = 0; i < noWeightCoordinates; i++) {
5451 weightCoordinates[i] = Context::getBasicProperty<MFloat>(
"weightCoordinates", AT_, &weightCoordinates.p[i], i);
5452 m_log <<
"weight coordinate [" << i <<
"] = " << weightCoordinates[i] << endl;
5456 if(noWeightValues != (m_maxRfnmntLvl - m_minLevel + 1)) {
5457 stringstream errorMsg;
5458 errorMsg <<
"ERROR: noWeightValues not correct = " << noWeightValues;
5459 m_log << errorMsg.str() << endl;
5460 mTerm(1, AT_, errorMsg.str());
5463 setWeightValue.fill(1);
5464 MInt levelCnt = m_maxRfnmntLvl;
5465 for(
MInt i = 0; i < noWeightValues; i++) {
5476 setWeightValue(i) = Context::getBasicProperty<MFloat>(
"setWeightValue", AT_, &setWeightValue(i), i);
5477 m_log <<
"weight values [" << i <<
"] = " << setWeightValue(i) <<
" on level " << levelCnt << endl;
5481 MInt level_ = m_maxRfnmntLvl;
5482 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
5483 if(a_coordinate(i, 0) > weightCoordinates[0] && a_coordinate(i, 0) < weightCoordinates[1]
5484 && a_coordinate(i, 1) > weightCoordinates[2] && a_coordinate(i, 1) < weightCoordinates[3]
5485 && a_coordinate(i, 2) > weightCoordinates[4] && a_coordinate(i, 2) < weightCoordinates[5]) {
5486 weight(i) = setWeightValue(m_maxRfnmntLvl - level_);
5493 if(noWeightValues != (m_maxRfnmntLvl - m_minLevel + 1)) {
5494 stringstream errorMsg;
5495 errorMsg <<
"ERROR: noWeightValues not correct = " << noWeightValues;
5496 m_log << errorMsg.str() << endl;
5497 mTerm(1, AT_, errorMsg.str());
5500 setWeightValue.fill(1);
5501 MInt levelCnt = m_maxRfnmntLvl;
5502 for(
MInt i = 0; i < noWeightValues; i++) {
5513 setWeightValue(i) = Context::getBasicProperty<MFloat>(
"setWeightValue", AT_, &setWeightValue(i), i);
5514 m_log <<
"weight values [" << i <<
"] = " << setWeightValue(i) <<
" on level " << levelCnt << endl;
5518 for(
MInt level_ = m_maxRfnmntLvl; level_ >= m_minLevel; --level_) {
5519 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
5520 weight(i) = setWeightValue(m_maxRfnmntLvl - level_);
5528 if(noWeightValues != (m_maxRfnmntLvl - m_minLevel + 1)) {
5529 stringstream errorMsg;
5530 errorMsg <<
"ERROR: noWeightValues not correct = " << noWeightValues;
5531 m_log << errorMsg.str() << endl;
5532 mTerm(1, AT_, errorMsg.str());
5535 setWeightValue.fill(1);
5536 MInt levelCnt = m_maxRfnmntLvl;
5537 for(
MInt i = 0; i < noWeightValues; i++) {
5548 setWeightValue(i) = Context::getBasicProperty<MFloat>(
"setWeightValue", AT_, &setWeightValue(i), i);
5549 m_log <<
"weight values [" << i <<
"] = " << setWeightValue(i) <<
" on level " << levelCnt << endl;
5553 for(
MInt level_ = m_maxRfnmntLvl; level_ >= m_minLevel; --level_) {
5554 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
5555 if(a_noChildren(i) == 0 && a_hasProperty(i, 1) == 1)
5556 weight(i) = setWeightValue(m_maxRfnmntLvl - level_);
5557 else if(a_noChildren(i) == 0)
5558 weight(i) = setWeightValue(m_maxRfnmntLvl - level_) + 0.3;
5568 for(
MInt level_ = m_maxRfnmntLvl; level_ >= m_minLevel; --level_) {
5569 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
5570 if(a_noChildren(i) > 0) {
5574 if(checkCellForCut(i)) {
5582 IF_CONSTEXPR(nDim == 3) {
5586 TERMM(1,
"Need to give a Coordinate for every dimension");
5589 for(
MInt i = 0; i < nDim; i++) {
5590 spawnCoord[i] = Context::getBasicProperty<MFloat>(
"spawnCoordinates", AT_, i);
5593 for(
MInt i = m_levelOffsets[m_maxRfnmntLvl][0]; i < m_levelOffsets[m_maxRfnmntLvl][1]; i++) {
5594 if(a_coordinate(i, 0) > spawnCoord[0] - 0.001 && a_coordinate(i, 0) < spawnCoord[0] + 0.001
5595 && a_coordinate(i, 1) > spawnCoord[1] - 0.001 && a_coordinate(i, 1) < spawnCoord[1] + 0.001
5596 && a_coordinate(i, 2) > spawnCoord[2] && a_coordinate(i, 2) < spawnCoord[2] + 0.02) {
5607 stringstream errorMessage;
5608 errorMessage <<
"ERROR: weight method does not exist! ";
5609 mTerm(1, AT_, errorMessage.str());
5628 for(
MInt dir0 = 0; dir0 < 2 * nDim; dir0++) {
5629 MLong nghbrId0 = -1;
5630 if(a_neighborId(cellId, dir0) > -1) nghbrId0 = a_neighborId(cellId, dir0);
5631 if(nghbrId0 < 0)
continue;
5632 nghbrs.insert(nghbrId0);
5633 for(
MInt dir1 = 0; dir1 < 2 * nDim; dir1++) {
5634 if((dir1 / 2) == (dir0 / 2))
continue;
5635 MLong nghbrId1 = -1;
5636 if(a_neighborId((
MInt)nghbrId0, dir1) > -1) nghbrId1 = a_neighborId((
MInt)nghbrId0, dir1);
5637 if(nghbrId1 < 0)
continue;
5638 nghbrs.insert(nghbrId1);
5639 IF_CONSTEXPR(nDim == 3) {
5640 for(
MInt dir2 = 0; dir2 < 2 * nDim; dir2++) {
5641 if(((dir2 / 2) == (dir0 / 2)) || ((dir2 / 2) == (dir1 / 2)))
continue;
5642 MLong nghbrId2 = -1;
5643 if(a_neighborId((
MInt)nghbrId1, dir2) > -1) nghbrId2 = a_neighborId((
MInt)nghbrId1, dir2);
5644 if(nghbrId2 < 0)
continue;
5645 nghbrs.insert(nghbrId2);
5650 set<MLong>::iterator it = nghbrs.begin();
5651 for(it = nghbrs.begin(); it != nghbrs.end(); it++) {
5652 ASSERT(cnt < 27,
"");
5653 adjacentCells[cnt] = (
MInt)*it;
5671 NEW_SUB_TIMER_STATIC(t_checkLBRefinementValidity,
"check refinement valdity for LB", m_t_finalizeGrid);
5672 RECORD_TIMER_START(t_checkLBRefinementValidity);
5674 outStream <<
" + checking mesh validity for LB" << endl;
5675 m_log <<
" + checking mesh validity for LB" << endl;
5681 set<MInt> lberrcells;
5684 for(
MInt i = 0; i < m_noCells; ++i) {
5686 if(a_noChildren(i) == 0) {
5690 if(parent >= 0 && a_noChildren(parent) != m_maxNoChildren) {
5692 for(
MInt l = 0; l < 27; l++)
5695 const MInt counter = getAdjacentGridCells(parent, nghbrList.
begin());
5696 for(
MInt n = 0; n < counter; n++) {
5697 if(nghbrList[n] > -1 && a_noChildren(nghbrList[n]) == 0 && !a_hasProperty(nghbrList[n], 5)) {
5698 lberrcells.insert(parent);
5707 MInt errorcells = 0;
5708 MInt l_lberrcells = (
MInt)lberrcells.size();
5710 MPI_Allreduce(&l_lberrcells, &errorcells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"l_lberrcells",
"errorcells");
5712 if(errorcells > 0) {
5713 outStream <<
" * \033[1;31mthere are " << errorcells <<
" errorneous cells\033[0m" << endl;
5715 <<
" - \033[1;31mEXPLANATION: there are cells that will be interface cells in the LB computation and "
5716 "which have missing children\033[0m"
5718 outStream <<
" - \033[1;31mHINTS : try to refine in- and outlets\033[0m" << endl;
5720 <<
" \033[1;31mmake sure you chose a good combination of localMinBoundaryThreshold and "
5721 "smoothDistance\033[0m"
5723 m_log <<
" * there are " << errorcells <<
" errorneous cells" << endl;
5724 m_log <<
" - EXPLANATION: there are cells that will be interface cells in the LB computation and which "
5725 "have missing children"
5727 m_log <<
" - HINTS : try to refine in- and outlets" << endl;
5728 m_log <<
" make sure you chose a good combination of localMinBoundaryThreshold and "
5732 outStream <<
" * mesh is \033[1;32mOK\033[0m" << endl;
5733 m_log <<
" * mesh is OK" << endl;
5737 RECORD_TIMER_STOP(t_checkLBRefinementValidity);
5761 checkMemoryAvailability(1, compRfnLvl + 1);
5764 refineGridPatch(m_levelOffsets, compRfnLvl, 0);
5765 if(noDomains() > 1) {
5766 refineGridPatch(m_haloCellOffsetsLevel, compRfnLvl, 1);
5770 m_noCells = m_levelOffsets[compRfnLvl + 1][1];
5773 findChildLevelNeighbors(m_levelOffsets, compRfnLvl);
5774 if(noDomains() > 1) {
5775 findChildLevelNeighbors(m_haloCellOffsetsLevel, compRfnLvl);
5779 if(noDomains() > 1) {
5780 deleteOutsideCellsParallel(compRfnLvl + 1);
5782 deleteOutsideCellsSerial(compRfnLvl + 1);
5786 m_noCells = m_levelOffsets[compRfnLvl + 1][1];
5790 checkLoadBalance(compRfnLvl);
5828 NEW_SUB_TIMER_STATIC(t_boundaryPropagation,
"boundary propagation", m_t_createComputationalGrid);
5829 RECORD_TIMER_START(t_boundaryPropagation);
5831 m_log <<
" marking boundary cells: ";
5834 vector<MInt> boundaryCells;
5835 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
5836 a_refinementDistance(i) = numeric_limits<MInt>::max();
5837 if(a_isSolverBoundary(i, solver)) {
5840 for(
MInt b = 0;
b < (
MInt)rfnBoundaryGroup.size();
b++) {
5841 if(m_bndCutInfo[solver][rfnBoundaryGroup[
b]]) {
5842 boundaryCells.push_back(i);
5849 if(noDomains() > 1) {
5850 MInt lev_pos = 2 * (level_ - m_minLevel);
5851 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
5852 for(
MInt i = m_haloCellOffsets[dom][lev_pos]; i < m_haloCellOffsets[dom][lev_pos + 1]; i++) {
5853 a_refinementDistance(i) = numeric_limits<MInt>::max();
5854 if(a_isSolverBoundary(i, solver)) {
5857 for(
MInt b = 0;
b < (
MInt)rfnBoundaryGroup.size();
b++) {
5858 if(m_bndCutInfo[solver][rfnBoundaryGroup[
b]]) {
5859 boundaryCells.push_back(i);
5869 for(
MInt i = 0; i < (
MInt)boundaryCells.size(); i++)
5870 propagationStep(boundaryCells[i], 0, distance, solver);
5873 if(noDomains() > 1) {
5877 vector<vector<MInt>> winCellIdsPerDomain(m_noNeighborDomains, vector<MInt>(0));
5878 vector<vector<MInt>> haloCellIdsPerDomain(m_noNeighborDomains, vector<MInt>(0));
5880 if(m_hasBeenLoadBalanced)
5881 findHaloAndWindowCellsKD(winCellIdsPerDomain, haloCellIdsPerDomain);
5883 findHaloAndWindowCells(winCellIdsPerDomain, haloCellIdsPerDomain);
5886 MIntScratchSpace noSendWindowPerDomain(m_noNeighborDomains, AT_,
"noSendWindowPerDomain");
5887 MIntScratchSpace noReceiveHaloPerDomain(m_noNeighborDomains, AT_,
"noReceiveHaloPerDomain");
5889 m_log <<
" - we need to transfer to domain [no. cells to transfer]: ";
5890 outStream <<
" - we need to transfer to domain [no. cells to transfer]: ";
5891 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
5892 noSendWindowPerDomain[d] = (
MInt)winCellIdsPerDomain[d].size();
5893 m_log << m_neighborDomains[d] <<
" [" << noSendWindowPerDomain[d] <<
"] ";
5894 outStream << m_neighborDomains[d] <<
" [" << noSendWindowPerDomain[d] <<
"] ";
5899 m_log <<
" - we need to receive from domain [no. cells to receive]: ";
5900 outStream <<
" - we need to receive from domain [no. cells to receive]: ";
5901 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
5902 noReceiveHaloPerDomain[d] = (
MInt)haloCellIdsPerDomain[d].size();
5903 m_log << m_neighborDomains[d] <<
" [" << noReceiveHaloPerDomain[d] <<
"] ";
5904 outStream << m_neighborDomains[d] <<
" [" << noReceiveHaloPerDomain[d] <<
"] ";
5910 MInt allReceive = 0;
5911 vector<MInt> offsetsSend;
5912 vector<MInt> offsetsReceive;
5913 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
5914 offsetsSend.push_back(allSend);
5915 offsetsReceive.push_back(allReceive);
5916 allSend += noSendWindowPerDomain[dom];
5917 allReceive += noReceiveHaloPerDomain[dom];
5933 MPI_Request* mpi_request_ =
nullptr;
5934 mAlloc(mpi_request_, m_noNeighborDomains,
"mpi_request_", AT_);
5935 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
5936 for(
MInt c = 0; c < noSendWindowPerDomain[d]; c++) {
5937 sndBufWin[offsetsSend[d] + c] = a_refinementDistance(winCellIdsPerDomain[d][c]);
5939 MPI_Issend(&(sndBufWin[offsetsSend[d]]), noSendWindowPerDomain[d], MPI_INT, m_neighborDomains[d], 0, mpiComm(),
5940 &mpi_request_[d], AT_,
"(sndBufWin[offsetsSend[d]])");
5944 for(
MInt d = 0; d < m_noNeighborDomains; d++)
5945 MPI_Recv(&(rcvBufHalo[offsetsReceive[d]]), noReceiveHaloPerDomain[d], MPI_INT, m_neighborDomains[d], 0,
5946 mpiComm(), &status_, AT_,
"(rcvBufHalo[offsetsReceive[d]])");
5948 for(
MInt d = 0; d < m_noNeighborDomains; d++)
5949 MPI_Wait(&mpi_request_[d], &status_, AT_);
5951 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
5952 for(
MInt c = 0; c < noReceiveHaloPerDomain[d]; c++) {
5953 const MInt halo = haloCellIdsPerDomain[d][c];
5954 if(rcvBufHalo[c + offsetsReceive[d]] < a_refinementDistance(halo)) {
5955 propagationStep(halo, rcvBufHalo[c + offsetsReceive[d]], distance, solver);
5961 MPI_Allreduce(MPI_IN_PLACE, &finished, 1, MPI_UNSIGNED_SHORT, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
5966 m_log <<
" - communication rounds required: " << rounds << endl;
5969 RECORD_TIMER_STOP(t_boundaryPropagation);
5992 NEW_SUB_TIMER_STATIC(t_markRfnDistance,
"mark refinement distance", m_t_createComputationalGrid);
5993 if(rfnDistance == 0) {
5994 RECORD_TIMER_START(t_markRfnDistance);
5997 if(a_refinementDistance(cellId) > rfnDistance) {
5998 a_refinementDistance(cellId) = rfnDistance;
6000 if(rfnDistance < (finalDistance - 1)) {
6001 for(
MInt n = 0; n < m_noNeighbors; n++) {
6002 if(a_neighborId(cellId, n) > -1) {
6003 if(a_isInSolver((
MInt)a_neighborId(cellId, n), solver)) {
6004 propagationStep((
MInt)a_neighborId(cellId, n), rfnDistance + 1, finalDistance, solver);
6011 if(rfnDistance == 0) {
6012 RECORD_TIMER_STOP(t_markRfnDistance);
6043 m_log <<
" * marking local box for solver " << solver << endl;
6044 m_log <<
" - corner1: ";
6045 for(
MInt d = 0; d < nDim; d++) {
6048 m_log << endl <<
" - corner2: ";
6049 for(
MInt d = nDim; d < 2 * nDim; d++) {
6054 for(
MInt k = m_levelOffsets[gridLvl][0]; k < m_levelOffsets[gridLvl][1]; k++) {
6055 if(a_isInSolver(k, solver)) {
6057 a_isToRefineForSolver(k, solver) = 1;
6063 if(noDomains() > 1) {
6064 MInt lev_pos = 2 * (gridLvl - m_minLevel);
6065 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
6066 for(
MInt k = m_haloCellOffsets[dom][lev_pos]; k < m_haloCellOffsets[dom][lev_pos + 1]; k++) {
6067 if(a_isInSolver(k, solver)) {
6069 a_isToRefineForSolver(k, solver) = 1;
6110 m_log <<
" * marking local sphere for solver " << solver << endl;
6111 m_log <<
" - center: ";
6112 for(
MInt d = 0; d < nDim; d++) {
6113 m_log << sphereCoord[d] <<
" ";
6115 m_log << endl <<
" - radius: " << radius << endl;
6117 for(
MInt k = m_levelOffsets[gridLvl][0]; k < m_levelOffsets[gridLvl][1]; k++) {
6118 if(a_isInSolver(k, solver)) {
6119 if(maia::geom::isPointInsideSphere<nDim>(&a_coordinate(k, 0), sphereCoord, radius)) {
6120 a_isToRefineForSolver(k, solver) = 1;
6126 if(noDomains() > 1) {
6127 MInt lev_pos = 2 * (gridLvl - m_minLevel);
6128 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
6129 for(
MInt k = m_haloCellOffsets[dom][lev_pos]; k < m_haloCellOffsets[dom][lev_pos + 1]; k++) {
6130 if(a_isInSolver(k, solver)) {
6131 if(maia::geom::isPointInsideSphere<nDim>(&a_coordinate(k, 0), sphereCoord, radius)) {
6132 a_isToRefineForSolver(k, solver) = 1;
6169 if(patchStr !=
"C" && patchStr !=
"T") {
6170 TERMM(1,
"This function doesn't support the selected patch type!");
6173 const MBool isTube = (patchStr ==
"T") ?
true :
false;
6181 m_log <<
" * marking local tube for solver " << solver << endl;
6183 m_log <<
" * marking local cylinder for solver " << solver << endl;
6187 std::array<MFloat, nDim> leftCoord;
6188 std::array<MFloat, nDim> rightCoord;
6189 for(
MInt d = 0; d < nDim; d++) {
6194 m_log <<
" - left center: ";
6195 for(
MInt d = 0; d < nDim; d++) {
6196 m_log << leftCoord[d] <<
" ";
6198 m_log <<
" - right center: ";
6199 for(
MInt d = 0; d < nDim; d++) {
6200 m_log << rightCoord[d] <<
" ";
6204 m_log <<
" - radius: " << radius << endl;
6205 MFloat innerRadius = -1.0;
6212 std::array<MFloat, nDim> normalDiffAB;
6213 std::array<MFloat, nDim> normalDiffBA;
6215 for(
MInt d = 0; d < nDim; d++) {
6216 normalDiffAB[d] = rightCoord[d] - leftCoord[d];
6217 normalDiffBA[d] = leftCoord[d] - rightCoord[d];
6218 length += normalDiffAB[d] * normalDiffAB[d];
6220 length = sqrt(length);
6222 for(
MInt d = 0; d < nDim; d++) {
6223 normalDiffAB[d] /= length;
6228 for(
MInt k = m_levelOffsets[gridLvl][0]; k < m_levelOffsets[gridLvl][1]; k++) {
6229 if(a_isInSolver(k, solver)) {
6230 if(isInsideCylinder(&a_coordinate(k, 0), leftCoord.data(), rightCoord.data(), normalDiffAB.data(),
6231 normalDiffBA.data(), radius, innerRadius)) {
6232 a_isToRefineForSolver(k, solver) = 1;
6238 if(noDomains() > 1) {
6239 MInt lev_pos = 2 * (gridLvl - m_minLevel);
6240 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
6241 for(
MInt k = m_haloCellOffsets[dom][lev_pos]; k < m_haloCellOffsets[dom][lev_pos + 1]; k++) {
6242 if(a_isInSolver(k, solver)) {
6243 if(isInsideCylinder(&a_coordinate(k, 0), leftCoord.data(), rightCoord.data(), normalDiffAB.data(),
6244 normalDiffBA.data(), radius, innerRadius)) {
6245 a_isToRefineForSolver(k, solver) = 1;
6268 const MFloat*
const rightCoord,
const MFloat*
const normalDiffAB,
6270 const MFloat innerRadius) {
6273 std::array<MFloat, nDim> diffA;
6274 std::array<MFloat, nDim> diffB;
6278 for(
MInt d = 0; d < nDim; d++) {
6279 diffA[d] = pointCoord[d] - leftCoord[d];
6280 diffB[d] = pointCoord[d] - rightCoord[d];
6281 s1 += diffA[d] * normalDiffAB[d];
6282 s2 += diffB[d] * normalDiffBA[d];
6285 std::array<MFloat, nDim> cross;
6287 for(
MInt d = 0; d < nDim; d++) {
6288 MInt p1 = (d + 1) % (nDim);
6289 MInt p2 = (d + 2) % (nDim);
6291 cross[d] = diffA[p1] * normalDiffAB[p2] - normalDiffAB[p1] * diffA[p2];
6292 distance += cross[d] * cross[d];
6294 distance = sqrt(distance);
6296 if(distance <= radius && distance >= innerRadius && s1 >= 0.0 && s2 >= 0.0) {
6311 m_log <<
" * marking local cylinder for solver " << solver << endl;
6312 m_log <<
" - min center: ";
6313 for(
MInt d = 0; d < nDim; d++) {
6326 if(axis >= nDim)
mTerm(1, AT_,
"cylinder wedge refinement: axis out of bounds! Must be < nDim");
6328 for(
MInt k = m_levelOffsets[gridLvl][0]; k < m_levelOffsets[gridLvl][1]; k++) {
6329 if(a_isInSolver(k, solver)) {
6330 MFloat* coords = &a_coordinate(k, 0);
6338 std::array<MFloat, nDim> normalVector;
6340 for(
MInt d = 0; d < nDim; d++) {
6342 normalVector[d] = 0.0;
6345 distance += normalVector[d] * normalVector[d];
6347 distance = sqrt(distance);
6353 MFloat angle = atan2(normalVector[(axis + 2) % nDim], normalVector[(axis + 1) % nDim]) * 180.0 / PI;
6358 a_isToRefineForSolver(k, solver) = 1;
6362 if(noDomains() > 1) {
6363 MInt lev_pos = 2 * (gridLvl - m_minLevel);
6364 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
6365 for(
MInt k = m_haloCellOffsets[dom][lev_pos]; k < m_haloCellOffsets[dom][lev_pos + 1]; k++) {
6366 if(a_isInSolver(k, solver)) {
6367 MFloat* coords = &a_coordinate(k, 0);
6373 std::array<MFloat, nDim> normalVector;
6375 for(
MInt d = 0; d < nDim; d++) {
6377 normalVector[d] = 0.0;
6380 distance += normalVector[d] * normalVector[d];
6382 distance = sqrt(distance);
6387 MFloat angle = atan2(normalVector[(axis + 2) % nDim], normalVector[(axis + 1) % nDim]) * 180.0 / PI;
6392 a_isToRefineForSolver(k, solver) = 1;
6431 m_log <<
" * marking local angled rectangle for solver " << solver << endl;
6432 m_log <<
" - left center: ";
6433 for(
MInt d = 0; d < nDim; d++) {
6436 m_log <<
" - right center: ";
6437 for(
MInt d = nDim; d < 2 * nDim; d++) {
6447 std::array<MFloat, nDim> normalDiffAB;
6448 std::array<MFloat, nDim> normalDiffBA;
6450 for(
MInt d = 0; d < nDim; d++) {
6453 length += normalDiffAB[d] * normalDiffAB[d];
6456 length = sqrt(length);
6458 for(
MInt d = 0; d < nDim; d++) {
6459 normalDiffAB[d] /= length;
6464 for(
MInt k = m_levelOffsets[gridLvl][0]; k < m_levelOffsets[gridLvl][1]; k++) {
6465 if(a_isInSolver(k, solver)) {
6466 MFloat* coords = &a_coordinate(k, 0);
6468 std::array<MFloat, nDim> diffA;
6469 std::array<MFloat, nDim> diffB;
6473 for(
MInt d = 0; d < nDim; d++) {
6476 s1 += diffA[d] * normalDiffAB[d];
6477 s2 += diffB[d] * normalDiffBA[d];
6480 std::array<MFloat, nDim> cross;
6485 for(
MInt d = 0; d < nDim; d++) {
6486 MInt p1 = (d + 1) % (nDim);
6487 MInt p2 = (d + 2) % (nDim);
6489 cross[d] = diffA[p1] * normalDiffAB[p2] - normalDiffAB[p1] * diffA[p2];
6491 distanceH += cross[d] * cross[d];
6494 distanceH += cross[d] * cross[d];
6497 distanceW += cross[d] * cross[d];
6500 distanceH = sqrt(distanceH);
6501 distanceW = sqrt(distanceW);
6503 if(distanceH <= bp->localRfnPatchProperties[pos][2 * nDim]
6504 && distanceW <= bp->localRfnPatchProperties[pos][2 * nDim + 1] && s1 >= 0.0 && s2 >= 0.0) {
6505 a_isToRefineForSolver(k, solver) = 1;
6511 if(noDomains() > 1) {
6512 MInt lev_pos = 2 * (gridLvl - m_minLevel);
6513 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
6514 for(
MInt k = m_haloCellOffsets[dom][lev_pos]; k < m_haloCellOffsets[dom][lev_pos + 1]; k++) {
6515 if(a_isInSolver(k, solver)) {
6516 MFloat* coords = &a_coordinate(k, 0);
6518 std::array<MFloat, nDim> diffA;
6519 std::array<MFloat, nDim> diffB;
6523 for(
MInt d = 0; d < nDim; d++) {
6526 s1 += diffA[d] * normalDiffAB[d];
6527 s2 += diffB[d] * normalDiffBA[d];
6530 std::array<MFloat, nDim> cross;
6535 for(
MInt d = 0; d < nDim; d++) {
6536 MInt p1 = (d + 1) % (nDim);
6537 MInt p2 = (d + 2) % (nDim);
6539 cross[d] = diffA[p1] * normalDiffAB[p2] - normalDiffAB[p1] * diffA[p2];
6541 distanceH += cross[d] * cross[d];
6544 distanceH += cross[d] * cross[d];
6547 distanceW += cross[d] * cross[d];
6550 distanceH = sqrt(distanceH);
6551 distanceW = sqrt(distanceW);
6553 if(distanceH <= bp->localRfnPatchProperties[pos][2 * nDim]
6554 && distanceW <= bp->localRfnPatchProperties[pos][2 * nDim + 1] && s1 >= 0.0 && s2 >= 0.0) {
6555 a_isToRefineForSolver(k, solver) = 1;
6596 m_log <<
" * marking local rounded cone for solver " << solver << endl;
6597 m_log <<
" - left point: ";
6598 for(
MInt d = 0; d < nDim; d++) {
6601 m_log <<
" - right point: ";
6602 for(
MInt d = nDim; d < 2 * nDim; d++) {
6613 MFloat angle_rad = angle * PI / 180.0;
6615 MFloat radius = Radius * cos(angle_rad);
6617 std::array<MFloat, nDim> normalDifforigAB;
6619 for(
MInt d = 0; d < nDim; d++) {
6621 length += normalDifforigAB[d] * normalDifforigAB[d];
6624 length = sqrt(length);
6626 for(
MInt d = 0; d < nDim; d++)
6627 normalDifforigAB[d] /= length;
6630 std::array<MFloat, nDim> newPosA;
6631 std::array<MFloat, nDim> sphereCenter;
6632 std::array<MFloat, nDim> normalDiffAB;
6633 std::array<MFloat, nDim> normalDiffBA;
6635 for(
MInt d = 0; d < nDim; d++) {
6643 lengthAB += normalDiffAB[d] * normalDiffAB[d];
6646 lengthAB = sqrt(lengthAB);
6648 for(
MInt d = 0; d < nDim; d++) {
6649 normalDiffAB[d] /= lengthAB;
6654 for(
MInt k = m_levelOffsets[gridLvl][0]; k < m_levelOffsets[gridLvl][1]; k++) {
6655 if(a_isInSolver(k, solver)) {
6656 MFloat* coords = &a_coordinate(k, 0);
6658 std::array<MFloat, nDim> diffA;
6659 std::array<MFloat, nDim> difforigA;
6660 std::array<MFloat, nDim> diffB;
6661 std::array<MFloat, nDim> diffCenter;
6665 MFloat len_diffOrig = 0.0;
6666 MFloat len_diffCenter = 0.0;
6667 for(
MInt d = 0; d < nDim; d++) {
6668 diffA[d] = coords[d] - newPosA[d];
6671 diffCenter[d] = coords[d] - sphereCenter[d];
6673 s1 += diffA[d] * normalDiffAB[d];
6674 s2 += diffB[d] * normalDiffBA[d];
6675 len_diffOrig += difforigA[d] * difforigA[d];
6676 len_diffCenter += diffCenter[d] * diffCenter[d];
6679 len_diffOrig = sqrt(len_diffOrig);
6680 len_diffCenter = sqrt(len_diffCenter);
6682 std::array<MFloat, nDim> cross;
6684 for(
MInt d = 0; d < nDim; d++) {
6685 MInt p1 = (d + 1) % (nDim);
6686 MInt p2 = (d + 2) % (nDim);
6688 cross[d] = diffA[p1] * normalDiffAB[p2] - normalDiffAB[p1] * diffA[p2];
6689 distance += cross[d] * cross[d];
6692 distance = sqrt(distance);
6694 MFloat ang = asin(distance / len_diffOrig) * 180 / PI;
6696 if((ang <= angle && s1 >= 0.0 && s2 >= 0.0) || len_diffCenter <= Radius) {
6697 a_isToRefineForSolver(k, solver) = 1;
6703 if(noDomains() > 1) {
6704 MInt lev_pos = 2 * (gridLvl - m_minLevel);
6706 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
6707 for(
MInt k = m_haloCellOffsets[dom][lev_pos]; k < m_haloCellOffsets[dom][lev_pos + 1]; k++) {
6708 if(a_isInSolver(k, solver)) {
6709 MFloat* coords = &a_coordinate(k, 0);
6711 std::array<MFloat, nDim> diffA;
6712 std::array<MFloat, nDim> difforigA;
6713 std::array<MFloat, nDim> diffB;
6714 std::array<MFloat, nDim> diffCenter;
6718 MFloat len_diffOrig = 0.0;
6719 MFloat len_diffCenter = 0.0;
6720 for(
MInt d = 0; d < nDim; d++) {
6721 diffA[d] = coords[d] - newPosA[d];
6724 diffCenter[d] = coords[d] - sphereCenter[d];
6726 s1 += diffA[d] * normalDiffAB[d];
6727 s2 += diffB[d] * normalDiffBA[d];
6728 len_diffOrig += difforigA[d] * difforigA[d];
6729 len_diffCenter += diffCenter[d] * diffCenter[d];
6732 len_diffOrig = sqrt(len_diffOrig);
6733 len_diffCenter = sqrt(len_diffCenter);
6735 std::array<MFloat, nDim> cross;
6737 for(
MInt d = 0; d < nDim; d++) {
6738 MInt p1 = (d + 1) % (nDim);
6739 MInt p2 = (d + 2) % (nDim);
6741 cross[d] = diffA[p1] * normalDiffAB[p2] - normalDiffAB[p1] * diffA[p2];
6742 distance += cross[d] * cross[d];
6745 distance = sqrt(distance);
6747 MFloat ang = asin(distance / len_diffOrig) * 180 / PI;
6749 if((ang <= angle && s1 >= 0.0 && s2 >= 0.0) || len_diffCenter <= Radius) {
6750 a_isToRefineForSolver(k, solver) = 1;
6781 if(patchStr !=
"A" && patchStr !=
"N") {
6782 TERMM(1,
"This function doesn't support the selected patch type!");
6785 const MBool isAligned = (patchStr ==
"A") ?
true :
false;
6792 m_log <<
" * marking local sliced cone for solver " << solver << endl;
6794 std::array<MFloat, nDim> leftCoord;
6795 std::array<MFloat, nDim> rightCoord;
6796 for(
MInt d = 0; d < nDim; d++) {
6801 m_log <<
" - left coord: ";
6802 for(
MInt d = 0; d < nDim; d++) {
6803 m_log << leftCoord[d] <<
" ";
6805 m_log << endl <<
" - right coord: ";
6806 for(
MInt d = 0; d < nDim; d++) {
6807 m_log << rightCoord[d] <<
" ";
6811 const MInt col = (isAligned) ? 2 : 4;
6815 m_log << endl <<
" - left radius: " << leftR << endl;
6816 m_log <<
" - right radius: " << rightR << endl;
6819 std::array<MFloat, nDim> normalDifforigAB;
6821 for(
MInt d = 0; d < nDim; d++) {
6822 normalDifforigAB[d] = rightCoord[d] - leftCoord[d];
6823 length += normalDifforigAB[d] * normalDifforigAB[d];
6825 length = sqrt(length);
6828 std::array<MFloat, nDim> leftNormal;
6829 std::array<MFloat, nDim> rightNormal;
6830 for(
MInt d = 0, i = 0; d < nDim; d++, i++) {
6832 rightNormal[d] = normalDifforigAB[d] / length;
6833 leftNormal[d] = -rightNormal[d];
6840 m_log <<
" - left normal: ";
6841 for(
MInt d = 0; d < nDim; d++) {
6842 m_log << leftNormal[d] <<
" ";
6844 m_log << endl <<
" - right normal: ";
6845 for(
MInt d = 0; d < nDim; d++) {
6846 m_log << rightNormal[d] <<
" ";
6853 MFloat leftNormalDir = 0.0;
6854 MFloat rightNormalDir = 0.0;
6855 MBool isAborting =
false;
6857 for(
MInt d = 0; d < nDim; d++) {
6858 leftNormalDir += (rightCoord[d] - leftCoord[d]) * leftNormal[d];
6859 rightNormalDir += (leftCoord[d] - rightCoord[d]) * rightNormal[d];
6861 if(
approx(normalDifforigAB[d], 0.0, MFloatEps) && !
approx(leftNormal[d], 0.0, MFloatEps)) {
6862 ss <<
"Warning: Normal values for the left circle are not valid at dir = " << d <<
"!" << endl;
6864 }
else if(
approx(normalDifforigAB[d], 0.0, MFloatEps) && !
approx(rightNormal[d], 0.0, MFloatEps)) {
6865 ss <<
"Warning: Normal values for the right circle are not valid at dir = " << d <<
"!" << endl;
6869 if((d == nDim - 1) && leftNormalDir >= 0.0 && rightNormalDir >= 0.0) {
6870 ss <<
"Warning: Normals are not consistent!" << endl;
6875 cerr << ss.str() <<
"Aborting...";
6876 m_log << ss.str() <<
"Aborting...";
6877 TERMM(1, ss.str() +
"Aborting...");
6883 for(
MInt k = m_levelOffsets[gridLvl][0]; k < m_levelOffsets[gridLvl][1]; k++) {
6884 if(a_isInSolver(k, solver)) {
6885 if(isInsideSlicedCone(&a_coordinate(k, 0), leftCoord.data(), rightCoord.data(), leftNormal.data(),
6886 rightNormal.data(), normalDifforigAB.data(), leftR, rightR)) {
6887 a_isToRefineForSolver(k, solver) = 1;
6893 if(noDomains() > 1) {
6894 MInt lev_pos = 2 * (gridLvl - m_minLevel);
6896 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
6897 for(
MInt k = m_haloCellOffsets[dom][lev_pos]; k < m_haloCellOffsets[dom][lev_pos + 1]; k++) {
6898 if(a_isInSolver(k, solver)) {
6899 if(isInsideSlicedCone(&a_coordinate(k, 0), leftCoord.data(), rightCoord.data(), leftNormal.data(),
6900 rightNormal.data(), normalDifforigAB.data(), leftR, rightR)) {
6901 a_isToRefineForSolver(k, solver) = 1;
6946 const MFloat*
const rightCoord,
const MFloat*
const leftNormal,
6947 const MFloat*
const rightNormal,
const MFloat*
const normalDifforigAB,
6956 for(
MInt d = 0; d < nDim; d++) {
6957 temp0 += (pointCoord[d] - leftCoord[d]) * normalDifforigAB[d];
6958 temp1 += normalDifforigAB[d] * normalDifforigAB[d];
6960 lambda = temp0 / temp1;
6965 std::array<MFloat, nDim> projectionCoord;
6967 for(
MInt d = 0; d < nDim; d++) {
6968 projectionCoord[d] = leftCoord[d] + lambda * normalDifforigAB[d];
6969 lengthPP += pow(pointCoord[d] - projectionCoord[d], 2);
6971 lengthPP = sqrt(lengthPP);
6972 if(lengthPP <= (leftR + lambda * (rightR - leftR))) {
6973 MFloat isPointDirLeftNormal = 0.0;
6974 MFloat isPointDirRightNormal = 0.0;
6976 for(
MInt d = 0; d < nDim; d++) {
6977 isPointDirLeftNormal += leftNormal[d] * (pointCoord[d] - leftCoord[d]);
6978 isPointDirRightNormal += rightNormal[d] * (pointCoord[d] - rightCoord[d]);
6981 if(isPointDirLeftNormal <= 0.0 && isPointDirRightNormal <= 0.0) {
7023 m_log <<
" * marking local hat for solver " << solver << endl;
7024 m_log <<
" - left point: ";
7025 for(
MInt d = 0; d < nDim; d++) {
7028 m_log <<
" - right point: ";
7029 for(
MInt d = nDim; d < 2 * nDim; d++) {
7043 MFloat angle_rad = angle * PI / 180.0;
7044 MFloat deltaA = thickness / (F2 * sin(angle_rad));
7046 std::array<MFloat, nDim> normalDifforigAB;
7048 for(
MInt d = 0; d < nDim; d++) {
7050 length += normalDifforigAB[d] * normalDifforigAB[d];
7053 length = sqrt(length);
7055 for(
MInt d = 0; d < nDim; d++) {
7056 normalDifforigAB[d] /= length;
7059 std::array<MFloat, nDim> newPosA;
7060 std::array<MFloat, nDim> sphereCenter;
7061 std::array<MFloat, nDim> normalDiffAB;
7062 std::array<MFloat, nDim> normalDiffBA;
7063 MBoolScratchSpace insideLargerCone((m_levelOffsets[gridLvl][1] - m_levelOffsets[gridLvl][0]), AT_,
7064 "insideLargerCone");
7066 for(
MInt k = m_levelOffsets[gridLvl][0]; k < m_levelOffsets[gridLvl][1]; k++) {
7067 insideLargerCone(k - m_levelOffsets[gridLvl][0]) =
false;
7070 for(
MInt dir = 1; dir > -2; dir = dir - 2) {
7072 MFloat radius = (Radius + dir * thickness / F2) * cos(angle_rad);
7075 for(
MInt d = 0; d < nDim; d++) {
7078 + radius / tan(angle_rad) * normalDifforigAB[d];
7081 + radius * (1.0 / tan(angle_rad) + tan(angle_rad)) * normalDifforigAB[d];
7086 lengthAB += normalDiffAB[d] * normalDiffAB[d];
7089 lengthAB = sqrt(lengthAB);
7092 for(
MInt d = 0; d < nDim; d++) {
7093 normalDiffAB[d] /= lengthAB;
7099 for(
MInt k = m_levelOffsets[gridLvl][0]; k < m_levelOffsets[gridLvl][1]; k++) {
7100 if(a_isInSolver(k, solver)) {
7101 MFloat* coords = &a_coordinate(k, 0);
7103 std::array<MFloat, nDim> diffA;
7104 std::array<MFloat, nDim> difforigA;
7105 std::array<MFloat, nDim> diffB;
7106 std::array<MFloat, nDim> diffCenter;
7110 MFloat len_diffOrig = 0.0;
7111 MFloat len_diffCenter = 0.0;
7112 for(
MInt d = 0; d < nDim; d++) {
7113 diffA[d] = coords[d] - newPosA[d];
7116 diffCenter[d] = coords[d] - sphereCenter[d];
7118 s1 += diffA[d] * normalDiffAB[d];
7119 s2 += diffB[d] * normalDiffBA[d];
7120 len_diffOrig += difforigA[d] * difforigA[d];
7121 len_diffCenter += diffCenter[d] * diffCenter[d];
7124 len_diffOrig = sqrt(len_diffOrig);
7125 len_diffCenter = sqrt(len_diffCenter);
7127 std::array<MFloat, nDim> cross;
7129 for(
MInt d = 0; d < nDim; d++) {
7130 MInt p1 = (d + 1) % (nDim);
7131 MInt p2 = (d + 2) % (nDim);
7133 cross[d] = diffA[p1] * normalDiffAB[p2] - normalDiffAB[p1] * diffA[p2];
7134 distance += cross[d] * cross[d];
7137 distance = sqrt(distance);
7139 MFloat ang = asin(distance / len_diffOrig) * 180 / PI;
7141 if((ang <= angle && s1 >= 0.0 && s2 >= 0.0) || len_diffCenter <= Radius + dir * thickness / F2) {
7142 insideLargerCone(k - m_levelOffsets[gridLvl][0]) =
true;
7144 insideLargerCone(k - m_levelOffsets[gridLvl][0]) =
false;
7151 for(
MInt k = m_levelOffsets[gridLvl][0]; k < m_levelOffsets[gridLvl][1]; k++) {
7152 if(insideLargerCone(k - m_levelOffsets[gridLvl][0])) {
7153 a_isToRefineForSolver(k, solver) = 1;
7159 if(noDomains() > 1) {
7160 MInt lev_pos = 2 * (gridLvl - m_minLevel);
7162 (m_haloCellOffsets[m_noNeighborDomains - 1][lev_pos + 1] - m_haloCellOffsets[0][lev_pos]), AT_,
7163 "insideLargerCone");
7164 for(
MInt k = m_haloCellOffsets[0][lev_pos]; k < m_haloCellOffsets[m_noNeighborDomains - 1][lev_pos + 1]; k++) {
7165 insideLargerConeHalo(k - m_haloCellOffsets[0][lev_pos]) =
false;
7168 for(
MInt dir = 1; dir > -2; dir = dir - 2) {
7170 MFloat radius = (Radius + dir * thickness / F2) * cos(angle_rad);
7173 for(
MInt d = 0; d < nDim; d++) {
7176 + radius / tan(angle_rad) * normalDifforigAB[d];
7178 + radius * (1.0 / tan(angle_rad) + tan(angle_rad)) * normalDifforigAB[d];
7182 lengthAB += normalDiffAB[d] * normalDiffAB[d];
7185 lengthAB = sqrt(lengthAB);
7188 for(
MInt d = 0; d < nDim; d++)
7189 normalDiffAB[d] /= lengthAB;
7191 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
7192 for(
MInt k = m_haloCellOffsets[dom][lev_pos]; k < m_haloCellOffsets[dom][lev_pos + 1]; k++) {
7193 if(a_isInSolver(k, solver)) {
7194 MFloat* coords = &a_coordinate(k, 0);
7196 std::array<MFloat, nDim> diffA;
7197 std::array<MFloat, nDim> difforigA;
7198 std::array<MFloat, nDim> diffB;
7199 std::array<MFloat, nDim> diffCenter;
7203 MFloat len_diffOrig = 0.0;
7204 MFloat len_diffCenter = 0.0;
7205 for(
MInt d = 0; d < nDim; d++) {
7206 diffA[d] = coords[d] - newPosA[d];
7209 diffCenter[d] = coords[d] - sphereCenter[d];
7211 s1 += diffA[d] * normalDiffAB[d];
7212 s2 += diffB[d] * normalDiffBA[d];
7213 len_diffOrig += difforigA[d] * difforigA[d];
7214 len_diffCenter += diffCenter[d] * diffCenter[d];
7217 len_diffOrig = sqrt(len_diffOrig);
7218 len_diffCenter = sqrt(len_diffCenter);
7220 std::array<MFloat, nDim> cross;
7222 for(
MInt d = 0; d < nDim; d++) {
7223 MInt p1 = (d + 1) % (nDim);
7224 MInt p2 = (d + 2) % (nDim);
7226 cross[d] = diffA[p1] * normalDiffAB[p2] - normalDiffAB[p1] * diffA[p2];
7227 distance += cross[d] * cross[d];
7230 distance = sqrt(distance);
7232 MFloat ang = asin(distance / len_diffOrig) * 180 / PI;
7234 if((ang <= angle && s1 >= 0.0 && s2 >= 0.0) || len_diffCenter <= Radius + dir * thickness / F2) {
7235 insideLargerConeHalo(k - m_haloCellOffsets[0][lev_pos]) =
true;
7237 insideLargerConeHalo(k - m_haloCellOffsets[0][lev_pos]) =
false;
7245 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
7246 for(
MInt k = m_haloCellOffsets[dom][lev_pos]; k < m_haloCellOffsets[dom][lev_pos + 1]; k++) {
7247 if(insideLargerConeHalo(k - m_haloCellOffsets[0][lev_pos])) {
7248 a_isToRefineForSolver(k, solver) = 1;
7267 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
7268 if(a_refinementDistance(i) < numeric_limits<MInt>::max()) {
7269 a_isToRefineForSolver(i, solver) = 1;
7274 if(noDomains() > 1) {
7276 MInt lev_pos = 2 * (level_ - m_minLevel);
7277 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
7278 for(
MInt i = m_haloCellOffsets[dom][lev_pos]; i < m_haloCellOffsets[dom][lev_pos + 1]; i++) {
7279 if(a_refinementDistance(i) < numeric_limits<MInt>::max()) {
7280 a_isToRefineForSolver(i, solver) = 1;
7305 if(in_level == 42) {
7310 MLong globalNoCells = 0;
7312 MPI_Allreduce(&localNoCells, &globalNoCells, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"localNoCells",
"globalNoCells");
7315 MLong averageNoCells = globalNoCells / ((
MLong)noDomains());
7317 averageNoCells += (averageNoCells / 2);
7320 MInt needsLoadBalancing = 0;
7321 if(m_noCells > averageNoCells) {
7322 needsLoadBalancing = 1;
7324 MPI_Allreduce(MPI_IN_PLACE, &needsLoadBalancing, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
7325 "needsLoadBalancing");
7328 if(needsLoadBalancing > 0) {
7329 m_log <<
"Imbalance found, starting load balancing." << endl;
7330 dynamicLoadBalancing();
7331 m_hasBeenLoadBalanced =
true;
7334#ifdef MAIA_EXTRA_DEBUG
7335 for(
MInt l = m_minLevel; l < in_level + 1; ++l) {
7336 m_log <<
"Checking Neighborhood for level " << l << endl;
7337 outStream <<
"Checking Neighborhood for level " << l << endl;
7338 checkNeighborhood(l);
7339 checkNeighborhoodDistance(l);
7340 checkNeighborhoodIntegrity(l);
7344 m_log <<
"****************************************" << endl;
7345 m_log <<
"* *" << endl;
7346 m_log <<
"* Finished, the load balancing is *" << endl;
7347 m_log <<
"* Grid generation, with, we continue *" << endl;
7348 m_log <<
"* *" << endl;
7349 m_log <<
"* May the force be with you *" << endl;
7350 m_log <<
"* *" << endl;
7351 m_log <<
"****************************************" << endl;
7356 m_log <<
"No imbalance in load was found, continuing with grid generation." << endl;
7404#ifdef MAIA_EXTRA_DEBUG
7405 m_log <<
"DynamicLoadBalancing Extra Debug: Step 0 - Setting timer" << endl;
7409 MInt t_dynamicLoadBalancing = 0;
7410 NEW_SUB_TIMER_STATIC(t_dynLoadBal,
"dynamic load balancing", m_t_createComputationalGrid);
7411 t_dynamicLoadBalancing = t_dynLoadBal;
7413 MInt t_gatherInformation = 0;
7414 MInt t_updateHaloIds = 0;
7415 MInt t_communicateCells = 0;
7416 MInt t_recreateCells = 0;
7417 MInt t_createHaloCells = 0;
7418 MInt t_globalToLocal = 0;
7420 NEW_SUB_TIMER_STATIC(t_dynLoadBal1,
"Gathering informations", t_dynamicLoadBalancing);
7421 NEW_SUB_TIMER_STATIC(t_dynLoadBal2,
"Update halo cells ids", t_dynamicLoadBalancing);
7422 NEW_SUB_TIMER_STATIC(t_dynLoadBal3,
"Sending and receiving new cells", t_dynamicLoadBalancing);
7423 NEW_SUB_TIMER_STATIC(t_dynLoadBal4,
"Recreation of cell array", t_dynamicLoadBalancing);
7424 NEW_SUB_TIMER_STATIC(t_dynLoadBal5,
"Regenerate halo cells", t_dynamicLoadBalancing);
7425 NEW_SUB_TIMER_STATIC(t_dynLoadBal6,
"Global to local", t_dynamicLoadBalancing);
7427 t_gatherInformation = t_dynLoadBal1;
7428 t_updateHaloIds = t_dynLoadBal2;
7429 t_communicateCells = t_dynLoadBal3;
7430 t_recreateCells = t_dynLoadBal4;
7431 t_createHaloCells = t_dynLoadBal5;
7432 t_globalToLocal = t_dynLoadBal6;
7434 RECORD_TIMER_START(t_dynamicLoadBalancing);
7440#ifdef MAIA_EXTRA_DEBUG
7441 m_log <<
"DynamicLoadBalancing Extra Debug: Step 1 - Gathering informations" << endl;
7444 RECORD_TIMER_START(t_gatherInformation);
7448 MLongScratchSpace globalNoCellsPerDomain(noDomains() + 1, AT_,
"globalNoCellsPerDomain");
7449 MPI_Allgather(&noCells, 1, MPI_LONG, globalNoCellsPerDomain.
getPointer(), 1, MPI_LONG, mpiComm(), AT_,
"noCells",
7450 "globalNoCellsPerDomain.getPointer()");
7454 MLong globalNoCells = globalNoCellsPerDomain[0];
7455 globalOffset[0] = 0;
7457 for(
MInt i = 1; i < noDomains(); ++i) {
7458 globalOffset[i] = globalOffset[i - 1] + globalNoCellsPerDomain[i - 1];
7459 globalNoCells += globalNoCellsPerDomain[i];
7473 MInt currentCellId = 0;
7476 MInt noMissingParents = m_noMissingParents;
7477#ifdef MAIA_EXTRA_DEBUG
7478 m_log <<
"DynamicLoadBalancing Extra Debug: Gathering informations:: m_noMisingParents is " << m_noMissingParents
7484 minWorkloadPerCell.
fill(0.0);
7486 minWeightList.
fill(0.0);
7488 minWorkloadList.
fill(0.0);
7489 MFloat currentWorkload = 0.0;
7491 while(noMissingParents > 0) {
7493 MInt cellId = m_levelOffsets[m_minLevel + noMissingParents][0];
7494 while((a_hasProperty((
MInt)a_parentId(cellId), 4) == 1) && (a_level(cellId) == (m_minLevel + noMissingParents))) {
7496 a_globalId(cellId) = currentGlobalId;
7497 localCellInfo(currentCellId, 0) = (
MLong)cellId;
7499 MInt last = currentCellId;
7501 traverseDFGlobalId(cellId, ¤tGlobalId, localCellInfo, minWorkloadPerCell, ¤tWorkload, minWeightList,
7502 minWorkloadList, ¤tCellId);
7504 MLong noOffsprings = 0;
7507 noOffsprings = currentGlobalId - globalOffset[
globalDomainId()] + 1;
7509 noOffsprings = currentGlobalId - a_globalId(cellId);
7511 localCellInfo(last, 1) = noOffsprings;
7515 cellId = m_levelOffsets[m_minLevel + noMissingParents][0] + k;
7525 for(
MInt cellId = m_levelOffsets[m_minLevel][0]; cellId < m_levelOffsets[m_minLevel][1]; cellId++, currentCellId++) {
7527 a_globalId(cellId) = currentGlobalId;
7528 localCellInfo(currentCellId, 0) = (
MLong)cellId;
7529 MInt lastCellId = currentCellId;
7531 traverseDFGlobalId(cellId, ¤tGlobalId, localCellInfo, minWorkloadPerCell, ¤tWorkload, minWeightList,
7532 minWorkloadList, ¤tCellId);
7534 MLong noOffsprings = 0;
7536 noOffsprings = currentGlobalId - globalOffset[
globalDomainId()] + 1;
7538 noOffsprings = currentGlobalId - a_globalId(cellId) + 1;
7541 localCellInfo(lastCellId, 1) = noOffsprings;
7546 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
7547 localCellInfo(cellId, 2) = a_globalId((
MInt)localCellInfo(cellId, 0));
7551 globalOffset.
fill(-1);
7552 globalNoCellsPerDomain.
fill(0);
7554 globalOffset[0] = 0;
7555 for(
MLong d = 1; d < noDomains(); ++d) {
7556 globalOffset[d] = globalOffset[d - 1] + ((globalNoCells - globalOffset[d - 1]) / (((
MLong)noDomains()) - (d - 1)));
7557 globalNoCellsPerDomain[d - 1] = globalOffset[d] - globalOffset[d - 1];
7559 globalNoCellsPerDomain[noDomains() - 1] = globalNoCells - globalOffset[noDomains() - 1];
7560 globalNoCellsPerDomain[noDomains()] = globalNoCells;
7561 globalOffset[noDomains()] = globalNoCells;
7564 MInt currentCpu = 0;
7565 for(
MInt i = 1; i < (noDomains() + 1); ++i) {
7566 if(globalOffset[i] > localCellInfo(0, 2)) {
7572 for(
MInt i = 0; i < m_noCells; ++i) {
7573 if(localCellInfo(i, 2) < globalOffset[currentCpu]) {
7574 localCellInfo(i, 3) = (
MLong)(currentCpu - 1);
7578 if(localCellInfo(i, 2) == globalOffset[currentCpu]) {
7579 localCellInfo(i, 3) = (
MLong)currentCpu;
7587 MIntScratchSpace noCellsToReceive(noDomains() + 1, AT_,
"noCellsToReceive");
7589 noCellsToReceive.
fill(0);
7590 noCellsToSend.
fill(0);
7592 for(
MInt i = 0; i < m_noCells; ++i) {
7597 noCellsToSend[localCellInfo(i, 3)] += 1;
7600 for(
MInt i = 0; i < noDomains(); ++i) {
7601 MPI_Scatter(noCellsToSend.
getPointer(), 1, MPI_INT, &noCellsToReceive[i], 1, MPI_INT, i, mpiComm(), AT_,
7602 "noCellsToSend.getPointer()",
"noCellsToReceive[i]");
7605 for(
MInt i = 0; i < noDomains(); ++i) {
7606 noCellsToSend[noDomains()] += noCellsToSend[i];
7607 noCellsToReceive[noDomains()] += noCellsToReceive[i];
7608#ifdef MAIA_EXTRA_DEBUG
7609 m_log <<
"DynamicLoadBalancing Debug: To domain " << i <<
", we will send " << noCellsToSend[i] <<
" and receive "
7610 << noCellsToReceive[i] <<
" cells." << endl;
7614#ifdef MAIA_EXTRA_DEBUG
7615 m_log <<
"DynamicLoadBalancing Debug: Total number of cells, we will send " << noCellsToSend[noDomains()]
7616 <<
" and receive " << noCellsToReceive[noDomains()] <<
" cells." << endl;
7619 RECORD_TIMER_STOP(t_gatherInformation);
7625#ifdef MAIA_EXTRA_DEBUG
7626 m_log <<
"DynamicLoadBalancing Extra Debug: Step 2 - Update halo global ids" << endl;
7629 RECORD_TIMER_START(t_updateHaloIds);
7631 communicateHaloGlobalIds(-42);
7633 RECORD_TIMER_STOP(t_updateHaloIds);
7639#ifdef MAIA_EXTRA_DEBUG
7640 m_log <<
"DynamicLoadBalancing Extra Debug: Step 3 - Sending and receiving new cells" << endl;
7643 RECORD_TIMER_START(t_communicateCells);
7646 MLongScratchSpace newParentId(noCellsToReceive[noDomains()], AT_,
"newParentId");
7647 MLongScratchSpace newGlobalId(noCellsToReceive[noDomains()], AT_,
"newGlobalId");
7649 MIntScratchSpace newNoChildren(noCellsToReceive[noDomains()], AT_,
"newNoChildren");
7651 MLongScratchSpace newChildId(noCellsToReceive[noDomains()], m_maxNoChildren, AT_,
"newChildId");
7652 MLongScratchSpace newNeighborId(noCellsToReceive[noDomains()], m_noNeighbors, AT_,
"newNeighborId");
7653 MIntScratchSpace newProperty(noCellsToReceive[noDomains()], 8, AT_,
"newProperty");
7654 MIntScratchSpace newIsInSolver(noCellsToReceive[noDomains()], m_noSolvers, AT_,
"newIsInSolver");
7655 MIntScratchSpace newIsSolverBoundary(noCellsToReceive[noDomains()], m_noSolvers, AT_,
"newIsSolverBoundary");
7656 MIntScratchSpace newIsToRefineForSolver(noCellsToReceive[noDomains()], m_noSolvers, AT_,
"newIsToRefineForSolver");
7657 MFloatScratchSpace newCoordinate(noCellsToReceive[noDomains()], nDim, AT_,
"newCoordinate");
7659 newParentId.
fill(-1);
7660 newGlobalId.
fill(-1);
7662 newNoChildren.
fill(-1);
7663 newChildId.
fill(-1);
7664 newNeighborId.
fill(-1);
7665 newProperty.
fill(-1);
7666 newCoordinate.
fill(-1.0);
7672 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7673 if(noCellsToSend[dom] == 0) {
7677 for(
MInt i = 0; i < m_noCells; ++i) {
7678 if(localCellInfo(i, 3) == dom) {
7679 sendBuffer(currentId) = a_parentId((
MInt)localCellInfo(i, 0));
7685 communicateLong(newParentId, noCellsToReceive, sendBuffer, noCellsToSend);
7692 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7693 if(noCellsToSend[dom] == 0) {
7697 for(
MInt i = 0; i < m_noCells; ++i) {
7698 if(localCellInfo(i, 3) == dom) {
7699 sendBuffer(currentId) = a_globalId((
MInt)localCellInfo(i, 0));
7705 communicateLong(newGlobalId, noCellsToReceive, sendBuffer, noCellsToSend);
7709 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
7712 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7713 if(noCellsToSend[dom] == 0) {
7717 for(
MInt i = 0; i < m_noCells; ++i) {
7718 if(localCellInfo(i, 3) == dom) {
7719 sendBuffer(currentId) = a_level((
MInt)localCellInfo(i, 0));
7725 communicateInt(newLevel, noCellsToReceive, sendBuffer, noCellsToSend);
7729 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
7732 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7733 if(noCellsToSend[dom] == 0) {
7737 for(
MInt i = 0; i < m_noCells; ++i) {
7738 if(localCellInfo(i, 3) == dom) {
7739 sendBuffer(currentId) = a_noChildren((
MInt)localCellInfo(i, 0));
7745 communicateInt(newNoChildren, noCellsToReceive, sendBuffer, noCellsToSend);
7749 for(
MInt childId = 0; childId < m_maxNoChildren; ++childId) {
7754 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7755 if(noCellsToSend[dom] == 0) {
7759 for(
MInt i = 0; i < m_noCells; ++i) {
7760 if(localCellInfo(i, 3) == dom) {
7761 sendBuffer(currentId) = a_childId((
MInt)localCellInfo(i, 0), childId);
7767 communicateLong(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
7769 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
7770 newChildId(i, childId) = recvBuffer(i);
7776 for(
MInt neighborId = 0; neighborId < m_noNeighbors; ++neighborId) {
7781 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7782 if(noCellsToSend[dom] == 0) {
7786 for(
MInt i = 0; i < m_noCells; ++i) {
7787 if(localCellInfo(i, 3) == dom) {
7788 sendBuffer(currentId) = a_neighborId((
MInt)localCellInfo(i, 0), neighborId);
7794 communicateLong(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
7796 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
7797 newNeighborId(i, neighborId) = recvBuffer(i);
7803 for(
MInt property = 0;
property < 8; ++property) {
7804 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
7805 MIntScratchSpace recvBuffer(noCellsToReceive[noDomains()], AT_,
"recvBuffer");
7808 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7809 if(noCellsToSend[dom] == 0) {
7813 for(
MInt i = 0; i < m_noCells; ++i) {
7814 if(localCellInfo(i, 3) == dom) {
7815 sendBuffer(currentId) = a_hasProperty((
MInt)localCellInfo(i, 0), property);
7821 communicateInt(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
7823 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
7824 newProperty(i, property) = recvBuffer(i);
7830 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
7831 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
7832 MIntScratchSpace recvBuffer(noCellsToReceive[noDomains()], AT_,
"recvBuffer");
7835 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7836 if(noCellsToSend[dom] == 0) {
7840 for(
MInt i = 0; i < m_noCells; ++i) {
7841 if(localCellInfo(i, 3) == dom) {
7842 sendBuffer(currentId) = a_isInSolver((
MInt)localCellInfo(i, 0), solver);
7848 communicateInt(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
7850 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
7851 newIsInSolver(i, solver) = recvBuffer(i);
7856 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
7857 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
7858 MIntScratchSpace recvBuffer(noCellsToReceive[noDomains()], AT_,
"recvBuffer");
7861 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7862 if(noCellsToSend[dom] == 0) {
7866 for(
MInt i = 0; i < m_noCells; ++i) {
7867 if(localCellInfo(i, 3) == dom) {
7868 sendBuffer(currentId) = a_isSolverBoundary((
MInt)localCellInfo(i, 0), solver);
7874 communicateInt(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
7876 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
7877 newIsSolverBoundary(i, solver) = recvBuffer(i);
7882 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
7883 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
7884 MIntScratchSpace recvBuffer(noCellsToReceive[noDomains()], AT_,
"recvBuffer");
7887 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7888 if(noCellsToSend[dom] == 0) {
7892 for(
MInt i = 0; i < m_noCells; ++i) {
7893 if(localCellInfo(i, 3) == dom) {
7894 sendBuffer(currentId) = a_isToRefineForSolver((
MInt)localCellInfo(i, 0), solver);
7900 communicateInt(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
7902 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
7903 newIsToRefineForSolver(i, solver) = recvBuffer(i);
7908 for(
MInt dim = 0; dim < nDim; ++dim) {
7913 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7914 if(noCellsToSend[dom] == 0) {
7918 for(
MInt i = 0; i < m_noCells; ++i) {
7919 if(localCellInfo(i, 3) == dom) {
7920 sendBuffer(currentId) = a_coordinate((
MInt)localCellInfo(i, 0), dim);
7926 communicateDouble(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
7928 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
7929 newCoordinate(i, dim) = recvBuffer(i);
7934 RECORD_TIMER_STOP(t_communicateCells);
7940#ifdef MAIA_EXTRA_DEBUG
7941 m_log <<
"DynamicLoadBalancing Extra Debug: Step 4 - Recreation of the cell array" << endl;
7944 RECORD_TIMER_START(t_recreateCells);
7947 currentCellId = m_maxNoCells - 2;
7948 for(
MInt i = m_noCells - 1; i > -1; --i) {
7950 a_parentId(currentCellId) = a_parentId((
MInt)localCellInfo(i, 0));
7951 a_globalId(currentCellId) = a_globalId((
MInt)localCellInfo(i, 0));
7952 a_noChildren(currentCellId) = a_noChildren((
MInt)localCellInfo(i, 0));
7953 a_level(currentCellId) = a_level((
MInt)localCellInfo(i, 0));
7955 for(
MInt child = 0; child < m_maxNoChildren; ++child) {
7956 a_childId(currentCellId, child) = a_childId((
MInt)localCellInfo(i, 0), child);
7959 for(
MInt ngh = 0; ngh < m_noNeighbors; ++ngh) {
7960 a_neighborId(currentCellId, ngh) = a_neighborId((
MInt)localCellInfo(i, 0), ngh);
7963 for(
MInt dim = 0; dim < nDim; ++dim) {
7964 a_coordinate(currentCellId, dim) = a_coordinate((
MInt)localCellInfo(i, 0), dim);
7967 for(
MInt property = 0;
property < 8; ++property) {
7968 a_hasProperty(currentCellId, property) = a_hasProperty((
MInt)localCellInfo(i, 0), property);
7971 for(
MInt solver = 0; solver < 8; solver++) {
7972 a_isInSolver(currentCellId, solver) = a_isInSolver((
MInt)localCellInfo(i, 0), solver);
7973 a_isSolverBoundary(currentCellId, solver) = a_isSolverBoundary((
MInt)localCellInfo(i, 0), solver);
7974 a_isToRefineForSolver(currentCellId, solver) = a_isToRefineForSolver((
MInt)localCellInfo(i, 0), solver);
7976 a_noSolidLayer(currentCellId, solver) = -1;
7979 localCellInfo(i, 0) = currentCellId;
7985 MInt currentLocalCellId = 0;
7986 for(
MInt level = m_minLevel; level <= m_maxRfnmntLvl; ++level) {
7987 m_levelOffsets[level][0] = currentLocalCellId;
7989 for(
MInt dom = 0; dom < noDomains(); ++dom) {
7991 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
7992 if((a_level((
MInt)localCellInfo(cellId, 0)) == level) && (localCellInfo(cellId, 3) ==
globalDomainId())) {
7993 a_parentId(currentLocalCellId) = a_parentId((
MInt)localCellInfo(cellId, 0));
7994 a_globalId(currentLocalCellId) = a_globalId((
MInt)localCellInfo(cellId, 0));
7995 a_noChildren(currentLocalCellId) = a_noChildren((
MInt)localCellInfo(cellId, 0));
7996 a_level(currentLocalCellId) = a_level((
MInt)localCellInfo(cellId, 0));
7998 for(
MInt child = 0; child < m_maxNoChildren; ++child) {
7999 a_childId(currentLocalCellId, child) = a_childId((
MInt)localCellInfo(cellId, 0), child);
8002 for(
MInt ngh = 0; ngh < m_noNeighbors; ++ngh) {
8003 a_neighborId(currentLocalCellId, ngh) = a_neighborId((
MInt)localCellInfo(cellId, 0), ngh);
8006 for(
MInt dim = 0; dim < nDim; ++dim) {
8007 a_coordinate(currentLocalCellId, dim) = a_coordinate((
MInt)localCellInfo(cellId, 0), dim);
8010 for(
MInt property = 0;
property < 8; ++property) {
8011 a_hasProperty(currentLocalCellId, property) = a_hasProperty((
MInt)localCellInfo(cellId, 0), property);
8014 for(
MInt solver = 0; solver < 8; solver++) {
8015 a_isInSolver(currentLocalCellId, solver) = a_isInSolver((
MInt)localCellInfo(cellId, 0), solver);
8016 a_isSolverBoundary(currentLocalCellId, solver) =
8017 a_isSolverBoundary((
MInt)localCellInfo(cellId, 0), solver);
8018 a_isToRefineForSolver(currentLocalCellId, solver) =
8019 a_isToRefineForSolver((
MInt)localCellInfo(cellId, 0), solver);
8021 a_noSolidLayer(currentLocalCellId, solver) = -1;
8024 ++currentLocalCellId;
8034 if(noCellsToReceive[dom] == 0) {
8038 if(noCellsToReceive[dom] > 0) {
8039 for(
MInt cellId = currentCellId; cellId < (currentCellId + noCellsToReceive[dom]); ++cellId) {
8040 if(newLevel(cellId) == level) {
8041 a_parentId(currentLocalCellId) = newParentId(cellId);
8042 a_globalId(currentLocalCellId) = newGlobalId(cellId);
8043 a_noChildren(currentLocalCellId) = newNoChildren(cellId);
8044 a_level(currentLocalCellId) = newLevel(cellId);
8046 for(
MInt child = 0; child < m_maxNoChildren; ++child) {
8047 a_childId(currentLocalCellId, child) = newChildId(cellId, child);
8050 for(
MInt ngh = 0; ngh < m_noNeighbors; ++ngh) {
8051 a_neighborId(currentLocalCellId, ngh) = newNeighborId(cellId, ngh);
8054 for(
MInt dim = 0; dim < nDim; ++dim) {
8055 a_coordinate(currentLocalCellId, dim) = newCoordinate(cellId, dim);
8058 for(
MInt property = 0;
property < 8; ++property) {
8059 a_hasProperty(currentLocalCellId, property) = (
MBool)newProperty(cellId, property);
8062 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
8063 a_isInSolver(currentLocalCellId, solver) = (
MBool)newIsInSolver(cellId, solver);
8064 a_isSolverBoundary(currentLocalCellId, solver) = (
MBool)newIsSolverBoundary(cellId, solver);
8065 a_isToRefineForSolver(currentLocalCellId, solver) = (
MBool)newIsToRefineForSolver(cellId, solver);
8068 a_noSolidLayer(currentLocalCellId, solver) = -1;
8072 for(
MInt solver = m_noSolvers; solver < 8; solver++) {
8073 a_isInSolver(currentLocalCellId, solver) = 0;
8074 a_isSolverBoundary(currentLocalCellId, solver) = 0;
8075 a_isToRefineForSolver(currentLocalCellId, solver) = 0;
8076 a_noSolidLayer(currentLocalCellId, solver) = -1;
8079 ++currentLocalCellId;
8082 currentCellId += noCellsToReceive[dom];
8087 m_levelOffsets[level][1] = currentLocalCellId;
8090 m_noCells = currentLocalCellId;
8094 RECORD_TIMER_STOP(t_recreateCells);
8100#ifdef MAIA_EXTRA_DEBUG
8101 m_log <<
"DynamicLoadBalancing Extra Debug: Step 5 - Regenerate halo cells" << endl;
8104 RECORD_TIMER_START(t_createHaloCells);
8109 m_noNeighborDomains = 0;
8110 noCellsToReceive.
fill(0);
8113 map<MLong, MInt> haloCellsMap;
8116 MInt parentDepth = 0;
8117 MLong parentId = -1;
8118 for(
MInt level = m_minLevel; level <= m_maxRfnmntLvl; ++level) {
8119 if(globalOffset[
globalDomainId()] == a_globalId(m_levelOffsets[level][0])) {
8120 parentDepth = a_level(m_levelOffsets[level][0]) - m_minLevel;
8121 parentId = a_parentId(m_levelOffsets[level][0]);
8126 m_noMissingParents = parentDepth;
8131 haloCellsMap.insert(make_pair(parentId, currentId));
8137 MBool stillLookingForParents =
true;
8138 while(stillLookingForParents) {
8140 MIntScratchSpace parentDepthGathered(noDomains(), AT_,
"parentDepthGathered");
8141 parentDepthGathered.
fill(0);
8142 MPI_Allgather(&parentDepth, 1, MPI_INT, parentDepthGathered.
getPointer(), 1, MPI_INT, mpiComm(), AT_,
"parentDepth",
8143 "parentDepthGathered.getPointer()");
8145 MLong parentIdToLookFor = -1;
8149 MInt parentDomain = -1;
8150 for(
MInt i = 0; i < noDomains(); ++i) {
8151 if(parentId < globalOffset[i]) {
8152 parentDomain = i - 1;
8158 MIntScratchSpace parentDomainGathered(noDomains(), AT_,
"parentDomainGathered");
8159 parentDomainGathered.
fill(-1);
8161 "parentDomain",
"parentDomainGathered.getPointer()");
8165 for(
MInt dom = 0; dom < noDomains(); ++dom) {
8169 MPI_Send(&parentId, 1, MPI_LONG, parentDomain, parentDomain, mpiComm(), AT_,
"parentId");
8171 MPI_Recv(&parentId, 1, MPI_LONG, parentDomain, parentDomain, mpiComm(), &status, AT_,
"parentId");
8177 haloCellsMap.insert(make_pair(parentId, currentId));
8182 if((parentDomainGathered[dom] ==
globalDomainId()) && (parentDepthGathered[dom] > 0)) {
8184 MPI_Recv(&parentIdToLookFor, 1, MPI_LONG, dom,
globalDomainId(), mpiComm(), &status, AT_,
"parentIdToLookFor");
8186 for(
MInt i = 0; i < m_noCells; ++i) {
8187 if(a_globalId(i) == parentIdToLookFor) {
8188 parentIdToLookFor = a_parentId(i);
8199 if(parentDepth > 0) {
8204 MInt continueSearch = 0;
8205 MPI_Allreduce(&parentDepth, &continueSearch, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"parentDepth",
"continueSearch");
8207 if(continueSearch == 0) {
8208 stillLookingForParents =
false;
8214 for(
MInt i = 0; i < m_noCells; ++i) {
8215 a_hasProperty(i, 3) = 0;
8216 a_hasProperty(i, 4) = 0;
8219 for(
MInt ngh = 0; ngh < m_noNeighbors; ++ngh) {
8220 if(a_neighborId(i, ngh) == -1) {
8224 || (a_neighborId(i, ngh) >= globalOffset[
globalDomainId()] + m_noCells)) {
8225 if(haloCellsMap.count(a_neighborId(i, ngh)) == 0) {
8230 haloCellsMap.insert(make_pair(a_neighborId(i, ngh), currentId));
8233 a_hasProperty(i, 3) = 1;
8238 for(
MInt child = 0; child < m_maxNoChildren; ++child) {
8239 if(a_childId(i, child) == -1) {
8244 || (a_childId(i, child) >= globalOffset[
globalDomainId()] + m_noCells)) {
8245 if(haloCellsMap.count(a_childId(i, child)) == 0) {
8250 haloCellsMap.insert(make_pair(a_childId(i, child), currentId));
8253 a_hasProperty(i, 3) = 1;
8259 || (a_parentId(i) >= globalOffset[
globalDomainId()] + m_noCells)) {
8260 if(a_parentId(i) == -1) {
8264 if(haloCellsMap.count(a_parentId(i)) == 0) {
8269 haloCellsMap.insert(make_pair(a_parentId(i), currentId));
8272 a_hasProperty(i, 3) = 1;
8283 haloInformation.
fill(-2);
8290 for(map<MLong, MInt>::iterator i = haloCellsMap.begin(); i != haloCellsMap.end(); ++i) {
8291 for(
MLong dom = 0; dom < (
MLong)noDomains(); ++dom) {
8292 if((globalOffset[dom] <= i->first) && (globalOffset[dom + 1] > i->first)) {
8293 haloInformation(currentId, 0) = (
MInt)i->second;
8294 haloInformation(currentId, 1) = i->first;
8295 haloInformation(currentId, 2) = dom;
8302 ++noCellsToReceive[dom];
8311 for(
MInt i = 0; i < noDomains(); ++i) {
8312 if(noCellsToReceive[i] > 0) {
8313 noCellsToReceive[noDomains()] += noCellsToReceive[i];
8317 noCellsToSend.
fill(0);
8318 for(
MInt i = 0; i < noDomains(); ++i) {
8319 MPI_Scatter(noCellsToReceive.
getPointer(), 1, MPI_INT, &noCellsToSend[i], 1, MPI_INT, i, mpiComm(), AT_,
8320 "noCellsToReceive.getPointer()",
"noCellsToSend[i]");
8323 for(
MInt i = 0; i < noDomains(); ++i) {
8324 if(noCellsToSend[i] > 0) {
8325 noCellsToSend[noDomains()] += noCellsToSend[i];
8329 for(
MInt i = 0; i < noDomains(); ++i) {
8330 if((noCellsToSend[i] > 0) || (noCellsToReceive[i] > 0)) {
8331 ++m_noNeighborDomains;
8335 mAlloc(m_neighborDomains, m_noNeighborDomains,
"m_neighborDomains", -1, AT_);
8336 mAlloc(m_rfnCountHalosDom, m_noNeighborDomains,
"m_rfnCountHalosDom", 0, AT_);
8339 for(
MInt i = 0; i < noDomains(); ++i) {
8340 if((noCellsToSend[i] > 0) || (noCellsToReceive[i] > 0)) {
8341 m_neighborDomains[currentId] = i;
8347 MLongScratchSpace cellsToSendGlobalId(noCellsToSend[noDomains()], AT_,
"cellsToSendGlobalId");
8351 MLongScratchSpace dataToReceive(noCellsToSend[noDomains()], AT_,
"dataToReceive");
8354 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8356 for(
MInt i = 0; i < (signed)haloCellsMap.size(); ++i) {
8357 if(haloInformation(i, 2) == m_neighborDomains[dom]) {
8358 dataToSend(currentId + offset) = haloInformation(i, 1);
8362 offset += currentId;
8365 communicateLong(dataToReceive, noCellsToSend, dataToSend, noCellsToReceive);
8368 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8369 for(
MInt i = 0; i < noCellsToSend[m_neighborDomains[dom]]; ++i) {
8372 cellsToSendGlobalId(i + offset) = dataToReceive(i + offset);
8375 offset += noCellsToSend[m_neighborDomains[dom]];
8391 MIntScratchSpace newIsSolverBoundary((
MInt)haloCellsMap.size(), m_noSolvers, AT_,
"newIsSolverBoundary");
8392 MIntScratchSpace newIsToRefineForSolver((
MInt)haloCellsMap.size(), m_noSolvers, AT_,
"newIsToRefineForSolver");
8395 MIntScratchSpace windowCellLocalId(noCellsToSend[noDomains()], AT_,
"windowCellLocalId");
8396 MIntScratchSpace windowCellLocalIdOffset(m_noNeighborDomains, AT_,
"windowCellLocalIdOffset");
8401 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8402 MInt domain = m_neighborDomains[dom];
8404 windowCellLocalIdOffset[dom] = currentId;
8409 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
8410 for(
MInt i = 0; i < noCellsToSend[domain]; ++i) {
8411 if(cellsToSendGlobalId(i + offset) == a_globalId(cellId)) {
8415 windowCellLocalId[currentId] = cellId;
8422 offset += noCellsToSend[domain];
8427 if(m_noNeighborDomains > 0) {
8431 for(
MInt dom = 1; dom < m_noNeighborDomains; ++dom) {
8432 haloOffset[dom] = haloOffset[dom - 1] + noCellsToReceive[m_neighborDomains[dom - 1]];
8440 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8441 MInt domain = m_neighborDomains[dom];
8443 for(
MInt i = windowCellLocalIdOffset[dom]; i < (windowCellLocalIdOffset[dom] + noCellsToSend[domain]); ++i) {
8444 sendBuffer(currentId) = a_parentId(windowCellLocalId(i));
8449 communicateLong(newParentId, noCellsToReceive, sendBuffer, noCellsToSend);
8456 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8457 MInt domain = m_neighborDomains[dom];
8459 for(
MInt i = windowCellLocalIdOffset[dom]; i < (windowCellLocalIdOffset[dom] + noCellsToSend[domain]); ++i) {
8460 sendBuffer(currentId) = a_globalId(windowCellLocalId(i));
8465 communicateLong(newGlobalId, noCellsToReceive, sendBuffer, noCellsToSend);
8469 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
8472 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8473 MInt domain = m_neighborDomains[dom];
8475 for(
MInt i = windowCellLocalIdOffset[dom]; i < (windowCellLocalIdOffset[dom] + noCellsToSend[domain]); ++i) {
8476 sendBuffer(currentId) = a_level(windowCellLocalId(i));
8481 communicateInt(newLevel, noCellsToReceive, sendBuffer, noCellsToSend);
8485 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
8488 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8489 MInt domain = m_neighborDomains[dom];
8491 for(
MInt i = windowCellLocalIdOffset[dom]; i < (windowCellLocalIdOffset[dom] + noCellsToSend[domain]); ++i) {
8492 sendBuffer(currentId) = a_noChildren(windowCellLocalId(i));
8497 communicateInt(newNoChildren, noCellsToReceive, sendBuffer, noCellsToSend);
8500 for(
MInt childId = 0; childId < m_maxNoChildren; ++childId) {
8505 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8506 MInt domain = m_neighborDomains[dom];
8508 for(
MInt i = windowCellLocalIdOffset[dom]; i < (windowCellLocalIdOffset[dom] + noCellsToSend[domain]); ++i) {
8509 sendBuffer(currentId) = a_childId(windowCellLocalId(i), childId);
8514 communicateLong(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
8516 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
8517 newChildId(i, childId) = recvBuffer(i);
8522 for(
MInt neighborId = 0; neighborId < m_noNeighbors; ++neighborId) {
8527 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8528 MInt domain = m_neighborDomains[dom];
8530 for(
MInt i = windowCellLocalIdOffset[dom]; i < (windowCellLocalIdOffset[dom] + noCellsToSend[domain]); ++i) {
8531 sendBuffer(currentId) = a_neighborId(windowCellLocalId(i), neighborId);
8536 communicateLong(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
8538 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
8539 newNeighborId(i, neighborId) = recvBuffer(i);
8544 for(
MInt property = 0;
property < 8; ++property) {
8545 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
8546 MIntScratchSpace recvBuffer(noCellsToReceive[noDomains()], AT_,
"recvBuffer");
8549 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8550 MInt domain = m_neighborDomains[dom];
8552 for(
MInt i = windowCellLocalIdOffset[dom]; i < (windowCellLocalIdOffset[dom] + noCellsToSend[domain]); ++i) {
8553 sendBuffer(currentId) = a_hasProperty(windowCellLocalId(i), property);
8558 communicateInt(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
8560 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
8561 newProperty(i, property) = recvBuffer(i);
8566 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
8567 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
8568 MIntScratchSpace recvBuffer(noCellsToReceive[noDomains()], AT_,
"recvBuffer");
8571 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8572 MInt domain = m_neighborDomains[dom];
8574 for(
MInt i = windowCellLocalIdOffset[dom]; i < (windowCellLocalIdOffset[dom] + noCellsToSend[domain]); ++i) {
8575 sendBuffer(currentId) = a_isInSolver(windowCellLocalId(i), solver);
8580 communicateInt(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
8582 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
8583 newIsInSolver(i, solver) = recvBuffer(i);
8587 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
8588 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
8589 MIntScratchSpace recvBuffer(noCellsToReceive[noDomains()], AT_,
"recvBuffer");
8592 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8593 MInt domain = m_neighborDomains[dom];
8595 for(
MInt i = windowCellLocalIdOffset[dom]; i < (windowCellLocalIdOffset[dom] + noCellsToSend[domain]); ++i) {
8596 sendBuffer(currentId) = a_isSolverBoundary(windowCellLocalId(i), solver);
8601 communicateInt(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
8603 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
8604 newIsSolverBoundary(i, solver) = recvBuffer(i);
8608 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
8609 MIntScratchSpace sendBuffer(noCellsToSend[noDomains()], AT_,
"sendBuffer");
8610 MIntScratchSpace recvBuffer(noCellsToReceive[noDomains()], AT_,
"recvBuffer");
8613 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8614 MInt domain = m_neighborDomains[dom];
8616 for(
MInt i = windowCellLocalIdOffset[dom]; i < (windowCellLocalIdOffset[dom] + noCellsToSend[domain]); ++i) {
8617 sendBuffer(currentId) = a_isSolverBoundary(windowCellLocalId(i), solver);
8622 communicateInt(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
8624 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
8625 newIsToRefineForSolver(i, solver) = recvBuffer(i);
8629 for(
MInt dim = 0; dim < nDim; ++dim) {
8634 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8635 MInt domain = m_neighborDomains[dom];
8637 for(
MInt i = windowCellLocalIdOffset[dom]; i < (windowCellLocalIdOffset[dom] + noCellsToSend[domain]); ++i) {
8638 sendBuffer(currentId) = a_coordinate(windowCellLocalId(i), dim);
8643 communicateDouble(recvBuffer, noCellsToReceive, sendBuffer, noCellsToSend);
8645 for(
MInt i = 0; i < noCellsToReceive[noDomains()]; ++i) {
8646 newCoordinate(i, dim) = recvBuffer(i);
8651 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8652 for(
MInt i = haloOffset[dom]; i < (haloOffset[dom] + noCellsToReceive[m_neighborDomains[dom]]); ++i) {
8653 newProperty(i, 3) = 0;
8654 newProperty(i, 4) = 1;
8660 mAlloc(m_haloCellOffsets, m_noNeighborDomains, 2 * (m_maxRfnmntLvl - m_minLevel + 1),
"m_haloCellOffsets", 0, AT_);
8661 m_noTotalHaloCells = 0;
8663 MInt currentLocalCellId = m_maxNoCells - 2;
8664 for(
MInt level = m_minLevel; level <= m_maxRfnmntLvl; ++level) {
8665 m_haloCellOffsetsLevel[level][1] = currentLocalCellId + 1;
8667 for(
MInt dom = m_noNeighborDomains - 1; dom > -1; --dom) {
8668 m_haloCellOffsets[dom][(2 * (level - m_minLevel)) + 1] = currentLocalCellId + 1;
8670 for(
MInt cellId = (haloOffset[dom] + noCellsToReceive[m_neighborDomains[dom]]) - 1; cellId >= haloOffset[dom];
8672 if(newLevel(cellId) == level) {
8673 a_parentId(currentLocalCellId) = newParentId(cellId);
8674 a_globalId(currentLocalCellId) = newGlobalId(cellId);
8675 a_noChildren(currentLocalCellId) = newNoChildren(cellId);
8676 a_level(currentLocalCellId) = level;
8678 for(
MInt child = 0; child < m_maxNoChildren; ++child) {
8679 a_childId(currentLocalCellId, child) = newChildId(cellId, child);
8682 for(
MInt ngh = 0; ngh < m_noNeighbors; ++ngh) {
8683 a_neighborId(currentLocalCellId, ngh) = newNeighborId(cellId, ngh);
8686 for(
MInt dim = 0; dim < nDim; ++dim) {
8687 a_coordinate(currentLocalCellId, dim) = newCoordinate(cellId, dim);
8690 for(
MInt property = 0;
property < 8; ++property) {
8691 a_hasProperty(currentLocalCellId, property) = (
MBool)newProperty(cellId, property);
8694 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
8695 a_isInSolver(currentLocalCellId, solver) = (
MBool)newIsInSolver(cellId, solver);
8696 a_isSolverBoundary(currentLocalCellId, solver) = (
MBool)newIsSolverBoundary(cellId, solver);
8697 a_isToRefineForSolver(currentLocalCellId, solver) = (
MBool)newIsToRefineForSolver(cellId, solver);
8699 a_noSolidLayer(currentLocalCellId, solver) = -1;
8702 for(
MInt solver = m_noSolvers; solver < 8; solver++) {
8703 a_isInSolver(currentLocalCellId, solver) = 0;
8704 a_isSolverBoundary(currentLocalCellId, solver) = 0;
8705 a_isToRefineForSolver(currentLocalCellId, solver) = 0;
8706 a_noSolidLayer(currentLocalCellId, solver) = -1;
8708 --currentLocalCellId;
8714 m_haloCellOffsets[dom][(2 * (level - m_minLevel))] = currentLocalCellId + 1;
8718 m_haloCellOffsetsLevel[level][0] = currentLocalCellId + 1;
8719 m_noHaloCellsOnLevel[level] = m_haloCellOffsetsLevel[level][1] - m_haloCellOffsetsLevel[level][0];
8720 m_noTotalHaloCells += m_noHaloCellsOnLevel[level];
8725 RECORD_TIMER_STOP(t_createHaloCells);
8731#ifdef MAIA_EXTRA_DEBUG
8732 m_log <<
"DynamicLoadBalancing Extra Debug: Step 6 - Global to local" << endl;
8735 RECORD_TIMER_START(t_globalToLocal);
8737 map<MLong, MInt> globalToLocal;
8740 for(
MInt i = 0; i < m_noCells; ++i) {
8741 globalToLocal.insert(make_pair(a_globalId(i), i));
8745 for(
MInt level = m_minLevel; level <= m_maxRfnmntLvl; ++level) {
8746 if(m_noHaloCellsOnLevel[level] > 0) {
8747 for(
MInt i = m_haloCellOffsetsLevel[level][0]; i < m_haloCellOffsetsLevel[level][1]; ++i) {
8748 globalToLocal.insert(make_pair(a_globalId(i), i));
8754 for(
MInt i = 0; i < m_noCells; ++i) {
8755 if(globalToLocal.count(a_parentId(i)) == 0) {
8756#ifdef MAIA_EXTRA_DEBUG
8757 if(a_parentId(i) > -1) {
8758 m_log <<
"DynamicLoadBalancing Debug: global parenId " << a_parentId(i) <<
" does not exist" << endl;
8763 a_parentId(i) = globalToLocal[a_parentId(i)];
8766 for(
MInt ngh = 0; ngh < m_noNeighbors; ++ngh) {
8767 if(globalToLocal.count(a_neighborId(i, ngh)) == 0) {
8768#ifdef MAIA_EXTRA_DEBUG
8769 if(a_neighborId(i, ngh) > -1) {
8770 m_log <<
"DynamicLoadBalancing Debug: global nghbrId " << a_neighborId(i, ngh) <<
" does not exist" << endl;
8773 a_neighborId(i, ngh) = -1;
8775 a_neighborId(i, ngh) = globalToLocal[a_neighborId(i, ngh)];
8779 a_noChildren(i) = m_maxNoChildren;
8780 for(
MInt child = 0; child < m_maxNoChildren; ++child) {
8781 if(globalToLocal.count(a_childId(i, child)) == 0) {
8782#ifdef MAIA_EXTRA_DEBUG
8783 if(a_childId(i, child) > -1) {
8784 m_log <<
"DynamicLoadBalancing Debug: global childId " << a_childId(i, child) <<
" does not exist" << endl;
8787 a_childId(i, child) = -1;
8790 a_childId(i, child) = globalToLocal[a_childId(i, child)];
8797 for(
MInt level = m_minLevel; level <= m_maxRfnmntLvl; ++level) {
8798 if(m_noHaloCellsOnLevel[level] > 0) {
8799 for(
MInt i = m_haloCellOffsetsLevel[level][0]; i < m_haloCellOffsetsLevel[level][1]; ++i) {
8800 if(globalToLocal.count(a_parentId(i)) == 0) {
8803 a_parentId(i) = globalToLocal[a_parentId(i)];
8806 for(
MInt ngh = 0; ngh < m_noNeighbors; ++ngh) {
8807 if(globalToLocal.count(a_neighborId(i, ngh)) == 0) {
8808 a_neighborId(i, ngh) = -1;
8810 a_neighborId(i, ngh) = globalToLocal[a_neighborId(i, ngh)];
8814 a_noChildren(i) = 0;
8815 for(
MInt child = 0; child < m_maxNoChildren; ++child) {
8816 if(globalToLocal.count(a_childId(i, child)) == 0) {
8817 a_childId(i, child) = -1;
8819 a_childId(i, child) = globalToLocal[a_childId(i, child)];
8830 RECORD_TIMER_STOP(t_globalToLocal);
8836#ifdef MAIA_EXTRA_DEBUG
8837 m_log <<
"DynamicLoadBalancing Extra Debug: Step 6 - Reset lookup table" << endl;
8840 m_cellIdLUT.clear();
8842 for(
MInt level = m_minLevel; level <= m_maxRfnmntLvl; ++level) {
8843 for(
MInt cellId = m_levelOffsets[level][0]; cellId < m_levelOffsets[level][1]; cellId++) {
8844 m_cellIdLUT.insert(m_cellIdLUT.end(), make_pair(cellId, cellId));
8847 for(
MInt cellId = m_haloCellOffsetsLevel[level][0]; cellId < m_haloCellOffsetsLevel[level][1]; cellId++) {
8848 m_cellIdLUT.insert(m_cellIdLUT.end(), make_pair(cellId, cellId));
8852 RECORD_TIMER_STOP(t_dynamicLoadBalancing);
8882 MInt* sndBuf = &m_noCells;
8883 MPI_Allgather(sndBuf, 1, MPI_INT, m_noCellsPerDomain, 1, MPI_INT, mpiComm(), AT_,
"sndBuf",
"m_noCellsPerDomain");
8887 m_cellOffsetPar += (
MLong)m_noCellsPerDomain[d];
8890 reorderGlobalIdsDF();
8894 vector<vector<MLong>> winCellIdsPerDomain;
8895 vector<vector<MLong>> haloCellIdsPerDomain;
8898 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
8900 winCellIdsPerDomain.push_back(w);
8903 haloCellIdsPerDomain.push_back(h);
8905 for(
MInt i = 0; i < m_noCells; ++i) {
8906 a_hasProperty(i, 3) = 0;
8907 a_hasProperty(i, 4) = 0;
8911 for(
MInt lev = m_minLevel; lev <= m_maxRfnmntLvl; lev++) {
8912 MInt lev_pos = 2 * (lev - m_minLevel);
8913 for(
MInt p = m_haloCellOffsets[dom][lev_pos]; p < m_haloCellOffsets[dom][lev_pos + 1]; p++) {
8914 haloCellIdsPerDomain[dom].push_back(m_cellIdLUT[p]);
8925 noDataToSend.
fill(0);
8926 noDataToReceive.
fill(0);
8928 for(
MInt i = 0; i < m_noNeighborDomains; ++i) {
8929 noDataToReceive[m_neighborDomains[i]] = (
MInt)haloCellIdsPerDomain[i].size();
8930 noDataToReceive[noDomains()] += (
MInt)haloCellIdsPerDomain[i].size();
8933 for(
MInt d = 0; d < noDomains(); ++d) {
8934 MPI_Scatter(noDataToReceive.
getPointer(), 1, MPI_INT, &noDataToSend[d], 1, MPI_INT, d, mpiComm(), AT_,
8935 "noDataToReceive.getPointer()",
"noDataToSend[d]");
8938 for(
MInt i = 0; i < noDomains(); ++i) {
8939 noDataToSend[noDomains()] += noDataToSend[i];
8943 MFloatScratchSpace haloCoordinates(noDataToSend[noDomains()], nDim, AT_,
"haloCoordinates");
8947 for(
MInt dim = 0; dim < nDim; ++dim) {
8952 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8953 for(
MInt i = 0; i < noDataToReceive[m_neighborDomains[dom]]; ++i) {
8954 recvBuffer(i + offset) = a_coordinate((
MInt)haloCellIdsPerDomain[dom][i], dim);
8956 offset += noDataToReceive[m_neighborDomains[dom]];
8959 communicateDouble(sendBuffer, noDataToSend, recvBuffer, noDataToReceive);
8962 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8963 for(
MInt i = 0; i < noDataToSend[m_neighborDomains[dom]]; ++i) {
8964 haloCoordinates(i + offset, dim) = sendBuffer(i + offset);
8966 offset += noDataToSend[m_neighborDomains[dom]];
8973 MIntScratchSpace recvBuffer(noDataToReceive[noDomains()], AT_,
"recvBuffer");
8976 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8977 for(
MInt i = 0; i < noDataToReceive[m_neighborDomains[dom]]; ++i) {
8978 recvBuffer(i + offset) = a_level((
MInt)haloCellIdsPerDomain[dom][i]);
8980 offset += noDataToReceive[m_neighborDomains[dom]];
8983 communicateInt(sendBuffer, noDataToSend, recvBuffer, noDataToReceive);
8986 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
8987 for(
MInt i = 0; i < noDataToSend[m_neighborDomains[dom]]; ++i) {
8988 haloLevel(i + offset) = sendBuffer(i + offset);
8990 offset += noDataToSend[m_neighborDomains[dom]];
8996 vector<Point<3>> pts;
8997 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
8998 IF_CONSTEXPR(nDim == 2) {
8999 Point<3> pt(a_coordinate(cellId, 0), a_coordinate(cellId, 1), 0.0, cellId);
9003 Point<3> pt(a_coordinate(cellId, 0), a_coordinate(cellId, 1), a_coordinate(cellId, 2), cellId);
9011 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
9012 for(
MInt i = 0; i < noDataToSend[m_neighborDomains[dom]]; ++i) {
9015 IF_CONSTEXPR(nDim == 2) {
9016 Point<3> pt(haloCoordinates(i + offset, 0), haloCoordinates(i + offset, 1), 0.0, cellId);
9017 cellId = tree.
nearest(pt, distance);
9020 Point<3> pt(haloCoordinates(i + offset, 0), haloCoordinates(i + offset, 1), haloCoordinates(i + offset, 2),
9022 cellId = tree.
nearest(pt, distance);
9025 winCellIdsPerDomain[dom].push_back(a_globalId(cellId));
9028 offset += noDataToSend[m_neighborDomains[dom]];
9035 sendBuffer.
fill(-2);
9036 recvBuffer.
fill(-2);
9039 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
9040 for(
MInt i = 0; i < (signed)winCellIdsPerDomain[dom].size(); ++i) {
9041 sendBuffer(i + offset) = winCellIdsPerDomain[dom][i];
9043 offset += (
MInt)winCellIdsPerDomain[dom].size();
9046 communicateLong(recvBuffer, noDataToReceive, sendBuffer, noDataToSend);
9049 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
9050 for(
MInt i = 0; i < (signed)haloCellIdsPerDomain[dom].size(); ++i) {
9051 a_globalId((
MInt)haloCellIdsPerDomain[dom][i]) = recvBuffer(i + offset);
9053 offset += (signed)haloCellIdsPerDomain[dom].size();
9061 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
9062 if(a_parentId(cellId) > -1) {
9063 a_parentId(cellId) = a_globalId((
MInt)a_parentId(cellId));
9066 for(
MInt i = 0; i < m_maxNoChildren; ++i) {
9067 if(a_childId(cellId, i) > -1) {
9068 a_childId(cellId, i) = a_globalId((
MInt)a_childId(cellId, i));
9072 for(
MInt i = 0; i < m_noNeighbors; ++i) {
9073 if(a_neighborId(cellId, i) > -1) {
9074 a_neighborId(cellId, i) = a_globalId((
MInt)a_neighborId(cellId, i));
9091 vector<vector<MInt>>& haloCellIdsPerDomain) {
9094 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
9095 for(
MInt i = 0; i < m_noCells; i++) {
9096 a_hasProperty(i, 3) = 0;
9100 for(
MInt lev = m_minLevel; lev <= m_maxRfnmntLvl; lev++) {
9102 MInt lev_pos = 2 * (lev - m_minLevel);
9103 for(
MInt p = m_haloCellOffsets[dom][lev_pos]; p < m_haloCellOffsets[dom][lev_pos + 1]; p++) {
9104 const MInt cellId = m_cellIdLUT[p];
9105 haloCellIdsPerDomain[dom].push_back(cellId);
9106 for(
MInt n = 0; n < m_noNeighbors; n++) {
9107 if(a_neighborId(cellId, n) < m_noCells && a_neighborId(cellId, n) > -1) {
9108 a_hasProperty((
MInt)a_neighborId(cellId, n), 3) = 1;
9116 for(
MInt lev = m_minLevel; lev <= m_maxRfnmntLvl; lev++) {
9118 for(
MInt i = m_levelOffsets[lev][0]; i < m_levelOffsets[lev][1]; i++) {
9119 if(a_hasProperty(m_cellIdLUT[i], 3)) {
9120 winCellIdsPerDomain[dom].push_back(m_cellIdLUT[i]);
9143 vector<vector<MInt>>& haloCellIdsPerDomain) {
9146 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
9147 for(
MInt i = 0; i < m_noCells; ++i) {
9148 a_hasProperty(i, 3) = 0;
9149 a_hasProperty(i, 4) = 0;
9152 for(
MInt lev = m_minLevel; lev <= m_maxRfnmntLvl; lev++) {
9153 MInt lev_pos = 2 * (lev - m_minLevel);
9154 for(
MInt p = m_haloCellOffsets[dom][lev_pos]; p < m_haloCellOffsets[dom][lev_pos + 1]; p++) {
9155 haloCellIdsPerDomain[dom].push_back(m_cellIdLUT[p]);
9163 noDataToSend.
fill(0);
9164 noDataToReceive.
fill(0);
9166 for(
MInt i = 0; i < m_noNeighborDomains; ++i) {
9167 noDataToReceive[m_neighborDomains[i]] = (
MInt)haloCellIdsPerDomain[i].size();
9168 noDataToReceive[noDomains()] += (
MInt)haloCellIdsPerDomain[i].size();
9172 "noDataToReceive.getPointer()",
"noDataToSend.getPointer()");
9174 for(
MInt i = 0; i < noDomains(); ++i) {
9175 noDataToSend[noDomains()] += noDataToSend[i];
9179 MFloatScratchSpace haloCoordinates(noDataToSend[noDomains()], nDim, AT_,
"haloCoordinates");
9180 for(
MInt dim = 0; dim < nDim; ++dim) {
9185 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
9186 for(
MInt i = 0; i < noDataToReceive[m_neighborDomains[dom]]; ++i) {
9187 recvBuffer(i + offset) = a_coordinate(haloCellIdsPerDomain[dom][i], dim);
9189 offset += noDataToReceive[m_neighborDomains[dom]];
9192 communicateDouble(sendBuffer, noDataToSend, recvBuffer, noDataToReceive);
9195 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
9196 for(
MInt i = 0; i < noDataToSend[m_neighborDomains[dom]]; ++i) {
9197 haloCoordinates(i + offset, dim) = sendBuffer(i + offset);
9199 offset += noDataToSend[m_neighborDomains[dom]];
9207 MIntScratchSpace recvBuffer(noDataToReceive[noDomains()], AT_,
"recvBuffer");
9210 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
9211 for(
MInt i = 0; i < noDataToReceive[m_neighborDomains[dom]]; ++i) {
9212 recvBuffer(i + offset) = a_level(haloCellIdsPerDomain[dom][i]);
9214 offset += noDataToReceive[m_neighborDomains[dom]];
9217 communicateInt(sendBuffer, noDataToSend, recvBuffer, noDataToReceive);
9220 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
9221 for(
MInt i = 0; i < noDataToSend[m_neighborDomains[dom]]; ++i) {
9222 haloLevel(i + offset) = sendBuffer(i + offset);
9224 offset += noDataToSend[m_neighborDomains[dom]];
9229 vector<Point<3>> pts;
9230 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
9231 IF_CONSTEXPR(nDim == 2) {
9232 Point<3> pt(a_coordinate(cellId, 0), a_coordinate(cellId, 1), 0.0, cellId);
9236 Point<3> pt(a_coordinate(cellId, 0), a_coordinate(cellId, 1), a_coordinate(cellId, 2), cellId);
9244 for(
MInt dom = 0; dom < m_noNeighborDomains; ++dom) {
9245 for(
MInt i = 0; i < noDataToSend[m_neighborDomains[dom]]; ++i) {
9248 IF_CONSTEXPR(nDim == 2) {
9249 Point<3> pt(haloCoordinates(i + offset, 0), haloCoordinates(i + offset, 1), 0.0, cellId);
9250 cellId = tree.
nearest(pt, distance);
9253 Point<3> pt(haloCoordinates(i + offset, 0), haloCoordinates(i + offset, 1), haloCoordinates(i + offset, 2),
9255 cellId = tree.
nearest(pt, distance);
9259 winCellIdsPerDomain[dom].push_back(cellId);
9262 offset += noDataToSend[m_neighborDomains[dom]];
9290 MPI_Status statusRecv;
9297 for(
MInt i = 1; i < noDomains(); ++i) {
9298 sendOffset[i] = sendOffset[i - 1] + noCellsToSend[i - 1];
9299 recvOffset[i] = recvOffset[i - 1] + noCellsToReceive[i - 1];
9302 for(
MInt dom = 0; dom < noDomains(); ++dom) {
9304 if(noCellsToReceive[dom] == 0) {
9310 MPI_Recv(recvData.
getPointer(), noCellsToReceive[dom], MPI_INT, dom, dom, mpiComm(), &statusRecv, AT_,
9311 "recvData.getPointer()");
9312 for(
MInt i = 0; i < noCellsToReceive[dom]; ++i) {
9313 recvBuffer[i + recvOffset[dom]] = recvData[i];
9318 for(
MInt toDom = 0; toDom < noDomains(); ++toDom) {
9325 for(
MInt i = 0; i < noCellsToSend[toDom]; ++i) {
9326 sendData[i] = sendBuffer[i + sendOffset[toDom]];
9330 "sendData.getPointer()");
9362 MPI_Status statusRecv;
9369 for(
MInt i = 1; i < noDomains(); ++i) {
9370 sendOffset[i] = sendOffset[i - 1] + noCellsToSend[i - 1];
9371 recvOffset[i] = recvOffset[i - 1] + noCellsToReceive[i - 1];
9374 for(
MInt dom = 0; dom < noDomains(); ++dom) {
9376 if(noCellsToReceive[dom] == 0) {
9382 MPI_Recv(recvData.
getPointer(), noCellsToReceive[dom], MPI_LONG, dom, dom, mpiComm(), &statusRecv, AT_,
9383 "recvData.getPointer()");
9384 for(
MInt i = 0; i < noCellsToReceive[dom]; ++i) {
9385 recvBuffer[i + recvOffset[dom]] = recvData[i];
9390 for(
MInt toDom = 0; toDom < noDomains(); ++toDom) {
9397 for(
MInt i = 0; i < noCellsToSend[toDom]; ++i) {
9398 sendData[i] = sendBuffer[i + sendOffset[toDom]];
9402 "sendData.getPointer()");
9435 MPI_Status statusRecv;
9442 for(
MInt i = 1; i < noDomains(); ++i) {
9443 sendOffset[i] = sendOffset[i - 1] + noCellsToSend[i - 1];
9444 recvOffset[i] = recvOffset[i - 1] + noCellsToReceive[i - 1];
9447 for(
MInt dom = 0; dom < noDomains(); ++dom) {
9449 if(noCellsToReceive[dom] == 0) {
9454 recvData.
fill(-2.0);
9455 MPI_Recv(recvData.
getPointer(), noCellsToReceive[dom], MPI_DOUBLE, dom, dom, mpiComm(), &statusRecv, AT_,
9456 "recvData.getPointer()");
9457 for(
MInt i = 0; i < noCellsToReceive[dom]; ++i) {
9458 recvBuffer[i + recvOffset[dom]] = recvData[i];
9463 for(
MInt toDom = 0; toDom < noDomains(); ++toDom) {
9469 sendData.
fill(-2.0);
9470 for(
MInt i = 0; i < noCellsToSend[toDom]; ++i) {
9471 sendData[i] = sendBuffer[i + sendOffset[toDom]];
9475 "sendData.getPointer()");
9500 for(
MInt i = 1; i < m_noNeighborDomains; i++) {
9501 sendOffset[i] = sendOffset[i - 1] + noCellsToSend[i - 1];
9502 recvOffset[i] = recvOffset[i - 1] + noCellsToReceive[i - 1];
9506 for(
MInt i = 0; i < m_noNeighborDomains; i++)
9507 if(noCellsToReceive[i] > 0) noRecv++;
9512 for(
MInt i = 0, rCnt = 0; i < m_noNeighborDomains; i++)
9513 if(noCellsToReceive[i] > 0) {
9514 MPI_Irecv(recvMem.
getPointer() + noVar * recvOffset[i], noVar * noCellsToReceive[i], MPI_INT,
9515 m_neighborDomains[i], 0, MPI_COMM_WORLD, request.
getPointer() + rCnt, AT_,
9516 "recvMem.getPointer() + noVar * recvOffset[i]");
9520 for(
MInt i = 0; i < m_noNeighborDomains; i++)
9521 if(noCellsToSend[i] > 0) {
9522 MPI_Send(sendMem.
getPointer() + noVar * sendOffset[i], noVar * noCellsToSend[i], MPI_INT, m_neighborDomains[i], 0,
9523 MPI_COMM_WORLD, AT_,
"sendMem.getPointer() + noVar * sendOffset[i]");
9546 RECORD_TIMER_START(m_t_saveGrid);
9548 m_log <<
" (7) writing grid to file" << endl;
9549 outStream <<
" (7) writing grid to file" << endl;
9551 if(m_noTotalCells > numeric_limits<MInt>::max()) {
9552 outStream <<
"Exceeding 32bit boundary." << endl;
9555 m_noPartitionCells = (
MInt)m_partitionCellList.size();
9559 MString filename = m_outputDir;
9560 filename.append(m_gridOutputFileName);
9563 MInt minLevel = m_maxLevels;
9564 for(
MInt j = 0; j < m_noCells; ++j) {
9565 maxLevel =
mMax(a_level(j), maxLevel);
9566 minLevel =
mMin(a_level(j), minLevel);
9569 MLong maxNoCells = m_noCells;
9572 m_log <<
"Save grid: maximum number of cells per rank: " << maxNoCells << std::endl;
9574 MLong maxNoHalos = m_noTotalHaloCells;
9577 m_log <<
"Save grid: maximum number of halo cells per rank: " << maxNoHalos << std::endl;
9579 MPI_Allreduce(MPI_IN_PLACE, &maxLevel, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"maxLevel");
9580 MPI_Allreduce(MPI_IN_PLACE, &minLevel, 1, MPI_INT, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
"minLevel");
9582 MFloat totalWorkload = F0;
9583 for(
MInt i = 0; i < m_noPartitionCells; ++i) {
9584 totalWorkload += get<2>(m_partitionCellList[i]);
9586 MPI_Allreduce(MPI_IN_PLACE, &totalWorkload, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"totalWorkload");
9589 MLong maxNoOffsprings = 0;
9591 for(
MInt i = 0; i < m_noPartitionCells; ++i) {
9592 if(get<1>(m_partitionCellList[i]) + 1 > maxNoOffsprings) maxNoOffsprings = get<1>(m_partitionCellList[i]) + 1;
9593 maxWorkload =
mMax(maxWorkload, get<2>(m_partitionCellList[i]));
9595 MPI_Allreduce(MPI_IN_PLACE, &maxNoOffsprings, 1, MPI_LONG, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
9597 MPI_Allreduce(MPI_IN_PLACE, &maxWorkload, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"maxWorkload");
9605 MFloat maxNoCPUs = totalWorkload / maxWorkload;
9607 MLong noTotalMinLevelCells = 0;
9608 MLong minLevelCellOffset = 0;
9609 MLong partitionCellOffset = 0;
9610 MLong noLeafCells = 0;
9611 MInt maxPartitionLevelShift = 0;
9612 MInt noMinLevelCells = 0;
9613 vector<pair<MLong, MInt>> minLevelCells;
9615 isMinLevelCell.
fill(0);
9616 for(
MInt i = 0; i < m_noCells; ++i) {
9617 if(a_level(i) == minLevel) {
9618 minLevelCells.push_back(make_pair(a_globalId(i), i));
9619 isMinLevelCell(i) = 1;
9622 if(a_noChildren(i) == 0) noLeafCells++;
9624 MPI_Allreduce(MPI_IN_PLACE, &noLeafCells, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"noLeafCells");
9625 sort(minLevelCells.begin(), minLevelCells.end());
9627 if(noDomains() == 1) {
9628 m_noTotalCells = (
MLong)m_noCells;
9629 m_noTotalPartitionCells = (
MLong)m_noPartitionCells;
9630 noTotalMinLevelCells = (
MLong)noMinLevelCells;
9632 mAlloc(m_noPartitionCellsPerDomain, noDomains(),
"m_noPartitionCellsPerDomain", AT_);
9633 MIntScratchSpace noMinLevelCellsPerDomain(noDomains(), AT_,
"noMinLevelCellsPerDomain");
9634 MPI_Allgather(&m_noPartitionCells, 1, MPI_INT, m_noPartitionCellsPerDomain, 1, MPI_INT, mpiComm(), AT_,
9635 "m_noPartitionCells",
"m_noPartitionCellsPerDomain");
9636 MPI_Allgather(&noMinLevelCells, 1, MPI_INT, noMinLevelCellsPerDomain.
getPointer(), 1, MPI_INT, mpiComm(), AT_,
9637 "noMinLevelCells",
"noMinLevelCellsPerDomain.getPointer()");
9640 partitionCellOffset += (
MLong)m_noPartitionCellsPerDomain[d];
9641 minLevelCellOffset += (
MLong)noMinLevelCellsPerDomain[d];
9644 m_noTotalPartitionCells = 0;
9645 noTotalMinLevelCells = 0;
9646 for(
MInt d = 0; d < noDomains(); d++) {
9647 m_noTotalPartitionCells += (
MLong)m_noPartitionCellsPerDomain[d];
9648 noTotalMinLevelCells += (
MLong)noMinLevelCellsPerDomain[d];
9651 MFloat avgWorkload = totalWorkload / ((
MFloat)m_noTotalPartitionCells);
9654 map<MLong, MInt> globalToLocal;
9655 for(
MInt i = 0; i < m_noCells; ++i) {
9656 globalToLocal.insert(pair<MLong, MInt>(a_globalId(i), i));
9659 set<MLong> partitionLevelAncestorIds;
9660 MInt partitionLevelShift = 0;
9661 for(
MInt i = 0; i < m_noPartitionCells; ++i) {
9662 MInt levelDiff = a_level(get<0>(m_partitionCellList[i])) - m_minLevel;
9663 partitionLevelShift =
mMax(levelDiff, partitionLevelShift);
9665 if(partitionLevelShift) {
9666 for(
MInt i = 0; i < m_noPartitionCells; ++i) {
9667 MInt cellId = get<0>(m_partitionCellList[i]);
9669 MLong parentId = a_parentId(globalToLocal[a_globalId(cellId)]);
9671 while(parentId > -1) {
9672 if(parentId >= m_cellOffsetPar && parentId < m_cellOffsetPar + m_noCells) {
9673 partitionLevelAncestorIds.insert(parentId);
9674 parentId = a_parentId(globalToLocal[parentId]);
9682 MLong totalNoPartitionLevelAncestors = 0;
9683 MLong localPartitionLevelAncestorCount = (signed)partitionLevelAncestorIds.size();
9684 MPI_Allreduce(&localPartitionLevelAncestorCount, &totalNoPartitionLevelAncestors, 1, MPI_LONG, MPI_SUM, mpiComm(),
9685 AT_,
"localPartitionLevelAncestorCount",
"totalNoPartitionLevelAncestors");
9686 MPI_Allreduce(&partitionLevelShift, &maxPartitionLevelShift, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
9687 "partitionLevelShift",
"maxPartitionLevelShift");
9689 ParallelIo grid(filename, PIO_REPLACE, mpiComm());
9691 grid.defineArray(PIO_LONG,
"partitionCellsGlobalId", m_noTotalPartitionCells);
9692 grid.defineArray(PIO_FLOAT,
"partitionCellsWorkload", m_noTotalPartitionCells);
9694 grid.defineArray(PIO_LONG,
"minLevelCellsTreeId", noTotalMinLevelCells);
9695 grid.defineArray(PIO_LONG,
"minLevelCellsNghbrIds", 2 * nDim * noTotalMinLevelCells);
9697 grid.defineArray(PIO_UCHAR,
"cellInfo", m_noTotalCells);
9699 if(m_noSolvers > 1 ||
g_multiSolverGrid) grid.defineArray(PIO_UCHAR,
"solver", m_noTotalCells);
9701 if(m_writeCoordinatesToGridFile) {
9702 m_log <<
"NOTE: writing coordinates to grid file" << std::endl;
9703 for(
MInt i = 0; i < nDim; i++) {
9704 grid.defineArray(PIO_FLOAT,
"coordinates_" + std::to_string(i), m_noTotalCells);
9710 MPI_Offset start = -1;
9711 MPI_Offset startMinLevelCells = -1;
9712 MPI_Offset startPartitionCells = -1;
9713 MPI_Offset count = -1;
9714 MPI_Offset countMinLevelCells = -1;
9715 MPI_Offset countPartitionCells = -1;
9722 for(
MInt b = 0;
b < m_noSolvers;
b++) {
9723 MLong solverCount = 0;
9725 for(
MInt i = 0; i < m_noCells; i++) {
9726 if(a_isInSolver(i,
b) ==
true) {
9730 cerr <<
"counted: " << solverCount <<
" for solver: " <<
b << endl;
9731 stringstream attributeName;
9732 attributeName <<
"noCells_" <<
b;
9734 MPI_Allreduce(MPI_IN_PLACE, &solverCount, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"solverCount");
9736 grid.setAttributes(&solverCount, attributeName.str(), 1);
9741 grid.setAttributes(&nodims,
"nDim", 1);
9742 grid.setAttributes(&m_noSolvers,
"noSolvers", 1);
9743 grid.setAttributes(&tstep,
"globalTimeStep", 1);
9744 grid.setAttributes(&m_noTotalCells,
"noCells", 1);
9745 grid.setAttributes(&noLeafCells,
"noLeafCells", 1);
9746 grid.setAttributes(&noTotalMinLevelCells,
"noMinLevelCells", 1);
9747 grid.setAttributes(&m_noTotalPartitionCells,
"noPartitionCells", 1);
9748 grid.setAttributes(&totalNoPartitionLevelAncestors,
"noPartitionLevelAncestors", 1);
9749 grid.setAttributes(&minLevel,
"minLevel", 1);
9750 grid.setAttributes(&maxLevel,
"maxLevel", 1);
9751 grid.setAttributes(&m_maxUniformRefinementLevel,
"maxUniformRefinementLevel", 1);
9752 grid.setAttributes(&maxPartitionLevelShift,
"maxPartitionLevelShift", 1);
9753 grid.setAttributes(&m_lengthOnLevel[0],
"lengthLevel0", 1);
9754 grid.setAttributes(&m_centerOfGravity[0],
"centerOfGravity", nDim);
9755 grid.setAttributes(&m_boundingBox[0],
"boundingBox", 2 * nDim);
9758 if(m_hasMultiSolverBoundingBox) {
9759 grid.setAttributes(&m_multiSolverLengthLevel0,
"multiSolverLengthLevel0", 1);
9760 grid.setAttributes(&m_multiSolverMinLevel,
"multiSolverMinLevel", 1);
9761 grid.setAttributes(&m_multiSolverCenterOfGravity[0],
"multiSolverCenterOfGravity", nDim);
9762 grid.setAttributes(&m_multiSolverBoundingBox[0],
"multiSolverBoundingBox", 2 * nDim);
9765 grid.setAttributes(&m_reductionFactor,
"reductionFactor", 1);
9766 grid.setAttributes(&m_decisiveDirection,
"decisiveDirection", 1);
9767 grid.setAttributes(&totalWorkload,
"totalWorkload", 1);
9768 grid.setAttributes(&maxWorkload,
"partitionCellMaxWorkload", 1);
9769 grid.setAttributes(&avgWorkload,
"partitionCellAverageWorkload", 1);
9770 grid.setAttributes(&maxNoOffsprings,
"partitionCellMaxNoOffspring", 1);
9771 grid.setAttributes(&avgOffspring,
"partitionCellAverageNoOffspring", 1);
9772 grid.setAttributes(&m_partitionCellWorkloadThreshold,
"partitionCellWorkloadThreshold", 1);
9773 grid.setAttributes(&m_partitionCellOffspringThreshold,
"partitionCellOffspringThreshold", 1);
9774 grid.setAttributes(&maxNoCPUs,
"maxNoBalancedCPUs", 1);
9777 start = m_cellOffsetPar;
9778 startMinLevelCells = minLevelCellOffset;
9779 startPartitionCells = partitionCellOffset;
9781 countMinLevelCells = noMinLevelCells;
9782 countPartitionCells = m_noPartitionCells;
9786 grid.setOffset(countPartitionCells, startPartitionCells);
9791 for(
MInt i = 0; i < m_noPartitionCells; ++i)
9792 tmp[i] = a_globalId(get<0>(m_partitionCellList[i]));
9793 grid.writeArray(tmp.
getPointer(),
"partitionCellsGlobalId");
9798 for(
MInt i = 0; i < m_noPartitionCells; ++i)
9799 tmp[i] = get<2>(m_partitionCellList[i]);
9800 grid.writeArray(tmp.
getPointer(),
"partitionCellsWorkload");
9805 grid.setOffset(countMinLevelCells, startMinLevelCells);
9810 "Tree id can not be stored using 64 bits. Change minLevelCellsTreeId to 128 bits or reduce minLevel to 21 "
9817 const MLong tmpMinLevel = (m_multiSolverMinLevel > -1) ? m_multiSolverMinLevel : minLevel;
9818 const MFloat tmpLength0 = (m_multiSolverMinLevel > -1) ? m_multiSolverLengthLevel0 : m_lengthOnLevel[0];
9819 const MFloat* tmpCog = (m_multiSolverMinLevel > -1) ? &m_multiSolverCenterOfGravity[0] : m_centerOfGravity;
9821 for(
MInt i = 0; i < noMinLevelCells; ++i) {
9822 maia::grid::hilbert::coordinatesToTreeId<nDim>(tmp[i], &a_coordinate(minLevelCells[i].second, 0), tmpMinLevel,
9823 tmpCog, tmpLength0);
9825 grid.writeArray(tmp.
getPointer(),
"minLevelCellsTreeId");
9830 for(
MInt i = 0; i < noMinLevelCells; ++i) {
9831 for(
MInt j = 0; j < m_noNeighbors; j++) {
9832 tmp(i, j) = a_neighborId(minLevelCells[i].second, j);
9835 grid.setOffset(2 * nDim * countMinLevelCells, 2 * nDim * startMinLevelCells);
9836 grid.writeArray(tmp.
getPointer(),
"minLevelCellsNghbrIds");
9840 grid.setOffset(count, start);
9846 for(
MInt i = 0; i < m_noCells; ++i) {
9847 MLong sortedLocalId = a_globalId(i) - m_cellOffsetPar;
9851 if(a_parentId(i) > -1) {
9852 MInt parentId = globalToLocal[a_parentId(i)];
9853 for(
MUint j = 0; j < (unsigned)m_maxNoChildren; j++) {
9854 if(a_childId(parentId, j) == a_globalId(i)) position = j;
9857 MUint tmpBit = noChilds | (position << 4) | (isMinLvl << 7);
9858 tmp[sortedLocalId] =
static_cast<MUchar>(tmpBit);
9860 grid.writeArray(tmp.
begin(),
"cellInfo");
9864 for(
MInt i = 0; i < m_noCells; ++i) {
9865 MLong sortedLocalId = a_globalId(i) - m_cellOffsetPar;
9867 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
9868 if(a_isInSolver(i, solver)) {
9869 tmpBit |= (1 << solver);
9872 tmp[sortedLocalId] =
static_cast<MUchar>(tmpBit);
9874 grid.writeArray(tmp.
begin(),
"solver");
9878 if(m_writeCoordinatesToGridFile) {
9880 for(
MInt d = 0; d < nDim; d++) {
9881 for(
MInt i = 0; i < m_noCells; ++i) {
9882 const MLong sortedLocalId = a_globalId(i) - m_cellOffsetPar;
9883 tmp[sortedLocalId] = a_coordinate(i, d);
9885 grid.writeArray(tmp.
begin(),
"coordinates_" + std::to_string(d));
9889 m_log <<
" + grid file written to file '" << filename <<
"'" << endl;
9890 outStream <<
" + grid file written to '" << filename <<
"'" << endl;
9892 RECORD_TIMER_STOP(m_t_saveGrid);
9896#if defined(MAIA_GCC_COMPILER)
9897#pragma GCC diagnostic pop
9929 sprintf(buf0,
"%d", tag);
9931 sprintf(buf1,
"%d", level_);
9933 preName.append(
"G");
9934 preName.append(buf);
9935 preName.append(
"_L");
9936 preName.append(buf1);
9937 preName.append(
"_");
9938 preName.append(m_gridOutputFileName);
9940 size_t size = m_noCells + m_noTotalHaloCells;
9942 size_t sndBuf = size;
9945 "noCellsPerDomain.getPointer()");
9947 size_t myOffset = 0;
9949 myOffset += noCellsPerDomain[d];
9958 TERMM(1,
"untested I/O method, please see comment for how to proceed");
9965 MString varnames[33] = {
"partitionCellsId",
9966 "partitionCellsNoOffsprings",
9967 "partitionCellsWorkLoad",
9968 "partitionCellsLvlDiff",
9999 MInt type[33] = {PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT,
10000 PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT,
10001 PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT,
10002 PIO_INT, PIO_INT, PIO_INT, PIO_FLOAT, PIO_FLOAT, PIO_FLOAT};
10004 parallelIo.defineScalar(PIO_INT,
"noCells");
10006 for(
MInt i = 0; i < 33; i++) {
10007 parallelIo.defineArray(type[i], varnames[i].c_str(), size);
10009 parallelIo.setOffset(size, 0);
10012 parallelIo.writeScalar(s,
"noCells");
10014 MInt shift = m_haloCellOffsetsLevel[level_][0] - m_noCells;
10021 for(; i < m_noCells; i++)
10022 tmpVars[i] = i + myOffset;
10023 if(noDomains() > 1)
10024 for(
MInt j = m_haloCellOffsetsLevel[level_][0]; j < m_maxNoCells - 1; j++, i++)
10025 tmpVars[i] = j - shift + myOffset;
10026 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10031 for(
MInt j = 0; j < 3; j++) {
10034 for(; i < m_noCells; i++)
10036 if(noDomains() > 1)
10037 for(
MInt k = m_haloCellOffsetsLevel[level_][0]; k < m_maxNoCells - 1; k++, i++)
10039 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10047 for(; i < m_noCells; i++) {
10048 if(a_parentId(i) >= 0)
10049 tmpVars[i] = (
MInt)a_parentId(i) + myOffset;
10051 tmpVars[i] = (
MInt)a_parentId(i);
10053 if(noDomains() > 1) {
10054 for(
MInt j = m_haloCellOffsetsLevel[level_][0]; j < m_maxNoCells - 1; j++, i++) {
10055 if(a_parentId(j) >= 0)
10056 tmpVars[i] = (
MInt)a_parentId(j) - shift + myOffset;
10058 tmpVars[i] = (
MInt)a_parentId(j);
10061 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10069 for(; i < m_noCells; i++)
10071 if(noDomains() > 1)
10072 for(
MInt j = m_haloCellOffsetsLevel[level_][0]; j < m_maxNoCells - 1; j++, i++)
10074 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10079 for(
MInt j = 0; j < 8; j++) {
10082 for(; i < m_noCells; i++) {
10083 if(a_childId(i, j) >= 0)
10084 tmpVars[i] = (
MInt)a_childId(i, j) + myOffset;
10086 tmpVars[i] = (
MInt)a_childId(i, j);
10088 if(noDomains() > 1) {
10089 for(
MInt k = m_haloCellOffsetsLevel[level_][0]; k < m_maxNoCells - 1; k++, i++) {
10090 if(a_childId(k, j) >= 0)
10091 tmpVars[i] = (
MInt)a_childId(k, j) - shift + myOffset;
10093 tmpVars[i] = (
MInt)a_childId(k, j);
10096 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10101 for(
MInt j = 0; j < 3; j++) {
10104 for(; i < m_noCells; i++)
10105 tmpVars[i] = a_level(i);
10106 if(noDomains() > 1)
10107 for(
MInt k = m_haloCellOffsetsLevel[level_][0]; k < m_maxNoCells - 1; k++, i++)
10108 tmpVars[i] = a_level(k);
10109 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10114 for(
MInt j = 0; j < 6; j++) {
10117 for(; i < m_noCells; i++)
10118 tmpVars[i] = (a_neighborId(i, j)) >= 0 ? 1 : 0;
10119 if(noDomains() > 1)
10120 for(
MInt k = m_haloCellOffsetsLevel[level_][0]; k < m_maxNoCells - 1; k++, i++)
10121 tmpVars[i] = (a_neighborId(k, j)) >= 0 ? 1 : 0;
10122 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10127 for(
MInt j = 0; j < 6; j++) {
10130 if(noDomains() > 1) {
10131 for(; i < m_noCells; i++) {
10132 if(a_neighborId(i, j) >= 0)
10133 if(a_neighborId(i, j) >= m_noCells)
10134 tmpVars[i] = (
MInt)a_neighborId(i, j) - shift;
10136 tmpVars[i] = (
MInt)a_neighborId(i, j);
10138 tmpVars[i] = (
MInt)a_neighborId(i, j);
10140 for(
MInt k = m_haloCellOffsetsLevel[level_][0]; k < m_maxNoCells - 1; k++, i++) {
10141 if(a_neighborId(k, j) >= 0)
10142 if(a_neighborId(k, j) >= m_noCells)
10143 tmpVars[i] = (
MInt)a_neighborId(k, j) - shift;
10145 tmpVars[i] = (
MInt)a_neighborId(k, j);
10147 tmpVars[i] = (
MInt)a_neighborId(k, j);
10150 for(; i < m_noCells; i++)
10151 if(a_neighborId(i, j) >= m_noCells)
10152 tmpVars[i] = (
MInt)a_neighborId(i, j) + myOffset;
10154 tmpVars[i] = (
MInt)a_neighborId(i, j);
10156 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10164 for(; i < m_noCells; i++)
10166 if(noDomains() > 1)
10167 for(
MInt j = m_haloCellOffsetsLevel[level_][0]; j < m_maxNoCells - 1; j++, i++)
10169 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10174 for(
MInt j = 0; j < 3; j++) {
10177 for(; i < m_noCells; i++)
10178 tmpVars[i] = a_coordinate(i, j);
10179 if(noDomains() > 1)
10180 for(
MInt k = m_haloCellOffsetsLevel[level_][0]; k < m_maxNoCells - 1; k++, i++)
10181 tmpVars[i] = a_coordinate(k, j);
10182 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10198template <MInt nDim>
10204 outStream <<
"Writing grid info" << endl;
10211 sprintf(buf0,
"%d", tag);
10213 sprintf(buf1,
"%d", level_);
10215 preName.append(
"G");
10216 preName.append(buf);
10217 preName.append(
"_L");
10218 preName.append(buf1);
10219 preName.append(
"_");
10220 preName.append(m_gridOutputFileName);
10223 preName1.append(
"Info");
10224 preName1.append(buf);
10225 preName1.append(
"_L");
10226 preName1.append(buf1);
10227 preName1.append(
"_");
10228 preName1.append(m_gridOutputFileName);
10230 size_t size = m_noCells + m_noTotalHaloCells;
10239 TERMM(1,
"untested I/O method, please see comment for how to proceed");
10242 parallelIo.setAttribute(preName.c_str(),
"gridFile");
10246 MString varnames[5] = {
"domainId",
"haloCode",
"windowCode",
"bndCut",
"inside"};
10247 MInt type[5] = {PIO_INT, PIO_INT, PIO_INT, PIO_INT, PIO_INT};
10249 parallelIo.defineScalar(PIO_INT,
"noCells");
10251 for(
MInt i = 0; i < 5; i++) {
10252 parallelIo.defineArray(type[i], varnames[i].c_str(), size);
10257 parallelIo.writeScalar(s,
"noCells");
10259 parallelIo.setOffset(size, 0);
10261 vector<vector<MInt>> winCellIdsPerDomain;
10262 vector<vector<MInt>> haloCellIdsPerDomain;
10263 for(
MInt d = 0; d < m_noNeighborDomains; d++) {
10265 winCellIdsPerDomain.push_back(c);
10267 haloCellIdsPerDomain.push_back(e);
10271 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
10273 for(
MInt i = 0; i < m_noCells; i++)
10274 a_hasProperty(i, 3) = 0;
10277 for(
MInt lev = m_minLevel; lev <= m_maxRfnmntLvl; lev++) {
10278 MInt lev_pos = 2 * (lev - m_minLevel);
10279 for(
MInt p = m_haloCellOffsets[dom][lev_pos]; p < m_haloCellOffsets[dom][lev_pos + 1]; p++) {
10280 haloCellIdsPerDomain[dom].push_back(p);
10281 MLong* neigh = &a_neighborId(p, 0);
10282 for(
MInt n = 0; n < m_noNeighbors; n++)
10283 if(neigh[n] < m_noCells && neigh[n] > -1) {
10284 a_hasProperty(neigh[n], 3) = 1;
10290 for(
MInt lev = m_minLevel; lev <= m_maxRfnmntLvl; lev++) {
10291 for(
MInt i = m_levelOffsets[lev][0]; i < m_levelOffsets[lev][1]; i++)
10292 if(a_hasProperty(i, 3)) {
10293 winCellIdsPerDomain[dom].push_back(i);
10302 for(; i < m_noCells; i++)
10304 if(noDomains() > 1)
10305 for(
MInt k = m_haloCellOffsetsLevel[level_][0]; k < m_maxNoCells - 1; k++, i++)
10307 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10315 for(; i < m_noCells; i++)
10317 if(noDomains() > 1)
10318 for(
MInt lev = level_; lev >= m_minLevel; lev--)
10319 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++) {
10320 MInt lev_pos = 2 * (lev - m_minLevel);
10321 for(
MInt p = m_haloCellOffsets[dom][lev_pos]; p < m_haloCellOffsets[dom][lev_pos + 1]; p++, i++)
10322 tmpVars[i] = m_neighborDomains[dom];
10324 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10332 for(; i < m_noCells; i++) {
10334 for(
MInt dom = 0; dom < m_noNeighborDomains; dom++)
10335 for(
MInt k = 0; k < (signed)winCellIdsPerDomain[dom].size(); k++)
10336 if(i == winCellIdsPerDomain[dom][k]) doms.push_back(m_neighborDomains[dom]);
10338 if(doms.size() > 0) {
10340 for(
MInt l = 0; l < (signed)doms.size(); l++)
10341 code += doms[l] * pow(10, l);
10347 if(noDomains() > 1)
10348 for(
MInt k = m_haloCellOffsetsLevel[level_][0]; k < m_maxNoCells - 1; k++, i++)
10351 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10359 for(; i < m_noCells; i++)
10360 tmpVars[i] = a_hasProperty(i, 1);
10361 if(noDomains() > 1)
10362 for(
MInt k = m_haloCellOffsetsLevel[level_][0]; k < m_maxNoCells - 1; k++, i++)
10363 tmpVars[i] = a_hasProperty(k, 1);
10364 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10372 for(; i < m_noCells; i++)
10373 tmpVars[i] = a_hasProperty(i, 0);
10374 if(noDomains() > 1)
10375 for(
MInt k = m_haloCellOffsetsLevel[level_][0]; k < m_maxNoCells - 1; k++, i++)
10376 tmpVars[i] = a_hasProperty(k, 0);
10377 parallelIo.writeArray(tmpVars.
getPointer(), varnames[cnt].c_str());
10390template <MInt nDim>
10394 outStream <<
"WRITING INFO FILE" << endl;
10402 ParallelIo grid(
"out/Info.Netcdf", PIO_REPLACE, mpiComm());
10405 grid.defineScalar(PIO_INT,
"noCells");
10406 grid.defineArray(PIO_INT,
"rfnDistance", m_noTotalCells);
10407 grid.defineArray(PIO_INT,
"bndCut", m_noTotalCells);
10408 grid.defineArray(PIO_INT,
"domainId", m_noTotalCells);
10410 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
10412 ss <<
"solver_" << solver;
10413 grid.defineArray(PIO_INT, ss.str(), m_noTotalCells);
10416 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
10418 ss <<
"solverBoundary_" << solver;
10419 grid.defineArray(PIO_INT, ss.str(), m_noTotalCells);
10422 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
10424 ss <<
"toRefine_" << solver;
10425 grid.defineArray(PIO_INT, ss.str(), m_noTotalCells);
10435 grid.setAttribute(m_gridOutputFileName,
"gridFile");
10437 MPI_Offset start = -1;
10438 MPI_Offset count = -1;
10440 MInt* tmpScratchInt = 0;
10445 grid.setOffset(count, start);
10447 grid.writeScalar(m_noTotalCells,
"noCells");
10450 if(noDomains() == 1)
10453 start = m_cellOffsetPar;
10456 grid.setOffset(count, start);
10461 for(
MInt j = 0; j < m_noCells; ++j) {
10462 MLong sortedLocalId = a_globalId(j) - m_cellOffsetPar;
10463 tmpScratchInt[sortedLocalId] = a_refinementDistance(j);
10465 grid.writeArray(tmpScratchInt,
"rfnDistance");
10467 for(
MInt j = 0; j < m_noCells; ++j) {
10468 MLong sortedLocalId = a_globalId(j) - m_cellOffsetPar;
10469 tmpScratchInt[sortedLocalId] = a_hasProperty(j, 1);
10471 grid.writeArray(tmpScratchInt,
"bndCut");
10473 for(
MInt j = 0; j < m_noCells; ++j) {
10474 MLong sortedLocalId = a_globalId(j) - m_cellOffsetPar;
10477 grid.writeArray(tmpScratchInt,
"domainId");
10479 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
10481 ss <<
"solver_" << solver;
10482 for(
MInt j = 0; j < m_noCells; ++j) {
10483 MLong sortedLocalId = a_globalId(j) - m_cellOffsetPar;
10484 tmpScratchInt[sortedLocalId] = a_isInSolver(j, solver);
10486 grid.writeArray(tmpScratchInt, ss.str());
10489 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
10491 ss <<
"solverBoundary_" << solver;
10492 for(
MInt j = 0; j < m_noCells; ++j) {
10493 MLong sortedLocalId = a_globalId(j) - m_cellOffsetPar;
10494 tmpScratchInt[sortedLocalId] = a_isSolverBoundary(j, solver);
10496 grid.writeArray(tmpScratchInt, ss.str());
10499 for(
MInt solver = 0; solver < m_noSolvers; solver++) {
10501 ss <<
"toRefine_" << solver;
10502 for(
MInt j = 0; j < m_noCells; ++j) {
10503 MLong sortedLocalId = a_globalId(j) - m_cellOffsetPar;
10504 tmpScratchInt[sortedLocalId] = a_isToRefineForSolver(j, solver);
10506 grid.writeArray(tmpScratchInt, ss.str());
10534template <MInt nDim>
10538 outStream <<
" * performing consistency check" << endl;
10540 std::array<MFloat, nDim> min;
10541 std::array<MFloat, nDim> max;
10542 for(
MInt d = 0; d < nDim; d++) {
10543 min[d] = m_centerOfGravity[d] + 0.5 * (m_reductionFactor * m_geometryExtents[m_decisiveDirection]);
10544 max[d] = m_centerOfGravity[d] - 0.5 * (m_reductionFactor * m_geometryExtents[m_decisiveDirection]);
10548 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
10549 MFloat* c = &a_coordinate(i, 0);
10551 for(
MInt d = 0; d < nDim; d++) {
10552 if(c[d] < min[d]) min[d] = c[d];
10553 if(c[d] > max[d]) max[d] = c[d];
10558 vector<vector<MInt>> min_cells;
10559 vector<vector<MInt>> max_cells;
10561 for(
MInt d = 0; d < nDim; d++) {
10562 vector<MInt> min_d;
10563 vector<MInt> max_d;
10564 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
10565 MFloat* c = &a_coordinate(i, 0);
10567 if(
approx(c[d], min[d], MFloatEps)) min_d.push_back(i);
10569 if(
approx(c[d], max[d], MFloatEps)) max_d.push_back(i);
10572 min_cells.push_back(min_d);
10573 max_cells.push_back(max_d);
10579 for(
MInt d = 0; d < 1; d++) {
10580 outStream << d << endl;
10581 MInt n_dir = 2 * d + 1;
10582 for(
MInt i = 0; i < (
MInt)min_cells[d].size(); i++) {
10583 MInt start_id = min_cells[d][i];
10585 MFloat* last_c = &a_coordinate(start_id, 0);
10587 outStream << start_id <<
": " << last_c[0] <<
" " << last_c[1] <<
" " << last_c[2] << endl;
10589 if(a_neighborId(start_id, n_dir) >= 0) {
10590 MInt next_id = a_neighborId(start_id, n_dir);
10591 MFloat* next_c = &a_coordinate(next_id, 0);
10593 while(next_id != start_id) {
10594 if(a_neighborId(next_id, n_dir) >= 0) {
10595 outStream << next_id <<
": " << next_c[0] <<
" " << next_c[1] <<
" " << next_c[2] << endl;
10596 outStream << a_hasProperty(next_id, 1) <<
" ";
10598 MInt od1 = (d + 1) % nDim;
10599 MInt od2 = (d + 2) % nDim;
10601 if(!(fabs(last_c[od1] - next_c[od1]) < eps) || !(fabs(last_c[od2] - next_c[od2]) < eps))
10602 outStream <<
"ERROR1 " << endl;
10604 if(!((fabs(last_c[d] - next_c[d]) - m_lengthOnLevel[level_]) < eps))
10605 outStream <<
"ERROR2 " << fabs(last_c[d] - next_c[d] - m_lengthOnLevel[level_]) <<
" "
10606 << m_lengthOnLevel[level_] << endl;
10608 last_c = &a_coordinate(next_id, 0);
10609 next_id = a_neighborId(next_id, n_dir);
10610 next_c = &a_coordinate(next_id, 0);
10623 for(
MInt d = 0; d < nDim; d++) {
10625 MInt n_dir = 2 * d;
10626 for(
MInt i = 0; i < (
MInt)max_cells[d].size(); i++) {
10627 MInt start_id = max_cells[d][i];
10629 MFloat* last_c = &a_coordinate(start_id, 0);
10633 if(a_neighborId(start_id, n_dir) >= 0) {
10634 MInt next_id = a_neighborId(start_id, n_dir);
10635 MFloat* next_c = &a_coordinate(next_id, 0);
10637 while(next_id != start_id) {
10638 if(a_neighborId(next_id, n_dir) >= 0) {
10641 MInt od1 = (d + 1) % nDim;
10642 MInt od2 = (d + 2) % nDim;
10644 if(!(fabs(last_c[od1] - next_c[od1]) < eps) || !(fabs(last_c[od2] - next_c[od2]) < eps))
10645 outStream <<
"ERROR1 " << endl;
10647 if(!((fabs(last_c[d] - next_c[d]) - m_lengthOnLevel[level_]) < eps))
10648 outStream <<
"ERROR2 " << fabs(last_c[d] - next_c[d] - m_lengthOnLevel[level_]) <<
" "
10649 << m_lengthOnLevel[level_] << endl;
10651 last_c = &a_coordinate(next_id, 0);
10652 next_id = a_neighborId(next_id, n_dir);
10653 next_c = &a_coordinate(next_id, 0);
10672template <MInt nDim>
10676 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
10677 MLong* neigh = &a_neighborId(i, 0);
10678 for(
MInt n = 0; n < m_noNeighbors; n++)
10679 if(neigh[n] >= 0) {
10681 for(
MInt dim = 0; dim < nDim; dim++)
10682 dist += (a_coordinate(neigh[n], dim) - a_coordinate(i, dim))
10683 * (a_coordinate(neigh[n], dim) - a_coordinate(i, dim));
10686 if(!
approx(
dist, m_lengthOnLevel[level_], MFloatEps)) outStream <<
dist << endl;
10690 for(
MInt i = m_haloCellOffsetsLevel[level_][0]; i < m_haloCellOffsetsLevel[level_][1]; i++) {
10691 MLong* neigh = &a_neighborId(i, 0);
10692 for(
MInt n = 0; n < m_noNeighbors; n++)
10693 if(neigh[n] >= 0) {
10695 for(
MInt dim = 0; dim < nDim; dim++)
10696 dist += (a_coordinate(neigh[n], dim) - a_coordinate(i, dim))
10697 * (a_coordinate(neigh[n], dim) - a_coordinate(i, dim));
10700 if(!
approx(
dist, m_lengthOnLevel[level_], MFloatEps)) {
10701 outStream << i <<
" " << n <<
" " << neigh[n] <<
" " <<
dist <<
" " << m_lengthOnLevel[level_]
10702 << a_coordinate(i, 0) <<
" " << a_coordinate(i, 1) <<
" " << a_coordinate(i, 2) <<
" "
10703 << a_coordinate(neigh[n], 0) <<
" " << a_coordinate(neigh[n], 1) <<
" " << a_coordinate(neigh[n], 2)
10704 <<
" " << a_level(i) <<
" " << a_level(neigh[n]) << endl;
10718template <MInt nDim>
10722 outStream <<
"Checking neighborhood integrity for level: " << level_ << endl;
10723 outStream <<
"Normal:" << endl;
10724 for(
MInt i = m_levelOffsets[level_][0]; i < m_levelOffsets[level_][1]; i++) {
10725 MLong* neigh = &a_neighborId(i, 0);
10726 for(
MInt n = 0; n < m_noNeighbors; n++)
10728 if(a_neighborId(neigh[n], oppositeDirGrid[n]) != i)
10730 outStream <<
"ERROR: " << i <<
" is not a neighbor of " << neigh[n] <<
" " << n <<
" " << oppositeDirGrid[n]
10735 outStream <<
"Halos" << endl;
10736 for(
MInt i = m_haloCellOffsetsLevel[level_][0]; i < m_haloCellOffsetsLevel[level_][1]; i++) {
10737 MLong* neigh = &a_neighborId(i, 0);
10738 for(
MInt n = 0; n < m_noNeighbors; n++)
10740 if(a_neighborId(neigh[n], oppositeDirGrid[n]) != i)
10742 outStream <<
"ERROR: " << i <<
" is not a neighbor of " << neigh[n] <<
" " << n <<
" " << oppositeDirGrid[n]
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
MBool mDeallocate(T *&a)
deallocates the memory previously allocated for element 'a'
define the names of all variables and attributes in the netcdf file
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 communicateDouble(MFloatScratchSpace &recvBuffer, MIntScratchSpace &noCellsToReceive, MFloatScratchSpace &sendBuffer, MIntScratchSpace &noCellsToSend)
Communicates an array of double values.
void findChildLevelNeighbors(MInt **offsets, MInt level_)
updates the children of a given level
MBool isInsideSlicedCone(const MFloat *const pointCoord, const MFloat *const leftCoord, const MFloat *const rightCoord, const MFloat *const leftNormal, const MFloat *const rightNormal, const MFloat *const normalDifforigAB, const MFloat leftR, const MFloat rightR)
checks if point (cell) is inside a sliced cone
void updateOffsets(MInt gridLevel)
updates the offsets
MInt nghborStencil(MInt, MInt)
void communicateInt(MIntScratchSpace &recvBuffer, MIntScratchSpace &noCellsToReceive, MIntScratchSpace &sendBuffer, MIntScratchSpace &noCellsToSend)
Communicates an array of int values.
void traverseDFGlobalId(MInt parentId, MLong *globalId_, MLongScratchSpace &partitionCellList, MFloatScratchSpace &workloadPerCell, MFloat *currentWorkload, MFloatScratchSpace &weight, MFloatScratchSpace &workload, MInt *j)
recursively traverses the octree
void checkMemoryAvailability(MInt stage, MInt level_)
void markInsideOutside(MInt **offsets, MInt level_)
marks inside and outside cells
MBool isInsideCylinder(const MFloat *const pointCoord, const MFloat *const leftCoord, const MFloat *const rightCoord, const MFloat *const normalDiffAB, const MFloat *const normalDiffBA, const MFloat radius, const MFloat innerRadius)
checks if point (cell) is inside a cylinder
void copyCell(MInt from, MInt to)
moves a cell from one location in the collector to another
void communicateLong(MLongScratchSpace &recvBuffer, MIntScratchSpace &noCellsToReceive, MLongScratchSpace &sendBuffer, MIntScratchSpace &noCellsToSend)
Communicates an array of int values.
void saveGridDomain(MInt level_, MInt tag)
degugging function writing the grid in serial
static void quickSort(T *globalIdArray, MInt *lookup, MInt startindex, MInt endindex)
sorts a list of integers and updates a second one
void deleteCoarseSolidCellsSerial()
performs deleting solid cells lower than maxRefinementLevel
void markSolverAffiliation(MInt level_)
marks cells without solver affiliation as outside cells
void markLocalCylinder(MInt level_, MInt patch, MInt solver, MString patchStr)
marks cells that lie in a cylinder-type patch
void refineComputationalGrid(MInt lvl)
refines cells of the computational grid that are marked for refinement
void markLocalBox(MInt level_, MInt patch, MInt solver)
marks cells that lie in a box-type patch
void initMembers()
initializes the member variables
MInt getAdjacentGridCells(MInt cellId, MInt *adjacentCells)
Retrieves all direct and diagonal neighboring cells of the given cell.
void propagationStep(MInt cellId, MInt rfnDistance, MInt finalDistance, MInt solver)
recursivley marks the cells with a distance
void updateHaloOffsets(MInt l, MInt noHalos, MInt *rfnCountHalosDom)
updates the offsets of the halos
void markLocalRectangleAngled(MInt level_, MInt patch, MInt solver)
marks cells that lie in a rectangular-angled-type patch
void checkNeighborhood(MInt level_)
checks if the neighborhood is correct
void communicateIntToNeighbors(MIntScratchSpace &recvMem, MIntScratchSpace &noCellsToReceive, MIntScratchSpace &sendMem, MIntScratchSpace &noCellsToSend, MInt noVar)
Communicates Int values, with a variable nmbr of variables to the Neighbors.
void createComputationalMultisolverGrid()
refinement > minLevel is processed in createComputationalMultisolverGrid
void performCutOff(MInt **offsets, MInt level_, MBool deleteMode=false)
performs a cut-off defined by the properties
MBool m_writeGridInformation
void deleteCellReferences(MInt cell, MInt pos)
deletes the references of a given cell
void initGeometry()
initializes the geometry
void deleteOutsideCellsSerial(MInt level_)
deletes the cells outside of the geometry
void markLocalRadius(MInt level_, MInt patch, MInt solver)
marks cells that lie in a sphere-type patch
GridgenPar(const MPI_Comm comm, const MInt noSolvers)
generates a Cartesian grid in parallel
void markBndForSolverRefinement(MInt level_, MInt solver)
void checkNeighborhoodDistance(MInt level_)
checks if the distance between neighboring cells is alright
void checkNeighborhoodIntegrity(MInt level_)
checks if the neighborhood relation of the cells is alright
void excludeInsideOutside(MInt **offsets, MInt level_, MInt solver)
excludes obvious non solver affiliated cells from the inside outside flooding
void reorderCellsHilbert()
reorders the cells after Hilbert id
void swapCells(MInt cellId1, MInt cellId2)
swaps two cells in memory
void updateGlobalIdsReferences()
updates the references of all cells to use the global-ids
void dynamicLoadBalancing()
Rebalances the grid dynamicaly while grid building.
void determineRankOffsets(MIntScratchSpace &offsets)
void readSolverProperties(MInt solver)
void findHaloAndWindowCells(std::vector< std::vector< MInt > > &winCellIdsPerDomain, std::vector< std::vector< MInt > > &haloCellIdsPerDomain)
find window cells using the known halo cells
void saveGrid()
writes the grid to file in parallel
void createSolidCellLayer(MInt cellId, MInt solidLayer, MInt finalLayer_)
void deleteOutsideCellsParallel(MInt level_)
deletes outside cells in parallel mode
void checkLBRefinementValidity()
checks if this is a valid mesh also for LB computations
void keepOutsideBndryCellChildrenSerial(MInt *offsets, MInt level_)
MBool pointIsInsideSolver(MFloat *coordinates, MInt solver)
void markLocalCartesianWedge(MInt level_, MInt patch, MInt solver)
void writeGridInformationPar()
writes a pseudo solution file with some grid information
void markLocalCone(MInt level_, MInt patch, MInt solver)
marks cells that lie in a cone-type patch with a smooth hat
void markPatchForSolverRefinement(MInt level_, MInt solver)
void markLocalHat(MInt level_, MInt patch, MInt solver)
marks cells that lie in a cone-type patch with a smooth hat
void communicateHaloGlobalIds(MInt level)
communicate the global ids of the halo cells.
void createStartGrid()
creates the start grid
MBool pointIsInside(MFloat *coordinates)
checks if a given point is inside the geometry
void collectHaloChildren(MInt parentId, std::vector< MInt > *cellIdsPerDomain)
recursively traverse the tree depth-first and collect halo cells
void refineGridPatch(MInt **offsets, MInt level_, MBool halo)
refines the grid on a given level for a provided patch
void markLocalSolverRefinement(MInt level_, MInt solver)
void gridAlignCutOff()
aligns the cutOffCoordinates with the grid
void collectWindowChildren(MInt parentId, std::vector< MInt > *cellIdsPerDomain)
recursively traverse the tree depth-first and collect window cells
void floodCells(std::stack< MInt > *fillStack, MChar marker)
floods cells
void readProperties()
reads necessary properties from the property file
void findHaloAndWindowCellsKD(std::vector< std::vector< MInt > > &winCellIdsPerDomain, std::vector< std::vector< MInt > > &haloCellIdsPerDomain)
finds halo and window cells using a kd tree
void refineCell(MInt id, MInt *currentChildId)
refines a single cell
void markSolverForRefinement(MInt level_, MInt solver)
void reorderGlobalIdsDF()
reorders the globalIds depth-first
void propagateDistance(MInt level_, MInt distance, std::vector< MInt > &rfnBoundaryGroup, MInt solver)
propagates the distance away from the boundary
void concludeSolverRefinement(MInt level_)
void parallelizeGrid()
parallize the present grid
void checkLoadBalance(MInt in_level)
checks if a dynamic load balancing is needed.
void markBndDistance(MInt level_, MInt solver)
marks cells that lie in a certain distance to the boundary
void updateInterRankNeighbors()
updates the neighbors on the neighboring ranks
MBool checkCellForCut(MInt id)
checks if a cell has a cut with the geometry
void deleteCoarseSolidCellsParallel()
performs deleting solid cells lower than maxRefinementLevel
void keepOutsideBndryCellChildrenParallel(MInt level_)
void refineGrid(MInt **offsets, MInt level_, MBool halo)
refines the grid on a given level
void setCellWeights(MFloatScratchSpace &weight)
sets the cell weights according to the box system
void writeGridInformation(MInt level_, MInt tag)
debugging function writing debug info to a file
void createInitialGrid()
creates the initial grid
void writeParallelGeometry()
void markLocalSlicedCone(MInt level_, MInt patch, MInt solver, MString patchStr)
marks cells that lie in a sliced cone-type patch
This class is a ScratchSpace.
T * getPointer() const
Deprecated: use begin() instead!
void fill(T val)
fill the scratch with a given value
void checkMultiSolverGridExtents(const MInt nDim, const MFloat *centerOfGravity, const MFloat lengthLevel0, const MInt minLevel, const MFloat *targetGridCenterOfGravity, const MFloat targetGridLengthLevel0, const MInt targetGridMinLevel)
Checks if the given grid extents and cell sizes match when creating a multisolver grid and correspond...
void mTerm(const MInt errorCode, const MString &location, const MString &message)
void writeMemoryStatistics(const MPI_Comm comm, const MInt noDomains, const MInt domainId, const MString at, const MString comment)
Write memory statistics.
constexpr Real POW2(const Real x)
MBool approx(const T &, const U &, const T)
constexpr T mMin(const T &x, const T &y)
constexpr T mMax(const T &x, const T &y)
MInt globalDomainId()
Return global domain id.
MBool g_dynamicLoadBalancing
constexpr MLong IPOW2(MInt x)
constexpr MFloat FPOW2(MInt x)
std::basic_string< char > MString
int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status, const MString &name, const MString &varname)
same as MPI_Recv
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Irecv
int MPI_Issend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Issend
int MPI_Scatter(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Scatter
int MPI_Wait(MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Wait
int MPI_Waitall(int count, MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Waitall
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allreduce
int MPI_Alltoall(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Alltoall
int MPI_Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allgather
int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Send
Namespace for auxiliary functions/classes.
PARALLELIO_DEFAULT_BACKEND ParallelIo
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)
MInt nearest(Point< DIM > pt, MFloat &dist)
MInt * localMinBoundaryThreshold
MInt * localBndRfnMinLvlDiff
MInt * localRfnBoundaryIds
MFloat * localBndRfnDistance
MInt maxUniformRefinementLevel
MInt noLocalRfnBoundaryIds
MFloat ** localRfnPatchProperties
MInt * localRfnLevelPropertiesOffset
std::vector< MString > cutOffMethods
MInt noPatchesPerLevel(MInt addLevel)
MInt noLocalPatchRfnLvls()
MFloat ** cutOffCoordinates
MInt * noLocalRfnPatchProperties
std::vector< MString > localRfnLevelMethods