void TerrainManagerModuleOrographyModifications::moveGroundPoint( point & p,scalar height0, scalar height, const word & addType){ // prepare: const Foam::vector & n_up = moduleBase().cooSys->e(TerrainBlock::UP); // add type 'add': if(addType.compare("add") == 0){ if( height != 0 ) p += height * n_up; } // add type 'max': else if(addType.compare("max") == 0){ const scalar h0 = dot(p,n_up); if( height0 + height > h0 ){ p += (height0 + height - h0) * n_up; } } // add type 'average': else if(addType.compare("average") == 0){ if( height != 0 ){ const scalar h0 = dot(p,n_up); scalar h = 0.5 * ( 2 * h0 + height0 + height ); p += (h - h0) * n_up; } } // add type 'hill': else if(addType.compare("hill") == 0){ if( height != 0.){ const scalar h0 = dot(p,n_up); p += (height0 + height - h0) * n_up; } } }
void TerrainManagerModuleCylinder::reserveStorageCylinder(){ cylinderBlockNr_ = cylinderRadialBlocks_ * moduleBase().walkBoxMaximum(); cylinderPointNr_ = cylinderRadialBlocks_ * moduleBase().walkBoxMaximum() * 2; if(cylinderSectionNr_ > cylinderBlockNr_){ Info << "\nTerrainManager: Error: The outer cylinder cannot have that many sections." << endl; Info << " sections : " << cylinderSectionNr_ <<endl; Info << " at most allowed: " << cylinderBlockNr_ << endl; throw; } moduleBase().resizePoints(moduleBase().points().size() + cylinderPointNr_); moduleBase().resizeBlocks(moduleBase().blocks().size() + cylinderBlockNr_); moduleBase().resizeEdges(moduleBase().edges().size() + 4 * cylinderBlockNr_); cylinderPointAdr_.resize(cylinderPointNr_); cylinderBlockAdr_.resize(cylinderBlockNr_); Info << " reserved storage for " << cylinderPointNr_ << " points, " << cylinderBlockNr_ << " blocks and " << 4 * cylinderBlockNr_ << " edges" << endl; }
void TerrainManagerModuleOrographyModifications::makeCyclic(label patchIA, label patchIB,const scalar & depth){ // prepare: label dir_perp = 0; label dir_long = 0; labelList vListA(2); labelList vListB(2); if(patchIA == BasicBlock::WEST && patchIB == BasicBlock::EAST){ dir_perp = 0; dir_long = 1; vListA[0] = BasicBlock::SWL; vListA[1] = BasicBlock::NWL; vListB[0] = BasicBlock::SEL; vListB[1] = BasicBlock::NEL; } else if(patchIA == BasicBlock::EAST && patchIB == BasicBlock::WEST){ makeCyclic(patchIB,patchIA,depth); return; } else if(patchIA == BasicBlock::SOUTH && patchIB == BasicBlock::NORTH){ dir_perp = 1; dir_long = 0; vListA[0] = BasicBlock::SWL; vListA[1] = BasicBlock::SEL; vListB[0] = BasicBlock::NWL; vListB[1] = BasicBlock::NEL; } else if(patchIA == BasicBlock::NORTH && patchIB == BasicBlock::SOUTH){ makeCyclic(patchIB,patchIA,depth); return; } labelList splPerp(2); const Foam::vector & n_perp = moduleBase().cooSys->e(dir_perp); const Foam::vector & n_long = moduleBase().cooSys->e(dir_long); const Foam::vector & n_up = moduleBase().cooSys->e(2); label splineA = SplineBlock::getSplineLabel(vListA[0],vListA[1]); label splineB = SplineBlock::getSplineLabel(vListB[0],vListB[1]); splPerp[0] = SplineBlock::getSplineLabel(vListA[0],vListB[0]); splPerp[1] = SplineBlock::getSplineLabel(vListA[1],vListB[1]); // calculate goal mean heights, set boundary values: HashTable<scalar> hMean_ilv; List<pointField> hMeanSplines_il(moduleBase().blockNrs[dir_long]); for(label il = 0; il < moduleBase().blockNrs[dir_long]; il++){ // point means: for(label v = 0; v < 2; v++){ // v = 1 is only relevant for last block: if(v == 1 && il < moduleBase().blockNrs[dir_long] - 1) continue; // calc average height: word keyA = dir_long == 0 ? key(il,0,vListA[v]): key(0,il,vListA[v]); word keyB = dir_long == 0 ? key(il,moduleBase().blockNrs[dir_perp] - 1,vListB[v]): key(moduleBase().blockNrs[dir_perp] - 1,il,vListB[v]); point & pA = moduleBase().points[moduleBase().pointAdr_ijv[keyA]]; point & pB = moduleBase().points[moduleBase().pointAdr_ijv[keyB]]; scalar h_av = 0.5 * ( dot(pA,n_up) + dot(pB,n_up) ); // store: hMean_ilv.set(key(il,v),h_av); // set boundary points to average: pA += (h_av - dot(pA,n_up)) * n_up; pB += (h_av - dot(pB,n_up)) * n_up; } } // mean parallel moduleBase().splines: for(label il = 0; il < moduleBase().blockNrs[dir_long]; il++){ // grab moduleBase().splines: word keyA = dir_long == 0 ? key(il,0): key(0,il); word keyB = dir_long == 0 ? key(il,moduleBase().blockNrs[dir_perp] - 1): key(moduleBase().blockNrs[dir_perp] - 1,il); TerrainBlock & blockA = moduleBase().blocks[moduleBase().blockAdr_ij[keyA]]; TerrainBlock & blockB = moduleBase().blocks[moduleBase().blockAdr_ij[keyB]]; Spline & splA = blockA.getSpline(splineA); Spline & splB = blockB.getSpline(splineB); label sPoints = splA.size(); // correct for possibly inverse point order in moduleBase().splines: label signA = 1; label signB = 1; scalar oA = dot(splA.last() - splA.first(),n_long); scalar oB = dot(splB.last() - splB.first(),n_long); if(oA < 0) signA = -1; if(oB < 0) signB = -1; // find average moduleBase().splines and fix them at boundaries: pointField hList_av(sPoints); forAll(hList_av,hI){ // get spline points: label hIA = signA > 0 ? hI : sPoints - 1 - hI; label hIB = signB > 0 ? hI : sPoints - 1 - hI; point & pA = splA[hIA]; point & pB = splB[hIB]; // calc mean: hList_av[hI] = 0.5 * ( pA + pB ); // adjust boundary moduleBase().splines: if(hI == 0){ pA = blockA.getVertex(vListA[0]); pB = blockB.getVertex(vListB[0]); } else if(hI == sPoints - 1){ pA = blockA.getVertex(vListA[1]); pB = blockB.getVertex(vListB[1]); } else { pA += dot(hList_av[hI] - pA,n_up) * n_up; pB += dot(hList_av[hI] - pB,n_up) * n_up; } } hMeanSplines_il[il] = hList_av; }
void TerrainManagerModuleCylinder::initCylinder ( const dictionary & dict ){ // read dictionary: cylinderCentre_ = point(dict.lookup("centrePoint")); cylinderRadius_ = readScalar(dict.lookup("radius")); cylinderRadialBlocks_ = 1;//readLabel(dict.lookup("radialBlocks")); cylinderRadialGrading_ = readScalar(dict.lookup("radialGrading")); cylinderRadialCells_ = readLabel(dict.lookup("radialBlockCells")); cylinderFirstSectionStartDir_ = point(dict.lookup("firstSectionStartDirection")); cylinderSectionNr_ = readLabel(dict.lookup("numberOfSections")); // check consistency: point pCheck = moduleBase().domainBox_.pMin(); scalar dist = mag(pCheck - cylinderCentre_); if(dist > cylinderRadius_){ Info << "\nTerrainManager: Error: cylinder radius smaller than distance from box corner SWL to cylinder centre." << endl; Info << " p_SWL = " << pCheck <<endl; Info << " p_cylinderCentre = " << cylinderCentre_ << endl; Info << " dist = " << dist << endl; Info << " radius = " << cylinderRadius_ << endl; throw; } pCheck = moduleBase().domainBox_.pMin() + moduleBase().domainBox_.lengths()[TerrainManager::BASE1] * moduleBase().coordinateSystem().e(TerrainManager::BASE1); dist = mag(pCheck - cylinderCentre_); if(dist > cylinderRadius_){ Info << "\nTerrainManager: Error: cylinder radius smaller than distance from box corner SEL to cylinder centre." << endl; Info << " p_SEL = " << pCheck <<endl; Info << " p_cylinderCentre = " << cylinderCentre_ << endl; Info << " dist = " << dist << endl; Info << " radius = " << cylinderRadius_ << endl; throw; } pCheck = moduleBase().domainBox_.pMin() + moduleBase().domainBox_.lengths()[TerrainManager::BASE2] * moduleBase().coordinateSystem().e(TerrainManager::BASE2); dist = mag(pCheck - cylinderCentre_); if(dist > cylinderRadius_){ Info << "\nTerrainManager: Error: cylinder radius smaller than distance from box corner NWL to cylinder centre." << endl; Info << " p_NWL = " << pCheck <<endl; Info << " p_cylinderCentre = " << cylinderCentre_ << endl; Info << " dist = " << dist << endl; Info << " radius = " << cylinderRadius_ << endl; throw; } pCheck = moduleBase().domainBox_.pMin() + moduleBase().domainBox_.lengths()[TerrainManager::BASE1] * moduleBase().coordinateSystem().e(TerrainManager::BASE1) + moduleBase().domainBox_.lengths()[TerrainManager::BASE2] * moduleBase().coordinateSystem().e(TerrainManager::BASE2); dist = mag(pCheck - cylinderCentre_); if(dist > cylinderRadius_){ Info << "\nTerrainManager: Error: cylinder radius smaller than distance from box corner NEL to cylinder centre." << endl; Info << " p_NEL = " << pCheck <<endl; Info << " p_cylinderCentre = " << cylinderCentre_ << endl; Info << " dist = " << dist << endl; Info << " radius = " << cylinderRadius_ << endl; throw; } // init blending: blending_ = ScalarBlendingFunction::New(dict.subDict("blendingFunction")); }
forAll(weights[TerrainManager::BASE2],wI){ blockGrading[TerrainManager::BASE2][wI + 1] = moduleBase().domainBox_.lengths()[TerrainManager::BASE2] * weights[TerrainManager::BASE2][wI] / sum[TerrainManager::BASE2]; }