externalCoupledFunctionObjectTemplates.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) 2015 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 i
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 "OSspecific.H"
28 #include "IFstream.H"
29 #include "OFstream.H"
30 #include "volFields.H"
32 #include "mixedFvPatchFields.H"
35 #include "OStringStream.H"
36 #include "globalIndex.H"
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
40 template<class Type>
42 (
43  const UPtrList<const fvMesh>& meshes,
44  const wordRe& groupName,
45  const word& fieldName
46 )
47 {
49  typedef externalCoupledMixedFvPatchField<Type> patchFieldType;
50 
51  wordList regionNames(meshes.size());
52  forAll(meshes, i)
53  {
54  regionNames[i] = meshes[i].dbDir();
55  }
56 
57  // File only opened on master; contains data for all processors, for all
58  // patchIDs.
59  autoPtr<IFstream> masterFilePtr;
60  if (Pstream::master())
61  {
62  const fileName transferFile
63  (
64  groupDir(commsDir_, compositeName(regionNames), groupName)
65  / fieldName + ".in"
66  );
67 
68  if (log_)
69  {
70  Info<< type() << ": reading data from " << transferFile << endl;
71  }
72  masterFilePtr.reset(new IFstream(transferFile));
73 
74  if (!masterFilePtr().good())
75  {
76  FatalIOErrorInFunction(masterFilePtr())
77  << "Cannot open file for region " << compositeName(regionNames)
78  << ", field " << fieldName
79  << exit(FatalIOError);
80  }
81  }
82 
83 
84  label nFound = 0;
85 
86 
87  forAll(meshes, i)
88  {
89  const fvMesh& mesh = meshes[i];
90 
91  if (!mesh.foundObject<volFieldType>(fieldName))
92  {
93  continue;
94  }
95 
96  nFound++;
97 
98  const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName);
99  const typename volFieldType::GeometricBoundaryField& bf =
100  cvf.boundaryField();
101 
102 
103  // Get the patches
104  const labelList patchIDs
105  (
106  mesh.boundaryMesh().patchSet
107  (
108  List<wordRe>(1, groupName)
109  ).sortedToc()
110  );
111 
112  // Handle column-wise reading of patch data. Supports most easy types
113  forAll(patchIDs, i)
114  {
115  label patchI = patchIDs[i];
116 
117  if (isA<patchFieldType>(bf[patchI]))
118  {
119  // Explicit handling of externalCoupledMixed bcs - they
120  // have specialised reading routines.
121 
122  patchFieldType& pf = const_cast<patchFieldType&>
123  (
124  refCast<const patchFieldType>
125  (
126  bf[patchI]
127  )
128  );
129 
130  // Read from master into local stream
131  OStringStream os;
132  readLines
133  (
134  bf[patchI].size(), // number of lines to read
135  masterFilePtr,
136  os
137  );
138 
139  // Pass responsability for all reading over to bc
140  pf.readData(IStringStream(os.str())());
141 
142  // Update the value from the read coefficicient. Bypass any
143  // additional processing by derived type.
144  pf.patchFieldType::evaluate();
145  }
146  else if (isA<mixedFvPatchField<Type> >(bf[patchI]))
147  {
148  // Read columns from file for
149  // value, snGrad, refValue, refGrad, valueFraction
151  readColumns
152  (
153  bf[patchI].size(), // number of lines to read
154  4*pTraits<Type>::nComponents+1, // nColumns: 4*Type+1*scalar
155  masterFilePtr,
156  data
157  );
158 
160  const_cast<mixedFvPatchField<Type>&>
161  (
162  refCast<const mixedFvPatchField<Type> >
163  (
164  bf[patchI]
165  )
166  );
167 
168  // Transfer read data to bc.
169  // Skip value, snGrad
171 
172  Field<Type>& refValue = pf.refValue();
173  for
174  (
175  direction cmpt = 0;
176  cmpt < pTraits<Type>::nComponents;
177  cmpt++
178  )
179  {
180  refValue.replace(cmpt, data[columnI++]);
181  }
182  Field<Type>& refGrad = pf.refGrad();
183  for
184  (
185  direction cmpt = 0;
186  cmpt < pTraits<Type>::nComponents;
187  cmpt++
188  )
189  {
190  refGrad.replace(cmpt, data[columnI++]);
191  }
192  pf.valueFraction() = data[columnI];
193 
194  // Update the value from the read coefficicient. Bypass any
195  // additional processing by derived type.
196  pf.mixedFvPatchField<Type>::evaluate();
197  }
198  else if (isA<fixedGradientFvPatchField<Type> >(bf[patchI]))
199  {
200  // Read columns for value and gradient
202  readColumns
203  (
204  bf[patchI].size(), // number of lines to read
205  2*pTraits<Type>::nComponents, // nColumns: Type
206  masterFilePtr,
207  data
208  );
209 
212  (
213  refCast<const fixedGradientFvPatchField<Type> >
214  (
215  bf[patchI]
216  )
217  );
218 
219  // Transfer gradient to bc
220  Field<Type>& gradient = pf.gradient();
221  for
222  (
223  direction cmpt = 0;
224  cmpt < pTraits<Type>::nComponents;
225  cmpt++
226  )
227  {
228  gradient.replace
229  (
230  cmpt,
232  );
233  }
234 
235  // Update the value from the read coefficicient. Bypass any
236  // additional processing by derived type.
237  pf.fixedGradientFvPatchField<Type>::evaluate();
238  }
239  else if (isA<fixedValueFvPatchField<Type> >(bf[patchI]))
240  {
241  // Read columns for value only
243  readColumns
244  (
245  bf[patchI].size(), // number of lines to read
246  pTraits<Type>::nComponents, // number of columns to read
247  masterFilePtr,
248  data
249  );
250 
251  // Transfer read value to bc
252  Field<Type> value(bf[patchI].size());
253  for
254  (
255  direction cmpt = 0;
256  cmpt < pTraits<Type>::nComponents;
257  cmpt++
258  )
259  {
260  value.replace(cmpt, data[cmpt]);
261  }
262 
264  const_cast<fixedValueFvPatchField<Type>&>
265  (
266  refCast<const fixedValueFvPatchField<Type> >
267  (
268  bf[patchI]
269  )
270  );
271 
272  pf == value;
273 
274  // Update the value from the read coefficicient. Bypass any
275  // additional processing by derived type.
276  pf.fixedValueFvPatchField<Type>::evaluate();
277  }
278  else
279  {
281  << "Unsupported boundary condition " << bf[patchI].type()
282  << " for patch " << bf[patchI].patch().name()
283  << " in region " << mesh.name()
284  << exit(FatalError);
285  }
286 
287  initialised_ = true;
288  }
289  }
290 
291  return nFound > 0;
292 }
293 
294 
295 template<class Type>
298 (
299  const Field<Type>& fld
300 )
301 {
302  // Collect values from all processors
303  List<Field<Type> > gatheredValues(Pstream::nProcs());
304  gatheredValues[Pstream::myProcNo()] = fld;
305  Pstream::gatherList(gatheredValues);
306 
307 
308  tmp<Field<Type> > tresult(new Field<Type>(0));
309  Field<Type>& result = tresult();
310 
311  if (Pstream::master())
312  {
313  // Combine values into single field
314  label globalElemI = 0;
315 
316  forAll(gatheredValues, lstI)
317  {
318  globalElemI += gatheredValues[lstI].size();
319  }
320 
321  result.setSize(globalElemI);
322 
323  globalElemI = 0;
324 
325  forAll(gatheredValues, lstI)
326  {
327  const Field<Type>& sub = gatheredValues[lstI];
328 
329  forAll(sub, elemI)
330  {
331  result[globalElemI++] = sub[elemI];
332  }
333  }
334  }
335 
336  return tresult;
337 }
338 
339 
340 template<class Type>
342 (
343  const UPtrList<const fvMesh>& meshes,
344  const wordRe& groupName,
345  const word& fieldName
346 ) const
347 {
348  typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
349  typedef externalCoupledMixedFvPatchField<Type> patchFieldType;
350 
351  wordList regionNames(meshes.size());
352  forAll(meshes, i)
353  {
354  regionNames[i] = meshes[i].dbDir();
355  }
356 
357  // File only opened on master; contains data for all processors, for all
358  // patchIDs
359  autoPtr<OFstream> masterFilePtr;
360  if (Pstream::master())
361  {
362  const fileName transferFile
363  (
364  groupDir(commsDir_, compositeName(regionNames), groupName)
365  / fieldName + ".out"
366  );
367 
368  if (log_)
369  {
370  Info<< type() << ": writing data to " << transferFile << endl;
371  }
372  masterFilePtr.reset(new OFstream(transferFile));
373 
374  if (!masterFilePtr().good())
375  {
376  FatalIOErrorInFunction(masterFilePtr())
377  << "Cannot open file for region " << compositeName(regionNames)
378  << ", field " << fieldName
379  << exit(FatalIOError);
380  }
381  }
382 
383 
384  bool headerDone = false;
385 
386  label nFound = 0;
387 
388  forAll(meshes, i)
389  {
390  const fvMesh& mesh = meshes[i];
391 
392  if (!mesh.foundObject<volFieldType>(fieldName))
393  {
394  continue;
395  }
396 
397  nFound++;
398 
399  const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName);
400  const typename volFieldType::GeometricBoundaryField& bf =
401  cvf.boundaryField();
402 
403 
404  // Get the patches
405  const labelList patchIDs
406  (
407  mesh.boundaryMesh().patchSet
408  (
409  List<wordRe>(1, groupName)
410  ).sortedToc()
411  );
412 
413  // Handle column-wise writing of patch data. Supports most easy types
414  forAll(patchIDs, i)
415  {
416  label patchI = patchIDs[i];
417 
418  const globalIndex globalFaces(bf[patchI].size());
419 
420  if (isA<patchFieldType>(bf[patchI]))
421  {
422  // Explicit handling of externalCoupledMixed bcs - they
423  // have specialised writing routines
424 
425  const patchFieldType& pf = refCast<const patchFieldType>
426  (
427  bf[patchI]
428  );
429  OStringStream os;
430 
431  // Pass responsibility for all writing over to bc
432  pf.writeData(os);
433 
434  // Collect contributions from all processors and output them on
435  // master
436  if (Pstream::master())
437  {
438  // Output master data first
439  if (!headerDone)
440  {
441  pf.writeHeader(masterFilePtr());
442  headerDone = true;
443  }
444  masterFilePtr() << os.str().c_str();
445 
446  for (label procI = 1; procI < Pstream::nProcs(); procI++)
447  {
448  IPstream fromSlave(Pstream::scheduled, procI);
449  string str(fromSlave);
450  masterFilePtr() << str.c_str();
451  }
452  }
453  else
454  {
455  OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
456  toMaster << os.str();
457  }
458  }
459  else if (isA<mixedFvPatchField<Type> >(bf[patchI]))
460  {
461  const mixedFvPatchField<Type>& pf =
462  refCast<const mixedFvPatchField<Type> >(bf[patchI]);
463 
464  Field<Type> value(gatherAndCombine(pf));
465  Field<Type> snGrad(gatherAndCombine(pf.snGrad()()));
466  Field<Type> refValue(gatherAndCombine(pf.refValue()));
467  Field<Type> refGrad(gatherAndCombine(pf.refGrad()));
468  scalarField valueFraction(gatherAndCombine(pf.valueFraction()));
469 
470  if (Pstream::master())
471  {
472  forAll(refValue, faceI)
473  {
474  masterFilePtr()
475  << value[faceI] << token::SPACE
476  << snGrad[faceI] << token::SPACE
477  << refValue[faceI] << token::SPACE
478  << refGrad[faceI] << token::SPACE
479  << valueFraction[faceI] << nl;
480  }
481  }
482  }
483  else
484  {
485  // Output the value and snGrad
486  Field<Type> value(gatherAndCombine(bf[patchI]));
487  Field<Type> snGrad(gatherAndCombine(bf[patchI].snGrad()()));
488  if (Pstream::master())
489  {
490  forAll(value, faceI)
491  {
492  masterFilePtr()
493  << value[faceI] << token::SPACE
494  << snGrad[faceI] << nl;
495  }
496  }
497  }
498  }
499  }
500 
501  return nFound > 0;
502 }
503 
504 
505 // ************************************************************************* //
volFields.H
Foam::externalCoupledFunctionObject::writeData
void writeData() const
Write data for all regions, all fields.
Definition: externalCoupledFunctionObject.C:653
Foam::fvc::snGrad
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > snGrad(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvcSnGrad.C:45
Foam::mixedFvPatchField::valueFraction
virtual scalarField & valueFraction()
Definition: mixedFvPatchField.H:244
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
externalCoupledMixedFvPatchFields.H
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::mixedFvPatchField::refValue
virtual Field< Type > & refValue()
Definition: mixedFvPatchField.H:224
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:118
Foam::IFstream
Input from file stream.
Definition: IFstream.H:81
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:50
globalIndex.H
Foam::externalCoupledFunctionObject::gatherAndCombine
static tmp< Field< Type > > gatherAndCombine(const Field< Type > &fld)
Helper: append data from all processors onto master.
Foam::mixedFvPatchField::refGrad
virtual Field< Type > & refGrad()
Definition: mixedFvPatchField.H:234
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::fixedGradientFvPatchField::gradient
virtual Field< Type > & gradient()
Return gradient at boundary.
Definition: fixedGradientFvPatchField.H:189
Foam::wordRe
A wordRe is a word, but can also have a regular expression for matching words.
Definition: wordRe.H:74
Foam::fixedValueFvPatchField
This boundary condition supplies a fixed value constraint, and is the base class for a number of othe...
Definition: fixedValueFvPatchField.H:79
Foam::OStringStream::str
string str() const
Return the string.
Definition: OStringStream.H:107
OFstream.H
Foam::mixedFvPatchField::snGrad
virtual tmp< Field< Type > > snGrad() const
Return gradient at boundary.
Definition: mixedFvPatchField.C:176
Foam::externalCoupledMixedFvPatchField
This boundary condition extends the mixed boundary condition with serialisation through.
Definition: externalCoupledMixedFvPatchField.H:69
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::Field< Type >
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
OStringStream.H
Foam::UPtrList
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: UPtrList.H:53
Foam::Field::replace
void replace(const direction, const UList< cmptType > &)
Replace a component field of the field.
IFstream.H
Foam::FatalError
error FatalError
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
fld
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< ' ';}gmvFile<< nl;forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Foam::IStringStream
Input from memory buffer stream.
Definition: IStringStream.H:49
Foam::mixedFvPatchField
This boundary condition provides a base class for 'mixed' type boundary conditions,...
Definition: mixedFvPatchField.H:126
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
mixedFvPatchFields.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::OFstream
Output to file stream.
Definition: OFstream.H:81
fixedGradientFvPatchFields.H
Foam::autoPtr
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::isA
bool isA(const Type &t)
Check if a dynamic_cast to typeid is possible.
Definition: typeInfo.H:134
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::pTraits
Traits class for primitives.
Definition: pTraits.H:50
Foam::OStringStream
Output to memory buffer stream.
Definition: OStringStream.H:49
fixedValueFvPatchFields.H
Foam::direction
unsigned char direction
Definition: direction.H:43
Foam::autoPtr::reset
void reset(T *=0)
If object pointer already set, delete object and set to given.
Definition: autoPtrI.H:114
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:50
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:330
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::type
fileName::Type type(const fileName &)
Return the file type: DIRECTORY or FILE.
Definition: POSIX.C:588
Foam::fixedGradientFvPatchField
This boundary condition supplies a fixed gradient condition, such that the patch values are calculate...
Definition: fixedGradientFvPatchField.H:107
Foam::GeometricField
Generic GeometricField class.
Definition: surfaceFieldsFwd.H:52
Foam::data
Database for solution data, solver performance and other reduced data.
Definition: data.H:52
Foam::externalCoupledFunctionObject::readData
void readData()
Read data for all regions, all fields.
Definition: externalCoupledFunctionObject.C:583
externalCoupledFunctionObject.H
Foam::UPtrList::size
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:31