forcing.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2017-2023 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "forcing.H"
27 #include "fvMatrix.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34 namespace fv
35 {
37 }
38 }
39 
40 
41 // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
42 
44 {
45  lambda_ =
47  (
48  lambda_.name(),
50  coeffs().lookup(lambda_.name())
51  );
52 
55  (
58  coeffs().lookupOrDefault(lambdaBoundary_.name(), 0.0)
59  );
60 
61  const bool foundScale = coeffs().found("scale");
62  const bool foundOgn = coeffs().found("origin");
63  const bool foundDir = coeffs().found("direction");
64  const bool foundOgns = coeffs().found("origins");
65  const bool foundDirs = coeffs().found("directions");
66  const bool foundAll =
67  foundScale
68  && (
69  (foundOgn && foundDir && !foundOgns && !foundDirs)
70  || (!foundOgn && !foundDir && foundOgns && foundDirs)
71  );
72  const bool foundAny =
73  foundScale || foundOgn || foundDir || foundOgns || foundDirs;
74 
75  if (!foundAll)
76  {
78  origins_.clear();
80  }
81 
82  if (foundAll)
83  {
84  scale_ = Function1<scalar>::New("scale", coeffs());
85  if (foundOgn)
86  {
87  origins_.setSize(1);
89  coeffs().lookup("origin") >> origins_.last();
90  coeffs().lookup("direction") >> directions_.last();
91  }
92  else
93  {
94  coeffs().lookup("origins") >> origins_;
95  coeffs().lookup("directions") >> directions_;
96 
97  if
98  (
99  origins_.size() == 0
100  || directions_.size() == 0
101  || origins_.size() != directions_.size()
102  )
103  {
105  << "The same, non-zero number of origins and "
106  << "directions must be provided" << exit(FatalError);
107  }
108  }
109  forAll(directions_, i)
110  {
111  directions_[i] /= mag(directions_[i]);
112  }
113  }
114 
115  if (!foundAll && foundAny)
116  {
118  << "The scaling specification is incomplete. \"scale\", "
119  << "\"origin\" and \"direction\" (or \"origins\" and "
120  << "\"directions\"), must all be specified in order to scale "
121  << "the forcing. The forcing will be applied uniformly across "
122  << "the cell set." << endl << endl;
123  }
124 }
125 
126 
128 {
130  (
132  (
133  typedName("scale"),
134  mesh(),
135  dimensionedScalar(dimless, scale_.valid() ? 0 : 1)
136  )
137  );
138 
139  scalarField& scale = tscale.ref();
140 
141  forAll(origins_, i)
142  {
143  const vectorField& c = mesh().cellCentres();
144  const scalarField x((c - origins_[i]) & directions_[i]);
145  scale = max(scale, scale_->value(x));
146  }
147 
148  // Write out the force coefficient for debugging
149  if (debug && mesh().time().writeTime())
150  {
151  tscale->write();
152  }
153 
154  return tscale;
155 }
156 
157 
159 (
160  const volScalarField::Internal& scale
161 ) const
162 {
164  (
165  volScalarField::Internal::New(typedName("forceCoeff"), lambda_*scale)
166  );
167 
168  // Damp the cells adjacent to the boundary with lambdaBoundary if specified
169  if (lambdaBoundary_.value() > 0)
170  {
171  const fvBoundaryMesh& bm = mesh().boundary();
172 
173  forAll(bm, patchi)
174  {
175  if (!bm[patchi].coupled())
176  {
177  UIndirectList<scalar>(tforceCoeff.ref(), bm[patchi].faceCells())
178  = lambdaBoundary_.value()
179  *Field<scalar>(scale, bm[patchi].faceCells());
180  }
181  }
182  }
183 
184  // Write out the force coefficient for debugging
185  if (debug && mesh().time().writeTime())
186  {
187  tforceCoeff->write();
188  }
189 
190  return tforceCoeff;
191 }
192 
193 
195 {
196  return forceCoeff(scale());
197 }
198 
199 
200 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
201 
203 (
204  const word& name,
205  const word& modelType,
206  const fvMesh& mesh,
207  const dictionary& dict
208 )
209 :
210  fvModel(name, modelType, mesh, dict),
211  lambda_("lambda", dimless/dimTime, NaN),
212  lambdaBoundary_("lambdaBoundary", dimless/dimTime, 0.0),
213  scale_(nullptr),
214  origins_(),
215  directions_()
216 {
217  readCoeffs();
218 }
219 
220 
221 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
222 
224 {
225  if (fvModel::read(dict))
226  {
227  readCoeffs();
228  return true;
229  }
230  else
231  {
232  return false;
233  }
234 }
235 
236 
237 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
static tmp< DimensionedField< Type, GeoMesh > > New(const word &name, const Mesh &mesh, const dimensionSet &, const Field< Type > &)
Return a temporary field constructed from name, mesh,.
static autoPtr< Function1< Type > > New(const word &name, const dictionary &dict)
Selector.
Definition: Function1New.C:32
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:125
void setSize(const label)
Reset size of List.
Definition: List.C:281
T & last()
Return the last element of the list.
Definition: UListI.H:128
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:860
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:659
const dimensionSet & dimensions() const
Return const reference to dimensions.
const word & name() const
Return const reference to name.
Foam::fvBoundaryMesh.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:101
Finite volume model abstract base class.
Definition: fvModel.H:59
const dictionary & coeffs() const
Return dictionary.
Definition: fvModelI.H:40
virtual bool read(const dictionary &dict)
Read source dictionary.
Definition: fvModel.C:187
Base fvModel for forcing functions.
Definition: forcing.H:59
void readCoeffs()
Non-virtual read.
Definition: forcing.C:43
vectorField directions_
Directions of increasing scaling coordinate.
Definition: forcing.H:77
dimensionedScalar lambda_
Damping coefficient [1/s].
Definition: forcing.H:65
vectorField origins_
Origins of the scaling coordinate.
Definition: forcing.H:74
dimensionedScalar lambdaBoundary_
Optional boundary damping coefficient [1/s].
Definition: forcing.H:68
forcing(const word &name, const word &modelType, const fvMesh &mesh, const dictionary &dict)
Construct from components.
Definition: forcing.C:203
virtual bool read(const dictionary &dict)
Read dictionary.
Definition: forcing.C:223
tmp< volScalarField::Internal > forceCoeff() const
Return the force coefficient.
Definition: forcing.C:194
tmp< volScalarField::Internal > scale() const
Return the scale distribution.
Definition: forcing.C:127
autoPtr< Function1< scalar > > scale_
The scaling function.
Definition: forcing.H:71
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:181
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
label patchi
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionedScalar c
Speed of light in a vacuum.
defineTypeNameAndDebug(bound, 0)
static Type NaN()
Return a primitive with all components set to NaN.
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
const dimensionSet dimless
const dimensionSet dimTime
dimensioned< scalar > mag(const dimensioned< Type > &)
word typedName(Name name)
Return the name of the object within the given type.
Definition: typeInfo.H:149
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
error FatalError
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
labelList fv(nPoints)
dictionary dict