diff --git a/applications/solvers/discreteMethods/dsmc/dsmcFoam/dsmcFoam.C b/applications/solvers/discreteMethods/dsmc/dsmcFoam/dsmcFoam.C index 1ea52cc6aa..cb068960e8 100644 --- a/applications/solvers/discreteMethods/dsmc/dsmcFoam/dsmcFoam.C +++ b/applications/solvers/discreteMethods/dsmc/dsmcFoam/dsmcFoam.C @@ -91,7 +91,7 @@ int main(int argc, char *argv[]) runTime.write(); - Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" + Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s" << " ClockTime = " << runTime.elapsedClockTime() << " s" << nl << endl; } diff --git a/applications/utilities/postProcessing/sampling/sample/sample.C b/applications/utilities/postProcessing/sampling/sample/sample.C index 2451522ffe..12864fdceb 100644 --- a/applications/utilities/postProcessing/sampling/sample/sample.C +++ b/applications/utilities/postProcessing/sampling/sample/sample.C @@ -97,10 +97,11 @@ using namespace Foam; int main(int argc, char *argv[]) { timeSelector::addOptions(); +# include "addRegionOption.H" # include "setRootCase.H" # include "createTime.H" instantList timeDirs = timeSelector::select0(runTime, args); -# include "createMesh.H" +# include "createNamedMesh.H" IOsampledSets sSets ( diff --git a/applications/utilities/postProcessing/sampling/sample/sampleDict b/applications/utilities/postProcessing/sampling/sample/sampleDict index 559eb28436..4284b2878c 100644 --- a/applications/utilities/postProcessing/sampling/sample/sampleDict +++ b/applications/utilities/postProcessing/sampling/sample/sampleDict @@ -105,6 +105,14 @@ sets end (2 0.51 0.005); nPoints 10; } + + somePoints + { + type cloud; + axis xyz; + points ((0.049 0.049 0.005)(0.051 0.049 0.005)); + } + ); diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C index ee6cea3e12..01ab952c16 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C @@ -2804,6 +2804,22 @@ void Foam::autoLayerDriver::addLayers << "Layer addition iteration " << iteration << nl << "--------------------------" << endl; + + // Unset the extrusion at the pp. + const dictionary& meshQualityDict = + ( + iteration < layerParams.nRelaxedIter() + ? motionDict + : motionDict.subDict("relaxed") + ); + + if (iteration >= layerParams.nRelaxedIter()) + { + Info<< "Switched to relaxed meshQuality constraints." << endl; + } + + + // Make sure displacement is equal on both sides of coupled patches. syncPatchDisplacement ( @@ -2845,6 +2861,7 @@ void Foam::autoLayerDriver::addLayers shrinkMeshMedialDistance ( meshMover, + meshQualityDict, layerParams.nSmoothThickness(), layerParams.maxThicknessToMedialRatio(), @@ -3044,19 +3061,6 @@ void Foam::autoLayerDriver::addLayers layerFacesSet.write(); } - // Unset the extrusion at the pp. - const dictionary& meshQualityDict = - ( - iteration < layerParams.nRelaxedIter() - ? motionDict - : motionDict.subDict("relaxed") - ); - - if (iteration >= layerParams.nRelaxedIter()) - { - Info<< "Switched to relaxed meshQuality constraints." << endl; - } - label nTotChanged = checkAndUnmark ( diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H index 6cdec2004b..164fd88ce0 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H @@ -473,6 +473,7 @@ class autoLayerDriver void shrinkMeshMedialDistance ( motionSmoother& meshMover, + const dictionary& meshQualityDict, const label nSmoothThickness, const scalar maxThicknessToMedialRatio, const label nAllowableErrors, diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C index 615978a308..cc88231b74 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C @@ -792,7 +792,7 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo wallInfo, pointWallDist, edgeWallDist, - mesh.nPoints() // max iterations + mesh.globalData().nTotalPoints() // max iterations ); } @@ -897,7 +897,7 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo pointMedialDist, edgeMedialDist, - mesh.nPoints() // max iterations + mesh.globalData().nTotalPoints() // max iterations ); // Extract medial axis distance as pointScalarField @@ -953,6 +953,7 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo void Foam::autoLayerDriver::shrinkMeshMedialDistance ( motionSmoother& meshMover, + const dictionary& meshQualityDict, const label nSmoothThickness, const scalar maxThicknessToMedialRatio, const label nAllowableErrors, @@ -1103,7 +1104,7 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance wallInfo, pointWallDist, edgeWallDist, - mesh.nPoints() // max iterations + mesh.globalData().nTotalPoints() // max iterations ); } @@ -1138,7 +1139,18 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance oldErrorReduction = meshMover.setErrorReduction(0.0); } - if (meshMover.scaleMesh(checkFaces, true, nAllowableErrors)) + if + ( + meshMover.scaleMesh + ( + checkFaces, + List(0), + meshMover.paramDict(), + meshQualityDict, + true, + nAllowableErrors + ) + ) { Info<< "shrinkMeshMedialDistance : Successfully moved mesh" << endl; break; diff --git a/src/dynamicMesh/motionSmoother/motionSmoother.C b/src/dynamicMesh/motionSmoother/motionSmoother.C index 4f40827f4b..d780ec79dd 100644 --- a/src/dynamicMesh/motionSmoother/motionSmoother.C +++ b/src/dynamicMesh/motionSmoother/motionSmoother.C @@ -502,6 +502,12 @@ const Foam::labelList& Foam::motionSmoother::adaptPatchIDs() const } +const Foam::dictionary& Foam::motionSmoother::paramDict() const +{ + return paramDict_; +} + + Foam::pointVectorField& Foam::motionSmoother::displacement() { return displacement_; diff --git a/src/dynamicMesh/motionSmoother/motionSmoother.H b/src/dynamicMesh/motionSmoother/motionSmoother.H index e4aeac6f50..3d853e476d 100644 --- a/src/dynamicMesh/motionSmoother/motionSmoother.H +++ b/src/dynamicMesh/motionSmoother/motionSmoother.H @@ -327,6 +327,8 @@ public: //- Patch labels that are being adapted const labelList& adaptPatchIDs() const; + const dictionary& paramDict() const; + //- Reference to displacement field pointVectorField& displacement(); diff --git a/src/finiteVolume/interpolation/volPointInterpolation/pointPatchInterpolation/pointPatchInterpolation.C b/src/finiteVolume/interpolation/volPointInterpolation/pointPatchInterpolation/pointPatchInterpolation.C index f9ebc6b8ce..16cd028f72 100644 --- a/src/finiteVolume/interpolation/volPointInterpolation/pointPatchInterpolation/pointPatchInterpolation.C +++ b/src/finiteVolume/interpolation/volPointInterpolation/pointPatchInterpolation/pointPatchInterpolation.C @@ -213,13 +213,12 @@ void pointPatchInterpolation::makePatchPatchWeights() if (!isA(bm[patchi]) && !bm[patchi].coupled()) { - pw[nFacesAroundPoint] = - 1.0/mag - ( - pointLoc - - centres.boundaryField()[patchi] - [bm[patchi].patch().whichFace(curFaces[facei])] - ); + vector d = + pointLoc + - centres.boundaryField()[patchi] + [bm[patchi].patch().whichFace(curFaces[facei])]; + + pw[nFacesAroundPoint] = 1.0/(mag(d)+VSMALL); nFacesAroundPoint++; } diff --git a/src/lagrangian/basic/Particle/Particle.C b/src/lagrangian/basic/Particle/Particle.C index ec1d09a00f..6c8cbe4aa1 100644 --- a/src/lagrangian/basic/Particle/Particle.C +++ b/src/lagrangian/basic/Particle/Particle.C @@ -390,7 +390,7 @@ Foam::scalar Foam::Particle::trackToFace // slightly towards the cell-centre. if (trackFraction < SMALL) { - position_ += 1.0e-6*(mesh.cellCentres()[celli_] - position_); + position_ += 1.0e-3*(mesh.cellCentres()[celli_] - position_); } return trackFraction; diff --git a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C index 4c4bcd0a43..53177e9afe 100644 --- a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C +++ b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C @@ -37,6 +37,7 @@ Foam::scalar Foam::DsmcCloud::kb = 1.380650277e-23; template Foam::scalar Foam::DsmcCloud::Tref = 273; + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template @@ -113,87 +114,161 @@ void Foam::DsmcCloud::initialise numberDensities /= nParticle_; - scalar x0 = mesh_.bounds().min().x(); - scalar xR = mesh_.bounds().max().x() - x0; - - scalar y0 = mesh_.bounds().min().y(); - scalar yR = mesh_.bounds().max().y() - y0; - - scalar z0 = mesh_.bounds().min().z(); - scalar zR = mesh_.bounds().max().z() - z0; - - forAll(molecules, i) + forAll(mesh_.cells(), cell) { - const word& moleculeName(molecules[i]); + const vector& cC = mesh_.cellCentres()[cell]; + const labelList& cellFaces = mesh_.cells()[cell]; + const scalar cV = mesh_.cellVolumes()[cell]; - label typeId(findIndex(typeIdList_, moleculeName)); + label nTets = 0; - if (typeId == -1) + // Each face is split into nEdges (or nVertices) - 2 tets. + forAll(cellFaces, face) { - FatalErrorIn("Foam::DsmcCloud::initialise") - << "typeId " << moleculeName << "not defined." << nl - << abort(FatalError); + nTets += mesh_.faces()[cellFaces[face]].size() - 2; } - const typename ParcelType::constantProperties& cP = constProps(typeId); + // Calculate the cumulative tet volumes circulating around the cell and + // record the vertex labels of each. + scalarList cTetVFracs(nTets, 0.0); - scalar numberDensity = numberDensities[i]; + List tetPtIs(nTets, labelList(3,-1)); - scalar spacing = pow(numberDensity,-(1.0/3.0)); + // Keep track of which tet this is. + label tet = 0; - int ni = label(xR/spacing) + 1; - int nj = label(yR/spacing) + 1; - int nk = label(zR/spacing) + 1; - - vector delta(xR/ni, yR/nj, zR/nk); - - scalar pert = spacing; - - for (int i = 0; i < ni; i++) + forAll(cellFaces, face) { - for (int j = 0; j < nj; j++) + const labelList& facePoints = mesh_.faces()[cellFaces[face]]; + + label pointI = 1; + while ((pointI + 1) < facePoints.size()) { - for (int k = 0; k < nk; k++) + + const vector& pA = mesh_.points()[facePoints[0]]; + const vector& pB = mesh_.points()[facePoints[pointI]]; + const vector& pC = mesh_.points()[facePoints[pointI + 1]]; + + cTetVFracs[tet] = + mag(((pA - cC) ^ (pB - cC)) & (pC - cC))/(cV*6.0) + + cTetVFracs[max((tet - 1),0)]; + + tetPtIs[tet][0] = facePoints[0]; + tetPtIs[tet][1] = facePoints[pointI]; + tetPtIs[tet][2] = facePoints[pointI + 1]; + + pointI++; + tet++; + } + } + + // Force the last volume fraction value to 1.0 to avoid any + // rounding/non-flat face errors giving a value < 1.0 + cTetVFracs[nTets - 1] = 1.0; + + forAll(molecules, i) + { + const word& moleculeName(molecules[i]); + + label typeId(findIndex(typeIdList_, moleculeName)); + + if (typeId == -1) + { + FatalErrorIn("Foam::DsmcCloud::initialise") + << "typeId " << moleculeName << "not defined." << nl + << abort(FatalError); + } + + const typename ParcelType::constantProperties& cP = + constProps(typeId); + + scalar numberDensity = numberDensities[i]; + + // Calculate the number of particles required + scalar particlesRequired = numberDensity*mesh_.cellVolumes()[cell]; + + // Only integer numbers of particles can be inserted + label nParticlesToInsert = label(particlesRequired); + + // Add another particle with a probability proportional to the + // remainder of taking the integer part of particlesRequired + if ((particlesRequired - nParticlesToInsert) > rndGen_.scalar01()) + { + nParticlesToInsert++; + } + + for (label pI = 0; pI < nParticlesToInsert; pI++) + { + // Choose a random point in a generic tetrahedron + + scalar s = rndGen_.scalar01(); + scalar t = rndGen_.scalar01(); + scalar u = rndGen_.scalar01(); + + if (s + t > 1.0) { - point p - ( - x0 + (i + 0.5)*delta.x(), - y0 + (j + 0.5)*delta.y(), - z0 + (k + 0.5)*delta.z() - ); + s = 1.0 - s; + t = 1.0 - t; + } - p.x() += pert*(rndGen_.scalar01() - 0.5); - p.y() += pert*(rndGen_.scalar01() - 0.5); - p.z() += pert*(rndGen_.scalar01() - 0.5); + if (t + u > 1.0) + { + scalar tmp = u; + u = 1.0 - s - t; + t = 1.0 - tmp; + } + else if (s + t + u > 1.0) + { + scalar tmp = u; + u = s + t + u - 1.0; + s = 1.0 - t - tmp; + } - label cell = mesh_.findCell(p); + // Choose a tetrahedron to insert in, based on their relative + // volumes + scalar tetSelection = rndGen_.scalar01(); - vector U = equipartitionLinearVelocity - ( - temperature, - cP.mass() - ); + // Selected tetrahedron + label sTet = -1; - scalar Ei = equipartitionInternalEnergy - ( - temperature, - cP.internalDegreesOfFreedom() - ); + forAll(cTetVFracs, tet) + { + sTet = tet; - U += velocity; - - if (cell >= 0) + if (cTetVFracs[tet] >= tetSelection) { - addNewParcel - ( - p, - U, - Ei, - cell, - typeId - ); + break; } } + + vector p = + (1 - s - t - u)*cC + + s*mesh_.points()[tetPtIs[sTet][0]] + + t*mesh_.points()[tetPtIs[sTet][1]] + + u*mesh_.points()[tetPtIs[sTet][2]]; + + vector U = equipartitionLinearVelocity + ( + temperature, + cP.mass() + ); + + scalar Ei = equipartitionInternalEnergy + ( + temperature, + cP.internalDegreesOfFreedom() + ); + + U += velocity; + + addNewParcel + ( + p, + U, + Ei, + cell, + typeId + ); } } } @@ -276,7 +351,7 @@ void Foam::DsmcCloud::collisions() scalar selectedPairs = collisionSelectionRemainder_[celli] - + 0.5*nC*(nC-1)*nParticle_*sigmaTcRMax*deltaT + + 0.5*nC*(nC - 1)*nParticle_*sigmaTcRMax*deltaT /mesh_.cellVolumes()[celli]; label nCandidates(selectedPairs); @@ -551,6 +626,13 @@ Foam::DsmcCloud::DsmcCloud buildConstProps(); buildCellOccupancy(); + + // Initialise the collision selection remainder to a random value between 0 + // and 1. + forAll(collisionSelectionRemainder_, i) + { + collisionSelectionRemainder_[i] = rndGen_.scalar01(); + } } @@ -739,22 +821,27 @@ void Foam::DsmcCloud::info() const Info<< "Cloud name: " << this->name() << nl << " Number of dsmc particles = " - << nDsmcParticles << nl - << " Number of molecules = " - << nMol << nl - << " Mass in system = " - << returnReduce(massInSystem(), sumOp()) << nl - << " Average linear momentum = " - << linearMomentum/nMol << nl - << " |Average linear momentum| = " - << mag(linearMomentum)/nMol << nl - << " Average linear kinetic energy = " - << linearKineticEnergy/nMol << nl - << " Average internal energy = " - << internalEnergy/nMol << nl - << " Average total energy = " - << (internalEnergy + linearKineticEnergy)/nMol << nl + << nDsmcParticles << endl; + + if (nDsmcParticles) + { + Info<< " Number of molecules = " + << nMol << nl + << " Mass in system = " + << returnReduce(massInSystem(), sumOp()) << nl + << " Average linear momentum = " + << linearMomentum/nMol << nl + << " |Average linear momentum| = " + << mag(linearMomentum)/nMol << nl + << " Average linear kinetic energy = " + << linearKineticEnergy/nMol << nl + << " Average internal energy = " + << internalEnergy/nMol << nl + << " Average total energy = " + << (internalEnergy + linearKineticEnergy)/nMol + << endl; + } } @@ -785,7 +872,11 @@ Foam::scalar Foam::DsmcCloud::equipartitionInternalEnergy { scalar Ei = 0.0; - if (iDof < 2.0 + SMALL && iDof > 2.0 - SMALL) + if (iDof < SMALL) + { + return Ei; + } + else if (iDof < 2.0 + SMALL && iDof > 2.0 - SMALL) { // Special case for iDof = 2, i.e. diatomics; Ei = -log(rndGen_.scalar01())*kb*temperature; @@ -796,7 +887,7 @@ Foam::scalar Foam::DsmcCloud::equipartitionInternalEnergy scalar energyRatio; - scalar P; + scalar P = -1; do { diff --git a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.H b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.H index b246b04990..20bed1ee7b 100644 --- a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.H +++ b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.H @@ -299,6 +299,12 @@ public: scalar mass ) const; + inline scalarField maxwellianAverageSpeed + ( + scalarField temperature, + scalar mass + ) const; + //- RMS particle speed inline scalar maxwellianRMSSpeed ( @@ -306,6 +312,12 @@ public: scalar mass ) const; + inline scalarField maxwellianRMSSpeed + ( + scalarField temperature, + scalar mass + ) const; + //- Most probable speed inline scalar maxwellianMostProbableSpeed ( @@ -313,6 +325,11 @@ public: scalar mass ) const; + inline scalarField maxwellianMostProbableSpeed + ( + scalarField temperature, + scalar mass + ) const; // Sub-models diff --git a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H index 73899636e8..d39de4954f 100644 --- a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H +++ b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H @@ -302,6 +302,17 @@ inline Foam::scalar Foam::DsmcCloud::maxwellianAverageSpeed } +template +inline Foam::scalarField Foam::DsmcCloud::maxwellianAverageSpeed +( + scalarField temperature, + scalar mass +) const +{ + return 2.0*sqrt(2.0*kb*temperature/(mathematicalConstant::pi*mass)); +} + + template inline Foam::scalar Foam::DsmcCloud::maxwellianRMSSpeed ( @@ -313,6 +324,17 @@ inline Foam::scalar Foam::DsmcCloud::maxwellianRMSSpeed } +template +inline Foam::scalarField Foam::DsmcCloud::maxwellianRMSSpeed +( + scalarField temperature, + scalar mass +) const +{ + return sqrt(3.0*kb*temperature/mass); +} + + template inline Foam::scalar Foam::DsmcCloud::maxwellianMostProbableSpeed @@ -325,6 +347,18 @@ Foam::DsmcCloud::maxwellianMostProbableSpeed } +template +inline Foam::scalarField +Foam::DsmcCloud::maxwellianMostProbableSpeed +( + scalarField temperature, + scalar mass +) const +{ + return sqrt(2.0*kb*temperature/mass); +} + + template inline const Foam::tmp Foam::DsmcCloud::rhoN() const @@ -343,7 +377,7 @@ Foam::DsmcCloud::rhoN() const false ), mesh_, - dimensionedScalar("zero", dimensionSet(0, -3, 0, 0, 0), 0.0) + dimensionedScalar("zero", dimensionSet(0, -3, 0, 0, 0), VSMALL) ) ); @@ -380,7 +414,7 @@ Foam::DsmcCloud::rhoM() const false ), mesh_, - dimensionedScalar("zero", dimensionSet(1, -3, 0, 0, 0), 0.0) + dimensionedScalar("zero", dimensionSet(1, -3, 0, 0, 0), VSMALL) ) ); @@ -568,7 +602,7 @@ Foam::DsmcCloud::iDof() const false ), mesh_, - dimensionedScalar("zero", dimensionSet(0, -3, 0, 0, 0), 0.0) + dimensionedScalar("zero", dimensionSet(0, -3, 0, 0, 0), VSMALL) ) ); diff --git a/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C b/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C index f4203f4d66..9d791a1ed3 100644 --- a/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C +++ b/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C @@ -36,32 +36,27 @@ Foam::FreeStream::FreeStream ) : InflowBoundaryModel(dict, cloud, typeName), - patchIndex_(), - temperature_(readScalar(this->coeffDict().lookup("temperature"))), - velocity_(this->coeffDict().lookup("velocity")), + patches_(), moleculeTypeIds_(), numberDensities_(), particleFluxAccumulators_() { - word patchName = this->coeffDict().lookup("patch"); + // Identify which patches to use - patchIndex_ = cloud.mesh().boundaryMesh().findPatchID(patchName); + DynamicList