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-2020 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 = readScalar
133  (
134  dict.lookup("firstLayerThickness")
135  );
136  thickness = readScalar(dict.lookup("thickness"));
137  break;
138 
139  case FIRST_AND_EXPANSION:
140  if (verbose)
141  {
142  Info<< "Layer specification as" << nl
143  << "- first layer thickness ('firstLayerThickness')" << nl
144  << "- expansion ratio ('expansionRatio')" << endl;
145  }
146  firstLayerThickness = readScalar
147  (
148  dict.lookup("firstLayerThickness")
149  );
150  expansionRatio = readScalar(dict.lookup("expansionRatio"));
151  break;
152 
153  case FINAL_AND_TOTAL:
154  if (verbose)
155  {
156  Info<< "Layer specification as" << nl
157  << "- final layer thickness ('finalLayerThickness')" << nl
158  << "- overall thickness ('thickness')" << endl;
159  }
160  finalLayerThickness = readScalar
161  (
162  dict.lookup("finalLayerThickness")
163  );
164  thickness = readScalar(dict.lookup("thickness"));
165  break;
166 
167  case FINAL_AND_EXPANSION:
168  if (verbose)
169  {
170  Info<< "Layer specification as" << nl
171  << "- final layer thickness ('finalLayerThickness')" << nl
172  << "- expansion ratio ('expansionRatio')" << endl;
173  }
174  finalLayerThickness = readScalar
175  (
176  dict.lookup("finalLayerThickness")
177  );
178  expansionRatio = readScalar(dict.lookup("expansionRatio"));
179  break;
180 
181  case TOTAL_AND_EXPANSION:
182  if (verbose)
183  {
184  Info<< "Layer specification as" << nl
185  << "- overall thickness ('thickness')" << nl
186  << "- expansion ratio ('expansionRatio')" << endl;
187  }
188  thickness = readScalar(dict.lookup("thickness"));
189  expansionRatio = readScalar(dict.lookup("expansionRatio"));
190  break;
191 
192  case FIRST_AND_RELATIVE_FINAL:
193  if (verbose)
194  {
195  Info<< "Layer specification as" << nl
196  << "- absolute first layer thickness"
197  << " ('firstLayerThickness')"
198  << nl
199  << "- and final layer thickness"
200  << " ('finalLayerThickness')" << nl
201  << endl;
202  }
203  firstLayerThickness = readScalar
204  (
205  dict.lookup("firstLayerThickness")
206  );
207  finalLayerThickness = readScalar
208  (
209  dict.lookup("finalLayerThickness")
210  );
211  break;
212 
213  default:
215  (
216  "layerParameters::layerParameters(..)",
217  dict
218  ) << "problem." << exit(FatalIOError);
219  break;
220  }
221 }
222 
223 
224 void Foam::layerParameters::calculateLayerParameters
225 (
226  const thicknessModelType& spec,
227  const label nLayers,
228  scalar& firstThickness,
229  scalar& finalThickness,
230  scalar& thickness,
231  scalar& expansionRatio
232 )
233 {
234  // Calculate the non-read parameters
235  switch (spec)
236  {
237  case FIRST_AND_TOTAL:
238  expansionRatio = layerExpansionRatio
239  (
240  spec,
241  nLayers,
242  firstThickness,
243  VGREAT,
244  thickness, //totalThickness
245  VGREAT //expansionRatio
246  );
247  finalThickness =
248  thickness
249  *finalLayerThicknessRatio(nLayers, expansionRatio);
250 
251  break;
252 
253  case FIRST_AND_EXPANSION:
254  thickness = layerThickness
255  (
256  spec,
257  nLayers,
258  firstThickness, //firstThickness
259  VGREAT, //finalThickness
260  VGREAT, //totalThickness
261  expansionRatio //expansionRatio
262  );
263  finalThickness =
264  thickness
265  *finalLayerThicknessRatio(nLayers, expansionRatio);
266 
267  break;
268 
269  case FINAL_AND_TOTAL:
270  firstThickness = firstLayerThickness
271  (
272  spec,
273  nLayers,
274  VGREAT, //firstThickness
275  VGREAT, //finalThickness
276  thickness, //totalThickness
277  VGREAT //expansionRatio
278  );
279  expansionRatio = layerExpansionRatio
280  (
281  spec,
282  nLayers,
283  VGREAT, //firstThickness
284  finalThickness, //finalThickness
285  thickness, //totalThickness
286  VGREAT //expansionRatio
287  );
288 
289  break;
290 
291  case FINAL_AND_EXPANSION:
292  firstThickness = firstLayerThickness
293  (
294  spec,
295  nLayers,
296  VGREAT, //firstThickness
297  finalThickness, //finalThickness
298  VGREAT, //thickness
299  expansionRatio //expansionRatio
300  );
301  thickness = layerThickness
302  (
303  spec,
304  nLayers,
305  VGREAT, //firstThickness
306  finalThickness, //finalThickness
307  VGREAT, //totalThickness
308  expansionRatio //expansionRatio
309  );
310  break;
311 
312  case TOTAL_AND_EXPANSION:
313  firstThickness = firstLayerThickness
314  (
315  spec,
316  nLayers,
317  VGREAT, //firstThickness
318  finalThickness, //finalThickness
319  VGREAT, //thickness
320  expansionRatio //expansionRatio
321  );
322  finalThickness =
323  thickness
324  *finalLayerThicknessRatio(nLayers, expansionRatio);
325 
326  break;
327 
328  case FIRST_AND_RELATIVE_FINAL:
329  thickness = layerThickness
330  (
331  spec,
332  nLayers,
333  firstThickness, //firstThickness
334  finalThickness, //finalThickness
335  VGREAT, //totalThickness
336  VGREAT //expansionRatio
337  );
338  expansionRatio = layerExpansionRatio
339  (
340  spec,
341  nLayers,
342  firstThickness, //firstThickness
343  finalThickness, //finalThickness
344  VGREAT, //totalThickness
345  VGREAT //expansionRatio
346  );
347 
348  break;
349 
350  default:
351  FatalErrorInFunction << "Illegal thicknessModel " << spec
352  << exit(FatalError);
353  break;
354  }
355 }
356 
357 
358 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
359 
360 Foam::layerParameters::layerParameters
361 (
362  const dictionary& dict,
364  const bool dryRun
365 )
366 :
367  dict_(dict),
368  dryRun_(dryRun),
369  numLayers_(boundaryMesh.size(), -1),
370  relativeSizes_
371  (
372  boundaryMesh.size(),
373  meshRefinement::get<bool>(dict, "relativeSizes", dryRun)
374  ),
375  layerModels_(boundaryMesh.size(), FIRST_AND_TOTAL),
376  firstLayerThickness_(boundaryMesh.size(), -123),
377  finalLayerThickness_(boundaryMesh.size(), -123),
378  thickness_(boundaryMesh.size(), -123),
379  expansionRatio_(boundaryMesh.size(), -123),
380  minThickness_
381  (
382  boundaryMesh.size(),
383  meshRefinement::get<scalar>(dict, "minThickness", dryRun)
384  ),
385  featureAngle_(meshRefinement::get<scalar>(dict, "featureAngle", dryRun)),
386  mergePatchFacesAngle_
387  (
388  dict.getOrDefault<scalar>
389  (
390  "mergePatchFacesAngle",
391  featureAngle_
392  )
393  ),
394  concaveAngle_
395  (
396  dict.getOrDefault<scalar>("concaveAngle", defaultConcaveAngle)
397  ),
398  nGrow_(meshRefinement::get<label>(dict, "nGrow", dryRun)),
399  maxFaceThicknessRatio_
400  (
401  meshRefinement::get<scalar>(dict, "maxFaceThicknessRatio", dryRun)
402  ),
403  nBufferCellsNoExtrude_
404  (
405  meshRefinement::get<label>(dict, "nBufferCellsNoExtrude", dryRun)
406  ),
407  nLayerIter_(meshRefinement::get<label>(dict, "nLayerIter", dryRun)),
408  nRelaxedIter_(labelMax),
409  additionalReporting_(dict.getOrDefault("additionalReporting", false)),
410  meshShrinker_
411  (
413  (
414  "meshShrinker",
415  medialAxisMeshMover::typeName
416  )
417  )
418 {
419  // Detect layer specification mode
420 
421  word spec;
422  if (dict.readIfPresent("thicknessModel", spec))
423  {
424  layerModels_ = thicknessModelTypeNames_[spec];
425  }
426  else
427  {
428  // Count number of specifications
429  label nSpec = 0;
430 
431  bool haveFirst = dict.found("firstLayerThickness");
432  if (haveFirst)
433  {
434  nSpec++;
435  }
436  bool haveFinal = dict.found("finalLayerThickness");
437  if (haveFinal)
438  {
439  nSpec++;
440  }
441  bool haveTotal = dict.found("thickness");
442  if (haveTotal)
443  {
444  nSpec++;
445  }
446  bool haveExp = dict.found("expansionRatio");
447  if (haveExp)
448  {
449  nSpec++;
450  }
451 
452  if (nSpec == 2 && haveFirst && haveTotal)
453  {
454  layerModels_ = FIRST_AND_TOTAL;
455  //Info<< "Layer thickness specified as first layer"
456  // << " and overall thickness." << endl;
457  }
458  else if (nSpec == 2 && haveFirst && haveExp)
459  {
460  layerModels_ = FIRST_AND_EXPANSION;
461  //Info<< "Layer thickness specified as first layer"
462  // << " and expansion ratio." << endl;
463  }
464  else if (nSpec == 2 && haveFinal && haveTotal)
465  {
466  layerModels_ = FINAL_AND_TOTAL;
467  //Info<< "Layer thickness specified as final layer"
468  // << " and overall thickness." << endl;
469  }
470  else if (nSpec == 2 && haveFinal && haveExp)
471  {
472  layerModels_ = FINAL_AND_EXPANSION;
473  //Info<< "Layer thickness specified as final layer"
474  // << " and expansion ratio." << endl;
475  }
476  else if (nSpec == 2 && haveTotal && haveExp)
477  {
478  layerModels_ = TOTAL_AND_EXPANSION;
479  //Info<< "Layer thickness specified as overall thickness"
480  // << " and expansion ratio." << endl;
481  }
482  else if (nSpec == 2 && haveFirst && haveFinal)
483  {
484  layerModels_ = FIRST_AND_RELATIVE_FINAL;
485  //Info<< "Layer thickness specified as absolute first and"
486  // << " relative final layer ratio." << endl;
487  }
488  else
489  {
491  << "Over- or underspecified layer thickness."
492  << " Please specify" << nl
493  << " first layer thickness ('firstLayerThickness')"
494  << " and overall thickness ('thickness') or" << nl
495  << " first layer thickness ('firstLayerThickness')"
496  << " and expansion ratio ('expansionRatio') or" << nl
497  << " final layer thickness ('finalLayerThickness')"
498  << " and expansion ratio ('expansionRatio') or" << nl
499  << " final layer thickness ('finalLayerThickness')"
500  << " and overall thickness ('thickness') or" << nl
501  << " overall thickness ('thickness')"
502  << " and expansion ratio ('expansionRatio'"
503  << exit(FatalIOError);
504  }
505  }
506 
507 
508  // Now we have determined the layer-specification read the actual fields
509  scalar firstThickness;
510  scalar finalThickness;
511  scalar thickness;
512  scalar expansionRatio;
513  readLayerParameters
514  (
515  true, // verbose
516  dict,
517  layerModels_[0], // spec
518  firstThickness,
519  finalThickness,
520  thickness,
521  expansionRatio
522  );
523  firstLayerThickness_ = firstThickness;
524  finalLayerThickness_ = finalThickness;
525  thickness_ = thickness;
526  expansionRatio_ = expansionRatio;
527 
528  dict.readIfPresent("nRelaxedIter", nRelaxedIter_);
529 
530  if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
531  {
533  << "Layer iterations should be >= 0." << nl
534  << "nLayerIter:" << nLayerIter_
535  << " nRelaxedIter:" << nRelaxedIter_
536  << exit(FatalIOError);
537  }
538 
539 
540  const dictionary& layersDict = meshRefinement::subDict
541  (
542  dict,
543  "layers",
544  dryRun
545  );
546 
547  for (const entry& dEntry : layersDict)
548  {
549  if (dEntry.isDict())
550  {
551  const keyType& key = dEntry.keyword();
552  const dictionary& layerDict = dEntry.dict();
553 
554  const labelHashSet patchIDs
555  (
556  boundaryMesh.patchSet(List<wordRe>(1, wordRe(key)))
557  );
558 
559  if (patchIDs.size() == 0)
560  {
561  IOWarningInFunction(layersDict)
562  << "Layer specification for " << key
563  << " does not match any patch." << endl
564  << "Valid patches are " << boundaryMesh.names() << endl;
565  }
566  else
567  {
568  for (const label patchi : patchIDs)
569  {
570  numLayers_[patchi] =
571  layerDict.get<label>("nSurfaceLayers");
572 
573  word spec;
574  if (layerDict.readIfPresent("thicknessModel", spec))
575  {
576  // If the thickness model is explicitly specified
577  // we want full specification of all parameters
578  layerModels_[patchi] = thicknessModelTypeNames_[spec];
579  readLayerParameters
580  (
581  false, // verbose
582  layerDict,
583  layerModels_[patchi], // spec
584  firstLayerThickness_[patchi],
585  finalLayerThickness_[patchi],
586  thickness_[patchi],
587  expansionRatio_[patchi]
588  );
589  minThickness_[patchi] = readScalar
590  (
591  layerDict.lookup("minThickness")
592  );
593  }
594  else
595  {
596  // Optional override of thickness parameters
597  switch (layerModels_[patchi])
598  {
599  case FIRST_AND_TOTAL:
600  layerDict.readIfPresent
601  (
602  "firstLayerThickness",
603  firstLayerThickness_[patchi]
604  );
605  layerDict.readIfPresent
606  (
607  "thickness",
608  thickness_[patchi]
609  );
610  break;
611 
612  case FIRST_AND_EXPANSION:
613  layerDict.readIfPresent
614  (
615  "firstLayerThickness",
616  firstLayerThickness_[patchi]
617  );
618  layerDict.readIfPresent
619  (
620  "expansionRatio",
621  expansionRatio_[patchi]
622  );
623  break;
624 
625  case FINAL_AND_TOTAL:
626  layerDict.readIfPresent
627  (
628  "finalLayerThickness",
629  finalLayerThickness_[patchi]
630  );
631  layerDict.readIfPresent
632  (
633  "thickness",
634  thickness_[patchi]
635  );
636  break;
637 
638  case FINAL_AND_EXPANSION:
639  layerDict.readIfPresent
640  (
641  "finalLayerThickness",
642  finalLayerThickness_[patchi]
643  );
644  layerDict.readIfPresent
645  (
646  "expansionRatio",
647  expansionRatio_[patchi]
648  );
649  break;
650 
651  case TOTAL_AND_EXPANSION:
652  layerDict.readIfPresent
653  (
654  "thickness",
655  thickness_[patchi]
656  );
657  layerDict.readIfPresent
658  (
659  "expansionRatio",
660  expansionRatio_[patchi]
661  );
662  break;
663 
664  case FIRST_AND_RELATIVE_FINAL:
665  layerDict.readIfPresent
666  (
667  "firstLayerThickness",
668  firstLayerThickness_[patchi]
669  );
670  layerDict.readIfPresent
671  (
672  "finalLayerThickness",
673  finalLayerThickness_[patchi]
674  );
675  break;
676 
677  default:
679  << "problem." << exit(FatalIOError);
680  break;
681  }
682 
683  layerDict.readIfPresent
684  (
685  "minThickness",
686  minThickness_[patchi]
687  );
688  }
689 
690  layerDict.readIfPresent
691  (
692  "relativeSizes",
693  relativeSizes_[patchi]
694  );
695  }
696  }
697  }
698  }
699 
700 
701  forAll(numLayers_, patchi)
702  {
703  // Calculate the remaining parameters
704  calculateLayerParameters
705  (
706  layerModels_[patchi],
707  numLayers_[patchi],
708  firstLayerThickness_[patchi],
709  finalLayerThickness_[patchi],
710  thickness_[patchi],
711  expansionRatio_[patchi]
712  );
713  }
714 }
715 
716 
717 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
718 
720 (
721  const thicknessModelType layerSpec,
722  const label nLayers,
723  const scalar firstLayerThickness,
724  const scalar finalLayerThickness,
725  const scalar totalThickness,
726  const scalar expansionRatio
727 )
728 {
729  switch (layerSpec)
730  {
731  case FIRST_AND_TOTAL:
732  case FINAL_AND_TOTAL:
733  case TOTAL_AND_EXPANSION:
734  {
735  return totalThickness;
736  }
737  break;
738 
739  case FIRST_AND_EXPANSION:
740  {
741  if (mag(expansionRatio-1) < SMALL)
742  {
743  return firstLayerThickness * nLayers;
744  }
745  else
746  {
747  return firstLayerThickness
748  *(1.0 - pow(expansionRatio, nLayers))
749  /(1.0 - expansionRatio);
750  }
751  }
752  break;
753 
754  case FINAL_AND_EXPANSION:
755  {
756  if (mag(expansionRatio-1) < SMALL)
757  {
758  return finalLayerThickness * nLayers;
759  }
760  else
761  {
762  scalar invExpansion = 1.0 / expansionRatio;
763  return finalLayerThickness
764  *(1.0 - pow(invExpansion, nLayers))
765  /(1.0 - invExpansion);
766  }
767  }
768  break;
769 
770  case FIRST_AND_RELATIVE_FINAL:
771  {
772  if (mag(expansionRatio-1) < SMALL)
773  {
774  return firstLayerThickness * nLayers;
775  }
776  else
777  {
778  scalar ratio = layerExpansionRatio
779  (
780  layerSpec,
781  nLayers,
782  firstLayerThickness,
783  finalLayerThickness,
784  totalThickness,
785  expansionRatio
786  );
787 
788  if (mag(ratio-1) < SMALL)
789  {
790  return firstLayerThickness * nLayers;
791  }
792  else
793  {
794  return firstLayerThickness *
795  (1.0 - pow(ratio, nLayers))
796  / (1.0 - ratio);
797  }
798  }
799  }
800  break;
801 
802  default:
803  {
805  << layerSpec << exit(FatalError);
806  return -VGREAT;
807  }
808  }
809 }
810 
811 
812 Foam::scalar Foam::layerParameters::layerExpansionRatio
813 (
814  const thicknessModelType layerSpec,
815  const label nLayers,
816  const scalar firstLayerThickness,
817  const scalar finalLayerThickness,
818  const scalar totalThickness,
819  const scalar expansionRatio
820 )
821 {
822  switch (layerSpec)
823  {
824  case FIRST_AND_EXPANSION:
825  case FINAL_AND_EXPANSION:
826  case TOTAL_AND_EXPANSION:
827  {
828  return expansionRatio;
829  }
830  break;
831 
832  case FIRST_AND_TOTAL:
833  {
834  if (firstLayerThickness < SMALL)
835  {
836  // Do what?
837  return 1;
838  }
839  else
840  {
841  return layerExpansionRatio
842  (
843  nLayers,
844  totalThickness/firstLayerThickness
845  );
846  }
847  }
848  break;
849 
850  case FINAL_AND_TOTAL:
851  {
852  if (finalLayerThickness < SMALL)
853  {
854  // Do what?
855  return 1;
856  }
857  else
858  {
859  return
860  1.0
861  / layerExpansionRatio
862  (
863  nLayers,
864  totalThickness/finalLayerThickness
865  );
866  }
867  }
868  break;
869 
870  case FIRST_AND_RELATIVE_FINAL:
871  {
872  if (firstLayerThickness < SMALL || nLayers <= 1)
873  {
874  return 1.0;
875  }
876  else
877  {
878  // Note: at this point the finalLayerThickness is already
879  // absolute
880  return pow
881  (
882  finalLayerThickness/firstLayerThickness,
883  1.0/(nLayers-1)
884  );
885  }
886  }
887  break;
888 
889  default:
890  {
892  << "Illegal thickness specification" << exit(FatalError);
893  return -VGREAT;
894  }
895  }
896 }
897 
898 
900 (
901  const thicknessModelType layerSpec,
902  const label nLayers,
903  const scalar firstLayerThickness,
904  const scalar finalLayerThickness,
905  const scalar totalThickness,
906  const scalar expansionRatio
907 )
908 {
909  switch (layerSpec)
910  {
911  case FIRST_AND_EXPANSION:
912  case FIRST_AND_TOTAL:
913  case FIRST_AND_RELATIVE_FINAL:
914  {
915  return firstLayerThickness;
916  }
917 
918  case FINAL_AND_EXPANSION:
919  {
920  if (expansionRatio < SMALL)
921  {
922  // Do what?
923  return 0.0;
924  }
925  else
926  {
927  return finalLayerThickness*pow(1.0/expansionRatio, nLayers-1);
928  }
929  }
930  break;
931 
932  case FINAL_AND_TOTAL:
933  {
934  scalar r = layerExpansionRatio
935  (
936  layerSpec,
937  nLayers,
938  firstLayerThickness,
939  finalLayerThickness,
940  totalThickness,
941  expansionRatio
942  );
943  return finalLayerThickness/pow(r, nLayers-1);
944  }
945  break;
946 
947  case TOTAL_AND_EXPANSION:
948  {
949  scalar r = finalLayerThicknessRatio
950  (
951  nLayers,
952  expansionRatio
953  );
954  scalar finalThickness = r*totalThickness;
955  return finalThickness/pow(expansionRatio, nLayers-1);
956  }
957  break;
958 
959  default:
960  {
962  << "Illegal thickness specification" << exit(FatalError);
963  return -VGREAT;
964  }
965  }
966 }
967 
968 
970 (
971  const label nLayers,
972  const scalar expansionRatio
973 )
974 {
975  if (nLayers > 0)
976  {
977  if (mag(expansionRatio-1) < SMALL)
978  {
979  return 1.0/nLayers;
980  }
981  else
982  {
983  return
984  pow(expansionRatio, nLayers - 1)
985  *(1.0 - expansionRatio)
986  /(1.0 - pow(expansionRatio, nLayers));
987  }
988  }
989  else
990  {
991  return 0.0;
992  }
993 }
994 
995 
996 // ************************************************************************* //
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:720
Foam::labelMax
constexpr label labelMax
Definition: label.H:61
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:62
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: dictionary.C:364
Foam::maxIters
static constexpr int maxIters
Definition: searchableSphere.C:155
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:3465
unitConversion.H
Unit conversion functions.
medialAxisMeshMover.H
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:81
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:72
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:970
searchableSurfaces.H
Foam::keyType
A class for handling keywords in dictionaries.
Definition: keyType.H:60
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
refinementSurfaces.H
FatalIOErrorIn
#define FatalIOErrorIn(functionName, ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:395
Foam::pow
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Definition: dimensionedScalar.C:75
Foam::dictionary::lookup
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.C:424
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:121
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:381
Foam::nl
constexpr char nl
Definition: Ostream.H:385
layerParameters.H
Foam::List< wordRe >
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
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:401
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:315
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:122
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:417