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-------------------------------------------------------------------------------
11License
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
38const Foam::Enum
39<
41>
42Foam::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
52const Foam::scalar Foam::layerParameters::defaultConcaveAngle = 90;
53
54
55// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
56
57Foam::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
111void 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
203void 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
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 (
391 dict.getOrDefault
392 (
393 "meshShrinker",
394 medialAxisMeshMover::typeName
395 )
396 ),
397 nOuterIter_(dict.getOrDefault<scalar>("nOuterIter", 1))
398{
399 // Detect layer specification mode
400
401 word spec;
402 if (dict.readIfPresent("thicknessModel", spec))
403 {
404 layerModels_ = thicknessModelTypeNames_[spec];
405 }
406 else
407 {
408 // Count number of specifications
409 label nSpec = 0;
410
411 bool haveFirst = dict.found("firstLayerThickness");
412 if (haveFirst)
413 {
414 nSpec++;
415 }
416 bool haveFinal = dict.found("finalLayerThickness");
417 if (haveFinal)
418 {
419 nSpec++;
420 }
421 bool haveTotal = dict.found("thickness");
422 if (haveTotal)
423 {
424 nSpec++;
425 }
426 bool haveExp = dict.found("expansionRatio");
427 if (haveExp)
428 {
429 nSpec++;
430 }
431
432 if (nSpec == 2 && haveFirst && haveTotal)
433 {
434 layerModels_ = FIRST_AND_TOTAL;
435 //Info<< "Layer thickness specified as first layer"
436 // << " and overall thickness." << endl;
437 }
438 else if (nSpec == 2 && haveFirst && haveExp)
439 {
440 layerModels_ = FIRST_AND_EXPANSION;
441 //Info<< "Layer thickness specified as first layer"
442 // << " and expansion ratio." << endl;
443 }
444 else if (nSpec == 2 && haveFinal && haveTotal)
445 {
446 layerModels_ = FINAL_AND_TOTAL;
447 //Info<< "Layer thickness specified as final layer"
448 // << " and overall thickness." << endl;
449 }
450 else if (nSpec == 2 && haveFinal && haveExp)
451 {
452 layerModels_ = FINAL_AND_EXPANSION;
453 //Info<< "Layer thickness specified as final layer"
454 // << " and expansion ratio." << endl;
455 }
456 else if (nSpec == 2 && haveTotal && haveExp)
457 {
458 layerModels_ = TOTAL_AND_EXPANSION;
459 //Info<< "Layer thickness specified as overall thickness"
460 // << " and expansion ratio." << endl;
461 }
462 else if (nSpec == 2 && haveFirst && haveFinal)
463 {
464 layerModels_ = FIRST_AND_RELATIVE_FINAL;
465 //Info<< "Layer thickness specified as absolute first and"
466 // << " relative final layer ratio." << endl;
467 }
468 else
469 {
471 << "Over- or underspecified layer thickness."
472 << " Please specify" << nl
473 << " first layer thickness ('firstLayerThickness')"
474 << " and overall thickness ('thickness') or" << nl
475 << " first layer thickness ('firstLayerThickness')"
476 << " and expansion ratio ('expansionRatio') or" << nl
477 << " final layer thickness ('finalLayerThickness')"
478 << " and expansion ratio ('expansionRatio') or" << nl
479 << " final layer thickness ('finalLayerThickness')"
480 << " and overall thickness ('thickness') or" << nl
481 << " overall thickness ('thickness')"
482 << " and expansion ratio ('expansionRatio'"
483 << exit(FatalIOError);
484 }
485 }
486
487
488 // Now we have determined the layer-specification read the actual fields
489 scalar firstThickness;
490 scalar finalThickness;
491 scalar thickness;
492 scalar expansionRatio;
493 readLayerParameters
494 (
495 true, // verbose
496 dict,
497 layerModels_[0], // spec
498 firstThickness,
499 finalThickness,
500 thickness,
502 );
503 firstLayerThickness_ = firstThickness;
504 finalLayerThickness_ = finalThickness;
505 thickness_ = thickness;
506 expansionRatio_ = expansionRatio;
507
508 dict.readIfPresent("nRelaxedIter", nRelaxedIter_);
509
510 if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
511 {
513 << "Layer iterations should be >= 0." << nl
514 << "nLayerIter:" << nLayerIter_
515 << " nRelaxedIter:" << nRelaxedIter_
516 << exit(FatalIOError);
517 }
518
519
520 const dictionary& layersDict = meshRefinement::subDict
521 (
522 dict,
523 "layers",
524 dryRun
525 );
526
527 for (const entry& dEntry : layersDict)
528 {
529 if (dEntry.isDict())
530 {
531 const keyType& key = dEntry.keyword();
532 const dictionary& layerDict = dEntry.dict();
533
534 const labelHashSet patchIDs
535 (
536 boundaryMesh.patchSet(wordRes(one{}, wordRe(key)))
537 );
538
539 if (patchIDs.size() == 0)
540 {
541 IOWarningInFunction(layersDict)
542 << "Layer specification for " << key
543 << " does not match any patch." << endl
544 << "Valid patches are " << boundaryMesh.names() << endl;
545 }
546 else
547 {
548 for (const label patchi : patchIDs)
549 {
550 numLayers_[patchi] =
551 layerDict.get<label>("nSurfaceLayers");
552
553 word spec;
554 if (layerDict.readIfPresent("thicknessModel", spec))
555 {
556 // If the thickness model is explicitly specified
557 // we want full specification of all parameters
558 layerModels_[patchi] = thicknessModelTypeNames_[spec];
559 readLayerParameters
560 (
561 false, // verbose
562 layerDict,
563 layerModels_[patchi], // spec
564 firstLayerThickness_[patchi],
565 finalLayerThickness_[patchi],
566 thickness_[patchi],
567 expansionRatio_[patchi]
568 );
569 minThickness_[patchi] =
570 layerDict.get<scalar>("minThickness");
571 }
572 else
573 {
574 // Optional override of thickness parameters
575 switch (layerModels_[patchi])
576 {
577 case FIRST_AND_TOTAL:
578 layerDict.readIfPresent
579 (
580 "firstLayerThickness",
581 firstLayerThickness_[patchi]
582 );
583 layerDict.readIfPresent
584 (
585 "thickness",
586 thickness_[patchi]
587 );
588 break;
589
591 layerDict.readIfPresent
592 (
593 "firstLayerThickness",
594 firstLayerThickness_[patchi]
595 );
596 layerDict.readIfPresent
597 (
598 "expansionRatio",
599 expansionRatio_[patchi]
600 );
601 break;
602
603 case FINAL_AND_TOTAL:
604 layerDict.readIfPresent
605 (
606 "finalLayerThickness",
607 finalLayerThickness_[patchi]
608 );
609 layerDict.readIfPresent
610 (
611 "thickness",
612 thickness_[patchi]
613 );
614 break;
615
617 layerDict.readIfPresent
618 (
619 "finalLayerThickness",
620 finalLayerThickness_[patchi]
621 );
622 layerDict.readIfPresent
623 (
624 "expansionRatio",
625 expansionRatio_[patchi]
626 );
627 break;
628
630 layerDict.readIfPresent
631 (
632 "thickness",
633 thickness_[patchi]
634 );
635 layerDict.readIfPresent
636 (
637 "expansionRatio",
638 expansionRatio_[patchi]
639 );
640 break;
641
643 layerDict.readIfPresent
644 (
645 "firstLayerThickness",
646 firstLayerThickness_[patchi]
647 );
648 layerDict.readIfPresent
649 (
650 "finalLayerThickness",
651 finalLayerThickness_[patchi]
652 );
653 break;
654
655 default:
657 << "problem." << exit(FatalIOError);
658 break;
659 }
660
661 layerDict.readIfPresent
662 (
663 "minThickness",
664 minThickness_[patchi]
665 );
666 }
667
668 layerDict.readIfPresent
669 (
670 "relativeSizes",
671 relativeSizes_[patchi]
672 );
673 }
674 }
675 }
676 }
677
678
679 forAll(numLayers_, patchi)
680 {
681 // Calculate the remaining parameters
682 calculateLayerParameters
683 (
684 layerModels_[patchi],
685 numLayers_[patchi],
686 firstLayerThickness_[patchi],
687 finalLayerThickness_[patchi],
688 thickness_[patchi],
689 expansionRatio_[patchi]
690 );
691 }
692}
693
694
695// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
696
698(
699 const label nLayers,
700 const scalar layerThickness, // overall layer thickness
701 const scalar expansionRatio,
702
703 const label layerStart, // start in nLayers
704 const label layerSize // size of slice of nLayers
705)
706{
707 if (layerSize == 0 || nLayers == 0)
708 {
709 return 0.0;
710 }
711 else if (layerSize > nLayers || layerStart >= nLayers)
712 {
713 FatalErrorInFunction << "Illegal input for slice of layer:"
714 << " overall nLayers:" << nLayers
715 << " slice nLayers:" << layerSize
716 << " slice start:" << layerStart
717 << exit(FatalError);
718 return 0.0;
719 }
720 else if (mag(expansionRatio-1) < SMALL)
721 {
722 return layerThickness*layerSize/nLayers;
723 }
724 else
725 {
726 const scalar firstLayerThickness =
727 finalLayerThicknessRatio(nLayers, expansionRatio)
728 * layerThickness
729 / pow(expansionRatio, nLayers-1);
730
731 // Calculate thickness of single layer at layerStart
732 const scalar startThickness =
733 firstLayerThickness
734 *pow(expansionRatio, layerStart);
735
736 // See below for formula
737 const scalar thickness =
738 startThickness
739 *(1.0 - pow(expansionRatio, layerSize))
740 /(1.0 - expansionRatio);
741
742 return thickness;
743 }
744}
745
746
748(
749 const thicknessModelType layerSpec,
750 const label nLayers,
751 const scalar firstLayerThickness,
752 const scalar finalLayerThickness,
753 const scalar totalThickness,
754 const scalar expansionRatio
755)
756{
757 switch (layerSpec)
758 {
759 case FIRST_AND_TOTAL:
760 case FINAL_AND_TOTAL:
761 case TOTAL_AND_EXPANSION:
762 {
763 return totalThickness;
764 }
765 break;
766
767 case FIRST_AND_EXPANSION:
768 {
769 if (mag(expansionRatio-1) < SMALL)
770 {
771 return firstLayerThickness * nLayers;
772 }
773 else
774 {
775 return firstLayerThickness
776 *(1.0 - pow(expansionRatio, nLayers))
777 /(1.0 - expansionRatio);
778 }
779 }
780 break;
781
782 case FINAL_AND_EXPANSION:
783 {
784 if (mag(expansionRatio-1) < SMALL)
785 {
786 return finalLayerThickness * nLayers;
787 }
788 else
789 {
790 scalar invExpansion = 1.0 / expansionRatio;
791 return finalLayerThickness
792 *(1.0 - pow(invExpansion, nLayers))
793 /(1.0 - invExpansion);
794 }
795 }
796 break;
797
798 case FIRST_AND_RELATIVE_FINAL:
799 {
800 if (mag(expansionRatio-1) < SMALL)
801 {
802 return firstLayerThickness * nLayers;
803 }
804 else
805 {
806 scalar ratio = layerExpansionRatio
807 (
808 layerSpec,
809 nLayers,
810 firstLayerThickness,
811 finalLayerThickness,
812 totalThickness,
813 expansionRatio
814 );
815
816 if (mag(ratio-1) < SMALL)
817 {
818 return firstLayerThickness * nLayers;
819 }
820 else
821 {
822 return firstLayerThickness *
823 (1.0 - pow(ratio, nLayers))
824 / (1.0 - ratio);
825 }
826 }
827 }
828 break;
829
830 default:
831 {
833 << layerSpec << exit(FatalError);
834 return -VGREAT;
835 }
836 }
837}
838
839
840Foam::scalar Foam::layerParameters::layerExpansionRatio
841(
842 const thicknessModelType layerSpec,
843 const label nLayers,
844 const scalar firstLayerThickness,
845 const scalar finalLayerThickness,
846 const scalar totalThickness,
847 const scalar expansionRatio
848)
849{
850 switch (layerSpec)
851 {
852 case FIRST_AND_EXPANSION:
853 case FINAL_AND_EXPANSION:
854 case TOTAL_AND_EXPANSION:
855 {
856 return expansionRatio;
857 }
858 break;
859
860 case FIRST_AND_TOTAL:
861 {
862 if (firstLayerThickness < SMALL)
863 {
864 // Do what?
865 return 1;
866 }
867 else
868 {
869 return layerExpansionRatio
870 (
871 nLayers,
872 totalThickness/firstLayerThickness
873 );
874 }
875 }
876 break;
877
878 case FINAL_AND_TOTAL:
879 {
880 if (finalLayerThickness < SMALL)
881 {
882 // Do what?
883 return 1;
884 }
885 else
886 {
887 return
888 1.0
889 / layerExpansionRatio
890 (
891 nLayers,
892 totalThickness/finalLayerThickness
893 );
894 }
895 }
896 break;
897
898 case FIRST_AND_RELATIVE_FINAL:
899 {
900 if (firstLayerThickness < SMALL || nLayers <= 1)
901 {
902 return 1.0;
903 }
904 else
905 {
906 // Note: at this point the finalLayerThickness is already
907 // absolute
908 return pow
909 (
910 finalLayerThickness/firstLayerThickness,
911 1.0/(nLayers-1)
912 );
913 }
914 }
915 break;
916
917 default:
918 {
920 << "Illegal thickness specification" << exit(FatalError);
921 return -VGREAT;
922 }
923 }
924}
925
926
928(
929 const thicknessModelType layerSpec,
930 const label nLayers,
931 const scalar firstLayerThickness,
932 const scalar finalLayerThickness,
933 const scalar totalThickness,
934 const scalar expansionRatio
935)
936{
937 switch (layerSpec)
938 {
939 case FIRST_AND_EXPANSION:
940 case FIRST_AND_TOTAL:
941 case FIRST_AND_RELATIVE_FINAL:
942 {
943 return firstLayerThickness;
944 }
945
946 case FINAL_AND_EXPANSION:
947 {
948 if (expansionRatio < SMALL)
949 {
950 // Do what?
951 return 0.0;
952 }
953 else
954 {
955 return finalLayerThickness*pow(1.0/expansionRatio, nLayers-1);
956 }
957 }
958 break;
959
960 case FINAL_AND_TOTAL:
961 {
962 scalar r = layerExpansionRatio
963 (
964 layerSpec,
965 nLayers,
966 firstLayerThickness,
967 finalLayerThickness,
968 totalThickness,
969 expansionRatio
970 );
971 return finalLayerThickness/pow(r, nLayers-1);
972 }
973 break;
974
975 case TOTAL_AND_EXPANSION:
976 {
977 scalar r = finalLayerThicknessRatio
978 (
979 nLayers,
980 expansionRatio
981 );
982 scalar finalThickness = r*totalThickness;
983 return finalThickness/pow(expansionRatio, nLayers-1);
984 }
985 break;
986
987 default:
988 {
990 << "Illegal thickness specification" << exit(FatalError);
991 return -VGREAT;
992 }
993 }
994}
995
996
998(
999 const label nLayers,
1000 const scalar expansionRatio
1001)
1002{
1003 if (nLayers > 0)
1004 {
1005 if (mag(expansionRatio-1) < SMALL)
1006 {
1007 return 1.0/nLayers;
1008 }
1009 else
1010 {
1011 return
1012 pow(expansionRatio, nLayers - 1)
1013 *(1.0 - expansionRatio)
1014 /(1.0 - pow(expansionRatio, nLayers));
1015 }
1016 }
1017 else
1018 {
1019 return 0.0;
1020 }
1021}
1022
1023
1024// ************************************************************************* //
label n
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: Enum.H:61
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:63
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
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
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:70
A class for handling keywords in dictionaries.
Definition: keyType.H:71
Simple container to keep together layer specific information.
const scalarField & expansionRatio() const
const scalarField & thickness() const
Wanted overall thickness of all layers.
thicknessModelType
Enumeration defining the layer specification:
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.
const scalarField & firstLayerThickness() const
Wanted thickness of the layer nearest to the wall.
static scalar finalLayerThicknessRatio(const label nLayers, const scalar expansionRatio)
Determine ratio of final layer thickness to.
const dictionary & dict() const
Mesh motion solver that uses a medial axis algorithm to work out a fraction between the (nearest poin...
Helper class which maintains intersections of (changing) mesh with (static) surfaces.
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.
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:62
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition: wordRe.H:83
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:54
A class for handling words, derived from Foam::string.
Definition: word.H:68
bool
Definition: EEqn.H:20
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
messageStream Info
Information stream (stdout output on master, null elsewhere)
constexpr label labelMax
Definition: label.H:61
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
static constexpr int maxIters
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
IOerror FatalIOError
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
dictionary dict
volScalarField & e
Definition: createFields.H:11
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
Unit conversion functions.