View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0004183 | OpenFOAM | Contribution | public | 2024-11-25 07:35 | 2024-11-26 12:00 |
Reporter | nguyenhung97 | Assigned To | will | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | no change required | ||
Platform | Ubuntu | OS | Other | OS Version | (please specify) |
Product Version | 12 | ||||
Summary | 0004183: make the write operation of particle interaction as an option for log-friendly purpose for lots of patches | ||||
Description | Normally, particle interaction with patches will be written in every time step in log which could cause huge storage of log with cases with many patches (for our case, 500). I now make it as an option (default is false as it is now). This change will be very convenient for users dealing with huge projects without affect the current state of OpenFOAM. | ||||
Steps To Reproduce | 1. In LocalInteraction.H: add a new variable: Switch logAtWriteTime_; 2. In LocalInteraction.C: read the value of logAtWriteTime_ from dict or default false (line 94) move the write operation into an "if". (line 449 - 489) | ||||
Additional Information | files of changes are attached. Other patch interaction model could be modified the same if you feel needed. | ||||
Tags | No tags attached. | ||||
|
LocalInteraction_new.C (14,525 bytes)
/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org \\ / A nd | Copyright (C) 2011-2024 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/>. \*---------------------------------------------------------------------------*/ #include "LocalInteraction.H" #include "wordAndDictionary.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { struct wordReAndDictionary : public Tuple2<wordRe, dictionary> { using Tuple2<wordRe, dictionary>::Tuple2; wordReAndDictionary(); wordReAndDictionary(Istream& is); }; inline Istream& operator>>(Istream& is, wordReAndDictionary& wd) { wd.first() = wordRe(is); dictionary d(is); wd.second().transfer(d); return is; } inline Ostream& operator<<(Ostream& os, const wordReAndDictionary& wd) { return os << wd.first() << token::SPACE << wd.second(); } inline wordReAndDictionary::wordReAndDictionary() {} inline wordReAndDictionary::wordReAndDictionary(Istream& is) { is >> *this; } } // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // template<class CloudType> Foam::LocalInteraction<CloudType>::LocalInteraction ( const dictionary& dict, CloudType& cloud ) : PatchInteractionModel<CloudType>(dict, cloud, typeName), patchInteractionTypes_ ( this->owner().mesh().boundaryMesh().size(), PatchInteractionModel<CloudType>::itOther ), patchEs_(this->owner().mesh().boundaryMesh().size(), NaN), patchMus_(this->owner().mesh().boundaryMesh().size(), NaN), nEscape_(this->owner().mesh().boundaryMesh().size(), 0), massEscape_(this->owner().mesh().boundaryMesh().size(), scalar(0)), nStick_(this->owner().mesh().boundaryMesh().size(), 0), massStick_(this->owner().mesh().boundaryMesh().size(), scalar(0)), writeFields_(this->coeffDict().lookupOrDefault("writeFields", false)), logAtWriteTime_(this->coeffDict().lookupOrDefault("logAtWriteTime", false)), massEscapePtr_(nullptr), massStickPtr_(nullptr) { const polyBoundaryMesh& patches = this->owner().mesh().boundaryMesh(); if (writeFields_) { const word massEscapeName(this->owner().name() + ":massEscape"); const word massStickName(this->owner().name() + ":massStick"); Info<< " Interaction fields will be written to " << massEscapeName << " and " << massStickName << endl; (void)massEscape(); (void)massStick(); } else { Info<< " Interaction fields will not be written" << endl; } // Get the patch-settings dictionaries dictionary patchesDict; if (this->coeffDict().isDict("patches")) { patchesDict = this->coeffDict().subDict("patches"); } else { const List<wordReAndDictionary> patchNameAndDicts ( this->coeffDict().lookup("patches") ); forAll(patchNameAndDicts, dicti) { patchesDict.set ( keyType(string(patchNameAndDicts[dicti].first())), patchNameAndDicts[dicti].second() ); } } // Read the patch settings wordList unspecifiedNonConstraintPatches; forAll(patches, patchi) { const word& patchName = patches[patchi].name(); const bool havePatchDict = patchesDict.found(patchName); const bool patchIsConstraint = polyPatch::constraintType(patches[patchi].type()); // No settings for constrained patch. No model. if (!havePatchDict && patchIsConstraint) { patchInteractionTypes_[patchi] = PatchInteractionModel<CloudType>::itNone; continue; } // No settings for non-constrained patch. Error. if (!havePatchDict && !patchIsConstraint) { unspecifiedNonConstraintPatches.append(patches[patchi].name()); continue; } const dictionary& patchDict = patchesDict.subDict(patchName); // Settings for constrained patch. Ignored unless "patchType" is // correctly specified. if (havePatchDict && patchIsConstraint) { if (!patchDict.found("patchType")) { patchInteractionTypes_[patchi] = PatchInteractionModel<CloudType>::itNone; continue; } const word patchType = patchDict.lookup<word>("patchType"); if (patchType != patches[patchi].type()) { FatalErrorInFunction << "Type " << patchType << " specified for patch " << patchName << " does not match the patch type " << patches[patchi].type() << exit(FatalError); } } // Read and set the interaction model const word itName = patchDict.lookup<word>("type"); const interactionType it = this->wordToInteractionType(itName); if (it == PatchInteractionModel<CloudType>::itOther) { FatalErrorInFunction << "Unknown patch interaction type " << itName << " for patch " << patchName << ". Valid types are:" << PatchInteractionModel<CloudType>::interactionTypeNames_ << nl << exit(FatalError); } patchInteractionTypes_[patchi] = it; if (it == PatchInteractionModel<CloudType>::itRebound) { patchEs_[patchi] = patchDict.lookupOrDefault<scalar>("e", 1); patchMus_[patchi] = patchDict.lookupOrDefault<scalar>("mu", 0); } } // Error if interactions are unspecified for non-constraint patches if (!unspecifiedNonConstraintPatches.empty()) { FatalErrorInFunction << "No interaction type was specified for non-constraint patches: " << unspecifiedNonConstraintPatches << exit(FatalError); } } template<class CloudType> Foam::LocalInteraction<CloudType>::LocalInteraction ( const LocalInteraction<CloudType>& pim ) : PatchInteractionModel<CloudType>(pim), patchInteractionTypes_(pim.patchInteractionTypes_), patchEs_(pim.patchEs_), patchMus_(pim.patchMus_), nEscape_(pim.nEscape_), massEscape_(pim.massEscape_), nStick_(pim.nStick_), massStick_(pim.massStick_), writeFields_(pim.writeFields_), logAtWriteTime_(pim.logAtWriteTime_), massEscapePtr_(nullptr), massStickPtr_(nullptr) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template<class CloudType> Foam::LocalInteraction<CloudType>::~LocalInteraction() {} // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // template<class CloudType> Foam::volScalarField& Foam::LocalInteraction<CloudType>::massEscape() { if (!massEscapePtr_.valid()) { const fvMesh& mesh = this->owner().mesh(); massEscapePtr_.reset ( new volScalarField ( IOobject ( this->owner().name() + ":massEscape", mesh.time().name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), mesh, dimensionedScalar(dimMass, 0) ) ); } return massEscapePtr_(); } template<class CloudType> Foam::volScalarField& Foam::LocalInteraction<CloudType>::massStick() { if (!massStickPtr_.valid()) { const fvMesh& mesh = this->owner().mesh(); massStickPtr_.reset ( new volScalarField ( IOobject ( this->owner().name() + ":massStick", mesh.time().name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), mesh, dimensionedScalar(dimMass, 0) ) ); } return massStickPtr_(); } template<class CloudType> bool Foam::LocalInteraction<CloudType>::correct ( typename CloudType::parcelType& p, const polyPatch& pp, bool& keepParticle ) { const label patchi = pp.index(); if (isA<processorPolyPatch>(pp)) { return false; } switch (patchInteractionTypes_[patchi]) { case PatchInteractionModel<CloudType>::itNone: { return false; } case PatchInteractionModel<CloudType>::itEscape: { const scalar dm = p.mass()*p.nParticle(); keepParticle = false; p.moving() = false; p.U() = Zero; nEscape_[patchi] ++; massEscape_[patchi] += dm; if (writeFields_) { const label patchFacei = pp.whichFace(p.face()); massEscape().boundaryFieldRef()[patchi][patchFacei] += dm; } return true; } case PatchInteractionModel<CloudType>::itStick: { const scalar dm = p.mass()*p.nParticle(); keepParticle = true; p.moving() = false; p.U() = Zero; nStick_[patchi] ++; massStick_[patchi] += dm; if (writeFields_) { const label patchFacei = pp.whichFace(p.face()); massStick().boundaryFieldRef()[patchi][patchFacei] += dm; } return true; } case PatchInteractionModel<CloudType>::itRebound: { keepParticle = true; p.moving() = true; vector nw, Up; this->owner().patchData(p, pp, nw, Up); // Make motion relative to patch velocity p.U() -= Up; const scalar Un = p.U() & nw; const vector Ut = p.U() - Un*nw; if (Un > 0) { p.U() -= (1 + patchEs_[patchi])*Un*nw; } p.U() -= patchMus_[patchi]*Ut; // Return velocity to global space p.U() += Up; return true; } default: { return false; } } return false; } template<class CloudType> void Foam::LocalInteraction<CloudType>::info(Ostream& os) { const polyBoundaryMesh& patches = this->owner().mesh().boundaryMesh(); // Determine the number of non-processor patches label nPatches = patches.size(); for (; isA<processorPolyPatch>(patches[nPatches - 1]); nPatches --); // Retrieve any stored data labelList npe0(nPatches, 0); this->getModelProperty("nEscape", npe0); scalarList mpe0(nPatches, scalar(0)); this->getModelProperty("massEscape", mpe0); labelList nps0(nPatches, 0); this->getModelProperty("nStick", nps0); scalarList mps0(nPatches, scalar(0)); this->getModelProperty("massStick", mps0); // Accumulate current data labelList npe(SubList<label>(nEscape_, nPatches)); Pstream::listCombineGather(npe, plusEqOp<label>()); npe = npe + npe0; scalarList mpe(SubList<scalar>(massEscape_, nPatches)); Pstream::listCombineGather(mpe, plusEqOp<scalar>()); mpe = mpe + mpe0; labelList nps(SubList<label>(nStick_, nPatches)); Pstream::listCombineGather(nps, plusEqOp<label>()); nps = nps + nps0; scalarList mps(SubList<scalar>(massStick_, nPatches)); Pstream::listCombineGather(mps, plusEqOp<scalar>()); mps = mps + mps0; if (logAtWriteTime_) { if (this->writeTime()) { for (label patchi = 0; patchi < nPatches; ++ patchi) { if ( patchInteractionTypes_[patchi] != PatchInteractionModel<CloudType>::itNone ) { os << " Parcel fate (number, mass) : patch " << this->owner().mesh().boundaryMesh()[patchi].name() << nl << " - escape = " << npe[patchi] << ", " << mpe[patchi] << nl << " - stick = " << nps[patchi] << ", " << mps[patchi] << nl; } } } } else { for (label patchi = 0; patchi < nPatches; ++ patchi) { if ( patchInteractionTypes_[patchi] != PatchInteractionModel<CloudType>::itNone ) { os << " Parcel fate (number, mass) : patch " << this->owner().mesh().boundaryMesh()[patchi].name() << nl << " - escape = " << npe[patchi] << ", " << mpe[patchi] << nl << " - stick = " << nps[patchi] << ", " << mps[patchi] << nl; } } } if (this->writeTime()) { this->setModelProperty("nEscape", npe); nEscape_ = 0; this->setModelProperty("massEscape", mpe); massEscape_ = scalar(0); this->setModelProperty("nStick", nps); nStick_ = 0; this->setModelProperty("massStick", mps); massStick_ = scalar(0); } } // ************************************************************************* // LocalInteraction_new.H (4,729 bytes)
/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org \\ / A nd | Copyright (C) 2011-2022 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/>. Class Foam::LocalInteraction Description Patch interaction specified on a patch-by-patch basis \*---------------------------------------------------------------------------*/ #ifndef LocalInteraction_H #define LocalInteraction_H #include "PatchInteractionModel.H" #include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ Class LocalInteraction Declaration \*---------------------------------------------------------------------------*/ template<class CloudType> class LocalInteraction : public PatchInteractionModel<CloudType> { // Private Typedefs //- Interaction type enumeration typedef typename PatchInteractionModel<CloudType>::interactionType interactionType; // Private Data // Interactions //- Patch interaction types List<interactionType> patchInteractionTypes_; //- Patch elasticity coefficients (for rebound) List<scalar> patchEs_; //- Patch restitution coefficients (for rebound) List<scalar> patchMus_; // Counters for particle fates //- Number of parcels escaped List<label> nEscape_; //- Mass of parcels escaped List<scalar> massEscape_; //- Number of parcels stuck to patches List<label> nStick_; //- Mass of parcels stuck to patches List<scalar> massStick_; //- Flag to output data as fields Switch writeFields_; //- Flag to write log at writeTime Switch logAtWriteTime_; //- Mass escape field autoPtr<volScalarField> massEscapePtr_; //- Mass stick field autoPtr<volScalarField> massStickPtr_; public: //- Runtime type information TypeName("localInteraction"); // Constructors //- Construct from dictionary LocalInteraction(const dictionary& dict, CloudType& owner); //- Construct copy from owner cloud and patch interaction model LocalInteraction(const LocalInteraction<CloudType>& pim); //- Construct and return a clone using supplied owner cloud virtual autoPtr<PatchInteractionModel<CloudType>> clone() const { return autoPtr<PatchInteractionModel<CloudType>> ( new LocalInteraction<CloudType>(*this) ); } //- Destructor virtual ~LocalInteraction(); // Member Functions //- Return access to the massEscape field volScalarField& massEscape(); //- Return access to the massStick field volScalarField& massStick(); //- Apply velocity correction // Returns true if particle remains in same cell virtual bool correct ( typename CloudType::parcelType& p, const polyPatch& pp, bool& keepParticle ); // I-O //- Write patch interaction info to stream virtual void info(Ostream& os); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository #include "LocalInteraction.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* // |
|
If you want the logging customised for the convenience of your workflow then you will need to pay for that work. Closed pending funding. |
Date Modified | Username | Field | Change |
---|---|---|---|
2024-11-25 07:35 | nguyenhung97 | New Issue | |
2024-11-25 07:35 | nguyenhung97 | File Added: LocalInteraction_new.C | |
2024-11-25 07:35 | nguyenhung97 | File Added: LocalInteraction_new.H | |
2024-11-26 12:00 | will | Assigned To | => will |
2024-11-26 12:00 | will | Status | new => closed |
2024-11-26 12:00 | will | Resolution | open => no change required |
2024-11-26 12:00 | will | Note Added: 0013477 |