DAFvSourceActuatorPoint.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2 
3  DAFoam : Discrete Adjoint with OpenFOAM
4  Version : v3
5 
6 \*---------------------------------------------------------------------------*/
7 
9 
10 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
11 
12 namespace Foam
13 {
14 
15 defineTypeNameAndDebug(DAFvSourceActuatorPoint, 0);
16 addToRunTimeSelectionTable(DAFvSource, DAFvSourceActuatorPoint, dictionary);
17 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
18 
20  const word modelType,
21  const fvMesh& mesh,
22  const DAOption& daOption,
23  const DAModel& daModel,
24  const DAIndex& daIndex)
25  : DAFvSource(modelType, mesh, daOption, daModel, daIndex)
26 {
27  printIntervalUnsteady_ = daOption.getOption<label>("printIntervalUnsteady");
28 }
29 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
30 
32 {
33  /*
34  Description:
35  Compute the actuator point source term. We support two types of smooth functions:
36 
37  1. Hyperbolic:
38  thrust = xT*yT*zT where xT is
39  xT = tanh( eps*(meshCX-actCX+0.5*actSX) ) - tanh( eps*(meshCX-actCX-0.5*actSX) )
40  if the mesh cell center is within the actuator box, xT~2 other wise xT~0
41  eps is a parameter to smooth the distribution
42 
43  2. Gaussian:
44  We use a 2D Gaussian function for thrust source distribution:
45  thrust = 1/(2*pi*eps^2)*e^{-d^2/(2*eps^2)} where d is the
46  distance between the cell center and actuator source center
47 
48  NOTE: this option has some issues for U field... it has many spikes
49 
50  Example:
51  An example of the fvSource in pyOptions in pyDAFoam can be
52  defOptions =
53  {
54  "fvSource"
55  {
56  "line1"
57  {
58  "type": "actuatorPoint",
59  "smoothFunction": "hyperbolic",
60  "center": [0.0, 0.0, 0.0], # center and size define a rectangular
61  "size": [0.5, 0.3, 0.5],
62  "amplitude": [0.0, 1.0, 0.0],
63  "phase": 0.0,
64  "thrustDirIdx": 0,
65  "periodicity": 1.0,
66  "eps": 1.0,
67  "scale": 1.0 # scale the source such the integral equals desired thrust
68  },
69  "line2"
70  {
71  "type": "actuatorDisk",
72  "smoothFunction": "gaussian",
73  "center": [0.0, 0.0, 0.0],
74  "amplitude": [0.0, 1.0, 0.0],
75  "phase": 1.0,
76  "thrustDirIdx": 0,
77  "periodicity": 1.0,
78  "eps": 1.0,
79  "scale": 1.0 # scale the source such the integral equals desired thrust
80  }
81  }
82  }
83  */
84 
85  forAll(fvSource, idxI)
86  {
87  fvSource[idxI] = vector::zero;
88  }
89 
90  dictionary fvSourceSubDict = daOption_.getAllOptions().subDict("fvSource");
91 
92  // loop over all the cell indices for all actuator points
93  forAll(fvSourceSubDict.toc(), idxI)
94  {
95 
96  // name of this point model
97  word pointName = fvSourceSubDict.toc()[idxI];
98 
99  // sub dictionary with all parameters for this disk
100  dictionary pointSubDict = fvSourceSubDict.subDict(pointName);
101 
102  word smoothFunction = pointSubDict.get<word>("smoothFunction");
103 
104  if (smoothFunction == "hyperbolic")
105  {
106  // now read in all parameters for this actuator point
107  scalarList center1;
108  scalarList size1;
109  scalarList amp1;
110  pointSubDict.readEntry<scalarList>("center", center1);
111  pointSubDict.readEntry<scalarList>("size", size1);
112  pointSubDict.readEntry<scalarList>("amplitude", amp1);
113  vector center = {center1[0], center1[1], center1[2]};
114  vector size = {size1[0], size1[1], size1[2]};
115  vector amp = {amp1[0], amp1[1], amp1[2]};
116  scalar period = pointSubDict.get<scalar>("periodicity");
117  scalar eps = pointSubDict.get<scalar>("eps");
118  scalar scale = pointSubDict.get<scalar>("scale");
119  label thrustDirIdx = pointSubDict.get<label>("thrustDirIdx");
120  scalar phase = pointSubDict.get<scalar>("phase");
121 
122  scalar t = mesh_.time().timeOutputValue();
123  center += amp * sin(constant::mathematical::twoPi * t / period + phase);
124 
125  scalar xTerm, yTerm, zTerm, s;
126  scalar thrustTotal = 0.0;
127  forAll(mesh_.C(), cellI)
128  {
129  const vector& meshC = mesh_.C()[cellI];
130  xTerm = (tanh(eps * (meshC[0] + 0.5 * size[0] - center[0])) - tanh(eps * (meshC[0] - 0.5 * size[0] - center[0])));
131  yTerm = (tanh(eps * (meshC[1] + 0.5 * size[1] - center[1])) - tanh(eps * (meshC[1] - 0.5 * size[1] - center[1])));
132  zTerm = (tanh(eps * (meshC[2] + 0.5 * size[2] - center[2])) - tanh(eps * (meshC[2] - 0.5 * size[2] - center[2])));
133 
134  s = xTerm * yTerm * zTerm;
135  // here we need to use += for multiple actuator points
136  fvSource[cellI][thrustDirIdx] += s * scale;
137 
138  thrustTotal += s * scale * mesh_.V()[cellI];
139  }
140  reduce(thrustTotal, sumOp<scalar>());
141 
142  if (daOption_.getOption<word>("runStatus") == "solvePrimal")
143  {
144  if (mesh_.time().timeIndex() % printIntervalUnsteady_ == 0 || mesh_.time().timeIndex() == 0)
145  {
146  Info << "Actuator point source: " << pointName << endl;
147  Info << "Total thrust source: " << thrustTotal << endl;
148  }
149  }
150  }
151  else if (smoothFunction == "gaussian")
152  {
153  // now read in all parameters for this actuator point
154  scalarList center1;
155  scalarList amp1;
156  pointSubDict.readEntry<scalarList>("center", center1);
157  pointSubDict.readEntry<scalarList>("amplitude", amp1);
158  vector center = {center1[0], center1[1], center1[2]};
159  vector amp = {amp1[0], amp1[1], amp1[2]};
160  scalar period = pointSubDict.get<scalar>("periodicity");
161  scalar eps = pointSubDict.get<scalar>("eps");
162  scalar scale = pointSubDict.get<scalar>("scale");
163  label thrustDirIdx = pointSubDict.get<label>("thrustDirIdx");
164  scalar phase = pointSubDict.get<scalar>("phase");
165 
166  scalar t = mesh_.time().timeOutputValue();
167  center += amp * sin(constant::mathematical::twoPi * t / period + phase);
168 
169  scalar thrustTotal = 0.0;
170  scalar coeff = 1.0 / constant::mathematical::twoPi / eps / eps;
171  forAll(mesh_.C(), cellI)
172  {
173  const vector& meshC = mesh_.C()[cellI];
174  scalar d = mag(meshC - center);
175  scalar s = coeff * exp(-d * d / 2.0 / eps / eps);
176  // here we need to use += for multiple actuator points
177  fvSource[cellI][thrustDirIdx] += s * scale;
178  thrustTotal += s * scale * mesh_.V()[cellI];
179  }
180  reduce(thrustTotal, sumOp<scalar>());
181 
182  if (daOption_.getOption<word>("runStatus") == "solvePrimal")
183  {
184  if (mesh_.time().timeIndex() % printIntervalUnsteady_ == 0 || mesh_.time().timeIndex() == 1)
185  {
186  Info << "Actuator point source: " << pointName << endl;
187  Info << "Total thrust source: " << thrustTotal << endl;
188  }
189  }
190  }
191  else
192  {
193  FatalErrorIn("") << "smoothFunction should be either hyperbolic or gaussian" << abort(FatalError);
194  }
195  }
196 
197  fvSource.correctBoundaryConditions();
198 }
199 
200 } // End namespace Foam
201 
202 // ************************************************************************* //
Foam::DAFvSource
Definition: DAFvSource.H:34
Foam::DAFvSourceActuatorPoint::printIntervalUnsteady_
label printIntervalUnsteady_
print interval
Definition: DAFvSourceActuatorPoint.H:33
forAll
forAll(pseudoP.boundaryField(), patchI)
Definition: solvePseudoPEqn.H:10
Foam::DAFvSource::daOption_
const DAOption & daOption_
DAOption object.
Definition: DAFvSource.H:53
Foam::DAFvSourceActuatorPoint::DAFvSourceActuatorPoint
DAFvSourceActuatorPoint(const word modelType, const fvMesh &mesh, const DAOption &daOption, const DAModel &daModel, const DAIndex &daIndex)
Definition: DAFvSourceActuatorPoint.C:19
Foam::DAOption
Definition: DAOption.H:29
daOption
DAOption daOption(mesh, pyOptions_)
Foam::DAFvSourceActuatorPoint::calcFvSource
virtual void calcFvSource(volVectorField &fvSource)
compute the FvSource term
Definition: DAFvSourceActuatorPoint.C:31
Foam::DAOption::getOption
classType getOption(const word key) const
get an option from subDict and key
Definition: DAOption.H:92
fvSource
volScalarField & fvSource
Definition: createRefsHeatTransfer.H:7
Foam::DAOption::getAllOptions
const dictionary & getAllOptions() const
return a reference of allOptions_ dictionary
Definition: DAOption.H:56
mesh
fvMesh & mesh
Definition: createRefsHeatTransfer.H:4
Foam::DAIndex
Definition: DAIndex.H:32
DAFvSourceActuatorPoint.H
Foam::DAModel
Definition: DAModel.H:59
Foam
Definition: multiFreqScalarFvPatchField.C:144
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(DAFvSource, 0)
Foam::DAFvSource::mesh_
const fvMesh & mesh_
fvMesh
Definition: DAFvSource.H:50
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(DAFvSource, DAFvSourceActuatorDisk, dictionary)
daModel
DAModel daModel(mesh, daOption)
daIndex
DAIndex daIndex(mesh, daOption, daModel)