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 \*---------------------------------------------------------------------------*/
28 #include "simpleTwoStroke.H"
29 #include "slidingInterface.H"
30 #include "layerAdditionRemoval.H"
31 #include "surfaceFields.H"
32 #include "regionSplit.H"
33 #include "componentMixedTetPolyPatchVectorField.H"
34 #include "mapPolyMesh.H"
36 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
37 void Foam::simpleTwoStroke::makeLayersLive()
39 const polyTopoChanger& morphs = topoChanger_;
44 if (typeid(morphs[modI]) == typeid(layerAdditionRemoval))
46 morphs[modI].enable();
48 else if (typeid(morphs[modI]) == typeid(slidingInterface))
50 morphs[modI].disable();
54 FatalErrorIn("void Foam::simpleTwoStroke::makeLayersLive()")
55 << "Don't know what to do with mesh modifier "
56 << modI << " of type " << morphs[modI].type()
62 void Foam::simpleTwoStroke::makeSlidersLive()
64 const polyTopoChanger& morphs = topoChanger_;
66 // Enable sliding interface
69 if (typeid(morphs[modI]) == typeid(layerAdditionRemoval))
71 morphs[modI].disable();
73 else if (typeid(morphs[modI]) == typeid(slidingInterface))
75 morphs[modI].enable();
79 FatalErrorIn("void movingSquaresTM::makeLayersLive()")
80 << "Don't know what to do with mesh modifier "
81 << modI << " of type " << morphs[modI].type()
88 bool Foam::simpleTwoStroke::attached() const
90 const polyTopoChanger& morphs = topoChanger_;
96 if (typeid(morphs[modI]) == typeid(slidingInterface))
100 || refCast<const slidingInterface>(morphs[modI]).attached();
104 // Check thal all sliders are in sync (debug only)
105 forAll (morphs, modI)
107 if (typeid(morphs[modI]) == typeid(slidingInterface))
112 != refCast<const slidingInterface>(morphs[modI]).attached()
115 FatalErrorIn("bool movingSquaresTM::attached() const")
116 << "Slider " << modI << " named " << morphs[modI].name()
117 << " out of sync: Should be" << result
118 << abort(FatalError);
127 bool Foam::simpleTwoStroke::update()
129 // Detaching the interface
132 Info << "Decoupling sliding interfaces" << endl;
134 topoChanger_.changeMesh();
136 Info << "sliding interfaces successfully decoupled!!!" << endl;
140 Info << "Sliding interfaces decoupled" << endl;
143 Info << "Executing layer action" << endl;
149 // Find piston mesh modifier
150 const label pistonLayerID =
151 topoChanger_.findModifierID("pistonLayer");
153 if (pistonLayerID < 0)
155 FatalErrorIn("void engineFvMesh::moveAndMorph()")
156 << "Piston modifier not found."
157 << abort(FatalError);
160 scalar minLayerThickness = piston().minLayer();
161 scalar deltaZ = engTime().pistonDisplacement().value();
162 virtualPistonPosition() += deltaZ;
164 Info << "virtualPistonPosition = " << virtualPistonPosition()
165 << ", deckHeight = " << deckHeight()
166 << ", pistonPosition = " << pistonPosition() << endl;
168 if (realDeformation())
170 // Dectivate piston layer
171 Info << "Mesh deformation mode" << endl;
172 topoChanger_[pistonLayerID].disable();
176 // Activate piston layer
177 Info << "Piston layering mode" << endl;
178 topoChanger_[pistonLayerID].enable();
182 // Changing topology by hand
183 autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh();
185 // Work array for new points position.
186 pointField newPoints = points();
188 if (topoChangeMap->morphing())
191 if (topoChangeMap->hasMotionPoints())
193 Info << "Topology change; executing pre-motion" << endl;
194 movePoints(topoChangeMap->preMotionPoints());
195 newPoints = topoChangeMap->preMotionPoints();
201 // Reset the position of layered interfaces
203 boolList scaleDisp(nPoints(), true);
204 label nScaled = nPoints();
206 List<bool> pistonPoint(newPoints.size(), false);
207 List<bool> headPoint(newPoints.size(), false);
209 // label pistonPtsIndex = pointZones().findZoneID("pistonPoints");
210 // const labelList& pistonPoints = pointZones()[pistonPtsIndex];
212 labelList pistonPoints;
215 label movingCellsIndex = cellZones().findZoneID("movingCells");
217 if (movingCellsIndex < 0)
219 FatalErrorIn("bool twoStrokeEngine::update()")
220 << "Cannot find cell zone movingCells"
221 << abort(FatalError);
225 const labelList& pistonCells = cellZones()[movingCellsIndex];
227 const labelListList& cp = cellPoints();
229 boolList count(newPoints.size(), false);
231 forAll (pistonCells, cellI)
233 const labelList& curCellPoints = cp[pistonCells[cellI]];
235 forAll (curCellPoints, i)
237 count[curCellPoints[i]] = true;
243 forAll (count, pointI)
245 if (count[pointI] == true)
251 pistonPoints.setSize(nCounted);
253 // Collect the points
255 forAll (count, pointI)
257 if (count[pointI] == true)
259 pistonPoints[nCounted] = pointI;
266 label headPtsIndex = pointZones().findZoneID("headPoints");
267 const labelList& headPoints = pointZones()[headPtsIndex];
269 const scalarField& movingPointsM = movingPointsMask();
271 forAll(pistonPoints, i)
273 label pointI = pistonPoints[i];
274 pistonPoint[pointI] = true;
275 point& p = newPoints[pointI];
277 if (p.z() < pistonPosition() - 1.0e-6)
279 scaleDisp[pointI] = false;
284 forAll(headPoints, i)
286 headPoint[headPoints[i]] = true;
287 scaleDisp[headPoints[i]] = false;
291 if (realDeformation())
293 forAll(scaleDisp, pointI)
295 point& p = newPoints[pointI];
297 if (scaleDisp[pointI])
299 p.z() += movingPointsM[pointI]*
301 * (deckHeight() - p.z())/(deckHeight() - pistonPosition());
305 if (!headPoint[pointI])
307 p.z() += movingPointsM[pointI] * deltaZ;
314 // Always move piston
315 scalar pistonTopZ = -GREAT;
316 forAll(pistonPoints, i)
318 point& p = newPoints[pistonPoints[i]];
319 p.z() += deltaZ*movingPointsM[pistonPoints[i]];
320 pistonTopZ = max(pistonTopZ, p.z());
324 // NN! fix. only needed for compression
327 // check if piston-points have moved beyond the layer above
332 if (virtualPistonPosition() > newPoints[i].z())
335 (1.0 - movingPointsM[i])*newPoints[i].z()
337 (pistonTopZ + 0.9*minLayerThickness);
345 movePoints(newPoints);
347 deleteDemandDrivenData(movingPointsMaskPtr_);
349 pistonPosition() += deltaZ;
352 // Attach the interface
353 Info << "Coupling sliding interfaces" << endl;
356 // Changing topology by hand
357 autoPtr<mapPolyMesh> topoChangeMap3 = topoChanger_.changeMesh();
359 Info << "Sliding interfaces coupled: " << attached() << endl;