diff --git a/applications/test/DynamicList2/Make/files b/applications/test/DynamicList2/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..78b8198c6a0a2af68afbb94d319ad5ba3501664c
--- /dev/null
+++ b/applications/test/DynamicList2/Make/files
@@ -0,0 +1,3 @@
+Test-DynamicList2.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-DynamicList2
diff --git a/applications/test/DynamicList2/Make/options b/applications/test/DynamicList2/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..18e6fe47afacb902cddccf82632772447704fd88
--- /dev/null
+++ b/applications/test/DynamicList2/Make/options
@@ -0,0 +1,2 @@
+/* EXE_INC = */
+/* EXE_LIBS = */
diff --git a/applications/test/DynamicList2/Test-DynamicList2.C b/applications/test/DynamicList2/Test-DynamicList2.C
new file mode 100644
index 0000000000000000000000000000000000000000..b199e67579479386f50b1e98436ed12d7f20f95c
--- /dev/null
+++ b/applications/test/DynamicList2/Test-DynamicList2.C
@@ -0,0 +1,155 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2021 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 <http://www.gnu.org/licenses/>.
+
+Description
+    Test allocation patterns when reading into an existing list.
+
+\*---------------------------------------------------------------------------*/
+
+#include "DynamicList.H"
+#include "DynamicField.H"
+#include "IOstreams.H"
+#include "ITstream.H"
+#include "OTstream.H"
+#include "StringStream.H"
+#include "FlatOutput.H"
+#include "ListOps.H"
+#include "labelRange.H"
+#include "labelIndList.H"
+
+using namespace Foam;
+
+template<class T, int SizeMin>
+void printInfo
+(
+    const word& tag,
+    const DynamicList<T, SizeMin>& list,
+    const bool showSize = true
+)
+{
+    Info<< '<' << tag;
+    if (showSize)
+    {
+        Info<< " size=\"" << list.size()
+            << "\" capacity=\"" << list.capacity() << "\"";
+        if (list.cdata())
+        {
+            Info<< " ptr=\"" << name(list.cdata()) << "\"";
+        }
+        else
+        {
+            Info<< " ptr=\"nullptr\"";
+        }
+    }
+    Info<< '>' << nl << flatOutput(list) << nl
+        << "</" << tag << ">\n" << endl;
+}
+
+
+template<class T, int SizeMin>
+void printInfo
+(
+    const word& tag,
+    const DynamicField<T, SizeMin>& list,
+    const bool showSize = true
+)
+{
+    Info<< '<' << tag;
+    if (showSize)
+    {
+        Info<< " size=\"" << list.size()
+            << "\" capacity=\"" << list.capacity() << "\"";
+        if (list.cdata())
+        {
+            Info<< " ptr=\"" << name(list.cdata()) << "\"";
+        }
+        else
+        {
+            Info<< " ptr=\"nullptr\"";
+        }
+    }
+    Info<< '>' << nl << flatOutput(list) << nl
+        << "</" << tag << ">\n" << endl;
+}
+
+
+template<class T, int SizeMin>
+void readList
+(
+    DynamicList<T, SizeMin>& output,
+    const UList<T>& input
+)
+{
+    OTstream os;
+    os << input;
+    ITstream is("input", os.tokens());
+
+    is >> output;
+}
+
+template<class T, int SizeMin>
+void readList
+(
+    DynamicField<T, SizeMin>& output,
+    const UList<T>& input
+)
+{
+    OTstream os;
+    os << input;
+    ITstream is("input", os.tokens());
+
+    is >> output;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    //
+    {
+        DynamicList<label, 64> list1;
+
+        list1.resize(4);
+        ListOps::identity(list1);
+
+        list1.resize(3);
+        printInfo("", list1);
+
+        // list1.clear();
+        // printInfo("", list1);
+
+        list1.setCapacity(3);
+        printInfo("", list1);
+    }
+
+    Info<< "\nEnd\n";
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedList.H b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H
index 1ae6f228f2592f4d38ad8ded51768520411f096f..23401256b65cc8af325b11d857d8478ae3f44371 100644
--- a/src/OpenFOAM/containers/Bits/PackedList/PackedList.H
+++ b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H
@@ -290,7 +290,7 @@ public:
         inline bool empty() const noexcept;
 
         //- The number of elements that can be stored with reallocating
-        inline label capacity() const;
+        inline label capacity() const noexcept;
 
         //- True if all entries have identical values, and list is non-empty
         bool uniform() const;
@@ -353,17 +353,20 @@ public:
         //- Alter the size of the underlying storage.
         //  The addressed size will be truncated if needed to fit, but will
         //  remain otherwise untouched.
-        inline void setCapacity(const label nElem);
+        inline void setCapacity(const label numElem);
 
         //- Reset addressable list size, does not shrink the allocated size.
         //  Optionally specify a value for new elements.
-        inline void resize(const label nElem, const unsigned int val = 0u);
+        inline void resize(const label numElem, const unsigned int val = 0u);
+
+        //- Currently identical to resize. Subject to future change (Oct-2021)
+        inline void resize_nocopy(const label numElem);
 
         //- Reserve allocation space for at least this size.
         //  Never shrinks the allocated size.
         //  The list size is adjusted as per DynamicList with
         //  SizeInc=0, SizeMult=2, SizeDiv=1
-        inline void reserve(const label nElem);
+        inline void reserve(const label numElem);
 
         //- Clear the list, i.e. set addressable size to zero.
         //  Does not adjust the underlying storage
diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H b/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H
index a525746d39bdb76884982894c57a3137ec3e0567..5d3dbe1dd596aa25841543e26041dfa17fb11dd0 100644
--- a/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H
+++ b/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H
@@ -388,12 +388,22 @@ inline bool Foam::PackedList<Width>::empty() const noexcept
 
 
 template<unsigned Width>
-inline Foam::label Foam::PackedList<Width>::capacity() const
+inline Foam::label Foam::PackedList<Width>::capacity() const noexcept
 {
     return elem_per_block * blocks_.size();
 }
 
 
+template<unsigned Width>
+inline void Foam::PackedList<Width>::resize_nocopy
+(
+    const label numElem
+)
+{
+    this->resize(numElem);
+}
+
+
 template<unsigned Width>
 inline void Foam::PackedList<Width>::resize
 (
@@ -406,7 +416,7 @@ inline void Foam::PackedList<Width>::resize
     const label oldSize = size();
     size_ = newSize;
 
-    if (oldSize < size())
+    if (oldSize < newSize)
     {
         // Fill new elements or newly exposed elements
         if (val)
@@ -438,7 +448,7 @@ inline void Foam::PackedList<Width>::resize
             clear_trailing_bits();
         }
     }
-    else if (size() < oldSize)
+    else if (newSize < oldSize)
     {
         // The list is now shorter than before, so we zero assign the unused
         // blocks and any trailing junk. This costs slightly here, but make
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
index d45d836afdcb47f312590d363efbcda5a553ce23..c97645e21fd7427ca840031f2eec26116a8e359a 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
@@ -46,7 +46,6 @@ SourceFiles
 #define DynamicList_H
 
 #include "List.H"
-#include <type_traits>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -92,6 +91,21 @@ class DynamicList
         template<class ListType>
         inline void assignDynList(const ListType& list);
 
+        //- Alter the size of the underlying storage
+        //  The 'nocopy' option will not attempt to recover old content
+        inline void doCapacity(const bool nocopy, const label len);
+
+        //- Reserve allocation space for at least this size.
+        //  Never shrinks the allocated size, use setCapacity() for that.
+        //  The 'nocopy' option will not attempt to recover old content
+        inline void doReserve(const bool nocopy, const label len);
+
+        //- Reserve allocation space for at least this size.
+        //  Never shrinks the allocated size, use setCapacity() for that.
+        //  The 'nocopy' option will not attempt to recover old content
+        inline void doResize(const bool nocopy, const label len);
+
+
 public:
 
     // Constructors
@@ -121,7 +135,7 @@ public:
 
         //- Construct from a FixedList
         template<unsigned N>
-        inline DynamicList(const FixedList<T, N>& lst);
+        inline explicit DynamicList(const FixedList<T, N>& lst);
 
         //- Construct from an initializer list. Size set to list size.
         inline explicit DynamicList(std::initializer_list<T> lst);
@@ -168,23 +182,49 @@ public:
         //  The addressed size will be truncated if needed to fit, but will
         //  remain otherwise untouched.
         //  Use this or reserve() in combination with append().
-        inline void setCapacity(const label newCapacity);
+        inline void setCapacity(const label len);
 
-        //- Reserve allocation space for at least this size.
-        //  Never shrinks the allocated size, use setCapacity() for that.
-        inline void reserve(const label len);
+        //- Alter the size of the underlying storage,
+        //- \em without retaining old content.
+        //  The addressed size will be truncated if needed to fit, but will
+        //  remain otherwise untouched.
+        inline void setCapacity_nocopy(const label len);
 
-        //- Alter addressable size.
-        //  New space will be allocated if required.
-        inline void resize(const label newLen);
+        //- Change the value for the list capacity directly (ADVANCED, UNSAFE)
+        //- Does not perform any memory management or resizing.
+        inline void setCapacity_unsafe(const label len) noexcept;
 
-        //- Alter addressable size and fill new space with constant value
-        inline void resize(const label newLen, const T& val);
+        //- Reserve allocation space for at least this size, allocating new
+        //- space if required and \em retaining old content.
+        //  Never shrinks the allocated size, use setCapacity() for that.
+        inline void reserve(const label len);
 
-        //- Alias for resize()
+        //- Reserve allocation space for at least this size, allocating new
+        //- space if required \em without retaining old content.
+        //  Never shrinks the allocated size, use setCapacity() for that.
+        inline void reserve_nocopy(const label len);
+
+        //- Alter addressable list size, allocating new space if required
+        //- while \em recovering old content.
+        //  If no reallocation is required, the contents remain untouched.
+        //  Otherwise new entries will be uninitialized.
+        //  Use this to resize the list prior to using the operator[] for
+        //  setting values (as per List usage).
+        inline void resize(const label len);
+
+        //- Alter addressable size and fill new entries with constant value
+        inline void resize(const label len, const T& val);
+
+        //- Alter addressable list size, allocating new space if required
+        //- \em without necessarily recovering old content.
+        //  If no reallocation is required, the contents remain untouched.
+        //  Otherwise all entries will be uninitialized.
+        inline void resize_nocopy(const label len);
+
+        //- Same as resize()
         void setSize(const label n) { this->resize(n); }
 
-        //- Alias for resize()
+        //- Same as resize()
         void setSize(const label n, const T& val) { this->resize(n, val); }
 
         //- Clear the addressed list, i.e. set the size to zero.
@@ -198,6 +238,9 @@ public:
         //  Returns the previous addressable size.
         inline label expandStorage() noexcept;
 
+        //- Shrink the allocated space to the number of elements used.
+        inline void shrinkStorage();
+
         //- Shrink the allocated space to the number of elements used.
         //  Returns a reference to the DynamicList.
         inline DynamicList<T, SizeMin>& shrink();
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
index 047aa3423aecc51003b7b668c97e9eeb49d31598..972317b73540fa1e9d02a185319acf19011b88bc 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
@@ -37,25 +37,101 @@ inline void Foam::DynamicList<T, SizeMin>::assignDynList
     const ListType& list
 )
 {
-    const label newLen = list.size();
+    const label len = list.size();
 
-    if (newLen <= capacity_)
+    if (capacity_ < len)
+    {
+        // Needs more space for the copy operation
+        List<T>::setAddressableSize(capacity_);  // Use entire space
+        List<T>::resize_nocopy(len);
+        capacity_ = List<T>::size();
+    }
+
+    // Perform copy into addressable portion
+    List<T>::setAddressableSize(len);
+    List<T>::operator=(list);
+}
+
+
+template<class T, int SizeMin>
+inline void Foam::DynamicList<T, SizeMin>::doCapacity
+(
+    const bool nocopy,
+    const label newCapacity
+)
+{
+    if (newCapacity == capacity_)
+    {
+        return;
+    }
+
+    // Addressable length, possibly truncated by new capacity
+    const label currLen = min(List<T>::size(), newCapacity);
+
+    // Corner case...
+    if (List<T>::size() == newCapacity)
+    {
+        // Adjust addressable size to trigger proper resizing.
+        // Using (old size+1) is safe since it does not affect the 'overlap'
+        // of old and new addressable regions, but incurs fewew copy
+        // operations than extending to use the current capacity would.
+        List<T>::setAddressableSize(currLen+1);
+    }
+
+    if (nocopy)
     {
-        // Can copy w/o reallocating - adjust addressable size accordingly.
-        List<T>::setAddressableSize(newLen);
-        List<T>::operator=(list);
+        List<T>::resize_nocopy(newCapacity);
     }
     else
     {
-        // Ensure list size consistency prior to copying.
-        List<T>::setAddressableSize(capacity_);
+        List<T>::resize(newCapacity);
+    }
 
-        List<T>::operator=(list);
-        capacity_ = List<T>::size();
+    capacity_ = List<T>::size();
+    List<T>::setAddressableSize(currLen);
+}
+
+
+template<class T, int SizeMin>
+inline void Foam::DynamicList<T, SizeMin>::doReserve
+(
+    const bool nocopy,
+    const label len
+)
+{
+    if (capacity_ < len)
+    {
+        // Preserve addressed size
+        const label currLen = List<T>::size();
+
+        // Increase capacity (doubling)
+        capacity_ = max(SizeMin, max(len, label(2*capacity_)));
+
+        if (nocopy)
+        {
+            List<T>::resize_nocopy(capacity_);
+        }
+        else
+        {
+            List<T>::resize(capacity_);
+        }
+        List<T>::setAddressableSize(currLen);
     }
 }
 
 
+template<class T, int SizeMin>
+inline void Foam::DynamicList<T, SizeMin>::doResize
+(
+    const bool nocopy,
+    const label len
+)
+{
+    this->doReserve(nocopy, len);
+    List<T>::setAddressableSize(len);
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template<class T, int SizeMin>
@@ -72,7 +148,7 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList(const label len)
     List<T>(),
     capacity_(0)
 {
-    reserve(len);
+    reserve_nocopy(len);
 }
 
 
@@ -141,10 +217,9 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
     const FixedList<T, N>& list
 )
 :
-    capacity_(0)
-{
-    this->operator=(list);
-}
+    List<T>(list),
+    capacity_(List<T>::size())
+{}
 
 
 template<class T, int SizeMin>
@@ -201,10 +276,9 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
     List<T>&& lst
 )
 :
