Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Private Attributes | Friends | List of all members
Nektar::SolverUtils::FilterAeroForces Class Reference

#include <FilterAeroForces.h>

Inheritance diagram for Nektar::SolverUtils::FilterAeroForces:
Inheritance graph
[legend]
Collaboration diagram for Nektar::SolverUtils::FilterAeroForces:
Collaboration graph
[legend]

Public Member Functions

SOLVER_UTILS_EXPORT FilterAeroForces (const LibUtilities::SessionReaderSharedPtr &pSession, const std::map< std::string, std::string > &pParams)
SOLVER_UTILS_EXPORT ~FilterAeroForces ()
- Public Member Functions inherited from Nektar::SolverUtils::Filter
SOLVER_UTILS_EXPORT Filter (const LibUtilities::SessionReaderSharedPtr &pSession)
virtual SOLVER_UTILS_EXPORT ~Filter ()
SOLVER_UTILS_EXPORT void Initialise (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
SOLVER_UTILS_EXPORT void Update (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
SOLVER_UTILS_EXPORT void Finalise (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
SOLVER_UTILS_EXPORT bool IsTimeDependent ()

Static Public Member Functions

static FilterSharedPtr create (const LibUtilities::SessionReaderSharedPtr &pSession, const std::map< std::string, std::string > &pParams)
 Creates an instance of this class.

Static Public Attributes

static std::string className = GetFilterFactory().RegisterCreatorFunction("AeroForces", FilterAeroForces::create)
 Name of the class.

Protected Member Functions

virtual void v_Initialise (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
virtual void v_Update (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
virtual void v_Finalise (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
virtual bool v_IsTimeDependent ()

Private Attributes

vector< unsigned int > m_boundaryRegionsIdList
 ID's of boundary regions where we want the forces.
vector< bool > m_boundaryRegionIsInList
 Determines if a given Boundary Region is in m_boundaryRegionsIdList.
unsigned int m_index
unsigned int m_outputFrequency
unsigned int m_outputPlane
 plane to take history point from if using a homogeneous1D expansion
bool m_isHomogeneous1D
std::string m_outputFile
std::ofstream m_outputStream
LibUtilities::BasisSharedPtr m_homogeneousBasis
std::string m_BoundaryString
int m_nplanes
 number of planes for homogeneous1D expansion

Friends

class MemoryManager< FilterAeroForces >

Additional Inherited Members

- Protected Attributes inherited from Nektar::SolverUtils::Filter
LibUtilities::SessionReaderSharedPtr m_session

Detailed Description

Definition at line 46 of file FilterAeroForces.h.

Constructor & Destructor Documentation

Nektar::SolverUtils::FilterAeroForces::FilterAeroForces ( const LibUtilities::SessionReaderSharedPtr pSession,
const std::map< std::string, std::string > &  pParams 
)

Definition at line 52 of file FilterAeroForces.cpp.

References ASSERTL0, m_BoundaryString, m_isHomogeneous1D, m_outputFile, m_outputFrequency, m_outputPlane, and Nektar::SolverUtils::Filter::m_session.

:
Filter(pSession)
{
if (pParams.find("OutputFile") == pParams.end())
{
m_outputFile = m_session->GetSessionName();
}
else
{
ASSERTL0(!(pParams.find("OutputFile")->second.empty()),
"Missing parameter 'OutputFile'.");
m_outputFile = pParams.find("OutputFile")->second;
}
if (!(m_outputFile.length() >= 4
&& m_outputFile.substr(m_outputFile.length() - 4) == ".fce"))
{
m_outputFile += ".fce";
}
if (pParams.find("OutputFrequency") == pParams.end())
{
}
else
{
atoi(pParams.find("OutputFrequency")->second.c_str());
}
m_session->MatchSolverInfo("Homogeneous", "1D",
{
if (pParams.find("OutputPlane") == pParams.end())
{
}
else
{
atoi(pParams.find("OutputPlane")->second.c_str());
}
}
//specify the boundary to calculate the forces
if (pParams.find("Boundary") == pParams.end())
{
ASSERTL0(false, "Missing parameter 'Boundary'.");
}
else
{
ASSERTL0(!(pParams.find("Boundary")->second.empty()),
"Missing parameter 'Boundary'.");
m_BoundaryString = pParams.find("Boundary")->second;
}
}
Nektar::SolverUtils::FilterAeroForces::~FilterAeroForces ( )

Definition at line 117 of file FilterAeroForces.cpp.

{
}

Member Function Documentation

static FilterSharedPtr Nektar::SolverUtils::FilterAeroForces::create ( const LibUtilities::SessionReaderSharedPtr pSession,
const std::map< std::string, std::string > &  pParams 
)
inlinestatic

Creates an instance of this class.

Definition at line 52 of file FilterAeroForces.h.

{
AllocateSharedPtr(pSession, pParams);
//p->InitObject();
return p;
}
void Nektar::SolverUtils::FilterAeroForces::v_Finalise ( const Array< OneD, const MultiRegions::ExpListSharedPtr > &  pFields,
const NekDouble time 
)
protectedvirtual

Implements Nektar::SolverUtils::Filter.

Definition at line 791 of file FilterAeroForces.cpp.

References m_outputStream.

{
if (pFields[0]->GetComm()->GetRank() == 0)
{
m_outputStream.close();
}
}
void Nektar::SolverUtils::FilterAeroForces::v_Initialise ( const Array< OneD, const MultiRegions::ExpListSharedPtr > &  pFields,
const NekDouble time 
)
protectedvirtual

Implements Nektar::SolverUtils::Filter.

Definition at line 126 of file FilterAeroForces.cpp.

References ASSERTL0, Nektar::StdRegions::find(), Nektar::ParseUtils::GenerateSeqVector(), Nektar::SpatialDomains::BoundaryConditions::GetBoundaryRegions(), m_boundaryRegionIsInList, m_boundaryRegionsIdList, m_BoundaryString, m_outputFile, m_outputStream, Nektar::SolverUtils::Filter::m_session, and v_Update().

{
// Parse the boundary regions into a list.
std::string::size_type FirstInd =
m_BoundaryString.find_first_of('[') + 1;
std::string::size_type LastInd =
m_BoundaryString.find_last_of(']') - 1;
ASSERTL0(FirstInd <= LastInd,
(std::string("Error reading boundary region definition:") +
m_BoundaryString).c_str());
std::string IndString =
m_BoundaryString.substr(FirstInd, LastInd - FirstInd + 1);
bool parseGood = ParseUtils::GenerateSeqVector(IndString.c_str(),
ASSERTL0(parseGood && !m_boundaryRegionsIdList.empty(),
(std::string("Unable to read boundary regions index "
"range for FilterAeroForces: ") + IndString).c_str());
// determine what boundary regions need to be considered
int cnt;
unsigned int numBoundaryRegions =
pFields[0]->GetBndConditions().num_elements();
numBoundaryRegions, 0);
pFields[0]->GetGraph());
bcs.GetBoundaryRegions();
SpatialDomains::BoundaryRegionCollection::const_iterator it;
for (cnt = 0, it = bregions.begin(); it != bregions.end();
++it, cnt++)
{
m_boundaryRegionsIdList.end(), it->first) !=
{
}
}
LibUtilities::CommSharedPtr vComm = pFields[0]->GetComm();
if (vComm->GetRank() == 0)
{
// Open output stream
m_outputStream.width(7);
m_outputStream << "Time";
m_outputStream.width(25);
m_outputStream << "Fx (press)";
m_outputStream.width(25);
m_outputStream << "Fx (visc)";
m_outputStream.width(25);
m_outputStream << "Fx (tot)";
m_outputStream.width(25);
m_outputStream << "Fy (press)";
m_outputStream.width(25);
m_outputStream << "Fy (visc)";
m_outputStream.width(25);
m_outputStream << "Fy (tot)";
m_outputStream.width(25);
m_outputStream << "Fz (press)";
m_outputStream.width(25);
m_outputStream << "Fz (visc)";
m_outputStream.width(25);
m_outputStream << "Fz (tot)";
m_outputStream << endl;
}
v_Update(pFields, time);
}
bool Nektar::SolverUtils::FilterAeroForces::v_IsTimeDependent ( )
protectedvirtual

Implements Nektar::SolverUtils::Filter.

Definition at line 805 of file FilterAeroForces.cpp.

{
return true;
}
void Nektar::SolverUtils::FilterAeroForces::v_Update ( const Array< OneD, const MultiRegions::ExpListSharedPtr > &  pFields,
const NekDouble time 
)
protectedvirtual

Implements Nektar::SolverUtils::Filter.

Definition at line 209 of file FilterAeroForces.cpp.

References Nektar::StdRegions::StdExpansion::GetTotPoints(), m_boundaryRegionIsInList, m_index, m_isHomogeneous1D, m_outputFrequency, m_outputStream, Nektar::SolverUtils::Filter::m_session, Vmath::Neg(), Nektar::LibUtilities::ReduceSum, Vmath::Smul(), Vmath::Vadd(), Vmath::Vmul(), Vmath::Vvtvp(), and Vmath::Zero().

Referenced by v_Initialise().

{
// Only output every m_outputFrequency.
{
return;
}
int n, cnt, elmtid, nq, offset, nt, boundary;
nt = pFields[0]->GetNpoints();
int dim = pFields.num_elements()-1;
Array<OneD, int> BoundarytoElmtID;
Array<OneD, int> BoundarytoTraceID;
Array<OneD, MultiRegions::ExpListSharedPtr> BndExp;
Array<OneD, const NekDouble> P(nt);
Array<OneD, const NekDouble> U(nt);
Array<OneD, const NekDouble> V(nt);
Array<OneD, const NekDouble> W(nt);
Array<OneD, Array<OneD, NekDouble> > gradU(dim);
Array<OneD, Array<OneD, NekDouble> > gradV(dim);
Array<OneD, Array<OneD, NekDouble> > gradW(dim);
Array<OneD, Array<OneD, NekDouble> > fgradU(dim);
Array<OneD, Array<OneD, NekDouble> > fgradV(dim);
Array<OneD, Array<OneD, NekDouble> > fgradW(dim);
Array<OneD, NekDouble> values;
LibUtilities::CommSharedPtr vComm = pFields[0]->GetComm();
NekDouble Fx,Fy,Fz,Fxp,Fxv,Fyp,Fyv,Fzp,Fzv;
Fxp = 0.0; // x-component of the force due to pressure difference
Fxv = 0.0; // x-component of the force due to viscous stress
Fx = 0.0; // x-component of the force (total) Fx = Fxp + Fxv (Drag)
Fyp = 0.0; // y-component of the force due to pressure difference
Fyv = 0.0; // y-component of the force due to viscous stress
Fy = 0.0; // y-component of the force (total) Fy = Fyp + Fyv (Lift)
Fzp = 0.0; // z-component of the force due to pressure difference
Fzv = 0.0; // z-component of the force due to viscous stress
Fz = 0.0; // z-component of the force (total) Fz = Fzp + Fzv (Side)
NekDouble rho = (m_session->DefinesParameter("rho"))
? (m_session->GetParameter("rho"))
: 1;
NekDouble mu = rho*m_session->GetParameter("Kinvis");
for(int i = 0; i < pFields.num_elements(); ++i)
{
pFields[i]->SetWaveSpace(false);
pFields[i]->BwdTrans(pFields[i]->GetCoeffs(),
pFields[i]->UpdatePhys());
pFields[i]->SetPhysState(true);
}
// Homogeneous 1D case Compute forces on all WALL boundaries
// This only has to be done on the zero (mean) Fourier mode.
{
if(vComm->GetColumnComm()->GetRank() == 0)
{
pFields[0]->GetPlane(0)->GetBoundaryToElmtMap(
BoundarytoElmtID,BoundarytoTraceID);
BndExp = pFields[0]->GetPlane(0)->GetBndCondExpansions();
// loop over the types of boundary conditions
for(cnt = n = 0; n < BndExp.num_elements(); ++n)
{
{
for(int i = 0; i < BndExp[n]->GetExpSize();
++i, cnt++)
{
// find element of this expansion.
elmtid = BoundarytoElmtID[cnt];
elmt = pFields[0]->GetPlane(0)->GetExp(elmtid);
nq = elmt->GetTotPoints();
offset = pFields[0]->GetPlane(0)->GetPhys_Offset(elmtid);
// Initialise local arrays for the velocity
// gradients size of total number of quadrature
// points for each element (hence local).
for(int j = 0; j < dim; ++j)
{
gradU[j] = Array<OneD, NekDouble>(nq,0.0);
gradV[j] = Array<OneD, NekDouble>(nq,0.0);
gradW[j] = Array<OneD, NekDouble>(nq,0.0);
}
// identify boundary of element
boundary = BoundarytoTraceID[cnt];
// Extract fields
U = pFields[0]->GetPlane(0)->GetPhys() + offset;
V = pFields[1]->GetPlane(0)->GetPhys() + offset;
P = pFields[3]->GetPlane(0)->GetPhys() + offset;
// compute the gradients
elmt->PhysDeriv(U,gradU[0],gradU[1]);
elmt->PhysDeriv(V,gradV[0],gradV[1]);
// Get face 1D expansion from element expansion
bc = BndExp[n]->GetExp(i)
// number of points on the boundary
int nbc = bc->GetTotPoints();
// several vectors for computing the forces
Array<OneD, NekDouble> Pb(nbc,0.0);
for(int j = 0; j < dim; ++j)
{
fgradU[j] = Array<OneD, NekDouble>(nbc,0.0);
fgradV[j] = Array<OneD, NekDouble>(nbc,0.0);
}
Array<OneD, NekDouble> drag_t(nbc,0.0);
Array<OneD, NekDouble> lift_t(nbc,0.0);
Array<OneD, NekDouble> drag_p(nbc,0.0);
Array<OneD, NekDouble> lift_p(nbc,0.0);
Array<OneD, NekDouble> temp(nbc,0.0);
Array<OneD, NekDouble> temp2(nbc,0.0);
// identify boundary of element .
boundary = BoundarytoTraceID[cnt];
// extraction of the pressure and wss on the
// boundary of the element
elmt->GetEdgePhysVals(boundary,bc,P,Pb);
for(int j = 0; j < dim; ++j)
{
elmt->GetEdgePhysVals(boundary,bc,gradU[j],
fgradU[j]);
elmt->GetEdgePhysVals(boundary,bc,gradV[j],
fgradV[j]);
}
//normals of the element
const Array<OneD, Array<OneD, NekDouble> > &normals
= elmt->GetEdgeNormal(boundary);
//
// Compute viscous tractive forces on wall from
//
// t_i = - T_ij * n_j (minus sign for force
// exerted BY fluid ON wall),
//
// where
//
// T_ij = viscous stress tensor (here in Cartesian
// coords)
// dU_i dU_j
// = RHO * KINVIS * ( ---- + ---- ) .
// dx_j dx_i
//a) DRAG TERMS
//-rho*kinvis*(2*du/dx*nx+(du/dy+dv/dx)*ny
Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,drag_t,1);
Vmath::Vmul(nbc,drag_t,1,normals[1],1,drag_t,1);
Vmath::Smul(nbc,2.0,fgradU[0],1,fgradU[0],1);
Vmath::Vmul(nbc,fgradU[0],1,normals[0],1,temp2,1);
Vmath::Smul(nbc,0.5,fgradU[0],1,fgradU[0],1);
Vmath::Vadd(nbc,temp2,1,drag_t,1,drag_t,1);
Vmath::Smul(nbc,-mu,drag_t,1,drag_t,1);
//zero temporary storage vector
Vmath::Zero(nbc,temp,0);
Vmath::Zero(nbc,temp2,0);
//b) LIFT TERMS
//-rho*kinvis*(2*dv/dy*nx+(du/dy+dv/dx)*nx
Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,lift_t,1);
Vmath::Vmul(nbc,lift_t,1,normals[0],1,lift_t,1);
Vmath::Smul(nbc,2.0,fgradV[1],1,fgradV[1],1);
Vmath::Vmul(nbc,fgradV[1],1,normals[1],1,temp2,1);
Vmath::Smul(nbc,-0.5,fgradV[1],1,fgradV[1],1);
Vmath::Vadd(nbc,temp2,1,lift_t,1,lift_t,1);
Vmath::Smul(nbc,-mu,lift_t,1,lift_t,1);
// Compute normal tractive forces on all WALL
// boundaries
Vmath::Vvtvp(nbc,Pb,1,normals[0],1,
drag_p,1,drag_p, 1);
Vmath::Vvtvp(nbc,Pb,1,normals[1],1,
lift_p,1,lift_p,1);
//integration over the boundary
Fxv += bc->Integral(drag_t);
Fyv += bc->Integral(lift_t);
Fxp += bc->Integral(drag_p);
Fyp += bc->Integral(lift_p);
}
}
else
{
cnt += BndExp[n]->GetExpSize();
}
}
}
for(int i = 0; i < pFields.num_elements(); ++i)
{
pFields[i]->SetWaveSpace(true);
pFields[i]->BwdTrans(pFields[i]->GetCoeffs(),
pFields[i]->UpdatePhys());
pFields[i]->SetPhysState(false);
}
}
//3D WALL case
else if(dim==3 && !m_isHomogeneous1D)
{
pFields[0]->GetBoundaryToElmtMap(BoundarytoElmtID,
BoundarytoTraceID);
BndExp = pFields[0]->GetBndCondExpansions();
// loop over the types of boundary conditions
for(cnt = n = 0; n < BndExp.num_elements(); ++n)
{
{
for(int i = 0; i < BndExp[n]->GetExpSize(); ++i, cnt++)
{
// find element of this expansion.
elmtid = BoundarytoElmtID[cnt];
elmt = pFields[0]->GetExp(elmtid);
nq = elmt->GetTotPoints();
offset = pFields[0]->GetPhys_Offset(elmtid);
// Initialise local arrays for the velocity
// gradients size of total number of quadrature
// points for each element (hence local).
for(int j = 0; j < dim; ++j)
{
gradU[j] = Array<OneD, NekDouble>(nq,0.0);
gradV[j] = Array<OneD, NekDouble>(nq,0.0);
gradW[j] = Array<OneD, NekDouble>(nq,0.0);
}
//identify boundary of element
boundary = BoundarytoTraceID[cnt];
//Extract fields
U = pFields[0]->GetPhys() + offset;
V = pFields[1]->GetPhys() + offset;
W = pFields[2]->GetPhys() + offset;
P = pFields[3]->GetPhys() + offset;
//compute the gradients
elmt->PhysDeriv(U,gradU[0],gradU[1],gradU[2]);
elmt->PhysDeriv(V,gradV[0],gradV[1],gradV[2]);
elmt->PhysDeriv(W,gradW[0],gradW[1],gradW[2]);
// Get face 2D expansion from element expansion
bc = BndExp[n]->GetExp(i)
//number of points on the boundary
int nbc = bc->GetTotPoints();
//several vectors for computing the forces
Array<OneD, NekDouble> Pb(nbc,0.0);
for(int j = 0; j < dim; ++j)
{
fgradU[j] = Array<OneD, NekDouble>(nbc,0.0);
fgradV[j] = Array<OneD, NekDouble>(nbc,0.0);
fgradW[j] = Array<OneD, NekDouble>(nbc,0.0);
}
Array<OneD, NekDouble> drag_t(nbc,0.0);
Array<OneD, NekDouble> lift_t(nbc,0.0);
Array<OneD, NekDouble> side_t(nbc,0.0);
Array<OneD, NekDouble> drag_p(nbc,0.0);
Array<OneD, NekDouble> lift_p(nbc,0.0);
Array<OneD, NekDouble> side_p(nbc,0.0);
Array<OneD, NekDouble> temp(nbc,0.0);
Array<OneD, NekDouble> temp2(nbc,0.0);
// identify boundary of element .
boundary = BoundarytoTraceID[cnt];
// extraction of the pressure and wss on the
// boundary of the element
elmt->GetFacePhysVals(boundary,bc,P,Pb);
for(int j = 0; j < dim; ++j)
{
elmt->GetFacePhysVals(boundary,bc,gradU[j],
fgradU[j]);
elmt->GetFacePhysVals(boundary,bc,gradV[j],
fgradV[j]);
elmt->GetFacePhysVals(boundary,bc,gradW[j],
fgradW[j]);
}
// normals of the element
const Array<OneD, Array<OneD, NekDouble> > &normals
= elmt->GetFaceNormal(boundary);
//
// Compute viscous tractive forces on wall from
//
// t_i = - T_ij * n_j (minus sign for force
// exerted BY fluid ON wall),
//
// where
//
// T_ij = viscous stress tensor (here in Cartesian
// coords)
// dU_i dU_j
// = RHO * KINVIS * ( ---- + ---- ) .
// dx_j dx_i
//a) DRAG TERMS
//-rho*kinvis*
// (2*du/dx*nx+(du/dy+dv/dx)*ny+(du/dz+dw/dx)*nz)
Vmath::Vadd(nbc,fgradU[2],1,fgradW[0],1,temp,1);
Vmath::Neg(nbc,temp,1);
Vmath::Vmul(nbc,temp,1,normals[2],1,temp,1);
Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,drag_t,1);
Vmath::Neg(nbc,drag_t,1);
Vmath::Vmul(nbc,drag_t,1,normals[1],1,drag_t,1);
Vmath::Smul(nbc,-2.0,fgradU[0],1,fgradU[0],1);
Vmath::Vmul(nbc,fgradU[0],1,normals[0],1,temp2,1);
Vmath::Smul(nbc,-0.5,fgradU[0],1,fgradU[0],1);
Vmath::Vadd(nbc,temp,1,temp2,1,temp,1);
Vmath::Vadd(nbc,temp,1,drag_t,1,drag_t,1);
Vmath::Smul(nbc,mu,drag_t,1,drag_t,1);
//zero temporary storage vector
Vmath::Zero(nbc,temp,0);
Vmath::Zero(nbc,temp2,0);
//b) LIFT TERMS
//-rho*kinvis*
// (2*dv/dy*nx+(du/dy+dv/dx)*nx+(dv/dz+dw/dy)*nz)
Vmath::Vadd(nbc,fgradV[2],1,fgradW[1],1,temp,1);
Vmath::Neg(nbc,temp,1);
Vmath::Vmul(nbc,temp,1,normals[2],1,temp,1);
Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,lift_t,1);
Vmath::Neg(nbc,lift_t,1);
Vmath::Vmul(nbc,lift_t,1,normals[0],1,lift_t,1);
Vmath::Smul(nbc,-2.0,fgradV[1],1,fgradV[1],1);
Vmath::Vmul(nbc,fgradV[1],1,normals[1],1,temp2,1);
Vmath::Smul(nbc,-0.5,fgradV[1],1,fgradV[1],1);
Vmath::Vadd(nbc,temp,1,temp2,1,temp,1);
Vmath::Vadd(nbc,temp,1,lift_t,1,lift_t,1);
Vmath::Smul(nbc,mu,lift_t,1,lift_t,1);
//zero temporary storage vector
Vmath::Zero(nbc,temp,0);
Vmath::Zero(nbc,temp2,0);
//b) SIDE TERMS
//-rho*kinvis*
// (2*dv/dy*nx+(du/dy+dv/dx)*nx+(dv/dz+dw/dy)*nz)
Vmath::Vadd(nbc,fgradV[2],1,fgradW[1],1,temp,1);
Vmath::Neg(nbc,temp,1);
Vmath::Vmul(nbc,temp,1,normals[1],1,temp,1);
Vmath::Vadd(nbc,fgradU[2],1,fgradW[0],1,side_t,1);
Vmath::Neg(nbc,side_t,1);
Vmath::Vmul(nbc,side_t,1,normals[0],1,side_t,1);
Vmath::Smul(nbc,-2.0,fgradW[2],1,fgradW[2],1);
Vmath::Vmul(nbc,fgradW[2],1,normals[2],1,temp2,1);
Vmath::Smul(nbc,-0.5,fgradW[2],1,fgradW[2],1);
Vmath::Vadd(nbc,temp,1,temp2,1,temp,1);
Vmath::Vadd(nbc,temp,1,side_t,1,side_t,1);
Vmath::Smul(nbc,mu,side_t,1,side_t,1);
// Compute normal tractive forces on all WALL
// boundaries
Vmath::Vvtvp(nbc,Pb,1,normals[0],1,
drag_p,1,drag_p,1);
Vmath::Vvtvp(nbc,Pb,1,normals[1],1,
lift_p,1,lift_p,1);
Vmath::Vvtvp(nbc,Pb,1,normals[2],1,
side_p,1,side_p,1);
//integration over the boundary
Fxv += bc->Expansion::Integral(drag_t);
Fyv += bc->Expansion::Integral(lift_t);
Fzv += bc->Expansion::Integral(side_t);
Fxp += bc->Expansion::Integral(drag_p);
Fyp += bc->Expansion::Integral(lift_p);
Fzp += bc->Expansion::Integral(side_p);
}
}
else
{
cnt += BndExp[n]->GetExpSize();
}
}
}
//2D WALL Condition
else
{
pFields[0]->GetBoundaryToElmtMap(BoundarytoElmtID,
BoundarytoTraceID);
BndExp = pFields[0]->GetBndCondExpansions();
// loop over the types of boundary conditions
for(cnt = n = 0; n < BndExp.num_elements(); ++n)
{
{
for(int i = 0; i < BndExp[n]->GetExpSize(); ++i, cnt++)
{
elmtid = BoundarytoElmtID[cnt];
elmt = pFields[0]->GetExp(elmtid);
nq = elmt->GetTotPoints();
offset = pFields[0]->GetPhys_Offset(elmtid);
for(int j = 0; j < dim; ++j)
{
gradU[j] = Array<OneD, NekDouble>(nq,0.0);
gradV[j] = Array<OneD, NekDouble>(nq,0.0);
}
boundary = BoundarytoTraceID[cnt];
U = pFields[0]->GetPhys() + offset;
V = pFields[1]->GetPhys() + offset;
P = pFields[2]->GetPhys() + offset;
elmt->PhysDeriv(U,gradU[0],gradU[1]);
elmt->PhysDeriv(V,gradV[0],gradV[1]);
bc = BndExp[n]->GetExp(i)
int nbc = bc->GetTotPoints();
Array<OneD, NekDouble> Pb(nbc,0.0);
Array<OneD, NekDouble> drag_t(nbc,0.0);
Array<OneD, NekDouble> lift_t(nbc,0.0);
Array<OneD, NekDouble> drag_p(nbc,0.0);
Array<OneD, NekDouble> lift_p(nbc,0.0);
Array<OneD, NekDouble> temp(nbc,0.0);
boundary = BoundarytoTraceID[cnt];
elmt->GetEdgePhysVals(boundary,bc,P,Pb);
for(int j = 0; j < dim; ++j)
{
fgradU[j] = Array<OneD, NekDouble>(nbc,0.0);
fgradV[j] = Array<OneD, NekDouble>(nbc,0.0);
}
for(int j = 0; j < dim; ++j)
{
elmt->GetEdgePhysVals(boundary,bc,gradU[j],
fgradU[j]);
elmt->GetEdgePhysVals(boundary,bc,gradV[j],
fgradV[j]);
}
const Array<OneD, Array<OneD, NekDouble> > &normals
= elmt->GetEdgeNormal(boundary);
Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,drag_t,1);
Vmath::Neg(nbc,drag_t,1);
Vmath::Vmul(nbc,drag_t,1,normals[1],1,drag_t,1);
Vmath::Smul(nbc,-2.0,fgradU[0],1,fgradU[0],1);
Vmath::Vmul(nbc,fgradU[0],1,normals[0],1,temp,1);
Vmath::Vadd(nbc,temp,1,drag_t,1,drag_t,1);
Vmath::Smul(nbc,mu,drag_t,1,drag_t,1);
Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,lift_t,1);
Vmath::Neg(nbc,lift_t,1);
Vmath::Vmul(nbc,lift_t,1,normals[0],1,lift_t,1);
Vmath::Smul(nbc,-2.0,fgradV[1],1,fgradV[1],1);
Vmath::Vmul(nbc,fgradV[1],1,normals[1],1,temp,1);
Vmath::Vadd(nbc,temp,1,lift_t,1,lift_t,1);
Vmath::Smul(nbc,mu,lift_t,1,lift_t,1);
Vmath::Vvtvp(nbc,Pb,1,normals[0],1,
drag_p,1,drag_p,1);
Vmath::Vvtvp(nbc,Pb,1,normals[1],1,
lift_p,1,lift_p,1);
Fxp += bc->Integral(drag_p);
Fyp += bc->Integral(lift_p);
Fxv += bc->Integral(drag_t);
Fyv += bc->Integral(lift_t);
}
}
else
{
cnt += BndExp[n]->GetExpSize();
}
}
}
vComm->AllReduce(Fxp, LibUtilities::ReduceSum);
vComm->AllReduce(Fxv, LibUtilities::ReduceSum);
Fx = Fxp + Fxv;
vComm->AllReduce(Fyp, LibUtilities::ReduceSum);
vComm->AllReduce(Fyv, LibUtilities::ReduceSum);
Fy = Fyp + Fyv;
vComm->AllReduce(Fzp, LibUtilities::ReduceSum);
vComm->AllReduce(Fzv, LibUtilities::ReduceSum);
Fz = Fzp + Fzv;
if (vComm->GetRank() == 0)
{
m_outputStream.width(8);
m_outputStream << setprecision(6) << time;
m_outputStream.width(25);
m_outputStream << setprecision(8) << Fxp;
m_outputStream.width(25);
m_outputStream << setprecision(8) << Fxv;
m_outputStream.width(25);
m_outputStream << setprecision(8) << Fx;
m_outputStream.width(25);
m_outputStream << setprecision(8) << Fyp;
m_outputStream.width(25);
m_outputStream << setprecision(8) << Fyv;
m_outputStream.width(25);
m_outputStream << setprecision(8) << Fy;
m_outputStream.width(25);
m_outputStream << setprecision(8) << Fzp;
m_outputStream.width(25);
m_outputStream << setprecision(8) << Fzv;
m_outputStream.width(25);
m_outputStream << setprecision(8) << Fz;
m_outputStream << endl;
}
}

