FreeFOAM The Cross-Platform CFD Toolkit
pressureGradientExplicitSource.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
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 
27 #include <finiteVolume/volFields.H>
28 #include <OpenFOAM/IFstream.H>
29 
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 
32 void Foam::pressureGradientExplicitSource::writeGradP() const
33 {
34  // Only write on output time
35  if (mesh_.time().outputTime())
36  {
37  IOdictionary propsDict
38  (
39  IOobject
40  (
41  sourceName_ + "Properties",
42  mesh_.time().timeName(),
43  "uniform",
44  mesh_,
47  )
48  );
49  propsDict.add("gradient", gradP_);
50  propsDict.write();
51  }
52 }
53 
54 
55 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
56 
57 Foam::pressureGradientExplicitSource::pressureGradientExplicitSource
58 (
59  const word& sourceName,
61 )
62 :
63  sourceName_(sourceName),
64  mesh_(U.mesh()),
65  U_(U),
66  dict_
67  (
68  IOobject
69  (
70  sourceName + "Properties",
71  mesh_.time().constant(),
72  mesh_,
75  )
76  ),
77  Ubar_(dict_.lookup("Ubar")),
78  gradPini_(dict_.lookup("gradPini")),
79  gradP_(gradPini_),
80  flowDir_(Ubar_/mag(Ubar_)),
81  cellSource_(dict_.lookup("cellSource")),
82  cellSelector_
83  (
85  (
86  cellSource_,
87  mesh_,
88  dict_.subDict(cellSource_ + "Coeffs")
89  )
90  ),
91  selectedCellSet_
92  (
93  mesh_,
94  sourceName_ + "CellSet",
95  mesh_.nCells()/10 + 1 // Reasonable size estimate.
96  )
97 {
98  // Create the cell set
99  cellSelector_->applyToSet
100  (
102  selectedCellSet_
103  );
104 
105  // Give some feedback
106  Info<< " Selected "
107  << returnReduce(selectedCellSet_.size(), sumOp<label>())
108  << " cells" << endl;
109 
110  // Read the initial pressure gradient from file if it exists
111  IFstream propsFile
112  (
113  mesh_.time().timeName()/"uniform"/(sourceName_ + "Properties")
114  );
115 
116  if (propsFile.good())
117  {
118  Info<< " Reading pressure gradient from file" << endl;
120  propsDict.lookup("gradient") >> gradP_;
121  }
122 
123  Info<< " Initial pressure gradient = " << gradP_ << nl << endl;
124 }
125 
126 
127 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
128 
131 {
133  (
135  (
136  IOobject
137  (
138  sourceName_,
139  mesh_.time().timeName(),
140  mesh_,
143  ),
144  mesh_,
145  dimensionedVector("zero", gradP_.dimensions(), vector::zero)
146  )
147  );
148 
149  DimensionedField<vector, volMesh>& sourceField = tSource();
150 
151  forAllConstIter(cellSet, selectedCellSet_, iter)
152  {
153  label cellI = iter.key();
154 
155  sourceField[cellI] = flowDir_*gradP_.value();
156  }
157 
158  return tSource;
159 }
160 
161 
163 {
164  const volScalarField& rUA =
165  mesh_.lookupObject<volScalarField>("(1|A(" + U_.name() + "))");
166 
167  // Integrate flow variables over cell set
168  scalar volTot = 0.0;
169  scalar magUbarAve = 0.0;
170  scalar rUAave = 0.0;
171  forAllConstIter(cellSet, selectedCellSet_, iter)
172  {
173  label cellI = iter.key();
174 
175  scalar volCell = mesh_.V()[cellI];
176  volTot += volCell;
177 
178  magUbarAve += (flowDir_ & U_[cellI])*volCell;
179  rUAave += rUA[cellI]*volCell;
180  }
181 
182  // Collect across all processors
183  reduce(volTot, sumOp<scalar>());
184  reduce(magUbarAve, sumOp<scalar>());
185  reduce(rUAave, sumOp<scalar>());
186 
187  // Volume averages
188  magUbarAve /= volTot;
189  rUAave /= volTot;
190 
191  // Calculate the pressure gradient increment needed to adjust the average
192  // flow-rate to the desired value
193  scalar gradPplus = (mag(Ubar_) - magUbarAve)/rUAave;
194 
195  // Apply correction to velocity field
196  forAllConstIter(cellSet, selectedCellSet_, iter)
197  {
198  label cellI = iter.key();
199  U_[cellI] += flowDir_*rUA[cellI]*gradPplus;
200  }
201 
202  // Update pressure gradient
203  gradP_.value() += gradPplus;
204 
205  Info<< "Uncorrected Ubar = " << magUbarAve << tab
206  << "Pressure gradient = " << gradP_.value() << endl;
207 
208  writeGradP();
209 }
210 
211 
212 // ************************ vim: set sw=4 sts=4 et: ************************ //