diff --git a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayer/atmBoundaryLayer.C b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayer/atmBoundaryLayer.C
index 9c4faaf498bfc628692b100f88a8268c542e4c6c..2c41babd15257ff138936dd2457cf5b340414d25 100644
--- a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayer/atmBoundaryLayer.C
+++ b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayer/atmBoundaryLayer.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2014-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2018 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -32,135 +32,183 @@ namespace Foam
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-atmBoundaryLayer::atmBoundaryLayer()
+atmBoundaryLayer::atmBoundaryLayer(const Time& time, const polyPatch& pp)
 :
-    flowDir_(Zero),
-    zDir_(Zero),
+    time_(time),
+    patch_(pp),
+    flowDir_(time, "flowDir"),
+    zDir_(time, "zDir"),
     kappa_(0.41),
     Cmu_(0.09),
-    Uref_(0),
-    Zref_(0),
-    z0_(0),
-    zGround_(0),
-    Ustar_(0)
+    Uref_(time, "Uref"),
+    Zref_(time, "Zref"),
+    z0_(),
+    zGround_()
 {}
 
 
-atmBoundaryLayer::atmBoundaryLayer(const vectorField& p, const dictionary& dict)
+atmBoundaryLayer::atmBoundaryLayer
+(
+    const Time& time,
+    const polyPatch& pp,
+    const dictionary& dict
+)
 :
-    flowDir_(dict.lookup("flowDir")),
-    zDir_(dict.lookup("zDir")),
+    time_(time),
+    patch_(pp),
+    flowDir_(TimeFunction1<vector>(time, "flowDir", dict)),
+    zDir_(TimeFunction1<vector>(time, "zDir", dict)),
     kappa_(dict.lookupOrDefault<scalar>("kappa", 0.41)),
     Cmu_(dict.lookupOrDefault<scalar>("Cmu", 0.09)),
-    Uref_(dict.get<scalar>("Uref")),
-    Zref_(dict.get<scalar>("Zref")),
-    z0_("z0", dict, p.size()),
-    zGround_("zGround", dict, p.size()),
-    Ustar_(p.size())
-{
-    if (mag(flowDir_) < SMALL || mag(zDir_) < SMALL)
-    {
-        FatalErrorInFunction
-            << "magnitude of n or z must be greater than zero"
-            << abort(FatalError);
-    }
-
-    // Ensure direction vectors are normalized
-    flowDir_ /= mag(flowDir_);
-    zDir_ /= mag(zDir_);
-
-    Ustar_ = kappa_*Uref_/(log((Zref_ + z0_)/z0_));
-}
+    Uref_(TimeFunction1<scalar>(time, "Uref", dict)),
+    Zref_(TimeFunction1<scalar>(time, "Zref", dict)),
+    z0_(PatchFunction1<scalar>::New(pp, "z0", dict)),
+    zGround_(PatchFunction1<scalar>::New(pp, "zGround", dict))
+{}
 
 
 atmBoundaryLayer::atmBoundaryLayer
 (
-    const atmBoundaryLayer& ptf,
+    const atmBoundaryLayer& abl,
+    const fvPatch& patch,
     const fvPatchFieldMapper& mapper
 )
 :
-    flowDir_(ptf.flowDir_),
-    zDir_(ptf.zDir_),
-    kappa_(ptf.kappa_),
-    Cmu_(ptf.Cmu_),
-    Uref_(ptf.Uref_),
-    Zref_(ptf.Zref_),
-    z0_(ptf.z0_, mapper),
-    zGround_(ptf.zGround_, mapper),
-    Ustar_(ptf.Ustar_, mapper)
+    time_(abl.time_),
+    patch_(patch.patch()),
+    flowDir_(abl.flowDir_),
+    zDir_(abl.zDir_),
+    kappa_(abl.kappa_),
+    Cmu_(abl.Cmu_),
+    Uref_(abl.Uref_),
+    Zref_(abl.Zref_),
+    z0_(abl.z0_.clone(patch_)),
+    zGround_(abl.zGround_.clone(patch_))
 {}
 
 
-atmBoundaryLayer::atmBoundaryLayer(const atmBoundaryLayer& blpvf)
+atmBoundaryLayer::atmBoundaryLayer(const atmBoundaryLayer& abl)
 :
