diff --git a/applications/solvers/lagrangian/DPMFoam/Allwclean b/applications/solvers/lagrangian/DPMFoam/Allwclean
index 390c1235d2..25d0b2955f 100755
--- a/applications/solvers/lagrangian/DPMFoam/Allwclean
+++ b/applications/solvers/lagrangian/DPMFoam/Allwclean
@@ -5,3 +5,4 @@ set -x
wclean DPMTurbulenceModels
wclean
+wclean MPPICFoam
diff --git a/applications/solvers/lagrangian/DPMFoam/Allwmake b/applications/solvers/lagrangian/DPMFoam/Allwmake
index 7cff009a34..6308a7052b 100755
--- a/applications/solvers/lagrangian/DPMFoam/Allwmake
+++ b/applications/solvers/lagrangian/DPMFoam/Allwmake
@@ -5,3 +5,4 @@ set -x
wmake DPMTurbulenceModels
wmake
+wmake MPPICFoam
diff --git a/src/lagrangian/intermediate/Make/files b/src/lagrangian/intermediate/Make/files
index 6d4e26a441..9cadf55117 100644
--- a/src/lagrangian/intermediate/Make/files
+++ b/src/lagrangian/intermediate/Make/files
@@ -19,6 +19,8 @@ KINEMATICPARCEL=$(DERIVEDPARCELS)/basicKinematicParcel
$(KINEMATICPARCEL)/defineBasicKinematicParcel.C
$(KINEMATICPARCEL)/makeBasicKinematicParcelSubmodels.C
+
+/* kinematic colliding parcel sub-models */
KINEMATICCOLLIDINGPARCEL=$(DERIVEDPARCELS)/basicKinematicCollidingParcel
$(KINEMATICCOLLIDINGPARCEL)/defineBasicKinematicCollidingParcel.C
$(KINEMATICCOLLIDINGPARCEL)/makeBasicKinematicCollidingParcelSubmodels.C
@@ -42,6 +44,12 @@ $(REACTINGMPPARCEL)/defineBasicReactingMultiphaseParcel.C
$(REACTINGMPPARCEL)/makeBasicReactingMultiphaseParcelSubmodels.C
+/* kinematic MPPIC parcel sub-models */
+KINEMATICMPPICPARCEL=$(DERIVEDPARCELS)/basicKinematicMPPICParcel
+$(KINEMATICMPPICPARCEL)/defineBasicKinematicMPPICParcel.C
+$(KINEMATICMPPICPARCEL)/makeBasicKinematicMPPICParcelSubmodels.C
+
+
/* bolt-on models */
RADIATION=submodels/addOns/radiation
$(RADIATION)/absorptionEmission/cloudAbsorptionEmission/cloudAbsorptionEmission.C
@@ -71,6 +79,24 @@ $(REACTINGMPINJECTION)/ReactingMultiphaseLookupTableInjection/reactingMultiphase
$(REACTINGMPINJECTION)/ReactingMultiphaseLookupTableInjection/reactingMultiphaseParcelInjectionDataIO.C
$(REACTINGMPINJECTION)/ReactingMultiphaseLookupTableInjection/reactingMultiphaseParcelInjectionDataIOList.C
+MPPICPARTICLESTRESS=submodels/MPPIC/ParticleStressModels
+$(MPPICPARTICLESTRESS)/ParticleStressModel/ParticleStressModel.C
+$(MPPICPARTICLESTRESS)/HarrisCrighton/HarrisCrighton.C
+$(MPPICPARTICLESTRESS)/Lun/Lun.C
+$(MPPICPARTICLESTRESS)/exponential/exponential.C
+
+MPPICCORRECTIONLIMITING=submodels/MPPIC/CorrectionLimitingMethods
+$(MPPICCORRECTIONLIMITING)/CorrectionLimitingMethod/CorrectionLimitingMethod.C
+$(MPPICCORRECTIONLIMITING)/noCorrectionLimiting/noCorrectionLimiting.C
+$(MPPICCORRECTIONLIMITING)/absolute/absolute.C
+$(MPPICCORRECTIONLIMITING)/relative/relative.C
+
+MPPICTIMESCALE=submodels/MPPIC/TimeScaleModels
+$(MPPICTIMESCALE)/TimeScaleModel/TimeScaleModel.C
+$(MPPICTIMESCALE)/equilibrium/equilibrium.C
+$(MPPICTIMESCALE)/nonEquilibrium/nonEquilibrium.C
+$(MPPICTIMESCALE)/isotropic/isotropic.C
+
/* integration schemes */
IntegrationScheme/makeIntegrationSchemes.C
@@ -81,8 +107,13 @@ phaseProperties/phaseProperties/phaseProperties.C
phaseProperties/phaseProperties/phasePropertiesIO.C
phaseProperties/phasePropertiesList/phasePropertiesList.C
-/* Additional helper classes */
+
+/* additional helper classes */
clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.C
+/* averaging methods */
+submodels/MPPIC/AveragingMethods/makeAveragingMethods.C
+
+
LIB = $(FOAM_LIBBIN)/liblagrangianIntermediate
diff --git a/src/lagrangian/intermediate/clouds/Templates/MPPICCloud/MPPICCloud.C b/src/lagrangian/intermediate/clouds/Templates/MPPICCloud/MPPICCloud.C
new file mode 100644
index 0000000000..f22cac7b0f
--- /dev/null
+++ b/src/lagrangian/intermediate/clouds/Templates/MPPICCloud/MPPICCloud.C
@@ -0,0 +1,299 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+\*---------------------------------------------------------------------------*/
+
+#include "MPPICCloud.H"
+#include "PackingModel.H"
+#include "ParticleStressModel.H"
+#include "DampingModel.H"
+#include "IsotropyModel.H"
+#include "TimeScaleModel.H"
+
+// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
+
+template
+void Foam::MPPICCloud::setModels()
+{
+ packingModel_.reset
+ (
+ PackingModel >::New
+ (
+ this->subModelProperties(),
+ *this
+ ).ptr()
+ );
+ dampingModel_.reset
+ (
+ DampingModel >::New
+ (
+ this->subModelProperties(),
+ *this
+ ).ptr()
+ );
+ isotropyModel_.reset
+ (
+ IsotropyModel >::New
+ (
+ this->subModelProperties(),
+ *this
+ ).ptr()
+ );
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+template
+Foam::MPPICCloud::MPPICCloud
+(
+ const word& cloudName,
+ const volScalarField& rho,
+ const volVectorField& U,
+ const volScalarField& mu,
+ const dimensionedVector& g,
+ bool readFields
+)
+:
+ CloudType(cloudName, rho, U, mu, g, false),
+ packingModel_(NULL),
+ dampingModel_(NULL),
+ isotropyModel_(NULL)
+{
+ if (this->solution().steadyState())
+ {
+ FatalErrorIn
+ (
+ "Foam::MPPICCloud::MPPICCloud"
+ "("
+ "const word&, "
+ "const volScalarField&, "
+ "const volVectorField&, "
+ "const volScalarField&, "
+ "const dimensionedVector&, "
+ "bool"
+ ")"
+ ) << "MPPIC modelling not available for steady state calculations"
+ << exit(FatalError);
+ }
+
+ if (this->solution().active())
+ {
+ setModels();
+
+ if (readFields)
+ {
+ parcelType::readFields(*this);
+ }
+ }
+}
+
+
+template
+Foam::MPPICCloud::MPPICCloud
+(
+ MPPICCloud& c,
+ const word& name
+)
+:
+ CloudType(c, name),
+ packingModel_(c.packingModel_->clone()),
+ dampingModel_(c.dampingModel_->clone()),
+ isotropyModel_(c.isotropyModel_->clone())
+{}
+
+
+template
+Foam::MPPICCloud::MPPICCloud
+(
+ const fvMesh& mesh,
+ const word& name,
+ const MPPICCloud& c
+)
+:
+ CloudType(mesh, name, c),
+ packingModel_(NULL),
+ dampingModel_(NULL),
+ isotropyModel_(NULL)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
+
+template
+Foam::MPPICCloud::~MPPICCloud()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template
+void Foam::MPPICCloud::storeState()
+{
+ cloudCopyPtr_.reset
+ (
+ static_cast*>
+ (
+ clone(this->name() + "Copy").ptr()
+ )
+ );
+}
+
+
+template
+void Foam::MPPICCloud::restoreState()
+{
+ this->cloudReset(cloudCopyPtr_());
+ cloudCopyPtr_.clear();
+}
+
+
+template
+void Foam::MPPICCloud::evolve()
+{
+ if (this->solution().canEvolve())
+ {
+ typename parcelType::template
+ TrackingData > td(*this);
+
+ this->solve(td);
+ }
+}
+
+
+template
+template
+void Foam::MPPICCloud::motion(TrackData& td)
+{
+ // Kinematic
+ // ~~~~~~~~~
+
+ // force calculation and tracking
+ td.part() = TrackData::tpLinearTrack;
+ CloudType::move(td, this->db().time().deltaTValue());
+
+
+ // Preliminary
+ // ~~~~~~~~~~~
+
+ // switch forces off so they are not applied in corrector steps
+ this->forces().setCalcNonCoupled(false);
+ this->forces().setCalcCoupled(false);
+
+
+ // Damping
+ // ~~~~~~~
+
+ if (dampingModel_->active())
+ {
+ // update averages
+ td.updateAverages(*this);
+
+ // memory allocation and eulerian calculations
+ dampingModel_->cacheFields(true);
+
+ // calculate the damping velocity corrections without moving the parcels
+ td.part() = TrackData::tpDampingNoTrack;
+ CloudType::move(td, this->db().time().deltaTValue());
+
+ // correct the parcel positions and velocities
+ td.part() = TrackData::tpCorrectTrack;
+ CloudType::move(td, this->db().time().deltaTValue());
+
+ // finalise and free memory
+ dampingModel_->cacheFields(false);
+ }
+
+
+ // Packing
+ // ~~~~~~~
+
+ if (packingModel_->active())
+ {
+ // same procedure as for damping
+ td.updateAverages(*this);
+ packingModel_->cacheFields(true);
+ td.part() = TrackData::tpPackingNoTrack;
+ CloudType::move(td, this->db().time().deltaTValue());
+ td.part() = TrackData::tpCorrectTrack;
+ CloudType::move(td, this->db().time().deltaTValue());
+ packingModel_->cacheFields(false);
+ }
+
+
+ // Isotropy
+ // ~~~~~~~~
+
+ if (isotropyModel_->active())
+ {
+ // update averages
+ td.updateAverages(*this);
+
+ // apply isotropy model
+ isotropyModel_->calculate();
+ }
+
+
+ // Final
+ // ~~~~~
+
+ // update cell occupancy
+ this->updateCellOccupancy();
+
+ // switch forces back on
+ this->forces().setCalcNonCoupled(true);
+ this->forces().setCalcCoupled(this->solution().coupled());
+}
+
+
+template
+void Foam::MPPICCloud::info()
+{
+ CloudType::info();
+
+ tmp alpha = this->theta();
+
+ Info<< " Min cell volume fraction = "
+ << gMin(alpha().internalField()) << endl;
+ Info<< " Max cell volume fraction = "
+ << gMax(alpha().internalField()) << endl;
+
+ label nOutside = 0;
+
+ forAllIter(typename CloudType, *this, iter)
+ {
+ typename CloudType::parcelType& p = iter();
+ const tetIndices tetIs(p.cell(), p.tetFace(), p.tetPt(), this->mesh());
+ nOutside += !tetIs.tet(this->mesh()).inside(p.position());
+ }
+
+ reduce(nOutside, plusOp