calcForcePerS.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2 
3  DAFoam : Discrete Adjoint with OpenFOAM
4  Version : v4
5 
6  Description:
7  Calculating force per surface area. This will be used to plot the
8  spanwise force distribution
9 
10 \*---------------------------------------------------------------------------*/
11 
12 #include "fvCFD.H"
13 #include "argList.H"
14 #include "autoPtr.H"
15 #include "Time.H"
16 #include "timeSelector.H"
17 #include "TimePaths.H"
18 #include "ListOps.H"
19 #include "fvMesh.H"
20 #include "OFstream.H"
21 #include "simpleControl.H"
22 #include "fvOptions.H"
23 #include "singlePhaseTransportModel.H"
24 
25 using namespace Foam;
26 
27 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
28 
29 int main(int argc, char* argv[])
30 {
31  Info << "Computing forces...." << endl;
32 
33  argList::addOption(
34  "patchNames",
35  "'(wing)'",
36  "List of patch names to compute");
37 
38  argList::addOption(
39  "time",
40  "1000",
41  "Time instance to compute, if not provided runs all times");
42 
43  argList::addOption(
44  "rho",
45  "1.0",
46  "Freestream density");
47 
48 #include "setRootCase.H"
49 #include "createTime.H"
50 
51  if (!args.optionFound("time"))
52  {
53  Info << "Time not set, running all times." << endl;
54  }
55 
56  // Create the processor databases
57  autoPtr<TimePaths> timePaths;
58  timePaths = autoPtr<TimePaths>::New(args.rootPath(), args.caseName());
59 
60  const instantList timeDirs(timeSelector::select(timePaths->times(), args));
61 
62  List<wordRe> patchNames;
63  if (args.optionFound("patchNames"))
64  {
65  patchNames = wordReList(args.optionLookup("patchNames")());
66  }
67  else
68  {
69  Info << "patchNames not set! Exit." << endl;
70  return 1;
71  }
72 
73  scalar rho = 1.0;
74  if (args.optionFound("rho"))
75  {
76  rho = readScalar(args.optionLookup("rho")());
77  }
78  else
79  {
80  Info << "Density not set! Defaulting to 1.0." << endl;
81  }
82 
83  forAll(timeDirs, iTime)
84  {
85  runTime.setTime(timeDirs[iTime].value(), 0);
86 
87 #include "createMesh.H"
88 #include "createFields.H"
89 
90  // Initialize surface field for face-centered forces
91  volVectorField forcePerS(
92  IOobject(
93  "forcePerS",
94  runTime.timeName(),
95  mesh,
96  IOobject::NO_READ,
97  IOobject::NO_WRITE),
98  mesh,
99  dimensionedVector("forcePerS", dimensionSet(1, -1, -2, 0, 0, 0, 0), vector::zero),
100  fixedValueFvPatchScalarField::typeName);
101 
102  // this code is pulled from:
103  // src/functionObjects/forcces/forces.C
104  // modified slightly
105  vector forces(vector::zero);
106 
107  const surfaceVectorField::Boundary& Sfb = mesh.Sf().boundaryField();
108  const surfaceScalarField::Boundary& magSfb = mesh.magSf().boundaryField();
109 
110  volSymmTensorField devRhoReff(
111  IOobject(
112  IOobject::groupName("devRhoReff", U.group()),
113  mesh.time().timeName(),
114  mesh,
115  IOobject::NO_READ,
116  IOobject::NO_WRITE),
117  -nuEff * dev(twoSymm(fvc::grad(U))));
118 
119  const volSymmTensorField::Boundary& devRhoReffb = devRhoReff.boundaryField();
120 
121  vector totalForce(vector::zero);
122  forAll(patchNames, cI)
123  {
124  // get the patch id label
125  label patchI = mesh.boundaryMesh().findPatchID(patchNames[cI]);
126  if (patchI < 0)
127  {
128  Info << "ERROR: Patch name " << patchNames[cI] << " not found in constant/polyMesh/boundary! Exit!" << endl;
129  return 1;
130  }
131  // create a shorter handle for the boundary patch
132  const fvPatch& patch = mesh.boundary()[patchI];
133  // normal force
134  vectorField fN(Sfb[patchI] * p.boundaryField()[patchI] * rho);
135  // tangential force
136  vectorField fT(Sfb[patchI] & devRhoReffb[patchI] * rho);
137  // sum them up
138  forAll(patch, faceI)
139  {
140  // compute forces
141  forces.x() = fN[faceI].x() + fT[faceI].x();
142  forces.y() = fN[faceI].y() + fT[faceI].y();
143  forces.z() = fN[faceI].z() + fT[faceI].z();
144 
145  // project force direction
146  forcePerS.boundaryFieldRef()[patchI][faceI] = forces / magSfb[patchI][faceI];
147 
148  totalForce.x() += forces.x();
149  totalForce.y() += forces.y();
150  totalForce.z() += forces.z();
151  }
152  }
153  forcePerS.write();
154 
155  Info << "Total force: " << totalForce << endl;
156 
157  Info << "Computing forces.... Completed!" << endl;
158  }
159  return 0;
160 }
161 
162 // ************************************************************************* //
U
volVectorField & U
Definition: createRefsPimpleDyM.H:7
mesh
fvMesh & mesh
Definition: createRefsHeatTransfer.H:4
p
volScalarField & p
Definition: createRefsPimpleDyM.H:6
main
int main(int argc, char *argv[])
Definition: calcForcePerS.C:29
Foam
Definition: checkGeometry.C:32
rho
volScalarField & rho
Definition: createRefsRhoPimple.H:8
argc
int argc
Definition: setArgs.H:18
forAll
forAll(nuTilda1, cellI)
Definition: nuTilda1EqnIrkPimple.H:19
createFields.H
args
Foam::argList & args
Definition: setRootCasePython.H:42
runTime
Time & runTime
Definition: createRefsHeatTransfer.H:1
argv
char ** argv
Definition: setArgs.H:26