diff --git a/examples/groupless/basic/reader.cpp b/examples/groupless/basic/reader.cpp
index 2f46aa7ad53bd277539a57bf67b26fc09ea1a889..c65cbe3a31da986f361e1abcb51c731dde146074 100644
--- a/examples/groupless/basic/reader.cpp
+++ b/examples/groupless/basic/reader.cpp
@@ -104,8 +104,7 @@ int main(int argc, char *argv[])
                                          "'myDoubles' in input file\n");
 
         // ? how do we know about the type? std::string varNice->m_Type
-        uint64_t gdim =
-            varNice->m_Shape[0]; // ?member var or member func?
+        uint64_t gdim = varNice->m_Shape[0]; // ?member var or member func?
         uint64_t ldim = gdim / nproc;
         uint64_t offs = rank * ldim;
         if (rank == nproc - 1)
diff --git a/examples/groupless/compound/reader.cpp b/examples/groupless/compound/reader.cpp
index 9181d50f8d095ff452dba96af7e7f66ecc23e4eb..aa6ff6d3168ec0d05065f5eb832ced3a908f24b5 100644
--- a/examples/groupless/compound/reader.cpp
+++ b/examples/groupless/compound/reader.cpp
@@ -127,8 +127,7 @@ int main(int argc, char *argv[])
                                          "'myDoubles' in input file\n");
 
         // ? how do we know about the type? std::string varNice->m_Type
-        uint64_t gdim =
-            varNice->m_Shape[0]; // ?member var or member func?
+        uint64_t gdim = varNice->m_Shape[0]; // ?member var or member func?
         uint64_t ldim = gdim / nproc;
         uint64_t offs = rank * ldim;
         if (rank == nproc - 1)
diff --git a/examples/groupless/multistep/reader_allsteps.cpp b/examples/groupless/multistep/reader_allsteps.cpp
index 5f4bda072e3e9a9c8502ff047b1ce5880d5ac4d7..f2a4fdf2689160ab1279f5d6ea120aa57b52213c 100644
--- a/examples/groupless/multistep/reader_allsteps.cpp
+++ b/examples/groupless/multistep/reader_allsteps.cpp
@@ -179,7 +179,9 @@ int main(int argc, char *argv[])
         Print2DArray(Nparts, vNparts->GetNSteps(), Nwriters, "Nparts");
         Delete2DArray(Nparts);
 
-        /* GlobalArrayFixedDims */
+        /*
+         * GlobalArrayFixedDims
+         */
         // inquiry about a variable, whose name we know
         adios::Variable<double> *vGlobalArrayFixedDims =
             bpReader->InquireVariableDouble("GlobalArrayFixedDims");
@@ -211,24 +213,47 @@ int main(int argc, char *argv[])
         Print2DArray(GlobalArrayFixedDims, vGlobalArrayFixedDims->GetNSteps(),
                      count, "GlobalArrayFixedDims");
 
-        /* LocalArrayFixedDims2D */
+        /*
+         * LocalArrayFixedDims
+         */
         // inquiry about a variable, whose name we know
-        adios::Variable<float> *vLocalArrayFixedDims2D =
-            bpReader->InquireVariableFloat("LocalArrayFixedDims2D");
-        if (vLocalArrayFixedDims2D->m_Shape[1] != adios::IrregularDim)
+        adios::Variable<float> *vLocalArrayFixedDims =
+            bpReader->InquireVariableFloat("LocalArrayFixedDims");
+        if (vLocalArrayFixedDims->m_Shape[0] != adios::IrregularDim)
         {
             throw std::ios_base::failure(
-                "Unexpected condition: LocalArrayFixedDims2D array's fast "
+                "Unexpected condition: LocalArrayFixedDims array's fast "
                 "dimension is supposed to be adios::IrregularDim indicating an "
                 "Irregular array\n");
         }
+        std::cout << "LocalArrayFixedDims is irregular. Cannot read this "
+                     "variable yet...\n";
 
-        /* LocalArrayFixedDims1D */
+        /*
+         * LocalArrayFixedDimsJoined
+         */
+        // inquiry about a variable, whose name we know
+        adios::Variable<float> *vLocalArrayFixedDimsJoined =
+            bpReader->InquireVariableFloat("LocalArrayFixedDimsJoined");
+        std::cout << "LocalArrayFixedDimsJoined ["
+                  << vLocalArrayFixedDimsJoined->m_Shape[0] << "]";
+        std::cout << " = Cannot read this variable yet...\n";
+
+        /*
+         * GlobalArray which changes size over time
+         */
         // inquiry about a variable, whose name we know
-        adios::Variable<float> *vLocalArrayFixedDims1D =
-            bpReader->InquireVariableFloat("LocalArrayFixedDims1D");
-        std::cout << "LocalArrayFixedDims1D ["
-                  << vLocalArrayFixedDims1D->m_Shape[0] << "]" << std::endl;
+        adios::Variable<double> *vGlobalArray =
+            bpReader->InquireVariableDouble("GlobalArray");
+        std::cout << "GlobalArray [" << vGlobalArray->m_Shape[0] << "]";
+        std::cout << " = Cannot read this variable yet...\n";
+        if (vGlobalArray->m_Shape[0] != adios::IrregularDim)
+        {
+            throw std::ios_base::failure(
+                "Unexpected condition: GlobalArray array's  "
+                "dimension is supposed to be adios::IrregularDim indicating an "
+                "Irregular array\n");
+        }
 
 // overloaded Read from Derived
 #if 0
diff --git a/examples/groupless/multistep/writer_multistep.cpp b/examples/groupless/multistep/writer_multistep.cpp
index 60fb1722ce44778da7dd7a54976501d0e6a86a3a..9ed6f7c608d0a9c06076a0d908a09ea6bbb4621d 100644
--- a/examples/groupless/multistep/writer_multistep.cpp
+++ b/examples/groupless/multistep/writer_multistep.cpp
@@ -62,8 +62,8 @@ int main(int argc, char *argv[])
         adios::Variable<int> &varNproc = adios.DefineVariable<int>("Nproc");
 
         // 2. Local value, varying across processes, constant over time
-        adios::Variable<int> &varProcessID = adios.DefineVariable<int>(
-            "ProcessID", {nproc}, {rank}, {1}, adios::ConstantShape);
+        adios::Variable<int> &varProcessID =
+            adios.DefineVariable<int>("ProcessID", {adios::LocalValueDim});
 
         // 3. Global array, global dimensions (shape), offsets (start) and local
         // dimensions (count)  are  constant over time
@@ -72,19 +72,15 @@ int main(int argc, char *argv[])
 
         // 4. Local array, local dimensions and offsets are
         // constant over time.