-    capacity_(0)
-{
-    transfer(lst);
-}
+    List<T>(std::move(lst)),
+    capacity_(List<T>::size())
+{}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
@@ -227,20 +301,30 @@ Foam::DynamicList<T, SizeMin>::capacity_bytes() const noexcept
 template<class T, int SizeMin>
 inline void Foam::DynamicList<T, SizeMin>::setCapacity
 (
-    const label newCapacity
+    const label len
 )
 {
-    label currLen = List<T>::size();
-    capacity_ = newCapacity;
+    this->doCapacity(false, len);  // nocopy = false
+}
 
-    if (currLen > capacity_)
-    {
-        // Truncate addressed sizes too
-        currLen = capacity_;
-    }
 
-    List<T>::resize(capacity_);
-    List<T>::setAddressableSize(currLen);
+template<class T, int SizeMin>
+inline void Foam::DynamicList<T, SizeMin>::setCapacity_nocopy
+(
+    const label len
+)
+{
+    this->doCapacity(true, len);  // nocopy = true
+}
+
+
+template<class T, int SizeMin>
+inline void Foam::DynamicList<T, SizeMin>::setCapacity_unsafe
+(
+    const label len
+) noexcept
+{
+    capacity_ = len;
 }
 
 
@@ -250,52 +334,55 @@ inline void Foam::DynamicList<T, SizeMin>::reserve
     const label len
 )
 {
-    if (capacity_ < len)
-    {
-        // Increase capacity (doubling)
-        capacity_ = max(SizeMin, max(len, label(2 * capacity_)));
+    this->doReserve(false, len);  // nocopy = false
+}
 
-        // Adjust allocated size, leave addressed size untouched
-        const label currLen = List<T>::size();
-        List<T>::resize(capacity_);
-        List<T>::setAddressableSize(currLen);
-    }
+
+template<class T, int SizeMin>
+inline void Foam::DynamicList<T, SizeMin>::reserve_nocopy
+(
+    const label len
+)
+{
+    this->doReserve(true, len);  // nocopy = true
 }
 
 
 template<class T, int SizeMin>
 inline void Foam::DynamicList<T, SizeMin>::resize
 (
-    const label newLen
+    const label len
 )
 {
-    if (capacity_ < newLen)
-    {
-        // Increase capacity (doubling)
-        capacity_ = max(SizeMin, max(newLen, label(2 * capacity_)));
+    this->doResize(false, len);  // nocopy = false
+}
 
-        List<T>::resize(capacity_);
-    }
 
