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 "simpleEngineTopoFvMesh.H"
27 #include "slidingInterface.H"
28 #include "layerAdditionRemoval.H"
29 #include "attachDetach.H"
30 #include "componentMixedTetPolyPatchVectorField.H"
31 #include "mapPolyMesh.H"
32 #include "polyTopoChange.H"
33 #include "tetMotionSolver.H"
35 #include "addToRunTimeSelectionTable.H"
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 defineTypeNameAndDebug(simpleEngineTopoFvMesh, 0);
43 addToRunTimeSelectionTable
45 engineTopoChangerMesh,
46 simpleEngineTopoFvMesh,
52 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
54 void Foam::simpleEngineTopoFvMesh::makeLayersLive()
57 forAll (topoChanger_, modI)
59 if (isA<layerAdditionRemoval>(topoChanger_[modI]))
63 Info<< "Enabling layer modifier "
64 << topoChanger_[modI].name() << endl;
67 topoChanger_[modI].enable();
69 else if (isA<slidingInterface>(topoChanger_[modI]))
73 Info<< "Disabling slider modifier "
74 << topoChanger_[modI].name() << endl;
77 topoChanger_[modI].disable();
79 else if (isA<attachDetach>(topoChanger_[modI]))
81 topoChanger_[modI].enable();
85 FatalErrorIn("void Foam::simpleEngineTopoFvMesh::makeLayersLive()")
86 << "Don't know what to do with mesh modifier "
87 << modI << " of type " << topoChanger_[modI].type()
94 void Foam::simpleEngineTopoFvMesh::makeSlidersLive()
96 // Enable sliding interface
97 forAll (topoChanger_, modI)
99 if (isA<layerAdditionRemoval>(topoChanger_[modI]))
103 Info<< "Disabling layer modifier "
104 << topoChanger_[modI].name() << endl;
107 topoChanger_[modI].disable();
109 else if (isA<slidingInterface>(topoChanger_[modI]))
113 Info<< "Enabling slider modifier "
114 << topoChanger_[modI].name() << endl;
117 topoChanger_[modI].enable();
119 else if (isA<attachDetach>(topoChanger_[modI]))
121 topoChanger_[modI].enable();
125 FatalErrorIn("void Foam::simpleEngineTopoFvMesh::makeSlidersLive()")
126 << "Don't know what to do with mesh modifier "
127 << modI << " of type " << topoChanger_[modI].type()
128 << abort(FatalError);
134 void Foam::simpleEngineTopoFvMesh::prepareValveDetach()
136 // Enable sliding interface
137 forAll (topoChanger_, modI)
139 if (isA<attachDetach>(topoChanger_[modI]))
141 const attachDetach& ad =
142 refCast<const attachDetach>(topoChanger_[modI]);
144 const word masterName = ad.masterPatchID().name();
146 // Find the valve with that name
147 label valveIndex = -1;
149 forAll (valves_, valveI)
153 valves_[valveI].detachInCylinderPatchID().name()
166 "void Foam::simpleEngineTopoFvMesh::prepareValveDetach()"
167 ) << "Cannot match patch for attach/detach " << modI
168 << abort(FatalError);
173 Info<< " valveI: " << valveIndex << " attached: "
175 << " valve open: " << valves_[valveIndex].isOpen()
179 if (valves_[valveIndex].isOpen())
192 bool Foam::simpleEngineTopoFvMesh::attached() const
196 forAll (topoChanger_, modI)
198 if (isA<slidingInterface>(topoChanger_[modI]))
202 || refCast<const slidingInterface>(topoChanger_[modI]).attached();
206 // Check thal all sliders are in sync (debug only)
207 forAll (topoChanger_, modI)
209 if (isA<slidingInterface>(topoChanger_[modI]))
214 != refCast<const slidingInterface>(topoChanger_[modI]).attached()
217 FatalErrorIn("bool simpleEngineTopoFvMesh::attached() const")
218 << "Slider " << modI << " named "
219 << topoChanger_[modI].name()
220 << " out of sync: Should be" << result
221 << abort(FatalError);
230 Info << "simpleEngineTopoFvMesh is attached" << endl;
234 Info << "simpleEngineTopoFvMesh is detached" << endl;
242 void Foam::simpleEngineTopoFvMesh::setBoundaryMotion()
244 // Set the boundary conditions on motion field in order to solve
245 // for motion. Deformation only happens within the cylinder and
246 // not in ports - the motion of valve top is set to zero. Correct
247 // using setBoundaryPosition()
248 // HJ, 10/Jun/2004 Reconsider
251 Info << "Setting boundary motion" << endl;
254 tetMotionSolver& mSolver =
255 refCast<tetMotionSolver>(msPtr_());
257 tetPointVectorField& motionU = mSolver.motionU();
259 // Set valve velocity
260 forAll (valves_, valveI)
262 // If valve is present in geometry, set the motion
263 if (valves_[valveI].bottomPatchID().active())
266 valves_[valveI].curVelocity()*valves_[valveI].cs().axis();
268 // Bottom of the valve moves with given velocity
269 motionU.boundaryField()[valves_[valveI].bottomPatchID().index()] ==
274 Info<< "Valve " << valveI << " lift: "
275 << valves_[valveI].curLift()
276 << " velocity: " << valves_[valveI].curVelocity()
281 if (valves_[valveI].poppetPatchID().active())
283 // Top of the valve does not move
284 motionU.boundaryField()[valves_[valveI].poppetPatchID().index()] ==
288 if (valves_[valveI].curtainInCylinderPatchID().active())
290 // label cicPatchIndex =
291 // valves_[valveI].curtainInCylinderPatchID().index();
293 // componentMixedTetPolyPatchVectorField& pf =
294 // refCast<componentMixedTetPolyPatchVectorField>
296 // motionU.boundaryField()[cicPatchIndex]
299 // if (valves_[valveI].isOpen())
301 // // Get valve coordinate system
302 // const coordinateSystem& vcs = valves_[valveI].cs();
303 // const scalar r = 0.5*valves_[valveI].diameter();
305 // // Get local points in the patch
306 // const pointField& cpGlobal =
307 // motionU.boundaryField()
308 // [cicPatchIndex].patchMesh().localPoints();
310 // pointField cpLocal(vcs.toLocal(cpGlobal));
311 // scalarField mask =
314 // cpLocal.component(vector::Z)
315 // + valves_[valveI].curLift()
319 // // Calculate motion of valve centre
323 // mask*r + (1.0 - mask)*0.0
328 // mask*(vcs.toGlobal(cpLocal) - cpGlobal)/
329 // engineTime_.deltaT().value()
331 // vector(vcs.axis().x()*valves_[valveI].curVelocity(), 0, 0)
334 // pf.valueFraction() =
335 // mask*vector::one + (1.0 - mask)*vector(1, 0, 0);
339 // pf.refValue() = vector::zero;
340 // pf.valueFraction() = vector::one;
345 // Set piston velocity
346 if (piston().patchID().active())
349 piston().cs().axis()*engineTime_.pistonSpeed().value();
353 Info<< "Piston velocity: " << pistonVel;
356 componentMixedTetPolyPatchVectorField& pp =
357 refCast<componentMixedTetPolyPatchVectorField>
359 motionU.boundaryField()[piston().patchID().index()]
366 Info << " deformation" << endl;
369 pp.refValue() = pistonVel;
375 Info << " layering" << endl;
378 pp.refValue() = vector::zero;
384 void Foam::simpleEngineTopoFvMesh::setBoundaryPosition()
386 // Set the boundary position for layer modifiers
389 Info << "Setting boundary position" << endl;
392 tetMotionSolver& mSolver =
393 refCast<tetMotionSolver>(msPtr_());
395 tetPointVectorField& motionU = mSolver.motionU();
397 // Set valve velocity
398 forAll (valves_, valveI)
401 valves_[valveI].curVelocity()*valves_[valveI].cs().axis();
403 // If valve is present in geometry, set the motion
404 if (valves_[valveI].bottomPatchID().active())
406 // Bottom of the valve moves with given velocity
407 motionU.boundaryField()[valves_[valveI].bottomPatchID().index()] ==
412 Info<< "Valve " << valveI << " lift: "
413 << valves_[valveI].curLift()
414 << " velocity: " << valves_[valveI].curVelocity()
420 if (valves_[valveI].poppetPatchID().active())
422 // Top of the valve does not move
423 motionU.boundaryField()[valves_[valveI].poppetPatchID().index()] ==
428 // Set piston velocity
429 if (piston().patchID().active())
432 piston().cs().axis()*engineTime_.pistonSpeed().value();
434 componentMixedTetPolyPatchVectorField& pp =
435 refCast<componentMixedTetPolyPatchVectorField>
437 motionU.boundaryField()[piston().patchID().index()]
442 Info<< "Piston velocity: " << pistonVel << endl;
445 pp.refValue() = pistonVel;
448 motionU.correctBoundaryConditions();
452 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
454 // Construct from components
455 Foam::simpleEngineTopoFvMesh::simpleEngineTopoFvMesh
460 engineTopoChangerMesh(io),
461 valves_(*this, engineTime_.engineDict().lookup("valves")),
462 piston_(*this, engineTime_.engineDict().subDict("piston")),
463 msPtr_(motionSolver::New(*this)),
464 deformSwitch_(readScalar(engineTime_.engineDict().lookup("deformAngle"))),
465 valvePosTol_(readScalar(engineTime_.engineDict().lookup("valvePosTol")))
467 // Add zones and modifiers if not already there.
468 addZonesAndModifiers();
472 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
475 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
477 bool Foam::simpleEngineTopoFvMesh::update()
479 tetMotionSolver& mSolver =
480 refCast<tetMotionSolver>(msPtr_());
482 // Detaching the interface
487 Info << "Decoupling sliding interfaces" << endl;
492 // Changing topology by hand
493 autoPtr<mapPolyMesh> topoChangeMap1 = topoChanger_.changeMesh();
495 if (topoChangeMap1->morphing())
497 mSolver.updateMesh(topoChangeMap1());
504 Info << "Sliding interfaces decoupled" << endl;
508 // Perform layer action and mesh motion
513 Info << "Executing layer action" << endl;
516 // Find piston mesh modifier
517 const label pistonLayerID =
518 topoChanger_.findModifierID("pistonLayer");
520 if (pistonLayerID < 0)
522 FatalErrorIn("void simpleEngineTopoFvMesh::moveAndMorph()")
523 << "Piston modifier not found."
524 << abort(FatalError);
529 // Dectivate piston layer
532 Info << "Disabling piston layer (deformation)"<< endl;
535 topoChanger_[pistonLayerID].disable();
539 // Activate piston layer
542 Info << "Enabling piston layer (deformation)"<< endl;
545 topoChanger_[pistonLayerID].enable();
548 // Changing topology by hand
550 autoPtr<mapPolyMesh> topoChangeMap2 = topoChanger_.changeMesh();
552 if (topoChangeMap2->morphing())
554 mSolver.updateMesh(topoChangeMap2());
558 Info << "Topology change; executing pre-motion" << endl;
561 movePoints(topoChangeMap2->preMotionPoints());
572 Info << "Mesh deformation mode" << endl;
580 // Dectivate piston layer
583 Info << "Disabling piston layer (topo 2)"<< endl;
586 topoChanger_[pistonLayerID].disable();
592 Info << "Piston layering mode" << endl;
595 bool tiltedValves = true;
605 // Blocking vertical motion
606 mSolver.motionU().internalField().replace(vector::Z, 0);
608 // Activate piston layer
611 Info << "Enabling piston layer (topo 2)"<< endl;
614 topoChanger_[pistonLayerID].enable();
617 // Reset the position of layered interfaces
618 setBoundaryPosition();
620 movePoints(mSolver.curPoints());
622 // Attach the interface
625 Info << "Coupling sliding interfaces" << endl;
629 prepareValveDetach();
631 // Changing topology by hand
633 // Grab old points to correct the motion
634 pointField oldPointsNew = oldAllPoints();
636 autoPtr<mapPolyMesh> topoChangeMap3 = topoChanger_.changeMesh();
640 Info << "Moving points post slider attach" << endl;
643 if (topoChangeMap3->morphing())
645 mSolver.updateMesh(topoChangeMap3());
649 Info << "Moving points post slider attach" << endl;
652 pointField newPoints = allPoints();
653 pointField mappedOldPointsNew(newPoints.size());
655 mappedOldPointsNew.map(oldPointsNew, topoChangeMap3->pointMap());
657 // Solve the correct mesh motion to make sure motion fluxes
658 // are solved for and not mapped
659 movePoints(mappedOldPointsNew);
662 movePoints(newPoints);
668 Info << "Sliding interfaces coupled: " << attached() << endl;
675 // ************************************************************************* //