Files
openfoam/integration/genAbs/common/memberFun.H
Andrew Heather 95e9467e84 INT: Integration of functionality produced by The Environmental Hydraulics Institute "IHCantabria" (http://www.ihcantabria.com/en/)
Capabilities include:
- Wave generation
  - Solitary wave using Boussinesq theory
  - Cnoidal wave theory
  - StokesI, StokesII, StokesV wave theory

- Active wave absorption at the inflow/outflow boundaries based on
  shallow water theory

Authors:
- Javier Lopez Lara (jav.lopez@unican.es)
- Gabriel Barajas (barajasg@unican.es)
- Inigo Losada (losadai@unican.es)
2016-11-16 14:02:14 +00:00

356 lines
9.0 KiB
C++

/*---------------------------------------------------------------------------*\
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<vector>& 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<scalar>());
reduce(groupWaterArea[i], sumOp<scalar>());
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<scalar>());
reduce(groupUx[i], sumOp<scalar>());
reduce(groupUy[i], sumOp<scalar>());
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]<dBreakPoints[j+1]) )
{
usedGroup[j] = 1.0;
continue;
}
}
}
reduce(usedGroup, maxOp<scalarList>());
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<scalar>());
reduce(numAngles[i], sumOp<scalar>());
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<scalar>());
reduce(zMinL[i], minOp<scalar>());
}
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;
}