-        // 4.a. Want to see this at reading as an irregular 2D array
-        // with appropriate global dimensions and offsets-per-writer
-        // generated by the reader and with rank serving as
-        // offset in the slow dimension
-        adios::Variable<float> &varLocalArrayFixedDims2D =
-            adios.DefineVariable<float>("LocalArrayFixedDims2D",
-                                        {nproc, adios::IrregularDim}, {rank, 0},
-                                        {1, LocalArrayFixedDims.size()});
+        // 4.a. Want to see this at reading as a bunch of local arrays
+        adios::Variable<float> &varLocalArrayFixedDims =
+            adios.DefineVariable<float>("LocalArrayFixedDims", {}, {},
+                                        {LocalArrayFixedDims.size()});
         // 4.b. Joined array, a 1D array, with global dimension and offsets
         // calculated at read time
-        adios::Variable<float> &varLocalArrayFixedDims1D =
-            adios.DefineVariable<float>("LocalArrayFixedDims1D",
-                                        {adios::JoinedDim}, {rank},
+        adios::Variable<float> &varLocalArrayFixedDimsJoined =
+            adios.DefineVariable<float>("LocalArrayFixedDimsJoined",
+                                        {adios::JoinedDim}, {},
                                         {LocalArrayFixedDims.size()});
 
         // 5. Global value, constant across processes, VARYING value over time
@@ -93,19 +89,16 @@ int main(int argc, char *argv[])
 
         // 6. Local value, varying across processes, VARYING over time
         adios::Variable<unsigned int> &varNparts =
-            adios.DefineVariable<unsigned int>("Nparts", {nproc}, {rank}, {1},
-                                               adios::ConstantShape);
+            adios.DefineVariable<unsigned int>("Nparts",
+                                               {adios::LocalValueDim});
 
         // 7. Global array, dimensions and offsets are VARYING over time
         adios::Variable<double> &varGlobalArray =
             adios.DefineVariable<double>("GlobalArray", {adios::UnknownDim});
 
         // 8. Local array, dimensions and offsets are VARYING over time
-        // Want to see this at reading as an irregular 2D array with rank
-        // serving as
-        // offset in the slow dimension
         adios::Variable<float> &varIrregularArray = adios.DefineVariable<float>(
-            "Irregular", {nproc, adios::IrregularDim});
+            "Irregular", {}, {}, {adios::UnknownDim});
 
         // add transform to variable in group...not executed (just testing API)
         // adios::Transform bzip2 = adios::transform::BZIP2();
@@ -192,11 +185,11 @@ int main(int argc, char *argv[])
 
             // 4.a Local array that will be shown at read as an irregular 2D
             // global array
-            bpWriter->Write<float>(varLocalArrayFixedDims2D,
+            bpWriter->Write<float>(varLocalArrayFixedDims,
                                    LocalArrayFixedDims.data());
             // 4.b Local array that will be shown at read as a joined 1D
             // global array
-            bpWriter->Write<float>(varLocalArrayFixedDims1D,
+            bpWriter->Write<float>(varLocalArrayFixedDimsJoined,
                                    LocalArrayFixedDims.data());
 
             // 7.
@@ -211,7 +204,7 @@ int main(int argc, char *argv[])
 
             // 8. Local array that will be shown at read as a ragged 2D global
             // array with ranks in slow dimension
-            varIrregularArray.SetSelection({rank, 0}, {1, Nparts});
+            varIrregularArray.SetSelection({}, {1, Nparts});
             bpWriter->Write<float>(varIrregularArray, IrregularArray.data());
 
             // Indicate we are done for this step
diff --git a/source/adios2/ADIOS.h b/source/adios2/ADIOS.h
index dbb84d76dbed0fe33bf0dd03df846ee187517a23..89a3d7eaa9789d9807c3b96841007a6c3cc1731f 100644
--- a/source/adios2/ADIOS.h
+++ b/source/adios2/ADIOS.h
@@ -107,9 +107,9 @@ public:
                                 bool constantShape = false);
 
     template <class T>
-    Variable<T> &DefineScalar(const std::string &name)
+    Variable<T> &DefineLocalValue(const std::string &name)
     {
-        return DefineVariable<T>(name, {}, {}, {}, false);
+        return DefineVariable<T>(name, {LocalValueDim}, {}, {}, false);
     }
 
     template <class T>
diff --git a/source/adios2/ADIOSTypes.h b/source/adios2/ADIOSTypes.h
index 0f211aa9d2cd6724d6d812edfcfb6ba616cabc4b..f20d8a27888f5c1bf6ce60c3a0d7abb76e6183ac 100644
--- a/source/adios2/ADIOSTypes.h
+++ b/source/adios2/ADIOSTypes.h
@@ -117,8 +117,18 @@ struct TypeInfo<T, typename std::enable_if<std::is_same<
 const size_t UnknownDim = 0;
 const size_t JoinedDim = SIZE_MAX - 1;
 const size_t IrregularDim = JoinedDim - 1;
+const size_t LocalValueDim = JoinedDim - 1;
 const bool ConstantShape = true;
 
+enum class VarClass
+{
+    GlobalValue,
+    LocalValue,
+    GlobalArray,
+    JoinedArray,
+    LocalArray
+};
+
 enum class Verbose
 {
     ERROR = 0,
diff --git a/source/adios2/core/VariableBase.h b/source/adios2/core/VariableBase.h
index c8953777d82669384fac8bf66d6c37ca4365f392..2509c851f73080576105a7fa71f2757ca2b3e2e6 100644
--- a/source/adios2/core/VariableBase.h
+++ b/source/adios2/core/VariableBase.h
@@ -50,7 +50,9 @@ public:
     Dims m_Count;            ///< dimensions of the local writer in global shape
     Dims m_MemoryDimensions; ///< array of memory dimensions
     Dims m_MemoryOffsets;    ///< array of memory offsets
-    bool m_IsScalar = false;
+
+    VarClass m_VarClass;
+    bool m_IsScalar = false; /// Global value or Loval value
     const bool m_IsDimension = false;
     const bool m_DebugMode = false;
 
@@ -62,8 +64,42 @@ public:
       m_ElementSize{elementSize}, m_Count{count}, m_Shape{shape},
       m_Start{start}, m_DebugMode{debugMode}
     {
-        if (shape.empty())
+        if (shape.empty() && start.empty())
+        {
+            if (count.empty())
+            {
+                m_VarClass = VarClass::GlobalValue;
+                m_IsScalar = true;
+            }
+            else
+            {
+                m_VarClass = VarClass::LocalArray;
+            }
+        }
+        else if (shape.size() == 1 && shape[0] == LocalValueDim)
+        {
+            m_VarClass = VarClass::LocalValue;
             m_IsScalar = true;
+        }
+        else if (shape.size() > 0 && shape[0] == JoinedDim)
+        {
+            m_VarClass = VarClass::JoinedArray;
+        }
+        else
+        {
+            if ((start.empty() && count.empty()) ||
+                (shape.size() == start.size() && shape.size() == count.size()))
+            {
+                m_VarClass = VarClass::GlobalArray;
+            }
+            else
+            {
+                throw std::invalid_argument("DefineVariable() is invalid. The "
+                                            "combination of dimension "
+                                            "specifications cannot be "
+                                            "interpreted\n");
+            }
+        }
     }
 
     virtual ~VariableBase() {}
@@ -93,19 +129,31 @@ public:
         if (m_IsScalar)
         {
             throw std::invalid_argument("Variable.SetSelection() is an invalid "
-                                        "call for single value variables\n");
+                                        "call for single value variable '" +
+                                        m_Name + "'\n");
         }
         if (m_ConstantShape)
         {
             throw std::invalid_argument(
                 "Variable.SetSelection() is not allowed "
-                "for arrays with a constant shape\n");
+                "for constant shape variable '" +
+                m_Name + "'\n");
         }
