37 const bool dictConstructed,
39 const word& entryName,
40 const dictionary&
dict,
41 const word& fieldTableName,
45 PatchFunction1<Type>(
pp, entryName,
dict, faceValues),
46 dictConstructed_(dictConstructed),
47 setAverage_(
dict.getOrDefault(
"setAverage", false)),
48 perturb_(
dict.getOrDefault<scalar>(
"perturb", 1
e-5)),
49 fieldTableName_(fieldTableName),
50 pointsName_(
dict.getOrDefault<word>(
"points",
"points")),
52 filterRadius_(
dict.getOrDefault<scalar>(
"filterRadius", 0)),
53 filterSweeps_(
dict.getOrDefault<label>(
"filterSweeps", 0)),
54 filterFieldPtr_(nullptr),
63 offset_(Function1<Type>::NewIfPresent(
"offset",
dict))
65 if (fieldTableName_.empty())
71 if ((filterSweeps_ < 1) || (filterRadius_ <= VSMALL))
77 if (
dict.readIfPresent(
"sampleFormat", readerFormat_))
79 dict.readEntry(
"sampleFile", readerFile_);
81 fileName fName(readerFile_);
94 Info<<
"mappedFile:" <<
nl;
95 if (readerFormat_.empty())
97 Info<<
" boundary format" <<
nl;
101 Info<<
" format:" << readerFormat_
102 <<
" file:" << readerFile_ <<
nl;
105 Info<<
" filter radius=" << filterRadius_
106 <<
" sweeps=" << filterSweeps_ <<
endl;
111 dict.readIfPresent(
"mapMethod", mapMethod_)
112 && !mapMethod_.empty()
113 && mapMethod_ !=
"nearest" 118 <<
"Unknown mapMethod type " << mapMethod_
119 <<
"\n\nValid mapMethod types :\n" 120 <<
"(nearest planar)" <<
nl 130 const word& redirectType,
131 const word& entryName,
133 const bool faceValues
142 dict.getOrDefault<
word>(
"fieldTable", entryName),
152 const word& entryName,
154 const word& fieldTableName,
155 const bool faceValues
188 dictConstructed_(rhs.dictConstructed_),
189 setAverage_(rhs.setAverage_),
190 perturb_(rhs.perturb_),
191 fieldTableName_(rhs.fieldTableName_),
192 pointsName_(rhs.pointsName_),
193 mapMethod_(rhs.mapMethod_),
194 filterRadius_(rhs.filterRadius_),
195 filterSweeps_(rhs.filterSweeps_),
196 filterFieldPtr_(nullptr),
197 readerFormat_(rhs.readerFormat_),
198 readerFile_(rhs.readerFile_),
200 mapperPtr_(rhs.mapperPtr_.clone()),
201 sampleTimes_(rhs.sampleTimes_),
202 sampleIndex_(rhs.sampleIndex_),
203 sampleAverage_(rhs.sampleAverage_),
204 sampleValues_(rhs.sampleValues_),
205 offset_(rhs.offset_.clone())
207 if (!readerFormat_.empty() && !readerFile_.empty())
227 if (sampleValues_.first().size())
229 sampleValues_.first().autoMap(mapper);
231 if (sampleValues_.second().size())
233 sampleValues_.second().autoMap(mapper);
237 filterFieldPtr_.reset(
nullptr);
238 mapperPtr_.reset(
nullptr);
253 refCast<const PatchFunction1Types::MappedFile<Type>>(pf1);
255 if (tiptf.sampleValues_.first().size())
257 sampleValues_.first().resize(this->size());
258 sampleValues_.first().rmap(tiptf.sampleValues_.first(), addr);
261 if (tiptf.sampleValues_.second().size())
263 sampleValues_.second().resize(this->size());
264 sampleValues_.second().rmap(tiptf.sampleValues_.second(), addr);
268 filterFieldPtr_.reset(
nullptr);
269 mapperPtr_.reset(
nullptr);
277 const label sampleIndex,
282 tmp<Field<Type>> tvalues;
287 wordList fieldNames = readerPtr_->fieldNames(sampleIndex);
289 label fieldIndex = fieldNames.
find(fieldTableName_);
294 <<
"Sample field='" << fieldTableName_
295 <<
"' not found. Known field names: " 302 Pout<<
"checkTable : Update index=" << sampleIndex
303 <<
" field=" << fieldNames[fieldIndex] <<
endl;
306 tvalues = readerPtr_->field
313 if (tvalues().size() != mapperPtr_().sourceSize())
316 <<
"Number of values (" << tvalues().size()
317 <<
") differs from the number of points (" 318 << mapperPtr_().sourceSize() <<
")" 324 const polyMesh&
mesh = this->patch_.boundaryMesh().mesh();
325 const Time& time =
mesh.time();
329 Pout<<
"checkTable : Update index=" << sampleIndex
330 <<
" Reading values from " 334 / this->patch_.name()
335 / sampleTimes_[sampleIndex].name()
341 const fileName valsFile
348 /sampleTimes_[sampleIndex].name()
362 rawIOField<Type> vals(
io, setAverage_);
364 if (vals.hasAverage())
366 avg = vals.average();
369 if (vals.size() != mapperPtr_().sourceSize())
372 <<
"Number of values (" << vals.size()
373 <<
") differs from the number of points (" 374 << mapperPtr_().sourceSize()
375 <<
") in file " << valsFile
379 tvalues = tmp<Field<Type>>
::New(std::move(vals.field()));
385 <<
"apply " << filterSweeps_ <<
" filter sweeps" <<
endl;
387 tvalues = filterFieldPtr_().evaluate(tvalues, filterSweeps_);
391 field = mapperPtr_().interpolate(tvalues);
401 const polyMesh&
mesh = this->patch_.boundaryMesh().mesh();
402 const Time& time =
mesh.time();
405 if (!mapperPtr_ && readerPtr_)
409 auto& reader = readerPtr_();
413 sampleTimes_ = reader.times();
420 geom.nFaces() ? geom.faceCentres() : geom.points()
424 <<
"Read " << samplePoints.size() <<
" sample points from " 425 << readerFile_ <<
endl 428 <<
"... in " << timing.timeIncrement() <<
's' <<
endl;
431 const bool nearestOnly =
433 !mapMethod_.empty() && !mapMethod_.starts_with(
"planar")
437 if (this->faceValues())
441 new pointToPointPlanarInterpolation
444 this->localPosition(this->patch_.faceCentres()),
454 new pointToPointPlanarInterpolation
457 this->localPosition(this->patch_.localPoints()),
465 <<
"Created point/point planar interpolation" 466 <<
" - in " << timing.timeIncrement() <<
's' <<
endl;
470 if (filterSweeps_ > 0)
472 filterFieldPtr_.reset(
new FilterField(geom, filterRadius_));
475 <<
"Calculated field-filter" 476 <<
" - in " << timing.timeIncrement() <<
's' <<
endl;
480 filterFieldPtr_.reset(
nullptr);
483 else if (!mapperPtr_)
488 const fileName samplePointsFile
509 const rawIOField<point> samplePoints(
io);
515 <<
"Read " << samplePoints.size() <<
" sample points from " 516 << samplePointsFile <<
endl 519 <<
"... in " << timing.timeIncrement() <<
's' <<
endl;
523 const bool nearestOnly =
525 !mapMethod_.empty() && !mapMethod_.starts_with(
"planar")
529 if (this->faceValues())
533 new pointToPointPlanarInterpolation
536 this->localPosition(this->patch_.faceCentres()),
546 new pointToPointPlanarInterpolation
549 this->localPosition(this->patch_.localPoints()),
557 <<
"Created point/point planar interpolation" 558 <<
" - in " << timing.timeIncrement() <<
's' <<
endl;
562 if (filterSweeps_ > 0)
564 filterFieldPtr_.reset(
new FilterField(samplePoints, filterRadius_));
567 <<
"Calculated field-filter" 568 <<
" - in " << timing.timeIncrement() <<
's' <<
endl;
572 filterFieldPtr_.reset(
nullptr);
585 if (timeIndices.first() < 0)
588 <<
"Cannot find starting sampling values for index " 590 <<
"Have sampling values for " 593 << time.constant()/
mesh.dbDir()/
"boundaryData"/this->patch_.name()
594 <<
"\n on patch " << this->patch_.name()
595 <<
" of field " << fieldTableName_
602 if (sampleIndex_.first() != timeIndices.first())
604 sampleIndex_.first() = timeIndices.first();
606 if (sampleIndex_.first() == sampleIndex_.second())
609 sampleValues_.first() = sampleValues_.second();
610 sampleAverage_.first() = sampleAverage_.second();
615 this->updateSampledValues
617 sampleIndex_.first(),
618 sampleValues_.first(),
619 sampleAverage_.first()
624 if (sampleIndex_.second() != timeIndices.second())
626 sampleIndex_.second() = timeIndices.second();
628 if (sampleIndex_.second() == -1)
631 sampleValues_.second().clear();
636 this->updateSampledValues
638 sampleIndex_.second(),
639 sampleValues_.second(),
640 sampleAverage_.second()
658 auto&
fld = tfld.ref();
661 if (sampleIndex_.second() == -1)
664 fld = sampleValues_.first();
665 wantedAverage = sampleAverage_.first();
669 const scalar beg = sampleTimes_[sampleIndex_.first()].value();
670 const scalar
end = sampleTimes_[sampleIndex_.second()].value();
671 const scalar
s = (
x - beg)/(
end - beg);
673 fld = (1 -
s)*sampleValues_.first() +
s*sampleValues_.second();
676 = (1 -
s)*sampleAverage_.first() +
s*sampleAverage_.second();
679 <<
"MappedFile<Type>::value : " 680 <<
"Sampled, interpolated values" 682 << sampleTimes_[sampleIndex_.first()].name()
683 <<
" and time:" << sampleTimes_[sampleIndex_.second()].name()
684 <<
" with weight:" <<
s <<
endl;
693 if (this->faceValues())
705 Pout<<
"MappedFile<Type>::value :" 706 <<
" actual average:" << averagePsi
707 <<
" wanted average:" << wantedAverage
711 if (
mag(averagePsi) < VSMALL)
714 const Type offset = wantedAverage - averagePsi;
717 Pout<<
"MappedFile<Type>::value :" 718 <<
" offsetting with:" << offset <<
endl;
724 const scalar scale =
mag(wantedAverage)/
mag(averagePsi);
728 Pout<<
"MappedFile<Type>::value :" 729 <<
" scaling with:" << scale <<
endl;
738 fld += offset_->value(
x);
743 Pout<<
"MappedFile<Type>::value : set fixedValue to min:" <<
gMin(
fld)
771 if (!readerFormat_.empty() && !readerFile_.empty())
773 os.writeEntry(
"readerFormat", readerFormat_);
774 os.writeEntry(
"readerFile", readerFile_);
777 os.writeEntryIfDifferent
784 if (!pointsName_.empty())
786 os.writeEntryIfDifferent<
word>(
"points",
"points", pointsName_);
789 if (!mapMethod_.empty() && !mapMethod_.starts_with(
"planar"))
791 os.writeEntry(
"mapMethod", mapMethod_);
796 os.writeEntry(
"setAverage", setAverage_);
799 os.writeEntryIfDifferent<scalar>(
"perturb", 1
e-5, perturb_);
801 if (filterSweeps_ >= 1)
803 os.writeEntry(
"filterRadius", filterRadius_);
804 os.writeEntry(
"filterSweeps", filterSweeps_);
809 offset_->writeData(
os);
824 if (dictConstructed_)
Patch value mapping from a set of values stored in a file and a set of unstructured points using the ...
static wordList timeNames(const instantList ×)
Helper: extract words of times.
A class for handling file names.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Type gMin(const FieldField< Field, Type > &f)
label find(const T &val, label pos=0) const
Find index of the first occurrence of the value.
static Pair< label > findRange(const UList< instant > ×, const scalar timeVal, const label start=-1)
Find lower/upper indices for given time value in list of instances (linear search) continuing after t...
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
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.
virtual tmp< Field< Type > > value(const scalar) const
Return MappedFile value.
Ignore writing from objectRegistry::writeObject()
const polyPatch const word const word const dictionary & dict
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
virtual tmp< Field< Type > > integrate(const scalar x1, const scalar x2) const
Integrate between two values.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
Type gSum(const FieldField< Field, Type > &f)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Abstract base class to hold the Field mapping addressing and weights.
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
MeshedSurface< face > meshedSurface
virtual void rmap(const PatchFunction1< Type > &pf1, const labelList &addr)
Reverse map the given PatchFunction1 onto this PatchFunction1.
virtual void autoMap(const FieldMapper &mapper)
Map (and resize as needed) from self given a mapping object.
const polyPatch const word const word & entryName
#define DebugInfo
Report an information message using Foam::Info.
virtual void writeData(Ostream &os) const
Write in dictionary format.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Top level data entry class for use in dictionaries. Provides a mechanism to specify a variable as a c...
int debug
Static debugging option.
Pair< label > labelPair
A pair of labels.
Type gMax(const FieldField< Field, Type > &f)
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
OBJstream os(runTime.globalPath()/outputName)
virtual void writeEntries(Ostream &os) const
Write coefficient entries in dictionary format.
static dictionary formatOptions(const dictionary &dict, const word &formatName, const word &entryName="formatOptions")
Same as fileFormats::getFormatOptions.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
List< word > wordList
List of word.
bool starts_with(char c) const
True if string starts with given character (cf. C++20)
static autoPtr< surfaceReader > New(const word &readType, const fileName &fName, const dictionary &options=dictionary())
Return a reference to the selected surfaceReader.
static instantList findTimes(const fileName &directory, const word &constantName="constant")
Search a given directory for valid time directories.
virtual void autoMap(const FieldMapper &mapper)
Map (and resize as needed) from self given a mapping object.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Type gAverage(const FieldField< Field, Type > &f)
const std::string patch
OpenFOAM patch number as a std::string.
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
A class for managing temporary objects.
A patch is a list of labels that address the faces in the global face list.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
virtual void rmap(const PatchFunction1< Type > &rhs, const labelList &addr)
Reverse map the given PatchFunction1 onto this PatchFunction1.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Do not request registration (bool: false)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
static constexpr const zero Zero
Global zero (0)
virtual void writeData(Ostream &os) const
Write in dictionary format.