diff --git a/applications/solvers/discreteMethods/dsmc/dsmcFoam/dsmcFoam.C b/applications/solvers/discreteMethods/dsmc/dsmcFoam/dsmcFoam.C
index 1ea52cc6aae883bd4f5fa85e93b0294ca799d638..cb068960e8e459dc3c3fc7db1d45e458f649c552 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 2451522ffe5d2a9f08e72e3fe882eebaade5bb82..12864fdceb7daf69c129b1e4b9eba68d04f46005 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 559eb2843678da0a0ea06eec30c154c6a82957b7..4284b2878c3ae308b563648976ce56fb28eed41c 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/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C
index 0c3bf4340838d01e7dbbf264a9fb6fdb948ed6ce..d85e393fd8d430687f8c0d1eaaabac5d5c586ab6 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C
@@ -296,6 +296,16 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
 
     this->operator==(newValues);
 
+    if (debug)
+    {
+        Info<< "directMapped on field:" << fldName
+            << " patch:" << this->patch().name()
+            << "  avg:" << gAverage(*this)
+            << "  min:" << gMin(*this)
+            << "  max:" << gMax(*this)
+            << endl;
+    }
+
     fixedValueFvPatchField<Type>::updateCoeffs();
 }
 
diff --git a/src/lagrangian/basic/Particle/Particle.C b/src/lagrangian/basic/Particle/Particle.C
index ec1d09a00f94244a5183af5a09fe41aae70f216c..6c8cbe4aa106f7181d0f93a84a8e6c5c5cd2996c 100644
--- a/src/lagrangian/basic/Particle/Particle.C
+++ b/src/lagrangian/basic/Particle/Particle.C
@@ -390,7 +390,7 @@ Foam::scalar Foam::Particle<ParticleType>::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 4c4bcd0a43dc965a3bd1daae9b06801b0d359c77..53177e9afebcc5a263917230543768ee48c5ebe1 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<ParcelType>::kb = 1.380650277e-23;
 template<class ParcelType>
 Foam::scalar Foam::DsmcCloud<ParcelType>::Tref = 273;
 
+
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class ParcelType>
@@ -113,87 +114,161 @@ void Foam::DsmcCloud<ParcelType>::initialise
 
     numberDensities /= nParticle_;
 
