kinematicSingleLayer.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) 2011-2015 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 "kinematicSingleLayer.H"
27 #include "fvm.H"
28 #include "fvcDiv.H"
29 #include "fvcLaplacian.H"
30 #include "fvcSnGrad.H"
31 #include "fvcReconstruct.H"
32 #include "fvcVolumeIntegrate.H"
34 #include "mappedWallPolyPatch.H"
35 #include "mapDistribute.H"
36 #include "filmThermoModel.H"
37 
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42 namespace regionModels
43 {
44 namespace surfaceFilmModels
45 {
46 
47 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
48 
49 defineTypeNameAndDebug(kinematicSingleLayer, 0);
50 
51 addToRunTimeSelectionTable(surfaceFilmModel, kinematicSingleLayer, mesh);
52 
53 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
54 
56 {
58  {
59  const dictionary& solution = this->solution().subDict("PISO");
60  solution.lookup("momentumPredictor") >> momentumPredictor_;
61  solution.readIfPresent("nOuterCorr", nOuterCorr_);
62  solution.lookup("nCorr") >> nCorr_;
63  solution.lookup("nNonOrthCorr") >> nNonOrthCorr_;
64 
65  return true;
66  }
67  else
68  {
69  return false;
70  }
71 }
72 
73 
75 {
76  rho_ == filmThermo_->rho();
77  mu_ == filmThermo_->mu();
78  sigma_ == filmThermo_->sigma();
79 }
80 
81 
83 {
84  if (debug)
85  {
86  Info<< "kinematicSingleLayer::resetPrimaryRegionSourceTerms()" << endl;
87  }
88 
91  pSpPrimary_ == dimensionedScalar("zero", pSp_.dimensions(), 0.0);
92 }
93 
94 
96 {
97  if (debug)
98  {
99  Info<< "kinematicSingleLayer::"
100  << "transferPrimaryRegionThermoFields()" << endl;
101  }
102 
103  // Update fields from primary region via direct mapped
104  // (coupled) boundary conditions
109 }
110 
111 
113 {
114  if (debug)
115  {
116  Info<< "kinematicSingleLayer::"
117  << "transferPrimaryRegionSourceFields()" << endl;
118  }
119 
120  // Convert accummulated source terms into per unit area per unit time
121  const scalar deltaT = time_.deltaTValue();
123  {
124  const scalarField& priMagSf =
125  primaryMesh().magSf().boundaryField()[patchI];
126 
127  rhoSpPrimary_.boundaryField()[patchI] /= priMagSf*deltaT;
128  USpPrimary_.boundaryField()[patchI] /= priMagSf*deltaT;
129  pSpPrimary_.boundaryField()[patchI] /= priMagSf*deltaT;
130  }
131 
132  // Retrieve the source fields from the primary region via direct mapped
133  // (coupled) boundary conditions
134  // - fields require transfer of values for both patch AND to push the
135  // values into the first layer of internal cells
139 
140  // update addedMassTotal counter
141  if (time().outputTime())
142  {
143  scalar addedMassTotal = 0.0;
144  outputProperties().readIfPresent("addedMassTotal", addedMassTotal);
145  addedMassTotal += returnReduce(addedMassTotal_, sumOp<scalar>());
146  outputProperties().add("addedMassTotal", addedMassTotal, true);
147  addedMassTotal_ = 0.0;
148  }
149 }
150 
151 
153 {
154  return tmp<volScalarField>
155  (
156  new volScalarField
157  (
158  IOobject
159  (
160  typeName + ":pu",
161  time_.timeName(),
162  regionMesh(),
165  ),
166  pPrimary_ // pressure (mapped from primary region)
167  - pSp_ // accumulated particle impingement
168  - fvc::laplacian(sigma_, delta_) // surface tension
169  )
170  );
171 }
172 
173 
175 {
176  return tmp<volScalarField>
177  (
178  new volScalarField
179  (
180  IOobject
181  (
182  typeName + ":pp",
183  time_.timeName(),
184  regionMesh(),
187  ),
188  -rho_*gNormClipped() // hydrostatic effect only
189  )
190  );
191 }
192 
193 
195 {
197 }
198 
199 
201 {
202  if (debug)
203  {
204  Info<< "kinematicSingleLayer::updateSubmodels()" << endl;
205  }
206 
207  // Update injection model - mass returned is mass available for injection
209 
210  // Update source fields
211  const dimensionedScalar deltaT = time().deltaT();
212  rhoSp_ += cloudMassTrans_/magSf()/deltaT;
213 
214  turbulence_->correct();
215 }
216 
217 
219 {
220  const volScalarField deltaRho0(deltaRho_);
221 
222  solveContinuity();
223 
224  if (debug)
225  {
229  + dimensionedScalar("SMALL", dimMass*dimVolume, ROOTVSMALL);
230 
231  const scalar sumLocalContErr =
232  (
233  fvc::domainIntegrate(mag(mass - magSf()*deltaRho0))/totalMass
234  ).value();
235 
236  const scalar globalContErr =
237  (
238  fvc::domainIntegrate(mass - magSf()*deltaRho0)/totalMass
239  ).value();
240 
242 
243  Info<< "Surface film: " << type() << nl
244  << " time step continuity errors: sum local = "
245  << sumLocalContErr << ", global = " << globalContErr
246  << ", cumulative = " << cumulativeContErr_ << endl;
247  }
248 }
249 
250 
252 {
253  if (debug)
254  {
255  Info<< "kinematicSingleLayer::solveContinuity()" << endl;
256  }
257 
258  solve
259  (
261  + fvc::div(phi_)
262  ==
263  - rhoSp_
264  );
265 }
266 
267 
269 {
270  // Push boundary film velocity values into internal field
271  for (label i=0; i<intCoupledPatchIDs_.size(); i++)
272  {
273  label patchI = intCoupledPatchIDs_[i];
274  const polyPatch& pp = regionMesh().boundaryMesh()[patchI];
276  U_.boundaryField()[patchI];
277  }
278  Uw_ -= nHat()*(Uw_ & nHat());
280 
281  Us_ = turbulence_->Us();
282 }
283 
284 
286 (
287  const volScalarField& pu,
288  const volScalarField& pp
289 )
290 {
291  if (debug)
292  {
293  Info<< "kinematicSingleLayer::solveMomentum()" << endl;
294  }
295 
296  // Momentum
297  tmp<fvVectorMatrix> tUEqn
298  (
300  + fvm::div(phi_, U_)
301  ==
302  - USp_
303 // - fvm::SuSp(rhoSp_, U_)
304  - rhoSp_*U_
305  + forces_.correct(U_)
306  + turbulence_->Su(U_)
307  );
308 
309  fvVectorMatrix& UEqn = tUEqn();
310 
311  UEqn.relax();
312 
313  if (momentumPredictor_)
314  {
315  solve
316  (
317  UEqn
318  ==
320  (
322  * (
323  regionMesh().magSf()
324  * (
325  fvc::snGrad(pu, "snGrad(p)")
326  + fvc::snGrad(pp, "snGrad(p)")*fvc::interpolate(delta_)
328  )
329  - (fvc::interpolate(rho_*gTan()) & regionMesh().Sf())
330  )
331  )
332  );
333 
334  // Remove any patch-normal components of velocity
335  U_ -= nHat()*(nHat() & U_);
337  }
338 
339  return tUEqn;
340 }
341 
342 
344 (
345  const volScalarField& pu,
346  const volScalarField& pp,
347  const fvVectorMatrix& UEqn
348 )
349 {
350  if (debug)
351  {
352  Info<< "kinematicSingleLayer::solveThickness()" << endl;
353  }
354 
355  volScalarField rUA(1.0/UEqn.A());
356  U_ = rUA*UEqn.H();
357 
360 
361  surfaceScalarField phiAdd
362  (
363  "phiAdd",
364  regionMesh().magSf()
365  * (
366  fvc::snGrad(pu, "snGrad(p)")
367  + fvc::snGrad(pp, "snGrad(p)")*fvc::interpolate(delta_)
368  )
369  - (fvc::interpolate(rho_*gTan()) & regionMesh().Sf())
370  );
371  constrainFilmField(phiAdd, 0.0);
372 
374  (
375  "phid",
376  (fvc::interpolate(U_*rho_) & regionMesh().Sf())
377  - deltarUAf*phiAdd*rhof
378  );
379  constrainFilmField(phid, 0.0);
380 
381  surfaceScalarField ddrhorUAppf
382  (
383  "deltaCoeff",
384  fvc::interpolate(delta_)*deltarUAf*rhof*fvc::interpolate(pp)
385  );
386 
388 
389  for (int nonOrth=0; nonOrth<=nNonOrthCorr_; nonOrth++)
390  {
391  // Film thickness equation
392  fvScalarMatrix deltaEqn
393  (
394  fvm::ddt(rho_, delta_)
395  + fvm::div(phid, delta_)
396  - fvm::laplacian(ddrhorUAppf, delta_)
397  ==
398  - rhoSp_
399  );
400 
401  deltaEqn.solve();
402 
403  if (nonOrth == nNonOrthCorr_)
404  {
405  phiAdd +=
406  fvc::interpolate(pp)
408  * regionMesh().magSf();
409 
410  phi_ == deltaEqn.flux();
411  }
412  }
413 
414  // Bound film thickness by a minimum of zero
415  delta_.max(0.0);
416 
417  // Update U field
418  U_ -= fvc::reconstruct(deltarUAf*phiAdd);
419 
420  // Remove any patch-normal components of velocity
421  U_ -= nHat()*(nHat() & U_);
422 
424 
425  // Continuity check
426  continuityCheck();
427 }
428 
429 
430 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
431 
432 kinematicSingleLayer::kinematicSingleLayer
433 (
434  const word& modelType,
435  const fvMesh& mesh,
436  const dimensionedVector& g,
437  const word& regionType,
438  const bool readFields
439 )
440 :
441  surfaceFilmModel(modelType, mesh, g, regionType),
442 
443  momentumPredictor_(solution().subDict("PISO").lookup("momentumPredictor")),
444  nOuterCorr_(solution().subDict("PISO").lookupOrDefault("nOuterCorr", 1)),
445  nCorr_(readLabel(solution().subDict("PISO").lookup("nCorr"))),
447  (
448  readLabel(solution().subDict("PISO").lookup("nNonOrthCorr"))
449  ),
450 
451  cumulativeContErr_(0.0),
452 
453  deltaSmall_("deltaSmall", dimLength, SMALL),
454  deltaCoLimit_(solution().lookupOrDefault("deltaCoLimit", 1e-4)),
455 
456  rho_
457  (
458  IOobject
459  (
460  "rhof",
461  time().timeName(),
462  regionMesh(),
465  ),
466  regionMesh(),
467  dimensionedScalar("zero", dimDensity, 0.0),
468  zeroGradientFvPatchScalarField::typeName
469  ),
470  mu_
471  (
472  IOobject
473  (
474  "muf",
475  time().timeName(),
476  regionMesh(),
479  ),
480  regionMesh(),
481  dimensionedScalar("zero", dimPressure*dimTime, 0.0),
482  zeroGradientFvPatchScalarField::typeName
483  ),
484  sigma_
485  (
486  IOobject
487  (
488  "sigmaf",
489  time().timeName(),
490  regionMesh(),
493  ),
494  regionMesh(),
495  dimensionedScalar("zero", dimMass/sqr(dimTime), 0.0),
496  zeroGradientFvPatchScalarField::typeName
497  ),
498 
499  delta_
500  (
501  IOobject
502  (
503  "deltaf",
504  time().timeName(),
505  regionMesh(),
508  ),
509  regionMesh()
510  ),
511  alpha_
512  (
513  IOobject
514  (
515  "alpha",
516  time().timeName(),
517  regionMesh(),
520  ),
521  regionMesh(),
522  dimensionedScalar("zero", dimless, 0.0),
523  zeroGradientFvPatchScalarField::typeName
524  ),
525  U_
526  (
527  IOobject
528  (
529  "Uf",
530  time().timeName(),
531  regionMesh(),
534  ),
535  regionMesh()
536  ),
537  Us_
538  (
539  IOobject
540  (
541  "Usf",
542  time().timeName(),
543  regionMesh(),
546  ),
547  U_,
548  zeroGradientFvPatchScalarField::typeName
549  ),
550  Uw_
551  (
552  IOobject
553  (
554  "Uwf",
555  time().timeName(),
556  regionMesh(),
559  ),
560  U_,
561  zeroGradientFvPatchScalarField::typeName
562  ),
563  deltaRho_
564  (
565  IOobject
566  (
567  delta_.name() + "*" + rho_.name(),
568  time().timeName(),
569  regionMesh(),
572  ),
573  regionMesh(),
575  zeroGradientFvPatchScalarField::typeName
576  ),
577 
578  phi_
579  (
580  IOobject
581  (
582  "phi",
583  time().timeName(),
584  regionMesh(),
587  ),
588  regionMesh(),
589  dimensionedScalar("0", dimLength*dimMass/dimTime, 0.0)
590  ),
591 
593  (
594  IOobject
595  (
596  "primaryMassTrans",
597  time().timeName(),
598  regionMesh(),
601  ),
602  regionMesh(),
603  dimensionedScalar("zero", dimMass, 0.0),
604  zeroGradientFvPatchScalarField::typeName
605  ),
607  (
608  IOobject
609  (
610  "cloudMassTrans",
611  time().timeName(),
612  regionMesh(),
615  ),
616  regionMesh(),
617  dimensionedScalar("zero", dimMass, 0.0),
618  zeroGradientFvPatchScalarField::typeName
619  ),
621  (
622  IOobject
623  (
624  "cloudDiameterTrans",
625  time().timeName(),
626  regionMesh(),
629  ),
630  regionMesh(),
631  dimensionedScalar("zero", dimLength, -1.0),
632  zeroGradientFvPatchScalarField::typeName
633  ),
634 
635  USp_
636  (
637  IOobject
638  (
639  "USpf",
640  time().timeName(),
641  regionMesh(),
644  ),
645  regionMesh(),
647  (
648  "zero", dimMass*dimVelocity/dimArea/dimTime, vector::zero
649  ),
650  this->mappedPushedFieldPatchTypes<vector>()
651  ),
652  pSp_
653  (
654  IOobject
655  (
656  "pSpf",
657  time_.timeName(),
658  regionMesh(),
661  ),
662  regionMesh(),
663  dimensionedScalar("zero", dimPressure, 0.0),
664  this->mappedPushedFieldPatchTypes<scalar>()
665  ),
666  rhoSp_
667  (
668  IOobject
669  (
670  "rhoSpf",
671  time_.timeName(),
672  regionMesh(),
675  ),
676  regionMesh(),
677  dimensionedScalar("zero", dimMass/dimTime/dimArea, 0.0),
678  this->mappedPushedFieldPatchTypes<scalar>()
679  ),
680 
682  (
683  IOobject
684  (
685  USp_.name(), // must have same name as USp_ to enable mapping
686  time().timeName(),
687  primaryMesh(),
690  ),
691  primaryMesh(),
693  ),
695  (
696  IOobject
697  (
698  pSp_.name(), // must have same name as pSp_ to enable mapping
699  time().timeName(),
700  primaryMesh(),
703  ),
704  primaryMesh(),
705  dimensionedScalar("zero", pSp_.dimensions(), 0.0)
706  ),
708  (
709  IOobject
710  (
711  rhoSp_.name(), // must have same name as rhoSp_ to enable mapping
712  time().timeName(),
713  primaryMesh(),
716  ),
717  primaryMesh(),
718  dimensionedScalar("zero", rhoSp_.dimensions(), 0.0)
719  ),
720 
721  UPrimary_
722  (
723  IOobject
724  (
725  "U", // must have same name as U to enable mapping
726  time().timeName(),
727  regionMesh(),
730  ),
731  regionMesh(),
733  this->mappedFieldAndInternalPatchTypes<vector>()
734  ),
735  pPrimary_
736  (
737  IOobject
738  (
739  "p", // must have same name as p to enable mapping
740  time().timeName(),
741  regionMesh(),
744  ),
745  regionMesh(),
746  dimensionedScalar("zero", dimPressure, 0.0),
747  this->mappedFieldAndInternalPatchTypes<scalar>()
748  ),
750  (
751  IOobject
752  (
753  "rho", // must have same name as rho to enable mapping
754  time().timeName(),
755  regionMesh(),
758  ),
759  regionMesh(),
760  dimensionedScalar("zero", dimDensity, 0.0),
761  this->mappedFieldAndInternalPatchTypes<scalar>()
762  ),
763  muPrimary_
764  (
765  IOobject
766  (
767  "thermo:mu", // must have same name as mu to enable mapping
768  time().timeName(),
769  regionMesh(),
772  ),
773  regionMesh(),
774  dimensionedScalar("zero", dimPressure*dimTime, 0.0),
775  this->mappedFieldAndInternalPatchTypes<scalar>()
776  ),
777 
779 
780  availableMass_(regionMesh().nCells(), 0.0),
781 
782  injection_(*this, coeffs_),
783 
785 
786  forces_(*this, coeffs_),
787 
788  addedMassTotal_(0.0)
789 {
790  if (readFields)
791  {
793 
794  correctAlpha();
795 
797 
798  deltaRho_ == delta_*rho_;
799 
801  (
802  IOobject
803  (
804  "phi",
805  time().timeName(),
806  regionMesh(),
809  false
810  ),
812  );
813 
814  phi_ == phi0;
815  }
816 }
817 
818 
819 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
820 
822 {}
823 
824 
825 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
826 
828 (
829  const label patchI,
830  const label faceI,
831  const scalar massSource,
832  const vector& momentumSource,
833  const scalar pressureSource,
834  const scalar energySource
835 )
836 {
837  if (debug)
838  {
839  Info<< "\nSurface film: " << type() << ": adding to film source:" << nl
840  << " mass = " << massSource << nl
841  << " momentum = " << momentumSource << nl
842  << " pressure = " << pressureSource << endl;
843  }
844 
845  rhoSpPrimary_.boundaryField()[patchI][faceI] -= massSource;
846  USpPrimary_.boundaryField()[patchI][faceI] -= momentumSource;
847  pSpPrimary_.boundaryField()[patchI][faceI] -= pressureSource;
848 
849  addedMassTotal_ += massSource;
850 }
851 
852 
854 {
855  if (debug)
856  {
857  Info<< "kinematicSingleLayer::preEvolveRegion()" << endl;
858  }
859 
861 
863 
865 
867 
868  // Reset transfer fields
869 // availableMass_ = mass();
871  cloudMassTrans_ == dimensionedScalar("zero", dimMass, 0.0);
873 }
874 
875 
877 {
878  if (debug)
879  {
880  Info<< "kinematicSingleLayer::evolveRegion()" << endl;
881  }
882 
883  // Update film coverage indicator
884  correctAlpha();
885 
886  // Update film wall and surface velocities
888 
889  // Update sub-models to provide updated source contributions
890  updateSubmodels();
891 
892  // Solve continuity for deltaRho_
893  solveContinuity();
894 
895  // Implicit pressure source coefficient - constant
896  tmp<volScalarField> tpp(this->pp());
897 
898  for (int oCorr=1; oCorr<=nOuterCorr_; oCorr++)
899  {
900  // Explicit pressure source contribution - varies with delta_
901  tmp<volScalarField> tpu(this->pu());
902 
903  // Solve for momentum for U_
904  tmp<fvVectorMatrix> UEqn = solveMomentum(tpu(), tpp());
905 
906  // Film thickness correction loop
907  for (int corr=1; corr<=nCorr_; corr++)
908  {
909  // Solve thickness for delta_
910  solveThickness(tpu(), tpp(), UEqn());
911  }
912  }
913 
914  // Update deltaRho_ with new delta_
915  deltaRho_ == delta_*rho_;
916 
917  // Reset source terms for next time integration
919 }
920 
921 
923 {
924  scalar CoNum = 0.0;
925 
926  if (regionMesh().nInternalFaces() > 0)
927  {
928  const scalarField sumPhi
929  (
931  / (deltaRho_.internalField() + ROOTVSMALL)
932  );
933 
934  forAll(delta_, i)
935  {
936  if (delta_[i] > deltaCoLimit_)
937  {
938  CoNum = max(CoNum, sumPhi[i]/(delta_[i]*magSf()[i]));
939  }
940  }
941 
942  CoNum *= 0.5*time_.deltaTValue();
943  }
944 
945  reduce(CoNum, maxOp<scalar>());
946 
947  Info<< "Film max Courant number: " << CoNum << endl;
948 
949  return CoNum;
950 }
951 
952 
954 {
955  return U_;
956 }
957 
958 
960 {
961  return Us_;
962 }
963 
964 
966 {
967  return Uw_;
968 }
969 
970 
972 {
973  return deltaRho_;
974 }
975 
976 
978 {
979  return phi_;
980 }
981 
982 
984 {
985  return rho_;
986 }
987 
988 
990 {
992  (
993  "const volScalarField& kinematicSingleLayer::T() const"
994  ) << "T field not available for " << type() << abort(FatalError);
995 
996  return volScalarField::null();
997 }
998 
999 
1001 {
1002  FatalErrorIn
1003  (
1004  "const volScalarField& kinematicSingleLayer::Ts() const"
1005  ) << "Ts field not available for " << type() << abort(FatalError);
1006 
1007  return volScalarField::null();
1008 }
1009 
1010 
1012 {
1013  FatalErrorIn
1014  (
1015  "const volScalarField& kinematicSingleLayer::Tw() const"
1016  ) << "Tw field not available for " << type() << abort(FatalError);
1017 
1018  return volScalarField::null();
1019 }
1020 
1021 
1023 {
1024  FatalErrorIn
1025  (
1026  "const volScalarField& kinematicSingleLayer::Cp() const"
1027  ) << "Cp field not available for " << type() << abort(FatalError);
1028 
1029  return volScalarField::null();
1030 }
1031 
1032 
1034 {
1035  FatalErrorIn
1036  (
1037  "const volScalarField& kinematicSingleLayer::kappa() const"
1038  ) << "kappa field not available for " << type() << abort(FatalError);
1039 
1040  return volScalarField::null();
1041 }
1042 
1043 
1045 {
1046  return tmp<volScalarField>
1047  (
1048  new volScalarField
1049  (
1050  IOobject
1051  (
1052  typeName + ":primaryMassTrans",
1053  time().timeName(),
1054  primaryMesh(),
1057  false
1058  ),
1059  primaryMesh(),
1060  dimensionedScalar("zero", dimMass/dimVolume/dimTime, 0.0)
1061  )
1062  );
1063 }
1064 
1065 
1067 {
1068  return cloudMassTrans_;
1069 }
1070 
1071 
1073 {
1074  return cloudDiameterTrans_;
1075 }
1076 
1077 
1079 {
1080  Info<< "\nSurface film: " << type() << endl;
1081 
1082  const scalarField& deltaInternal = delta_.internalField();
1083  const vectorField& Uinternal = U_.internalField();
1084  scalar addedMassTotal = 0.0;
1085  outputProperties().readIfPresent("addedMassTotal", addedMassTotal);
1086  addedMassTotal += returnReduce(addedMassTotal_, sumOp<scalar>());
1087 
1088  Info<< indent << "added mass = " << addedMassTotal << nl
1089  << indent << "current mass = "
1090  << gSum((deltaRho_*magSf())()) << nl
1091  << indent << "min/max(mag(U)) = " << gMin(mag(Uinternal)) << ", "
1092  << gMax(mag(Uinternal)) << nl
1093  << indent << "min/max(delta) = " << gMin(deltaInternal) << ", "
1094  << gMax(deltaInternal) << nl
1095  << indent << "coverage = "
1096  << gSum(alpha_.internalField()*magSf())/gSum(magSf()) << nl;
1097 
1098  injection_.info(Info);
1099 }
1100 
1101 
1103 {
1105  (
1107  (
1108  IOobject
1109  (
1110  typeName + ":Srho",
1111  time().timeName(),
1112  primaryMesh(),
1115  false
1116  ),
1117  primaryMesh(),
1118  dimensionedScalar("zero", dimMass/dimVolume/dimTime, 0.0)
1119  )
1120  );
1121 }
1122 
1123 
1126  const label i
1127 ) const
1128 {
1130  (
1132  (
1133  IOobject
1134  (
1135  typeName + ":Srho(" + Foam::name(i) + ")",
1136  time().timeName(),
1137  primaryMesh(),
1140  false
1141  ),
1142  primaryMesh(),
1143  dimensionedScalar("zero", dimMass/dimVolume/dimTime, 0.0)
1144  )
1145  );
1146 }
1147 
1148 
1150 {
1152  (
1154  (
1155  IOobject
1156  (
1157  typeName + ":Sh",
1158  time().timeName(),
1159  primaryMesh(),
1162  false
1163  ),
1164  primaryMesh(),
1165  dimensionedScalar("zero", dimEnergy/dimVolume/dimTime, 0.0)
1166  )
1167  );
1168 }
1169 
1170 
1171 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1172 
1173 } // End namespace surfaceFilmModels
1174 } // End namespace regionModels
1175 } // End namespace Foam
1176 
1177 // ************************************************************************* //
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &vf, const surfaceScalarField &faceFlux, Istream &schemeData)
const dimensionSet dimPressure
tmp< fvMatrix< Type > > ddt(const GeometricField< Type, fvPatchField, volMesh > &vf)
Definition: fvmDdt.C:46
scalar addedMassTotal_
Cumulative mass added via sources [kg].
virtual const volScalarField & deltaRho() const
Return the film thickness*density (helper field) [kg/m3].
virtual tmp< volScalarField > primaryMassTrans() const
Return mass transfer source - Eulerian phase only.
virtual scalar CourantNumber() const
Courant number evaluation.
dimensionedScalar totalMass
Definition: continuityErrs.H:4
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Calculate the snGrad of the given volField.
volScalarField alpha_
Film coverage indicator, 1 = covered, 0 = uncovered / [].
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
tmp< fvMatrix< Type > > div(const surfaceScalarField &flux, const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvmDiv.C:46
dimensioned< scalar > mag(const dimensioned< Type > &)
GeometricBoundaryField & boundaryField()
Return reference to GeometricBoundaryField.
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
defineTypeNameAndDebug(kinematicSingleLayer, 0)
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > flux() const
Return the face-flux field from the matrix.
Definition: fvMatrix.C:883
virtual const volScalarField & rho() const
Return the film density [kg/m3].
autoPtr< filmThermoModel > filmThermo_
Film thermo model.
scalar sumLocalContErr
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> reconstruct(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
const IOdictionary & outputProperties() const
Return const access to the output properties dictionary.
Definition: regionModelI.H:116
void setFluxRequired(const word &name) const
Definition: fvSchemes.C:497
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:221
virtual void evolveRegion()
Evolve the film equations.
virtual void info(Ostream &os)
Provide some info.
virtual const volScalarField & kappa() const
Return the film thermal conductivity [W/m/K].
const labelUList & faceCells() const
Return face-cell addressing.
Definition: polyPatch.C:316
volScalarField cloudMassTrans_
Film mass available for transfer to cloud.
tmp< GeometricField< Type, fvPatchField, volMesh > > surfaceSum(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
virtual tmp< volScalarField > pu()
Explicit pressure source contribution.
tmp< volScalarField > mass() const
Return the current film mass.
virtual const volScalarField & Tw() const
Return the film wall temperature [K].
const dimensionSet dimArea(sqr(dimLength))
Definition: dimensionSets.H:57
A class for handling words, derived from string.
Definition: word.H:59
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
tmp< fvMatrix< Type > > laplacian(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvmLaplacian.C:46
static word timeName(const scalar, const int precision=precision_)
Return time name of given scalar time.
Definition: Time.C:741
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
addToRunTimeSelectionTable(surfaceFilmModel, kinematicSingleLayer, mesh)
InternalField & internalField()
Return internal field.
virtual const volVectorField & Uw() const
Return the film wall velocity [m/s].
tmp< GeometricField< Type, fvPatchField, volMesh > > laplacian(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvcLaplacian.C:45
const dimensionSet dimEnergy
const fvMesh & regionMesh() const
Return the region mesh database.
Definition: regionModelI.H:61
A special matrix type and solver, designed for finite volume solutions of scalar equations. Face addressing is used to make all matrix assembly and solution loops vectorise.
Definition: fvPatchField.H:68
const Time & time() const
Return the reference to the time database.
Definition: regionModelI.H:37
virtual const volVectorField & nHat() const
Return the patch normal vectors.
messageStream Info
const dimensionSet dimDensity
tmp< GeometricField< Type, fvPatchField, volMesh > > H() const
Return the H operation source.
Definition: fvMatrix.C:769
virtual void preEvolveRegion()
Pre-evolve region.
Definition: regionModel.C:564
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
virtual void transferPrimaryRegionThermoFields()
Transfer thermo fields from the primary region to the film region.
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
Definition: dictionary.C:638
labelList intCoupledPatchIDs_
List of patch IDs internally coupled with the primary region.
Definition: regionModel.H:117
virtual tmp< DimensionedField< scalar, volMesh > > Sh() const
Return enthalpy source - Eulerian phase only.
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:50
virtual bool read()
Read control parameters from dictionary.
Selector class for relaxation factors, solver type and solution.
Definition: solution.H:48
void constrainFilmField(Type &field, const typename Type::cmptType &value)
Constrain a film region master/slave boundaries of a field to a.
Namespace for OpenFOAM.
virtual const volScalarField & cloudMassTrans() const
Return the film mass available for transfer to cloud.
label readLabel(Istream &is)
Definition: label.H:64
virtual const volScalarField & Cp() const
Return the film specific heat capacity [J/kg/K].
Calculate the laplacian of the given field.
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
static autoPtr< filmThermoModel > New(surfaceFilmModel &owner, const dictionary &dict)
Return a reference to the selected phase change model.
virtual void updateSubmodels()
Update the film sub-models.
label nNonOrthCorr_
Number of non-orthogonal correctors.
Type gSum(const FieldField< Field, Type > &f)
tmp< volScalarField > gNormClipped() const
Return the gravity normal-to-patch component contribution.
volScalarField cloudDiameterTrans_
Parcel diameters originating from film to cloud.
virtual void resetPrimaryRegionSourceTerms()
Reset source term fields.
virtual void correctThermoFields()
Correct the thermo fields.
static const char nl
Definition: Ostream.H:260
const double e
Elementary charge.
Definition: doubleFloat.H:78
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
virtual const volVectorField & U() const
Return the film velocity [m/s].
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
virtual tmp< fvVectorMatrix > solveMomentum(const volScalarField &pu, const volScalarField &pp)
Solve for film velocity.
scalar deltaTValue() const
Return time step value.
Definition: TimeState.H:100
fvVectorMatrix UEqn(fvm::ddt(rho, U)+fvm::div(phi, U)+turbulence->divDevRhoReff(U)==fvOptions(rho, U))
surfaceScalarField phid("phid", fvc::interpolate(psi)*( (mesh.Sf()&fvc::interpolate(HbyA)) +rhorAUf *fvc::ddtCorr(rho, U, phi)/fvc::interpolate(rho) ))
A List with indirect addressing.
Definition: fvMatrix.H:106
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:52
tmp< volVectorField > gTan() const
Return the gravity tangential component contributions.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Reconstruct volField from a face flux field.
virtual tmp< DimensionedField< scalar, volMesh > > Srho() const
Return total mass source - Eulerian phase only.
#define forAll(list, i)
Definition: UList.H:421
virtual const volScalarField & magSf() const
Return the face area magnitudes / [m2].
dictionary coeffs_
Model coefficients dictionary.
Definition: regionModel.H:105
virtual const volScalarField & T() const
Return the film mean temperature [K].
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:49
Macros for easy insertion into run-time selection tables.
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
surfaceScalarField phi_
Mass flux (includes film thickness) / [kg.m/s].
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > snGrad(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvcSnGrad.C:45
tmp< volScalarField > netMass() const
Return the net film mass available over the next integration.
const dimensionSet & dimensions() const
Return dimensions.
virtual const volScalarField & Ts() const
Return the film surface temperature [K].
solverPerformance solve(const dictionary &)
Solve segregated or coupled returning the solution statistics.
Definition: fvMatrixSolve.C:57
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:739
errorManip< error > abort(error &err)
Definition: errorManip.H:131
const word & name() const
Return name.
Definition: IOobject.H:260
virtual tmp< volScalarField > pp()
Implicit pressure source coefficient.
Type gMin(const FieldField< Field, Type > &f)
fileName::Type type(const fileName &)
Return the file type: DIRECTORY or FILE.
Definition: POSIX.C:589
volScalarField primaryMassTrans_
Film mass available for transfer to the primary region.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
const dictionary & solution() const
Return the solution dictionary.
Definition: regionModelI.H:109
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
static autoPtr< filmTurbulenceModel > New(surfaceFilmModel &owner, const dictionary &dict)
Return a reference to the selected injection model.
virtual const surfaceScalarField & phi() const
Return the film flux [kg.m/s].
scalar deltaCoLimit_
Film thickness above which Courant number calculation in valid.
autoPtr< filmTurbulenceModel > turbulence_
Turbulence model.
static const GeometricField< scalar, fvPatchField, volMesh > & null()
Return a null geometric field.
tmp< volScalarField > A() const
Return the central coefficient.
Definition: fvMatrix.C:740
solverPerformance solve(fvMatrix< Type > &, const dictionary &)
Solve returning the solution statistics given convergence tolerance.
Calculate the divergence of the given field.
virtual void solveThickness(const volScalarField &pu, const volScalarField &pp, const fvVectorMatrix &UEqn)
Solve coupled velocity-thickness equations.
const fvMesh & primaryMesh() const
Return the reference to the primary mesh database.
Definition: regionModelI.H:31
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:452
error FatalError
IOobject(const word &name, const fileName &instance, const objectRegistry &registry, readOption r=NO_READ, writeOption w=NO_WRITE, bool registerObject=true)
Construct from name, instance, registry, io options.
Definition: IOobject.C:131
void correctBoundaryConditions()
Correct boundary field.
scalar CoNum
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
const dimensionSet dimVolume(pow3(dimLength))
Definition: dimensionSets.H:58
static const Vector zero
Definition: Vector.H:80
dimensioned< Type > domainIntegrate(const GeometricField< Type, fvPatchField, volMesh > &vf)
bool readIfPresent(const word &, T &, bool recursive=false, bool patternMatch=true) const
Find an entry if present, and assign to T.
const Time & time_
Reference to the time database.
Definition: regionModel.H:90
surfaceScalarField rhof(fvc::interpolate(rho,"div(phi,rho)"))
void max(const dimensioned< Type > &)
virtual void transferPrimaryRegionSourceFields()
Transfer source fields from the primary region to the film region.
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:47
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcDiv.C:47
virtual bool read()
Read control parameters from dictionary.
dimensionedScalar pos(const dimensionedScalar &ds)
virtual void addSources(const label patchI, const label faceI, const scalar massSource, const vector &momentumSource, const scalar pressureSource, const scalar energySource=0)
External hook to add sources to the film.
virtual void updateSurfaceVelocities()
Update film surface velocities.
dimensionedScalar deltaT() const
Return time step.
Definition: TimeState.C:79
dimensionedSymmTensor sqr(const dimensionedVector &dv)
virtual void solveContinuity()
Solve continuity equation.
const dimensionedScalar phi0
Magnetic flux quantum: default SI units: [Wb].
tmp< fvVectorMatrix > correct(volVectorField &U)
Return (net) force system.
Definition: forceList.C:78
virtual void correct(scalarField &availableMass, volScalarField &massToInject, volScalarField &diameterToInject)
Correct.
scalar globalContErr
virtual const volVectorField & Us() const
Return the film surface velocity [m/s].
const dimensionSet dimVelocity
Volume integrate volField creating a volField.
scalarField availableMass_
Available mass for transfer via sub-models.
Type gMax(const FieldField< Field, Type > &f)
virtual const volScalarField & cloudDiameterTrans() const
Return the parcel diameters originating from film to cloud.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
A class for managing temporary objects.
Definition: PtrList.H:118
virtual void correctAlpha()
Correct film coverage field.
conserve internalField()+
word timeName
Definition: getTimeIndex.H:3
volScalarField deltaRho_
Film thickness*density (helper field) / [kg/m2].