diff --git a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C
index 4c4bcd0a43dc965a3bd1daae9b06801b0d359c77..ac3b625638d165c82577210fa16cfefba12430f8 100644
--- a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C
+++ b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C
@@ -113,87 +113,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];
 
-    scalar y0 = mesh_.bounds().min().y();
-    scalar yR = mesh_.bounds().max().y() - y0;
+        label nTets = 0;
 
-    scalar z0 = mesh_.bounds().min().z();
-    scalar zR = mesh_.bounds().max().z() - z0;
+        // Each face is split into nEdges (or nVertices) - 2 tets.
+        forAll(cellFaces, face)
+        {
+            nTets += mesh_.faces()[cellFaces[face]].size() - 2;
+        }
 
-    forAll(molecules, i)
-    {
-        const word& moleculeName(molecules[i]);
+        // Calculate the cumulative tet volumes circulating around the cell and
+        // record the vertex labels of each.
+        scalarList cTetVFracs(nTets, 0.0);
+
+        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++;
+            }
 
-                    U += velocity;
+            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 (cell >= 0)
+                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();
+
+                // Selected tetrahedron
+                label sTet = -1;
+
+                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
+                );
             }
         }
     }
diff --git a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H
index 73899636e8f6cf2a7e47754a15c8cf8aeb711712..ede1e3559bb9dbb76619f45f05bdbd5e17a4515a 100644
--- a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H
+++ b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H
@@ -343,7 +343,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 +380,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 +568,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..02ed6d28b5852cb35ef1eff08e94a1cc044d8a7a 100644
--- a/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C
+++ b/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C
@@ -157,7 +157,7 @@ void Foam::FreeStream<CloudType>::inflow()
 
         scalar fA = mag(patch.faceAreas()[f]);
 
-        // Cummulative triangle area fractions
+        // Cumulative triangle area fractions
         List<scalar> cTriAFracs(nVertices);
 
         for (label v = 0; v < nVertices - 1; v++)