1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "layerARGambit.H"
28 #include "engineTime.H"
29 #include "layerAdditionRemoval.H"
30 #include "pointField.H"
31 #include "mapPolyMesh.H"
32 #include "polyTopoChange.H"
33 #include "addToRunTimeSelectionTable.H"
34 #include "GeometricField.H"
36 #include "fvPatchField.H"
37 #include "volPointInterpolation.H"
38 #include "fvcMeshPhi.H"
39 #include "fvcVolumeIntegrate.H"
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 defineTypeNameAndDebug(layerARGambit, 0);
45 addToRunTimeSelectionTable(engineTopoChangerMesh, layerARGambit, IOobject);
49 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
51 void Foam::layerARGambit::makeLayersLive()
53 const polyTopoChanger& topoChanges = topoChanger_;
56 forAll (topoChanges, modI)
58 if (typeid(topoChanges[modI]) == typeid(layerAdditionRemoval))
60 topoChanges[modI].enable();
64 FatalErrorIn("void Foam::layerARGambit::makeLayersLive()")
65 << "Don't know what to do with mesh modifier "
66 << modI << " of type " << topoChanges[modI].type()
73 void Foam::layerARGambit::checkAndCalculate()
75 label pistonIndex = -1;
76 bool foundPiston = false;
78 label linerIndex = -1;
79 bool foundLiner = false;
81 label cylinderHeadIndex = -1;
82 bool foundCylinderHead = false;
86 Info << boundary()[i].name() << endl;
87 if (boundary()[i].name() == "piston")
92 else if (boundary()[i].name() == "liner")
97 else if (boundary()[i].name() == "cylinderHead")
99 cylinderHeadIndex = i;
100 foundCylinderHead = true;
104 reduce(foundPiston, orOp<bool>());
105 reduce(foundLiner, orOp<bool>());
106 reduce(foundCylinderHead, orOp<bool>());
110 FatalErrorIn("Foam::layerARGambit::checkAndCalculate()")
111 << " : cannot find piston patch"
112 << abort(FatalError);
117 FatalErrorIn("Foam::layerARGambit::checkAndCalculate()")
118 << " : cannot find liner patch"
119 << abort(FatalError);
122 if (!foundCylinderHead)
124 FatalErrorIn("Foam::layerARGambit::checkAndCalculate()")
125 << " : cannot find cylinderHead patch"
130 if (linerIndex != -1)
133 max(boundary()[pistonIndex].patch().localPoints()).z();
135 reduce(pistonPosition(), minOp<scalar>());
137 if (cylinderHeadIndex != -1)
141 boundary()[cylinderHeadIndex].patch().localPoints()
144 reduce(deckHeight(), minOp<scalar>());
146 Info<< "deckHeight: " << deckHeight() << nl
147 << "piston position: " << pistonPosition() << endl;
151 void Foam::layerARGambit::setVirtualPistonPosition()
154 label pistonFaceIndex = faceZones().findZoneID("pistonLayerFaces");
156 bool foundPistonFace = (pistonFaceIndex != -1);
158 Info << "piston face index = " << pistonFaceIndex << endl;
162 FatalErrorIn("Foam::layerARGambit::setVirtualPistonPosition()")
163 << " : cannot find the pistonLayerFaces"
167 const labelList& pistonFaces = faceZones()[pistonFaceIndex];
168 forAll(pistonFaces, i)
170 const face& f = faces()[pistonFaces[i]];
172 // should loop over facepoints...
175 virtualPistonPosition() =
176 Foam::max(virtualPistonPosition(), points()[f[j]].z());
180 reduce(virtualPistonPosition(), maxOp<scalar>());
185 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
187 // Construct from components
188 Foam::layerARGambit::layerARGambit
193 engineTopoChangerMesh(io),
194 piston_(*this, engTime().engineDict().subDict("piston")),
195 deformSwitch_(readScalar(engTime().engineDict().lookup("deformAngle"))),
196 delta_(readScalar(engTime().engineDict().lookup("delta"))),
197 offSet_(readScalar(engTime().engineDict().lookup("offSet"))),
198 pistonPosition_(-GREAT),
199 virtualPistonPosition_(-GREAT),
202 // Add zones and modifiers if not already there.
203 addZonesAndModifiers();
207 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
209 Foam::layerARGambit::~layerARGambit()
213 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
215 bool Foam::layerARGambit::update()
217 scalar deltaZ = engTime().pistonDisplacement().value();
218 Info<< "deltaZ = " << deltaZ << " Piston at:" << pistonPosition()
220 virtualPistonPosition() += deltaZ;
222 // Find piston mesh modifier
223 const label pistonLayerID =
224 topoChanger_.findModifierID("pistonLayer");
226 Info << "pistonLayerID: " << pistonLayerID << endl;
228 const layerAdditionRemoval& pistonLayers =
229 dynamicCast<const layerAdditionRemoval>
231 topoChanger_[pistonLayerID]
234 bool realDeformation = deformation();
238 virtualPistonPosition() + deltaZ
239 > deckHeight()-engTime().clearance().value() - SMALL
242 realDeformation = true;
247 // Disable layer addition
248 Info << "Mesh deformation mode" << endl;
249 topoChanger_[pistonLayerID].disable();
253 // Enable layer addition
254 Info << "Piston layering mode" << endl;
255 topoChanger_[pistonLayerID].enable();
258 scalar minLayerThickness = pistonLayers.minLayerThickness();
260 autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh();
262 bool meshChanged = topoChangeMap->morphing();
264 pointField newPoints = allPoints();
268 if (topoChangeMap().hasMotionPoints())
270 movePoints(topoChangeMap().preMotionPoints());
271 newPoints = topoChangeMap().preMotionPoints();
277 Info << "virtualPistonPosition = " << virtualPistonPosition()
278 << ", deckHeight = " << deckHeight() << endl;
280 // Mesh in three parts:
281 // - pistonPoints - move with deltaZ
282 // - headPoints - do not move
284 const pointZoneMesh& pZones = pointZones();
285 label headPtsIndex = pZones.findZoneID("headPoints");
286 label pistonPtsIndex = pZones.findZoneID("pistonPoints");
287 const labelList& pistonPoints = pZones[pistonPtsIndex];
288 const labelList& headPoints = pZones[headPtsIndex];
291 // Whether point displacement is by scaling
292 boolList scaleDisp(nPoints(), true);
293 label nScaled = nPoints();
294 List<bool> pistonPoint(newPoints.size(), false);
295 List<bool> headPoint(newPoints.size(), false);
297 forAll(pistonPoints, i)
299 label pointI = pistonPoints[i];
300 pistonPoint[pointI] = true;
301 point& p = newPoints[pointI];
303 if (p.z() < pistonPosition() - 1.0e-6)
305 scaleDisp[pointI] = false;
310 forAll(headPoints, i)
312 headPoint[headPoints[i]] = true;
313 scaleDisp[headPoints[i]] = false;
320 forAll(scaleDisp, pointI)
322 point& p = newPoints[pointI];
324 if (scaleDisp[pointI])
328 * (deckHeight() - p.z())/(deckHeight() - pistonPosition());
332 if (!headPoint[pointI])
342 // Always move piston
343 scalar pistonTopZ = -GREAT;
344 forAll(pistonPoints, i)
346 point& p = newPoints[pistonPoints[i]];
348 pistonTopZ = max(pistonTopZ, p.z());
352 // NN! fix. only needed for compression
355 // check if piston-points have moved beyond the layer above
360 if (virtualPistonPosition() > newPoints[i].z())
362 newPoints[i].z() = pistonTopZ + 0.9*minLayerThickness;
369 movePoints(newPoints);
371 pistonPosition() += deltaZ;
372 scalar pistonSpeed = deltaZ/engTime().deltaT().value();
374 Info<< "clearance: " << deckHeight() - pistonPosition() << nl
375 << "Piston speed = " << pistonSpeed << " m/s" << endl;
377 Info << "Total cylinder volume at CA " << engTime().timeName() << " = " <<
384 void Foam::layerARGambit::setBoundaryVelocity(volVectorField& U)
386 // Does nothing, using the movingWallVelocity boundary condition for U in the piston patch...
388 // vector pistonVel = piston().cs().axis()*engTime().pistonSpeed().value();
390 //mean piston velocityy
392 vector pistonVel = 0.5 * piston().cs().axis()*
397 2.0*engTime().stroke().value()*engTime().rpm().value()/60.0
401 // U.boundaryField()[piston().patchID().index()] = pistonVel;
404 // ************************************************************************* //