-        if (m_Shape.size() != count.size())
+        if (m_VarClass == VarClass::GlobalArray &&
+            m_Shape.size() != count.size())
         {
-            throw std::invalid_argument("Variable.SetSelection() bounding box "
+            throw std::invalid_argument("Variable.SetSelection() selection "
                                         "dimension must equal the global "
-                                        "dimension of the variable\n");
+                                        "dimension of the variable '" +
+                                        m_Name + "'\n");
+        }
+        if ((m_VarClass == VarClass::LocalArray ||
+             m_VarClass == VarClass::JoinedArray) &&
+            !start.empty())
+        {
+            throw std::invalid_argument(
+                "Variable.SetSelection() for local or joined array '" + m_Name +
+                "' should pass an empty 'start' argument\n");
         }
         ConvertUint64VectorToSizetVector(count, m_Count);
         ConvertUint64VectorToSizetVector(start, m_Start);
@@ -169,12 +217,20 @@ public:
     void SetNSteps(unsigned int steps) { m_NStepsAvailable = steps; }
     unsigned int GetReadFromStep() { return m_ReadFromStep; }
     unsigned int GetReadNSteps() { return m_ReadNSteps; }
+    void SetReadAsJoinedArray() { m_ReadAsJoined = true; }
+    void SetReadAsLocalValue() { m_ReadAsLocalValue = true; }
+    bool ReadAsJoinedArray() { return m_ReadAsJoined; }
+    bool ReadAsLocalValue() { return m_ReadAsLocalValue; }
 
 private:
     ///< Read from this step (must be 0 in staging)
     unsigned int m_ReadFromStep = 0;
     ///< Read this many steps at once (must be 1 in staging)
     unsigned int m_ReadNSteps = 1;
+    ///< Global array was written as Joined array, so read accordingly
+    bool m_ReadAsJoined = false;
+    ///< Global array was written as Local value, so read accordingly
+    bool m_ReadAsLocalValue = false;
 
     /* Values filled by InquireVariable() */
     ///< number of steps available in a file (or 1 in staging),
diff --git a/source/adios2/engine/adios1/ADIOS1Reader.cpp b/source/adios2/engine/adios1/ADIOS1Reader.cpp
index 407b93c59b99134489acd3d178cce45a5ad70366..1fd84c523fc92274a409d062971d6e8bd93c2b08 100644
--- a/source/adios2/engine/adios1/ADIOS1Reader.cpp
+++ b/source/adios2/engine/adios1/ADIOS1Reader.cpp
@@ -173,132 +173,275 @@ ADIOS1Reader::InquireVariableCompound(const std::string &variableName,
     return nullptr;
 }
 
