diff --git a/src/optimisation/adjointOptimisation/adjoint/objectives/objective/objective.C b/src/optimisation/adjointOptimisation/adjoint/objectives/objective/objective.C
index 975813fdbc9a21e16705e1e105635d765c6fb232..a8ee9c77e15b151a0d4b2cbf4bf861e5689de4a7 100644
--- a/src/optimisation/adjointOptimisation/adjoint/objectives/objective/objective.C
+++ b/src/optimisation/adjointOptimisation/adjoint/objectives/objective/objective.C
@@ -106,6 +106,22 @@ objective::objective
     const word& primalSolverName
 )
 :
+    localIOdictionary
+    (
+        IOobject
+        (
+            dict.dictName(),
+            mesh.time().timeName(),
+            fileName("uniform")/fileName("objectives")/adjointSolverName,
+            mesh,
+            IOobject::READ_IF_PRESENT,
+            IOobject::AUTO_WRITE
+        ),
+        // avoid type checking since dictionary is read using the
+        // derived type name and type() will result in "objective"
+        // here
+        word::null
+    ),
     mesh_(mesh),
     dict_(dict),
     adjointSolverName_(adjointSolverName),
@@ -115,7 +131,7 @@ objective::objective
     nullified_(false),
 
     J_(Zero),
-    JMean_(Zero),
+    JMean_(this->getOrDefault<scalar>("JMean", Zero)),
     weight_(Zero),
 
     integrationStartTimePtr_(nullptr),
@@ -158,21 +174,6 @@ objective::objective
             new scalar(dict.get<scalar>("integrationEndTime"))
         );
     }
-
-    // Read JMean from dictionary, if present
-    IOobject headObjectiveIODict
-    (
-        "objectiveDict" + objectiveName_,
-        mesh_.time().timeName(),
-        "uniform",
-        mesh_,
-        IOobject::READ_IF_PRESENT,
-        IOobject::NO_WRITE
-    );
-    if (headObjectiveIODict.typeHeaderOk<IOdictionary>(false))
-    {
-        JMean_ = IOdictionary(headObjectiveIODict).get<scalar>("JMean");
-    }
 }
 
 
@@ -660,22 +661,13 @@ void objective::writeMeanValue() const
                 << mesh_.time().value() << tab << JMean_ << endl;
         }
     }
-    // Write mean value under time/uniform, to allow for lineSearch to work
-    // appropriately in continuation runs, when field averaging is used
-    IOdictionary objectiveDict
-    (
-        IOobject
-        (
-            "objectiveDict" + objectiveName_,
-            mesh_.time().timeName(),
-            "uniform",
-            mesh_,
-            IOobject::NO_READ,
-            IOobject::NO_WRITE
-        )
-    );
-    objectiveDict.add<scalar>("JMean", JMean_);
-    objectiveDict.regIOobject::write();
+}
+
+
+bool objective::writeData(Ostream& os) const
+{
+    os.writeEntry("JMean", JMean_);
+    return os.good();
 }
 
 
diff --git a/src/optimisation/adjointOptimisation/adjoint/objectives/objective/objective.H b/src/optimisation/adjointOptimisation/adjoint/objectives/objective/objective.H
index 7b6a3aa3d49f8a8fc78c5ee60ffd54d1f1abe701..7fc69c3f5f9f95fd3f94313ca7f29789f2fe035b 100644
--- a/src/optimisation/adjointOptimisation/adjoint/objectives/objective/objective.H
+++ b/src/optimisation/adjointOptimisation/adjoint/objectives/objective/objective.H
@@ -40,6 +40,7 @@ SourceFiles
 #ifndef objective_H
 #define objective_H
 
+#include "localIOdictionary.H"
 #include "autoPtr.H"
 #include "runTimeSelectionTables.H"
 #include "OFstream.H"
@@ -57,6 +58,8 @@ namespace Foam
 \*---------------------------------------------------------------------------*/
 
 class objective
