ENH: add the infrastructure for computing and utilising

the Jacobian of an objective function, defined at the boundary, wrt nut
and gradU. Also modified the current objectives that include such
contributions
This commit is contained in:
Vaggelis Papoutsis
2022-02-07 12:01:34 +02:00
committed by Andrew Heather
parent 080567375f
commit b550a23acb
14 changed files with 204 additions and 56 deletions

View File

@ -103,6 +103,18 @@ tmp<scalarField> boundaryAdjointContribution::adjointTMVariable2Source()
} }
tmp<scalarField> boundaryAdjointContribution::dJdnut()
{
return tmp<scalarField>::New(patch_.size(), Zero);
}
tmp<tensorField> boundaryAdjointContribution::dJdGradU()
{
return tmp<tensorField>::New(patch_.size(), Zero);
}
tmp<scalarField> boundaryAdjointContribution::TMVariable1Diffusion() tmp<scalarField> boundaryAdjointContribution::TMVariable1Diffusion()
{ {
return tmp<scalarField>::New(patch_.size(), Zero); return tmp<scalarField>::New(patch_.size(), Zero);

View File

@ -138,6 +138,8 @@ public:
virtual tmp<vectorField> normalVelocitySource() = 0; virtual tmp<vectorField> normalVelocitySource() = 0;
virtual tmp<scalarField> adjointTMVariable1Source(); virtual tmp<scalarField> adjointTMVariable1Source();
virtual tmp<scalarField> adjointTMVariable2Source(); virtual tmp<scalarField> adjointTMVariable2Source();
virtual tmp<scalarField> dJdnut();
virtual tmp<tensorField> dJdGradU();
virtual tmp<scalarField> energySource() = 0; virtual tmp<scalarField> energySource() = 0;
virtual tmp<scalarField> momentumDiffusion() = 0; virtual tmp<scalarField> momentumDiffusion() = 0;

View File

@ -223,6 +223,30 @@ boundaryAdjointContributionIncompressible::adjointTMVariable2Source()
} }
tmp<scalarField>
boundaryAdjointContributionIncompressible::dJdnut()
{
return
sumContributions
(
objectiveManager_.getObjectiveFunctions(),
&objectiveIncompressible::boundarydJdnut
);
}
tmp<tensorField>
boundaryAdjointContributionIncompressible::dJdGradU()
{
return
sumContributions
(
objectiveManager_.getObjectiveFunctions(),
&objectiveIncompressible::boundarydJdGradU
);
}
tmp<scalarField> boundaryAdjointContributionIncompressible::momentumDiffusion() tmp<scalarField> boundaryAdjointContributionIncompressible::momentumDiffusion()
{ {
tmp<scalarField> tnuEff(new scalarField(patch_.size(), Zero)); tmp<scalarField> tnuEff(new scalarField(patch_.size(), Zero));

View File

@ -139,6 +139,8 @@ public:
tmp<scalarField> energySource(); tmp<scalarField> energySource();
tmp<scalarField> adjointTMVariable1Source(); tmp<scalarField> adjointTMVariable1Source();
tmp<scalarField> adjointTMVariable2Source(); tmp<scalarField> adjointTMVariable2Source();
tmp<scalarField> dJdnut();
tmp<tensorField> dJdGradU();
tmp<scalarField> momentumDiffusion(); tmp<scalarField> momentumDiffusion();
tmp<scalarField> laminarDiffusivity(); tmp<scalarField> laminarDiffusivity();

View File

@ -113,7 +113,8 @@ objectiveForce::objectiveForce
bdJdpPtr_.reset(createZeroBoundaryPtr<vector>(mesh_)); bdJdpPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdSdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_)); bdSdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdxdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_)); bdxdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdJdStressPtr_.reset(createZeroBoundaryPtr<tensor>(mesh_)); bdJdnutPtr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
bdJdGradUPtr_.reset(createZeroBoundaryPtr<tensor>(mesh_));
} }
@ -268,14 +269,35 @@ void objectiveForce::update_dxdbMultiplier()
} }
void objectiveForce::update_dJdStressMultiplier() void objectiveForce::update_boundarydJdnut()
{ {
const volVectorField& U = vars_.U();
volSymmTensorField devGradU(dev(twoSymm(fvc::grad(U))));
for (const label patchI : forcePatches_) for (const label patchI : forcePatches_)
{ {
const fvPatch& patch = mesh_.boundary()[patchI]; const fvPatch& patch = mesh_.boundary()[patchI];
tmp<vectorField> tnf = patch.nf(); tmp<vectorField> tnf = patch.nf();
const vectorField& nf = tnf(); const vectorField& nf = tnf();
bdJdStressPtr_()[patchI] = (forceDirection_ * nf)/denom(); bdJdnutPtr_()[patchI] =
-((devGradU.boundaryField()[patchI] & forceDirection_) & nf)/denom();
}
}
void objectiveForce::update_boundarydJdGradU()
{
const autoPtr<incompressible::RASModelVariables>&
turbVars = vars_.RASModelVariables();
const singlePhaseTransportModel& lamTransp = vars_.laminarTransport();
volScalarField nuEff(lamTransp.nu() + turbVars->nutRef());
for (const label patchI : forcePatches_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
const vectorField& Sf = patch.Sf();
bdJdGradUPtr_()[patchI] =
- nuEff.boundaryField()[patchI]
*dev(forceDirection_*Sf + Sf*forceDirection_);
} }
} }