-    flowDir_(blpvf.flowDir_),
-    zDir_(blpvf.zDir_),
-    kappa_(blpvf.kappa_),
-    Cmu_(blpvf.Cmu_),
-    Uref_(blpvf.Uref_),
-    Zref_(blpvf.Zref_),
-    z0_(blpvf.z0_),
-    zGround_(blpvf.zGround_),
-    Ustar_(blpvf.Ustar_)
+    time_(abl.time_),
+    patch_(abl.patch_),
+    flowDir_(abl.flowDir_),
+    zDir_(abl.zDir_),
+    kappa_(abl.kappa_),
+    Cmu_(abl.Cmu_),
+    Uref_(abl.Uref_),
+    Zref_(abl.Zref_),
+    z0_(abl.z0_.clone(patch_)),
+    zGround_(abl.zGround_.clone(patch_))
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void atmBoundaryLayer::autoMap(const fvPatchFieldMapper& m)
+vector atmBoundaryLayer::flowDir() const
+{
+    const scalar t = time_.timeOutputValue();
+    vector dir(flowDir_.value(t));
+    const scalar magDir = mag(dir);
+
+    if (magDir < SMALL)
+    {
+        FatalErrorInFunction
+            << "magnitude of " << flowDir_.name()
+            << " vector must be greater than zero"
+            << abort(FatalError);
+    }
+
+    return dir/magDir;
+}
+
+
+vector atmBoundaryLayer::zDir() const
+{
+    const scalar t = time_.timeOutputValue();
+    vector dir(zDir_.value(t));
+    const scalar magDir = mag(dir);
+
+    if (magDir < SMALL)
+    {
+        FatalErrorInFunction
+            << "magnitude of " << zDir_.name()
+            << " vector must be greater than zero"
+            << abort(FatalError);
+    }
+
+    return dir/magDir;
+}
+
+
+tmp<scalarField> atmBoundaryLayer::Ustar(const scalarField& z0) const
+{
+    const scalar t = time_.timeOutputValue();
+    const scalar Uref = Uref_.value(t);
+    const scalar Zref = Zref_.value(t);
+
+    return kappa_*Uref/(log((Zref + z0)/z0));
+}
+
+
+void atmBoundaryLayer::autoMap(const fvPatchFieldMapper& mapper)
 {
-    z0_.autoMap(m);
-    zGround_.autoMap(m);
-    Ustar_.autoMap(m);
+    z0_->autoMap(mapper);
+    zGround_->autoMap(mapper);
 }
 
 
 void atmBoundaryLayer::rmap
 (
-    const atmBoundaryLayer& blptf,
+    const atmBoundaryLayer& abl,
     const labelList& addr
 )
 {
-    z0_.rmap(blptf.z0_, addr);
-    zGround_.rmap(blptf.zGround_, addr);
-    Ustar_.rmap(blptf.Ustar_, addr);
+    z0_->rmap(abl.z0_(), addr);
+    zGround_->rmap(abl.zGround_(), addr);
 }
 
 
 tmp<vectorField> atmBoundaryLayer::U(const vectorField& p) const
 {
-    scalarField Un
-    (
-        (Ustar_/kappa_)
-       *log(((zDir_ & p) - zGround_ + z0_)/z0_)
-    );
+    const scalar t = time_.timeOutputValue();
+    const scalarField zGround(zGround_->value(t));
+    const scalarField z0(max(z0_->value(t), ROOTVSMALL));
+
+    scalarField Un((Ustar(z0)/kappa_)*log(((zDir() & p) - zGround + z0)/z0));
 
-    return flowDir_*Un;
+    return flowDir()*Un;
 }
 
 
 tmp<scalarField> atmBoundaryLayer::k(const vectorField& p) const
 {
-    return sqr(Ustar_)/sqrt(Cmu_);
+    const scalar t = time_.timeOutputValue();
+    const scalarField z0(max(z0_->value(t), ROOTVSMALL));
+
+    return sqr(Ustar(z0))/sqrt(Cmu_);
 }
 
 
 tmp<scalarField> atmBoundaryLayer::epsilon(const vectorField& p) const
 {
-    return pow3(Ustar_)/(kappa_*((zDir_ & p) - zGround_ + z0_));
+    const scalar t = time_.timeOutputValue();
+    const scalarField zGround(zGround_->value(t));
+    const scalarField z0(max(z0_->value(t), ROOTVSMALL));
+
+    return pow3(Ustar(z0))/(kappa_*((zDir() & p) - zGround + z0));
 }
 
 
 void atmBoundaryLayer::write(Ostream& os) const
 {
-    z0_.writeEntry("z0", os) ;
-    os.writeEntry("flowDir", flowDir_);
-    os.writeEntry("zDir", zDir_);
+    z0_->writeData(os) ;
+    flowDir_.writeData(os);
+    zDir_.writeData(os);
     os.writeEntry("kappa", kappa_);
     os.writeEntry("Cmu", Cmu_);
-    os.writeEntry("Uref", Uref_);
-    os.writeEntry("Zref", Zref_);
-    zGround_.writeEntry("zGround", os) ;
+    Uref_.writeData(os);
+    Zref_.writeData(os);
+    zGround_->writeData(os);
 }
 
 
