Loading...
Searching...
No Matches
mappedPatchFieldBase.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) 2013-2016 OpenFOAM Foundation
9 Copyright (C) 2018-2025 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
30#include "mappedPatchBase.H"
31#include "interpolationCell.H"
32
33// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
34
35template<class Type>
36Type Foam::mappedPatchFieldBase<Type>::getAverage
37(
38 const dictionary& dict,
39 const bool mandatory
40)
41{
42 if (mandatory)
43 {
44 return dict.get<Type>("average");
45 }
47 return Zero;
48}
49
50
51template<class Type>
52template<class T>
54(
55 const objectRegistry& obr,
56 const word& region,
57 const word& patch,
58 const label myComm,
59 const labelListList& procToMap,
60 const word& fieldName,
61 const Field<T>& fld
62) const
63{
64 // Store my data onto database
65
66 const auto& procIDs = UPstream::procID(myComm);
67
68 forAll(procToMap, ranki)
69 {
70 const labelList& map = procToMap[ranki];
71 const label proci = procIDs[ranki];
72
73 if (map.size())
74 {
75 const Field<T> subFld(fld, map);
76
77 auto& subObr = const_cast<objectRegistry&>
78 (
80 (
81 obr,
82 mapper_.sendPath(proci)
83 / region
84 / patch
85 )
86 );
87
89 {
90 Pout<< "*** STORING :"
91 << " field:" << fieldName
92 << " values:" << flatOutput(subFld)
93 << " as:" << subObr.objectPath() << endl;
94 }
95
96 mappedPatchBase::storeField(subObr, fieldName, subFld);
97 }
98 }
99}
100
101
102template<class Type>
103template<class T>
105(
106 const bool allowUnset,
107 const objectRegistry& obr,
108 const word& region,
109 const word& patch,
110 const label myComm,
111 const labelListList& procToMap,
112 const word& fieldName,
113 Field<T>& fld
114) const
115{
116 const auto& procIDs = UPstream::procID(myComm);
117
118 bool ok = true;
119
120 forAll(procToMap, ranki)
121 {
122 const labelList& map = procToMap[ranki];
123 const label proci = procIDs[ranki];
124
125 if (map.size())
126 {
127 auto& subObr = const_cast<objectRegistry&>
128 (
129 mappedPatchBase::subRegistry
130 (
131 obr,
132 mapper_.receivePath(proci)
133 / region
134 / patch
135 )
136 );
137
138 const IOField<T>* subFldPtr = subObr.getObjectPtr<IOField<T>>
139 (
140 fieldName
141 );
142 if (subFldPtr)
143 {
144 if (subFldPtr->size() != map.size())
145 {
146 // This is the dummy value inserted at start-up since the
147 // map is always non-zero size (checked above)
148 //Pout<< "*** RETRIEVED DUMMY :"
149 // << " field:" << fieldName
150 // << " subFldPtr:" << subFldPtr->size()
151 // << " map:" << map.size() << endl;
152
153 ok = false;
154 }
155 else
156 {
157 UIndirectList<T>(fld, map) = *subFldPtr;
158
160 {
161 Pout<< "*** RETRIEVED :"
162 << " field:" << fieldName
163 << " values:" << flatOutput(fld)
164 << " from:" << subObr.objectPath() << endl;
165 }
166 }
167 }
168 else if (allowUnset)
169 {
171 {
172 WarningInFunction << "Not found"
173 << " field:" << fieldName
174 << " in:" << subObr.objectPath() << endl;
175 }
176
177 // Store dummy value so the database has something on it.
178 // Note that size 0 should never occur naturally so we can
179 // detect it if necessary.
180 const Field<T> dummyFld;
181
182 mappedPatchBase::storeField(subObr, fieldName, dummyFld);
183
184 ok = false;
185 }
186 else
187 {
188 // Not found. Make it fail
189 (void)subObr.lookupObject<IOField<T>>(fieldName);
190 ok = false;
191 }
192 }
194 return ok;
195}
196
197
198template<class Type>
199template<class T>
201(
202 const objectRegistry& obr,
203 const word& region,
204 const word& patch,
205 const labelListList& map,
206 const word& fieldName,
207 const Field<T>& fld
208) const
209{
210 // Old code. Likely not quite correct...
211
212 // Store my data onto database
213 const label nProcs = UPstream::nProcs(UPstream::worldComm);
214
215 for (label domain = 0; domain < nProcs; domain++)
216 {
217 const labelList& constructMap = map[domain];
218 if (constructMap.size())
219 {
220 auto& subObr = const_cast<objectRegistry&>
221 (
223 (
224 obr,
225 mapper_.receivePath(domain)
226 / region
227 / patch
228 )
229 );
230
231 const Field<T> receiveFld(fld, constructMap);
232
234 {
235 Pout<< "*** STORING INITIAL :"
236 << " field:" << fieldName << " values:"
237 << flatOutput(receiveFld)
238 << " from:" << flatOutput(fld)
239 << " constructMap:" << flatOutput(constructMap)
240 << " as:" << subObr.objectPath() << endl;
241 }
242
243 mappedPatchBase::storeField(subObr, fieldName, receiveFld);
245 }
246}
247
248
249template<class Type>
250template<class T>
252(
253 const word& fieldName,
254 const label myComm,
255 const labelListList& subMap,
256 const label constructSize,
257 const labelListList& constructMap,
258 const labelListList& address,
259 const scalarListList& weights,
260 Field<T>& fld
261) const
262{
263 storeField
264 (
265 patchField_.internalField().time(),
266 patchField_.patch().boundaryMesh().mesh().name(),
267 patchField_.patch().name(),
268 myComm,
269 subMap,
270 fieldName,
271 fld
272 );
273
274 Field<T> work(constructSize);
275 const bool ok = retrieveField
276 (
277 true, // allow unset
278 patchField_.internalField().time(),
279 mapper_.sampleRegion(),
280 mapper_.samplePatch(),
281 myComm,
282 constructMap,
283 fieldName,
284 work
285 );
286
287 if (ok)
288 {
289 // Do interpolation
290
291 fld.setSize(address.size());
292 fld = Zero;
293
294 const plusEqOp<T> cop;
295 const multiplyWeightedOp<T, plusEqOp<T>> mop(cop);
296
297 forAll(address, facei)
298 {
299 const labelList& slots = address[facei];
300 const scalarList& w = weights[facei];
301
302 forAll(slots, i)
303 {
304 mop(fld[facei], facei, work[slots[i]], w[i]);
305 }
306 }
307 }
308 else
309 {
310 // Leave fld intact
311 }
312
313 return ok;
314}
315
316
317// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
318
319template<class Type>
322 const mappedPatchBase& mapper,
323 const fvPatchField<Type>& patchField,
324 const word& fieldName,
325 const bool setAverage,
326 const Type average,
327 const word& interpolationScheme
328)
329:
331 patchField_(patchField),
332 fieldName_(fieldName),
333 setAverage_(setAverage),
335 interpolationScheme_(interpolationScheme)
336{}
337
338
339template<class Type>
341(
342 const mappedPatchBase& mapper,
343 const fvPatchField<Type>& patchField,
344 const dictionary& dict
345)
348 patchField_(patchField),
350 (
351 dict.template getOrDefault<word>
352 (
353 "field",
354 patchField_.internalField().name()
355 )
356 ),
357 setAverage_(dict.getOrDefault("setAverage", false)),
358 average_(getAverage(dict, setAverage_)),
360{
361 if
362 (
363 mapper_.sampleDatabase()
364 && (
367 )
368 )
369 {
370 FatalErrorInFunction
371 << "Mapping using the database only supported for "
372 << "sampleModes "
373 << mappedPatchBase::sampleModeNames_
374 [
375 mappedPatchBase::NEARESTPATCHFACE
376 ]
377 << " and "
378 << mappedPatchBase::sampleModeNames_
379 [
380 mappedPatchBase::NEARESTPATCHFACEAMI
381 ]
382 << exit(FatalError);
383 }
384
386 {
387 dict.readEntry("interpolationScheme", interpolationScheme_);
388 }
390 // Note: in database mode derived boundary conditions need to initialise
391 // fields
392}
393
394
395template<class Type>
397(
398 const mappedPatchBase& mapper,
399 const fvPatchField<Type>& patchField,
400 const dictionary& dict,
401 const Field<Type>& fld
402)
403:
404 mappedPatchFieldBase<Type>::mappedPatchFieldBase(mapper, patchField, dict)
405{
407 {
408 if (mapper_.mode() == mappedPatchBase::NEARESTPATCHFACE)
409 {
410 // Store my data on receive buffers so we have some initial data
411 initRetrieveField
412 (
413 patchField_.internalField().time(),
414 //patchField_.patch().boundaryMesh().mesh().name(),
415 mapper_.sampleRegion(),
416 //patchField_.patch().name(),
417 mapper_.samplePatch(),
418 mapper_.map().constructMap(),
419 patchField_.internalField().name(),
420 patchField_
421 );
422 }
424 {
425 // Depend on fall-back (sorting dummy field) in retrieveField
426 // since it would be too hard to determine the field that gives
427 // the wanted result after interpolation
428 }
429 }
430}
431
432
433template<class Type>
435(
436 const mappedPatchBase& mapper,
437 const fvPatchField<Type>& patchField
438)
439:
440 mapper_(mapper),
441 patchField_(patchField),
442 fieldName_(patchField_.internalField().name()),
444 average_(Zero),
446{}
447
448
449template<class Type>
451(
452 const mappedPatchFieldBase<Type>& mapper
453)
454:
455 mapper_(mapper.mapper_),
456 patchField_(mapper.patchField_),
457 fieldName_(mapper.fieldName_),
472 mapper_(mapper),
473 patchField_(patchField),
474 fieldName_(base.fieldName_),
475 setAverage_(base.setAverage_),
476 average_(base.average_),
477 interpolationScheme_(base.interpolationScheme_)
478{}
480
481// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
482
483template<class Type>
484template<class Type2>
487{
489
490 if (mapper_.sameRegion())
491 {
492 if (fieldName == patchField_.internalField().name())
493 {
494 // Optimisation: bypass field lookup
495 return
496 dynamic_cast<const fieldType&>
497 (
498 patchField_.internalField()
499 );
500 }
501 else
502 {
503 const fvMesh& thisMesh = patchField_.patch().boundaryMesh().mesh();
504 return thisMesh.template lookupObject<fieldType>(fieldName);
505 }
506 }
507
508 const fvMesh& nbrMesh = refCast<const fvMesh>(mapper_.sampleMesh());
509 return nbrMesh.template lookupObject<fieldType>(fieldName);
510}
511
512
513template<class Type>
518}
519
520
521template<class Type>
522template<class T>
524(
525 const word& fieldName,
527) const
528{
529 if (mapper_.sampleDatabase())
530 {
531 const label myComm = mapper_.getCommunicator(); // Get or create
532
533 if (mapper_.mode() != mappedPatchBase::NEARESTPATCHFACEAMI)
534 {
535 // Store my data on send buffers
536 storeField
537 (
538 patchField_.internalField().time(),
539 patchField_.patch().boundaryMesh().mesh().name(),
540 patchField_.patch().name(),
541 myComm,
542 mapper_.map().subMap(),
543 fieldName,
544 fld
545 );
546 // Construct my data from receive buffers
547 fld.setSize(mapper_.map().constructSize());
548 retrieveField
549 (
550 true, // allow unset
551 patchField_.internalField().time(),
552 mapper_.sampleRegion(),
553 mapper_.samplePatch(),
554 myComm,
555 mapper_.map().constructMap(),
556 fieldName,
557 fld
558 );
559 }
560 else
561 {
562 const AMIPatchToPatchInterpolation& AMI = mapper_.AMI();
563
564 // The AMI does an interpolateToSource/ToTarget. This is a
565 // mapDistribute (so using subMap/constructMap) and then a
566 // weighted sum. We'll store the sent data as before and
567 // do the weighted summation after the retrieveField
568
569 if (mapper_.masterWorld())
570 {
571 // See AMIInterpolation::interpolateToSource. Use tgtMap,
572 // srcAddress, srcWeights
573 storeAndRetrieveField
574 (
575 fieldName,
576 myComm,
577 AMI.srcMap().subMap(),
578 AMI.tgtMap().constructSize(),
579 AMI.tgtMap().constructMap(),
580 AMI.srcAddress(),
581 AMI.srcWeights(),
582 fld
583 );
584 }
585 else
586 {
587 // See AMIInterpolation::interpolateToTarget.
588 // Use srcMap, tgtAddress, tgtWeights
589 storeAndRetrieveField
590 (
591 fieldName,
592 myComm,
593 AMI.tgtMap().subMap(),
594 AMI.srcMap().constructSize(),
595 AMI.srcMap().constructMap(),
596 AMI.tgtAddress(),
597 AMI.tgtWeights(),
598 fld
599 );
600 }
601 }
602 }
603 else
604 {
605 mapper_.distribute(fld);
607}
608
609
610template<class Type>
611//template<class T>
614(
615// const GeometricField<T, fvPatchField, volMesh>& fld
616) const
617{
618 typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
619
620 // Since we're inside initEvaluate/evaluate there might be processor
621 // comms underway. Change the tag we use.
622 const int oldTag = UPstream::incrMsgType();
623
624 const fvMesh& thisMesh = patchField_.patch().boundaryMesh().mesh();
625
626 // Result of obtaining remote values
627 auto tnewValues = tmp<Field<Type>>::New();
628 auto& newValues = tnewValues.ref();
629
630 switch (mapper_.mode())
631 {
633 {
634 const fieldType& fld = sampleField();
635 const mapDistribute& distMap = mapper_.map();
636
637 if (interpolationScheme_ != interpolationCell<Type>::typeName)
638 {
639 if (!mapper_.sameWorld() || mapper_.sampleDatabase())
640 {
642 << "Interpolating cell values from different world"
643 << " or database currently not supported"
644 << exit(FatalError);
645 }
646
647 const fvMesh& nbrMesh =
648 refCast<const fvMesh>(mapper_.sampleMesh());
649
650 // Send back sample points to the processor that holds the cell
651 vectorField samples(mapper_.samplePoints());
652
653 distMap.reverseDistribute
654 (
655 (
656 mapper_.sameRegion()
657 ? thisMesh.nCells()
658 : nbrMesh.nCells()
659 ),
661 samples
662 );
663
664 auto interpolator =
666 (
667 interpolationScheme_,
668 fld
669 );
670
671 const auto& interp = *interpolator;
672
673 newValues.setSize(samples.size(), pTraits<Type>::max);
674 forAll(samples, celli)
675 {
676 if (samples[celli] != point::max)
677 {
678 newValues[celli] = interp.interpolate
679 (
680 samples[celli],
681 celli
682 );
683 }
684 }
685 }
686 else
687 {
688 newValues = fld;
689 }
690
691 distribute(fieldName_, newValues);
692
693 break;
694 }
697 {
698 if (mapper_.sameWorld())
699 {
700 const fvMesh& nbrMesh =
701 refCast<const fvMesh>(mapper_.sampleMesh());
702 const fieldType& fld = sampleField();
703
704 const label nbrPatchID =
705 nbrMesh.boundaryMesh().findPatchID(mapper_.samplePatch());
706
707 if (nbrPatchID < 0)
708 {
710 << "Unable to find sample patch " << mapper_.samplePatch()
711 << " in region " << mapper_.sampleRegion()
712 << " for patch " << patchField_.patch().name() << nl
713 << abort(FatalError);
714 }
715
716 const auto& nbrField = fld;
717
718 newValues = nbrField.boundaryField()[nbrPatchID];
719 }
720 else
721 {
722 // Start off from my patch values, let distribute function below
723 // do all the work
724 newValues = patchField_;
725 }
726 distribute(fieldName_, newValues);
727
728 break;
729 }
731 {
732 Field<Type> allValues;
733 if (mapper_.sameWorld())
734 {
735 const fvMesh& nbrMesh =
736 refCast<const fvMesh>(mapper_.sampleMesh());
737 const fieldType& fld = sampleField();
738
739 allValues.setSize(nbrMesh.nFaces(), Zero);
740
741 const auto& nbrField = fld;
742
743 for (const fvPatchField<Type>& pf : nbrField.boundaryField())
744 {
745 label faceStart = pf.patch().start();
746
747 forAll(pf, facei)
748 {
749 allValues[faceStart++] = pf[facei];
750 }
751 }
752 }
753 else
754 {
755 // Start off from my patch values. Let distribute function below
756 // do all the work
757 allValues.setSize(thisMesh.nFaces(), Zero);
758
759 const fieldType& thisFld = dynamic_cast<const fieldType&>
760 (
761 patchField_.internalField()
762 );
763
764 for (const fvPatchField<Type>& pf : thisFld.boundaryField())
765 {
766 label faceStart = pf.patch().start();
767
768 forAll(pf, facei)
769 {
770 allValues[faceStart++] = pf[facei];
771 }
772 }
773 }
774
775 distribute(fieldName_, allValues);
776 newValues.transfer(allValues);
777
778 break;
779 }
780 default:
781 {
783 << "Unknown sampling mode: " << mapper_.mode() << nl
784 << abort(FatalError);
785 }
786 }
787
788 if (setAverage_)
789 {
790 Type averagePsi =
791 gWeightedAverage(patchField_.patch().magSf(), newValues);
792
793 if (mag(averagePsi) > 0.5*mag(average_))
794 {
795 newValues *= mag(average_)/mag(averagePsi);
796 }
797 else
798 {
799 newValues += (average_ - averagePsi);
800 }
801 }
802
803 UPstream::msgType(oldTag); // Restore tag
804
805 return tnewValues;
806}
807
808
809//template<class Type>
810//Foam::tmp<Foam::Field<Type>>
811//Foam::mappedPatchFieldBase<Type>::mappedField() const
812//{
813// const GeometricField<Type, fvPatchField, volMesh>& fld = sampleField();
814// return mappedField<Type>(fld);
815//}
816
817
818template<class Type>
821{
822 // Swap to obtain full local values of neighbour internal field
823 auto tnbrIntFld = tmp<Field<Type>>::New();
824 auto& nbrIntFld = tnbrIntFld.ref();
825
826 if (mapper_.sameWorld())
827 {
828 // Same world so lookup
829 const label nbrPatchID = mapper_.samplePolyPatch().index();
830 const auto& nbrField = this->sampleField();
831 nbrIntFld = nbrField.boundaryField()[nbrPatchID].patchInternalField();
832 }
833 else
834 {
835 // Different world so use my region,patch. Distribution below will
836 // do the reordering
837 nbrIntFld = patchField_.patchInternalField();
838 }
839
840 // Since we're inside initEvaluate/evaluate there might be processor
841 // comms underway. Change the tag we use.
842 const int oldTag = UPstream::incrMsgType();
843
844 distribute(fieldName_, nbrIntFld);
845
846 UPstream::msgType(oldTag); // Restore tag
848 return tnbrIntFld;
849}
850
851
852template<class Type>
855{
856 // Swap to obtain full local values of neighbour internal field
857 auto tnbrKDelta = tmp<scalarField>::New();
858 auto& nbrKDelta = tnbrKDelta.ref();
859
860 if (mapper_.sameWorld())
861 {
862 // Same world so lookup
863 const auto& nbrMesh = refCast<const fvMesh>(this->mapper_.sampleMesh());
864 const label nbrPatchID = mapper_.samplePolyPatch().index();
865 const auto& nbrPatch = nbrMesh.boundary()[nbrPatchID];
866 nbrKDelta = nbrPatch.deltaCoeffs();
867 }
868 else
869 {
870 // Different world so use my region,patch. Distribution below will
871 // do the reordering
872 nbrKDelta = patchField_.patch().deltaCoeffs();
873 }
874
875
876 // Since we're inside initEvaluate/evaluate there might be processor
877 // comms underway. Change the tag we use.
878 const int oldTag = UPstream::incrMsgType();
879
880 distribute(fieldName_ + "_deltaCoeffs", nbrKDelta);
881
882 UPstream::msgType(oldTag); // Restore tag
883
884 return tnbrKDelta;
885}
886
887
888template<class Type>
890(
891 const word& fieldName,
892 tmp<scalarField>& thisWeights,
893 tmp<scalarField>& nbrWeights
894) const
895{
896 thisWeights = new scalarField(patchField_.patch().deltaCoeffs());
897 if (!fieldName.empty())
898 {
899 thisWeights.ref() *=
900 patchField_.patch().template lookupPatchField<volScalarField>
901 (
902 fieldName
903 ).patchInternalField();
904 }
905
906
907 // Swap to obtain full local values of neighbour internal field
908
909 if (mapper_.sameWorld())
910 {
911 // Same world so lookup
912 const auto& nbrMesh = refCast<const fvMesh>(mapper_.sampleMesh());
913 const label nbrPatchID = mapper_.samplePolyPatch().index();
914 const auto& nbrPatch = nbrMesh.boundary()[nbrPatchID];
915
916 nbrWeights = new scalarField(nbrPatch.deltaCoeffs());
917
918 if (!fieldName.empty())
919 {
920 // Weightfield is volScalarField
921 const auto& nbrWeightField =
922 nbrMesh.template lookupObject<volScalarField>(fieldName);
923 nbrWeights.ref() *=
924 nbrWeightField.boundaryField()[nbrPatchID].patchInternalField();
925 }
926 }
927 else
928 {
929 // Different world so use my region,patch. Distribution below will
930 // do the reordering
931 nbrWeights = new scalarField(thisWeights());
932 }
933
934 // Since we're inside initEvaluate/evaluate there might be processor
935 // comms underway. Change the tag we use.
936 const int oldTag = UPstream::incrMsgType();
937
938 distribute(fieldName_ + "_weights", nbrWeights.ref());
939
940 UPstream::msgType(oldTag); // Restore tag
941}
942
943
944template<class Type>
946(
947 const fvPatch& p,
949)
950{
951 if (!isA<mappedPatchBase>(p.patch()))
952 {
954 << "Incorrect patch type " << p.patch().type()
955 << " for patch " << p.patch().name()
956 << " of field " << iF.name()
957 << " in file " << iF.objectPath() << nl
958 << "Type should be a mappedPatch"
959 << exit(FatalError);
961 return refCast<const mappedPatchBase>(p.patch());
962}
963
964
965template<class Type>
966template<class T>
968(
969 const word& fieldName,
970 const Field<T>& fld
971) const
972{
973 if (mapper_.sampleDatabase())
974 {
975 // Store my data on receive buffers (reverse of storeField;
976 // i.e. retrieveField will obtain patchField)
977 if (mapper_.mode() == mappedPatchBase::NEARESTPATCHFACE)
978 {
979 initRetrieveField
980 (
981 patchField_.internalField().time(),
982 mapper_.sampleRegion(),
983 mapper_.samplePatch(),
984 mapper_.map().constructMap(),
985 fieldName,
986 fld
987 );
988 }
989 }
990}
991
992
993template<class Type>
995{
996 //os.writeEntry("field", fieldName_);
998 (
999 "field",
1000 patchField_.internalField().name(),
1001 fieldName_
1002 );
1003
1004 if (setAverage_)
1005 {
1006 os.writeEntry("setAverage", "true");
1007 os.writeEntry("average", average_);
1008 }
1009
1010 if (mapper_.mode() == mappedPatchBase::NEARESTCELL)
1011 {
1012 os.writeEntry("interpolationScheme", interpolationScheme_);
1013 }
1014}
1015
1016
1017// ************************************************************************* //
if(patchID !=-1)
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
const mapDistribute & srcMap() const
Source map - valid only if singlePatchProc = -1 This gets source data into a form to be consumed by t...
const mapDistribute & tgtMap() const
Target map - valid only if singlePatchProc=-1. This gets target data into a form to be consumed by sr...
const scalarListList & tgtWeights() const
Return const access to target patch weights.
const labelListList & srcAddress() const
Return const access to source patch addressing.
const scalarListList & srcWeights() const
Return const access to source patch weights.
const labelListList & tgtAddress() const
Return const access to target patch addressing.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
Generic GeometricField class.
A primitive field of type <T> with automated input and output.
Definition IOField.H:53
const word & name() const noexcept
Return the object name.
Definition IOobjectI.H:205
fileName objectPath() const
The complete path + object name.
Definition IOobjectI.H:313
void setSize(label n)
Alias for resize().
Definition List.H:536
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition Ostream.H:331
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
Definition Ostream.H:346
A List with indirect addressing. Like IndirectList but does not store addressing.
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static List< int > & procID(int communicator)
The list of ranks within a given communicator.
Definition UPstream.H:1767
static int & msgType() noexcept
Message tag of standard messages.
Definition UPstream.H:1926
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
Definition UPstream.H:1697
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition UPstream.H:1069
static int incrMsgType(int val=1) noexcept
Increment the message tag for standard messages.
Definition UPstream.H:1948
static const Form max
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
Mesh data needed to do the Finite Volume discretisation.
Definition fvMesh.H:85
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition fvPatch.H:71
Uses the cell value for any location within the cell.
static autoPtr< interpolation< Type > > New(const word &interpolationType, const GeometricField< Type, fvPatchField, volMesh > &psi)
Return a reference to the specified interpolation scheme.
const labelListList & constructMap() const noexcept
From subsetted data to new reconstructed data.
const labelListList & subMap() const noexcept
From subsetted data back to original data.
label constructSize() const noexcept
Constructed data size.
Class containing processor-to-processor mapping information.
void reverseDistribute(const label constructSize, List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
Determines a mapping between patch face centres and mesh cell or face centres and processors they're ...
static FOAM_NO_DANGLING_REFERENCE const objectRegistry & subRegistry(const objectRegistry &obr, const wordList &names, const label index)
Lookup (sub)objectRegistry by following names of sub registries. Creates non-existing intermediate on...
@ NEARESTCELL
nearest cell containing sample
@ NEARESTPATCHFACE
nearest face on selected patch
@ NEARESTPATCHFACEAMI
nearest patch face + AMI interpolation
bool sampleDatabase() const noexcept
sampleMode mode() const noexcept
What to sample.
static void storeField(objectRegistry &obr, const word &fieldName, const Field< Type > &values)
Store an IOField on the objectRegistry relative to obr.
Functionality for sampling fields using mappedPatchBase. Every call to mappedField() returns a sample...
void storeField(const objectRegistry &obr, const word &region, const word &patch, const label myComm, const labelListList &procToMap, const word &fieldName, const Field< T > &fld) const
Store elements of field onto (sub) registry.
const mappedPatchBase & mapper_
Mapping engine.
void initRetrieveField(const objectRegistry &obr, const word &region, const word &patch, const labelListList &map, const word &fieldName, const Field< T > &fld) const
Construct field from registered elements.
virtual tmp< Field< Type > > mappedField() const
Map sampleField onto *this patch.
const GeometricField< T, fvPatchField, volMesh > & sampleField(const word &fieldName) const
Field to sample. Either on my or nbr mesh.
virtual void write(Ostream &os) const
Write.
static const mappedPatchBase & mapper(const fvPatch &p, const DimensionedField< Type, volMesh > &iF)
Check that patch is of correct type.
virtual tmp< scalarField > mappedWeightField() const
Map optional weightField onto *this patch. Default is deltaCoeffs.
virtual tmp< Field< Type > > mappedInternalField() const
Map internal of sampleField onto *this patch.
const GeometricField< Type, fvPatchField, volMesh > & sampleField() const
Field to sample. Either on my or nbr mesh.
mappedPatchFieldBase(const mappedPatchBase &mapper, const fvPatchField< Type > &patchField, const word &fieldName, const bool setAverage, const Type average, const word &interpolationScheme)
Construct from components.
const fvPatchField< Type > & patchField_
Underlying patch field.
bool retrieveField(const bool allowUnset, const objectRegistry &obr, const word &region, const word &patch, const label myComm, const labelListList &procToMap, const word &fieldName, Field< T > &fld) const
Construct field from registered elements.
void distribute(const word &fieldName, Field< T > &newValues) const
Wrapper for mapDistribute::distribute that knows about dabase mapping.
bool storeAndRetrieveField(const word &fieldName, const label myComm, const labelListList &subMap, const label constructSize, const labelListList &constructMap, const labelListList &address, const scalarListList &weights, Field< T > &fld) const
Helper : storeField and retrieveField and interpolate. Leaves fld.
Registry of regIOobjects.
A traits class, which is primarily used for primitives and vector-space.
Definition pTraits.H:64
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Definition polyMesh.H:609
label nCells() const noexcept
Number of mesh cells.
label nFaces() const noexcept
Number of mesh faces.
A class for managing temporary objects.
Definition tmp.H:75
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Definition tmp.H:215
T & ref() const
Return non-const reference to the contents of a non-null managed pointer.
Definition tmpI.H:235
A class for handling words, derived from Foam::string.
Definition word.H:66
volScalarField & p
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
auto & name
#define WarningInFunction
Report a warning using Foam::Warning.
const std::string patch
OpenFOAM patch number as a std::string.
List< scalarList > scalarListList
List of scalarList.
Definition scalarList.H:35
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
Definition typeInfo.H:172
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
Type gWeightedAverage(const UList< scalar > &weights, const UList< Type > &fld, const label comm)
The global weighted average of a field, using the mag() of the weights.
List< label > labelList
A List of labels.
Definition List.H:62
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
Definition typeInfo.H:87
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition FlatOutput.H:217
AMIInterpolation AMIPatchToPatchInterpolation
Patch-to-patch interpolation == Foam::AMIInterpolation.
errorManip< error > abort(error &err)
Definition errorManip.H:139
Field< vector > vectorField
Specialisation of Field<T> for vector.
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
List< scalar > scalarList
List of scalar.
Definition scalarList.H:32
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &f1, const label comm)
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
scalarField samples(nIntervals, Zero)