OpenFOAM-5.x/src/dynamicMesh/attachDetach/attachDetach.C
Henry Weller 5e6a7ea282 Completed update ...ErrorIn -> ...ErrorInFunction
Avoids the clutter and maintenance effort associated with providing the
function signature string.
2015-11-11 09:03:39 +00:00

485 lines
13 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Attach/detach boundary mesh modifier. This modifier takes a set of
internal faces and converts them into boundary faces and vice versa
based on the given activation switch.
\*---------------------------------------------------------------------------*/
#include "attachDetach.H"
#include "polyTopoChanger.H"
#include "polyMesh.H"
#include "Time.H"
#include "primitiveMesh.H"
#include "polyTopoChange.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(attachDetach, 0);
addToRunTimeSelectionTable
(
polyMeshModifier,
attachDetach,
dictionary
);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::attachDetach::checkDefinition()
{
if
(
!faceZoneID_.active()
|| !masterPatchID_.active()
|| !slavePatchID_.active()
)
{
FatalErrorInFunction
<< "Not all zones and patches needed in the definition "
<< "have been found. Please check your mesh definition."
<< abort(FatalError);
}
const polyMesh& mesh = topoChanger().mesh();
if (debug)
{
Pout<< "Attach/detach object " << name() << " :" << nl
<< " faceZoneID: " << faceZoneID_ << nl
<< " masterPatchID: " << masterPatchID_ << nl
<< " slavePatchID: " << slavePatchID_ << endl;
}
// Check the sizes and set up state
if
(
mesh.boundaryMesh()[masterPatchID_.index()].empty()
&& mesh.boundaryMesh()[slavePatchID_.index()].empty()
)
{
// Boundary is attached
if (debug)
{
Pout<< " Attached on construction" << endl;
}
state_ = ATTACHED;
// Check if there are faces in the master zone
if (mesh.faceZones()[faceZoneID_.index()].empty())
{
FatalErrorInFunction
<< "mesh definition."
<< abort(FatalError);
}
// Check that all the faces in the face zone are internal
if (debug)
{
const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
DynamicList<label> bouFacesInZone(addr.size());
forAll(addr, faceI)
{
if (!mesh.isInternalFace(addr[faceI]))
{
bouFacesInZone.append(addr[faceI]);
}
}
if (bouFacesInZone.size())
{
FatalErrorInFunction
<< "Found boundary faces in the zone defining "
<< "attach/detach boundary "
<< " for object " << name()
<< " : . This is not allowed." << nl
<< "Boundary faces: " << bouFacesInZone
<< abort(FatalError);
}
}
}
else
{
// Boundary is detached
if (debug)
{
Pout<< " Detached on construction" << endl;
}
state_ = DETACHED;
// Check that the sizes of master and slave patch are identical
// and identical to the size of the face zone
if
(
(
mesh.boundaryMesh()[masterPatchID_.index()].size()
!= mesh.boundaryMesh()[slavePatchID_.index()].size()
)
|| (
mesh.boundaryMesh()[masterPatchID_.index()].size()
!= mesh.faceZones()[faceZoneID_.index()].size()
)
)
{
FatalErrorInFunction
<< "Problem with sizes in mesh modifier. The face zone,"
<< " master and slave patch should have the same size"
<< " for object " << name() << ". " << nl
<< "Zone size: "
<< mesh.faceZones()[faceZoneID_.index()].size()
<< " Master patch size: "
<< mesh.boundaryMesh()[masterPatchID_.index()].size()
<< " Slave patch size: "
<< mesh.boundaryMesh()[slavePatchID_.index()].size()
<< abort(FatalError);
}
// Check that all the faces belong to either master or slave patch
if (debug)
{
const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
DynamicList<label> zoneProblemFaces(addr.size());
forAll(addr, faceI)
{
label facePatch =
mesh.boundaryMesh().whichPatch(addr[faceI]);
if
(
facePatch != masterPatchID_.index()
&& facePatch != slavePatchID_.index()
)
{
zoneProblemFaces.append(addr[faceI]);
}
}
if (zoneProblemFaces.size())
{
FatalErrorInFunction
<< "Found faces in the zone defining "
<< "attach/detach boundary which do not belong to "
<< "either master or slave patch. "
<< "This is not allowed." << nl
<< "Problem faces: " << zoneProblemFaces
<< abort(FatalError);
}
}
}
// Check that trigger times are in ascending order
bool triggersOK = true;
for (label i = 0; i < triggerTimes_.size() - 1; i++)
{
triggersOK = triggersOK && (triggerTimes_[i] < triggerTimes_[i + 1]);
}
if
(
!triggersOK
|| (triggerTimes_.empty() && !manualTrigger())
)
{
FatalErrorInFunction
<< "Problem with definition of trigger times: "
<< triggerTimes_
<< abort(FatalError);
}
}
void Foam::attachDetach::clearAddressing() const
{
deleteDemandDrivenData(pointMatchMapPtr_);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::attachDetach::attachDetach
(
const word& name,
const label index,
const polyTopoChanger& mme,
const word& faceZoneName,
const word& masterPatchName,
const word& slavePatchName,
const scalarField& triggerTimes,
const bool manualTrigger
)
:
polyMeshModifier(name, index, mme, true),
faceZoneID_(faceZoneName, mme.mesh().faceZones()),
masterPatchID_(masterPatchName, mme.mesh().boundaryMesh()),
slavePatchID_(slavePatchName, mme.mesh().boundaryMesh()),
triggerTimes_(triggerTimes),
manualTrigger_(manualTrigger),
triggerIndex_(0),
state_(UNKNOWN),
trigger_(false),
pointMatchMapPtr_(NULL)
{
checkDefinition();
}
// Construct from components
Foam::attachDetach::attachDetach
(
const word& name,
const dictionary& dict,
const label index,
const polyTopoChanger& mme
)
:
polyMeshModifier(name, index, mme, Switch(dict.lookup("active"))),
faceZoneID_
(
dict.lookup("faceZoneName"),
mme.mesh().faceZones()
),
masterPatchID_
(
dict.lookup("masterPatchName"),
mme.mesh().boundaryMesh()
),
slavePatchID_
(
dict.lookup("slavePatchName"),
mme.mesh().boundaryMesh()
),
triggerTimes_(dict.lookup("triggerTimes")),
manualTrigger_(dict.lookup("manualTrigger")),
triggerIndex_(0),
state_(UNKNOWN),
trigger_(false),
pointMatchMapPtr_(NULL)
{
checkDefinition();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::attachDetach::~attachDetach()
{
clearAddressing();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::attachDetach::setAttach() const
{
if (!attached())
{
trigger_ = true;
}
else
{
trigger_ = false;
}
return trigger_;
}
bool Foam::attachDetach::setDetach() const
{
if (attached())
{
trigger_ = true;
}
else
{
trigger_ = false;
}
return trigger_;
}
bool Foam::attachDetach::changeTopology() const
{
if (manualTrigger())
{
if (debug)
{
Pout<< "bool attachDetach::changeTopology() const "
<< " for object " << name() << " : "
<< "Manual trigger" << endl;
}
return trigger_;
}
// To deal with multiple calls within the same time step, return true
// if trigger is already set
if (trigger_)
{
if (debug)
{
Pout<< "bool attachDetach::changeTopology() const "
<< " for object " << name() << " : "
<< "Already triggered for current time step" << endl;
}
return true;
}
// If the end of the list of trigger times has been reached, no
// new topological changes will happen
if (triggerIndex_ >= triggerTimes_.size())
{
if (debug)
{
Pout<< "bool attachDetach::changeTopology() const "
<< " for object " << name() << " : "
<< "Reached end of trigger list" << endl;
}
return false;
}
if (debug)
{
Pout<< "bool attachDetach::changeTopology() const "
<< " for object " << name() << " : "
<< "Triggering attach/detach topology change." << nl
<< "Current time: " << topoChanger().mesh().time().value()
<< " current trigger time: " << triggerTimes_[triggerIndex_]
<< " trigger index: " << triggerIndex_ << endl;
}
// Check if the time is greater than the currentTime. If so, increment
// the current lookup and request topology change
if (topoChanger().mesh().time().value() >= triggerTimes_[triggerIndex_])
{
trigger_ = true;
// Increment the trigger index
triggerIndex_++;
return true;
}
// No topological change
return false;
}
void Foam::attachDetach::setRefinement(polyTopoChange& ref) const
{
// Insert the attach/detach instructions into the topological change
if (trigger_)
{
// Clear point addressing from previous attach/detach event
clearAddressing();
if (state_ == ATTACHED)
{
detachInterface(ref);
// Set the state to detached
state_ = DETACHED;
}
else if (state_ == DETACHED)
{
attachInterface(ref);
// Set the state to attached
state_ = ATTACHED;
}
else
{
FatalErrorInFunction
<< "Requested attach/detach event and currect state "
<< "is not known."
<< abort(FatalError);
}
trigger_ = false;
}
}
void Foam::attachDetach::updateMesh(const mapPolyMesh&)
{
// Mesh has changed topologically. Update local topological data
const polyMesh& mesh = topoChanger().mesh();
faceZoneID_.update(mesh.faceZones());
masterPatchID_.update(mesh.boundaryMesh());
slavePatchID_.update(mesh.boundaryMesh());
clearAddressing();
}
void Foam::attachDetach::write(Ostream& os) const
{
os << nl << type() << nl
<< name()<< nl
<< faceZoneID_.name() << nl
<< masterPatchID_.name() << nl
<< slavePatchID_.name() << nl
<< triggerTimes_ << endl;
}
void Foam::attachDetach::writeDict(Ostream& os) const
{
os << nl << name() << nl << token::BEGIN_BLOCK << nl
<< " type " << type()
<< token::END_STATEMENT << nl
<< " faceZoneName " << faceZoneID_.name()
<< token::END_STATEMENT << nl
<< " masterPatchName " << masterPatchID_.name()
<< token::END_STATEMENT << nl
<< " slavePatchName " << slavePatchID_.name()
<< token::END_STATEMENT << nl
<< " triggerTimes " << triggerTimes_
<< token::END_STATEMENT << nl
<< " manualTrigger " << manualTrigger()
<< token::END_STATEMENT << nl
<< " active " << active()
<< token::END_STATEMENT << nl
<< token::END_BLOCK << endl;
}
// ************************************************************************* //