diff --git a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayer/atmBoundaryLayer.H b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayer/atmBoundaryLayer.H
index 0f244ed59ed03a7172b7e77d427bbe2f004e2588..f9b33f9828f8f2ce32cbd15ab9e353e7223cce8e 100644
--- a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayer/atmBoundaryLayer.H
+++ b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayer/atmBoundaryLayer.H
@@ -116,6 +116,8 @@ SourceFiles
 #define atmBoundaryLayer_H
 
 #include "fvPatchFields.H"
+#include "TimeFunction1.H"
+#include "PatchFunction1.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -130,11 +132,17 @@ class atmBoundaryLayer
 {
     // Private data
 
+        //- Reference to the time database
+        const Time& time_;
+
+        //- Reference to the patch
+        const polyPatch& patch_;
+
         //- Flow direction
-        vector flowDir_;
+        TimeFunction1<vector> flowDir_;
 
         //- Direction of the z-coordinate
-        vector zDir_;
+        TimeFunction1<vector> zDir_;
 
         //- Von Karman constant
         const scalar kappa_;
@@ -143,36 +151,39 @@ class atmBoundaryLayer
         const scalar Cmu_;
 
         //- Reference velocity
-        const scalar Uref_;
+        TimeFunction1<scalar> Uref_;
 
         //- Reference height
-        const scalar Zref_;
+        TimeFunction1<scalar> Zref_;
 
         //- Surface roughness height
-        scalarField z0_;
+        autoPtr<PatchFunction1<scalar>> z0_;
 
         //- Minimum coordinate value in z direction
-        scalarField zGround_;
-
-        //- Friction velocity
-        scalarField Ustar_;
+        autoPtr<PatchFunction1<scalar>> zGround_;
 
 
 public:
 
     // Constructors
 
-        //- Construct null
-        atmBoundaryLayer();
+        //- Construct null from time
+        atmBoundaryLayer(const Time& time, const polyPatch& pp);
 
-        //- Construct from the coordinates field and dictionary
-        atmBoundaryLayer(const vectorField& p, const dictionary&);
+        //- Construct from the time database and dictionary
+        atmBoundaryLayer
+        (
+            const Time& time,
+            const polyPatch& pp,
+            const dictionary& dict
+        );
 
         //- Construct by mapping given atmBoundaryLayer onto a new patch
         atmBoundaryLayer
         (
-            const atmBoundaryLayer&,
-            const fvPatchFieldMapper&
+            const atmBoundaryLayer& abl,
+            const fvPatch& patch,
+            const fvPatchFieldMapper& mapper
         );
 
         //- Construct as copy
@@ -184,22 +195,13 @@ public:
         // Access
 
             //- Return flow direction
-            const vector& flowDir() const
-            {
-                return flowDir_;
-            }
+            vector flowDir() const;
 
             //- Return z-direction
-            const vector& zDir() const
-            {
-                return zDir_;
-            }
+            vector zDir() const;
 
             //- Return friction velocity
-            const scalarField& Ustar() const
-            {
-                return Ustar_;
-            }
+            tmp<scalarField> Ustar(const scalarField& z0) const;
 
 
         // Mapping functions
diff --git a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletEpsilon/atmBoundaryLayerInletEpsilonFvPatchScalarField.C b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletEpsilon/atmBoundaryLayerInletEpsilonFvPatchScalarField.C
index 8aeeed713de29690132a0acd455d60710e13cfbd..1521bcf7a8f742bee6f6ea2e0f62df6c0f0f5020 100644
--- a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletEpsilon/atmBoundaryLayerInletEpsilonFvPatchScalarField.C
+++ b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletEpsilon/atmBoundaryLayerInletEpsilonFvPatchScalarField.C
@@ -44,7 +44,7 @@ atmBoundaryLayerInletEpsilonFvPatchScalarField
 )
 :
     inletOutletFvPatchScalarField(p, iF),
