Loading...
Searching...
No Matches
MapFieldConstraint.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) 2023-2024 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "MapFieldConstraint.H"
29#include "fvMatrices.H"
30#include "meshToMesh.H"
31#include "Function1.H"
32
33// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
34
35namespace Foam
36{
37
39(
40 const fvMesh& mesh,
41 const scalar val
42)
43{
45 (
48 mesh,
49 val,
51 );
52}
53
54} // End namespace Foam
55
56
57// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
58
59template<class Type>
60void Foam::fv::MapFieldConstraint<Type>::setSourceMesh
61(
62 refPtr<fvMesh>& meshRef,
63 const autoPtr<Time>& runTimePtr
64)
65{
66 const Time& runTime = runTimePtr();
67 const word meshName(polyMesh::defaultRegion);
68
69 // Fetch mesh from Time database
70 meshRef.cref
71 (
72 runTime.cfindObject<fvMesh>(meshName)
73 );
74
75 if (!meshRef)
76 {
77 // Fallback: load mesh from disk and cache it
78 meshRef.reset
79 (
80 new fvMesh
81 (
82 IOobject
83 (
84 meshName,
85 runTime.timeName(),
86 runTime,
87 IOobject::MUST_READ,
88 IOobject::NO_WRITE,
89 IOobject::REGISTER
90 )
91 )
92 );
93 }
94}
95
96
97template<class Type>
98void Foam::fv::MapFieldConstraint<Type>::createInterpolation
99(
100 const fvMesh& srcMesh,
101 const fvMesh& tgtMesh
102)
103{
104 if (consistent_)
105 {
106 interpPtr_.reset
107 (
108 new meshToMesh
109 (
110 srcMesh,
111 tgtMesh,
112 mapMethodName_,
113 patchMapMethodName_
114 )
115 );
116 }
117 else
118 {
119 interpPtr_.reset
120 (
121 new meshToMesh
122 (
123 srcMesh,
124 tgtMesh,
125 mapMethodName_,
126 patchMapMethodName_,
127 patchMap_,
128 cuttingPatches_
129 )
130 );
131 }
132}
133
134
135template<class Type>
136template<class VolFieldType>
137VolFieldType& Foam::fv::MapFieldConstraint<Type>::getOrReadField
138(
139 const fvMesh& thisMesh,
140 const word& fieldName
141) const
142{
143 auto* ptr = thisMesh.getObjectPtr<VolFieldType>(fieldName);
144
145 if (!ptr)
146 {
147 ptr = new VolFieldType
148 (
149 IOobject
150 (
151 fieldName,
152 thisMesh.time().timeName(),
153 thisMesh.thisDb(),
154 IOobject::MUST_READ,
155 IOobject::NO_WRITE,
156 IOobject::REGISTER
157 ),
158 thisMesh
159 );
160 regIOobject::store(ptr);
161 }
162
163 return *ptr;
164}
165
166
167template<class Type>
168Foam::labelList Foam::fv::MapFieldConstraint<Type>::tgtCellIDs() const
169{
170 const fvMesh& srcMesh = srcMeshPtr_();
171 const fvMesh& tgtMesh = mesh_;
172
173 // Create mask fields
174 const volScalarField srcFld(createField(srcMesh, 1));
175 volScalarField tgtFld(createField(tgtMesh, 0));
176
177 // Map the mask field of 1s onto the mask field of 0s
178 interpPtr_->mapSrcToTgt(srcFld, plusEqOp<scalar>(), tgtFld);
179
180 // Identify and collect cell indices whose values were changed from 0 to 1
181 DynamicList<label> cells;
182 forAll(tgtFld, i)
183 {
184 if (tgtFld[i] != 0)
185 {
186 cells.append(i);
187 }
188 }
189
190 return cells;
191}
192
193
194// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
195
196template<class Type>
197Foam::fv::MapFieldConstraint<Type>::transform::transform()
198:
199 positionPtr_(),
200 directionPtr_(),
201 points_(),
202 origin_(),
203 normal_(),
204 active_(false)
205{}
206
207
208template<class Type>
210(
211 const word& name,
212 const word& modelType,
213 const dictionary& dict,
214 const fvMesh& mesh
215)
216:
217 fv::option(name, modelType, dict, mesh),
218 transform_(),
219 srcTimePtr_(),
220 srcMeshPtr_(),
221 interpPtr_(),
222 patchMap_(),
223 cells_(),
224 cuttingPatches_(),
225 mapMethodName_(),
226 patchMapMethodName_(),
227 consistent_(false)
228{
229 read(dict);
230
231 setSourceMesh(srcMeshPtr_, srcTimePtr_);
232
233 const fvMesh& srcMesh = srcMeshPtr_();
234 const fvMesh& tgtMesh = mesh_;
235 createInterpolation(srcMesh, tgtMesh);
236
237 cells_ = tgtCellIDs();
238
239 if (returnReduceAnd(cells_.empty()))
240 {
242 << "No cells selected!" << endl;
243 }
244
245 transform_.initialize(srcMesh, dict);
246}
247
248
249// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
250
251template<class Type>
252bool Foam::fv::MapFieldConstraint<Type>::transform::initialize
253(
254 const fvMesh& srcMesh,
255 const dictionary& dict
256)
257{
258 const dictionary* subDictPtr = dict.findDict("transform");
259
260 if (!subDictPtr)
261 {
262 return false;
263 }
264
265 positionPtr_.reset
266 (
268 (
269 "position",
270 *subDictPtr,
272 &srcMesh
273 )
274 );
275
276 directionPtr_.reset
277 (
279 (
280 "direction",
281 *subDictPtr,
283 &srcMesh
284 )
285 );
286
287 if (positionPtr_)
288 {
289 subDictPtr->readIfPresent("origin", origin_);
290 }
291
292 if (directionPtr_)
293 {
294 subDictPtr->readIfPresent("normal", normal_);
295 normal_.normalise();
296 }
297
298 points_ = srcMesh.points();
299
300 active_ = true;
301
302 return true;
303}
304
305
306template<class Type>
307void Foam::fv::MapFieldConstraint<Type>::transform::translate
308(
309 refPtr<fvMesh>& srcMeshPtr,
310 const scalar t
311)
312{
313 if (!positionPtr_)
314 {
315 return;
316 }
317
318 const pointField translate
319 (
320 points_ + (positionPtr_->value(t) - origin_)
321 );
322
323 fvMesh& srcMesh = srcMeshPtr.ref();
324 srcMesh.movePoints(translate);
325}
326
327
328template<class Type>
329void Foam::fv::MapFieldConstraint<Type>::transform::rotate
330(
331 refPtr<fvMesh>& srcMeshPtr,
332 const scalar t
333)
334{
335 if (!directionPtr_)
336 {
337 return;
338 }
339
340 const vector dir(normalised(directionPtr_->value(t)));
341
342 const tensor rot(rotationTensor(normal_, dir));
343
344 pointField rotate(points_);
345
346 Foam::transform(rotate, rot, rotate);
348 fvMesh& srcMesh = srcMeshPtr.ref();
349 srcMesh.movePoints(rotate);
350}
351
352
353template<class Type>
355{
357 {
358 return false;
359 }
360
361 fieldNames_.resize(1, coeffs_.getWord("field"));
362
364
365 // Load the time database for the source mesh once per simulation
366 if (!srcTimePtr_)
367 {
368 fileName srcMesh(coeffs_.get<fileName>("srcMesh").expand());
369 srcMesh.clean();
370
371 srcTimePtr_.reset(Time::New(srcMesh));
372
373 // Set time-step of source database to an arbitrary yet safe value
374 srcTimePtr_().setDeltaT(1.0);
375 }
376
377 coeffs_.readEntry("mapMethod", mapMethodName_);
378 if (!meshToMesh::interpolationMethodNames_.found(mapMethodName_))
379 {
381 << type() << " " << name() << ": unknown map method "
382 << mapMethodName_ << nl
383 << "Available methods include: "
385 << exit(FatalIOError);
386 }
387
388 coeffs_.readIfPresent("consistent", consistent_);
389 coeffs_.readIfPresent("patchMap", patchMap_);
390 coeffs_.readIfPresent("cuttingPatches", cuttingPatches_);
391
392 if (!coeffs_.readIfPresent("patchMapMethod", patchMapMethodName_))
393 {
395 (
397 );
398 patchMapMethodName_ = meshToMesh::interpolationMethodAMI(mapMethod);
400
401 return true;
402}
403
404
405template<class Type>
407(
408 fvMatrix<Type>& eqn,
409 const label
410)
411{
413 << "MapFieldConstraint<"
415 << ">::constrain for source " << name_ << endl;
416
417 // Translate and/or rotate source mesh if requested
418 if (transform_.isActive())
419 {
420 // Use time from mesh_ since source mesh does not advance in time
421 const scalar t = mesh_.time().timeOutputValue();
422 transform_.translate(srcMeshPtr_, t);
423 transform_.rotate(srcMeshPtr_, t);
424 }
425
426 typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
427
428 const word& fldName = fieldNames_[0];
429
430 const fvMesh& srcMesh = srcMeshPtr_();
431 const fvMesh& tgtMesh = mesh_;
432
433 // Fetch source and target fields
434 const VolFieldType& srcFld = getOrReadField<VolFieldType>(srcMesh, fldName);
435 VolFieldType& tgtFld = tgtMesh.lookupObjectRef<VolFieldType>(fldName);
436
437 // When mesh/src changes, reinitilize mesh-to-mesh members
438 if (tgtMesh.changing() || transform_.isActive())
439 {
440 createInterpolation(srcMesh, tgtMesh);
441 cells_ = tgtCellIDs();
442 }
443
444 // Map source-mesh field onto target-mesh field
445 interpPtr_->mapSrcToTgt(srcFld, plusEqOp<Type>(), tgtFld);
446
447 // Constrain mapped field in target mesh to avoid overwrite by solver
448 eqn.setValues(cells_, UIndirectList<Type>(tgtFld, cells_));
449}
450
451
452// ************************************************************************* //
bool found
static autoPtr< Function1< Type > > NewIfPresent(const word &entryName, const dictionary &dict, const word &redirectType, const objectRegistry *obrPtr=nullptr)
An optional selector, with fallback redirection.
Generic GeometricField class.
static tmp< GeometricField< scalar, fvPatchField, volMesh > > New(const word &name, IOobjectOption::registerOption regOpt, const Mesh &mesh, const dimensionSet &dims, const word &patchFieldType=fvPatchField< scalar >::calculatedType())
@ NO_REGISTER
Do not request registration (bool: false).
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition TimeNew.C:26
A List with indirect addressing. Like IndirectList but does not store addressing.
bool empty() const noexcept
True if List is empty (ie, size() is zero).
Definition UList.H:701
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
A class for handling file names.
Definition fileName.H:75
static bool clean(std::string &str)
Cleanup filename string, possibly applies other transformations such as changing the path separator e...
Definition fileName.C:192
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition fvMatrix.H:118
void setValues(const labelUList &cellLabels, const Type &value)
Set solution in given cells to the specified value and eliminate the corresponding equations from the...
Definition fvMatrix.C:971
Mesh data needed to do the Finite Volume discretisation.
Definition fvMesh.H:85
virtual void movePoints(const pointField &)
Move points, returns volumes swept by faces in motion.
Definition fvMesh.C:884
MapFieldConstraint(const word &name, const word &modelType, const dictionary &dict, const fvMesh &mesh)
Construct from components.
virtual void constrain(fvMatrix< Type > &eqn, const label)
Set value on field.
virtual bool read(const dictionary &dict)
Read source dictionary.
Base abstract class for handling finite volume options (i.e. fvOption).
Definition fvOption.H:124
bool active_
Source active flag.
Definition fvOption.H:167
const word & name() const noexcept
Return const access to the source name.
Definition fvOptionI.H:24
const fvMesh & mesh_
Reference to the mesh database.
Definition fvOption.H:142
wordList fieldNames_
Field names to apply source to - populated by derived models.
Definition fvOption.H:157
option(const word &name, const word &modelType, const dictionary &dict, const fvMesh &mesh)
Construct from components.
Definition fvOption.C:51
virtual bool read(const dictionary &dict)
Read source dictionary.
Definition fvOptionIO.C:48
dictionary coeffs_
Dictionary containing source coefficients.
Definition fvOption.H:152
void resetApplied()
Resize/reset applied flag list for all fieldNames_ entries.
Definition fvOption.C:41
const fvMesh & mesh() const noexcept
Return const access to the mesh database.
Definition fvOptionI.H:30
const word name_
Source name.
Definition fvOption.H:132
interpolationMethod
Enumeration specifying interpolation method.
Definition meshToMesh.H:70
static word interpolationMethodAMI(const interpolationMethod method)
Conversion between mesh and patch interpolation methods.
Definition meshToMesh.C:639
static const Enum< interpolationMethod > interpolationMethodNames_
Definition meshToMesh.H:77
Type & lookupObjectRef(const word &name, const bool recursive=false) const
Lookup and return non-const reference to the object of the given Type. Fatal if not found or the wron...
A traits class, which is primarily used for primitives and vector-space.
Definition pTraits.H:64
static word defaultRegion
Return the default region name.
Definition polyMesh.H:406
virtual const pointField & points() const
Return raw points.
Definition polyMesh.C:1063
bool changing() const noexcept
Is mesh changing (topology changing and/or moving).
Definition polyMesh.H:768
void reset(const label nPoints, const label nInternalFaces, const label nFaces, const label nCells)
Reset this primitiveMesh given the primitive array sizes.
string & expand(const bool allowEmpty=false)
Inplace expand initial tags, tildes, and all occurrences of environment variables as per stringOps::e...
Definition string.C:166
A class for managing temporary objects.
Definition tmp.H:75
A class for handling words, derived from Foam::string.
Definition word.H:66
static const word null
An empty word.
Definition word.H:84
dynamicFvMesh & mesh
Info<< "Create engine time\n"<< endl;autoPtr< engineTime > runTimePtr(engineTime::New(Time::controlDictName, args.rootPath(), args.caseName()))
engineTime & runTime
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
A special matrix type and solver, designed for finite volume solutions of scalar equations.
auto & name
const cellShapeList & cells
#define DebugInfo
Report an information message using Foam::Info.
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for finite-volume.
Namespace for OpenFOAM.
const dimensionSet dimless
Dimensionless.
List< label > labelList
A List of labels.
Definition List.H:62
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
tensor rotationTensor(const vector &n1, const vector &n2)
Rotational transformation tensor from vector n1 to n2.
Definition transform.H:47
refinementData transform(const tensor &, const refinementData val)
No-op rotational transform for base types.
Tensor< scalar > tensor
Definition symmTensor.H:57
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition POSIX.C:801
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
bool returnReduceAnd(const bool value, const int communicator=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
vectorField pointField
pointField is a vectorField.
Vector< scalar > vector
Definition vector.H:57
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
static tmp< volScalarField > createField(const fvMesh &mesh, const scalar val)
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