+//#include "core/adios_selection_util.h"
+//#include "core/util.h"
+void ADIOS1Reader::ReadJoinedArray(const std::string &name, const Dims &offs,
+                                   const Dims &ldims, const int fromStep,
+                                   const int nSteps, void *data)
+{
+#if 0
+    ADIOS_VARINFO *vi = adios_inq_var(m_fh, name.c_str());
+    if (vi)
+    {
+        /* Update blockinfo: calculate start offsets now */
+        adios_inq_var_blockinfo(m_fh, vi);
+        int block = 0;
+        int firstblock = 0; // first block in fromStep
+        for (int step = 0; step < vi->nsteps; step++)
+        {
+            uint64_t offs = 0;
+            if (step == fromStep)
+                firstblock = block;
+            for (int j = 0; j < vi->nblocks[step]; j++)
+            {
+                vi->blockinfo[block].start[0] = offs;
+                offs += vi->blockinfo[block].count[0];
+                ++block;
+            }
+        }
+        ADIOS_SELECTION *bb =
+            adios_selection_boundingbox(vi->ndim, offs.data(), ldims.data());
+        /* Implement block-based reading here and now */
+        for (int step = fromStep; step < fromStep + nSteps && step < vi->nsteps;
+             step++)
+        {
+            /* read blocks that intersect with the selection */
+            block = firstblock;
+            for (int j = 0; j < vi->nblocks[step]; j++)
+            {
+                ADIOS_SELECTION *blockbb = adios_selection_boundingbox(
+                    vi->ndim, vi->blockinfo[block].start,
+                    vi->blockinfo[block].count);
+                ADIOS_SELECTION *intersectbb =
+                    adios_selection_intersect_global(bb, blockbb);
+                if (intersectbb)
+                {
+                    size_t ele_num = 0;
+                    for (int i = 0; i < vi->ndim; i++)
+                        ele_num += vi->blockinfo[block].count[i];
+                    int size_of_type = adios_type_size(vi->type, nullptr);
+                    char *blockdata = malloc(ele_num * size_of_type);
+                    ADIOS_SELECTION *wb = adios_selection_writeblock(j);
+                    adios_schedule_read(m_fh, wb, name.c_str(), step, 1,
+                                        blockdata);
+                    adios_perform_reads(m_fh, 1);
+
+                    /* Copy data into place */
+                    uint64_t dst_stride;
+                    uint64_t src_stride;
+                    uint64_t dst_offset;
+                    uint64_t src_offset;
+                    std::vector<uint64_t> size_in_dset[32];
+
+                    /* determine how many (fastest changing) dimensions can we
+                     * copy in one swoop */
+                    int i;
+                    for (i = vi->ndim - 1; i > -1; i--)
+                    {
+                        if (blockbb->u.bb.start[i] == offs[i] &&
+                            blockbb->u.bb.count[i] == ldims[i])
+                        {
+                            datasize *= ldims[i];
+                        }
+                        else
+                            break;
+                    }
+
+                    adios_util_copy_data(data, blockdata, 0, vi->ndim,
+                                         size_in_dset.data(), bbsize,
+                                         ldims.data(), dst_stride, src_stride,
+                                         dst_offset, src_offset, ele_num,
+                                         size_of_type, adios_flag_no, vi->type);
+
+                    adios_selection_delete(intersectbb);
+                    free(blockdata);
+                }
+                adios_selection_delete(blockbb);
+                block++;
+            }
+        }
+        adios_selection_delete(bb);
+    }
+    adios_free_varinfo(vi);
+#endif
+}
+
 void ADIOS1Reader::ScheduleReadCommon(const std::string &name, const Dims &offs,
                                       const Dims &ldims, const int fromStep,
-                                      const int nSteps, void *data)
+                                      const int nSteps,
+                                      const bool readAsLocalValue,
+                                      const bool readAsJoinedArray, void *data)
 {
-
-    uint64_t start[32], count[32];
-    for (int i = 0; i < ldims.size(); i++)
+    if (readAsLocalValue)
     {
-        start[i] = (uint64_t)offs[i];
-        count[i] = (uint64_t)ldims[i];
+        /* Get all the requested values from metadata now */
+        ADIOS_VARINFO *vi = adios_inq_var(m_fh, name.c_str());
+        if (vi)
+        {
+            adios_inq_var_stat(m_fh, vi, 0, 1);
+            int elemsize = adios_type_size(vi->type, nullptr);
+            long long blockidx = 0;
+            for (int i = 0; i < fromStep; i++)
+            {
+                blockidx += vi->nblocks[i];
+            }
+            char *dest = (char *)data;
+            for (int i = fromStep; i < fromStep + nSteps; i++)
+            {
+                for (int j = 0; j < vi->nblocks[i]; j++)
+                {
+                    memcpy(dest, vi->statistics->blocks->mins[blockidx],
+                           elemsize);
+                    ++blockidx;
+                    dest += elemsize;
+                }
+            }
+        }
     }
-    ADIOS_SELECTION *sel = nullptr;
-    if (ldims.size() > 0)
+    else if (readAsJoinedArray)
+    {
+        ReadJoinedArray(name, offs, ldims, fromStep, nSteps, data);
+    }
+    else
     {
-        adios_selection_boundingbox(ldims.size(), start, count);
+        uint64_t start[32], count[32];
+        for (int i = 0; i < ldims.size(); i++)
+        {
+            start[i] = (uint64_t)offs[i];
+            count[i] = (uint64_t)ldims[i];
+        }
+        ADIOS_SELECTION *sel = nullptr;
+        if (ldims.size() > 0)
+        {
+            adios_selection_boundingbox(ldims.size(), start, count);
+        }
+        adios_schedule_read(m_fh, sel, name.c_str(), (int)fromStep, (int)nSteps,
+                            data);
+        adios_selection_delete(sel);
     }
-    adios_schedule_read(m_fh, sel, name.c_str(), (int)fromStep, (int)nSteps,
-                        data);
-    adios_selection_delete(sel);
 }
 
 void ADIOS1Reader::ScheduleRead(Variable<char> &variable, char *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<unsigned char> &variable,
                                 unsigned char *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<short> &variable, short *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<unsigned short> &variable,
                                 unsigned short *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<int> &variable, int *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<unsigned int> &variable,
                                 unsigned int *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<long int> &variable, long int *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<unsigned long int> &variable,
                                 unsigned long int *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<long long int> &variable,
                                 long long int *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<unsigned long long int> &variable,
                                 unsigned long long int *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<float> &variable, float *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<double> &variable, double *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<long double> &variable,
                                 long double *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<std::complex<float>> &variable,
                                 std::complex<float> *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<std::complex<double>> &variable,
                                 std::complex<double> *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 void ADIOS1Reader::ScheduleRead(Variable<std::complex<long double>> &variable,
                                 std::complex<long double> *values)
 {
     ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count,
                        variable.GetReadFromStep(), variable.GetReadNSteps(),
-                       (void *)values);
+                       variable.ReadAsLocalValue(),
+                       variable.ReadAsJoinedArray(), (void *)values);
 }
 
 void ADIOS1Reader::ScheduleRead(const std::string &variableName, char *values)
diff --git a/source/adios2/engine/adios1/ADIOS1Reader.h b/source/adios2/engine/adios1/ADIOS1Reader.h
index 3cfe5b82c16c1a3d2a10df07053b12af6f67d74f..a30894d5df688e9b78ff4124278c9115c089a0ed 100644
--- a/source/adios2/engine/adios1/ADIOS1Reader.h
+++ b/source/adios2/engine/adios1/ADIOS1Reader.h
@@ -180,30 +180,93 @@ private:
         {
             CheckADIOS1TypeCompatibility(name, GetType<T>(),
                                          vi->type); // throws
+
             if (vi->ndim > 0)
             {
                 Dims gdims = Uint64ArrayToSizetVector(vi->ndim, vi->dims);
+
+                bool joinedread = false;
                 if (gdims[0] == JoinedDim)
                 {
+                    /* Joined Array */
                     adios_inq_var_blockinfo(m_fh, vi);
                     size_t joined_size = 0;
-                    // TODO: This just looks at the first step. What's with
-                    // arrays changing over time?
                     for (int i = 0; i < *vi->nblocks; i++)
                     {
                         joined_size += vi->blockinfo[i].count[0];
                     }
                     gdims[0] = joined_size;
+                    joinedread = true;
+                }
+
+                if (!vi->global)
+                {
+                    /* Local array */
+                    for (int j = 0; j < vi->ndim; ++j)
+                    {
+                        gdims[j] = IrregularDim;
+                    }
+                }
+                else
+                {
+                    /* Check if dimensions change in time */
+                    for (int step = 1; step < vi->nsteps; ++step)
+                    {
+                        Dims dims =
+                            gdims; // GetGlobalDimsAtStep(vi, step, joinedread);
+                        for (int j = 0; j < vi->ndim; ++j)
+                        {
+                            if (dims[j] != gdims[j])
+                                gdims[j] = IrregularDim;
+                        }
+                    }
                 }
                 var = &m_ADIOS.DefineArray<T>(name, gdims);
+                if (joinedread)
+                    var->SetReadAsJoinedArray();
             }
-            else /* scalar variable */
+            else /* Scalars */
             {
-                var = &m_ADIOS.DefineVariable<T>(name);
-                if (var && readIn)
+                /* scalar variable but global value or local value*/
+                std::string aname = name + "/ReadAsArray";
+                bool isLocalValue = false;
+                for (int i = 0; i < vi->nattrs; ++i)
+                {
+                    if (!strcmp(m_fh->attr_namelist[vi->attr_ids[i]],
+                                aname.c_str()))
+                    {
+                        isLocalValue = true;
+                    }
+                }
+                if (isLocalValue)
                 {
-                    var->m_Data = std::vector<T>(1);
-                    var->m_Data[0] = *static_cast<T *>(vi->value);
+                    /* Local Value */
+                    bool changingDims = false;
+                    for (int step = 1; step < vi->nsteps; ++step)
+                    {
+                        if (vi->nblocks[step] != vi->nblocks[0])
+                            changingDims = true;
+                    }
+                    if (changingDims)
+                    {
+                        var = &m_ADIOS.DefineVariable<T>(name, {IrregularDim});
+                    }
+                    else
+                    {
+                        var = &m_ADIOS.DefineVariable<T>(
+                            name, {(unsigned int)vi->nblocks[0]});
+                    }
+                    var->SetReadAsLocalValue();
+                }
+                else
+                {
+                    /* Global value: store only one value */
+                    var = &m_ADIOS.DefineVariable<T>(name);
+                    if (var)
+                    {
+                        var->m_Data = std::vector<T>(1);
+                        var->m_Data[0] = *static_cast<T *>(vi->value);
+                    }
                 }
             }
             var->SetNSteps(vi->nsteps);
@@ -214,7 +277,12 @@ private:
 
     void ScheduleReadCommon(const std::string &name, const Dims &offs,
                             const Dims &ldims, const int fromStep,
-                            const int nSteps, void *data);
+                            const int nSteps, const bool readAsLocalValue,
+                            const bool readAsJoinedArray, void *data);
+
+    void ReadJoinedArray(const std::string &name, const Dims &offs,
+                         const Dims &ldims, const int fromStep,
+                         const int nSteps, void *data);
 
     bool CheckADIOS1TypeCompatibility(const std::string &name,
                                       std::string adios2Type,
diff --git a/source/adios2/engine/adios1/ADIOS1Writer.cpp b/source/adios2/engine/adios1/ADIOS1Writer.cpp
index 3c94ea76810aa51076a4d76d8f47afcf420cedec..815aa895b8dce02b640f164275b9426c46626cab 100644
--- a/source/adios2/engine/adios1/ADIOS1Writer.cpp
+++ b/source/adios2/engine/adios1/ADIOS1Writer.cpp
@@ -72,30 +72,38 @@ bool ADIOS1Writer::ReOpenAsNeeded()
     return m_IsFileOpen;
 }
 