View File

@ -111,8 +111,11 @@ public:
//- Update delta(x)/delta b multiplier //- Update delta(x)/delta b multiplier
void update_dxdbMultiplier(); void update_dxdbMultiplier();
//- Update dJ/dStress multiplier //- Update dJ/dnut multiplier
void update_dJdStressMultiplier(); void update_boundarydJdnut();
//- Update dJ/dGradU multiplier
void update_boundarydJdGradU();
//- Return denominator, without density //- Return denominator, without density
virtual scalar denom() const; virtual scalar denom() const;

View File

@ -84,7 +84,9 @@ objectiveIncompressible::objectiveIncompressible
bdJdpPtr_(nullptr), bdJdpPtr_(nullptr),
bdJdTPtr_(nullptr), bdJdTPtr_(nullptr),
bdJdTMvar1Ptr_(nullptr), bdJdTMvar1Ptr_(nullptr),
bdJdTMvar2Ptr_(nullptr) bdJdTMvar2Ptr_(nullptr),
bdJdnutPtr_(nullptr),
bdJdGradUPtr_(nullptr)
{ {
weight_ = dict.get<scalar>("weight"); weight_ = dict.get<scalar>("weight");
computeMeanFields_ = vars_.computeMeanFields(); computeMeanFields_ = vars_.computeMeanFields();
@ -182,6 +184,14 @@ void objectiveIncompressible::doNormalization()
{ {
bdJdTMvar2Ptr_() *= oneOverNorm; bdJdTMvar2Ptr_() *= oneOverNorm;
} }
if (hasBoundarydJdnut())
{
bdJdnutPtr_() *= oneOverNorm;
}
if (hasBoundarydJdGradU())
{
bdJdGradUPtr_() *= oneOverNorm;
}
// Normalize geometric fields // Normalize geometric fields
objective::doNormalization(); objective::doNormalization();
@ -375,6 +385,32 @@ const fvPatchScalarField& objectiveIncompressible::boundarydJdTMvar2
} }
const fvPatchScalarField& objectiveIncompressible::boundarydJdnut
(
const label patchI
)
{
if (!bdJdnutPtr_)
{
bdJdnutPtr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
}
return bdJdnutPtr_()[patchI];
}
const fvPatchTensorField& objectiveIncompressible::boundarydJdGradU
(
const label patchI
)
{
if (!bdJdGradUPtr_)
{
bdJdGradUPtr_.reset(createZeroBoundaryPtr<tensor>(mesh_));
}
return bdJdGradUPtr_()[patchI];
}
const boundaryVectorField& objectiveIncompressible::boundarydJdv() const boundaryVectorField& objectiveIncompressible::boundarydJdv()
{ {
if (!bdJdvPtr_) if (!bdJdvPtr_)
@ -445,6 +481,26 @@ const boundaryScalarField& objectiveIncompressible::boundarydJdTMvar2()
} }
const boundaryScalarField& objectiveIncompressible::boundarydJdnut()
{
if (!bdJdnutPtr_)
{
bdJdnutPtr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
}
return bdJdnutPtr_();
}
const boundaryTensorField& objectiveIncompressible::boundarydJdGradU()
{
if (!bdJdGradUPtr_)
{
bdJdGradUPtr_.reset(createZeroBoundaryPtr<tensor>(mesh_));
}
return *bdJdGradUPtr_;
}
void objectiveIncompressible::update() void objectiveIncompressible::update()
{ {
// Objective function value // Objective function value
@ -472,13 +528,14 @@ void objectiveIncompressible::update()
update_boundarydJdT(); update_boundarydJdT();
update_boundarydJdTMvar1(); update_boundarydJdTMvar1();
update_boundarydJdTMvar2(); update_boundarydJdTMvar2();
update_boundarydJdnut();
update_boundarydJdGradU();
update_boundarydJdb(); update_boundarydJdb();
update_dSdbMultiplier(); update_dSdbMultiplier();
update_dndbMultiplier(); update_dndbMultiplier();
update_dxdbMultiplier(); update_dxdbMultiplier();
update_dxdbDirectMultiplier(); update_dxdbDirectMultiplier();
update_boundaryEdgeContribution(); update_boundaryEdgeContribution();
update_dJdStressMultiplier();
// Divide everything with normalization factor // Divide everything with normalization factor
doNormalization(); doNormalization();
@ -539,6 +596,14 @@ void objectiveIncompressible::nullify()
{ {
bdJdTMvar2Ptr_() == scalar(0); bdJdTMvar2Ptr_() == scalar(0);
} }
if (hasBoundarydJdnut())
{
bdJdnutPtr_() == scalar(0);
}
if (hasBoundarydJdGradU())
{
bdJdGradUPtr_() == tensor::zero;
}
// Nullify geometric fields and sets nullified_ to true // Nullify geometric fields and sets nullified_ to true
objective::nullify(); objective::nullify();

View File

@ -97,6 +97,12 @@ protected:
//- Adjoint outlet turbulence model var 2 //- Adjoint outlet turbulence model var 2
autoPtr<boundaryScalarField> bdJdTMvar2Ptr_; autoPtr<boundaryScalarField> bdJdTMvar2Ptr_;
//- Jacobian wrt to nut
autoPtr<boundaryScalarField> bdJdnutPtr_;
//- Term multiplying gradU variations
autoPtr<boundaryTensorField> bdJdGradUPtr_;
private: private:
@ -207,6 +213,12 @@ public:
//- patch //- patch
const fvPatchScalarField& boundarydJdTMvar2(const label); const fvPatchScalarField& boundarydJdTMvar2(const label);
//- Objective partial deriv wrt nut for a specific patch
const fvPatchScalarField& boundarydJdnut(const label);
//- Objective partial deriv wrt stress tensor
const fvPatchTensorField& boundarydJdGradU(const label);
//- Objective partial deriv wrt velocity for all patches //- Objective partial deriv wrt velocity for all patches
const boundaryVectorField& boundarydJdv(); const boundaryVectorField& boundarydJdv();
@ -228,6 +240,12 @@ public:
//- Objective partial deriv wrt turbulence model var 2 for all patches //- Objective partial deriv wrt turbulence model var 2 for all patches
const boundaryScalarField& boundarydJdTMvar2(); const boundaryScalarField& boundarydJdTMvar2();
//- Objective partial deriv wrt nut for all patches
const boundaryScalarField& boundarydJdnut();
//- Objective partial deriv wrt gradU
const boundaryTensorField& boundarydJdGradU();
//- Update objective function derivatives //- Update objective function derivatives
virtual void update(); virtual void update();
@ -282,6 +300,12 @@ public:
virtual void update_boundarydJdTMvar2() virtual void update_boundarydJdTMvar2()
{} {}
virtual void update_boundarydJdnut()
{}
virtual void update_boundarydJdGradU()
{}
virtual void update_boundarydJdb() virtual void update_boundarydJdb()
{} {}
@ -321,6 +345,8 @@ public:
inline bool hasBoundarydJdT() const; inline bool hasBoundarydJdT() const;
inline bool hasBoundarydJdTMVar1() const; inline bool hasBoundarydJdTMVar1() const;
inline bool hasBoundarydJdTMVar2() const; inline bool hasBoundarydJdTMVar2() const;
inline bool hasBoundarydJdnut() const;
inline bool hasBoundarydJdGradU() const;
}; };

