Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Force based data sets #148

Merged
merged 5 commits into from
Jan 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions FSI/FSI.C
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ void preciceAdapter::FSI::FluidStructureInteraction::addWriters(std::string data
interface->addCouplingDataWriter
(
dataName,
new Force(mesh_, runTime_.timeName(), solverType_) /* TODO: Add any other arguments here */
new Force(mesh_, solverType_) /* TODO: Add any other arguments here */
);
DEBUG(adapterInfo("Added writer: Force."));
}
Expand All @@ -138,7 +138,7 @@ void preciceAdapter::FSI::FluidStructureInteraction::addWriters(std::string data
interface->addCouplingDataWriter
(
dataName,
new Stress(mesh_, runTime_.timeName(), solverType_) /* TODO: Add any other arguments here */
new Stress(mesh_, solverType_) /* TODO: Add any other arguments here */
);
DEBUG(adapterInfo("Added writer: Stress."));
}
Expand All @@ -157,7 +157,7 @@ void preciceAdapter::FSI::FluidStructureInteraction::addReaders(std::string data
interface->addCouplingDataReader
(
dataName,
new Force(mesh_, runTime_.timeName(), solverType_) /* TODO: Add any other arguments here */
new Force(mesh_, solverType_) /* TODO: Add any other arguments here */
);
DEBUG(adapterInfo("Added reader: Force."));
}
Expand All @@ -184,7 +184,7 @@ void preciceAdapter::FSI::FluidStructureInteraction::addReaders(std::string data
interface->addCouplingDataReader
(
dataName,
new Stress(mesh_, runTime_.timeName(), solverType_) /* TODO: Add any other arguments here */
new Stress(mesh_, solverType_) /* TODO: Add any other arguments here */
);
DEBUG(adapterInfo("Added reader: Stress."));
}
Expand Down
257 changes: 9 additions & 248 deletions FSI/Force.C
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,20 @@

using namespace Foam;

preciceAdapter::FSI::Force::Force
(
const Foam::fvMesh& mesh,
const std::string solverType
)
:
mesh_(mesh),
solverType_(solverType),
force_field_created(false)
{}


preciceAdapter::FSI::Force::Force
(
const Foam::fvMesh& mesh,
const fileName& timeName,
const std::string solverType
/* TODO: We should add any required field names here.
/ They would need to be vector fields.
/ See FSI/Temperature.C for details.
*/
)
:
mesh_(mesh),
solverType_(solverType),
force_field_created(true)
ForceBase(mesh,solverType)
{
//What about type "basic"?
if (solverType_.compare("incompressible") != 0 && solverType_.compare("compressible") != 0)
{
FatalErrorInFunction
<< "Forces calculation does only support "
<< "compressible or incompressible solver type."
<< exit(FatalError);
}

dataType_ = vector;

Force_ = new volVectorField
(
IOobject
(
"Force",
timeName,
mesh_.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
Expand All @@ -60,232 +30,23 @@ force_field_created(true)
);
}

//Calculate viscous force
Foam::tmp<Foam::volSymmTensorField> preciceAdapter::FSI::Force::devRhoReff() const
{
//For turbulent flows
typedef compressible::turbulenceModel cmpTurbModel;
typedef incompressible::turbulenceModel icoTurbModel;

if (mesh_.foundObject<cmpTurbModel>(cmpTurbModel::propertiesName))
{
const cmpTurbModel & turb
(
mesh_.lookupObject<cmpTurbModel>(cmpTurbModel::propertiesName)
);

return turb.devRhoReff();

}
else if (mesh_.foundObject<icoTurbModel>(icoTurbModel::propertiesName))
{
const incompressible::turbulenceModel& turb
(
mesh_.lookupObject<icoTurbModel>(icoTurbModel::propertiesName)
);

return rho()*turb.devReff();
}
else
{
// For laminar flows get the velocity
const volVectorField & U
(
mesh_.lookupObject<volVectorField>("U")
);

return -mu()*dev(twoSymm(fvc::grad(U)));
}
}

//lookup correct rho
Foam::tmp<Foam::volScalarField> preciceAdapter::FSI::Force::rho() const
void preciceAdapter::FSI::Force::write(double * buffer, bool meshConnectivity, const unsigned int dim)
{
// If volScalarField exists, read it from registry (for compressible cases)
// interFoam is incompressible but has volScalarField rho

if (mesh_.foundObject<volScalarField>("rho"))
{
return mesh_.lookupObject<volScalarField>("rho");
}
else if (solverType_.compare("incompressible") == 0)
{
const dictionary& FSIDict =
mesh_.lookupObject<IOdictionary>("preciceDict").subOrEmptyDict("FSI");

return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"rho",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedScalar(FSIDict.lookup("rho"))
)
);

}
else
{
FatalErrorInFunction
<< "Did not find the correct rho."
<< exit(FatalError);

return volScalarField::null();
}
this->writeToBuffer(buffer, *Force_, dim);
}