-    scalar x0 = mesh_.bounds().min().x();
-    scalar xR = mesh_.bounds().max().x() - x0;
+    forAll(mesh_.cells(), cell)
+    {
+        const vector& cC = mesh_.cellCentres()[cell];
+        const labelList& cellFaces = mesh_.cells()[cell];
+        const scalar cV = mesh_.cellVolumes()[cell];
+
+        label nTets = 0;
 
-    scalar y0 = mesh_.bounds().min().y();
-    scalar yR = mesh_.bounds().max().y() - y0;
+        // Each face is split into nEdges (or nVertices) - 2 tets.
+        forAll(cellFaces, face)
+        {
+            nTets += mesh_.faces()[cellFaces[face]].size() - 2;
+        }
 
-    scalar z0 = mesh_.bounds().min().z();
-    scalar zR = mesh_.bounds().max().z() - z0;
+        // Calculate the cumulative tet volumes circulating around the cell and
+        // record the vertex labels of each.
+        scalarList cTetVFracs(nTets, 0.0);
 
-    forAll(molecules, i)
-    {
-        const word& moleculeName(molecules[i]);
+        List<labelList> tetPtIs(nTets, labelList(3,-1));
 
-        label typeId(findIndex(typeIdList_, moleculeName));
+        // Keep track of which tet this is.
+        label tet = 0;
 
-        if (typeId == -1)
+        forAll(cellFaces, face)
         {
-            FatalErrorIn("Foam::DsmcCloud<ParcelType>::initialise")
-                << "typeId " << moleculeName << "not defined." << nl
-                << abort(FatalError);
-        }
+            const labelList& facePoints = mesh_.faces()[cellFaces[face]];
 
-        const typename ParcelType::constantProperties& cP = constProps(typeId);
+            label pointI = 1;
+            while ((pointI + 1) < facePoints.size())
+            {
 
-        scalar numberDensity = numberDensities[i];
+                const vector& pA = mesh_.points()[facePoints[0]];
+                const vector& pB = mesh_.points()[facePoints[pointI]];
+                const vector& pC = mesh_.points()[facePoints[pointI + 1]];
 
-        scalar spacing = pow(numberDensity,-(1.0/3.0));
+                cTetVFracs[tet] =
+                    mag(((pA - cC) ^ (pB - cC)) & (pC - cC))/(cV*6.0)
+                  + cTetVFracs[max((tet - 1),0)];
 
-        int ni = label(xR/spacing) + 1;
-        int nj = label(yR/spacing) + 1;
-        int nk = label(zR/spacing) + 1;
+                tetPtIs[tet][0] = facePoints[0];
+                tetPtIs[tet][1] = facePoints[pointI];
+                tetPtIs[tet][2] = facePoints[pointI + 1];
 
-        vector delta(xR/ni, yR/nj, zR/nk);
+                pointI++;
+                tet++;
+            }
+        }
 
-        scalar pert = spacing;
+        // 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;
 
-        for (int i = 0; i < ni; i++)
+        forAll(molecules, i)
         {
-            for (int j = 0; j < nj; j++)
+            const word& moleculeName(molecules[i]);
+
+            label typeId(findIndex(typeIdList_, moleculeName));
+
+            if (typeId == -1)
             {
-                for (int k = 0; k < nk; k++)
-                {
-                    point p
-                    (
-                        x0 + (i + 0.5)*delta.x(),
-                        y0 + (j + 0.5)*delta.y(),
-                        z0 + (k + 0.5)*delta.z()
-                    );
+                FatalErrorIn("Foam::DsmcCloud<ParcelType>::initialise")
+                << "typeId " << moleculeName << "not defined." << nl
+                    << abort(FatalError);
+            }
 
-                    p.x() += pert*(rndGen_.scalar01() - 0.5);
-                    p.y() += pert*(rndGen_.scalar01() - 0.5);
-                    p.z() += pert*(rndGen_.scalar01() - 0.5);
+            const typename ParcelType::constantProperties& cP =
+                constProps(typeId);
 
-                    label cell = mesh_.findCell(p);
+            scalar numberDensity = numberDensities[i];
 
-                    vector U = equipartitionLinearVelocity
-                    (
-                        temperature,
-                        cP.mass()
-                    );
+            // Calculate the number of particles required
+            scalar particlesRequired = numberDensity*mesh_.cellVolumes()[cell];
 
-                    scalar Ei = equipartitionInternalEnergy
-                    (
-                        temperature,
-                        cP.internalDegreesOfFreedom()
-                    );
+            // 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)
+                {
+                    s = 1.0 - s;
+                    t = 1.0 - t;
+                }
+
+                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;
+                }
+
+                // Choose a tetrahedron to insert in, based on their relative
+                // volumes
+                scalar tetSelection = rndGen_.scalar01();
 
-                    U += velocity;
+                // Selected tetrahedron
+                label sTet = -1;
 
-                    if (cell >= 0)
+                forAll(cTetVFracs, tet)
+                {
+                    sTet = tet;
+
+                    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<ParcelType>::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<ParcelType>::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<ParcelType>::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<scalar>()) << 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<scalar>()) << 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<ParcelType>::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<ParcelType>::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 b246b0499040fa15a68ab38ceb2543b8249e43f1..20bed1ee7b14429c66fcc90b2dcb52023ff73241 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 73899636e8f6cf2a7e47754a15c8cf8aeb711712..d39de4954faa1a062ab15da0d878e736d542b42e 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<ParcelType>::maxwellianAverageSpeed
 }
 
 