Friends And Related Function Documentation

friend class MemoryManager< FilterAeroForces >
friend

Definition at line 49 of file FilterAeroForces.h.

Member Data Documentation

std::string Nektar::SolverUtils::FilterAeroForces::className = GetFilterFactory().RegisterCreatorFunction("AeroForces", FilterAeroForces::create)
static

Name of the class.

Definition at line 63 of file FilterAeroForces.h.

vector<bool> Nektar::SolverUtils::FilterAeroForces::m_boundaryRegionIsInList
private

Determines if a given Boundary Region is in m_boundaryRegionsIdList.

Definition at line 81 of file FilterAeroForces.h.

Referenced by v_Initialise(), and v_Update().

vector<unsigned int> Nektar::SolverUtils::FilterAeroForces::m_boundaryRegionsIdList
private

ID's of boundary regions where we want the forces.

Definition at line 78 of file FilterAeroForces.h.

Referenced by v_Initialise().

std::string Nektar::SolverUtils::FilterAeroForces::m_BoundaryString
private

Definition at line 91 of file FilterAeroForces.h.

Referenced by FilterAeroForces(), and v_Initialise().

LibUtilities::BasisSharedPtr Nektar::SolverUtils::FilterAeroForces::m_homogeneousBasis
private

Definition at line 90 of file FilterAeroForces.h.

