cloud.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2025-2026 OpenFOAM Foundation
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 
26 #include "cloud.H"
30 #include "LagrangianFields.H"
31 #include "LagrangianmDdt.H"
32 #include "LagrangianSubFields.H"
33 #include "dimensionedTypes.H"
36 #include "Time.H"
37 #include "fvMesh.H"
38 
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40 
41 namespace Foam
42 {
45 }
46 
47 
48 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
49 
51 (
52  const polyMesh& pMesh,
53  const word& name,
54  const IOobject::readOption readOption,
55  const IOobject::writeOption writeOption
56 )
57 {
58  if (!pMesh.foundObject<LagrangianMesh>(name))
59  {
60  wordList wantedPatchTypes(pMesh.boundary().size());
61 
62  forAll(pMesh.boundary(), patchi)
63  {
64  const polyPatch& pPatch = pMesh.boundary()[patchi];
65 
66  wantedPatchTypes[patchi] =
67  pPatch.constraint()
68  ? pPatch.type()
70  }
71 
72  LagrangianMesh* lMesh =
73  new LagrangianMesh
74  (
75  pMesh,
76  name,
77  wantedPatchTypes,
78  readOption,
80  );
81 
82  lMesh->store();
83  }
84 
85  return pMesh.lookupObjectRef<LagrangianMesh>(name);
86 }
87 
88 
89 #define ACCESS_DERIVED_FIELDS(Type, nullArg) \
90 namespace Foam \
91 { \
92  template<> \
93  PtrList<Foam::CloudDerivedField<Type>>& cloud::derivedFields() const \
94  { \
95  return CAT3(derived, CAPITALIZE(Type), Fields_); \
96  } \
97 }
99 #undef ACCESS_DERIVED_FIELDS
100 
101 
102 void Foam::cloud::clearDerivedFields(const bool final)
103 {
104  #define CLEAR_TYPE_DERIVED_FIELDS(Type, nullArg) \
105  forAll(derivedFields<Type>(), i) \
106  { \
107  derivedFields<Type>()[i].clear(final); \
108  }
110  #undef CLEAR_TYPE_DERIVED_FIELDS
111 }
112 
113 
114 #define ACCESS_AVERAGE_FIELDS(Type, nullArg) \
115 namespace Foam \
116 { \
117  template<> \
118  PtrList<Foam::CloudAverageField<Type>>& cloud::averageFields() const \
119  { \
120  return CAT3(average, CAPITALIZE(Type), Fields_); \
121  } \
122 }
124 #undef ACCESS_AVERAGE_FIELDS
125 
126 
127 void Foam::cloud::removeFromAverageFields(const LagrangianSubMesh& subMesh)
128 {
129  #define REMOVE_FROM_TYPE_AVERAGE_FIELDS(Type, nullArg) \
130  forAll(averageFields<Type>(), i) \
131  { \
132  averageFields<Type>()[i].remove(subMesh); \
133  }
135  #undef REMOVE_FROM_TYPE_AVERAGE_FIELDS
136 }
137 
138 
139 void Foam::cloud::addToAverageFields
140 (
141  const LagrangianSubMesh& subMesh,
142  const bool final
143 )
144 {
145  #define ADD_TO_TYPE_AVERAGE_FIELDS(Type, nullArg) \
146  forAll(averageFields<Type>(), i) \
147  { \
148  averageFields<Type>()[i].add(subMesh, !final); \
149  }
151  #undef ADD_TO_TYPE_AVERAGE_FIELDS
152 }
153 
154 
155 void Foam::cloud::correctAverageFields
156 (
157  const LagrangianSubMesh& subMesh,
158  const bool final
159 )
160 {
161  #define CORRECT_TYPE_AVERAGE_FIELDS(Type, nullArg) \
162  forAll(averageFields<Type>(), i) \
163  { \
164  averageFields<Type>()[i].correct(subMesh, !final); \
165  }
167  #undef CORRECT_TYPE_AVERAGE_FIELDS
168 }
169 
170 
171 void Foam::cloud::clearAverageFields()
172 {
173  #define CLEAR_TYPE_AVERAGE_FIELDS(Type, nullArg) \
174  forAll(averageFields<Type>(), i) \
175  { \
176  averageFields<Type>()[i].clear(true); \
177  }
179  #undef CLEAR_TYPE_AVERAGE_FIELDS
180 }
181 
182 
183 void Foam::cloud::resetAverageFields()
184 {
185  #define RESET_TYPE_AVERAGE_FIELDS(Type, nullArg) \
186  forAll(averageFields<Type>(), i) \
187  { \
188  averageFields<Type>()[i].reset(); \
189  }
191  #undef RESET_TYPE_AVERAGE_FIELDS
192 }
193 
194 
195 Foam::IOobject Foam::cloud::stateIo(const IOobject::readOption r) const
196 {
197  return
198  IOobject
199  (
200  "state",
201  time().name(),
202  mesh(),
203  r,
205  );
206 }
207 
208 
210 Foam::cloud::readStates() const
211 {
212  typeIOobject<LagrangianLabelDynamicField> stateIo
213  (
214  this->stateIo(IOobject::MUST_READ)
215  );
216 
217  return
218  autoPtr<Foam::LagrangianLabelDynamicField>
219  (
220  stateIo.headerOk()
221  ? new LagrangianLabelDynamicField(stateIo, mesh_)
222  : nullptr
223  );
224 }
225 
226 
228 Foam::cloud::initialStates() const
229 {
230  // Return an empty pointer if we have no states stored
231  if (!statePtr_.valid()) return autoPtr<List<LagrangianState>>();
232 
233  // Allocate a list of states
234  autoPtr<List<LagrangianState>> resultPtr
235  (
237  );
238  List<LagrangianState>& result = resultPtr();
239 
240  // Convert from the state labels to state enumerations
241  forAll(mesh_, i)
242  {
243  const LagrangianState s =
244  static_cast<LagrangianState>(statePtr_()[i]);
245 
246  if (s != LagrangianState::none)
247  {
248  result[i] = s;
249  }
250  }
251 
252  return resultPtr;
253 }
254 
255 
256 void Foam::cloud::clearStates()
257 {
258  statePtr_.clear();
259 }
260 
261 
262 bool Foam::cloud::storeStates()
263 {
264  // Determine whether states are needed
265  bool needStates = false;
266 
267  forAll(mesh_.boundary(), patchi)
268  {
269  const LagrangianSubMesh& patchMesh =
270  mesh_.boundary()[patchi].mesh();
271 
272  if (!patchMesh.empty()) needStates = true;
273  }
274 
275  reduce(needStates, orOp<bool>());
276 
277  // Create the state labels field as appropriate
278  if (needStates && !statePtr_.valid())
279  {
280  statePtr_.set
281  (
283  (
284  stateIo(IOobject::NO_READ),
285  mesh_,
286  dimensioned<label>
287  (
289  dimless,
290  static_cast<label>(LagrangianState::none)
291  ),
292  wordList
293  (
294  mesh().boundary().size(),
296  ),
297  wordList::null(),
298  LagrangianModels().modelTypeFieldSourceTypes
299  <
300  LagrangianInjection,
301  noneStateLagrangianLabelFieldSource
302  >()
303  )
304  );
305  }
306 
307  return needStates;
308 }
309 
310 
311 void Foam::cloud::storeStates(const LagrangianSubMesh& subMesh)
312 {
313  const LagrangianState state = groupToState(subMesh.group());
314 
315  forAll(subMesh, subi)
316  {
317  const label i = subMesh.start() + subi;
318 
319  // If this particle is complete, then store the sub-mesh state within
320  // the retained state labels. If it is not complete, then reset its
321  // state so that it continues to be associated with this sub-mesh.
322  if (mesh_.states()[i] == LagrangianState::complete)
323  {
324  statePtr_()[i] = static_cast<label>(state);
325  }
326  else
327  {
328  mesh_.states()[i] = state;
329  }
330  }
331 }
332 
333 
334 Foam::tmp<Foam::LagrangianSubScalarField> Foam::cloud::cellLengthScale
335 (
336  const LagrangianSubMesh& subMesh
337 ) const
338 {
339  return
341  (
342  "cellLengthScale",
343  subMesh,
344  dimLength,
345  scalarField(cellLengthScaleVf_, subMesh.sub(mesh_.celli()))
346  );
347 }
348 
349 
350 void Foam::cloud::track
351 (
353  const scalar maxTimeStepFraction,
354  const scalar maxCellLengthScaleFraction
355 )
356 {
357  const LagrangianSubMesh& subMesh = fraction.mesh();
358 
359  // Initialise tracking to completion over the remaining fraction
360  List<LagrangianState> endState(subMesh.size(), LagrangianState::complete);
361  LagrangianSubScalarField deltaFraction(1 - fraction);
362 
363  // Evaluate the displacement over the entire time-step
364  const LagrangianSubVectorField displacement
365  (
366  time().deltaT()*U(subMesh)
367  );
368 
369  // Limit the track to the maximum allowed fraction of the time-step
370  if (maxTimeStepFraction < 1)
371  {
372  forAll(deltaFraction, subi)
373  {
374  if (deltaFraction[subi] > maxTimeStepFraction)
375  {
376  endState[subi] = LagrangianState::inCell;
377  deltaFraction[subi] = maxTimeStepFraction;
378  }
379  }
380  }
381 
382  // Limit the track to the maximum allowed fraction of the cell length scale
383  if (maxCellLengthScaleFraction < rootGreat)
384  {
385  const LagrangianSubScalarField maxDFraction
386  (
387  maxCellLengthScaleFraction
388  *cellLengthScale(subMesh)
389  /max
390  (
391  mag(displacement),
392  dimensionedScalar(dimLength, rootVSmall)
393  )
394  );
395 
396  forAll(deltaFraction, subi)
397  {
398  if (deltaFraction[subi] > maxDFraction[subi])
399  {
400  endState[subi] = LagrangianState::inCell;
401  deltaFraction[subi] = maxDFraction[subi];
402  }
403  }
404  }
405 
406  // Track the particles
407  switch (tracking)
408  {
409  case trackingType::linear:
410  mesh_.track
411  (
412  endState,
413  LagrangianMesh::linearDisplacement
414  (
415  deltaFraction*displacement
416  ),
417  deltaFraction,
418  fraction
419  );
420  break;
421 
422  case trackingType::parabolic:
423  {
424  mesh_.track
425  (
426  endState,
427  LagrangianMesh::parabolicDisplacement
428  (
429  deltaFraction*displacement,
430  sqr(deltaFraction*time().deltaT())/2*dUdt(subMesh)
431  ),
432  deltaFraction,
433  fraction
434  );
435  break;
436  }
437  }
438 }
439 
440 
441 bool Foam::cloud::writeData(Ostream&) const
442 {
444  return false;
445 }
446 
447 
448 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
449 
451 {
452  clearDerivedFields(true);
453  clearAverageFields();
454 }
455 
456 
457 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
458 
459 namespace Foam
460 {
462  {"linear", "parabolic"};
463 }
464 
465 
466 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
467 
469 :
471  mesh_(mesh),
472  LagrangianModelsPtr_(nullptr),
473  statePtr_(readStates()),
474  cellLengthScaleVf_(mag(cbrt(mesh_.poly().cellVolumes()))),
475  context(context),
476  tracking(cloudTrackingNames[mesh.schemes().lookup<word>("tracking")]),
477  U
478  (
479  IOobject
480  (
481  "U",
482  time().name(),
483  mesh_,
484  IOobject::MUST_READ,
485  IOobject::AUTO_WRITE
486  ),
487  mesh_
488  )
489 {}
490 
491 
493 (
495  const contextType context,
497 )
498 :
500  mesh_(mesh),
501  LagrangianModelsPtr_(nullptr),
502  statePtr_(readStates()),
503  cellLengthScaleVf_(mag(cbrt(mesh_.poly().cellVolumes()))),
504  context(context),
505  tracking(cloudTrackingNames[mesh.schemes().lookup<word>("tracking")]),
506  U
507  (
508  IOobject
509  (
510  "U",
511  time().name(),
512  mesh_,
513  IOobject::READ_IF_PRESENT,
514  IOobject::AUTO_WRITE
515  ),
516  tU
517  )
518 {}
519 
520 
521 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
522 
524 (
525  const polyMesh& pMesh,
526  const word& name,
527  const contextType context,
528  const dictionary& dict,
529  const word& type,
532 )
533 {
534  Info<< indentOrNl << "Selecting " << typeName
535  << " with name " << name
536  << " of type " << type << endl;
537 
538  if (!LagrangianMeshConstructorTablePtr_)
539  {
541  << typeName << "s table is empty"
542  << exit(FatalError);
543  }
544 
545  LagrangianMeshConstructorTable::iterator cstrIter;
546 
547  cstrIter = LagrangianMeshConstructorTablePtr_->find(type);
548 
549  if (cstrIter == LagrangianMeshConstructorTablePtr_->end())
550  {
551  libs.open("lib" + type + typeName.capitalise() + ".so");
552  }
553 
554  cstrIter = LagrangianMeshConstructorTablePtr_->find(type);
555 
556  if (cstrIter == LagrangianMeshConstructorTablePtr_->end())
557  {
559  << "Unknown " << typeName << " type "
560  << type << nl << nl
561  << "Valid " << typeName << "s are :" << endl
562  << LagrangianMeshConstructorTablePtr_->sortedToc()
563  << exit(FatalError);
564  }
565 
566  autoPtr<cloud> cloudPtr
567  (
568  cstrIter()
569  (
570  mesh(pMesh, name, readOption, writeOption),
571  context,
572  dict
573  )
574  );
575 
576  // Ensure LagrangianModels are constructed before time is incremented
577  cloudPtr->LagrangianModels();
578 
579  return cloudPtr;
580 }
581 
582 
583 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
584 
586 {}
587 
588 
589 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
590 
592 {
594 }
595 
596 
598 {
599  if (!LagrangianModelsPtr_)
600  {
601  LagrangianModelsPtr_ = &Foam::LagrangianModels::New(mesh_);
602  }
603 
604  return *LagrangianModelsPtr_;
605 }
606 
607 
608 void Foam::cloud::solve(const bool initial, const bool final)
609 {
610  // Create the functions list
611  cloudFunctionObjectUList functions(*this);
612 
613  // Initial reset of cached objects
614  clearDerivedFields(true);
615  if (!initial || !final)
616  {
617  resetAverageFields();
618  }
619  else
620  {
621  clearAverageFields();
622  }
623 
624  // Reset the fields
625  mesh_.reset(initial, final);
626 
627  Info<< "Solving cloud " << mesh_.name() << ':' << endl << incrIndent;
628 
629  // Get solution controls
630  const scalar maxTimeStepFraction =
631  mesh_.solution().lookup<scalar>("maxTimeStepFraction");
632  const scalar maxCellLengthScaleFraction =
633  mesh_.solution().lookup<scalar>("maxCellLengthScaleFraction");
634  const label nCorrectors = mesh_.solution().lookup<label>("nCorrectors");
635 
636  // Correct the models
638 
639  // Initialise the tracked fraction to zero, representing all particles
640  // being at the start of the time-step
642  (
643  IOobject
644  (
646  time().name(),
647  mesh_
648  ),
649  mesh_,
650  dimensionedScalar("zero", dimless, 0)
651  );
652 
653  // Let the models do any instantaneous modifications, removals and
654  // injections/creations of existing particles
655  const LagrangianSubMesh preModifiedMesh =
656  LagrangianModels().preModify(mesh_);
657  removeFromAverageFields(preModifiedMesh);
658  const LagrangianSubMesh modifiedMesh =
659  LagrangianModels().modify(mesh_, preModifiedMesh);
660  addToAverageFields(modifiedMesh, true);
661 
662  // Do a calculation on modified particles (if necessary)
663  if (reCalculateModified())
664  {
665  removeFromAverageFields(modifiedMesh);
666 
667  const LagrangianSubScalarField zeroDeltaT
668  (
669  IOobject("zeroDeltaT", mesh().time().name(), mesh()),
670  modifiedMesh,
671  dimensionedScalar(dimTime, scalar(0))
672  );
673 
674  addToAverageFields(modifiedMesh, false);
675 
676  LagrangianModels().calculate(zeroDeltaT, true);
677  LagrangianModels().preSource(zeroDeltaT, true);
678  calculate(zeroDeltaT, true);
679  functions.calculate(zeroDeltaT, true);
680  LagrangianModels().postSource(zeroDeltaT, true);
681 
682  correctAverageFields(modifiedMesh, true);
683  }
684 
685  // Construct the object defining the scope of the Lagrangian mesh changes
686  autoPtr<List<LagrangianState>> statesPtr = initialStates();
687  LagrangianMesh::changer changer =
688  statesPtr.valid()
689  ? LagrangianMesh::changer(mesh_, statesPtr())
691  statesPtr.clear();
692 
693  // State information is now in the cloud. Clear the stored state labels so
694  // that they can be re-built (if necessary) by the cloud evolution below.
695  clearStates();
696 
697  // If we have initial states then we need to evaluate the
698  // derived/non-constraint boundary conditions so that any affected
699  // properties are up date. This evaluation of the velocity boundary fields
700  // is what ensures that "stuck" particles move consistently with their
701  // respective patches. In theory, though, it could apply to any field.
702  #define EVAL_TYPE_DERIVED_PATCH_FIELDS(Type, GeoField) \
703  { \
704  HashTable<GeoField<Type>*> fields \
705  ( \
706  mesh_.lookupClass<GeoField<Type>>() \
707  ); \
708  \
709  forAllIter(typename HashTable<GeoField<Type>*>, fields, iter) \
710  { \
711  forAll(mesh_.boundary(), patchi) \
712  { \
713  const LagrangianPatch& patch = mesh_.boundary()[patchi]; \
714  \
715  if \
716  ( \
717  patch.mesh().size() \
718  && !patch.poly().constraint() \
719  ) \
720  { \
721  iter()->boundaryFieldRef()[patchi].evaluate \
722  ( \
723  NullObjectNonConstRef<PstreamBuffers>(), \
724  fraction \
725  ); \
726  } \
727  } \
728  } \
729  }
732  #undef EVAL_TYPE_DERIVED_PATCH_FIELDS
733 
734  // Iterate whilst there are incomplete particles
735  while
736  (
738  (
739  mesh_.sub(LagrangianGroup::complete).size() != mesh_.size(),
740  orOp<bool>()
741  )
742  )
743  {
744  // Internal tracking and calculation
745  {
746  const LagrangianSubMesh internalMesh
747  (
749  );
750 
751  LagrangianSubScalarSubField internalFraction
752  (
753  internalMesh.sub(fraction)
754  );
755 
756  removeFromAverageFields(internalMesh);
757 
758  track
759  (
760  internalFraction,
761  maxTimeStepFraction,
762  maxCellLengthScaleFraction
763  );
764 
765  const LagrangianSubScalarField deltaT
766  (
767  (internalFraction - internalFraction.oldTime())
768  *mesh_.time().deltaT()
769  );
770 
771  addToAverageFields(internalMesh, false);
772 
773  for (label i = 0; i <= nCorrectors; ++ i)
774  {
775  const bool final = i == nCorrectors;
776 
777  LagrangianModels().calculate(deltaT, final);
778  LagrangianModels().preSource(deltaT, final);
779  calculate(deltaT, final);
780  functions.calculate(deltaT, final);
781  LagrangianModels().postSource(deltaT, final);
782 
783  clearDerivedFields(final);
784  correctAverageFields(internalMesh, final);
785  }
786  }
787 
788  // Boundary tracking and calculation (if necessary)
789  if (storeStates())
790  {
791  const labelList subMeshGlobalSizes = mesh_.subMeshGlobalSizes();
792 
793  forAll(mesh_.boundary(), patchi)
794  {
795  static const label onPatchZeroi =
796  static_cast<label>(LagrangianGroup::onPatchZero);
797 
798  if (subMeshGlobalSizes[onPatchZeroi + patchi] <= 0) continue;
799 
800  const LagrangianSubMesh patchMesh
801  (
802  mesh_.boundary()[patchi].mesh()
803  );
804 
805  LagrangianSubScalarSubField patchFraction
806  (
807  patchMesh.sub(fraction)
808  );
809 
810  removeFromAverageFields(patchMesh);
811 
812  track
813  (
814  patchFraction,
815  maxTimeStepFraction,
816  maxCellLengthScaleFraction
817  );
818 
819  storeStates(patchMesh);
820 
821  const LagrangianSubScalarField deltaT
822  (
823  (patchFraction - patchFraction.oldTime())
824  *mesh_.time().deltaT()
825  );
826 
827  addToAverageFields(patchMesh, false);
828 
829  for (label i = 0; i <= nCorrectors; ++ i)
830  {
831  const bool final = i == nCorrectors;
832 
833  LagrangianModels().calculate(deltaT, final);
834  LagrangianModels().preSource(deltaT, final);
835  calculate(deltaT, final);
836  functions.calculate(deltaT, final);
837  LagrangianModels().postSource(deltaT, final);
838 
839  clearDerivedFields(final);
840  correctAverageFields(patchMesh, final);
841  }
842  }
843  }
844 
845  // Intermediate partitioning
846  mesh_.partition();
847  partition();
848 
849  removeFromAverageFields(mesh_.subIncomplete());
850 
851  // Cross the faces
852  functions.preCrossFaces(fraction);
853  mesh_.crossFaces(fraction);
854  functions.postCrossFaces(fraction);
855 
856  addToAverageFields(mesh_.subIncomplete(), true);
857 
858  // Final partitioning
859  mesh_.partition();
860  partition();
861  };
862 
863  Info<< decrIndent;
864 }
865 
866 
868 {
869  mesh_.storePosition();
870 }
871 
872 
874 {
875  cellLengthScaleVf_ = mag(cbrt(mesh_.poly().cellVolumes()));
876 }
877 
878 
880 {
881  mesh_.topoChange(map);
882 
883  cellLengthScaleVf_ = mag(cbrt(mesh_.poly().cellVolumes()));
884 }
885 
886 
888 {
889  mesh_.mapMesh(map);
890 
891  cellLengthScaleVf_ = mag(cbrt(mesh_.poly().cellVolumes()));
892 }
893 
894 
896 {
897  mesh_.distribute(map);
898 
899  cellLengthScaleVf_ = mag(cbrt(mesh_.poly().cellVolumes()));
900 }
901 
902 
903 // ************************************************************************* //
#define ACCESS_DERIVED_FIELDS(Type, nullArg)
Definition: cloud.C:89
#define CLEAR_TYPE_DERIVED_FIELDS(Type, nullArg)
#define CORRECT_TYPE_AVERAGE_FIELDS(Type, nullArg)
#define REMOVE_FROM_TYPE_AVERAGE_FIELDS(Type, nullArg)
#define RESET_TYPE_AVERAGE_FIELDS(Type, nullArg)
#define ACCESS_AVERAGE_FIELDS(Type, nullArg)
Definition: cloud.C:114
#define ADD_TO_TYPE_AVERAGE_FIELDS(Type, nullArg)
#define CLEAR_TYPE_AVERAGE_FIELDS(Type, nullArg)
#define EVAL_TYPE_DERIVED_PATCH_FIELDS(Type, GeoField)
Functions for calculating the time derivative for a Lagrangian equation.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
static LagrangianModels & New(const word &name, const LagrangianMesh &mesh)
Construct and return the named DemandDrivenMeshObject.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
static tmp< DimensionedField< Type, GeoMesh, PrimitiveField > > New(const word &name, const GeoMesh &mesh, const dimensionSet &, const PrimitiveField< Type > &)
Return a temporary field constructed from name, mesh,.
Generic GeometricField class.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
readOption
Enumeration defining the read options.
Definition: IOobject.H:117
const word & name() const
Return name.
Definition: IOobject.H:307
writeOption
Enumeration defining the write options.
Definition: IOobject.H:126
Class to define the scope of Lagrangian mesh state changes.
Class containing Lagrangian geometry and topology.
static const word fractionName
Name of the tracked fraction field.
List of Lagrangian models, constructed as a (Lagrangian) mesh object. Provides similar functions to t...
void correct()
Correct the LagrangianModels.
virtual void postSource(const LagrangianSubScalarField &deltaT, const bool final)
Hook after source evaluation.
virtual void preSource(const LagrangianSubScalarField &deltaT, const bool final)
Hook before source evaluation.
LagrangianSubMesh preModify(LagrangianMesh &mesh) const
Identify elements in the Lagrangian mesh which are to be.
LagrangianSubMesh modify(LagrangianMesh &mesh, const LagrangianSubMesh &modifiedMesh) const
Instantaneously modify and/or create and remove elements in the.
void calculate(const LagrangianSubScalarField &deltaT, const bool final)
Solve equations and/or update continually changing properties.
Mesh that relates to a sub-section of a Lagrangian mesh. This is used to construct fields that relate...
word sub(const word &fieldName) const
Return the name of a field corresponding to this sub-mesh.
static const List< word > & null()
Return a null List.
Definition: ListI.H:118
Initialise the NamedEnum HashTable from the static list of names.
Definition: NamedEnum.H:55
const Field0Type & oldTime() const
Return the old-time field.
Definition: OldTimeField.C:322
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
bool valid() const
Return true if the autoPtr valid (ie, the pointer is set)
Definition: autoPtrI.H:83
void clear()
Delete object (if the pointer is valid) and set pointer to.
Definition: autoPtrI.H:126
List of references to the cloud function objects. Designed to be constructed temporarily for the scop...
virtual void preCrossFaces(const LagrangianInternalScalarDynamicField &fraction)
Hook before face crossings.
virtual void postCrossFaces(const LagrangianSubScalarSubField &fraction)
Hook following face crossings of a specific sub-mesh.
virtual void calculate(const LagrangianSubScalarField &deltaT, const bool final)
Solve equations and/or update continually changing properties.
Base class for clouds. Provides a basic evolution algorithm, models, and a database for caching deriv...
Definition: cloud.H:61
contextType
Context in which this cloud is used.
Definition: cloud.H:203
virtual void solve(const bool initial, const bool final)
Solve the cloud's evolution over the current time-step.
Definition: cloud.C:608
static autoPtr< cloud > New(const polyMesh &mesh, const word &name, const contextType context, const dictionary &dict, const word &type, const IOobject::readOption readOption=IOobject::READ_IF_PRESENT, const IOobject::writeOption writeOption=IOobject::AUTO_WRITE)
Selectors.
Definition: cloud.C:524
virtual void topoChange(const polyTopoChangeMap &)
Update topology using the given map.
Definition: cloud.C:879
virtual void distribute(const polyDistributionMap &)
Redistribute or update using the given distribution map.
Definition: cloud.C:895
virtual void storePosition()
Store the positions for use during mapping.
Definition: cloud.C:867
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
Definition: cloud.C:887
Foam::LagrangianModels & LagrangianModels() const
Access the models.
Definition: cloud.C:597
virtual void movePoints(const polyMesh &)
Update for mesh motion.
Definition: cloud.C:873
static const Foam::cloud & lookup(const LagrangianMesh &mesh)
Lookup the cloud associated with a mesh.
Definition: cloud.C:591
virtual ~cloud()
Destructor.
Definition: cloud.C:585
virtual void partition()
Partition hook.
Definition: cloud.C:450
cloud(LagrangianMesh &mesh, const contextType context)
Construct from a mesh and context. Reads the velocity field.
Definition: cloud.C:468
const LagrangianMesh & mesh() const
Access the mesh.
Definition: cloud.H:280
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
bool open(const fileName &libName, const bool verbose=true)
Open the named library, optionally with warnings if problems occur.
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type and name.
Motion of the mesh specified as a list of pointMeshMovers.
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:78
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:55
A class for managing temporary objects.
Definition: tmp.H:55
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:381
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
label patchi
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
U
Definition: pEqn.H:72
const dimensionSet time
label calculate(const fvMesh &mesh, const labelHashSet &patchIDs, const scalar minFaceFraction, GeometricField< scalar, GeoMesh > &distance)
Calculate distance data from patches.
const unitSet fraction
const unitSet & lookup(const word &unitName)
Lookup and return the named unit from the table.
Definition: units.C:346
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
dlLibraryTable libs
Table of loaded dynamic libraries.
List< word > wordList
A List of words.
Definition: fileName.H:54
const dimensionSet & dimless
Definition: dimensions.C:138
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:272
LagrangianState groupToState(const LagrangianGroup &group)
Convert from a state enumeration to the corresponding group enumerations.
const NamedEnum< enum cloud::trackingType, 2 > cloudTrackingNames
Definition: cloud.C:462
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
LagrangianDynamicField< label > LagrangianLabelDynamicField
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
const dimensionSet & dimLength
Definition: dimensions.C:141
String typeName(const std::type_info &info)
Return the un-mangled name given the standard type info.
FOR_ALL_FIELD_TYPES(makeDimensionedPointFieldFunctions)
messageStream Info
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:265
LagrangianState
Lagrangian state enumeration.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
const dimensionSet & dimTime
Definition: dimensions.C:142
defineRunTimeSelectionTable(fvConstraint, dictionary)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
void cbrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
LagrangianSubSubField< scalar > LagrangianSubScalarSubField
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
Ostream & indentOrNl(Ostream &os)
Indent stream or add newline if indent level == 0.
Definition: Ostream.H:250
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
error FatalError
LagrangianSubField< scalar > LagrangianSubScalarField
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
static const char nl
Definition: Ostream.H:297
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
LagrangianSubField< vector > LagrangianSubVectorField
faceListList boundary(nPatches)
dictionary dict