fanDirectionLagrangianVectorFieldSource.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) 2025-2026 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 
29 
30 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
31 
34 (
35  const LagrangianFieldSourceBase& field,
36  const dictionary& dict
37 )
38 :
39  field_(field),
40  normal_
41  (
43  (
44  "normal",
45  field.time().userUnits(),
46  dimless,
47  dict
48  )
49  ),
50  thetaInner_
51  (
52  Function1<scalar>::New
53  (
54  "thetaInner",
55  field.time().userUnits(),
56  units::degrees,
57  dict
58  )
59  ),
60  thetaOuter_
61  (
62  Function1<scalar>::New
63  (
64  "thetaOuter",
65  field.time().userUnits(),
66  units::degrees,
67  dict
68  )
69  ),
70  rndGen_
71  (
72  "fanDirectionRndGen",
73  dict,
74  randomGenerator::seed(field.db().name() + ':' + dict.dictName()),
75  false
76  ),
77  timeIndex_(-1)
78 {}
79 
80 
83 (
85  const LagrangianFieldSourceBase& field
86 )
87 :
88  field_(field),
89  normal_(cdlvfs.normal_, false),
90  thetaInner_(cdlvfs.thetaInner_, false),
91  thetaOuter_(cdlvfs.thetaOuter_, false),
92  rndGen_(cdlvfs.rndGen_),
93  timeIndex_(-1)
94 {}
95 
96 
97 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
98 
101 {}
102 
103 
104 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
105 
108 (
109  const LagrangianSubVectorField& axis
110 ) const
111 {
112  const LagrangianSubMesh& subMesh = axis.mesh();
113 
114  // Restart the generator if necessary and set the time index up to date
115  rndGen_.start(timeIndex_ == field_.time().timeIndex());
116  timeIndex_ = field_.time().timeIndex();
117 
118  // Construct a direction in the plane of the fan
119  const tmp<LagrangianSubVectorField> normal =
120  Function1LagrangianFieldSource::value(subMesh, dimless, normal_());
121  const tmp<LagrangianSubVectorField> tangential(axis ^ normal);
122 
123  // Pick a random angle within the fan angles
124  const tmp<LagrangianSubScalarField> tthetaInner =
125  Function1LagrangianFieldSource::value(subMesh, dimless, thetaInner_());
126  const tmp<LagrangianSubScalarField> tthetaOuter =
127  Function1LagrangianFieldSource::value(subMesh, dimless, thetaOuter_());
128  const tmp<LagrangianSubScalarField> tfrac =
130  (
131  "frac",
132  subMesh,
133  dimless,
134  rndGen_.scalarAB(subMesh.size(), -1, 1)
135  );
136  const tmp<LagrangianSubScalarField> tmagFrac = mag(tfrac());
137  const LagrangianSubScalarField theta
138  (
139  (1 - tmagFrac())*tthetaInner
140  + tmagFrac()*tthetaOuter
141  );
142  tmagFrac.clear();
143 
144  // Return the calculated direction
145  return cos(theta)*axis + sign(tfrac)*sin(theta)*tangential;
146 }
147 
148 
150 {
151  writeEntry(os, field_.time().userUnits(), units::none, normal_());
152 
153  writeEntry
154  (
155  os,
156  field_.time().userUnits(),
158  thetaInner_()
159  );
160 
161  writeEntry
162  (
163  os,
164  field_.time().userUnits(),
166  thetaOuter_()
167  );
168 
169  writeEntry(os, "fanDirectionRndGen", rndGen_);
170 }
171 
172 
173 // ************************************************************************* //
Macros for easy insertion into run-time selection tables.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
static tmp< DimensionedField< Type, GeoMesh, PrimitiveField > > New(const word &name, const GeoMesh &mesh, const dimensionSet &, const PrimitiveField< Type > &)
Return a temporary field constructed from name, mesh,.
const GeoMesh & mesh() const
Return mesh.
tmp< LagrangianSubField< Type > > value(const LagrangianSubMesh &subMesh, const Function1< Type > &function) const
Return the source value.
Run-time selectable general function of one variable.
Definition: Function1.H:62
Base class for Lagrangian source conditions.
Mesh that relates to a sub-section of a Lagrangian mesh. This is used to construct fields that relate...
label size() const
Return size.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Mix-in for source conditions that provides a random injection direction between two fan angles.
fanDirectionLagrangianVectorFieldSource(const LagrangianFieldSourceBase &, const dictionary &dict)
Construct from a dictionary.
tmp< LagrangianSubVectorField > direction(const LagrangianSubVectorField &axis) const
Return the value for an instantaneous injection.
Random number generator.
A class for managing temporary objects.
Definition: tmp.H:55
void clear() const
If object pointer points to valid object:
Definition: tmpI.H:253
const dimensionSet dimless
const dimensionSet time
const unitSet none
const unitSet degrees
const dimensionSet & dimless
Definition: dimensions.C:138
dimensionedScalar sign(const dimensionedScalar &ds)
dimensionedScalar sin(const dimensionedScalar &ds)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
void writeEntry(Ostream &os, const word &key, const DimensionedFieldFunction< DimensionedFieldType > &f)
dimensionedScalar cos(const dimensionedScalar &ds)
dictionary dict