-    atmBoundaryLayer()
+    atmBoundaryLayer(iF.time(), p.patch())
 {}
 
 
@@ -57,7 +57,7 @@ atmBoundaryLayerInletEpsilonFvPatchScalarField
 )
 :
     inletOutletFvPatchScalarField(p, iF),
-    atmBoundaryLayer(patch().Cf(), dict)
+    atmBoundaryLayer(iF.time(), p.patch(), dict)
 {
     phiName_ = dict.lookupOrDefault<word>("phi", "phi");
 
@@ -86,7 +86,7 @@ atmBoundaryLayerInletEpsilonFvPatchScalarField
 )
 :
     inletOutletFvPatchScalarField(psf, p, iF, mapper),
-    atmBoundaryLayer(psf, mapper)
+    atmBoundaryLayer(psf, p, mapper)
 {}
 
 
@@ -104,6 +104,19 @@ atmBoundaryLayerInletEpsilonFvPatchScalarField
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+void atmBoundaryLayerInletEpsilonFvPatchScalarField::updateCoeffs()
+{
+    if (updated())
+    {
+        return;
+    }
+
+    refValue() = epsilon(patch().Cf());
+
+    inletOutletFvPatchScalarField::updateCoeffs();
+}
+
+
 void atmBoundaryLayerInletEpsilonFvPatchScalarField::autoMap
 (
     const fvPatchFieldMapper& m
diff --git a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletEpsilon/atmBoundaryLayerInletEpsilonFvPatchScalarField.H b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletEpsilon/atmBoundaryLayerInletEpsilonFvPatchScalarField.H
index ff347f966c3fad8a38625130c5751056c97da8fd..b6ad79cf22eec9649e9558d53665888c18ffcd28 100644
--- a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletEpsilon/atmBoundaryLayerInletEpsilonFvPatchScalarField.H
+++ b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletEpsilon/atmBoundaryLayerInletEpsilonFvPatchScalarField.H
@@ -142,6 +142,10 @@ public:
 
     // Member functions
 
+        //- Update the coefficients associated with the patch field
+        virtual void updateCoeffs();
+
+
         // Mapping functions
 
             //- Map (and resize as needed) from self given a mapping object
diff --git a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletK/atmBoundaryLayerInletKFvPatchScalarField.C b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletK/atmBoundaryLayerInletKFvPatchScalarField.C
index 06f366089d146055d8650d120cbbd402f1bd82d1..94eb9da5f276755ac9789d43b4b15779361bf6dc 100644
--- a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletK/atmBoundaryLayerInletKFvPatchScalarField.C
+++ b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletK/atmBoundaryLayerInletKFvPatchScalarField.C
@@ -44,7 +44,7 @@ atmBoundaryLayerInletKFvPatchScalarField
 )
 :
     inletOutletFvPatchScalarField(p, iF),
-    atmBoundaryLayer()
+    atmBoundaryLayer(iF.time(), p.patch())
 {}
 
 
@@ -57,7 +57,7 @@ atmBoundaryLayerInletKFvPatchScalarField
 )
 :
     inletOutletFvPatchScalarField(p, iF),
-    atmBoundaryLayer(patch().Cf(), dict)
+    atmBoundaryLayer(iF.time(), p.patch(), dict)
 {
     phiName_ = dict.lookupOrDefault<word>("phi", "phi");
 
@@ -86,7 +86,7 @@ atmBoundaryLayerInletKFvPatchScalarField
 )
 :
     inletOutletFvPatchScalarField(psf, p, iF, mapper),