//lookup correct mu
Foam::tmp<Foam::volScalarField> preciceAdapter::FSI::Force::mu() const
{

if (solverType_.compare("incompressible") == 0)
{
typedef immiscibleIncompressibleTwoPhaseMixture iitpMixture;
if (mesh_.foundObject<iitpMixture>("mixture"))
{
const iitpMixture& mixture
(
mesh_.lookupObject<iitpMixture>("mixture")
);

return mixture.mu();
}
else
{

const dictionary& FSIDict =
mesh_.lookupObject<IOdictionary>("preciceDict").subOrEmptyDict("FSI");

dimensionedScalar nu(FSIDict.lookup("nu"));

return tmp<volScalarField>
(
new volScalarField
(
nu*rho()
)
);
}

}
else if (solverType_.compare("compressible") == 0)
{
return mesh_.lookupObject<volScalarField>("thermo:mu");
}
else
{
FatalErrorInFunction
<< "Did not find the correct mu."
<< exit(FatalError);

return volScalarField::null();
}
}

void preciceAdapter::FSI::Force::write(double * buffer, bool meshConnectivity, const unsigned int dim)
void preciceAdapter::FSI::Force::read(double * buffer, const unsigned int dim)
{
// Compute forces. See the Forces function object.

// Normal vectors on the boundary, multiplied with the face areas
const surfaceVectorField::Boundary& Sfb
(
mesh_.Sf().boundaryField()
);

// Stress tensor boundary field
tmp<volSymmTensorField> tdevRhoReff(devRhoReff());
const volSymmTensorField::Boundary& devRhoReffb
(
tdevRhoReff().boundaryField()
);

// Density boundary field
tmp<volScalarField> trho(rho());
const volScalarField::Boundary& rhob =
trho().boundaryField();

// Pressure boundary field
tmp<volScalarField> tp = mesh_.lookupObject<volScalarField>("p");
const volScalarField::Boundary& pb
(
tp().boundaryField()
);

int bufferIndex = 0;
// For every boundary patch of the interface
for (uint j = 0; j < patchIDs_.size(); j++)
{

int patchID = patchIDs_.at(j);

// Pressure forces
if (solverType_.compare("incompressible") == 0)
{
Force_->boundaryFieldRef()[patchID] =
Sfb[patchID] * pb[patchID] * rhob[patchID];
}
else if (solverType_.compare("compressible") == 0)
{
Force_->boundaryFieldRef()[patchID] =
Sfb[patchID] * pb[patchID];
}
else
{
FatalErrorInFunction
<< "Forces calculation does only support "
<< "compressible or incompressible solver type."
<< exit(FatalError);
}

// Viscous forces
Force_->boundaryFieldRef()[patchID] +=
Sfb[patchID] & devRhoReffb[patchID];

// Write the forces to the preCICE buffer
// For every cell of the patch
forAll(Force_->boundaryField()[patchID], i)
{
// Copy the force into the buffer
// x-dimension
buffer[bufferIndex++]
=
Force_->boundaryField()[patchID][i].x();

// y-dimension
buffer[bufferIndex++]
=
Force_->boundaryField()[patchID][i].y();

if(dim == 3)
// z-dimension
buffer[bufferIndex++]
=
Force_->boundaryField()[patchID][i].z();
}
}
this->readFromBuffer(buffer);
}

void preciceAdapter::FSI::Force::read(double * buffer, const unsigned int dim)
vectorField preciceAdapter::FSI::Force::getFaceVectors(const unsigned int patchID) const
{
/* TODO: Implement
* We need two nested for-loops for each patch,
* the outer for the locations and the inner for the dimensions.
* See the preCICE readBlockVectorData() implementation.
*/
FatalErrorInFunction
<< "Reading forces is not supported."
<< exit(FatalError);
// Normal vectors multiplied by face area
return mesh_.boundary()[patchID].Sf();
}

preciceAdapter::FSI::Force::~Force()
{
if(force_field_created)
delete Force_;
}
Loading