regionCoupledBase.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 | Copyright (C) 2011-2017 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "regionCoupledBase.H"
27 #include "SubField.H"
28 #include "polyMesh.H"
29 #include "Time.H"
30 
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  defineTypeNameAndDebug(regionCoupledBase, 0);
37 }
38 
39 
40 // * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
41 
42 void Foam::regionCoupledBase::resetAMI() const
43 {
44  if (owner())
45  {
46  AMIPtr_.clear();
47 
48  const polyPatch& nbr = refCast<const polyPatch>(neighbPatch());
49  pointField nbrPoints = nbr.localPoints();
50 
51  if (debug)
52  {
53  const Time& t = patch_.boundaryMesh().mesh().time();
54  OFstream os(t.path()/patch_.name() + "_neighbourPatch-org.obj");
55  meshTools::writeOBJ(os, nbr.localFaces(), nbrPoints);
56  }
57 
58  // transform neighbour patch to local system
59  //transformPosition(nbrPoints);
60  primitivePatch nbrPatch0
61  (
62  SubList<face>
63  (
64  nbr.localFaces(),
65  nbr.size()
66  ),
67  nbrPoints
68  );
69 
70  if (debug)
71  {
72  const Time& t = patch_.boundaryMesh().mesh().time();
73  OFstream osN(t.path()/patch_.name() + "_neighbourPatch-trans.obj");
74  meshTools::writeOBJ(osN, nbrPatch0.localFaces(), nbrPoints);
75 
76  OFstream osO(t.path()/patch_.name() + "_ownerPatch.obj");
78  (
79  osO,
80  patch_.localFaces(),
81  patch_.localPoints()
82  );
83  }
84 
85  // Construct/apply AMI interpolation to determine addressing and weights
86  AMIPtr_.reset
87  (
89  (
90  patch_,
91  nbrPatch0,
92  surfPtr(),
94  true,
96  -1,
97  AMIReverse_
98  )
99  );
100 
101  if (debug)
102  {
103  Pout<< "regionCoupledBase : " << patch_.name()
104  << " constructed AMI with " << nl
105  << " " << ":srcAddress:" << AMIPtr_().srcAddress().size()
106  << nl
107  << " " << " tgAddress :" << AMIPtr_().tgtAddress().size()
108  << nl << endl;
109  }
110  }
111 }
112 
113 
114 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
115 
117 {
118  AMIPtr_.clear();
119  surfPtr_.clear();
120 }
121 
122 
123 // * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
124 
126 (
127  const polyPatch& pp
128 )
129 :
130  patch_(pp),
131  nbrPatchName_(word::null),
132  nbrPatchID_(-1),
133  nbrRegionName_(word::null),
134  sameRegion_(false),
135  AMIPtr_(nullptr),
136  AMIReverse_(false),
137  surfPtr_(nullptr),
138  surfDict_(fileName("surface"))
139 {}
140 
141 
143 (
144  const polyPatch& pp,
145  const dictionary& dict
146 )
147 :
148  patch_(pp),
149  nbrPatchName_(dict.lookup("neighbourPatch")),
150  nbrPatchID_(-1),
151  nbrRegionName_(dict.lookup("neighbourRegion")),
152  sameRegion_(nbrRegionName_ == patch_.boundaryMesh().mesh().name()),
153  AMIPtr_(nullptr),
154  AMIReverse_(dict.lookupOrDefault<bool>("flipNormals", false)),
155  surfPtr_(nullptr),
156  surfDict_(dict.subOrEmptyDict("surface"))
157 {}
158 
159 
161 (
162  const polyPatch& pp,
163  const regionCoupledBase& mpb
164 )
165 :
166  patch_(pp),
167  nbrPatchName_(mpb.nbrPatchName_),
168  nbrPatchID_(mpb.nbrPatchID_),
169  nbrRegionName_(mpb.nbrRegionName_),
170  sameRegion_(mpb.sameRegion_),
171  AMIPtr_(nullptr),
172  AMIReverse_(mpb.AMIReverse_),
173  surfPtr_(mpb.surfPtr_),
174  surfDict_(mpb.surfDict_)
175 {}
176 
177 
178 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
179 
181 {}
182 
183 
184 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
185 
187 {
188  if (nbrPatchID_ == -1)
189  {
190  if
191  (
192  patch_.boundaryMesh().mesh().time().foundObject<polyMesh>
193  (
194  nbrRegionName_
195  )
196  )
197  {
198  const polyMesh& mesh =
200  (
201  nbrRegionName_
202  );
203 
204  nbrPatchID_ = mesh.boundaryMesh().findPatchID(nbrPatchName_);
205 
206  if (nbrPatchID_ == -1)
207  {
209  << "Illegal neighbourPatch name " << nbrPatchName_
210  << nl << "Valid patch names are "
211  << mesh.boundaryMesh().names()
212  << exit(FatalError);
213  }
214 
215  // Check that it is a cyclic AMI patch
216  const regionCoupledBase& nbrPatch =
217  refCast<const regionCoupledBase>
218  (
219  mesh.boundaryMesh()[nbrPatchID_]
220  );
221 
222  if (nbrPatch.nbrPatchName() != patch_.name())
223  {
225  << "Patch " << patch_.name()
226  << " specifies neighbour patch " << nbrPatchName()
227  << nl << " but that in return specifies "
228  << nbrPatch.nbrPatchName() << endl;
229  }
230  }
231  }
232 
233  return nbrPatchID_;
234 }
235 
236 
238 {
239  if (nbrRegionName_ == patch_.boundaryMesh().mesh().name())
240  {
241  return patch_.index() < neighbPatchID();
242  }
243  else
244  {
245  return patch_.boundaryMesh().mesh().name() < nbrRegionName_;
246  }
247 }
248 
249 
251 surfPtr() const
252 {
253  const word surfType(surfDict_.lookupOrDefault<word>("type", "none"));
254 
255  if (!surfPtr_.valid() && owner() && surfType != "none")
256  {
257  word surfName(surfDict_.lookupOrDefault("name", patch_.name()));
258 
259  const polyMesh& mesh = patch_.boundaryMesh().mesh();
260 
261  surfPtr_ =
263  (
264  surfType,
265  IOobject
266  (
267  surfName,
268  mesh.time().constant(),
269  "triSurface",
270  mesh,
273  ),
274  surfDict_
275  );
276  }
277 
278  return surfPtr_;
279 }
280 
281 
283 {
284  if (!owner())
285  {
287  << "AMI interpolator only available to owner patch"
288  << abort(FatalError);
289  }
290 
291  if (!AMIPtr_.valid())
292  {
293  resetAMI();
294  }
295 
296  return AMIPtr_();
297 }
298 
299 
302 {
303  const polyMesh& mesh =
305  (
306  nbrRegionName_
307  );
308 
309  const polyPatch& pp = mesh.boundaryMesh()[neighbPatchID()];
310  return refCast<const regionCoupledBase>(pp);
311 }
312 
313 
315 (
316  PstreamBuffers& pBufs,
317  const primitivePatch& pp,
318  labelList& faceMap,
319  labelList& rotation
320 ) const
321 {
322  faceMap.setSize(pp.size());
323  faceMap = -1;
324 
325  rotation.setSize(pp.size());
326  rotation = 0;
327 
328  return false;
329 }
330 
331 
333 {
334  os.writeKeyword("neighbourPatch") << nbrPatchName_
335  << token::END_STATEMENT << nl;
336  os.writeKeyword("neighbourRegion") << nbrRegionName_
337  << token::END_STATEMENT << nl;
338 
339  if (AMIReverse_)
340  {
341  os.writeKeyword("flipNormals") << AMIReverse_
342  << token::END_STATEMENT << nl;
343  }
344 
345  if (!surfDict_.empty())
346  {
347  os.writeKeyword(surfDict_.dictName());
348  os << surfDict_;
349  }
350 }
351 
352 
353 // ************************************************************************* //
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:424
Base class with common functinality for regionCoupled polyPatch. It includes AMI. ...
virtual const fileName & name() const
Return the name of the stream.
Definition: OSstream.H:88
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
A class for handling file names.
Definition: fileName.H:69
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
virtual void clearGeom()
Clear geometry.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
label findPatchID(const word &patchName) const
Find patch index given a name.
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of point.
Definition: meshTools.C:203
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type.
bool owner() const
Does this side own the patch?
const regionCoupledBase & neighbPatch() const
Return a reference to the neighbour patch.
label neighbPatchID() const
Neighbour patch ID.
A list of faces which address into the list of points.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
dynamicFvMesh & mesh
A class for handling words, derived from string.
Definition: word.H:59
wordList names() const
Return a list of patch names.
const word & constant() const
Return constant name.
Definition: TimePaths.H:124
static const word null
An empty word.
Definition: word.H:77
const polyMesh & mesh() const
Return the mesh reference.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
Return new ordering for primitivePatch.
static const char nl
Definition: Ostream.H:262
const Time & time() const
Return time.
defineTypeNameAndDebug(combustionModel, 0)
Ostream & writeKeyword(const keyType &)
Write the keyword followed by an appropriate indentation.
Definition: Ostream.C:54
Buffers for inter-processor communications streams (UOPstream, UIPstream).
PrimitivePatch< face, SubList, const pointField & > primitivePatch
Addressing for a faceList slice.
virtual ~regionCoupledBase()
Destructor.
void setSize(const label)
Reset size of List.
Definition: List.C:281
regionCoupledBase(const polyPatch &)
Construct from patch.
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
#define WarningInFunction
Report a warning using Foam::Warning.
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
const word & nbrPatchName() const
Neighbour patch name.
Interpolation class dealing with transfer of data between two primitive patches with an arbitrary mes...
static autoPtr< searchableSurface > New(const word &surfaceType, const IOobject &io, const dictionary &dict)
Return a reference to the selected searchableSurface.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
AMIInterpolation< PrimitivePatch< face, SubList, const pointField & >, PrimitivePatch< face, SubList, const pointField & > > AMIPatchToPatchInterpolation
const autoPtr< searchableSurface > & surfPtr() const
Return a reference to the projection surface.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:92
const AMIPatchToPatchInterpolation & AMI() const
Return a reference to the AMI interpolator.
dictionary subOrEmptyDict(const word &, const bool mustRead=false) const
Find and return a sub-dictionary as a copy, or.
Definition: dictionary.C:727
Namespace for OpenFOAM.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:576