-    atmBoundaryLayer(psf, mapper)
+    atmBoundaryLayer(psf, p, mapper)
 {}
 
 
@@ -104,6 +104,19 @@ atmBoundaryLayerInletKFvPatchScalarField
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+void atmBoundaryLayerInletKFvPatchScalarField::updateCoeffs()
+{
+    if (updated())
+    {
+        return;
+    }
+
+    refValue() = k(patch().Cf());
+
+    inletOutletFvPatchScalarField::updateCoeffs();
+}
+
+
 void atmBoundaryLayerInletKFvPatchScalarField::autoMap
 (
     const fvPatchFieldMapper& m
diff --git a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletK/atmBoundaryLayerInletKFvPatchScalarField.H b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletK/atmBoundaryLayerInletKFvPatchScalarField.H
index b575ca3e332ed90418333fdacaf4cf65501a7348..a17c8ab3c889684498c2a69f504d9ee8d4fe2302 100644
--- a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletK/atmBoundaryLayerInletKFvPatchScalarField.H
+++ b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletK/atmBoundaryLayerInletKFvPatchScalarField.H
@@ -142,6 +142,10 @@ public:
 
     // Member functions
 
+        //- Update the coefficients associated with the patch field
+        virtual void updateCoeffs();
+
+
         // Mapping functions
 
             //- Map (and resize as needed) from self given a mapping object
diff --git a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletVelocity/atmBoundaryLayerInletVelocityFvPatchVectorField.C b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletVelocity/atmBoundaryLayerInletVelocityFvPatchVectorField.C
index b1d423e54548427f56b997c7375acc326239eed0..2ecce50f7fcae9d776e5bd79d4f36df4e41a3582 100644
--- a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletVelocity/atmBoundaryLayerInletVelocityFvPatchVectorField.C
+++ b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletVelocity/atmBoundaryLayerInletVelocityFvPatchVectorField.C
@@ -44,7 +44,7 @@ atmBoundaryLayerInletVelocityFvPatchVectorField
 )
 :
     inletOutletFvPatchVectorField(p, iF),
-    atmBoundaryLayer()
+    atmBoundaryLayer(iF.time(), p.patch())
 {}
 
 
@@ -57,7 +57,7 @@ atmBoundaryLayerInletVelocityFvPatchVectorField
 )
 :
     inletOutletFvPatchVectorField(p, iF),
-    atmBoundaryLayer(patch().Cf(), dict)
+    atmBoundaryLayer(iF.time(), p.patch(), dict)
 {
     phiName_ = dict.lookupOrDefault<word>("phi", "phi");
 
@@ -86,7 +86,7 @@ atmBoundaryLayerInletVelocityFvPatchVectorField
 )
 :
     inletOutletFvPatchVectorField(pvf, p, iF, mapper),
-    atmBoundaryLayer(pvf, mapper)
+    atmBoundaryLayer(pvf, p, mapper)
 {}
 
 
@@ -104,6 +104,19 @@ atmBoundaryLayerInletVelocityFvPatchVectorField
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+void atmBoundaryLayerInletVelocityFvPatchVectorField::updateCoeffs()
+{
+    if (updated())
+    {
+        return;
+    }
+
+    refValue() = U(patch().Cf());
+
+    inletOutletFvPatchVectorField::updateCoeffs();
+}
+
+
 void atmBoundaryLayerInletVelocityFvPatchVectorField::autoMap
 (
     const fvPatchFieldMapper& m
diff --git a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletVelocity/atmBoundaryLayerInletVelocityFvPatchVectorField.H b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletVelocity/atmBoundaryLayerInletVelocityFvPatchVectorField.H
index 22b421f4aae270d5da6f29d8b2e20861071ff8ef..d989b8528dcc56be3f20c9da5d04a24e40e9aeac 100644
--- a/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletVelocity/atmBoundaryLayerInletVelocityFvPatchVectorField.H
+++ b/src/atmosphericModels/derivedFvPatchFields/atmBoundaryLayerInletVelocity/atmBoundaryLayerInletVelocityFvPatchVectorField.H
@@ -143,6 +143,9 @@ public:
 
     // Member functions
 
+        //- Update the coefficients associated with the patch field
+        virtual void updateCoeffs();
+
         // Mapping functions
 
             //- Map (and resize as needed) from self given a mapping object