-    // Adjust addressed size
-    List<T>::setAddressableSize(newLen);
+template<class T, int SizeMin>
+inline void Foam::DynamicList<T, SizeMin>::resize_nocopy
+(
+    const label len
+)
+{
+    this->doResize(true, len);  // nocopy = true
 }
 
 
 template<class T, int SizeMin>
 inline void Foam::DynamicList<T, SizeMin>::resize
 (
-    const label newLen,
+    const label len,
     const T& val
 )
 {
-    label currLen = List<T>::size();
-    resize(newLen);
+    label idx = List<T>::size();
+    resize(len);
 
     // Fill newly exposed with constant value
-    while (currLen < newLen)
+    while (idx < len)
     {
-        this->operator[](currLen++) = val;
+        this->operator[](idx) = val;
+        ++idx;
     }
 }
 
@@ -320,7 +407,7 @@ inline Foam::label Foam::DynamicList<T, SizeMin>::expandStorage() noexcept
 {
     const label currLen = List<T>::size();
 
-    // Allow addressing into the entire list
+    // Address into the entire list
     List<T>::setAddressableSize(capacity_);
 
     return currLen;
@@ -328,20 +415,25 @@ inline Foam::label Foam::DynamicList<T, SizeMin>::expandStorage() noexcept
 
 
 template<class T, int SizeMin>
-inline Foam::DynamicList<T, SizeMin>&
-Foam::DynamicList<T, SizeMin>::shrink()
+inline void Foam::DynamicList<T, SizeMin>::shrinkStorage()
 {
     const label currLen = List<T>::size();
     if (currLen < capacity_)
     {
-        // Use the full list when resizing
-        List<T>::setAddressableSize(capacity_);
+        // Adjust addressable size to trigger proper resizing
+        List<T>::setAddressableSize(currLen+1);
 
-        // Capacity and size are identical
-        capacity_ = currLen;
         List<T>::resize(currLen);
-        // Redundant: List<T>::setAddressableSize(currLen);
+        capacity_ = List<T>::size();
     }
+}
+
+
+template<class T, int SizeMin>
+inline Foam::DynamicList<T, SizeMin>&
+Foam::DynamicList<T, SizeMin>::shrink()
+{
+    this->shrinkStorage();
     return *this;
 }
 
@@ -745,14 +837,7 @@ inline void Foam::DynamicList<T, SizeMin>::operator=
     const FixedList<T, N>& lst
 )
 {
-    const label n = lst.size();
-
-    resize(n);
-
-    for (label i=0; i<n; ++i)
-    {
-        this->operator[](i) = lst[i];  // copy element
-    }
+    assignDynList(lst);
 }
 
 
diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H
index 3a3a6c63ef8146d858eb07cf04f3183e44cf28ae..2120e2ce062fe14abac81d9990ddfc69dad92fd0 100644
--- a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H
+++ b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H
@@ -298,6 +298,9 @@ public:
         //- Dummy function, to make FixedList consistent with List
         inline void resize(const label n);
 
+        //- Dummy function, to make FixedList consistent with List
+        inline void resize_nocopy(const label n);
+
         //- Dummy function, to make FixedList consistent with List
         void setSize(const label n) { this->resize(n); }
 
diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H
index d72b3fb94440dc76dd4e441dea1a16ad4c6af65b..b23bd86ba8aceb7bd4fbf477e5f183d3117407fe 100644
--- a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H
+++ b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H
@@ -346,6 +346,16 @@ inline void Foam::FixedList<T, N>::resize(const label n)
     #endif
 }
 
+
+template<class T, unsigned N>
+inline void Foam::FixedList<T, N>::resize_nocopy(const label n)
+{
+    #ifdef FULLDEBUG
+    checkSize(n);
+    #endif
+}
+
+
 template<class T, unsigned N>
 inline void Foam::FixedList<T, N>::fill(const T& val)
 {
diff --git a/src/OpenFOAM/containers/Lists/List/List.C b/src/OpenFOAM/containers/Lists/List/List.C
index 1a7186cace438ac7491b200c9e533832f9ce902e..858b046e839cbcaa3359ac09e30b77ca25b150de 100644
--- a/src/OpenFOAM/containers/Lists/List/List.C
+++ b/src/OpenFOAM/containers/Lists/List/List.C
@@ -37,54 +37,57 @@ License
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class T>
-void Foam::List<T>::doResize(const label newSize)
+void Foam::List<T>::doResize(const label len)
 {
-    if (newSize < 0)
+    if (len == this->size_)
     {
-        FatalErrorInFunction
-            << "bad size " << newSize
-            << abort(FatalError);
+        return;
     }
 
-    if (newSize != this->size_)
+    if (len > 0)
     {
-        if (newSize > 0)
-        {
-            // With sign-check to avoid spurious -Walloc-size-larger-than
-            T* nv = new T[newSize];
+        // With sign-check to avoid spurious -Walloc-size-larger-than
+        T* nv = new T[len];
 
-            const label overlap = min(this->size_, newSize);
+        const label overlap = min(this->size_, len);
 
-            if (overlap)
+        if (overlap)
+        {
+            #ifdef USEMEMCPY
+            if (is_contiguous<T>::value)
             {
-                #ifdef USEMEMCPY
-                if (is_contiguous<T>::value)
-                {
-                    std::memcpy
-                    (
-                        static_cast<void*>(nv), this->v_, overlap*sizeof(T)
-                    );
-                }
-                else
-                #endif
+                std::memcpy
+                (
+                    static_cast<void*>(nv), this->v_, overlap*sizeof(T)
+                );
+            }
+            else
+            #endif
+            {
+                List_ACCESS(T, *this, vp);
+                for (label i = 0; i < overlap; ++i)
                 {
-                    // No speedup observed for copy assignment on simple types
-                    List_ACCESS(T, *this, vp);
-                    for (label i = 0; i < overlap; ++i)
-                    {
-                        nv[i] = std::move(vp[i]);
-                    }
+                    nv[i] = std::move(vp[i]);
                 }
             }
-
-            clear();
-            this->size_ = newSize;
-            this->v_ = nv;
         }
-        else
+
+        clear();
+        this->size_ = len;
+        this->v_ = nv;
+    }
+    else
+    {
+        // Or only #ifdef FULLDEBUG
+        if (len < 0)
         {
-            clear();
+            FatalErrorInFunction
+                << "bad size " << len
+                << abort(FatalError);
         }
+        // #endif
+
+        clear();
     }
 }
 
@@ -257,7 +260,7 @@ Foam::List<T>::List(List<T>& a, bool reuse)
 {
     if (reuse)
     {
-        // swap content
+        // Steal content
         this->v_ = a.v_;
         a.v_ = nullptr;
         a.size_ = 0;
@@ -435,15 +438,16 @@ Foam::List<T>::~List()
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class T>
-void Foam::List<T>::resize(const label newSize, const T& val)
+void Foam::List<T>::resize(const label len, const T& val)
 {
-    const label oldSize = this->size_;
-    this->doResize(newSize);
+    label idx = this->size_;
+    this->doResize(len);
 
     List_ACCESS(T, *this, vp);
-    for (label i = oldSize; i < newSize; ++i)
+    while (idx < len)
     {
-        vp[i] = val;
+        vp[idx] = val;
+        ++idx;
     }
 }
 
@@ -562,7 +566,7 @@ template<class T>
 template<unsigned N>
 void Foam::List<T>::operator=(const FixedList<T, N>& list)
 {
-    reAlloc(label(N));
+    reAlloc(static_cast<label>(N));
 
     T* iter = this->begin();
 
diff --git a/src/OpenFOAM/containers/Lists/List/List.H b/src/OpenFOAM/containers/Lists/List/List.H
index 4cb9815a42fb2120f2950ac152c6783a26c1d113..c300941d482da9fd46a58dbeec7b48a8a8ca083d 100644
--- a/src/OpenFOAM/containers/Lists/List/List.H
+++ b/src/OpenFOAM/containers/Lists/List/List.H
@@ -43,8 +43,8 @@ SourceFiles
 #ifndef List_H
 #define List_H
 
-#include "UList.H"
 #include "autoPtr.H"
+#include "UList.H"
 #include "SLListFwd.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -83,14 +83,16 @@ class List
         inline void doAlloc();
 
         //- Reallocate list storage to the given size
+        //  Discards old storage (if any). Does not copy old contents
         inline void reAlloc(const label len);
 
-        //- Copy list of given type.
+        //- Copy all list contents
         template<class List2>
         inline void copyList(const List2& list);
 
-        //- Change allocation size - backend for resize.
-        void doResize(const label newSize);
+        //- Change allocation size of List, retaining old contents.
+        //  Backend for resize
+        void doResize(const label len);
 
         //- Construct given begin/end iterators and number of elements
         //  Since the size is provided, the end iterator is actually ignored.
@@ -206,10 +208,16 @@ public:
 
         //- Adjust allocated size of list.
         //  The boolList version fills new memory with false.
-        inline void resize(const label newLen);
+        inline void resize(const label len);
 
         //- Adjust allocated size of list and set val for new elements
-        void resize(const label newLen, const T& val);
+        void resize(const label len, const T& val);
+
+        //- Adjust allocated size of list \b without necessarily
+        //  retaining old content.
+        //  If no reallocation is required, the contents remain untouched.
+        //  Otherwise the contents will be uninitialized.
+        inline void resize_nocopy(const label len);
 
         //- Alias for resize()
         void setSize(const label n) { this->resize(n); }
@@ -221,15 +229,19 @@ public:
         // Edit
 
             //- Append an element at the end of the list
+            //  If this is frequently required, consider a DynamicList
             inline void append(const T& val);
 
             //- Move append an element at the end of the list
+            //  If this is frequently required, consider a DynamicList
             inline void append(T&& val);
 
             //- Append a List to the end of this list
+            //  If this is frequently required, consider a DynamicList
             inline void append(const UList<T>& list);
 
             //- Append IndirectList contents at the end of this list
+            //  If this is frequently required, consider a DynamicList
             template<class Addr>
             inline void append(const IndirectListBase<T, Addr>& list);
 
diff --git a/src/OpenFOAM/containers/Lists/List/ListI.H b/src/OpenFOAM/containers/Lists/List/ListI.H
index 7249511c1001f9cefc725f3264736e94360b6e6b..4063c27bcffb965c63d5299f865af0d83711aa92 100644
--- a/src/OpenFOAM/containers/Lists/List/ListI.H
+++ b/src/OpenFOAM/containers/Lists/List/ListI.H
@@ -120,14 +120,13 @@ inline void Foam::List<T>::clear()
         delete[] this->v_;
         this->v_ = nullptr;
     }
-
     this->size_ = 0;
 }
 
 
 namespace Foam
 {
-    // Template specialization for bool. Fills with false
+    // Template specialization for bool. Fills new entries with false
     template<>
     inline void List<bool>::resize(const label newLen)
     {
@@ -137,9 +136,16 @@ namespace Foam
 
 
 template<class T>
-inline void Foam::List<T>::resize(const label newLen)
+inline void Foam::List<T>::resize(const label len)
 {
-    this->doResize(newLen);
+    this->doResize(len);
+}
+
+
+template<class T>
+inline void Foam::List<T>::resize_nocopy(const label len)
+{
+    this->reAlloc(len);
 }
 
 
@@ -168,7 +174,10 @@ inline T& Foam::List<T>::newElmt(const label i)
 template<class T>
 inline void Foam::List<T>::append(const T& val)
 {
-    resize(this->size() + 1, val);  // copy element
+    const label idx = this->size();
+    resize(idx + 1);
+
+    this->operator[](idx) = val;  // copy element
 }
 
 
diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H
index 3c0131a62379d472759696f505c9b3951d86abb5..13fee326f20f1b164201b4ead3014a2ce2f229e5 100644
--- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H
+++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H
@@ -114,11 +114,7 @@ public:
 
     // Sizing
 
-        //- Alter the size of the underlying storage.
-        inline void setCapacity(const label newCapacity);
-
         //- Reserve allocation space for at least this size.
-        //  Never shrinks the allocated size, use setCapacity() for that.
         inline void reserve(const label len);
 
         //- Alter the addressed list size.
diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H
index 950b5ad6278591bced8a80ce93695b607299e78a..b8973ff4b6f3c405b496aab8f6e3dfb5553867f6 100644
--- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H
+++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H
@@ -97,33 +97,17 @@ inline const T* Foam::PtrDynList<T, SizeMin>::get(const label i) const
 }
 
 
-template<class T, int SizeMin>
-inline void Foam::PtrDynList<T, SizeMin>::setCapacity(const label newCapacity)
-{
-    label currLen = PtrList<T>::size();
-    capacity_ = newCapacity;
-
-    if (currLen > capacity_)
-    {
-        // Truncate addressed sizes too
-        currLen = capacity_;
-    }
-
-    PtrList<T>::resize(capacity_);
-    PtrList<T>::setAddressableSize(currLen);
-}
-
-
 template<class T, int SizeMin>
 inline void Foam::PtrDynList<T, SizeMin>::reserve(const label len)
 {
     if (capacity_ < len)
     {
+        // Preserve addressed size
+        const label currLen = PtrList<T>::size();
+
         // Increase capacity (doubling)
-        capacity_ = max(SizeMin, max(len, label(2 * capacity_)));
+        capacity_ = max(SizeMin, max(len, label(2*capacity_)));
 
-        // Adjust allocated size, leave addressed size untouched
-        const label currLen = PtrList<T>::size();
         PtrList<T>::resize(capacity_);
         PtrList<T>::setAddressableSize(currLen);
     }
@@ -140,7 +124,7 @@ inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
     if (capacity_ < newLen)
     {
         // Increase capacity (doubling)
-        capacity_ = max(SizeMin, max(newLen, label(2 * capacity_)));
+        capacity_ = max(SizeMin, max(newLen, label(2*capacity_)));
 
         PtrList<T>::resize(capacity_);
     }
@@ -193,13 +177,11 @@ inline void Foam::PtrDynList<T, SizeMin>::shrink()
     const label currLen = PtrList<T>::size();
     if (currLen < capacity_)
     {
-        // Use the full list when resizing
-        PtrList<T>::setAddressableSize(capacity_);
+        // Adjust addressable size to trigger proper resizing
+        PtrList<T>::setAddressableSize(currLen+1);
 
-        // Capacity and size are identical
-        capacity_ = currLen;
         PtrList<T>::resize(currLen);
-        // Redundant: PtrList<T>::setAddressableSize(currLen);
+        capacity_ = PtrList<T>::size();
     }
 }
 
diff --git a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.C b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.C
index 64af6c6b6de9c48c3b2458b8e31ddddb65212359..a72ec9461a619e6df4ef4a9b714fb3e2fdc4a7d3 100644
--- a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.C
+++ b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018-2019 OpenCFD Ltd.
+    Copyright (C) 2018-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -66,6 +66,19 @@ Foam::label Foam::Detail::PtrListDetail<T>::findNull() const
 }
 
 
+template<class T>
+void Foam::Detail::PtrListDetail<T>::setNull()
+{
+    List<T*>& ptrs = *this;
+    const label len = ptrs.size();
+
+    for (label i=0; i<len; ++i)
+    {
+        ptrs[i] = nullptr;
+    }
+}
+
+
 template<class T>
 void Foam::Detail::PtrListDetail<T>::free()
 {
diff --git a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.H b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.H
index 811ae9d18f4d4723e5e33d3ef8064086fb921224..8e7ccf43722fa133197e754e2050fd52544f7b4f 100644
--- a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.H
+++ b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.H
@@ -95,6 +95,9 @@ public:
         //- Locate the first null entry, -1 if there are not any
         label findNull() const;
 
+        //- Assign all pointers to nullptr, without deleting.
+        void setNull();
+
         //- Delete the allocated entries, but retain the list size.
         void free();
 
@@ -129,6 +132,9 @@ public:
         void setSize(const label) = delete;
         void setSize(const label, const T&) = delete;
         void setSize(const label, const T*) = delete;
+
+        // Too fragile or dangerous
+        void resize_nocopy(const label) = delete;
 };
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H
index 517d292afd5550a0a183d6f9846dbd375f91df84..1293335420b3536a16f98611446a3da154848e91 100644
--- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H
+++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H
@@ -39,7 +39,7 @@ SourceFiles
 #define DynamicField_H
 
 #include "Field.H"
-#include <type_traits>
+#include "DynamicList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -78,6 +78,21 @@ class DynamicField
         template<class ListType>
         inline void assignDynList(const ListType& list);
 
+        //- Alter the size of the underlying storage
+        //  The 'nocopy' option will not attempt to recover old content
+        inline void doCapacity(const bool nocopy, const label len);
+
+        //- Reserve allocation space for at least this size.
+        //  Never shrinks the allocated size, use setCapacity() for that.
+        //  The 'nocopy' option will not attempt to recover old content
+        inline void doReserve(const bool nocopy, const label len);
+
+        //- Reserve allocation space for at least this size.
+        //  Never shrinks the allocated size, use setCapacity() for that.
+        //  The 'nocopy' option will not attempt to recover old content
+        inline void doResize(const bool nocopy, const label len);
+
+
 public:
 
     // Static Member Functions
@@ -128,6 +143,10 @@ public:
         template<int AnySizeMin>
         inline DynamicField(DynamicField<T, AnySizeMin>&& content);
 
+        //- Move construct from DynamicList
+        template<int AnySizeMin>
+        inline DynamicField(DynamicList<T, AnySizeMin>&& list);
+
         //- Construct by 1 to 1 mapping from the given field
         inline DynamicField
         (
@@ -178,18 +197,44 @@ public:
         //  The addressed size will be truncated if needed to fit, but will
         //  remain otherwise untouched.
         //  Use this or reserve() in combination with append().
-        inline void setCapacity(const label newCapacity);
+        inline void setCapacity(const label len);
 
-        //- Reserve allocation space for at least this size.
+        //- Alter the size of the underlying storage,
+        //- \em without retaining old content.
+        //  The addressed size will be truncated if needed to fit, but will
+        //  remain otherwise untouched.
+        inline void setCapacity_nocopy(const label len);
+
+        //- Change the value for the list capacity directly (ADVANCED, UNSAFE)
+        //- Does not perform any memory management or resizing.
+        inline void setCapacity_unsafe(const label len) noexcept;
+
+        //- Reserve allocation space for at least this size, allocating new
+        //- space if required and \em retaining old content.
         //  Never shrinks the allocated size, use setCapacity() for that.
         inline void reserve(const label len);
 
-        //- Alter addressable size.
-        //  New space will be allocated if required.
-        inline void resize(const label newLen);
+        //- Reserve allocation space for at least this size, allocating new
+        //- space if required \em without retaining old content.
+        //  Never shrinks the allocated size, use setCapacity() for that.
+        inline void reserve_nocopy(const label len);
+
+        //- Alter addressable list size, allocating new space if required
+        //- while \em recovering old content.
+        //  If no reallocation is required, the contents remain untouched.
+        //  Otherwise new entries will be uninitialized.
+        //  Use this to resize the list prior to using the operator[] for
+        //  setting values (as per List usage).
+        inline void resize(const label len);
 
         //- Alter addressable size and fill new space with constant value
-        inline void resize(const label newLen, const T& val);
+        inline void resize(const label len, const T& val);
+
+        //- Alter addressable list size, allocating new space if required
+        //- \em without necessarily recovering old content.
+        //  If no reallocation is required, the contents remain untouched.
+        //  Otherwise all entries will be uninitialized.
+        inline void resize_nocopy(const label len);
 
         //- Alias for resize()
         void setSize(const label n) { this->resize(n); }
@@ -208,6 +253,9 @@ public:
         //  Returns the previous addressable size.
         inline label expandStorage() noexcept;
 
+        //- Shrink the allocated space to the number of elements used.
+        inline void shrinkStorage();
+
         //- Shrink the allocated space to the number of elements used.
         //  Returns a reference to the DynamicField.
         inline DynamicField<T, SizeMin>& shrink();
@@ -219,6 +267,10 @@ public:
         template<int AnySizeMin>
         inline void swap(DynamicField<T, AnySizeMin>& other);
 
+        //- Swap content with DynamicList, independent of sizing parameter
+        template<int AnySizeMin>
+        inline void swap(DynamicList<T, AnySizeMin>& other);
+
         //- Transfer the parameter contents into this
         inline void transfer(List<T>& list);
 
@@ -271,6 +323,10 @@ public:
         //- Move assignment
         inline void operator=(List<T>&& list);
 
+        //- Move assignment
+        template<int AnySizeMin>
+        inline void operator=(DynamicList<T, AnySizeMin>&& list);
+
         //- Move assignment
         inline void operator=(DynamicField<T, SizeMin>&& list);
 
diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H
index 8d41f1e36351aba021296231e6fe6b48ea3e8f68..7a3da8641650194e761d84a20921a2c5a29cb13e 100644
--- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H
+++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H
@@ -35,25 +35,97 @@ inline void Foam::DynamicField<T, SizeMin>::assignDynList
     const ListType& list
 )
 {
-    const label newLen = list.size();
+    const label len = list.size();
 
-    if (newLen <= capacity_)
+    if (capacity_ < len)
+    {
+        // Needs more space for the copy operation
+        List<T>::setAddressableSize(capacity_);  // Use entire space
+        List<T>::resize_nocopy(len);
+        capacity_ = List<T>::size();
+    }
+
+    // Perform copy into addressable portion
+    List<T>::setAddressableSize(len);
+    List<T>::operator=(list);
+}
+
+
+template<class T, int SizeMin>
+inline void Foam::DynamicField<T, SizeMin>::doCapacity
+(
+    const bool nocopy,
+    const label newCapacity
+)
+{
+    if (newCapacity == capacity_)
+    {
+        return;
+    }
+
+    // Addressable length, possibly truncated by new capacity
+    const label currLen = min(List<T>::size(), newCapacity);
+
+    // Corner case - see comments in DynamicList doCapacity
+    if (List<T>::size() == newCapacity)
+    {
+        List<T>::setAddressableSize(currLen+1);
+    }
+
+    if (nocopy)
     {
-        // Can copy w/o reallocating - adjust addressable size accordingly.
-        List<T>::setAddressableSize(newLen);
-        List<T>::operator=(list);
+        List<T>::resize_nocopy(newCapacity);
     }
     else
     {
-        // Ensure list size consistency prior to copying.
-        List<T>::setAddressableSize(capacity_);
+        List<T>::resize(newCapacity);
+    }
 
-        List<T>::operator=(list);
-        capacity_ = List<T>::size();
+    capacity_ = List<T>::size();
+    List<T>::setAddressableSize(currLen);
+}
+
+
+template<class T, int SizeMin>
+inline void Foam::DynamicField<T, SizeMin>::doReserve
+(
+    const bool nocopy,
+    const label len
+)
+{
+    if (capacity_ < len)
+    {
+        // Preserve addressed size
+        const label currLen = List<T>::size();
+
+        // Increase capacity (doubling)
+        capacity_ = max(SizeMin, max(len, label(2*capacity_)));
+
+        if (nocopy)
+        {
+            List<T>::resize_nocopy(capacity_);
+        }
+        else
+        {
+            List<T>::resize(capacity_);
+        }
+        List<T>::setAddressableSize(currLen);
     }
 }
 
 
+template<class T, int SizeMin>
+inline void Foam::DynamicField<T, SizeMin>::doResize
+(
+    const bool nocopy,
+    const label len
+)
+{
+    this->doReserve(nocopy, len);
+    List<T>::setAddressableSize(len);
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template<class T, int SizeMin>
@@ -70,7 +142,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField(const label len)
     Field<T>(),
     capacity_(0)
 {
-    reserve(len);
+    reserve_nocopy(len);
 }
 
 
@@ -155,6 +227,20 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
 {}
 
 
+template<class T, int SizeMin>
+template<int AnySizeMin>
+inline Foam::DynamicField<T, SizeMin>::DynamicField
+(
+    DynamicList<T, AnySizeMin>&& list
+)
+:
+    Field<T>(),
+    capacity_(0)
+{
+    transfer(list);
+}
+
+
 template<class T, int SizeMin>
 inline Foam::DynamicField<T, SizeMin>::DynamicField
 (
@@ -255,20 +341,30 @@ Foam::DynamicField<T, SizeMin>::capacity_bytes() const noexcept
 template<class T, int SizeMin>
 inline void Foam::DynamicField<T, SizeMin>::setCapacity
 (
-    const label newCapacity
+    const label len
 )
 {
-    label currLen = List<T>::size();
-    capacity_ = newCapacity;
+    this->doCapacity(false, len);  // nocopy = false
+}
 
-    if (currLen > capacity_)
-    {
-        // Truncate addressed sizes too
-        currLen = capacity_;
-    }
 
-    List<T>::resize(capacity_);
-    List<T>::setAddressableSize(currLen);
+template<class T, int SizeMin>
+inline void Foam::DynamicField<T, SizeMin>::setCapacity_nocopy
+(
+    const label len
+)
+{
+    this->doCapacity(true, len);  // nocopy = true
+}
+
+
+template<class T, int SizeMin>
+inline void Foam::DynamicField<T, SizeMin>::setCapacity_unsafe
+(
+    const label len
+) noexcept
+{
+    capacity_ = len;
 }
 
 
@@ -278,52 +374,55 @@ inline void Foam::DynamicField<T, SizeMin>::reserve
     const label len
 )
 {
-    if (capacity_ < len)
-    {
-        // Increase capacity (doubling)
-        capacity_ = max(SizeMin, max(len, label(2 * capacity_)));
+    this->doReserve(false, len);  // nocopy = false
+}
 
-        // Adjust allocated size, leave addressed size untouched
-        const label currLen = List<T>::size();
-        List<T>::resize(capacity_);
-        List<T>::setAddressableSize(currLen);
-    }
+
+template<class T, int SizeMin>
+inline void Foam::DynamicField<T, SizeMin>::reserve_nocopy
+(
+    const label len
+)
+{
+    this->doReserve(true, len);  // nocopy = true
 }
 
 
 template<class T, int SizeMin>
 inline void Foam::DynamicField<T, SizeMin>::resize
 (
-    const label newLen
+    const label len
 )
 {
-    if (capacity_ < newLen)
-    {
-        // Increase capacity (doubling)
-        capacity_ = max(SizeMin, max(newLen, label(2 * capacity_)));
+    this->doResize(false, len);  // nocopy = false
+}
 
-        List<T>::resize(capacity_);
-    }
 
-    // Adjust addressed size
-    List<T>::setAddressableSize(newLen);
+template<class T, int SizeMin>
+inline void Foam::DynamicField<T, SizeMin>::resize_nocopy
+(
+    const label len
+)
+{
+    this->doResize(true, len);  // nocopy = true
 }
 
 
 template<class T, int SizeMin>
 inline void Foam::DynamicField<T, SizeMin>::resize
 (
-    const label newLen,
+    const label len,
     const T& val
 )
 {
-    label currLen = List<T>::size();
-    resize(newLen);
+    label idx = List<T>::size();
+    resize(len);
 
     // Fill newly exposed with constant value
-    while (currLen < newLen)
+    while (idx < len)
     {
-        this->operator[](currLen++) = val;
+        this->operator[](idx) = val;
+        ++idx;
     }
 }
 
@@ -356,20 +455,26 @@ inline Foam::label Foam::DynamicField<T, SizeMin>::expandStorage() noexcept
 
 
 template<class T, int SizeMin>
-inline Foam::DynamicField<T, SizeMin>&
-Foam::DynamicField<T, SizeMin>::shrink()
+inline void Foam::DynamicField<T, SizeMin>::shrinkStorage()
 {
-    const label currLen = Field<T>::size();
+    const label currLen = List<T>::size();
+
     if (currLen < capacity_)
     {
-        // Use the full list when resizing
-        List<T>::setAddressableSize(capacity_);
+        // Adjust addressable size to trigger proper resizing
+        List<T>::setAddressableSize(currLen+1);
 
-        // Capacity and size are identical
-        capacity_ = currLen;
         List<T>::resize(currLen);
-        // Redundant: List<T>::setAddressableSize(currLen);
+        capacity_ = List<T>::size();
     }
+}
+
+
+template<class T, int SizeMin>
+inline Foam::DynamicField<T, SizeMin>&
+Foam::DynamicField<T, SizeMin>::shrink()
+{
+    this->shrinkStorage();
     return *this;
 }
 
@@ -395,6 +500,34 @@ inline void Foam::DynamicField<T, SizeMin>::swap
 }
 
 
+template<class T, int SizeMin>
+template<int AnySizeMin>
+inline void Foam::DynamicField<T, SizeMin>::swap
+(
+    DynamicList<T, AnySizeMin>& other
+)
+{
+    auto& self = (*this);
+
+    // ... not yet needed:
+    // Cannot compare 'this' for different types, so use cdata()
+    if (self.cdata() == other.cdata())
+    {
+        return;  // Self-swap is a no-op
+    }
+
+    // Swap storage and addressable size
+    UList<T>::swap(other);
+
+    // Swap capacity
+    const label oldCap = self.capacity();
+    const label newCap = other.capacity();
+
+    self.setCapacity_unsafe(newCap);
+    other.setCapacity_unsafe(oldCap);
+}
+
+
 template<class T, int SizeMin>
 inline void Foam::DynamicField<T, SizeMin>::transfer(List<T>& list)
 {
@@ -421,7 +554,7 @@ inline void Foam::DynamicField<T, SizeMin>::transfer
     // clear addressing and storage for old list.
     capacity_ = list.capacity();
 
-    Field<T>::transfer(static_cast<Field<T>&>(list));
+    Field<T>::transfer(static_cast<List<T>&>(list));
     list.clearStorage();  // Ensure capacity=0
 }
 
@@ -443,7 +576,7 @@ inline void Foam::DynamicField<T, SizeMin>::transfer
     // clear addressing and storage for old list.
     capacity_ = list.capacity();
 
-    Field<T>::transfer(static_cast<Field<T>&>(list));
+    Field<T>::transfer(static_cast<List<T>&>(list));
     list.clearStorage();  // Ensure capacity=0
 }
 
@@ -531,7 +664,7 @@ inline T& Foam::DynamicField<T, SizeMin>::operator()
     const label i
 )
 {
-    if (i >= Field<T>::size())
+    if (i >= List<T>::size())
     {
         resize(i + 1);
     }
@@ -616,6 +749,17 @@ inline void Foam::DynamicField<T, SizeMin>::operator=
 }
 
 
+template<class T, int SizeMin>
+template<int AnySizeMin>
+inline void Foam::DynamicField<T, SizeMin>::operator=
+(
+    DynamicList<T, AnySizeMin>&& list
+)
+{
+    transfer(list);
+}
+
+
 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
 
 template<class T, int SizeMin>
@@ -624,13 +768,14 @@ inline Foam::Istream& Foam::DynamicField<T, SizeMin>::readList
     Istream& is
 )
 {
-    DynamicField<T, SizeMin>& rhs = *this;
+    // Use DynamicList::readList for reading DynamicField.
+    // The logic should be the same and this avoids duplicate code
 
-    // Use entire storage - ie, resize(capacity())
-    (void) rhs.expandStorage();
+    DynamicList<T, SizeMin> list;
+    (*this).swap(list);
 
-    is >> static_cast<Field<T>&>(rhs);
-    rhs.capacity_ = rhs.Field<T>::size();
+    list.readList(is);
+    (*this).swap(list);
 
     return is;
 }
