All Classes Namespaces Files Functions Variables Typedefs Friends Macros Groups
leastSquaresStencilOpt.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2019 OpenCFD Ltd.
10  Copyright (C) 2016-2019 ISP RAS (www.ispras.ru) UniCFD Group (www.unicfd.ru)
11 -------------------------------------------------------------------------------
12 License
13  This file is part of QGDsolver library, based on OpenFOAM+.
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22  You should have received a copy of the GNU General Public License
23  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 Class
25  Foam::fvsc::leastSquaresOpt::leastSquaresStencilOpt
26 Description
27  Methods for optimal calculating of directional derivative.
28  With parallel realisation.
29 \*---------------------------------------------------------------------------*/
30 
31 
32 #include "leastSquaresStencilOpt.H"
33 #include "polyMesh.H"
34 #include "fvMesh.H"
35 #include "word.H"
36 #include "IOstream.H"
37 #include "Ostream.H"
38 #include "wedgeFvPatch.H"
39 #include "symmetryPlaneFvPatch.H"
40 #include "symmetryFvPatch.H"
41 #include "emptyFvPatch.H"
42 #include <HashTable.H>
43 
44 #include "addToRunTimeSelectionTable.H"
45 
46 namespace Foam
47 {
48 namespace fvsc
49 {
50  defineTypeNameAndDebug(leastSquaresOpt,0);
52  (
55  components
56  );
57 }
58 }
59 
60 // constructors
62 :
63  fvscStencil(io),
64  leastSquaresBase(this->mesh_)
65 {
66 }
67 
68 
70 {
71 }
72 
73 Foam::tmp<Foam::surfaceTensorField> Foam::fvsc::leastSquaresOpt::Grad(const volVectorField& iVF)
74 {
75  return Grad(iVF, linearInterpolate(iVF));
76 }
77 
78 //- Calculate gradient of volume vector field on the faces.
79 //
80 // \param iVF Internal vector field.
81 // Allowable values: constant reference to the volVectorField.
82 //
83 // \return Gradient of iVF (tensor field) which was computed on the faces of mesh.
84 Foam::tmp<Foam::surfaceTensorField> Foam::fvsc::leastSquaresOpt::Grad(const volVectorField& iVF, const surfaceVectorField& sVF)
85 {
86 
87  tmp<surfaceTensorField> tgradIVF(0*nf_*fvc::snGrad(iVF));
88  surfaceScalarField tField = sVF.component(0)*0;
89  surfaceTensorField& gradIVF = tgradIVF.ref();
90 
91  faceScalarDer(iVF.primitiveField().component(0),sVF.primitiveField().component(0),0,tField);
92  gradIVF.primitiveFieldRef().replace(0,tField);
93 
94  faceScalarDer(iVF.primitiveField().component(0),sVF.primitiveField().component(0),1,tField);
95  gradIVF.primitiveFieldRef().replace(3,tField);
96 
97  faceScalarDer(iVF.primitiveField().component(0),sVF.primitiveField().component(0),2,tField);
98  gradIVF.primitiveFieldRef().replace(6,tField);
99 
100  faceScalarDer(iVF.primitiveField().component(1),sVF.primitiveField().component(1),0,tField);
101  gradIVF.primitiveFieldRef().replace(1,tField);
102 
103  faceScalarDer(iVF.primitiveField().component(1),sVF.primitiveField().component(1),1,tField);
104  gradIVF.primitiveFieldRef().replace(4,tField);
105 
106  faceScalarDer(iVF.primitiveField().component(1),sVF.primitiveField().component(1),2,tField);
107  gradIVF.primitiveFieldRef().replace(7,tField);
108 
109  faceScalarDer(iVF.primitiveField().component(2),sVF.primitiveField().component(2),0,tField);
110  gradIVF.primitiveFieldRef().replace(2,tField);
111 
112  faceScalarDer(iVF.primitiveField().component(2),sVF.primitiveField().component(2),1,tField);
113  gradIVF.primitiveFieldRef().replace(5,tField);
114 
115  faceScalarDer(iVF.primitiveField().component(2),sVF.primitiveField().component(2),2,tField);
116  gradIVF.primitiveFieldRef().replace(8,tField);
117 
118 
119  forAll(mesh_.boundaryMesh(), ipatch)
120  {
121  bool notConstrain = true;
122  const fvPatch& fvp = mesh_.boundary()[ipatch];
123  if
124  (
125  isA<emptyFvPatch>(fvp) ||
126  isA<wedgeFvPatch>(fvp) ||
127  isA<coupledFvPatch>(fvp) ||
128  isA<symmetryFvPatch>(fvp) ||
129  isA<symmetryPlaneFvPatch>(fvp)
130  )
131  {
132  notConstrain = false;
133  }
134 
135  if (notConstrain)
136  {
137  gradIVF.boundaryFieldRef()[ipatch] = nf_.boundaryField()[ipatch]*iVF.boundaryField()[ipatch].snGrad();
138  }
139  }
140 
141  if(!Pstream::parRun())
142  {
143  return tgradIVF;
144  }
145 
146  List<List3<scalar>> procVfValues(nProcPatches_);
147 
148  formVfValues(iVF,procVfValues);
149 
150  faceScalarDer(procVfValues[0],sVF.component(0),0,tField);
151  gradIVF.boundaryFieldRef().replace(0,tField.boundaryField());
152 
153  faceScalarDer(procVfValues[0],sVF.component(0),1,tField);
154  gradIVF.boundaryFieldRef().replace(3,tField.boundaryField());
155 
156  faceScalarDer(procVfValues[0],sVF.component(0),2,tField);
157  gradIVF.boundaryFieldRef().replace(6,tField.boundaryField());
158 
159  faceScalarDer(procVfValues[1],sVF.component(1),0,tField);
160  gradIVF.boundaryFieldRef().replace(1,tField.boundaryField());
161 
162  faceScalarDer(procVfValues[1],sVF.component(1),1,tField);
163  gradIVF.boundaryFieldRef().replace(4,tField.boundaryField());
164 
165  faceScalarDer(procVfValues[1],sVF.component(1),2,tField);
166  gradIVF.boundaryFieldRef().replace(7,tField.boundaryField());
167 
168  faceScalarDer(procVfValues[2],sVF.component(2),0,tField);
169  gradIVF.boundaryFieldRef().replace(2,tField.boundaryField());
170 
171  faceScalarDer(procVfValues[2],sVF.component(2),1,tField);
172  gradIVF.boundaryFieldRef().replace(5,tField.boundaryField());
173 
174  faceScalarDer(procVfValues[2],sVF.component(2),2,tField);
175  gradIVF.boundaryFieldRef().replace(8,tField.boundaryField());
176 
177  return tgradIVF;
178 
179 };
180 
181 //- Calculate divergence of volume vector field on the faces.
182 //
183 // \param iVF Internal vector field.
184 // Allowable values: constant reference to the volVectorField.
185 //
186 // \return Divergence of iVF (scalar field) which was computed on the faces of mesh.
187 Foam::tmp<Foam::surfaceScalarField> Foam::fvsc::leastSquaresOpt::Div(const volVectorField& iVF)
188 {
189 
190  surfaceVectorField sVF = linearInterpolate(iVF);
191  surfaceScalarField tField = sVF.component(0)*0;
192  tmp<surfaceScalarField> tdivIVF(0*nf_&fvc::snGrad(iVF));
193  surfaceScalarField& divIVF = tdivIVF.ref();
194 
195  faceScalarDer(iVF.primitiveField().component(0),sVF.primitiveField().component(0),0,tField);
196  divIVF.primitiveFieldRef() = tField;
197 
198  faceScalarDer(iVF.primitiveField().component(1),sVF.primitiveField().component(1),1,tField);
199  divIVF.primitiveFieldRef() += tField;
200 
201  faceScalarDer(iVF.primitiveField().component(2),sVF.primitiveField().component(2),2,tField);
202  divIVF.primitiveFieldRef() += tField;
203 
204  forAll(mesh_.boundaryMesh(), ipatch)
205  {
206  bool notConstrain = true;
207  const fvPatch& fvp = mesh_.boundary()[ipatch];
208  if
209  (
210  isA<emptyFvPatch>(fvp) ||
211  isA<wedgeFvPatch>(fvp) ||
212  isA<coupledFvPatch>(fvp) ||
213  isA<symmetryFvPatch>(fvp) ||
214  isA<symmetryPlaneFvPatch>(fvp)
215  )
216  {
217  notConstrain = false;
218  }
219 
220  if (notConstrain)
221  {
222  divIVF.boundaryFieldRef()[ipatch] = nf_.boundaryField()[ipatch] & iVF.boundaryField()[ipatch].snGrad();
223  }
224  }
225 
226  if(!Pstream::parRun())
227  {
228  return tdivIVF;
229  }
230 
231  List<List3<scalar>> procVfValues(nProcPatches_);
232  formVfValues(iVF,procVfValues);
233 
234 
235  faceScalarDer(procVfValues[0],sVF.component(0),0,tField);
236  divIVF.boundaryFieldRef() = tField.boundaryField();
237 
238  faceScalarDer(procVfValues[1],sVF.component(1),1,tField);
239  divIVF.boundaryFieldRef() += tField.boundaryField();
240 
241  faceScalarDer(procVfValues[2],sVF.component(2),2,tField);
242  divIVF.boundaryFieldRef() += tField.boundaryField();
243 
244 
245  return tdivIVF;
246 };
247 
248 //- Calculate divergence of volume tensor field on the faces.
249 //
250 // \param iTF Internal tensor field.
251 // Allowable values: constant reference to the volTensorField.
252 //
253 // \return Divergence of iTF (vector field) which was computed on the faces of mesh.
254 Foam::tmp<Foam::surfaceVectorField> Foam::fvsc::leastSquaresOpt::Div(const volTensorField& iTF)
255 {
257  surfaceTensorField sTF = linearInterpolate(iTF);
258  surfaceScalarField tField = sTF.component(0)*0;
259  tmp<surfaceVectorField> tdivITF(0*nf_*fvc::snGrad(iTF.component(0)));
260  surfaceVectorField& divITF = tdivITF.ref();
261  surfaceScalarField divComp = tField;
262 
263  faceScalarDer(iTF.primitiveField().component(0),sTF.primitiveField().component(0),0,tField);
264  divComp = tField;
265  faceScalarDer(iTF.primitiveField().component(1),sTF.primitiveField().component(1),1,tField);
266  divComp += tField;
267  faceScalarDer(iTF.primitiveField().component(2),sTF.primitiveField().component(2),2,tField);
268  divComp += tField;
269  divITF.primitiveFieldRef().replace(0,divComp);
270 
271  faceScalarDer(iTF.primitiveField().component(3),sTF.primitiveField().component(3),0,tField);
272  divComp = tField;
273  faceScalarDer(iTF.primitiveField().component(4),sTF.primitiveField().component(4),1,tField);
274  divComp += tField;
275  faceScalarDer(iTF.primitiveField().component(5),sTF.primitiveField().component(5),2,tField);
276  divComp += tField;
277  divITF.primitiveFieldRef().replace(1,divComp);
278 
279  faceScalarDer(iTF.primitiveField().component(6),sTF.primitiveField().component(6),0,tField);
280  divComp = tField;
281  faceScalarDer(iTF.primitiveField().component(7),sTF.primitiveField().component(7),1,tField);
282  divComp += tField;
283  faceScalarDer(iTF.primitiveField().component(8),sTF.primitiveField().component(8),2,tField);
284  divComp += tField;
285  divITF.primitiveFieldRef().replace(2,divComp);
286 
287  forAll(mesh_.boundaryMesh(), ipatch)
288  {
289  bool notConstrain = true;
290  const fvPatch& fvp = mesh_.boundary()[ipatch];
291  if
292  (
293  isA<emptyFvPatch>(fvp) ||
294  isA<wedgeFvPatch>(fvp) ||
295  isA<coupledFvPatch>(fvp) ||
296  isA<symmetryFvPatch>(fvp) ||
297  isA<symmetryPlaneFvPatch>(fvp)
298  )
299  {
300  notConstrain = false;
301  }
302 
303  if (notConstrain)
304  {
305  divITF.boundaryFieldRef()[ipatch] = nf_.boundaryField()[ipatch]
306  & iTF.boundaryField()[ipatch].snGrad();
307  }
308  }
309 
310 
311  if (!Pstream::parRun())
312  {
313  return tdivITF;
314  }
315 
316 
317  List<List3<scalar>> procVfValues(nProcPatches_);
318  formVfValues(iTF,procVfValues);
319 
320  faceScalarDer(procVfValues[0],sTF.component(0),0,tField);
321  divComp = tField;
322  faceScalarDer(procVfValues[1],sTF.component(1),1,tField);
323  divComp += tField;
324  faceScalarDer(procVfValues[2],sTF.component(2),2,tField);
325  divComp += tField;
326  divITF.boundaryFieldRef().replace(0,divComp.boundaryField());
327 
328  faceScalarDer(procVfValues[3],sTF.component(3),0,tField);
329  divComp = tField;
330  faceScalarDer(procVfValues[4],sTF.component(4),1,tField);
331  divComp += tField;
332  faceScalarDer(procVfValues[5],sTF.component(5),2,tField);
333  divComp += tField;
334  divITF.boundaryFieldRef().replace(1,divComp.boundaryField());
335 
336  faceScalarDer(procVfValues[6],sTF.component(6),0,tField);
337  divComp = tField;
338  faceScalarDer(procVfValues[7],sTF.component(7),1,tField);
339  divComp += tField;
340  faceScalarDer(procVfValues[8],sTF.component(8),2,tField);
341  divComp += tField;
342  divITF.boundaryFieldRef().replace(2,divComp.boundaryField());
343 
344  return tdivITF;
345 }
346 
347 //
348 //END-OF-FILE
349 //
350 
351 
void formVfValues(const volScalarField &iF, List3< scalar > &procVfValues)
tmp< surfaceScalarField > Div(const volVectorField &iVF)
Calculate divergence of volume vector field on the faces.
tmp< surfaceVectorField > Grad(const volScalarField &iF)
Calculate gradient of volume scalar function on the faces.
addToRunTimeSelectionTable(fvscStencil, GaussVolPoint, components)
surfaceVectorField nf_
Definition: fvscStencil.H:54
const fvMesh & mesh_
Definition: fvscStencil.H:44
forAll(Y, i)
Definition: QGDYEqn.H:36
fvscStencil(const IOobject &io)
Construct from components.
virtual tmp< surfaceVectorField > Grad(const volScalarField &vF)
Definition: fvscStencil.H:118
leastSquaresOpt(const IOobject &)
Construct from IOobject. Optional flag for if IOobject is the.
defineTypeNameAndDebug(fvscStencil, 0)