layerParameters.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-2015 OpenFOAM Foundation
9  Copyright (C) 2018-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
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 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "layerParameters.H"
30 #include "polyBoundaryMesh.H"
31 #include "unitConversion.H"
32 #include "refinementSurfaces.H"
33 #include "searchableSurfaces.H"
34 #include "medialAxisMeshMover.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 const Foam::Enum
39 <
41 >
42 Foam::layerParameters::thicknessModelTypeNames_
43 ({
44  { thicknessModelType::FIRST_AND_TOTAL, "firstAndOverall" },
45  { thicknessModelType::FIRST_AND_EXPANSION, "firstAndExpansion" },
46  { thicknessModelType::FINAL_AND_TOTAL, "finalAndOverall" },
47  { thicknessModelType::FINAL_AND_EXPANSION, "finalAndExpansion" },
48  { thicknessModelType::TOTAL_AND_EXPANSION, "overallAndExpansion" },
49  { thicknessModelType::FIRST_AND_RELATIVE_FINAL, "firstAndRelativeFinal" },
50 });
51 
52 const Foam::scalar Foam::layerParameters::defaultConcaveAngle = 90;
53 
54 
55 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
56 
57 Foam::scalar Foam::layerParameters::layerExpansionRatio
58 (
59  const label n,
60  const scalar totalOverFirst
61 )
62 {
63  if (n <= 1)
64  {
65  return 1.0;
66  }
67 
68  const label maxIters = 20;
69  const scalar tol = 1e-8;
70 
71  if (mag(n-totalOverFirst) < tol)
72  {
73  return 1.0;
74  }
75 
76  // Calculate the bounds of the solution
77  scalar minR;
78  scalar maxR;
79 
80  if (totalOverFirst < n)
81  {
82  minR = 0.0;
83  maxR = pow(totalOverFirst/n, scalar(1)/(n-1));
84  }
85  else
86  {
87  minR = pow(totalOverFirst/n, scalar(1)/(n-1));
88  maxR = totalOverFirst/(n - 1);
89  }
90 
91  // Starting guess
92  scalar r = 0.5*(minR + maxR);
93 
94  for (label i = 0; i < maxIters; ++i)
95  {
96  const scalar prevr = r;
97 
98  const scalar fx = pow(r, n) - totalOverFirst*r - (1 - totalOverFirst);
99  const scalar dfx = n*pow(r, n - 1) - totalOverFirst;
100  r -= fx/dfx;
101 
102  if (mag(r - prevr) < tol)
103  {
104  break;
105  }
106  }
107  return r;
108 }
109 
110 
111 void Foam::layerParameters::readLayerParameters
112 (
113  const bool verbose,
114  const dictionary& dict,
115  const thicknessModelType& spec,
116  scalar& firstLayerThickness,
117  scalar& finalLayerThickness,
118  scalar& thickness,
119  scalar& expansionRatio
120 )
121 {
122  // Now we have determined the layer-specification read the actual fields
123  switch (spec)
124  {
125  case FIRST_AND_TOTAL:
126  if (verbose)
127  {
128  Info<< "Layer specification as" << nl
129  << "- first layer thickness ('firstLayerThickness')" << nl
130  << "- overall thickness ('thickness')" << endl;
131  }
132  firstLayerThickness = dict.get<scalar>("firstLayerThickness");
133  thickness = dict.get<scalar>("thickness");
134  break;
135 
136  case FIRST_AND_EXPANSION:
137  if (verbose)
138  {
139  Info<< "Layer specification as" << nl
140  << "- first layer thickness ('firstLayerThickness')" << nl
141  << "- expansion ratio ('expansionRatio')" << endl;
142  }
143  firstLayerThickness = dict.get<scalar>("firstLayerThickness");
144  expansionRatio = dict.get<scalar>("expansionRatio");
145  break;
146 
147  case FINAL_AND_TOTAL:
148  if (verbose)
149  {
150  Info<< "Layer specification as" << nl
151  << "- final layer thickness ('finalLayerThickness')" << nl
152  << "- overall thickness ('thickness')" << endl;
153  }
154  finalLayerThickness = dict.get<scalar>("finalLayerThickness");
155  thickness = dict.get<scalar>("thickness");
156  break;
157 
158  case FINAL_AND_EXPANSION:
159  if (verbose)
160  {
161  Info<< "Layer specification as" << nl
162  << "- final layer thickness ('finalLayerThickness')" << nl
163  << "- expansion ratio ('expansionRatio')" << endl;
164  }
165  finalLayerThickness = dict.get<scalar>("finalLayerThickness");
166  expansionRatio = dict.get<scalar>("expansionRatio");
167  break;
168 
169  case TOTAL_AND_EXPANSION:
170  if (verbose)
171  {
172  Info<< "Layer specification as" << nl
173  << "- overall thickness ('thickness')" << nl
174  << "- expansion ratio ('expansionRatio')" << endl;
175  }
176  thickness = dict.get<scalar>("thickness");
177  expansionRatio = dict.get<scalar>("expansionRatio");
178  break;
179 
180  case FIRST_AND_RELATIVE_FINAL:
181  if (verbose)
182  {
183  Info<< "Layer specification as" << nl
184  << "- absolute first layer thickness"
185  << " ('firstLayerThickness')"
186  << nl
187  << "- and final layer thickness"
188  << " ('finalLayerThickness')" << nl
189  << endl;
190  }
191  firstLayerThickness = dict.get<scalar>("firstLayerThickness");
192  finalLayerThickness = dict.get<scalar>("finalLayerThickness");
193  break;
194 
195  default:
197  << "problem." << exit(FatalIOError);
198  break;
199  }
200 }
201 
202 
203 void Foam::layerParameters::calculateLayerParameters
204 (
205  const thicknessModelType& spec,
206  const label nLayers,
207  scalar& firstThickness,
208  scalar& finalThickness,
209  scalar& thickness,
210  scalar& expansionRatio
211 )
212 {
213  // Calculate the non-read parameters
214  switch (spec)
215  {
216  case FIRST_AND_TOTAL:
217  expansionRatio = layerExpansionRatio
218  (
219  spec,
220  nLayers,
221  firstThickness,
222  VGREAT,
223  thickness, //totalThickness
224  VGREAT //expansionRatio
225  );
226  finalThickness =
227  thickness
228  *finalLayerThicknessRatio(nLayers, expansionRatio);
229 
230  break;
231 
232  case FIRST_AND_EXPANSION:
233  thickness = layerThickness
234  (
235  spec,
236  nLayers,
237  firstThickness, //firstThickness
238  VGREAT, //finalThickness
239  VGREAT, //totalThickness
240  expansionRatio //expansionRatio
241  );
242  finalThickness =
243  thickness
244  *finalLayerThicknessRatio(nLayers, expansionRatio);
245 
246  break;
247 
248  case FINAL_AND_TOTAL:
249  firstThickness = firstLayerThickness
250  (
251  spec,
252  nLayers,
253  VGREAT, //firstThickness
254  VGREAT, //finalThickness
255  thickness, //totalThickness
256  VGREAT //expansionRatio
257  );
258  expansionRatio = layerExpansionRatio
259  (
260  spec,
261  nLayers,
262  VGREAT, //firstThickness
263  finalThickness, //finalThickness
264  thickness, //totalThickness
265  VGREAT //expansionRatio
266  );
267 
268  break;
269 
270  case FINAL_AND_EXPANSION:
271  firstThickness = firstLayerThickness
272  (
273  spec,
274  nLayers,
275  VGREAT, //firstThickness
276  finalThickness, //finalThickness
277  VGREAT, //thickness
278  expansionRatio //expansionRatio
279  );
280  thickness = layerThickness
281  (
282  spec,
283  nLayers,
284  VGREAT, //firstThickness
285  finalThickness, //finalThickness
286  VGREAT, //totalThickness
287  expansionRatio //expansionRatio
288  );
289  break;
290 
291  case TOTAL_AND_EXPANSION:
292  firstThickness = firstLayerThickness
293  (
294  spec,
295  nLayers,
296  VGREAT, //firstThickness
297  finalThickness, //finalThickness
298  VGREAT, //thickness
299  expansionRatio //expansionRatio
300  );
301  finalThickness =
302  thickness
303  *finalLayerThicknessRatio(nLayers, expansionRatio);
304 
305  break;
306 
307  case FIRST_AND_RELATIVE_FINAL:
308  thickness = layerThickness
309  (
310  spec,
311  nLayers,
312  firstThickness, //firstThickness
313  finalThickness, //finalThickness
314  VGREAT, //totalThickness
315  VGREAT //expansionRatio
316  );
317  expansionRatio = layerExpansionRatio
318  (
319  spec,
320  nLayers,
321  firstThickness, //firstThickness
322  finalThickness, //finalThickness
323  VGREAT, //totalThickness
324  VGREAT //expansionRatio
325  );
326 
327  break;
328 
329  default:
330  FatalErrorInFunction << "Illegal thicknessModel " << spec
331  << exit(FatalError);
332  break;
333  }
334 }
335 
336 
337 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
338 
339 Foam::layerParameters::layerParameters
340 (
341  const dictionary& dict,
343  const bool dryRun
344 )
345 :
346  dict_(dict),
347  dryRun_(dryRun),
348  numLayers_(boundaryMesh.size(), -1),
349  relativeSizes_
350  (
351  boundaryMesh.size(),
352  meshRefinement::get<bool>(dict, "relativeSizes", dryRun)
353  ),
354  layerModels_(boundaryMesh.size(), FIRST_AND_TOTAL),
355  firstLayerThickness_(boundaryMesh.size(), -123),
356  finalLayerThickness_(boundaryMesh.size(), -123),
357  thickness_(boundaryMesh.size(), -123),
358  expansionRatio_(boundaryMesh.size(), -123),
359  minThickness_
360  (
361  boundaryMesh.size(),
362  meshRefinement::get<scalar>(dict, "minThickness", dryRun)
363  ),
364  featureAngle_(meshRefinement::get<scalar>(dict, "featureAngle", dryRun)),
365  mergePatchFacesAngle_
366  (
367  dict.getOrDefault<scalar>
368  (
369  "mergePatchFacesAngle",
370  featureAngle_
371  )
372  ),
373  concaveAngle_
374  (
375  dict.getOrDefault<scalar>("concaveAngle", defaultConcaveAngle)
376  ),
377  nGrow_(meshRefinement::get<label>(dict, "nGrow", dryRun)),
378  maxFaceThicknessRatio_
379  (
380  meshRefinement::get<scalar>(dict, "maxFaceThicknessRatio", dryRun)
381  ),
382  nBufferCellsNoExtrude_
383  (
384  meshRefinement::get<label>(dict, "nBufferCellsNoExtrude", dryRun)
385  ),
386  nLayerIter_(meshRefinement::get<label>(dict, "nLayerIter", dryRun)),
387  nRelaxedIter_(labelMax),
388  additionalReporting_(dict.getOrDefault("additionalReporting", false)),
389  meshShrinker_
390  (
392  (
393  "meshShrinker",
394  medialAxisMeshMover::typeName
395  )
396  )
397 {
398  // Detect layer specification mode
399 
400  word spec;
401  if (dict.readIfPresent("thicknessModel", spec))
402  {
403  layerModels_ = thicknessModelTypeNames_[spec];
404  }
405  else
406  {
407  // Count number of specifications
408  label nSpec = 0;
409 
410  bool haveFirst = dict.found("firstLayerThickness");
411  if (haveFirst)
412  {
413  nSpec++;
414  }
415  bool haveFinal = dict.found("finalLayerThickness");
416  if (haveFinal)
417  {
418  nSpec++;
419  }
420  bool haveTotal = dict.found("thickness");
421  if (haveTotal)
422  {
423  nSpec++;
424  }
425  bool haveExp = dict.found("expansionRatio");
426  if (haveExp)
427  {
428  nSpec++;
429  }
430 
431  if (nSpec == 2 && haveFirst && haveTotal)
432  {
433  layerModels_ = FIRST_AND_TOTAL;
434  //Info<< "Layer thickness specified as first layer"
435  // << " and overall thickness." << endl;
436  }
437  else if (nSpec == 2 && haveFirst && haveExp)
438  {
439  layerModels_ = FIRST_AND_EXPANSION;
440  //Info<< "Layer thickness specified as first layer"
441  // << " and expansion ratio." << endl;
442  }
443  else if (nSpec == 2 && haveFinal && haveTotal)
444  {
445  layerModels_ = FINAL_AND_TOTAL;
446  //Info<< "Layer thickness specified as final layer"
447  // << " and overall thickness." << endl;
448  }
449  else if (nSpec == 2 && haveFinal && haveExp)
450  {
451  layerModels_ = FINAL_AND_EXPANSION;
452  //Info<< "Layer thickness specified as final layer"
453  // << " and expansion ratio." << endl;
454  }
455  else if (nSpec == 2 && haveTotal && haveExp)
456  {
457  layerModels_ = TOTAL_AND_EXPANSION;
458  //Info<< "Layer thickness specified as overall thickness"
459  // << " and expansion ratio." << endl;
460  }
461  else if (nSpec == 2 && haveFirst && haveFinal)
462  {
463  layerModels_ = FIRST_AND_RELATIVE_FINAL;
464  //Info<< "Layer thickness specified as absolute first and"
465  // << " relative final layer ratio." << endl;
466  }
467  else
468  {
470  << "Over- or underspecified layer thickness."
471  << " Please specify" << nl
472  << " first layer thickness ('firstLayerThickness')"
473  << " and overall thickness ('thickness') or" << nl
474  << " first layer thickness ('firstLayerThickness')"
475  << " and expansion ratio ('expansionRatio') or" << nl
476  << " final layer thickness ('finalLayerThickness')"
477  << " and expansion ratio ('expansionRatio') or" << nl
478  << " final layer thickness ('finalLayerThickness')"
479  << " and overall thickness ('thickness') or" << nl
480  << " overall thickness ('thickness')"
481  << " and expansion ratio ('expansionRatio'"
482  << exit(FatalIOError);
483  }
484  }
485 
486 
487  // Now we have determined the layer-specification read the actual fields
488  scalar firstThickness;
489  scalar finalThickness;
490  scalar thickness;
491  scalar expansionRatio;
492  readLayerParameters
493  (
494  true, // verbose
495  dict,
496  layerModels_[0], // spec
497  firstThickness,
498  finalThickness,
499  thickness,
500  expansionRatio
501  );
502  firstLayerThickness_ = firstThickness;
503  finalLayerThickness_ = finalThickness;
504  thickness_ = thickness;
505  expansionRatio_ = expansionRatio;
506 
507  dict.readIfPresent("nRelaxedIter", nRelaxedIter_);
508 
509  if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
510  {
512  << "Layer iterations should be >= 0." << nl
513  << "nLayerIter:" << nLayerIter_
514  << " nRelaxedIter:" << nRelaxedIter_
515  << exit(FatalIOError);
516  }
517 
518 
519  const dictionary& layersDict = meshRefinement::subDict
520  (
521  dict,
522  "layers",
523  dryRun
524  );
525 
526  for (const entry& dEntry : layersDict)
527  {
528  if (dEntry.isDict())
529  {
530  const keyType& key = dEntry.keyword();
531  const dictionary& layerDict = dEntry.dict();
532 
533  const labelHashSet patchIDs
534  (
535  boundaryMesh.patchSet(wordRes(one{}, wordRe(key)))
536  );
537 
538  if (patchIDs.size() == 0)
539  {
540  IOWarningInFunction(layersDict)
541  << "Layer specification for " << key
542  << " does not match any patch." << endl
543  << "Valid patches are " << boundaryMesh.names() << endl;
544  }
545  else
546  {
547  for (const label patchi : patchIDs)
548  {
549  numLayers_[patchi] =
550  layerDict.get<label>("nSurfaceLayers");
551 
552  word spec;
553  if (layerDict.readIfPresent("thicknessModel", spec))
554  {
555  // If the thickness model is explicitly specified
556  // we want full specification of all parameters
557  layerModels_[patchi] = thicknessModelTypeNames_[spec];
558  readLayerParameters
559  (
560  false, // verbose
561  layerDict,
562  layerModels_[patchi], // spec
563  firstLayerThickness_[patchi],
564  finalLayerThickness_[patchi],
565  thickness_[patchi],
566  expansionRatio_[patchi]
567  );
568  minThickness_[patchi] =
569  layerDict.get<scalar>("minThickness");
570  }
571  else
572  {
573  // Optional override of thickness parameters
574  switch (layerModels_[patchi])
575  {
576  case FIRST_AND_TOTAL:
577  layerDict.readIfPresent
578  (
579  "firstLayerThickness",
580  firstLayerThickness_[patchi]
581  );
582  layerDict.readIfPresent
583  (
584  "thickness",
585  thickness_[patchi]
586  );
587  break;
588 
589  case FIRST_AND_EXPANSION:
590  layerDict.readIfPresent
591  (
592  "firstLayerThickness",
593  firstLayerThickness_[patchi]
594  );
595  layerDict.readIfPresent
596  (
597  "expansionRatio",
598  expansionRatio_[patchi]
599  );
600  break;
601 
602  case FINAL_AND_TOTAL:
603  layerDict.readIfPresent
604  (
605  "finalLayerThickness",
606  finalLayerThickness_[patchi]
607  );
608  layerDict.readIfPresent
609  (
610  "thickness",
611  thickness_[patchi]
612  );
613  break;
614 
615  case FINAL_AND_EXPANSION:
616  layerDict.readIfPresent
617  (
618  "finalLayerThickness",
619  finalLayerThickness_[patchi]
620  );
621  layerDict.readIfPresent
622  (
623  "expansionRatio",
624  expansionRatio_[patchi]
625  );
626  break;
627 
628  case TOTAL_AND_EXPANSION:
629  layerDict.readIfPresent
630  (
631  "thickness",
632  thickness_[patchi]
633  );
634  layerDict.readIfPresent
635  (
636  "expansionRatio",
637  expansionRatio_[patchi]
638  );
639  break;
640 
641  case FIRST_AND_RELATIVE_FINAL:
642  layerDict.readIfPresent
643  (
644  "firstLayerThickness",
645  firstLayerThickness_[patchi]
646  );
647  layerDict.readIfPresent
648  (
649  "finalLayerThickness",
650  finalLayerThickness_[patchi]
651  );
652  break;
653 
654  default:
656  << "problem." << exit(FatalIOError);
657  break;
658  }
659 
660  layerDict.readIfPresent
661  (
662  "minThickness",
663  minThickness_[patchi]
664  );
665  }
666 
667  layerDict.readIfPresent
668  (
669  "relativeSizes",
670  relativeSizes_[patchi]
671  );
672  }
673  }
674  }
675  }
676 
677 
678  forAll(numLayers_, patchi)
679  {
680  // Calculate the remaining parameters
681  calculateLayerParameters
682  (
683  layerModels_[patchi],
684  numLayers_[patchi],
685  firstLayerThickness_[patchi],
686  finalLayerThickness_[patchi],
687  thickness_[patchi],
688  expansionRatio_[patchi]
689  );
690  }
691 }
692 
693 
694 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
695 
697 (
698  const thicknessModelType layerSpec,
699  const label nLayers,
700  const scalar firstLayerThickness,
701  const scalar finalLayerThickness,
702  const scalar totalThickness,
703  const scalar expansionRatio
704 )
705 {
706  switch (layerSpec)
707  {
708  case FIRST_AND_TOTAL:
709  case FINAL_AND_TOTAL:
710  case TOTAL_AND_EXPANSION:
711  {
712  return totalThickness;
713  }
714  break;
715 
716  case FIRST_AND_EXPANSION:
717  {
718  if (mag(expansionRatio-1) < SMALL)
719  {
720  return firstLayerThickness * nLayers;
721  }
722  else
723  {
724  return firstLayerThickness
725  *(1.0 - pow(expansionRatio, nLayers))
726  /(1.0 - expansionRatio);
727  }
728  }
729  break;
730 
731  case FINAL_AND_EXPANSION:
732  {
733  if (mag(expansionRatio-1) < SMALL)
734  {
735  return finalLayerThickness * nLayers;
736  }
737  else
738  {
739  scalar invExpansion = 1.0 / expansionRatio;
740  return finalLayerThickness
741  *(1.0 - pow(invExpansion, nLayers))
742  /(1.0 - invExpansion);
743  }
744  }
745  break;
746 
747  case FIRST_AND_RELATIVE_FINAL:
748  {
749  if (mag(expansionRatio-1) < SMALL)
750  {
751  return firstLayerThickness * nLayers;
752  }
753  else
754  {
755  scalar ratio = layerExpansionRatio
756  (
757  layerSpec,
758  nLayers,
759  firstLayerThickness,
760  finalLayerThickness,
761  totalThickness,
762  expansionRatio
763  );
764 
765  if (mag(ratio-1) < SMALL)
766  {
767  return firstLayerThickness * nLayers;
768  }
769  else
770  {
771  return firstLayerThickness *
772  (1.0 - pow(ratio, nLayers))
773  / (1.0 - ratio);
774  }
775  }
776  }
777  break;
778 
779  default:
780  {
782  << layerSpec << exit(FatalError);
783  return -VGREAT;
784  }
785  }
786 }
787 
788 
789 Foam::scalar Foam::layerParameters::layerExpansionRatio
790 (
791  const thicknessModelType layerSpec,
792  const label nLayers,
793  const scalar firstLayerThickness,
794  const scalar finalLayerThickness,
795  const scalar totalThickness,
796  const scalar expansionRatio
797 )
798 {
799  switch (layerSpec)
800  {
801  case FIRST_AND_EXPANSION:
802  case FINAL_AND_EXPANSION:
803  case TOTAL_AND_EXPANSION:
804  {
805  return expansionRatio;
806  }
807  break;
808 
809  case FIRST_AND_TOTAL:
810  {
811  if (firstLayerThickness < SMALL)
812  {
813  // Do what?
814  return 1;
815  }
816  else
817  {
818  return layerExpansionRatio
819  (
820  nLayers,
821  totalThickness/firstLayerThickness
822  );
823  }
824  }
825  break;
826 
827  case FINAL_AND_TOTAL:
828  {
829  if (finalLayerThickness < SMALL)
830  {
831  // Do what?
832  return 1;
833  }
834  else
835  {
836  return
837  1.0
838  / layerExpansionRatio
839  (
840  nLayers,
841  totalThickness/finalLayerThickness
842  );
843  }
844  }
845  break;
846 
847  case FIRST_AND_RELATIVE_FINAL:
848  {
849  if (firstLayerThickness < SMALL || nLayers <= 1)
850  {
851  return 1.0;
852  }
853  else
854  {
855  // Note: at this point the finalLayerThickness is already
856  // absolute
857  return pow
858  (
859  finalLayerThickness/firstLayerThickness,
860  1.0/(nLayers-1)
861  );
862  }
863  }
864  break;
865 
866  default:
867  {
869  << "Illegal thickness specification" << exit(FatalError);
870  return -VGREAT;
871  }
872  }
873 }
874 
875 
877 (
878  const thicknessModelType layerSpec,
879  const label nLayers,
880  const scalar firstLayerThickness,
881  const scalar finalLayerThickness,
882  const scalar totalThickness,
883  const scalar expansionRatio
884 )
885 {
886  switch (layerSpec)
887  {
888  case FIRST_AND_EXPANSION:
889  case FIRST_AND_TOTAL:
890  case FIRST_AND_RELATIVE_FINAL:
891  {
892  return firstLayerThickness;
893  }
894 
895  case FINAL_AND_EXPANSION:
896  {
897  if (expansionRatio < SMALL)
898  {
899  // Do what?
900  return 0.0;
901  }
902  else
903  {
904  return finalLayerThickness*pow(1.0/expansionRatio, nLayers-1);
905  }
906  }
907  break;
908 
909  case FINAL_AND_TOTAL:
910  {
911  scalar r = layerExpansionRatio
912  (
913  layerSpec,
914  nLayers,
915  firstLayerThickness,
916  finalLayerThickness,
917  totalThickness,
918  expansionRatio
919  );
920  return finalLayerThickness/pow(r, nLayers-1);
921  }
922  break;
923 
924  case TOTAL_AND_EXPANSION:
925  {
926  scalar r = finalLayerThicknessRatio
927  (
928  nLayers,
929  expansionRatio
930  );
931  scalar finalThickness = r*totalThickness;
932  return finalThickness/pow(expansionRatio, nLayers-1);
933  }
934  break;
935 
936  default:
937  {
939  << "Illegal thickness specification" << exit(FatalError);
940  return -VGREAT;
941  }
942  }
943 }
944 
945 
947 (
948  const label nLayers,
949  const scalar expansionRatio
950 )
951 {
952  if (nLayers > 0)
953  {
954  if (mag(expansionRatio-1) < SMALL)
955  {
956  return 1.0/nLayers;
957  }
958  else
959  {
960  return
961  pow(expansionRatio, nLayers - 1)
962  *(1.0 - expansionRatio)
963  /(1.0 - pow(expansionRatio, nLayers));
964  }
965  }
966  else
967  {
968  return 0.0;
969  }
970 }
971 
972 
973 // ************************************************************************* //
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
Foam::layerParameters::layerThickness
static scalar layerThickness(const thicknessModelType, const label nLayers, const scalar firstLayerThickness, const scalar finalLayerThickness, const scalar totalThickness, const scalar expansionRatio)
Determine overall thickness. Uses two of the four parameters.
Definition: layerParameters.C:697
Foam::labelMax
constexpr label labelMax
Definition: label.H:61
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:63
Foam::dictionary::found
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionaryI.H:87
Foam::maxIters
static constexpr int maxIters
Definition: searchableSphere.C:156
Foam::meshRefinement::subDict
static const dictionary & subDict(const dictionary &dict, const word &keyword, const bool noExit, enum keyType::option matchOpt=keyType::REGEX)
Wrapper around dictionary::subDict which does not exit.
Definition: meshRefinement.C:3451
Foam::glTF::key
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:108
unitConversion.H
Unit conversion functions.
Foam::one
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:61
medialAxisMeshMover.H
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:107
Foam::HashSet< label, Hash< label > >
Foam::wordRe
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition: wordRe.H:80
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::layerParameters::finalLayerThicknessRatio
static scalar finalLayerThicknessRatio(const label nLayers, const scalar expansionRatio)
Determine ratio of final layer thickness to.
Definition: layerParameters.C:947
searchableSurfaces.H
Foam::keyType
A class for handling keywords in dictionaries.
Definition: keyType.H:68
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
refinementSurfaces.H
Foam::pow
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Definition: dimensionedScalar.C:75
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
layerParameters.H
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::layerParameters::firstLayerThickness
const scalarField & firstLayerThickness() const
Wanted thickness of the layer nearest to the wall.
Definition: layerParameters.H:248
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::wordRes
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:51
polyBoundaryMesh.H
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:62
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::layerParameters::thicknessModelType
thicknessModelType
Enumeration defining the layer specification:
Definition: layerParameters.H:70
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:340
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:148
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:405