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 "twoStrokeEngine.H"
28 #include "slidingInterface.H"
29 #include "layerAdditionRemoval.H"
30 #include "surfaceFields.H"
31 #include "regionSplit.H"
32 #include "componentMixedTetPolyPatchVectorField.H"
33 #include "mapPolyMesh.H"
35 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
37 void Foam::twoStrokeEngine::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::twoStrokeEngine::makeLayersLive()")
55 << "Don't know what to do with mesh modifier "
56 << modI << " of type " << morphs[modI].type()
62 void Foam::twoStrokeEngine::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::twoStrokeEngine::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::twoStrokeEngine::update()
129 // Detaching the interface
132 Info << "Decoupling sliding interfaces" << endl;
135 // Changing topology by hand
136 autoPtr<mapPolyMesh> topoChangeMap5 = topoChanger_.changeMesh();
138 if (topoChangeMap5->hasMotionPoints() && topoChangeMap5->morphing())
140 Info << "Topology change; executing pre-motion after "
141 << "sliding detach" << endl;
142 movePoints(topoChangeMap5->preMotionPoints());
145 Info << "sliding interfaces successfully decoupled!!!" << endl;
149 Info << "Sliding interfaces decoupled" << endl;
152 Info << "Executing layer action" << endl;
157 // Changing topology by hand
160 // /* Tommaso, 23/5/2008
162 // Find piston mesh modifier
163 const label pistonLayerID =
164 topoChanger_.findModifierID("pistonLayer");
166 if (pistonLayerID < 0)
168 FatalErrorIn("void engineFvMesh::moveAndMorph()")
169 << "Piston modifier not found."
170 << abort(FatalError);
173 scalar minLayerThickness = piston().minLayer();
174 scalar deltaZ = engTime().pistonDisplacement().value();
175 virtualPistonPosition() += deltaZ;
177 Info << "virtualPistonPosition = " << virtualPistonPosition()
178 << ", deckHeight = " << deckHeight()
179 << ", pistonPosition = " << pistonPosition() << endl;
181 if (realDeformation())
183 // Dectivate piston layer
184 Info << "Mesh deformation mode" << endl;
185 topoChanger_[pistonLayerID].disable();
189 // Activate piston layer
190 Info << "Piston layering mode" << endl;
191 topoChanger_[pistonLayerID].enable();
195 // Changing topology by hand
196 autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh();
198 // Work array for new points position.
199 pointField newPoints = allPoints();
200 const pointField& refPoints = allPoints();
202 if (topoChangeMap->morphing())
204 if (topoChangeMap->hasMotionPoints())
206 Info<< "Topology change; executing pre-motion after "
207 << "dynamic layering" << endl;
208 movePoints(topoChangeMap->preMotionPoints());
209 newPoints = topoChangeMap->preMotionPoints();
216 // Reset the position of layered interfaces
218 boolList scaleDisp(nPoints(), true);
220 boolList pistonPoint(newPoints.size(), false);
221 boolList headPoint(newPoints.size(), false);
223 // Make a list of piston and head points. HJ, 2/Dec/2009
225 labelList pistonPoints;
226 labelList headPoints;
228 label pistonCellIndex = cellZones().findZoneID("pistonCells");
230 if (pistonCellIndex < 0)
232 FatalErrorIn("bool twoStrokeEngine::update()")
233 << "Cannot find cell zone pistonCells"
234 << abort(FatalError);
238 const labelList& pistonCells = cellZones()[pistonCellIndex];
240 label headCellIndex = cellZones().findZoneID("headCells");
242 if (headCellIndex < 0)
244 FatalErrorIn("bool twoStrokeEngine::update()")
245 << "Cannot find cell zone headCells"
246 << abort(FatalError);
249 const labelList& headCells = cellZones()[headCellIndex];
251 const labelListList& cp = cellPoints();
253 boolList count(newPoints.size(), false);
255 forAll (pistonCells, cellI)
257 const labelList& curCellPoints = cp[pistonCells[cellI]];
259 forAll (curCellPoints, i)
261 count[curCellPoints[i]] = true;
267 forAll (count, pointI)
269 if (count[pointI] == true)
275 pistonPoints.setSize(nCounted);
277 // Collect the points
279 forAll (count, pointI)
281 if (count[pointI] == true)
283 pistonPoints[nCounted] = pointI;
288 // Repeat for head points
291 forAll (headCells, cellI)
293 const labelList& curCellPoints = cp[pistonCells[cellI]];
295 forAll (curCellPoints, i)
297 count[curCellPoints[i]] = true;
303 forAll (count, pointI)
305 if (count[pointI] == true)
311 headPoints.setSize(nCounted);
313 // Collect the points
315 forAll (count, pointI)
317 if (count[pointI] == true)
319 headPoints[nCounted] = pointI;
326 label nScaled = nPoints();
328 // label pistonPtsIndex = pointZones().findZoneID("pistonPoints");
329 // const labelList& pistonPoints = pointZones()[pistonPtsIndex];
331 // label headPtsIndex = pointZones().findZoneID("headPoints");
332 // const labelList& headPoints = pointZones()[headPtsIndex];
334 const scalarField& movingPointsM = movingPointsMask();
336 forAll(pistonPoints, i)
338 label pointI = pistonPoints[i];
339 pistonPoint[pointI] = true;
340 point& p = newPoints[pointI];
342 if (p.z() < pistonPosition() - 1.0e-6)
344 scaleDisp[pointI] = false;
349 forAll(headPoints, i)
351 headPoint[headPoints[i]] = true;
352 scaleDisp[headPoints[i]] = false;
356 if (realDeformation())
358 forAll(scaleDisp, pointI)
360 point& p = newPoints[pointI];
362 if (scaleDisp[pointI])
364 p.z() += movingPointsM[pointI]*deltaZ*
365 (deckHeight() - p.z())/(deckHeight() - pistonPosition());
369 if (!headPoint[pointI])
371 p.z() += movingPointsM[pointI]*deltaZ;
378 // Always move piston
379 scalar pistonTopZ = -GREAT;
380 forAll(pistonPoints, i)
382 point& p = newPoints[pistonPoints[i]];
383 p.z() += deltaZ*movingPointsM[pistonPoints[i]];
384 pistonTopZ = max(pistonTopZ, p.z());
388 // NN! fix. only needed for compression
391 // check if piston-points have moved beyond the layer above
396 if (virtualPistonPosition() > newPoints[i].z())
399 (1.0 - movingPointsM[i])*newPoints[i].z()
402 (pistonTopZ + 0.9*minLayerThickness);
411 movePoints(newPoints);
412 deleteDemandDrivenData(movingPointsMaskPtr_);
414 pistonPosition() += deltaZ;
416 //*/ //Tommaso, 23/5/2008
419 // Grab old points to correct the motion
420 pointField oldPointsNew = oldAllPoints();
422 // Attach the interface
423 Info << "Coupling sliding interfaces" << endl;
426 // Changing topology by hand
427 autoPtr<mapPolyMesh> topoChangeMap4 = topoChanger_.changeMesh();
429 if (topoChangeMap4->morphing())
431 if (topoChangeMap4->hasMotionPoints())
433 Info<< "Topology change; executing pre-motion after "
434 << "sliding attach" << endl;
436 // Info<< "topoChangeMap4->preMotionPoints().size() = "
437 // << topoChangeMap4->preMotionPoints().size() << nl
438 // << "allPoints.size() = " << allPoints().size() << nl
439 // << "points.size() = " << points().size() << endl;
441 movePoints(topoChangeMap4->preMotionPoints());
442 newPoints = points();
446 pointField mappedOldPointsNew(allPoints().size());
448 mappedOldPointsNew.map
450 oldPointsNew, topoChangeMap4->pointMap()
453 forAll(scavInPortPatches_, patchi)
455 const labelList& cutPointsAddressing =
458 pointZones().findZoneID
460 "cutPointZone" + Foam::name(patchi + 1)
464 forAll(cutPointsAddressing, i)
466 mappedOldPointsNew[cutPointsAddressing[i]] =
467 newPoints[cutPointsAddressing[i]];
470 forAll(cutPointsAddressing, i)
474 newPoints[cutPointsAddressing[i]].z()
475 > virtualPistonPosition()
478 mappedOldPointsNew[cutPointsAddressing[i]].z() =
479 newPoints[cutPointsAddressing[i]].z();
483 mappedOldPointsNew[cutPointsAddressing[i]].z() =
484 newPoints[cutPointsAddressing[i]].z() - deltaZ;
488 pointField newPoints = allPoints();
490 movePoints(mappedOldPointsNew);
494 movePoints(newPoints);
503 // ************************************************************************* //