diff --git a/src/OpenFOAM/matrices/Matrix/Matrix.C b/src/OpenFOAM/matrices/Matrix/Matrix.C
index 7de050fc9e7a045faa213120de553582998f1030..d27013e8aeca8d6d7d9113112bfb00630a804fc0 100644
--- a/src/OpenFOAM/matrices/Matrix/Matrix.C
+++ b/src/OpenFOAM/matrices/Matrix/Matrix.C
@@ -345,6 +345,36 @@ void Foam::Matrix<Form, Type>::resize(const label m, const label n)
 }
 
 
+template<class Form, class Type>
+void Foam::Matrix<Form, Type>::resize_nocopy(const label mrow, const label ncol)
+{
+    if (mrow == mRows_ && ncol == nCols_)
+    {
+        return;
+    }
+
+    const label oldLen = (mRows_ * nCols_);
+
+    const label newLen = (mrow * ncol);
+
+    if (oldLen == newLen)
+    {
+        // Shallow resize is enough
+        mRows_ = mrow;
+        nCols_ = ncol;
+    }
+    else
+    {
+        this->clear();
+
+        mRows_ = mrow;
+        nCols_ = ncol;
+
+        this->doAlloc();
+    }
+}
+
+
 template<class Form, class Type>
 void Foam::Matrix<Form, Type>::round(const scalar tol)
 {
diff --git a/src/OpenFOAM/matrices/Matrix/Matrix.H b/src/OpenFOAM/matrices/Matrix/Matrix.H
index 24eb0bd7e6bbee218223ecece66ec813086416bc..c11d7a27ec0f544a4abe26526f2ea608dab4f53c 100644
--- a/src/OpenFOAM/matrices/Matrix/Matrix.H
+++ b/src/OpenFOAM/matrices/Matrix/Matrix.H
@@ -357,6 +357,9 @@ public:
         //- Change Matrix dimensions, preserving the elements
         void resize(const label m, const label n);
 
+        //- Change Matrix dimensions \em without preserving existing content
+        void resize_nocopy(const label mrow, const label ncol);
+
         //- Change Matrix dimensions, preserving the elements
         inline void setSize(const label m, const label n);
 
@@ -366,6 +369,7 @@ public:
         //- Round elements with magnitude smaller than tol (SMALL) to zero
         void round(const scalar tol = SMALL);
 
+
     // Operations
 
         //- Return (conjugate) transpose of Matrix