+:
+    public localIOdictionary
 {
 protected:
 
@@ -70,9 +73,13 @@ protected:
         bool computeMeanFields_;
         bool nullified_;
 
-        // Objective function value and weight
+        //- Objective function value and weight
         scalar J_;
-        scalar JMean_;  //average value
+
+        //- Average objective value
+        scalar JMean_;
+
+        //- Objective weight
         scalar weight_;
 
         // Objective integration start and end times (for unsteady flows)
@@ -361,6 +368,9 @@ public:
         //- Write mean objective function history
         virtual void writeMeanValue() const;
 
+        //- Write averaged objective for continuation
+        virtual bool writeData(Ostream& os) const;
+
         // Inline functions for checking whether pointers are set or not
         inline const word& objectiveName() const;
         inline bool hasdJdb() const;
diff --git a/src/optimisation/adjointOptimisation/adjoint/solvers/adjointSolvers/incompressible/adjointSimple/adjointSimple.C b/src/optimisation/adjointOptimisation/adjoint/solvers/adjointSolvers/incompressible/adjointSimple/adjointSimple.C
index d59f6e934718f1cecf73c78cc59ecc58e6cbe329..8b54effb8ac3fb363e79f03e896d6e660810471e 100644
--- a/src/optimisation/adjointOptimisation/adjoint/solvers/adjointSolvers/incompressible/adjointSimple/adjointSimple.C
+++ b/src/optimisation/adjointOptimisation/adjoint/solvers/adjointSolvers/incompressible/adjointSimple/adjointSimple.C
@@ -5,8 +5,8 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2007-2019 PCOpt/NTUA
-    Copyright (C) 2013-2019 FOSS GP
+    Copyright (C) 2007-2020 PCOpt/NTUA
+    Copyright (C) 2013-2020 FOSS GP
     Copyright (C) 2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
@@ -312,9 +312,6 @@ void Foam::adjointSimple::solve()
 {
     if (active_)
     {
-        // Update objective function related quantities
-        objectiveManagerPtr_->updateAndWrite();
-
         // Reset mean fields before solving
         adjointVars_.resetMeanFields();
 
@@ -389,6 +386,15 @@ Foam::sensitivity& Foam::adjointSimple::getSensitivityBase()
 }
 
 
+void Foam::adjointSimple::updatePrimalBasedQuantities()
+{
+    incompressibleAdjointSolver::updatePrimalBasedQuantities();
+
+    // Update objective function related quantities
+    objectiveManagerPtr_->updateAndWrite();
+}
+
+
 bool Foam::adjointSimple::writeData(Ostream& os) const
 {
     os.writeEntry("averageIter", solverControl_().averageIter());
diff --git a/src/optimisation/adjointOptimisation/adjoint/solvers/adjointSolvers/incompressible/adjointSimple/adjointSimple.H b/src/optimisation/adjointOptimisation/adjoint/solvers/adjointSolvers/incompressible/adjointSimple/adjointSimple.H
index 14b348f632f1d3b29ecfc306a9e2805f2119ab62..a5884247be4f59e1dc1323bfa71dfc7c176a9610 100644
--- a/src/optimisation/adjointOptimisation/adjoint/solvers/adjointSolvers/incompressible/adjointSimple/adjointSimple.H
+++ b/src/optimisation/adjointOptimisation/adjoint/solvers/adjointSolvers/incompressible/adjointSimple/adjointSimple.H
@@ -5,8 +5,8 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2007-2019 PCOpt/NTUA
-    Copyright (C) 2013-2019 FOSS GP
+    Copyright (C) 2007-2020 PCOpt/NTUA
+    Copyright (C) 2013-2020 FOSS GP
     Copyright (C) 2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
@@ -168,6 +168,14 @@ public:
             //- Return the base sensitivity object
             virtual sensitivity& getSensitivityBase();
 
+            //- Update primal based quantities
+            //- related to the objective functions.
+            //  Also writes the objective function values to files.
+            //  Written here and not in the postLoop function of the primal
+            //  to make sure we don't pollute the objective files with
+            //  objectives of non-converged linearSearch iterations
+            virtual void updatePrimalBasedQuantities();
+
             //- Write average iteration
             virtual bool writeData(Ostream& os) const;
 };
diff --git a/src/optimisation/adjointOptimisation/adjoint/solvers/primalSolvers/incompressible/incompressiblePrimalSolver/incompressiblePrimalSolver.C b/src/optimisation/adjointOptimisation/adjoint/solvers/primalSolvers/incompressible/incompressiblePrimalSolver/incompressiblePrimalSolver.C
index bfc3a4bc11aed0639949f7142bf2642339d0a749..f1f50530e36e924c371e6c23092a43cdd92c8d83 100644
--- a/src/optimisation/adjointOptimisation/adjoint/solvers/primalSolvers/incompressible/incompressiblePrimalSolver/incompressiblePrimalSolver.C
+++ b/src/optimisation/adjointOptimisation/adjoint/solvers/primalSolvers/incompressible/incompressiblePrimalSolver/incompressiblePrimalSolver.C
@@ -5,8 +5,8 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2007-2019 PCOpt/NTUA
-    Copyright (C) 2013-2019 FOSS GP
+    Copyright (C) 2007-2020 PCOpt/NTUA
+    Copyright (C) 2013-2020 FOSS GP
     Copyright (C) 2019-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
@@ -130,7 +130,7 @@ Foam::incompressiblePrimalSolver::getObjectiveFunctions() const
     {
         adjointSolver& adjoint = *adjointPtr;
 
-        if (adjoint.active() && adjoint.primalSolverName() == solverName_)
+        if (adjoint.primalSolverName() == solverName_)
         {
             PtrList<objective>& managerObjectives =
                 adjoint.getObjectiveManager().getObjectiveFunctions();