Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Functions
FldQCriterion.cpp File Reference
#include <cstdio>
#include <cstdlib>
#include <MultiRegions/ExpList.h>
#include <MultiRegions/ExpList1D.h>
#include <MultiRegions/ExpList2D.h>
#include <MultiRegions/ExpList3D.h>
#include <MultiRegions/ExpList2DHomogeneous1D.h>
#include <MultiRegions/ExpList3DHomogeneous1D.h>
#include <MultiRegions/ExpList3DHomogeneous2D.h>
Include dependency graph for FldQCriterion.cpp:

Go to the source code of this file.

Functions

int main (int argc, char *argv[])

Function Documentation

int main ( int  argc,
char *  argv[] 
)

Definition at line 49 of file FldQCriterion.cpp.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, Nektar::LibUtilities::SessionReader::CreateInstance(), Nektar::LibUtilities::ePolyEvenlySpaced, Nektar::LibUtilities::Import(), Nektar::SpatialDomains::MeshGraph::Read(), Vmath::Smul(), Vmath::Vadd(), Vmath::Vmul(), Vmath::Vsub(), Nektar::LibUtilities::Write(), and Vmath::Zero().

{
int i, j;
if (argc != 4)
{
fprintf(stderr, "Usage: FldQCriterion meshfile infld outfld\n");
exit(1);
}
= LibUtilities::SessionReader::CreateInstance(argc, argv);
//----------------------------------------------
// Read in mesh from input file
string meshfile(argv[argc - 3]);
SpatialDomains::MeshGraph::Read(vSession);
//----------------------------------------------
//----------------------------------------------
// Import field file.
string fieldfile(argv[argc - 2]);
vector<LibUtilities::FieldDefinitionsSharedPtr> fielddef;
vector<vector<NekDouble> > fielddata;
LibUtilities::Import(fieldfile, fielddef, fielddata);
bool useFFT = false;
bool dealiasing = false;
//----------------------------------------------
//----------------------------------------------
// Define Expansion
int expdim = graphShPt->GetMeshDimension();
int nfields = fielddef[0]->m_fields.size();
int addfields = 1;
Array<OneD, MultiRegions::ExpListSharedPtr> Exp(nfields + addfields);
switch (expdim)
{
case 1:
{
ASSERTL0(fielddef[0]->m_numHomogeneousDir <= 2,
"Quasi-3D approach is only set up for 1 or 2 homogeneous "
"directions");
if (fielddef[0]->m_numHomogeneousDir == 1)
{
// Define Homogeneous expansion
int nplanes;
vSession->LoadParameter(
"HomModesZ", nplanes, fielddef[0]->m_numModes[1]);
// choose points to be at evenly spaced points at
// nplanes points
fielddef[0]->m_basis[1], nplanes, Pkey);
NekDouble ly = fielddef[0]->m_homogeneousLengths[0];
vSession, Bkey, ly, useFFT, dealiasing, graphShPt);
Exp[0] = Exp2DH1;
for (i = 1; i < nfields; ++i)
{
}
}
else if (fielddef[0]->m_numHomogeneousDir == 2)
{
// Define Homogeneous expansion
//int nylines = fielddef[0]->m_numModes[1];
//int nzlines = fielddef[0]->m_numModes[2];
int nylines;
int nzlines;
vSession->LoadParameter(
"HomModesY", nylines, fielddef[0]->m_numModes[1]);
vSession->LoadParameter(
"HomModesZ", nzlines, fielddef[0]->m_numModes[2]);
// choose points to be at evenly spaced points at
// nplanes points
fielddef[0]->m_basis[1], nylines, PkeyY);
fielddef[0]->m_basis[2], nzlines, PkeyZ);
NekDouble ly = fielddef[0]->m_homogeneousLengths[0];
NekDouble lz = fielddef[0]->m_homogeneousLengths[1];
::AllocateSharedPtr(vSession, BkeyY, BkeyZ, ly, lz,
useFFT, dealiasing, graphShPt);
Exp[0] = Exp3DH2;
for (i = 1; i < nfields; ++i)
{
}
}
else
{
::AllocateSharedPtr(vSession, graphShPt);
Exp[0] = Exp1D;
for (i = 1; i < nfields + addfields; ++i)
{
}
}
}
break;
case 2:
{
ASSERTL0(fielddef[0]->m_numHomogeneousDir <= 1,
"NumHomogeneousDir is only set up for 1");
if (fielddef[0]->m_numHomogeneousDir == 1)
{
// Define Homogeneous expansion
//int nplanes = fielddef[0]->m_numModes[2];
int nplanes;
vSession->LoadParameter(
"HomModesZ", nplanes, fielddef[0]->m_numModes[2]);
// choose points to be at evenly spaced points at
// nplanes points
fielddef[0]->m_basis[2], nplanes, Pkey);
NekDouble lz = fielddef[0]->m_homogeneousLengths[0];
::AllocateSharedPtr(vSession, Bkey, lz, useFFT,
dealiasing, graphShPt);
Exp[0] = Exp3DH1;
for (i = 1; i < nfields + addfields; ++i)
{
}
}
else
{
::AllocateSharedPtr(vSession, graphShPt);
Exp[0] = Exp2D;
for (i = 1; i < nfields + addfields; ++i)
{
}
}
}
break;
case 3:
{
::AllocateSharedPtr(vSession, graphShPt);
Exp[0] = Exp3D;
for (i = 1; i < nfields + addfields; ++i)
{
}
}
break;
default:
ASSERTL0(false, "Expansion dimension not recognised");
break;
}
//----------------------------------------------
//----------------------------------------------
// Copy data from field file
for (j = 0; j < nfields; ++j)
{
for (int i = 0; i < fielddata.size(); ++i)
{
Exp[j]->ExtractDataToCoeffs(fielddef [i],
fielddata[i],
fielddef [i]->m_fields[j],
Exp[j]->UpdateCoeffs());
}
Exp[j]->BwdTrans(Exp[j]->GetCoeffs(), Exp[j]->UpdatePhys());
}
//----------------------------------------------
//----------------------------------------------
// Compute gradients of fields
int nq = Exp[0]->GetNpoints();
Array<OneD, Array<OneD, NekDouble> > grad(nfields * nfields);
Array<OneD, Array<OneD, NekDouble> > omega(nfields * nfields);
Array<OneD, Array<OneD, NekDouble> > S (nfields * nfields);
Array<OneD, Array<OneD, NekDouble> > Q (nfields * nfields);
Array<OneD, Array<OneD, NekDouble> > outfield (addfields);
Array<OneD, Array<OneD, NekDouble> > outfield1(addfields);
Array<OneD, Array<OneD, NekDouble> > outfield2(addfields);
Array<OneD, Array<OneD, NekDouble> > outfield3(addfields);
for (i = 0; i < nfields * nfields; ++i)
{
grad[i] = Array<OneD, NekDouble>(nq);
}
for (i = 0; i < addfields; ++i)
{
outfield [i] = Array<OneD, NekDouble>(nq);
outfield1[i] = Array<OneD, NekDouble>(nq);
outfield2[i] = Array<OneD, NekDouble>(nq);
outfield3[i] = Array<OneD, NekDouble>(nq);
omega[i] = Array<OneD, NekDouble>(nq);
S[i] = Array<OneD, NekDouble>(nq);
Q[i] = Array<OneD, NekDouble>(nq);
}
// Calculate Gradient & Vorticity
for (i = 0; i < nfields; ++i)
{
Exp[i]->PhysDeriv(
Exp[i]->GetPhys(), grad[i * nfields], grad[i * nfields + 1],
grad[i * nfields + 2]);
}
// W_x = Wy - Vz
Vmath::Vsub(nq, grad[2 * nfields + 1], 1, grad[1 * nfields + 2], 1,
outfield1[0], 1);
// W_x^2
Vmath::Vmul(nq, outfield1[0], 1, outfield1[0], 1, outfield1[0], 1);
// W_y = Uz - Wx
Vmath::Vsub(nq, grad[0 * nfields + 2], 1, grad[2 * nfields + 0], 1,
outfield2[0], 1);
// W_y^2
Vmath::Vmul(nq, outfield2[0], 1, outfield2[0], 1, outfield2[0], 1);
// W_z = Vx - Uy
Vmath::Vsub(nq, grad[1 * nfields + 0], 1, grad[0 * nfields + 1], 1,
outfield3[0], 1);
// W_z^2
Vmath::Vmul(nq, outfield3[0], 1, outfield3[0], 1, outfield3[0], 1);
// add fields omega = 0.5*(W_x^2 + W_y^2 + W_z^2)
NekDouble fac = 0.5;
Vmath::Vadd(nq, &outfield1[0][0], 1, &outfield2[0][0], 1, &omega[0][0], 1);
Vmath::Vadd(nq, &omega[0][0], 1, &outfield3[0][0], 1, &omega[0][0], 1);
for (int k = 0; k < addfields; ++k)
{
Vmath::Smul(nq, fac, &omega[k][0], 1, &omega[k][0], 1);
}
Vmath::Zero(nq, &outfield1[0][0], 1);
Vmath::Zero(nq, &outfield2[0][0], 1);
Vmath::Zero(nq, &outfield3[0][0], 1);
Vmath::Vmul(nq, grad[0 * nfields + 0], 1, grad[0 * nfields + 0], 1,
outfield1[0], 1);
Vmath::Vmul(nq, grad[1 * nfields + 1], 1, grad[1 * nfields + 1], 1,
outfield2[0], 1);
Vmath::Vmul(nq, grad[2 * nfields + 2], 1, grad[2 * nfields + 2], 1,
outfield3[0], 1);
Vmath::Vadd(nq, &outfield1[0][0], 1, &outfield2[0][0], 1, &S[0][0], 1);
Vmath::Vadd(nq, &S[0][0], 1, &outfield3[0][0], 1, &S[0][0], 1);
// W_y + V_z
Vmath::Vadd(nq, grad[2 * nfields + 1], 1, grad[1 * nfields + 2], 1,
outfield1[0], 1);
Vmath::Vmul(nq, &outfield1[0][0], 1, &outfield1[0][0], 1,
&outfield1[0][0], 1);
// U_z + W_x
Vmath::Vadd(nq, grad[0 * nfields + 2], 1, grad[2 * nfields + 0], 1,
outfield2[0], 1);
Vmath::Vmul(nq, &outfield2[0][0], 1, &outfield2[0][0], 1,
&outfield2[0][0], 1);
// V_x + U_y
Vmath::Vadd(nq, grad[1 * nfields + 0], 1, grad[0 * nfields + 1], 1,
outfield3[0], 1);
Vmath::Vmul(nq, &outfield3[0][0], 1, &outfield3[0][0], 1,
&outfield3[0][0], 1);
Vmath::Vadd(nq, &outfield1[0][0], 1, &outfield2[0][0], 1,
&outfield2[0][0], 1);
Vmath::Vadd(nq, &outfield2[0][0], 1, &outfield3[0][0], 1,
&outfield3[0][0], 1);
for (int k = 0; k < addfields; ++k)
{
Vmath::Smul(nq, fac, &outfield3[k][0], 1, &outfield3[k][0], 1);
}
Vmath::Vadd(nq, &outfield3[0][0], 1, &S[0][0], 1, &S[0][0], 1);
Vmath::Vsub(nq, omega[0], 1, S[0], 1, Q[0], 1);
for (int k = 0; k < addfields; ++k)
{
Vmath::Smul(nq, fac, &Q[k][0], 1, &Q[k][0], 1);
}
for (i = 0; i < addfields; ++i)
{
Exp[nfields + i]->FwdTrans(Q[i], Exp[nfields + i]->UpdateCoeffs());
}
//-----------------------------------------------
// Write solution to file with additional computed fields
string out(argv[argc - 1]);
std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef
= Exp[0]->GetFieldDefinitions();
std::vector<std::vector<NekDouble> > FieldData(FieldDef.size());
vector<string> outname;
outname.push_back("Q");
for (j = 0; j < nfields + addfields; ++j)
{
for (i = 0; i < FieldDef.size(); ++i)
{
if (j >= nfields)
{
FieldDef[i]->m_fields.push_back(outname[j - nfields]);
}
else
{
FieldDef[i]->m_fields.push_back(fielddef[i]->m_fields[j]);
}
Exp[j]->AppendFieldData(FieldDef[i], FieldData[i]);
}
}
LibUtilities::Write(out, FieldDef, FieldData);
//-----------------------------------------------
return 0;
}