unsigned int Nektar::SolverUtils::FilterAeroForces::m_index
private

Definition at line 82 of file FilterAeroForces.h.

Referenced by v_Update().

bool Nektar::SolverUtils::FilterAeroForces::m_isHomogeneous1D
private

Definition at line 87 of file FilterAeroForces.h.

Referenced by FilterAeroForces(), and v_Update().

int Nektar::SolverUtils::FilterAeroForces::m_nplanes
private

number of planes for homogeneous1D expansion

Definition at line 93 of file FilterAeroForces.h.

std::string Nektar::SolverUtils::FilterAeroForces::m_outputFile
private

Definition at line 88 of file FilterAeroForces.h.

Referenced by FilterAeroForces(), and v_Initialise().

unsigned int Nektar::SolverUtils::FilterAeroForces::m_outputFrequency
private

Definition at line 83 of file FilterAeroForces.h.

Referenced by FilterAeroForces(), and v_Update().

unsigned int Nektar::SolverUtils::FilterAeroForces::m_outputPlane
private

plane to take history point from if using a homogeneous1D expansion

Definition at line 86 of file FilterAeroForces.h.

Referenced by FilterAeroForces().

std::ofstream Nektar::SolverUtils::FilterAeroForces::m_outputStream
private

Definition at line 89 of file FilterAeroForces.h.

Referenced by v_Finalise(), v_Initialise(), and v_Update().