+template<class ParcelType>
+inline Foam::scalarField Foam::DsmcCloud<ParcelType>::maxwellianAverageSpeed
+(
+    scalarField temperature,
+    scalar mass
+) const
+{
+    return 2.0*sqrt(2.0*kb*temperature/(mathematicalConstant::pi*mass));
+}
+
+
 template<class ParcelType>
 inline Foam::scalar Foam::DsmcCloud<ParcelType>::maxwellianRMSSpeed
 (
@@ -313,6 +324,17 @@ inline Foam::scalar Foam::DsmcCloud<ParcelType>::maxwellianRMSSpeed
 }
 
 
+template<class ParcelType>
+inline Foam::scalarField Foam::DsmcCloud<ParcelType>::maxwellianRMSSpeed
+(
+    scalarField temperature,
+    scalar mass
+) const
+{
+    return sqrt(3.0*kb*temperature/mass);
+}
+
+
 template<class ParcelType>
 inline Foam::scalar
 Foam::DsmcCloud<ParcelType>::maxwellianMostProbableSpeed
@@ -325,6 +347,18 @@ Foam::DsmcCloud<ParcelType>::maxwellianMostProbableSpeed
 }
 
 
+template<class ParcelType>
+inline Foam::scalarField
+Foam::DsmcCloud<ParcelType>::maxwellianMostProbableSpeed
+(
+    scalarField temperature,
+    scalar mass
+) const
+{
+    return sqrt(2.0*kb*temperature/mass);
+}
+
+
 template<class ParcelType>
 inline const Foam::tmp<Foam::volScalarField>
 Foam::DsmcCloud<ParcelType>::rhoN() const