View File

@ -102,4 +102,16 @@ inline bool Foam::objectiveIncompressible::hasBoundarydJdTMVar2() const
} }
inline bool Foam::objectiveIncompressible::hasBoundarydJdnut() const
{
return bool(bdJdnutPtr_);
}
inline bool Foam::objectiveIncompressible::hasBoundarydJdGradU() const
{
return bool(bdJdGradUPtr_);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -120,6 +120,8 @@ objectiveMoment::objectiveMoment
bdSdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_)); bdSdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdxdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_)); bdxdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdxdbDirectMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_)); bdxdbDirectMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdJdnutPtr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
//bdJdGradUPtr_.reset(createZeroBoundaryPtr<tensor>(mesh_));
} }
@ -306,6 +308,25 @@ void objectiveMoment::update_dxdbDirectMultiplier()
} }
void objectiveMoment::update_boundarydJdnut()
{
const volVectorField& U = vars_.U();
volSymmTensorField devGradU(dev(twoSymm(fvc::grad(U))));
for (const label patchI : momentPatches_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
tmp<vectorField> nf(patch.nf());
const vectorField dx(patch.Cf() - rotationCentre_);
bdJdnutPtr_()[patchI] =
-rhoInf_
*(
(dx^(devGradU.boundaryField()[patchI] & nf)) & momentDirection_
)*invDenom_;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace objectives } // End namespace objectives

View File

@ -118,6 +118,14 @@ public:
//- Update delta(x)/delta b multiplier coming directly from the //- Update delta(x)/delta b multiplier coming directly from the
//- objective //- objective
void update_dxdbDirectMultiplier(); void update_dxdbDirectMultiplier();
//- Update dJ/dnut multiplier
void update_boundarydJdnut();
//- Update dJ/dGradU multiplier
/* WIP
void update_boundarydJdGradU();
*/
}; };

