From a64357983c93c3983c09830d07a6c56b3cb3581d Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Mon, 22 May 2023 11:27:46 +0200
Subject: [PATCH] BUG: uniformMixed fields not always full initialised (#2703)

- calling the mixed BC dictionary construct with NO_READ leaves the
  fields properly sized, but not initialised.

ENH: add mixed BC constructor zero initialise
---
 .../basic/mixed/mixedFaPatchField.C              | 15 +++++++++++++++
 .../basic/mixed/mixedFaPatchField.H              |  9 +++++++++
 .../uniformMixed/uniformMixedFaPatchField.C      |  5 ++++-
 .../basic/mixed/mixedFvPatchField.C              | 16 ++++++++++++++++
 .../basic/mixed/mixedFvPatchField.H              |  9 +++++++++
 .../mappedMixed/mappedMixedFvPatchField.C        |  7 +++++--
 .../uniformMixed/uniformMixedFvPatchField.C      |  5 ++++-
 7 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/src/finiteArea/fields/faPatchFields/basic/mixed/mixedFaPatchField.C b/src/finiteArea/fields/faPatchFields/basic/mixed/mixedFaPatchField.C
index bcc81e72e7f..c90344dd19d 100644
--- a/src/finiteArea/fields/faPatchFields/basic/mixed/mixedFaPatchField.C
+++ b/src/finiteArea/fields/faPatchFields/basic/mixed/mixedFaPatchField.C
@@ -93,6 +93,21 @@ Foam::mixedFaPatchField<Type>::mixedFaPatchField
 {}
 
 
+template<class Type>
+Foam::mixedFaPatchField<Type>::mixedFaPatchField
+(
+    const faPatch& p,
+    const DimensionedField<Type, areaMesh>& iF,
+    const Foam::zero
+)
+:
+    faPatchField<Type>(p, iF),
+    refValue_(p.size(), Zero),
+    refGrad_(p.size(), Zero),
+    valueFraction_(p.size(), Zero)
+{}
+
+
 template<class Type>
 Foam::mixedFaPatchField<Type>::mixedFaPatchField
 (
diff --git a/src/finiteArea/fields/faPatchFields/basic/mixed/mixedFaPatchField.H b/src/finiteArea/fields/faPatchFields/basic/mixed/mixedFaPatchField.H
index 5109e649208..f4d0bdbab50 100644
--- a/src/finiteArea/fields/faPatchFields/basic/mixed/mixedFaPatchField.H
+++ b/src/finiteArea/fields/faPatchFields/basic/mixed/mixedFaPatchField.H
@@ -109,6 +109,15 @@ public:
             const DimensionedField<Type, areaMesh>&
         );
 
+        //- Construct from patch and internal field,
+        //- initialise as zero-gradient
+        mixedFaPatchField
+        (
+            const faPatch&,
+            const DimensionedField<Type, areaMesh>&,
+            const Foam::zero
+        );
+
         //- Construct from patch, internal field and dictionary
         mixedFaPatchField
         (
diff --git a/src/finiteArea/fields/faPatchFields/derived/uniformMixed/uniformMixedFaPatchField.C b/src/finiteArea/fields/faPatchFields/derived/uniformMixed/uniformMixedFaPatchField.C
index 82ee838495f..cf9c1dd88d3 100644
--- a/src/finiteArea/fields/faPatchFields/derived/uniformMixed/uniformMixedFaPatchField.C
+++ b/src/finiteArea/fields/faPatchFields/derived/uniformMixed/uniformMixedFaPatchField.C
@@ -66,7 +66,8 @@ Foam::uniformMixedFaPatchField<Type>::uniformMixedFaPatchField
     const dictionary& dict
 )
 :
-    mixedFaPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ),
+    // Bypass dict constructor, default initialise as zero-gradient
+    mixedFaPatchField<Type>(p, iF, Foam::zero{}),
     refValueFunc_
     (
         Function1<Type>::NewIfPresent
@@ -87,6 +88,8 @@ Foam::uniformMixedFaPatchField<Type>::uniformMixedFaPatchField
     ),
     valueFractionFunc_(nullptr)
 {
+    faPatchFieldBase::readDict(dict);  // Consistent with a dict constructor
+
     if (refValueFunc_)
     {
         if (refGradFunc_)
diff --git a/src/finiteVolume/fields/fvPatchFields/basic/mixed/mixedFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/basic/mixed/mixedFvPatchField.C
index 80dd0a97182..812bd194716 100644
--- a/src/finiteVolume/fields/fvPatchFields/basic/mixed/mixedFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/basic/mixed/mixedFvPatchField.C
@@ -94,6 +94,22 @@ Foam::mixedFvPatchField<Type>::mixedFvPatchField
 {}
 
 
+template<class Type>
+Foam::mixedFvPatchField<Type>::mixedFvPatchField
+(
+    const fvPatch& p,
+    const DimensionedField<Type, volMesh>& iF,
+    const Foam::zero
+)
+:
+    fvPatchField<Type>(p, iF),
+    refValue_(p.size(), Zero),
+    refGrad_(p.size(), Zero),
+    valueFraction_(p.size(), Zero),
+    source_(p.size(), Zero)
+{}
+
+
 template<class Type>
 Foam::mixedFvPatchField<Type>::mixedFvPatchField
 (
diff --git a/src/finiteVolume/fields/fvPatchFields/basic/mixed/mixedFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/basic/mixed/mixedFvPatchField.H
index 143df47f4fa..7c43a6ca226 100644
--- a/src/finiteVolume/fields/fvPatchFields/basic/mixed/mixedFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/basic/mixed/mixedFvPatchField.H
@@ -133,6 +133,15 @@ public:
             const DimensionedField<Type, volMesh>&
         );
 
+        //- Construct from patch and internal field,
+        //- initialise as zero-gradient
+        mixedFvPatchField
+        (
+            const fvPatch&,
+            const DimensionedField<Type, volMesh>&,
+            const Foam::zero
+        );
+
         //- Construct from patch, internal field and dictionary
         mixedFvPatchField
         (
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedMixed/mappedMixedFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/mappedMixed/mappedMixedFvPatchField.C
index da6886a5054..4249c7d443f 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/mappedMixed/mappedMixedFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedMixed/mappedMixedFvPatchField.C
@@ -61,8 +61,9 @@ Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
     const dictionary& dict
 )
 :
-    // Reading of mixed entries handled later...
-    mixedFvPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ),
+    // Bypass dictionary constructor (all reading handled later)
+    // but cannot use NO_READ since will still trigger an evaluate()
+    mixedFvPatchField<Type>(p, iF),
     mappedPatchFieldBase<Type>
     (
         mappedFixedValueFvPatchField<Type>::mapper(p, iF),
@@ -71,6 +72,8 @@ Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
     ),
     weightFieldName_(dict.getOrDefault<word>("weightField", word::null))
 {
+    fvPatchFieldBase::readDict(dict);  // Consistent with a dict constructor
+
     this->readValueEntry(dict, IOobjectOption::MUST_READ);
 
     if (this->readMixedEntries(dict))
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/uniformMixed/uniformMixedFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/uniformMixed/uniformMixedFvPatchField.C
index c73934f4ec1..ca2817148a9 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/uniformMixed/uniformMixedFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/uniformMixed/uniformMixedFvPatchField.C
@@ -66,7 +66,8 @@ Foam::uniformMixedFvPatchField<Type>::uniformMixedFvPatchField
     const dictionary& dict
 )
 :
-    mixedFvPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ),
+    // Bypass dict constructor, default initialise as zero-gradient
+    mixedFvPatchField<Type>(p, iF, Foam::zero{}),
     refValueFunc_
     (
         PatchFunction1<Type>::NewIfPresent(p.patch(), "uniformValue", dict)
@@ -77,6 +78,8 @@ Foam::uniformMixedFvPatchField<Type>::uniformMixedFvPatchField
     ),
     valueFractionFunc_(nullptr)
 {
+    fvPatchFieldBase::readDict(dict);  // Consistent with a dict constructor
+
     if (refValueFunc_)
     {
         if (refGradFunc_)
-- 
GitLab