@@ -343,7 +377,7 @@ Foam::DsmcCloud<ParcelType>::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<ParcelType>::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<ParcelType>::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 f4203f4d66f7e85eaf335eee7c5c3b80521dd4e0..cd18d9064d3dfbe6d5126f6621c96d8af32a5df7 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<CloudType>::FreeStream
 )
 :
     InflowBoundaryModel<CloudType>(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<label> patches;
 
-    const polyPatch& patch = cloud.mesh().boundaryMesh()[patchIndex_];
-
-    if (patchIndex_ == -1)
+    forAll(cloud.mesh().boundaryMesh(), p)
     {
-        FatalErrorIn
-        (
-            "Foam::FreeStream<CloudType>::FreeStream"
-            "("
-                "const dictionary&, "
-                "CloudType&"
-            ")"
-        )   << "patch " << patchName << " not found." << nl
-            << abort(FatalError);
+        const polyPatch& patch = cloud.mesh().boundaryMesh()[p];
+
+        if (patch.type() == polyPatch::typeName)
+        {
+            patches.append(p);
+        }
     }
 
+    patches_.transfer(patches);
+
     const dictionary& numberDensitiesDict
     (
         this->coeffDict().subDict("numberDensities")
@@ -69,10 +64,24 @@ Foam::FreeStream<CloudType>::FreeStream
 
     List<word> molecules(numberDensitiesDict.toc());
 
-    numberDensities_.setSize(molecules.size());
+    // Initialise the particleFluxAccumulators_
+    particleFluxAccumulators_.setSize(patches_.size());
+
+    forAll(patches_, p)
+    {
+        const polyPatch& patch = cloud.mesh().boundaryMesh()[patches_[p]];
+
+        particleFluxAccumulators_[p] = List<Field<scalar> >
+        (
+            molecules.size(),
+            Field<scalar>(patch.size(), 0.0)
+        );
+    }
 
     moleculeTypeIds_.setSize(molecules.size());
 
+    numberDensities_.setSize(molecules.size());
+
     forAll(molecules, i)
     {
         numberDensities_[i] = readScalar
@@ -97,12 +106,6 @@ Foam::FreeStream<CloudType>::FreeStream
     }
 
     numberDensities_ /= cloud.nParticle();
-
-    particleFluxAccumulators_.setSize
-    (
-        molecules.size(),
-        Field<scalar>(patch.size(), 0)
-    );
 }
 
 
@@ -127,144 +130,262 @@ void Foam::FreeStream<CloudType>::inflow()
 
     Random& rndGen(cloud.rndGen());
 
-    const polyPatch& patch = mesh.boundaryMesh()[patchIndex_];
+    scalar sqrtPi = sqrt(mathematicalConstant::pi);
 
     label particlesInserted = 0;
 
-    // Add mass to the accumulators.  negative face area dotted with the
-    // velocity to point flux into the domain.
+    const volScalarField::GeometricBoundaryField& boundaryT
+    (
+        cloud.T().boundaryField()
+    );
 
-    forAll(particleFluxAccumulators_, i)
-    {
-        particleFluxAccumulators_[i] +=
-           -patch.faceAreas() & (velocity_*numberDensities_[i]*deltaT);
-    }
+    const volVectorField::GeometricBoundaryField& boundaryU
+    (
+        cloud.U().boundaryField()
+    );
 
-    forAll(patch, f)
+    forAll(patches_, p)
     {
-        // Loop over all faces as the outer loop to avoid calculating
-        // geometrical properties multiple times.
+        label patchI = patches_[p];
 
-        labelList faceVertices = patch[f];
+        const polyPatch& patch = mesh.boundaryMesh()[patchI];
 
-        label nVertices = faceVertices.size();
+        // Add mass to the accumulators.  negative face area dotted with the
+        // velocity to point flux into the domain.
 
-        label globalFaceIndex = f + patch.start();
+        // Take a reference to the particleFluxAccumulator for this patch
+        List<Field<scalar> >& pFA = particleFluxAccumulators_[p];
 
-        label cell = mesh.faceOwner()[globalFaceIndex];
-
-        const vector& fC = patch.faceCentres()[f];
+        forAll(pFA, i)
+        {
+            label typeId = moleculeTypeIds_[i];
 
-        scalar fA = mag(patch.faceAreas()[f]);
+            scalar mass = cloud.constProps(typeId).mass();
 
-        // Cummulative triangle area fractions
-        List<scalar> cTriAFracs(nVertices);
+            scalarField mostProbableSpeed
+            (
+                cloud.maxwellianMostProbableSpeed
+                (
+                    boundaryT[patchI],
+                    mass
+                )
+            );
+
+            // Dotting boundary velocity with the face unit normal (which points
+            // out of the domain, so it must be negated), dividing by the most
+            // probable speed to form molecularSpeedRatio * cosTheta
+
+            scalarField sCosTheta =
+                boundaryU[patchI]
+              & -patch.faceAreas()/mag(patch.faceAreas())
+               /mostProbableSpeed;
+
+            // From Bird eqn 4.22
+
+            pFA[i] +=
+                mag(patch.faceAreas())*numberDensities_[i]*deltaT
+               *mostProbableSpeed
+               *(
+                   exp(-sqr(sCosTheta)) + sqrtPi*sCosTheta*(1 + erf(sCosTheta))
+                )
+               /(2.0*sqrtPi);
+        }
 
-        for (label v = 0; v < nVertices - 1; v++)
+        forAll(patch, f)
         {
-            const point& vA = mesh.points()[faceVertices[v]];
+            // Loop over all faces as the outer loop to avoid calculating
+            // geometrical properties multiple times.
 
-            const point& vB = mesh.points()[faceVertices[(v + 1)]];
+            labelList faceVertices = patch[f];
 
-            cTriAFracs[v] =
-                0.5*mag((vA - fC)^(vB - fC))/fA
-              + cTriAFracs[max((v - 1), 0)];
-        }
+            label nVertices = faceVertices.size();
 
-        // Force the last area fraction value to 1.0 to avoid any
-        // rounding/non-flat face errors giving a value < 1.0
-        cTriAFracs[nVertices - 1] = 1.0;
+            label globalFaceIndex = f + patch.start();
 
-        // Normal unit vector *negative* so normal is pointing into the
-        // domain
-        vector nw = patch.faceAreas()[f];
-        nw /= -mag(nw);
+            label cell = mesh.faceOwner()[globalFaceIndex];
 
-        // Wall tangential unit vector. Use the direction between the
-        // face centre and the first vertex in the list
-        vector tw1 = fC - (mesh.points()[faceVertices[0]]);
-        tw1 /= mag(tw1);
+            const vector& fC = patch.faceCentres()[f];
 
-        // Other tangential unit vector.  Rescaling in case face is not
-        // flat and nw and tw1 aren't perfectly orthogonal
-        vector tw2 = nw^tw1;
-        tw2 /= mag(tw2);
+            scalar fA = mag(patch.faceAreas()[f]);
 
-        forAll(particleFluxAccumulators_, i)
-        {
-            scalar& faceAccumulator = particleFluxAccumulators_[i][f];
+            // Cumulative triangle area fractions
+            List<scalar> cTriAFracs(nVertices);
 
-            // Number of particles to insert
-            label nI = max(label(faceAccumulator), 0);
+            for (label v = 0; v < nVertices - 1; v++)
+            {
+                const point& vA = mesh.points()[faceVertices[v]];
 
-            faceAccumulator -= nI;
+                const point& vB = mesh.points()[faceVertices[(v + 1)]];
 
-            label typeId = moleculeTypeIds_[i];
+                cTriAFracs[v] =
+                    0.5*mag((vA - fC)^(vB - fC))/fA
+                  + cTriAFracs[max((v - 1), 0)];
+            }
 
-            scalar mass = cloud.constProps(typeId).mass();
+            // Force the last area fraction value to 1.0 to avoid any
+            // rounding/non-flat face errors giving a value < 1.0
+            cTriAFracs[nVertices - 1] = 1.0;
+
+            // Normal unit vector *negative* so normal is pointing into the
+            // domain
+            vector n = patch.faceAreas()[f];
+            n /= -mag(n);
+
+            // Wall tangential unit vector. Use the direction between the
+            // face centre and the first vertex in the list
+            vector t1 = fC - (mesh.points()[faceVertices[0]]);
+            t1 /= mag(t1);
 
-            for (label n = 0; n < nI; n++)
+            // Other tangential unit vector.  Rescaling in case face is not
+            // flat and n and t1 aren't perfectly orthogonal
+            vector t2 = n^t1;
+            t2 /= mag(t2);
+
+            scalar faceTemperature = boundaryT[patchI][f];
+
+            const vector& faceVelocity = boundaryU[patchI][f];
+
+            forAll(pFA, i)
             {
-                // Choose a triangle to insert on, based on their relative area
+                scalar& faceAccumulator = pFA[i][f];
 
-                scalar triSelection = rndGen.scalar01();
+                // Number of whole particles to insert
+                label nI = max(label(faceAccumulator), 0);
 
-                // Selected triangle
-                label sTri = -1;
+                // Add another particle with a probability proportional to the
+                // remainder of taking the integer part of faceAccumulator
+                if ((faceAccumulator - nI) > rndGen.scalar01())
+                {
+                    nI++;
+                }
+
+                faceAccumulator -= nI;
+
+                label typeId = moleculeTypeIds_[i];
+
+                scalar mass = cloud.constProps(typeId).mass();
 
-                forAll(cTriAFracs, tri)
+                for (label i = 0; i < nI; i++)
                 {
-                    sTri = tri;
+                    // Choose a triangle to insert on, based on their relative
+                    // area
 
-                    if (cTriAFracs[tri] >= triSelection)
+                    scalar triSelection = rndGen.scalar01();
+
+                    // Selected triangle
+                    label sTri = -1;
+
+                    forAll(cTriAFracs, tri)
                     {
-                        break;
+                        sTri = tri;
+
+                        if (cTriAFracs[tri] >= triSelection)
+                        {
+                            break;
+                        }
                     }
-                }
 
-                // Randomly distribute the points on the triangle, using the
-                // method from:
-                // Generating Random Points in Triangles
-                // by Greg Turk
-                // from "Graphics Gems", Academic Press, 1990
-                // http://tog.acm.org/GraphicsGems/gems/TriPoints.c
+                    // Randomly distribute the points on the triangle, using the
+                    // method from:
+                    // Generating Random Points in Triangles
+                    // by Greg Turk
+                    // from "Graphics Gems", Academic Press, 1990
+                    // http://tog.acm.org/GraphicsGems/gems/TriPoints.c
 
-                const point& A = fC;
-                const point& B = mesh.points()[faceVertices[sTri]];
-                const point& C =
+                    const point& A = fC;
+                    const point& B = mesh.points()[faceVertices[sTri]];
+                    const point& C =
                     mesh.points()[faceVertices[(sTri + 1) % nVertices]];
 
-                scalar s = rndGen.scalar01();
-                scalar t = sqrt(rndGen.scalar01());
+                    scalar s = rndGen.scalar01();
+                    scalar t = sqrt(rndGen.scalar01());
 
-                point p = (1 - t)*A + (1 - s)*t*B + s*t*C;
+                    point p = (1 - t)*A + (1 - s)*t*B + s*t*C;
 
-                vector U =
-                    sqrt(CloudType::kb*temperature_/mass)
-                   *(
-                        rndGen.GaussNormal()*tw1
-                      + rndGen.GaussNormal()*tw2
-                      - sqrt(-2.0*log(max(1 - rndGen.scalar01(), VSMALL)))*nw
+                    // Velocity generation
+
+                    scalar mostProbableSpeed
+                    (
+                        cloud.maxwellianMostProbableSpeed
+                        (
+                            faceTemperature,
+                            mass
+                        )
                     );
 
-                U += velocity_;
+                    scalar sCosTheta = (faceVelocity & n)/mostProbableSpeed;
 
-                scalar Ei = cloud.equipartitionInternalEnergy
-                (
-                    temperature_,
-                    cloud.constProps(typeId).internalDegreesOfFreedom()
-                );
+                    // Coefficients required for Bird eqn 12.5
+                    scalar uNormProbCoeffA =
+                        sCosTheta + sqrt(sqr(sCosTheta) + 2.0);
 
-                cloud.addNewParcel
-                (
-                    p,
-                    U,
-                    Ei,
-                    cell,
-                    typeId
-                );
-
-                particlesInserted++;
+                    scalar uNormProbCoeffB =
+                        0.5*
+                        (
+                            1.0
+                          + sCosTheta*(sCosTheta - sqrt(sqr(sCosTheta) + 2.0))
+                        );
+
+                    // Equivalent to the QA value in Bird's DSMC3.FOR
+                    scalar randomScaling = 3.0;
+
+                    if (sCosTheta < -3)
+                    {
+                        randomScaling = mag(sCosTheta) + 1;
+                    }
+
+                    scalar P = -1;
+
+                    // Normalised candidates for the normal direction velocity
+                    // component
+                    scalar uNormal;
+                    scalar uNormalThermal;
+
+                    // Select a velocity using Bird eqn 12.5
+                    do
+                    {
+                        uNormalThermal =
+                            randomScaling*(2.0*rndGen.scalar01() - 1);
+
+                        uNormal = uNormalThermal + sCosTheta;
+
+                        if (uNormal < 0.0)
+                        {
+                            P = -1;
+                        }
+                        else
+                        {
+                            P = 2.0*uNormal/uNormProbCoeffA
+                               *exp(uNormProbCoeffB - sqr(uNormalThermal));
+                        }
+
+                    } while (P < rndGen.scalar01());
+
+                    vector U =
+                        sqrt(CloudType::kb*faceTemperature/mass)
+                       *(
+                            rndGen.GaussNormal()*t1
+                          + rndGen.GaussNormal()*t2
+                        )
+                      + mostProbableSpeed*uNormal*n;
+
+                    scalar Ei = cloud.equipartitionInternalEnergy
+                    (
+                        faceTemperature,
+                        cloud.constProps(typeId).internalDegreesOfFreedom()
+                    );
+
+                    cloud.addNewParcel
+                    (
+                        p,
+                        U,
+                        Ei,
+                        cell,
+                        typeId
+                    );
+
+                    particlesInserted++;
+                }
             }
         }
     }
diff --git a/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.H b/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.H
index f1bd4cc32133490ea027136a6de2f36798898574..03c2fe2abb72fe657ef9905162585099c445693d 100644
--- a/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.H
+++ b/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.H
@@ -26,8 +26,10 @@ Class
     Foam::FreeStream
 
 Description
-    Inserting new particles across the faces of a specified patch for a free
-    stream.  Uniform values of temperature, velocity and number densities
+    Inserting new particles across the faces of a all patched of type
+    "patch" for a free stream.  Uniform values number density, temperature
+    and velocity sourced face-by-face from the boundaryT and boundaryU fields
+    of the cloud.
 
 \*---------------------------------------------------------------------------*/
 
@@ -52,14 +54,8 @@ class FreeStream
 {
     // Private data
 
-        //- Index of patch to introduce particles across
-        label patchIndex_;
-
-        //- Temperature of the free stream
-        scalar temperature_;
-
-        //- Velocity of the free stream
-        vector velocity_;
+        //- The indices of patches to introduce molecules across
+        labelList patches_;
 
         //- The molecule types to be introduced
         List<label> moleculeTypeIds_;
@@ -67,10 +63,13 @@ class FreeStream
         //- The number density of the species in the inflow
         Field<scalar> numberDensities_;
 
-        //- A List of Fields, one Field for every species to be introduced, each
-        // field entry corresponding to a face on the patch to be injected
-        // across.
-        List<Field<scalar> > particleFluxAccumulators_;
+        //- A List of Lists of Fields specifying carry-over of mass flux from
+        // one timestep to the next
+        // + Outer List - one inner List for each patch
+        // + Inner List - one Field for every species to be introduced
+        // + Each field entry corresponding to a face to be injected across
+        //   with a particular species
+        List<List<Field<scalar> > > particleFluxAccumulators_;
 
 
 public:
diff --git a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C
index 3aaa9c514a462f7d2850d0035ab34478d70e7817..273c88f3699822572bce150ad303b3224f5574ce 100644
--- a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C
+++ b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C
@@ -137,7 +137,7 @@ void Foam::dsmcFields::write()
             iDofMeanName
         );
 
-        if (min(rhoNMean).value() > VSMALL)
+        if (min(mag(rhoNMean)).value() > VSMALL)
         {
             Info<< "Calculating dsmcFields." << endl;
 
@@ -223,10 +223,9 @@ void Foam::dsmcFields::write()
         }
         else
         {
-            Info<< "Small or negative value (" << min(rhoNMean)
+            Info<< "Small value (" << min(mag(rhoNMean))
                 << ") found in rhoNMean field. "
-                << "Not calculating dsmcFields to avoid division by zero "
-                << "or invalid results."
+                << "Not calculating dsmcFields to avoid division by zero."
                 << endl;
         }
     }
diff --git a/src/sampling/sampledSet/sampledSets/sampledSets.C b/src/sampling/sampledSet/sampledSets/sampledSets.C
index 3f7b7a3323ede9cbc888a87d1929da1ba887e405..4d71403277a790c84179c0f5612cbff226f6754e 100644
--- a/src/sampling/sampledSet/sampledSets/sampledSets.C
+++ b/src/sampling/sampledSet/sampledSets/sampledSets.C
@@ -236,8 +236,6 @@ Foam::sampledSets::sampledSets
     loadFromFiles_(loadFromFiles),
     outputPath_(fileName::null),
     searchEngine_(mesh_, true),
-//    pMeshPtr_(NULL),
-//    pInterpPtr_(NULL),
     fieldNames_(),
     interpolationScheme_(word::null),
     writeFormat_(word::null)
@@ -250,6 +248,10 @@ Foam::sampledSets::sampledSets
     {
         outputPath_ = mesh_.time().path()/name_;
     }
+    if (mesh_.name() != fvMesh::defaultRegion)
+    {
+        outputPath_ = outputPath_/mesh_.name();
+    }
 
     read(dict);
 }