View File

@ -156,7 +156,6 @@ objective::objective
bdxdbMultPtr_(nullptr), bdxdbMultPtr_(nullptr),
bdxdbDirectMultPtr_(nullptr), bdxdbDirectMultPtr_(nullptr),
bEdgeContribution_(nullptr), bEdgeContribution_(nullptr),
bdJdStressPtr_(nullptr),
divDxDbMultPtr_(nullptr), divDxDbMultPtr_(nullptr),
gradDxDbMultPtr_(nullptr), gradDxDbMultPtr_(nullptr),
@ -376,10 +375,6 @@ void objective::doNormalization()
{ {
gradDxDbMultPtr_() *= oneOverNorm; gradDxDbMultPtr_() *= oneOverNorm;
} }
if (hasBoundarydJdStress())
{
bdJdStressPtr_() *= oneOverNorm;
}
} }
} }
@ -507,16 +502,6 @@ const vectorField& objective::boundaryEdgeMultiplier
} }
const fvPatchTensorField& objective::boundarydJdStress(const label patchI)
{
if (!bdJdStressPtr_)
{
bdJdStressPtr_.reset(createZeroBoundaryPtr<tensor>(mesh_));
}
return bdJdStressPtr_()[patchI];
}
const boundaryVectorField& objective::boundarydJdb() const boundaryVectorField& objective::boundarydJdb()
{ {
if (!bdJdbPtr_) if (!bdJdbPtr_)
@ -580,16 +565,6 @@ const vectorField3& objective::boundaryEdgeMultiplier()
} }
const boundaryTensorField& objective::boundarydJdStress()
{
if (!bdJdStressPtr_)
{
bdJdStressPtr_.reset(createZeroBoundaryPtr<tensor>(mesh_));
}
return *bdJdStressPtr_;
}
const volScalarField& objective::divDxDbMultiplier() const volScalarField& objective::divDxDbMultiplier()
{ {
if (!divDxDbMultPtr_) if (!divDxDbMultPtr_)
@ -666,10 +641,6 @@ void objective::nullify()
field = vector::zero; field = vector::zero;
} }
} }
if (hasBoundarydJdStress())
{
bdJdStressPtr_() == tensor::zero;
}
if (hasDivDxDbMult()) if (hasDivDxDbMult())
{ {
divDxDbMultPtr_() == divDxDbMultPtr_() ==

View File

@ -127,9 +127,6 @@ protected:
//- NURBS surfaces G1 continuity //- NURBS surfaces G1 continuity
autoPtr<vectorField3> bEdgeContribution_; autoPtr<vectorField3> bEdgeContribution_;
//- For use with discrete-like sensitivities
autoPtr<boundaryTensorField> bdJdStressPtr_;
// Contribution to volume-based sensitivities from volume-based // Contribution to volume-based sensitivities from volume-based
// objective functions // objective functions
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -298,9 +295,6 @@ public:
const label edgeI const label edgeI
); );
//- Objective partial deriv wrt stress tensor
const fvPatchTensorField& boundarydJdStress(const label);
//- Contribution to surface sensitivities for all patches //- Contribution to surface sensitivities for all patches
const boundaryVectorField& boundarydJdb(); const boundaryVectorField& boundarydJdb();
@ -319,9 +313,6 @@ public:
//- Multiplier located at patch boundary edges //- Multiplier located at patch boundary edges
const vectorField3& boundaryEdgeMultiplier(); const vectorField3& boundaryEdgeMultiplier();
//- Objective partial deriv wrt stress tensor
const boundaryTensorField& boundarydJdStress();
//- Multiplier of grad( delta(x)/delta b) for volume-based sensitivities //- Multiplier of grad( delta(x)/delta b) for volume-based sensitivities
const volScalarField& divDxDbMultiplier(); const volScalarField& divDxDbMultiplier();
@ -363,10 +354,6 @@ public:
virtual void update_boundaryEdgeContribution() virtual void update_boundaryEdgeContribution()
{} {}
//- Update dJ/dStress field
virtual void update_dJdStressMultiplier()
{}
//- Update div( dx/db multiplier). Volume-based sensitivity term //- Update div( dx/db multiplier). Volume-based sensitivity term
virtual void update_divDxDbMultiplier() virtual void update_divDxDbMultiplier()
{} {}
@ -415,7 +402,6 @@ public:
inline bool hasdxdbMult() const; inline bool hasdxdbMult() const;
inline bool hasdxdbDirectMult() const; inline bool hasdxdbDirectMult() const;
inline bool hasBoundaryEdgeContribution() const; inline bool hasBoundaryEdgeContribution() const;
inline bool hasBoundarydJdStress() const;
inline bool hasDivDxDbMult() const; inline bool hasDivDxDbMult() const;
inline bool hasGradDxDbMult() const; inline bool hasGradDxDbMult() const;

View File

@ -90,12 +90,6 @@ inline bool Foam::objective::hasGradDxDbMult() const
} }
inline bool Foam::objective::hasBoundarydJdStress() const
{
return bool(bdJdStressPtr_);
}
inline bool Foam::objective::hasIntegrationStartTime() const inline bool Foam::objective::hasIntegrationStartTime() const
{ {
return bool(integrationStartTimePtr_); return bool(integrationStartTimePtr_);