/*---------------------------------------------------------------------------*\ IH-Cantabria 2015 (http://www.ihcantabria.com/en/) IHFOAM 2015 (http://ihfoam.ihcantabria.com/) Author(s): Javier Lopez Lara (jav.lopez@unican.es) Gabriel Barajas (barajasg@unican.es) \*---------------------------------------------------------------------------*/ //- Return Pi scalar PI() { #if OFVERSION >= 200 const scalar PI = constant::mathematical::pi; #else const scalar PI = mathematicalConstant::pi; #endif return PI; } //- Return alphaName word alphaName() { #if OFVERSION >= 230 const word an = "alpha.water"; #else const word an = "alpha1"; #endif return an; } //- Return prevalent direction - X or Y to sort groups of columns scalarField patchDirection ( vector span, scalar* dMin, scalar* dSpan ) { const pointField& points = patch().patch().localPoints(); if (span[0] >= span[1]) { *dMin = gMin(points.component(0)); *dSpan = gMax(points.component(0)) - *dMin; return patch().Cf().component(0); } else { *dMin = gMin(points.component(1)); *dSpan = gMax(points.component(1)) - *dMin; return patch().Cf().component(1); } } //- Return Zmax and Zmin of the patch faces void faceBoundsZ(scalarField* zSup, scalarField* zInf) { const label nF = patch().faceCells().size(); scalarField zMax = Foam::scalarField(nF, -9999.0); scalarField zMin = Foam::scalarField(nF, 9999.0); const faceList& faces = this->patch().patch().localFaces(); const List& points = this->patch().patch().localPoints(); forAll( faces, faceI ) { const face& f = faces[faceI]; forAll(f, point) { scalar auxiliar = points[f[point]].component(2); zMax[faceI] = max(zMax[faceI], auxiliar); zMin[faceI] = min(zMin[faceI], auxiliar); } } *zSup = zMax; *zInf = zMin; } //- Calculate water levels on each paddle (same zSpan) scalarList calcWL ( scalarField alphaCell, labelList cellGroup, scalar zSpan ) { scalarList groupTotalArea (nPaddles_,0.0); scalarList groupWaterArea (nPaddles_,0.0); scalarList heights (nPaddles_,0.0); const scalarField faceSurface = patch().magSf(); forAll( patch().faceCells(), index ) { groupTotalArea[cellGroup[index]-1] += faceSurface[index]; groupWaterArea[cellGroup[index]-1] += faceSurface[index]*alphaCell[index]; } for (label i=0; i<=gMax(cellGroup)-1; i++) { reduce(groupTotalArea[i], sumOp()); reduce(groupWaterArea[i], sumOp()); heights[i] = groupWaterArea[i]/groupTotalArea[i]*zSpan; } return heights; } //- Calculate mean velocities on each paddle void calcUV ( scalarField alphaCell, labelList cellGroup, scalarField UxCell, scalarList* Ux, scalarField UyCell, scalarList* Uy ) { scalarList groupWaterArea (nPaddles_,0.0); scalarList groupUx (nPaddles_,0.0); scalarList groupUy (nPaddles_,0.0); const scalarField faceSurface = patch().magSf(); forAll( patch().faceCells(), index ) { groupWaterArea[cellGroup[index]-1] += faceSurface[index]*alphaCell[index]; groupUx[cellGroup[index]-1] += UxCell[index]*alphaCell[index]*faceSurface[index]; groupUy[cellGroup[index]-1] += UyCell[index]*alphaCell[index]*faceSurface[index]; } for (label i=0; i<=nPaddles_-1; i++) { reduce(groupWaterArea[i], sumOp()); reduce(groupUx[i], sumOp()); reduce(groupUy[i], sumOp()); groupUx[i] = groupUx[i]/groupWaterArea[i]; groupUy[i] = groupUy[i]/groupWaterArea[i]; } *Ux = groupUx; *Uy = groupUy; } //- Mean of a scalarList scalar meanSL ( scalarList lst ) { scalar aux = 0.0; forAll(lst,i) { aux += lst[i]; } return aux/scalar(lst.size()); } //- Reduce number of paddles if too high (paddles without cells) label decreaseNPaddles ( label np, scalarField patchD, scalar dMin, scalar dSpan ) { scalarList dBreakPoints(np+1, 0.0); while(1) { scalarList usedGroup (np,0.0); for (label i=0; i<=np; i++) { dBreakPoints[i] = dMin + dSpan/(np)*i; } forAll(patch().faceCells(), patchCells) { for (label j=0; j<=np; j++) { if ( (patchD[patchCells]>=dBreakPoints[j]) && (patchD[patchCells]()); if ( gMin(usedGroup) < 0.5 ) { Info << "Reduced nPaddles from " << np << " to " << np-1 << endl; np -= 1; } else { break; } } return np; } //- Own convenient definition of atan scalar arcTan ( scalar x, scalar y ) { scalar A = 0.0; if( x > 0.0 ) { A = atan(y/x); } else if ( y >= 0.0 && x < 0.0 ) { A = PI() + atan(y/x); } else if ( y < 0.0 && x < 0.0 ) { A = -PI() + atan(y/x); } else if ( y > 0.0 && x == 0.0 ) { A = PI()/2.0; } else if ( y < 0.0 && x == 0.0 ) { A = -PI()/2.0; } else if ( y == 0.0 && x == 0.0 ) { A = 0; } return A; } //- Calculate mean horizontal angle for each paddle scalarList meanPatchDirs ( labelList cellGroup ) { const vectorField nVecCell = patch().nf(); scalarList numAngles (nPaddles_, 0.0); scalarList meanAngle (nPaddles_, 0.0); forAll(patch().faceCells(), patchCells) { meanAngle[cellGroup[patchCells]-1] += arcTan( nVecCell[patchCells].component(0), nVecCell[patchCells].component(1)); numAngles[cellGroup[patchCells]-1] += 1.0; } for (label i=0; i<=nPaddles_-1; i++) { reduce(meanAngle[i], sumOp()); reduce(numAngles[i], sumOp()); meanAngle[i] = meanAngle[i]/numAngles[i] + PI(); } return meanAngle; } //- Calculate z-bounds for each paddle scalarList zSpanList ( labelList cellGroup, scalarField zInf, scalarField zSup ) { scalarList zMaxL (nPaddles_, -9999.0); scalarList zMinL (nPaddles_, 9999.0); forAll(patch().faceCells(), patchCells) { zMaxL[cellGroup[patchCells]-1] = max(zMaxL[cellGroup[patchCells]-1], zSup[patchCells] ); zMinL[cellGroup[patchCells]-1] = min(zMinL[cellGroup[patchCells]-1], zInf[patchCells] ); } for (label i=0; i<=nPaddles_-1; i++) { reduce(zMaxL[i], maxOp()); reduce(zMinL[i], minOp()); } return zMaxL-zMinL; } //- In-line print for scalarLists label inlinePrint ( std::string name, scalarList SL ) { Info << name << " " << SL.size() << "( "; forAll(SL, i) { Info << SL[i] << " "; } Info << ")\n" << endl; return 0; } //- Simple linear interpolation scalar interpolation ( scalar x1, scalar x2, scalar y1, scalar y2, scalar xInt ) { scalar yInt = y1 + (y2-y1)/(x2-x1)*(xInt-x1); return yInt; } //- Limit angle between -pi/2 and pi/2 scalar limAngle (scalar ang) { ang = abs(ang); while (ang >= 2.0*PI()) { ang -= 2.0*PI(); } if ( ang >= PI()/2.0 && ang <= 3.0*PI()/2.0 ) { return PI()/2.0; } else { return ang; } } //- Interpolation BO style scalar interpolatte ( scalar x1, scalar x2, scalar y1, scalar y2, scalar xInt ) { scalar yInt = (y1 + y2)*0.5; return yInt; }