1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "linearValveLayersFvMesh.H"
28 #include "slidingInterface.H"
29 #include "layerAdditionRemoval.H"
30 #include "pointField.H"
31 #include "mapPolyMesh.H"
32 #include "polyTopoChange.H"
33 #include "pointZone.H"
35 #include "addToRunTimeSelectionTable.H"
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 defineTypeNameAndDebug(linearValveLayersFvMesh, 0);
43 addToRunTimeSelectionTable
46 linearValveLayersFvMesh,
52 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
54 void Foam::linearValveLayersFvMesh::addZonesAndModifiers()
57 const word innerSliderName(motionDict_.subDict("slider").lookup("inside"));
60 const word outerSliderName
62 motionDict_.subDict("slider").lookup("outside")
65 bool initialised = false;
67 // Check if zones and modifiers for motion action are present
68 label insideZoneID = faceZones().findZoneID(innerSliderName + "Zone");
69 label outsideZoneID = faceZones().findZoneID(outerSliderName + "Zone");
77 // Zones found. Check topo changer
79 if (topoChanger_.empty())
83 "void linearValveLayersFvMesh::addZonesAndModifiers()"
84 ) << "Mesh modifiers not read properly"
91 // Check if slider has been initialised on any of the processors
92 reduce(initialised, orOp<bool>());
96 InfoIn("void linearValveLayersFvMesh::addZonesAndModifiers()")
97 << "Zones and modifiers already present. Skipping."
103 // Add zones and modifiers for motion action
104 Info<< "Time = " << time().timeName() << endl
105 << "Adding zones and modifiers to the mesh" << endl;
111 List<pointZone*> pz(pointZones().size() + 1);
112 List<faceZone*> fz(faceZones().size() + 4);
113 List<cellZone*> cz(cellZones().size());
115 // Add a topology modifier
116 topoChanger_.setSize(2);
119 // Copy existing point zones
120 forAll (pointZones(), zoneI)
122 pz[nPz] = pointZones()[zoneI].clone(pointZones()).ptr();
126 // Copy existing face zones
127 forAll (faceZones(), zoneI)
129 fz[nFz] = faceZones()[zoneI].clone(faceZones()).ptr();
133 // Copy existing cell zones
134 forAll (cellZones(), zoneI)
136 cz[nCz] = cellZones()[zoneI].clone(cellZones()).ptr();
142 // Do face zones for slider
145 const polyPatch& innerSlider =
146 boundaryMesh()[boundaryMesh().findPatchID(innerSliderName)];
149 const polyPatch& outerSlider =
150 boundaryMesh()[boundaryMesh().findPatchID(outerSliderName)];
152 if (!innerSlider.empty() && !outerSlider.empty())
154 Pout<< "Adding sliding interface between patches "
155 << innerSliderName << " and " << outerSliderName << endl;
158 // Add an empty zone for cut points
159 pz[nPz] = new pointZone
168 labelList isf(innerSlider.size());
172 isf[i] = innerSlider.start() + i;
175 fz[nFz] = new faceZone
177 innerSliderName + "Zone",
179 boolList(innerSlider.size(), false),
185 labelList osf(outerSlider.size());
189 osf[i] = outerSlider.start() + i;
192 fz[nFz] = new faceZone
194 outerSliderName + "Zone",
196 boolList(outerSlider.size(), false),
202 // Add empty zone for cut faces
203 fz[nFz] = new faceZone
214 // Add face zone for layer addition. This is present on all processors
215 const word layerPatchName
217 motionDict_.subDict("layer").lookup("patch")
220 const polyPatch& layerPatch =
221 boundaryMesh()[boundaryMesh().findPatchID(layerPatchName)];
223 labelList lpf(layerPatch.size());
227 lpf[i] = layerPatch.start() + i;
230 fz[nFz] = new faceZone
234 boolList(layerPatch.size(), true),
240 // Resize the number of live zones
243 // Cell zones remain unchanged
245 Info << "Adding point and face zones" << endl;
247 addZones(pz, fz, cz);
249 if (!innerSlider.empty() && !outerSlider.empty())
251 // Set the topo changer for sliding interface
260 outerSliderName + "Zone",
261 innerSliderName + "Zone",
266 slidingInterface::INTEGRAL, // Edge matching algorithm
267 true, // Attach-detach action
268 intersection::VISIBLE // Projection algorithm
272 // Record one added topo modifyer
276 // Add the layer addition-removal topo modifyer
280 new layerAdditionRemoval
288 motionDict_.subDict("layer").lookup("minThickness")
292 motionDict_.subDict("layer").lookup("maxThickness")
298 // Reset the size of mesh modifiers
299 topoChanger_.setSize(nTc);
300 Pout<< nTc << " topology modifiers on processor" << endl;
301 // Write mesh and modifiers
302 topoChanger_.writeOpt() = IOobject::AUTO_WRITE;
303 topoChanger_.write();
306 // Update the mesh for changes in zones. This needs to
307 // happen after write, because mesh instance will be changed
308 // HJ and OP, 20/Nov/2013
313 void Foam::linearValveLayersFvMesh::makeLayersLive()
315 const polyTopoChanger& topoChanges = topoChanger_;
318 forAll (topoChanges, modI)
320 if (isA<layerAdditionRemoval>(topoChanges[modI]))
322 topoChanges[modI].enable();
324 else if (isA<slidingInterface>(topoChanges[modI]))
326 topoChanges[modI].disable();
330 FatalErrorIn("void linearValveLayersFvMesh::makeLayersLive()")
331 << "Don't know what to do with mesh modifier "
332 << modI << " of type " << topoChanges[modI].type()
333 << abort(FatalError);
339 void Foam::linearValveLayersFvMesh::makeSlidersLive()
341 const polyTopoChanger& topoChanges = topoChanger_;
343 // Enable sliding interface
344 forAll (topoChanges, modI)
346 if (isA<layerAdditionRemoval>(topoChanges[modI]))
348 topoChanges[modI].disable();
350 else if (isA<slidingInterface>(topoChanges[modI]))
352 topoChanges[modI].enable();
356 FatalErrorIn("void linearValveLayersFvMesh::makeLayersLive()")
357 << "Don't know what to do with mesh modifier "
358 << modI << " of type " << topoChanges[modI].type()
359 << abort(FatalError);
365 bool Foam::linearValveLayersFvMesh::attached() const
367 const polyTopoChanger& topoChanges = topoChanger_;
371 forAll (topoChanges, modI)
373 if (isA<slidingInterface>(topoChanges[modI]))
377 || refCast<const slidingInterface>(topoChanges[modI]).attached();
381 // Check that all sliders are in sync (debug only)
382 forAll (topoChanges, modI)
384 if (isA<slidingInterface>(topoChanges[modI]))
389 != refCast<const slidingInterface>(topoChanges[modI]).attached()
392 FatalErrorIn("bool linearValveLayersFvMesh::attached() const")
393 << "Slider " << modI << " named "
394 << topoChanges[modI].name()
395 << " out of sync: Should be" << result
396 << abort(FatalError);
401 // Sync across processors
402 reduce(result, orOp<bool>());
408 Foam::tmp<Foam::pointField>
409 Foam::linearValveLayersFvMesh::newLayerPoints() const
411 tmp<pointField> tnewLayerPoints
413 new pointField(allPoints())
416 pointField& np = tnewLayerPoints();
418 const word layerPatchName
420 motionDict_.subDict("layer").lookup("patch")
423 const polyPatch& layerPatch =
424 boundaryMesh()[boundaryMesh().findPatchID(layerPatchName)];
426 const labelList& patchPoints = layerPatch.meshPoints();
430 motionDict_.lookup("pistonVelocity")
433 forAll (patchPoints, ppI)
435 np[patchPoints[ppI]] += vel*time().deltaT().value();
438 return tnewLayerPoints;
443 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
445 // Construct from components
446 Foam::linearValveLayersFvMesh::linearValveLayersFvMesh(const IOobject& io)
448 topoChangerFvMesh(io),
461 ).subDict(typeName + "Coeffs")
464 addZonesAndModifiers();
468 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
470 Foam::linearValveLayersFvMesh::~linearValveLayersFvMesh()
474 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
476 bool Foam::linearValveLayersFvMesh::update()
478 // Detaching the interface
481 Info<< "Decoupling sliding interfaces" << endl;
484 // Changing topology by hand
485 autoPtr<mapPolyMesh> topoChangeMap1 = topoChanger_.changeMesh();
487 bool localMorphing1 = topoChangeMap1->morphing();
489 // Note: Since we are detaching, global morphing is always true
494 Info << "Topology change; executing pre-motion after "
495 << "sliding detach" << endl;
496 movePoints(topoChangeMap1->preMotionPoints());
500 pointField newPoints = allPoints();
503 movePoints(newPoints);
506 Info<< "sliding interfaces successfully decoupled!!!" << endl;
510 Info<< "Sliding interfaces decoupled" << endl;
513 // Perform layer action and mesh motion
516 // Changing topology by hand
517 autoPtr<mapPolyMesh> topoChangeMap2 = topoChanger_.changeMesh();
519 bool localMorphing2 = topoChangeMap2->morphing();
520 bool globalMorphing2 = localMorphing2;
522 reduce(globalMorphing2, orOp<bool>());
524 // Work array for new points position.
525 pointField newPoints = allPoints();
529 Info<< "Topology change; executing pre-motion after "
530 << "dynamic layering" << endl;
534 Info << "Topology change; executing pre-motion" << endl;
535 // Note: using setOldPoints instead of movePoints.
537 setOldPoints(topoChangeMap2->preMotionPoints());
538 newPoints = topoChangeMap2->preMotionPoints();
542 // Note: using setOldPoints instead of movePoints.
544 setOldPoints(newPoints);
551 // Move points to change layer thickness
552 movePoints(newLayerPoints());
554 // Changing topology by hand
556 // Grab old points to correct the motion
557 pointField oldPointsNew = oldAllPoints();
559 // Attach the interface
560 Info << "Coupling sliding interfaces" << endl;
563 autoPtr<mapPolyMesh> topoChangeMap3 = topoChanger_.changeMesh();
565 bool localMorphing3 = topoChangeMap3->morphing();
566 bool globalMorphing3 = localMorphing3;
568 reduce(globalMorphing3, orOp<bool>());
572 Info<< "Topology change; executing pre-motion after "
573 << "sliding attach" << endl;
576 newPoints = allPoints();
580 // If there is layering, pick up correct points
581 if (topoChangeMap3->hasMotionPoints())
583 newPoints = topoChangeMap3->preMotionPoints();
586 pointField mappedOldPointsNew(newPoints.size());
588 mappedOldPointsNew.map
591 topoChangeMap3->pointMap()
594 // Solve the correct mesh motion to make sure motion fluxes
595 // are solved for and not mapped
596 // Note: using setOldPoints instead of movePoints.
598 setOldPoints(mappedOldPointsNew);
603 // Set new point motion
604 movePoints(newPoints);
608 // No local topological change. Execute double motion for
609 // sync with topological changes
610 // Note: using setOldPoints instead of movePoints.
612 setOldPoints(oldPointsNew);
617 // Set new point motion
618 movePoints(newPoints);
627 // ************************************************************************* //