-void ADIOS1Writer::DefineVariable(std::string name, bool isScalar,
+void ADIOS1Writer::DefineVariable(std::string name, VarClass varclass,
                                   enum ADIOS_DATATYPES vartype,
                                   std::string ldims, std::string gdims,
                                   std::string offs)
 {
-    if (isScalar)
+    switch (varclass)
     {
+    case VarClass::GlobalValue:
         adios_define_var(m_adios_group, name.c_str(), "", vartype, "", "", "");
-    }
-    else
-    {
+        break;
+    case VarClass::LocalValue:
+        adios_define_var(m_adios_group, name.c_str(), "", vartype, "", "", "");
+        adios_define_attribute(m_adios_group, "ReadAsArray", name.c_str(),
+                               adios_byte, "1", nullptr);
+        break;
+    case VarClass::GlobalArray:
+    case VarClass::LocalArray:
+    case VarClass::JoinedArray:
         adios_define_var(m_adios_group, name.c_str(), "", vartype,
                          ldims.c_str(), gdims.c_str(), offs.c_str());
+        break;
     }
 }
 
-void ADIOS1Writer::WriteVariable(std::string name, bool isScalar,
+void ADIOS1Writer::WriteVariable(std::string name, VarClass varclass,
                                  enum ADIOS_DATATYPES vartype,
                                  std::string ldims, std::string gdims,
                                  std::string offs, const void *values)
 {
     if (ReOpenAsNeeded())
     {
-        DefineVariable(name, isScalar, vartype, ldims, gdims, offs);
+        DefineVariable(name, varclass, vartype, ldims, gdims, offs);
         adios_write(m_adios_file, name.c_str(), values);
     }
 }
@@ -127,7 +135,7 @@ static std::string DimsToCSV_LocalAware(const std::vector<std::size_t> &dims)
 
 void ADIOS1Writer::Write(Variable<char> &variable, const char *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_byte,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_byte,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -136,7 +144,7 @@ void ADIOS1Writer::Write(Variable<char> &variable, const char *values)
 void ADIOS1Writer::Write(Variable<unsigned char> &variable,
                          const unsigned char *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_byte,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_unsigned_byte,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -144,7 +152,7 @@ void ADIOS1Writer::Write(Variable<unsigned char> &variable,
 
 void ADIOS1Writer::Write(Variable<short> &variable, const short *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_short,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_short,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -153,7 +161,7 @@ void ADIOS1Writer::Write(Variable<short> &variable, const short *values)
 void ADIOS1Writer::Write(Variable<unsigned short> &variable,
                          const unsigned short *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_short,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_unsigned_short,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -161,7 +169,7 @@ void ADIOS1Writer::Write(Variable<unsigned short> &variable,
 
 void ADIOS1Writer::Write(Variable<int> &variable, const int *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_integer,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_integer,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -170,7 +178,7 @@ void ADIOS1Writer::Write(Variable<int> &variable, const int *values)
 void ADIOS1Writer::Write(Variable<unsigned int> &variable,
                          const unsigned int *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_integer,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_unsigned_integer,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -184,7 +192,7 @@ void ADIOS1Writer::Write(Variable<long int> &variable, const long int *values)
     {
         type = adios_long;
     }
-    WriteVariable(variable.m_Name, variable.m_IsScalar, type,
+    WriteVariable(variable.m_Name, variable.m_VarClass, type,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -199,7 +207,7 @@ void ADIOS1Writer::Write(Variable<unsigned long int> &variable,
     {
         type = adios_unsigned_long;
     }
-    WriteVariable(variable.m_Name, variable.m_IsScalar, type,
+    WriteVariable(variable.m_Name, variable.m_VarClass, type,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -208,7 +216,7 @@ void ADIOS1Writer::Write(Variable<unsigned long int> &variable,
 void ADIOS1Writer::Write(Variable<long long int> &variable,
                          const long long int *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_long,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_long,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -217,7 +225,7 @@ void ADIOS1Writer::Write(Variable<long long int> &variable,
 void ADIOS1Writer::Write(Variable<unsigned long long int> &variable,
                          const unsigned long long int *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_long,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_unsigned_long,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -225,7 +233,7 @@ void ADIOS1Writer::Write(Variable<unsigned long long int> &variable,
 
 void ADIOS1Writer::Write(Variable<float> &variable, const float *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_real,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_real,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -233,7 +241,7 @@ void ADIOS1Writer::Write(Variable<float> &variable, const float *values)
 
 void ADIOS1Writer::Write(Variable<double> &variable, const double *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_double,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_double,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -245,7 +253,7 @@ void ADIOS1Writer::Write(Variable<long double> &variable,
     /* TODO: This is faulty: adios_long_double expects 16 bytes per elements,
      * but
      * long double is compiler dependent */
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_long_double,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_long_double,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -254,7 +262,7 @@ void ADIOS1Writer::Write(Variable<long double> &variable,
 void ADIOS1Writer::Write(Variable<std::complex<float>> &variable,
                          const std::complex<float> *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_complex,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_complex,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
@@ -263,7 +271,7 @@ void ADIOS1Writer::Write(Variable<std::complex<float>> &variable,
 void ADIOS1Writer::Write(Variable<std::complex<double>> &variable,
                          const std::complex<double> *values)
 {
-    WriteVariable(variable.m_Name, variable.m_IsScalar, adios_double_complex,
+    WriteVariable(variable.m_Name, variable.m_VarClass, adios_double_complex,
                   DimsToCSV_LocalAware(variable.m_Count),
                   DimsToCSV_LocalAware(variable.m_Shape),
                   DimsToCSV_LocalAware(variable.m_Start), values);
diff --git a/source/adios2/engine/adios1/ADIOS1Writer.h b/source/adios2/engine/adios1/ADIOS1Writer.h
index bc9ebe4502dde8c8e5eb71867c6fdfe3b9ad591c..8a932da8e378788f789feab6242a255d47789152 100644
--- a/source/adios2/engine/adios1/ADIOS1Writer.h
+++ b/source/adios2/engine/adios1/ADIOS1Writer.h
@@ -129,10 +129,10 @@ private:
     void InitProcessGroup();
 
     bool ReOpenAsNeeded(); // return true if file is open or reopened
-    void DefineVariable(std::string name, bool isScalar,
+    void DefineVariable(std::string name, VarClass varclass,
                         enum ADIOS_DATATYPES vartype, std::string ldims,
                         std::string gdims, std::string offs);
-    void WriteVariable(std::string name, bool isScalar,
+    void WriteVariable(std::string name, VarClass varclass,
                        enum ADIOS_DATATYPES vartype, std::string ldims,
                        std::string gdims, std::string offs, const void *values);
 };
diff --git a/testing/adios2/interface/TestADIOSInterfaceWrite.cpp b/testing/adios2/interface/TestADIOSInterfaceWrite.cpp
index a5446b70daec220fa15708690b4aa52ba422ea44..ece198e126594b365855ce3ba118f8fcc9bbe5fb 100644
--- a/testing/adios2/interface/TestADIOSInterfaceWrite.cpp
+++ b/testing/adios2/interface/TestADIOSInterfaceWrite.cpp
@@ -33,9 +33,9 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarChar1x10)
                  std::invalid_argument);
 
     // Verify the dimensions, name, and type are correct
-    ASSERT_EQ(var_i8.m_Count.size(), 1);
-    EXPECT_EQ(var_i8.m_Count[0], 10);
-    EXPECT_EQ(var_i8.m_Shape.size(), 0);
+    ASSERT_EQ(var_i8.m_Shape.size(), 1);
+    EXPECT_EQ(var_i8.m_Shape[0], 10);
+    EXPECT_EQ(var_i8.m_Count.size(), 0);
     EXPECT_EQ(var_i8.m_Start.size(), 0);
     EXPECT_EQ(var_i8.m_Name, "i8");
     EXPECT_EQ(var_i8.m_Type, "char");
@@ -50,9 +50,9 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarShort1x10)
     EXPECT_THROW(auto &foo =
                      adios.DefineVariable<short>("i16", adios::Dims{10}),
                  std::invalid_argument);
-    ASSERT_EQ(var_i16.m_Count.size(), 1);
-    EXPECT_EQ(var_i16.m_Count[0], 10);
-    EXPECT_EQ(var_i16.m_Shape.size(), 0);
+    ASSERT_EQ(var_i16.m_Shape.size(), 1);
+    EXPECT_EQ(var_i16.m_Shape[0], 10);
+    EXPECT_EQ(var_i16.m_Count.size(), 0);
     EXPECT_EQ(var_i16.m_Start.size(), 0);
     EXPECT_EQ(var_i16.m_Name, "i16");
     EXPECT_EQ(var_i16.m_Type, "short");
@@ -64,9 +64,9 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarInt1x10)
     ::testing::StaticAssertTypeEq<decltype(var_i32), adios::Variable<int> &>();
     EXPECT_THROW(auto &foo = adios.DefineVariable<int>("i32", adios::Dims{10}),
                  std::invalid_argument);
-    ASSERT_EQ(var_i32.m_Count.size(), 1);
-    EXPECT_EQ(var_i32.m_Count[0], 10);
-    EXPECT_EQ(var_i32.m_Shape.size(), 0);
+    ASSERT_EQ(var_i32.m_Shape.size(), 1);
+    EXPECT_EQ(var_i32.m_Shape[0], 10);
+    EXPECT_EQ(var_i32.m_Count.size(), 0);
     EXPECT_EQ(var_i32.m_Start.size(), 0);
     EXPECT_EQ(var_i32.m_Name, "i32");
     EXPECT_EQ(var_i32.m_Type, "int");
@@ -78,9 +78,9 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarLong1x10)
     ::testing::StaticAssertTypeEq<decltype(var_i64), adios::Variable<long> &>();
     EXPECT_THROW(auto &foo = adios.DefineVariable<long>("i64", adios::Dims{10}),
                  std::invalid_argument);
-    ASSERT_EQ(var_i64.m_Count.size(), 1);
-    EXPECT_EQ(var_i64.m_Count[0], 10);
-    EXPECT_EQ(var_i64.m_Shape.size(), 0);
+    ASSERT_EQ(var_i64.m_Shape.size(), 1);
+    EXPECT_EQ(var_i64.m_Shape[0], 10);
+    EXPECT_EQ(var_i64.m_Count.size(), 0);
     EXPECT_EQ(var_i64.m_Start.size(), 0);
     EXPECT_EQ(var_i64.m_Name, "i64");
     EXPECT_EQ(var_i64.m_Type, "long int");
@@ -94,9 +94,9 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarUChar1x10)
     EXPECT_THROW(auto &foo =
                      adios.DefineVariable<unsigned char>("u8", adios::Dims{10}),
                  std::invalid_argument);
-    ASSERT_EQ(var_u8.m_Count.size(), 1);
-    EXPECT_EQ(var_u8.m_Count[0], 10);
-    EXPECT_EQ(var_u8.m_Shape.size(), 0);
+    ASSERT_EQ(var_u8.m_Shape.size(), 1);
+    EXPECT_EQ(var_u8.m_Shape[0], 10);
+    EXPECT_EQ(var_u8.m_Count.size(), 0);
     EXPECT_EQ(var_u8.m_Start.size(), 0);
     EXPECT_EQ(var_u8.m_Name, "u8");
     EXPECT_EQ(var_u8.m_Type, "unsigned char");
@@ -111,9 +111,9 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarUShort1x10)
     EXPECT_THROW(auto &foo = adios.DefineVariable<unsigned short>(
                      "u16", adios::Dims{10}),
                  std::invalid_argument);
-    ASSERT_EQ(var_u16.m_Count.size(), 1);
-    EXPECT_EQ(var_u16.m_Count[0], 10);
-    EXPECT_EQ(var_u16.m_Shape.size(), 0);
+    ASSERT_EQ(var_u16.m_Shape.size(), 1);
+    EXPECT_EQ(var_u16.m_Shape[0], 10);
+    EXPECT_EQ(var_u16.m_Count.size(), 0);
     EXPECT_EQ(var_u16.m_Start.size(), 0);
     EXPECT_EQ(var_u16.m_Name, "u16");
     EXPECT_EQ(var_u16.m_Type, "unsigned short");
@@ -127,9 +127,9 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarUInt1x10)
     EXPECT_THROW(auto &foo =
                      adios.DefineVariable<unsigned int>("u32", adios::Dims{10}),
                  std::invalid_argument);
-    ASSERT_EQ(var_u32.m_Count.size(), 1);
-    EXPECT_EQ(var_u32.m_Count[0], 10);
-    EXPECT_EQ(var_u32.m_Shape.size(), 0);
+    ASSERT_EQ(var_u32.m_Shape.size(), 1);
+    EXPECT_EQ(var_u32.m_Shape[0], 10);
+    EXPECT_EQ(var_u32.m_Count.size(), 0);
     EXPECT_EQ(var_u32.m_Start.size(), 0);
     EXPECT_EQ(var_u32.m_Name, "u32");
     EXPECT_EQ(var_u32.m_Type, "unsigned int");
@@ -143,9 +143,9 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarULong1x10)
     EXPECT_THROW(
         auto &foo = adios.DefineVariable<unsigned long>("u64", adios::Dims{10}),
         std::invalid_argument);
-    ASSERT_EQ(var_u64.m_Count.size(), 1);
-    EXPECT_EQ(var_u64.m_Count[0], 10);
-    EXPECT_EQ(var_u64.m_Shape.size(), 0);
+    ASSERT_EQ(var_u64.m_Shape.size(), 1);
+    EXPECT_EQ(var_u64.m_Shape[0], 10);
+    EXPECT_EQ(var_u64.m_Count.size(), 0);
     EXPECT_EQ(var_u64.m_Start.size(), 0);
     EXPECT_EQ(var_u64.m_Name, "u64");
     EXPECT_EQ(var_u64.m_Type, "unsigned long int");
@@ -159,9 +159,9 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarFloat1x10)
     EXPECT_THROW(auto &foo =
                      adios.DefineVariable<float>("r32", adios::Dims{10}),
                  std::invalid_argument);
-    ASSERT_EQ(var_r32.m_Count.size(), 1);
-    EXPECT_EQ(var_r32.m_Count[0], 10);
-    EXPECT_EQ(var_r32.m_Shape.size(), 0);
+    ASSERT_EQ(var_r32.m_Shape.size(), 1);
+    EXPECT_EQ(var_r32.m_Shape[0], 10);
+    EXPECT_EQ(var_r32.m_Count.size(), 0);
     EXPECT_EQ(var_r32.m_Start.size(), 0);
     EXPECT_EQ(var_r32.m_Name, "r32");
     EXPECT_EQ(var_r32.m_Type, "float");
@@ -175,9 +175,9 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarDouble1x10)
     EXPECT_THROW(auto &foo =
                      adios.DefineVariable<double>("r64", adios::Dims{10}),
                  std::invalid_argument);
-    ASSERT_EQ(var_r64.m_Count.size(), 1);
-    EXPECT_EQ(var_r64.m_Count[0], 10);
-    EXPECT_EQ(var_r64.m_Shape.size(), 0);
+    ASSERT_EQ(var_r64.m_Shape.size(), 1);
+    EXPECT_EQ(var_r64.m_Shape[0], 10);
+    EXPECT_EQ(var_r64.m_Count.size(), 0);
     EXPECT_EQ(var_r64.m_Start.size(), 0);
     EXPECT_EQ(var_r64.m_Name, "r64");
     EXPECT_EQ(var_r64.m_Type, "double");
@@ -190,10 +190,10 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarChar2x5)
     EXPECT_THROW(auto &foo =
                      adios.DefineVariable<char>("i8", adios::Dims{2, 5}),
                  std::invalid_argument);
-    ASSERT_EQ(var_i8.m_Count.size(), 2);
-    EXPECT_EQ(var_i8.m_Count[0], 2);
-    EXPECT_EQ(var_i8.m_Count[1], 5);
-    EXPECT_EQ(var_i8.m_Shape.size(), 0);
+    ASSERT_EQ(var_i8.m_Shape.size(), 2);
+    EXPECT_EQ(var_i8.m_Shape[0], 2);
+    EXPECT_EQ(var_i8.m_Shape[1], 5);
+    EXPECT_EQ(var_i8.m_Count.size(), 0);
     EXPECT_EQ(var_i8.m_Start.size(), 0);
     EXPECT_EQ(var_i8.m_Name, "i8");
     EXPECT_EQ(var_i8.m_Type, "char");
@@ -207,10 +207,10 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarShort2x5)
     EXPECT_THROW(auto &foo =
                      adios.DefineVariable<short>("i16", adios::Dims{2, 5}),
                  std::invalid_argument);
-    ASSERT_EQ(var_i16.m_Count.size(), 2);
-    EXPECT_EQ(var_i16.m_Count[0], 2);
-    EXPECT_EQ(var_i16.m_Count[1], 5);
-    EXPECT_EQ(var_i16.m_Shape.size(), 0);
+    ASSERT_EQ(var_i16.m_Shape.size(), 2);
+    EXPECT_EQ(var_i16.m_Shape[0], 2);
+    EXPECT_EQ(var_i16.m_Shape[1], 5);
+    EXPECT_EQ(var_i16.m_Count.size(), 0);
     EXPECT_EQ(var_i16.m_Start.size(), 0);
     EXPECT_EQ(var_i16.m_Name, "i16");
     EXPECT_EQ(var_i16.m_Type, "short");
@@ -223,10 +223,10 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarInt2x5)
     EXPECT_THROW(auto &foo =
                      adios.DefineVariable<int>("i32", adios::Dims{2, 5}),
                  std::invalid_argument);
-    ASSERT_EQ(var_i32.m_Count.size(), 2);
-    EXPECT_EQ(var_i32.m_Count[0], 2);
-    EXPECT_EQ(var_i32.m_Count[1], 5);
-    EXPECT_EQ(var_i32.m_Shape.size(), 0);
+    ASSERT_EQ(var_i32.m_Shape.size(), 2);
+    EXPECT_EQ(var_i32.m_Shape[0], 2);
+    EXPECT_EQ(var_i32.m_Shape[1], 5);
+    EXPECT_EQ(var_i32.m_Count.size(), 0);
     EXPECT_EQ(var_i32.m_Start.size(), 0);
     EXPECT_EQ(var_i32.m_Name, "i32");
     EXPECT_EQ(var_i32.m_Type, "int");
@@ -239,10 +239,10 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarLong2x5)
     EXPECT_THROW(auto &foo =
                      adios.DefineVariable<long>("i64", adios::Dims{2, 5}),
                  std::invalid_argument);
-    ASSERT_EQ(var_i64.m_Count.size(), 2);
-    EXPECT_EQ(var_i64.m_Count[0], 2);
-    EXPECT_EQ(var_i64.m_Count[1], 5);
-    EXPECT_EQ(var_i64.m_Shape.size(), 0);
+    ASSERT_EQ(var_i64.m_Shape.size(), 2);
+    EXPECT_EQ(var_i64.m_Shape[0], 2);
+    EXPECT_EQ(var_i64.m_Shape[1], 5);
+    EXPECT_EQ(var_i64.m_Count.size(), 0);
     EXPECT_EQ(var_i64.m_Start.size(), 0);
     EXPECT_EQ(var_i64.m_Name, "i64");
     EXPECT_EQ(var_i64.m_Type, "long int");
@@ -256,10 +256,10 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarUChar2x5)
     EXPECT_THROW(auto &foo = adios.DefineVariable<unsigned char>(
                      "u8", adios::Dims{2, 5}),
                  std::invalid_argument);
-    ASSERT_EQ(var_u8.m_Count.size(), 2);
-    EXPECT_EQ(var_u8.m_Count[0], 2);
-    EXPECT_EQ(var_u8.m_Count[1], 5);
-    EXPECT_EQ(var_u8.m_Shape.size(), 0);
+    ASSERT_EQ(var_u8.m_Shape.size(), 2);
+    EXPECT_EQ(var_u8.m_Shape[0], 2);
+    EXPECT_EQ(var_u8.m_Shape[1], 5);
+    EXPECT_EQ(var_u8.m_Count.size(), 0);
     EXPECT_EQ(var_u8.m_Start.size(), 0);
     EXPECT_EQ(var_u8.m_Name, "u8");
     EXPECT_EQ(var_u8.m_Type, "unsigned char");
@@ -274,10 +274,10 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarUShort2x5)
     EXPECT_THROW(auto &foo = adios.DefineVariable<unsigned short>(
                      "u16", adios::Dims{2, 5}),
                  std::invalid_argument);
-    ASSERT_EQ(var_u16.m_Count.size(), 2);
-    EXPECT_EQ(var_u16.m_Count[0], 2);
-    EXPECT_EQ(var_u16.m_Count[1], 5);
-    EXPECT_EQ(var_u16.m_Shape.size(), 0);
+    ASSERT_EQ(var_u16.m_Shape.size(), 2);
+    EXPECT_EQ(var_u16.m_Shape[0], 2);
+    EXPECT_EQ(var_u16.m_Shape[1], 5);
+    EXPECT_EQ(var_u16.m_Count.size(), 0);
     EXPECT_EQ(var_u16.m_Start.size(), 0);
     EXPECT_EQ(var_u16.m_Name, "u16");
     EXPECT_EQ(var_u16.m_Type, "unsigned short");
@@ -292,10 +292,10 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarUInt2x5)
     EXPECT_THROW(auto &foo = adios.DefineVariable<unsigned int>(
                      "u32", adios::Dims{2, 5}),
                  std::invalid_argument);
-    ASSERT_EQ(var_u32.m_Count.size(), 2);
-    EXPECT_EQ(var_u32.m_Count[0], 2);
-    EXPECT_EQ(var_u32.m_Count[1], 5);
-    EXPECT_EQ(var_u32.m_Shape.size(), 0);
+    ASSERT_EQ(var_u32.m_Shape.size(), 2);
+    EXPECT_EQ(var_u32.m_Shape[0], 2);
+    EXPECT_EQ(var_u32.m_Shape[1], 5);
+    EXPECT_EQ(var_u32.m_Count.size(), 0);
     EXPECT_EQ(var_u32.m_Start.size(), 0);
     EXPECT_EQ(var_u32.m_Name, "u32");
     EXPECT_EQ(var_u32.m_Type, "unsigned int");
@@ -310,10 +310,10 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarULong2x5)
     EXPECT_THROW(auto &foo = adios.DefineVariable<unsigned long>(
                      "u64", adios::Dims{2, 5}),
                  std::invalid_argument);
-    ASSERT_EQ(var_u64.m_Count.size(), 2);
-    EXPECT_EQ(var_u64.m_Count[0], 2);
-    EXPECT_EQ(var_u64.m_Count[1], 5);
-    EXPECT_EQ(var_u64.m_Shape.size(), 0);
+    ASSERT_EQ(var_u64.m_Shape.size(), 2);
+    EXPECT_EQ(var_u64.m_Shape[0], 2);
+    EXPECT_EQ(var_u64.m_Shape[1], 5);
+    EXPECT_EQ(var_u64.m_Count.size(), 0);
     EXPECT_EQ(var_u64.m_Start.size(), 0);
     EXPECT_EQ(var_u64.m_Name, "u64");
     EXPECT_EQ(var_u64.m_Type, "unsigned long int");
@@ -327,10 +327,10 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarFloat2x5)
     EXPECT_THROW(auto &foo =
                      adios.DefineVariable<float>("r32", adios::Dims{2, 5}),
                  std::invalid_argument);
-    ASSERT_EQ(var_r32.m_Count.size(), 2);
-    EXPECT_EQ(var_r32.m_Count[0], 2);
-    EXPECT_EQ(var_r32.m_Count[1], 5);
-    EXPECT_EQ(var_r32.m_Shape.size(), 0);
+    ASSERT_EQ(var_r32.m_Shape.size(), 2);
+    EXPECT_EQ(var_r32.m_Shape[0], 2);
+    EXPECT_EQ(var_r32.m_Shape[1], 5);
+    EXPECT_EQ(var_r32.m_Count.size(), 0);
     EXPECT_EQ(var_r32.m_Start.size(), 0);
     EXPECT_EQ(var_r32.m_Name, "r32");
     EXPECT_EQ(var_r32.m_Type, "float");
@@ -344,10 +344,10 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarDouble2x5)
     EXPECT_THROW(auto &foo =
                      adios.DefineVariable<double>("r64", adios::Dims{2, 5}),
                  std::invalid_argument);
-    ASSERT_EQ(var_r64.m_Count.size(), 2);
-    EXPECT_EQ(var_r64.m_Count[0], 2);
-    EXPECT_EQ(var_r64.m_Count[1], 5);
-    EXPECT_EQ(var_r64.m_Shape.size(), 0);
+    ASSERT_EQ(var_r64.m_Shape.size(), 2);
+    EXPECT_EQ(var_r64.m_Shape[0], 2);
+    EXPECT_EQ(var_r64.m_Shape[1], 5);
+    EXPECT_EQ(var_r64.m_Count.size(), 0);
     EXPECT_EQ(var_r64.m_Start.size(), 0);
     EXPECT_EQ(var_r64.m_Name, "r64");
     EXPECT_EQ(var_r64.m_Type, "double");