/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2015-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- 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 . \*---------------------------------------------------------------------------*/ #include "StandardWallInteraction.H" // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // template void Foam::StandardWallInteraction::writeFileHeader(Ostream& os) { PatchInteractionModel::writeFileHeader(os); forAll(nEscape_, patchi) { const word& patchName = mesh_.boundary()[patchi].name(); forAll(nEscape_[patchi], injectori) { const word suffix = Foam::name(injectori); this->writeTabbed(os, patchName + "_nEscape_" + suffix); this->writeTabbed(os, patchName + "_massEscape_" + suffix); this->writeTabbed(os, patchName + "_nStick_" + suffix); this->writeTabbed(os, patchName + "_massStick_" + suffix); } } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template Foam::StandardWallInteraction::StandardWallInteraction ( const dictionary& dict, CloudType& cloud ) : PatchInteractionModel(dict, cloud, typeName), mesh_(cloud.mesh()), interactionType_ ( this->wordToInteractionType(this->coeffDict().getWord("type")) ), e_(0.0), mu_(0.0), nEscape_(mesh_.boundaryMesh().nNonProcessor()), massEscape_(nEscape_.size()), nStick_(nEscape_.size()), massStick_(nEscape_.size()), injIdToIndex_() { const bool outputByInjectorId = this->coeffDict().getOrDefault("outputByInjectorId", false); switch (interactionType_) { case PatchInteractionModel::itOther: { const word interactionTypeName(this->coeffDict().getWord("type")); FatalErrorInFunction << "Unknown interaction result type " << interactionTypeName << ". Valid selections are:" << this->interactionTypeNames_ << endl << exit(FatalError); break; } case PatchInteractionModel::itRebound: { e_ = this->coeffDict().getOrDefault("e", 1.0); mu_ = this->coeffDict().getOrDefault("mu", 0.0); break; } default: {} } // Determine the number of injectors and the injector mapping label nInjectors = 0; if (outputByInjectorId) { for (const auto& inj : cloud.injectors()) { injIdToIndex_.insert(inj.injectorID(), nInjectors++); } } // The normal case, and safety if injector mapping was somehow null. if (injIdToIndex_.empty()) { nInjectors = 1; } forAll(nEscape_, patchi) { nEscape_[patchi].setSize(nInjectors, Zero); massEscape_[patchi].setSize(nInjectors, Zero); nStick_[patchi].setSize(nInjectors, Zero); massStick_[patchi].setSize(nInjectors, Zero); } } template Foam::StandardWallInteraction::StandardWallInteraction ( const StandardWallInteraction& pim ) : PatchInteractionModel(pim), mesh_(pim.mesh_), interactionType_(pim.interactionType_), e_(pim.e_), mu_(pim.mu_), nEscape_(pim.nEscape_), massEscape_(pim.massEscape_), nStick_(pim.nStick_), massStick_(pim.massStick_), injIdToIndex_(pim.injIdToIndex_) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template bool Foam::StandardWallInteraction::correct ( typename CloudType::parcelType& p, const polyPatch& pp, bool& keepParticle ) { vector& U = p.U(); if (isA(pp)) { // Location for storing the stats. const label idx = ( injIdToIndex_.size() ? injIdToIndex_.lookup(p.typeId(), 0) : 0 ); switch (interactionType_) { case PatchInteractionModel::itNone: { return false; } case PatchInteractionModel::itEscape: { keepParticle = false; p.active(false); U = Zero; const scalar dm = p.nParticle()*p.mass(); nEscape_[pp.index()][idx]++; massEscape_[pp.index()][idx] += dm; break; } case PatchInteractionModel::itStick: { keepParticle = true; p.active(false); U = Zero; const scalar dm = p.nParticle()*p.mass(); nStick_[pp.index()][idx]++; massStick_[pp.index()][idx] += dm; break; } case PatchInteractionModel::itRebound: { keepParticle = true; p.active(true); vector nw; vector Up; this->owner().patchData(p, pp, nw, Up); // Calculate motion relative to patch velocity U -= Up; if (mag(Up) > 0 && mag(U) < this->Urmax()) { WarningInFunction << "Particle U the same as patch " << " The particle has been removed" << nl << endl; keepParticle = false; p.active(false); U = Zero; break; } scalar Un = U & nw; vector Ut = U - Un*nw; if (Un > 0) { U -= (1.0 + e_)*Un*nw; } U -= mu_*Ut; // Return velocity to global space U += Up; break; } default: { FatalErrorInFunction << "Unknown interaction type " << this->interactionTypeToWord(interactionType_) << "(" << interactionType_ << ")" << endl << abort(FatalError); } } return true; } return false; } template void Foam::StandardWallInteraction::info() { PatchInteractionModel::info(); labelListList npe0(nEscape_.size()); scalarListList mpe0(nEscape_.size()); labelListList nps0(nEscape_.size()); scalarListList mps0(nEscape_.size()); forAll(nEscape_, patchi) { label lsd = nEscape_[patchi].size(); npe0[patchi].setSize(lsd, Zero); mpe0[patchi].setSize(lsd, Zero); nps0[patchi].setSize(lsd, Zero); mps0[patchi].setSize(lsd, Zero); } this->getModelProperty("nEscape", npe0); this->getModelProperty("massEscape", mpe0); this->getModelProperty("nStick", nps0); this->getModelProperty("massStick", mps0); // Accumulate current data labelListList npe(nEscape_); forAll(npe, i) { Pstream::listGather(npe[i], sumOp