void Foam::twoStrokeEngine::setBoundaryVelocity(volVectorField& U) { vector pistonVel = piston().cs().axis()*engTime().pistonSpeed().value(); // On the piston movingWallVelocity is used. // There is no need to update the piston velocity forAll (scavInPortPatches_, patchi) { const label curPatchID = boundaryMesh().findPatchID(scavInPortPatches_[patchi]); U.boundaryField()[curPatchID] == pistonVel; } }
bool Foam::pistonSliding::realDeformation() const { bool deformationValve = false; forAll(valves(), valveI) { scalar maxLayer = piston().minLayer(); if(valves()[valveI].bottomPatchID().active()) { maxLayer = max(maxLayer, valves()[valveI].minBottomLayer()); } scalar valveDisplacement = valves_[valveI].curVelocity()*valves_[valveI].cs().axis().z()*engTime().deltaT().value() ; if(valvePistonPosition()[valveI] + engTime().pistonDisplacement().value() > valveBottomPosition_[valveI] + valveDisplacement - 5.0*maxLayer - 0.001 ) { deformationValve = true; } }
void Foam::simpleEngineTopoFvMesh::addZonesAndModifiers() { // Add the zones and mesh modifiers to operate piston and valve motion if ( pointZones().size() > 0 || faceZones().size() > 0 || cellZones().size() > 0 ) { Info<< "void Foam::simpleEngineTopoFvMesh::addZonesAndModifiers() : " << "Zones and modifiers already present. Skipping." << endl; if (topoChanger_.size() == 0) { FatalErrorIn ( "void simpleEngineTopoFvMesh::addZonesAndModifiers()" ) << "Mesh modifiers not read properly" << abort(FatalError); } return; } Info<< "Time = " << engineTime_.theta() << endl << "Adding zones to the engine mesh" << endl; List<pointZone*> pz(nValves()); List<faceZone*> fz(6*nValves() + 1); List<cellZone*> cz(0); label nPointZones = 0; label nFaceZones = 0; for (label valveI = 0; valveI < nValves(); valveI++) { // If both sides of the interface exist, add sliding interface // for a valve if ( valves_[valveI].curtainInCylinderPatchID().active() && valves_[valveI].curtainInPortPatchID().active() ) { Info<< "Adding sliding interface zones for curtain of valve " << valveI + 1 << endl; pz[nPointZones] = new pointZone ( "cutPointsV" + Foam::name(valveI + 1), labelList(0), nPointZones, pointZones() ); nPointZones++; const polyPatch& cylCurtain = boundaryMesh() [valves_[valveI].curtainInCylinderPatchID().index()]; labelList cylCurtainLabels(cylCurtain.size(), cylCurtain.start()); forAll (cylCurtainLabels, i) { cylCurtainLabels[i] += i; } fz[nFaceZones] = new faceZone ( "curtainCylZoneV" + Foam::name(valveI + 1), cylCurtainLabels, boolList(cylCurtainLabels.size(), false), nFaceZones, faceZones() ); nFaceZones++; const polyPatch& portCurtain = boundaryMesh() [valves_[valveI].curtainInPortPatchID().index()]; labelList portCurtainLabels ( portCurtain.size(), portCurtain.start() ); forAll (portCurtainLabels, i) { portCurtainLabels[i] += i; } fz[nFaceZones] = new faceZone ( "curtainPortZoneV" + Foam::name(valveI + 1), portCurtainLabels, boolList(portCurtainLabels.size(), false), nFaceZones, faceZones() ); nFaceZones++; // Add empty zone for cut faces fz[nFaceZones] = new faceZone ( "cutFaceZoneV" + Foam::name(valveI + 1), labelList(0), boolList(0, false), nFaceZones, faceZones() ); nFaceZones++; // Create a detach zone if ( valves_[valveI].detachInCylinderPatchID().active() && valves_[valveI].detachInPortPatchID().active() && valves_[valveI].detachFaces().size() > 0 ) { Info<< "Adding detach boundary for valve " << valveI + 1 << endl; const vectorField& areas = Sf().internalField(); const labelList& df = valves_[valveI].detachFaces(); boolList flip(df.size(), false); const vector& pistonAxis = piston().cs().axis(); forAll (df, dfI) { if (isInternalFace(df[dfI])) { if ((areas[df[dfI]] & pistonAxis) > 0) { flip[dfI] = true; } } else { FatalErrorIn ( "void simpleEngineTopoFvMesh::" "addZonesAndModifiers()" ) << "found boundary face in valve detach definition" << " for valve " << valveI + 1 << ". This is not allowed. Detach faces: " << df << " nInternalFaces: " << nInternalFaces() << abort(FatalError); } } // Add detach face zone fz[nFaceZones] = new faceZone ( "detachFaceZoneV" + Foam::name(valveI + 1), df, flip, nFaceZones, faceZones() ); nFaceZones++; } }
bool Foam::twoStrokeEngine::update() { // Detaching the interface if (attached()) { Info << "Decoupling sliding interfaces" << endl; makeSlidersLive(); // Changing topology by hand autoPtr<mapPolyMesh> topoChangeMap5 = topoChanger_.changeMesh(); if (topoChangeMap5->hasMotionPoints() && topoChangeMap5->morphing()) { Info << "Topology change; executing pre-motion after " << "sliding detach" << endl; movePoints(topoChangeMap5->preMotionPoints()); } Info << "sliding interfaces successfully decoupled!!!" << endl; } else { Info << "Sliding interfaces decoupled" << endl; } Info << "Executing layer action" << endl; // Piston Layering makeLayersLive(); // Changing topology by hand // /* Tommaso, 23/5/2008 // Find piston mesh modifier const label pistonLayerID = topoChanger_.findModifierID("pistonLayer"); if (pistonLayerID < 0) { FatalErrorIn("void engineFvMesh::moveAndMorph()") << "Piston modifier not found." << abort(FatalError); } scalar minLayerThickness = piston().minLayer(); scalar deltaZ = engTime().pistonDisplacement().value(); virtualPistonPosition() += deltaZ; Info << "virtualPistonPosition = " << virtualPistonPosition() << ", deckHeight = " << deckHeight() << ", pistonPosition = " << pistonPosition() << endl; if (realDeformation()) { // Dectivate piston layer Info << "Mesh deformation mode" << endl; topoChanger_[pistonLayerID].disable(); } else { // Activate piston layer Info << "Piston layering mode" << endl; topoChanger_[pistonLayerID].enable(); } // Changing topology by hand autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh(); // Work array for new points position. pointField newPoints = allPoints(); const pointField& refPoints = allPoints(); if (topoChangeMap->morphing()) { if (topoChangeMap->hasMotionPoints()) { Info<< "Topology change; executing pre-motion after " << "dynamic layering" << endl; movePoints(topoChangeMap->preMotionPoints()); newPoints = topoChangeMap->preMotionPoints(); } setV0(); resetMotion(); } // Reset the position of layered interfaces boolList scaleDisp(nPoints(), true); boolList pistonPoint(newPoints.size(), false); boolList headPoint(newPoints.size(), false); // Make a list of piston and head points. HJ, 2/Dec/2009 labelList pistonPoints; labelList headPoints; { label pistonCellIndex = cellZones().findZoneID("pistonCells"); if (pistonCellIndex < 0) { FatalErrorIn("bool twoStrokeEngine::update()") << "Cannot find cell zone pistonCells" << abort(FatalError); } const labelList& pistonCells = cellZones()[pistonCellIndex]; label headCellIndex = cellZones().findZoneID("headCells"); if (headCellIndex < 0) { FatalErrorIn("bool twoStrokeEngine::update()") << "Cannot find cell zone headCells" << abort(FatalError); } const labelList& headCells = cellZones()[headCellIndex]; const labelListList& cp = cellPoints(); boolList count(newPoints.size(), false); forAll (pistonCells, cellI) { const labelList& curCellPoints = cp[pistonCells[cellI]]; forAll (curCellPoints, i) { count[curCellPoints[i]] = true; } } // Count the points label nCounted = 0; forAll (count, pointI) { if (count[pointI] == true) { nCounted++; } } pistonPoints.setSize(nCounted); // Collect the points nCounted = 0; forAll (count, pointI) { if (count[pointI] == true) { pistonPoints[nCounted] = pointI; nCounted++; } } // Repeat for head points count = false; forAll (headCells, cellI) { const labelList& curCellPoints = cp[pistonCells[cellI]]; forAll (curCellPoints, i) { count[curCellPoints[i]] = true; } } // Count the points nCounted = 0; forAll (count, pointI) { if (count[pointI] == true) { nCounted++; } } headPoints.setSize(nCounted); // Collect the points nCounted = 0; forAll (count, pointI) { if (count[pointI] == true) { headPoints[nCounted] = pointI; nCounted++; } } } label nScaled = nPoints(); // label pistonPtsIndex = pointZones().findZoneID("pistonPoints"); // const labelList& pistonPoints = pointZones()[pistonPtsIndex]; // label headPtsIndex = pointZones().findZoneID("headPoints"); // const labelList& headPoints = pointZones()[headPtsIndex]; const scalarField& movingPointsM = movingPointsMask(); forAll(pistonPoints, i) { label pointI = pistonPoints[i]; pistonPoint[pointI] = true; point& p = newPoints[pointI]; if (p.z() < pistonPosition() - 1.0e-6) { scaleDisp[pointI] = false; nScaled--; } }
void Foam::layerAR::addZonesAndModifiers() { // Add the zones and mesh modifiers to operate piston motion if ( pointZones().size() > 0 || faceZones().size() > 0 || cellZones().size() > 0 ) { Info<< "void layerAR::addZonesAndModifiers() : " << "Zones and modifiers already present. Skipping." << endl; if (topoChanger_.size() == 0) { FatalErrorIn ( "void layerAR::addZonesAndModifiers()" ) << "Mesh modifiers not read properly" << abort(FatalError); } setVirtualPistonPosition(); checkAndCalculate(); return; } checkAndCalculate(); Info<< "Time = " << engTime().theta() << endl << "Adding zones to the engine mesh" << endl; //fz = 1: faces where layer are added/removed //pz = 2: points below the virtual piston faces and head points List<pointZone*> pz(2); List<faceZone*> fz(1); List<cellZone*> cz(0); label nPointZones = 0; label nFaceZones = 0; // Add the piston zone if (piston().patchID().active() && offSet() > SMALL) { // Piston position label pistonPatchID = piston().patchID().index(); scalar zPist = max(boundary()[pistonPatchID].patch().localPoints()).z(); scalar zPistV = zPist + offSet(); labelList zone1(faceCentres().size()); boolList flipZone1(faceCentres().size(), false); label nZoneFaces1 = 0; bool foundAtLeastOne = false; scalar zHigher = GREAT; scalar dh = GREAT; scalar dl = GREAT; forAll (faceCentres(), faceI) { scalar zc = faceCentres()[faceI].z(); vector n = faceAreas()[faceI]/mag(faceAreas()[faceI]); scalar dd = n & vector(0,0,1); if (dd > 0.1) { if (zPistV - zc > 0 && zPistV - zc < dl) { dl = zPistV - zc; } if (zc - zPistV > 0 && zc - zPistV < dh) { zHigher = zc; dh = zc - zHigher; } if ( zc > zPistV - delta() && zc < zPistV + delta() ) { foundAtLeastOne = true; if ((faceAreas()[faceI] & vector(0,0,1)) < 0) { flipZone1[nZoneFaces1] = true; } zone1[nZoneFaces1] = faceI; nZoneFaces1++; } } }
void Foam::simpleTwoStroke::addZonesAndModifiers() { // Add the zones and mesh modifiers to operate piston motion if ( pointZones().size() > 0 || faceZones().size() > 0 || cellZones().size() > 0 ) { Info<< "Time = " << engTime().theta() << endl; Info<< "void simpleTwoStroke::addZonesAndModifiers() : " << "Zones and modifiers already present. Skipping." << endl; if (topoChanger_.size() == 0) { FatalErrorIn ( "void simpleTwoStroke::addZonesAndModifiers()" ) << "Mesh modifiers not read properly" << abort(FatalError); } setVirtualPistonPosition(); checkAndCalculate(); return; } Info << "checkAndCalculate()" << endl; checkAndCalculate(); Info<< "Time = " << engTime().theta() << endl << "Adding zones to the engine mesh" << endl; //fz = 4: virtual piston, outSidePort, insidePort, cutFaceZone //pz = 2: piston points, cutPointZone //cz = 1: moving mask List<pointZone*> pz(3); List<faceZone*> fz(4); List<cellZone*> cz(1); label nPointZones = 0; label nFaceZones = 0; label nCellZones = 0; // Add the piston zone if (piston().patchID().active()) { // Piston position Info << "Adding face zone for piston layer addition/removal" << endl; label pistonPatchID = piston().patchID().index(); scalar zPist = max(boundary()[pistonPatchID].patch().localPoints()).z(); scalar zPistV = zPist + offSet(); labelList zone1(faceCentres().size()); boolList flipZone1(faceCentres().size(), false); label nZoneFaces1 = 0; bool foundAtLeastOne = false; scalar zHigher = GREAT; scalar dh = GREAT; scalar dl = GREAT; forAll (faceCentres(), faceI) { // The points have to be in the cylinder and not in the ports.... scalar zc = faceCentres()[faceI].z(); scalar xc = faceCentres()[faceI].x(); scalar yc = faceCentres()[faceI].y(); vector n = faceAreas()[faceI]/mag(faceAreas()[faceI]); scalar dd = n & vector(0,0,1); if(sqrt(sqr(xc)+sqr(yc)) < 0.5 * engTime().bore().value()) { if (dd > 0.1) { if (zPistV - zc > 0 && zPistV - zc < dl) { dl = zPistV - zc; } if (zc - zPistV > 0 && zc - zPistV < dh) { zHigher = zc; dh = zc - zHigher; } if ( zc > zPistV - delta() && zc < zPistV + delta() ) { foundAtLeastOne = true; if ((faceAreas()[faceI] & vector(0,0,1)) < 0) { flipZone1[nZoneFaces1] = true; } zone1[nZoneFaces1] = faceI; nZoneFaces1++; } } } }
main() { int i, itest, dobackface, dofill, dodouble; char buf[100]; float H; short idata; int xr, yr; vinit("mswin"); winopen("piston"); /* * Wait for REDRAW event ... */ while (qread(&idata) != REDRAW) ; doublebuffer(); gconfig(); unqdevice(INPUTCHANGE); qdevice(QKEY); qdevice(FKEY); qdevice(BKEY); qdevice(ESCKEY); qdevice(REDRAW); makecyl(); polymode(PYM_FILL); backface(1); /* * set up a perspective projection with a field of view of * 40.0 degrees, aspect ratio of 1.0, near clipping plane 0.1, * and the far clipping plane at 1000.0. */ perspective(400, 1.5, 0.1, 600.0); lookat(0.0, -6.0, 4., 0.0, 0.0, 0.0, 0); /* * here we loop back here adnaseum until someone hits a key */ xr = yr = 0; while(1) { for (i = 0; i < 360; i += 5) { color(BLACK); clear(); color(RED); H = 1.0 + cos(2.0 * 3.14159265*i / 180.0); yr = 500 - (int)getvaluator(MOUSEY); xr = 500 - (int)getvaluator(MOUSEX); yr = 500 - (int)getvaluator(MOUSEY); xr *= 3; yr *= 3; pushmatrix(); rotate(xr, 'x'); rotate(yr, 'y'); piston(H); popmatrix(); if (dodouble) swapbuffers(); if (qtest()) { itest = qread(&idata); itest = qread(&idata); /* Zap Up event */ if (itest == BKEY) { dobackface = !dobackface; backface(dobackface); } else if (itest == FKEY) { dofill = !dofill; if (dofill) polymode(PYM_FILL); else polymode(PYM_LINE); } else if(itest == QKEY || itest == ESCKEY) { gexit(); exit(0); } } } } }
void Foam::accordionEngineMesh::checkAndCalculate() { label pistonIndex = -1; bool foundPiston = false; label linerIndex = -1; bool foundLiner = false; label cylinderHeadIndex = -1; bool foundCylinderHead = false; forAll(boundary(), i) { if (boundary()[i].name() == piston().patchID().name()) { pistonIndex = i; foundPiston = true; } else if (boundary()[i].name() == linerName_) { linerIndex = i; foundLiner = true; } // else if (boundary()[i].name() == "cylinderHead") else if (boundary()[i].name() == cylinderHeadName_) { cylinderHeadIndex = i; foundCylinderHead = true; } } reduce(foundPiston, orOp<bool>()); reduce(foundLiner, orOp<bool>()); reduce(foundCylinderHead, orOp<bool>()); if (!foundPiston) { FatalErrorIn("Foam::accordionEngineMesh::checkAndCalculate()") << " : cannot find piston patch" << abort(FatalError); } if (!foundLiner) { FatalErrorIn("Foam::accordionEngineMesh::checkAndCalculate()") << " : cannot find liner patch" << abort(FatalError); } if (!foundCylinderHead) { FatalErrorIn("Foam::accordionEngineMesh::checkAndCalculate()") << " : cannot find cylinderHead patch" << exit(FatalError); } { if (linerIndex != -1) { pistonPosition() = max(boundary()[pistonIndex].patch().localPoints()).z(); } reduce(pistonPosition(), minOp<scalar>()); if (cylinderHeadIndex != -1) { deckHeight() = min ( boundary()[cylinderHeadIndex].patch().localPoints() ).z(); /* deckHeight() = max ( boundary()[linerIndex].patch().localPoints() ).z(); */ } reduce(deckHeight(), minOp<scalar>()); Info<< "deckHeight: " << deckHeight() << nl << "piston position: " << pistonPosition() << endl; } }