From fc5eb577d5b910e2186c0396509aebf9310fce31 Mon Sep 17 00:00:00 2001
From: wfg <wfg@pc0098504.ornl.gov>
Date: Thu, 26 Jan 2017 17:42:53 -0500
Subject: [PATCH] Made changes to ADIOS Class to return references and smart
 pointers rather than handlers

Group&, Method& and the polymorphic std::shared_ptr<Engine> will be
returned by DeclareGroup, DeclareMethod and Open.

Added Group functions DefineVariable to be a template
Now using adios::Var when creating a variable (still a variable name
string).

Uses more C++ OO + templates features

Compiled and tested with ./examples/hello/helloWriter_OOP.cpp , mpi and
no-mpi versions
---
 examples/hello/writer/Makefile            |  24 ++-
 examples/hello/writer/helloWriter_OOP.cpp |  49 ++++--
 include/ADIOS.h                           | 190 ++++------------------
 include/ADIOS_C.h                         |  18 +-
 include/ADIOS_OOP.h                       |   5 +-
 include/core/Engine.h                     |  14 ++
 include/core/Group.h                      |  62 ++++---
 include/core/Transform.h                  |   4 +-
 include/core/Variable.h                   |   4 +
 include/engine/writer/WriterTemplates.h   |   2 +-
 include/format/BP1Writer.h                |  30 +++-
 include/functions/adiosTemplates.h        |  61 +++++++
 src/ADIOS.cpp                             | 121 +++-----------
 src/ADIOS_C.cpp                           |  10 +-
 src/core/Engine.cpp                       |  11 ++
 src/core/Group.cpp                        |  43 +++--
 src/core/Transform.cpp                    |   7 +
 src/engine/writer/Writer.cpp              |  13 ++
 src/functions/adiosFunctions.cpp          |   2 +-
 19 files changed, 316 insertions(+), 354 deletions(-)
 create mode 100644 include/functions/adiosTemplates.h

diff --git a/examples/hello/writer/Makefile b/examples/hello/writer/Makefile
index 5b5d6ae4d..ad66a1719 100644
--- a/examples/hello/writer/Makefile
+++ b/examples/hello/writer/Makefile
@@ -1,35 +1,31 @@
-# Makefile for testing purposes, will build libadios.a 
+# Makefile for testing purposes, will build helloWriter_OOP_mpi (make or make mpi) or helloWriter_OOP_nompi (make nompi) 
 # Created on: Oct 4, 2016
 #     Author: wfg
 
-
 BASE_NAME=helloWriter_OOP
-     
-TOOL_DIR=/usr/bin
 
-CC=$(TOOL_DIR)/g++ # Compiling with mpicc for now
-MPICC=$(TOOL_DIR)/mpic++
-AR=$(TOOL_DIR)/ar
+#COMPILERS
+CC=g++ 
+MPICC=mpic++
 
 #ADIOS LOCATION
 ADIOS_DIR=../../..
+ADIOS_INCLUDE=-I$(ADIOS_DIR)/include
 ADIOS_LIB=$(ADIOS_DIR)/lib/libadios.a
 ADIOS_NOMPI_LIB=$(ADIOS_DIR)/lib/libadios_nompi.a
 
-ADIOS_INCLUDE=-I$(ADIOS_DIR)/include
-
-
 #FLAGS
-CFLAGS=-Wall -O0 -g -Wpedantic -std=c++11
+CFLAGS=-Wall -O0 -g -Wpedantic -Woverloaded-virtual -std=c++11
+LDFLAGS=-static-libgcc -static-libstdc++
 
 all: mpi
 
 mpi: $(ADIOS_LIB) $(ADIOS_HFiles)
-	$(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) -DHAVE_MPI $(BASE_NAME).cpp -o $(BASE_NAME)_mpi $(ADIOS_LIB) -lpthread
+	$(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) -DHAVE_MPI $(BASE_NAME).cpp -o $(BASE_NAME)_mpi $(ADIOS_LIB) $(LDFLAGS) -lpthread
 	
 nompi: $(ADIOS_NOMPI_LIB) $(NoMPI_HFiles)
-	$(CC) $(CFLAGS) $(ADIOS_INCLUDE) $(BASE_NAME).cpp -o $(BASE_NAME)_nompi $(ADIOS_NOMPI_LIB) -lpthread
+	$(CC) $(CFLAGS) $(ADIOS_INCLUDE) $(BASE_NAME).cpp -o $(BASE_NAME)_nompi $(ADIOS_NOMPI_LIB) $(LDFLAGS) -lpthread
 
 clean:
 	rm *_mpi; rm *_nompi
-     
+     
\ No newline at end of file
diff --git a/examples/hello/writer/helloWriter_OOP.cpp b/examples/hello/writer/helloWriter_OOP.cpp
index 36bfd1b49..91767b464 100644
--- a/examples/hello/writer/helloWriter_OOP.cpp
+++ b/examples/hello/writer/helloWriter_OOP.cpp
@@ -27,29 +27,42 @@ int main( int argc, char* argv [] )
     int rank;
     MPI_Comm_rank( MPI_COMM_WORLD, &rank );
     const bool adiosDebug = true;
+    adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug );
 
     //Application variable
-    std::vector<double> myInts = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
-    int myIntsSize = static_cast<int>( myInts.size() );
+    std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+    std::vector<float> myFloats = { 0, -1, -2, -3, -4, -5, -6, -7, -8, -9 };
+    const unsigned int Nx = 10; //static_cast<unsigned int>( myDoubles.size() );
 
     try
     {
-        //Define group and variables
-        adios::Group group( adiosDebug );
-        group.DefineVariable( "myIntsSize", "int" ); //define size as scalar
-        group.DefineVariable( "myInts",     "double", "myIntsSize" ); //define variable with associate size
-
-        //Define method
-        adios::Method method( "Writer");
-        method.AddCapsule( "Heap" );
-        method.AddTransport( "POSIX", "have_metadata_file=0" );
-
-        //Create engine and Write
-        adios::Writer writer( "myInts.bp", "w", MPI_COMM_WORLD, method, adiosDebug );
-        writer.SetDefaultGroup( group );
-        writer.Write( "myIntsSize", &myIntsSize  );
-        writer.Write( "myInts", &myInts.front() );
-        writer.Close( );
+        //Define group and variables with transforms
+        adios::Group& ioGroup = adios.DeclareGroup( "ioGroup" );
+        adios::Var ioNx = ioGroup.DefineVariable<unsigned int>( "Nx" );
+        adios::Var ioMyDoubles = ioGroup.DefineVariable<double>( "myDoubles", "Nx" );
+        adios::Var ioMyFloats = ioGroup.DefineVariable<float>( "myFloats", "Nx" );
+
+        //add transform to variable in group...not executed (just testing API)
+        adios::Transform bzip2 = adios::transform::BZIP2( );
+        ioGroup.AddTransform( ioMyDoubles, bzip2, 1 );
+        ioGroup.AddTransform( ioMyFloats, bzip2, 1 );
+
+        //Define method for engine creation, it is basically straight-forward parameters
+        adios::Method& bpWriterSettings = adios.DeclareMethod( "SinglePOSIXFile" ); //default method type is Writer
+        bpWriterSettings.AddTransport( "POSIX", "have_metadata_file=yes" );
+        bpWriterSettings.SetDefaultGroup( ioGroup );
+
+        //Create engine smart pointer due to polymorphism,
+        //Open returns a smart pointer to Engine containing the Derived class Writer
+        auto bpWriter = adios.Open( "myNumbers.bp", "w", bpWriterSettings );
+
+        if( bpWriter == nullptr )
+            throw std::ios_base::failure( "ERROR: failed to open ADIOS bpWriter\n" );
+
+        bpWriter->Write<unsigned int>( ioNx, &Nx );
+        bpWriter->Write<double>( ioMyDoubles, myDoubles.data() );
+        bpWriter->Write<float>( ioMyFloats, myFloats.data() );
+        bpWriter->Close( );
     }
     catch( std::invalid_argument& e )
     {
diff --git a/include/ADIOS.h b/include/ADIOS.h
index d9dd95dc3..0f6f2d63b 100644
--- a/include/ADIOS.h
+++ b/include/ADIOS.h
@@ -13,7 +13,6 @@
 #include <vector>
 #include <memory> //shared_ptr
 #include <ostream>
-#include <unordered_map>
 #include <set>
 #include <map>
 /// \endcond
@@ -49,7 +48,6 @@ public: // PUBLIC Constructors and Functions define the User Interface with ADIO
     int m_RankMPI = 0; ///< current MPI rank process
     int m_SizeMPI = 1; ///< current MPI processes size
 
-
     /**
      * @brief ADIOS empty constructor. Used for non XML config file API calls.
      */
@@ -88,73 +86,15 @@ public: // PUBLIC Constructors and Functions define the User Interface with ADIO
      * Creates an empty group
      * @param groupName
      */
-    void DeclareGroup( const std::string groupName );
-
-    /**
-     * Creates a new Variable, if debugMode = true, program will throw an exception, else it will overwrite current variable with the same name
-     * @param groupName corresponding variable group
-     * @param variableName corresponding variable name
-     * @param type variable type
-     * @param dimensionsCSV comma separated (no space) dimensions "Nx,Ny,Nz" defined by other variables
-     * @param globalDimensionsCSV comma separated (no space) global dimensions "gNx,gNy,gNz" defined by other variables
-     * @param globalOffsetsCSV comma separated (no space) global offsets "oNx,oNy,oNz" defined by other variables
-     */
-    void DefineVariable( const std::string groupName, const std::string variableName, const std::string type,
-                         const std::string dimensionsCSV = "", const std::string globalDimensionsCSV = "",
-                         const std::string globalOffsetsCSV = ""  );
-    /**
-     * Sets a transform method to a variable, to be applied when writing
-     * @param groupName corresponding variable group
-     * @param variableName corresponding variable name
-     * @param transform method to be applied for this variable
-     */
-    void AddTransform( const std::string groupName, const std::string variableName, const std::string transform );
-
-
-    /**
-     * @brief Creates a new Attribute.
-     * Debug Mode: program will throw an exception if attribute exists (attributeName),
-     * else: overwrites current attribute using the same name
-     * @param groupName corresponding variable group
-     * @param attributeName corresponding attribute name
-     * @param type string or number
-     * @param value string contents of the attribute (e.g. "Communication value", "1" )
-     */
-    void DefineAttribute( const std::string groupName, const std::string attributeName,
-                          const std::string type, const std::string value );
-
+    Group& DeclareGroup( const std::string groupName );
 
     /**
      * Declares a new method
-     * @param name
-     * @param type
+     * @param name must be unique
+     * @param type supported type : "Writer" (default), "DataMan"...future: "Sirius"
      */
-    void DeclareMethod( const std::string methodName, const std::string type );
+    Method& DeclareMethod( const std::string methodName, const std::string type = "Writer" );
 
-    template< class ...Args>
-    void SetParameters( const std::string methodName, const Args... args )
-    {
-        auto itMethod = m_Methods.find( methodName );
-        if( m_DebugMode == true )
-            CheckMethod( itMethod, methodName, " from call to AddTransport\n" );
-
-        itMethod->second.SetParameters( args... );
-    }
-
-    /**
-     * Add a transport type to method name defined from DeclareMethod
-     * @param methodName unique method name
-     * @param args variadic parameters with format parameter=value
-     */
-    template< class ...Args>
-    void AddTransport( const std::string methodName, const std::string transportType, const Args... args )
-    {
-        auto itMethod = m_Methods.find( methodName );
-        if( m_DebugMode == true )
-            CheckMethod( itMethod, methodName, " from call to AddTransport\n" );
-
-        itMethod->second.AddTransport( transportType, args... );
-    }
 
     /**
      * @brief Open to Write, Read. Creates a new engine from previously defined method
@@ -163,81 +103,48 @@ public: // PUBLIC Constructors and Functions define the User Interface with ADIO
      * @param mpiComm option to modify communicator from ADIOS class constructor
      * @param method looks for corresponding Method object in ADIOS to initialize the engine
      * @param cores optional parameter for threaded operations
-     * @return handler to created engine
+     * @return Derived class of base Engine depending on Method parameters, shared_ptr for potential flexibility
      */
-    unsigned int Open( const std::string streamName, const std::string accessMode, MPI_Comm mpiComm,
-                       const std::string methodName, const unsigned int cores = 1 );
+    std::shared_ptr<Engine> Open( const std::string streamName, const std::string accessMode, MPI_Comm mpiComm,
+                                  const Method& method, const unsigned int cores = 1 );
 
 
     /**
-     * @brief Open to Write, Read. Creates a new engine from previously defined method. Reuses MPI communicator from ADIOS class constructor.
+     * @brief Open to Write, Read. Creates a new engine from previously defined method.
+     * Reuses MPI communicator from ADIOS constructor.
      * @param streamName unique stream or file name
      * @param accessMode "w" or "write", "r" or "read", "a" or "append"
-     * @param methodName looks for corresponding Method object in ADIOS to initialize the engine
+     * @param method contains engine parameters
      * @param cores optional parameter for threaded operations
-     * @return handler to created engine
-     */
-    unsigned int Open( const std::string streamName, const std::string accessMode, const std::string methodName,
-                       const unsigned int cores = 1 );
-
-
-    /**
-     * Sets a default group to be associated with a method and engine before writing variables with Open/Write functions.
-     * @param methodName
-     * @param groupName
+     * @return Derived class of base Engine depending on Method parameters, shared_ptr for potential flexibility
      */
-    void SetDefaultGroup( const std::string methodName, const std::string groupName );
+    std::shared_ptr<Engine> Open( const std::string streamName, const std::string accessMode, const Method& method,
+                                  const unsigned int cores = 1 );
 
 
     /**
-     * Sets a default group to be associated with a stream before writing variables with Write function.
-     * @param streamName unique name
-     * @param groupName default group from which variables will be used
-     */
-    void SetDefaultGroup( const unsigned int handler, const std::string groupName );
-
-
-    /**
-     * Write version using an explicit Group
-     * Submits a data element values for writing and associates it with the given variableName
-     * @param handler returned by ADIOS Open
-     * @param variableName name of existing variable in the XML file or created with DefineVariable
-     * @param values pointer to the variable values passed from the user application
+     * Version required by the XML config file implementation, searches method inside ADIOS through a unique name
+     * @param streamName unique stream or file name
+     * @param accessMode "w" or "write", "r" or "read", "a" or "append"
+     * @param mpiComm mpi Communicator
+     * @param methodName used to search method object inside ADIOS object
+     * @param cores optional parameter for threaded operations
+     * @return Derived class of base Engine depending on Method parameters, shared_ptr for potential flexibility
      */
-    template<class T>
-    void Write( const unsigned int handler, const std::string groupName, const std::string variableName, const T* values )
-    {
-        auto itEngine = m_Engines.find( handler );
-        auto itGroup = m_Groups.find( groupName );
-
-        if( m_DebugMode == true )
-        {
-            CheckEngine( itEngine, handler, " from call to Write variable " + variableName );
-            CheckGroup( itGroup, groupName, " from call to Write variable " + variableName );
-        }
-
-        itEngine->second->Write( itGroup->second, variableName, values );
-    }
-
+    std::shared_ptr<Engine> Open( const std::string streamName, const std::string accessMode, MPI_Comm mpiComm,
+                                  const std::string methodName, const unsigned int cores = 1 );
 
     /**
-     * Write version using default Group set with SetDefaultGroup function on method or handler created by Open
-     * Submits a data element values for writing and associates it with the given variableName
-     * @param handler returned by ADIOS Open
-     * @param variableName name of existing variable in the XML file or created with DefineVariable
-     * @param values pointer to the variable values passed from the user application
+     * Version required by the XML config file implementation, searches method inside ADIOS through a unique name.
+     * Reuses ADIOS MPI Communicator from constructor.
+     * @param streamName unique stream or file name
+     * @param accessMode "w" or "write", "r" or "read", "a" or "append"
+     * @param methodName used to search method object inside ADIOS object
+     * @param cores optional parameter for threaded operations
+     * @return Derived class of base Engine depending on Method parameters, shared_ptr for potential flexibility
      */
-    template<class T>
-    void Write( const unsigned int handler, const std::string variableName, const T* values )
-    {
-        auto itEngine = m_Engines.find( handler );
-
-        if( m_DebugMode == true )
-            CheckEngine( itEngine, handler, " from call to Write variable " + variableName );
-
-        itEngine->second->Write( variableName, values );
-    }
-
+    std::shared_ptr<Engine> Open( const std::string streamName, const std::string accessMode,
+                                  const std::string methodName, const unsigned int cores = 1 );
 
     /**
      * Close a particular stream and the corresponding transport
@@ -256,7 +163,7 @@ public: // PUBLIC Constructors and Functions define the User Interface with ADIO
 
 
 
-private:
+private: //no const to allow default empty and copy constructors
 
     std::string m_XMLConfigFile; ///< XML File to be read containing configuration information
     std::string m_HostLanguage = "C++"; ///< Supported languages: C, C++, Fortran, Python, etc.
@@ -264,41 +171,25 @@ private:
 
     //GROUP
     /**
-     * @brief List of groups defined from either ADIOS XML configuration file or the CreateGroup function.
+     * @brief List of groups defined from either ADIOS XML configuration file or the DeclareGroup function.
      * <pre>
      *     Key: std::string unique group name
      *     Value: Group class
      * </pre>
      */
     std::map< std::string, Group > m_Groups;
+    std::vector< std::shared_ptr<Transform> > m_Transforms; ///< transforms associated with ADIOS run
+
 
-    //METHODS -> Engine Metadata
     /**
-     * @brief List of Methods defined from either ADIOS XML configuration file or the CreateMethod function.
+     * @brief List of Methods (engine metadata) defined from either ADIOS XML configuration file or the DeclareMethod function.
      * <pre>
      *     Key: std::string unique method name
      *     Value: Method class
      * </pre>
      */
     std::map< std::string, Method > m_Methods;
-
-
-    //ENGINE
-    /**
-     * @brief List of Engines, ADIOS Open adds to this container.
-     * <pre>
-     *     Key: Engine handle give by a counter
-     *     Value: Engine derived class
-     * </pre>
-     */
-    std::unordered_map< unsigned int, std::shared_ptr<Engine> > m_Engines;
     std::set< std::string > m_EngineNames; ///< set used to check Engine name uniqueness in debug mode
-    int m_EngineCounter = -1; ///< used to set the unsigned int key in m_Capsules, helpful is a capsule is removed
-
-
-    //TRANSFORMS
-    std::vector< std::shared_ptr<Transform> > m_Transforms; ///< transforms associated with ADIOS run
-
 
     /**
      * @brief Checks for group existence in m_Groups, if failed throws std::invalid_argument exception
@@ -319,15 +210,6 @@ private:
     void CheckMethod( std::map< std::string, Method >::const_iterator itMethod,
                       const std::string methodName, const std::string hint ) const;
 
-
-    /**
-     * @brief Checks for engine existence in m_Engines, if failed throws std::invalid_argument exception
-     * @param itEngine from Open
-     * @param hint adds information to thrown exception
-     */
-    void CheckEngine( std::unordered_map< unsigned int, std::shared_ptr<Engine> >::const_iterator itEngine,
-                      const unsigned int handle, const std::string hint ) const;
-
 };
 
 
diff --git a/include/ADIOS_C.h b/include/ADIOS_C.h
index 2331d5147..efe9ed286 100644
--- a/include/ADIOS_C.h
+++ b/include/ADIOS_C.h
@@ -19,6 +19,11 @@
 
 
 typedef void ADIOS;
+typedef void Group;
+typedef void Method;
+typedef void Engine;
+
+
 
 #ifdef __cplusplus
 extern "C"
@@ -26,16 +31,15 @@ extern "C"
 #endif
 
 
-ADIOS* adios_init( const char* xmlConfigFile, const MPI_Comm mpicomm );
-ADIOS* adios_init_debug( const char* xmlConfigFile, const MPI_Comm mpicomm );
-
-void adios_open( const ADIOS* adiosC, const char* groupName, const char* fileName, const char* accessMode );
-void adios_write( const ADIOS* adiosC, const char* groupName, const char* variableName, const void* values  );
+void adios_init( const char* xmlConfigFile, const MPI_Comm mpicomm );
+void adios_init_debug( const char* xmlConfigFile, const MPI_Comm mpicomm );
 
-void adios_close( const ADIOS* adiosC, const char* groupName );
+int adios_open( const char* fileName, const char* accessMode, MPI_Comm );
+void adios_write(const char* groupName, const char* variableName, const void* values  );
 
-void adios_free( const ADIOS* adiosC ); // deallocate ADIOS pointer
+void adios_close( const int handler );
 
+void adios_finalize( const ADIOS* adiosC ); // deallocate ADIOS pointer
 
 void adios_monitor_groups( const ADIOS* adiosC );
 
diff --git a/include/ADIOS_OOP.h b/include/ADIOS_OOP.h
index 398f98f1c..8495e5bac 100644
--- a/include/ADIOS_OOP.h
+++ b/include/ADIOS_OOP.h
@@ -9,9 +9,12 @@
 #define ADIOS_OOP_H_
 
 
+#include "ADIOS.h"
 #include "core/Group.h"
 #include "core/Method.h"
-#include "engine/writer/Writer.h"
+#include "core/Engine.h"
+
+#include "core/Transform.h"
 #include "transform/BZip2.h"
 
 
diff --git a/include/core/Engine.h b/include/core/Engine.h
index a28b7500c..2cdd048a5 100644
--- a/include/core/Engine.h
+++ b/include/core/Engine.h
@@ -73,6 +73,18 @@ public:
 
     void SetDefaultGroup( Group& group );
 
+    template< class T >
+    void Write( const std::string variableName, const T* values )
+    {
+        Write( *m_Group, variableName, values );
+    }
+
+    template< class T >
+    void Write( Group& group, const std::string variableName, const T* values )
+    {
+        Write( group, variableName, values );
+    }
+
     /**
      * @brief Write functions can be overridden by derived classes. Base class behavior is to:
      * 1) Write to Variable values (m_Values) in a group
@@ -161,6 +173,8 @@ protected:
                          const std::string hint ) const;
 
 
+    void CheckDefaultGroup( ) const; ///< checks if default group m_Group is nullptr, throws exception if trying to use
+
     std::string GetName( const std::vector<std::string>& arguments ) const; //might move this to adiosFunctions
 
 };
diff --git a/include/core/Group.h b/include/core/Group.h
index 69d0c58ce..3d6704032 100644
--- a/include/core/Group.h
+++ b/include/core/Group.h
@@ -28,10 +28,13 @@
 #include "core/Attribute.h"
 #include "core/Transport.h"
 #include "core/Transform.h"
+#include "functions/adiosTemplates.h"
 
 
 namespace adios
 {
+
+using Var = std::string;
 /**
  * Class that defines each ADIOS Group composed of Variables, Attributes and GlobalBounds (if global variables exist)
  */
@@ -42,6 +45,21 @@ class Group
 public:
 
     const std::string m_Name;
+    std::vector< std::pair< std::string, std::string > > m_GlobalBounds; ///<  if a variable or an attribute is global it fills this container, from global-bounds in XML File, data in global space, pair.first = global dimensions, pair.second = global bounds
+
+    std::vector< Variable<char> > m_Char; ///< Key: variable name, Value: variable of type char
+    std::vector< Variable<unsigned char> > m_UChar; ///< Key: variable name, Value: variable of type unsigned char
+    std::vector< Variable<short> > m_Short; ///< Key: variable name, Value: variable of type short
+    std::vector< Variable<unsigned short> > m_UShort; ///< Key: variable name, Value: variable of type unsigned short
+    std::vector< Variable<int> > m_Int; ///< Key: variable name, Value: variable of type int
+    std::vector< Variable<unsigned int> > m_UInt; ///< Key: variable name, Value: variable of type unsigned int
+    std::vector< Variable<long int> > m_LInt; ///< Key: variable name, Value: variable of type long int
+    std::vector< Variable<unsigned long int> > m_ULInt; ///< Key: variable name, Value: variable of type unsigned long int
+    std::vector< Variable<long long int> > m_LLInt; ///< Key: variable name, Value: variable of type long long int
+    std::vector< Variable<unsigned long long int> > m_ULLInt; ///< Key: variable name, Value: variable of type unsigned long long int
+    std::vector< Variable<float> > m_Float; ///< Key: variable name, Value: variable of type float
+    std::vector< Variable<double> > m_Double; ///< Key: variable name, Value: variable of type double
+    std::vector< Variable<long double> > m_LDouble; ///< Key: variable name, Value: variable of type double
 
     /**
      * Empty constructor
@@ -52,7 +70,7 @@ public:
      * Empty constructor
      * @param debugMode true: additional checks throwing exceptions, false: skip checks
      */
-    Group( const bool debugMode = false );
+    Group( const std::string name, const bool debugMode = false );
 
     /**
      * @brief Constructor for XML config file
@@ -61,7 +79,7 @@ public:
      * @param transforms passed from ADIOS.m_Transforms, single look up table for all transforms
      * @param debugMode
      */
-    Group( const std::string& xmlGroup, std::vector< std::shared_ptr<Transform> >& transforms, const bool debugMode );
+    Group( const std::string name, const std::string& xmlGroup, std::vector< std::shared_ptr<Transform> >& transforms, const bool debugMode );
 
 
     ~Group( ); ///< Using STL containers, no deallocation
@@ -76,11 +94,22 @@ public:
      * @param transforms collection of Transform objects applied to this variable, sequence matters, default is empty
      * @param parameters corresponding parameter used by a Transform object in transforms (index should match), default is empty
      */
-    void DefineVariable( const std::string variableName, const std::string type,
-                         const std::string dimensionsCSV = "",
-                         const std::string globalDimensionsCSV = "", const std::string globalOffsetsCSV = "",
-                         const std::vector<Transform*> transforms = std::vector<Transform*>(),
-                         const std::vector<int> parameters = std::vector<int>() );
+    Var DefineVariable( const std::string variableName, const std::string type,
+                        const std::string dimensionsCSV = "",
+                        const std::string globalDimensionsCSV = "", const std::string globalOffsetsCSV = "",
+                        const std::vector<Transform*> transforms = std::vector<Transform*>(),
+                        const std::vector<int> parameters = std::vector<int>() );
+
+
+    template< class T >
+    Var DefineVariable( const std::string variableName,
+                        const std::string dimensionsCSV = "",
+                        const std::string globalDimensionsCSV = "", const std::string globalOffsetsCSV = "",
+                        const std::vector<Transform*> transforms = std::vector<Transform*>(),
+                        const std::vector<int> parameters = std::vector<int>() )
+    {
+        return DefineVariable( variableName, GetType<T>(), dimensionsCSV, globalDimensionsCSV, globalOffsetsCSV, transforms, parameters );
+    }
 
     /**
      * Sets a variable transform contained in ADIOS Transforms (single container for all groups and variables)
@@ -112,25 +141,6 @@ public:
      */
     std::vector<unsigned long long int> GetDimensions( const std::string dimensionsCSV ) const;
 
-    unsigned long long int m_SerialSize = 0; ///< size used for potential serialization of metadata into a std::vector<char>. Counts sizes from m_Variables, m_Attributes, m_GlobalBounds
-
-    std::vector< std::pair< std::string, std::string > > m_GlobalBounds; ///<  if a variable or an attribute is global it fills this container, from global-bounds in XML File, data in global space, pair.first = global dimensions, pair.second = global bounds
-
-    std::vector< Variable<char> > m_Char; ///< Key: variable name, Value: variable of type char
-    std::vector< Variable<unsigned char> > m_UChar; ///< Key: variable name, Value: variable of type unsigned char
-    std::vector< Variable<short> > m_Short; ///< Key: variable name, Value: variable of type short
-    std::vector< Variable<unsigned short> > m_UShort; ///< Key: variable name, Value: variable of type unsigned short
-    std::vector< Variable<int> > m_Int; ///< Key: variable name, Value: variable of type int
-    std::vector< Variable<unsigned int> > m_UInt; ///< Key: variable name, Value: variable of type unsigned int
-    std::vector< Variable<long int> > m_LInt; ///< Key: variable name, Value: variable of type long int
-    std::vector< Variable<unsigned long int> > m_ULInt; ///< Key: variable name, Value: variable of type unsigned long int
-    std::vector< Variable<long long int> > m_LLInt; ///< Key: variable name, Value: variable of type long long int
-    std::vector< Variable<unsigned long long int> > m_ULLInt; ///< Key: variable name, Value: variable of type unsigned long long int
-    std::vector< Variable<float> > m_Float; ///< Key: variable name, Value: variable of type float
-    std::vector< Variable<double> > m_Double; ///< Key: variable name, Value: variable of type double
-    std::vector< Variable<long double> > m_LDouble; ///< Key: variable name, Value: variable of type double
-
-
 private:
 
     std::set<std::string> m_WrittenVariables;
diff --git a/include/core/Transform.h b/include/core/Transform.h
index e664fb574..c78c7f18a 100644
--- a/include/core/Transform.h
+++ b/include/core/Transform.h
@@ -37,9 +37,9 @@ public:
 
     virtual ~Transform( );
 
-    virtual void Compress( const std::vector<char>& bufferIn, std::vector<char>& bufferOut ) = 0;
+    virtual void Compress( const std::vector<char>& bufferIn, std::vector<char>& bufferOut );
 
-    virtual void Decompress( const std::vector<char>& bufferIn, std::vector<char>& bufferOut ) = 0;
+    virtual void Decompress( const std::vector<char>& bufferIn, std::vector<char>& bufferOut );
 
 };
 
diff --git a/include/core/Variable.h b/include/core/Variable.h
index e4ce49ad7..8e8b75855 100644
--- a/include/core/Variable.h
+++ b/include/core/Variable.h
@@ -11,10 +11,12 @@
 /// \cond EXCLUDE_FROM_DOXYGEN
 #include <string>
 #include <vector>
+#include <memory>
 /// \endcond
 
 #include "core/Transform.h"
 
+
 namespace adios
 {
 /**
@@ -29,6 +31,8 @@ struct Variable
 
     std::vector< Transform* > Transforms; ///< associated transforms, sequence determines application order, e.g. first Transforms[0] then Transforms[1]. Pointer used as reference (no memory management).
     std::vector< int > Parameters; ///< additional optional parameter understood by the corresponding Transform in Transforms vector
+    //Group& Group; ///< reference to group
+    //bool IsDimension = false; ///< true: is used as a dimension in another variable (typically scalars), false: none
 };
 
 
diff --git a/include/engine/writer/WriterTemplates.h b/include/engine/writer/WriterTemplates.h
index a572c2300..bf9c569c4 100644
--- a/include/engine/writer/WriterTemplates.h
+++ b/include/engine/writer/WriterTemplates.h
@@ -38,7 +38,7 @@ void WriterWriteVariable( const Group& group, const std::string variableName, co
                           format::BP1Writer& bp1Writer )
 {
 
-    std::cout << "Hello from writing variable " << variableName << "of type " << typeid(T).name() << "\n";
+    std::cout << "Hello from bp Writer, writing variable " << variableName << " of typeid(T).name() = " << typeid(T).name() << "\n";
     //here deal with buffers allocation
 
 
diff --git a/include/format/BP1Writer.h b/include/format/BP1Writer.h
index 5c26215b4..c47feb9fb 100644
--- a/include/format/BP1Writer.h
+++ b/include/format/BP1Writer.h
@@ -368,7 +368,6 @@ public:
        }
 
        ++characteristicsCounter;
-
        //Stat -> Min, Max
        characteristicID = characteristic_stat;
        if( verbose == 0 ) //default verbose
@@ -377,25 +376,40 @@ public:
            //here we can make decisions for threads based on valuesSize
            T min, max;
 
-           if( valuesSize >= 10000000 ) //ten million?
+           if( valuesSize >= 10000000 ) //ten million? this needs actual results
                GetMinMax( variable.Values, valuesSize, min, max, m_Cores ); //here we can add cores from constructor
            else
                GetMinMax( variable.Values, valuesSize, min, max );
 
            const std::int8_t statisticMinID = statistic_min;
            const std::int8_t statisticMaxID = statistic_max;
-           //write statistics here
 
+           //write min and max to metadata
+           WriteToBuffers( metadataBuffers, &characteristicID, 1, metadataOffset  ); //min
+           WriteToBuffers( metadataBuffers, &statisticMinID, 1, metadataOffset  );
+           WriteToBuffers( metadataBuffers, &min, sizeof(T), metadataOffset );
+
+           WriteToBuffers( metadataBuffers, &characteristicID, 1, metadataOffset  ); //max
+           WriteToBuffers( metadataBuffers, &statisticMaxID, 1, metadataOffset  );
+           WriteToBuffers( metadataBuffers, &max, sizeof(T), metadataOffset );
+
+           //write min and max to data
+           WriteToBuffers( dataBuffers, &characteristicID, 1, dataOffset  ); //min
+           const std::int16_t lengthCharacteristic = 1 + sizeof( T );
+           WriteToBuffers( dataBuffers, &lengthCharacteristic, 2, dataOffset  );
+           WriteToBuffers( dataBuffers, &statisticMinID, 1, dataOffset  );
+           WriteToBuffers( dataBuffers, &min, sizeof(T), dataOffset );
+
+           WriteToBuffers( dataBuffers, &characteristicID, 1, dataOffset  ); //max
+           WriteToBuffers( dataBuffers, &lengthCharacteristic, 2, dataOffset  );
+           WriteToBuffers( dataBuffers, &statisticMaxID, 1, dataOffset  );
+           WriteToBuffers( dataBuffers, &max, sizeof(T), dataOffset );
        }
-       //Offsets should be last
-
-
+       //Offsets should be last and only written to metadata
 
     } //end of function
 
 
-
-
 private:
 
     bool m_DebugMode = false;
diff --git a/include/functions/adiosTemplates.h b/include/functions/adiosTemplates.h
new file mode 100644
index 000000000..643153351
--- /dev/null
+++ b/include/functions/adiosTemplates.h
@@ -0,0 +1,61 @@
+/*
+ * adiosTemplates.h
+ *
+ *  Created on: Jan 26, 2017
+ *      Author: wfg
+ */
+
+#ifndef ADIOSTEMPLATES_H_
+#define ADIOSTEMPLATES_H_
+
+
+namespace adios
+{
+
+template< class T >
+std::string GetType( ) noexcept
+{
+    std::string type;
+
+    if( std::is_same<T,char>::value )
+        type = "char";
+
+    else if( std::is_same<T,short>::value )
+        type = "short";
+
+    else if( std::is_same<T,int>::value )
+        type = "int";
+
+    else if( std::is_same<T,long int>::value )
+        type = "long int";
+
+    else if( std::is_same<T,unsigned char>::value )
+        type = "unsigned char";
+
+    else if( std::is_same<T,unsigned short>::value )
+        type = "unsigned short";
+
+    else if( std::is_same<T,unsigned int>::value )
+        type = "unsigned int";
+
+    else if( std::is_same<T,unsigned long int>::value )
+        type = "unsigned long int";
+
+    else if( std::is_same<T,float>::value )
+        type = "float";
+
+    else if( std::is_same<T,double>::value )
+        type = "double";
+
+    else if( std::is_same<T,long double>::value )
+        type = "long double";
+
+    return type;
+}
+
+
+
+} //end namespace
+
+
+#endif /* ADIOSTEMPLATES_H_ */
diff --git a/src/ADIOS.cpp b/src/ADIOS.cpp
index ab94cf42d..058a22222 100644
--- a/src/ADIOS.cpp
+++ b/src/ADIOS.cpp
@@ -63,7 +63,7 @@ ADIOS::~ADIOS( )
 { }
 
 
-void ADIOS::DeclareGroup( const std::string groupName )
+Group& ADIOS::DeclareGroup( const std::string groupName )
 {
     if( m_DebugMode == true )
     {
@@ -71,54 +71,12 @@ void ADIOS::DeclareGroup( const std::string groupName )
             throw std::invalid_argument( "ERROR: group " + groupName + " already exist, from call to DeclareGroup\n" );
     }
 
-    m_Groups.emplace( groupName, Group( m_DebugMode ) );
+    m_Groups.emplace( groupName, Group( groupName, m_DebugMode ) );
+    return m_Groups.at( groupName );
 }
 
 
-void ADIOS::DefineVariable( const std::string groupName, const std::string variableName, const std::string type,
-                            const std::string dimensionsCSV,
-                            const std::string globalDimensionsCSV, const std::string globalOffsetsCSV )
-{
-    auto itGroup = m_Groups.find( groupName );
-    if( m_DebugMode == true )
-        CheckGroup( itGroup, groupName, " from call to CreateVariable \n" );
-
-    itGroup->second.DefineVariable( variableName, type, dimensionsCSV, globalDimensionsCSV, globalOffsetsCSV );
-}
-
-
-void ADIOS::AddTransform( const std::string groupName, const std::string variableName, const std::string transform )
-{
-    auto itGroup = m_Groups.find( groupName );
-    if( m_DebugMode == true ) //check group and transform
-    {
-        CheckGroup( itGroup, groupName, " from call to SetTransform \n" );
-
-        if( Support::Transforms.count( transform ) == 0 )
-            throw std::invalid_argument( "ERROR: transform method " + transform +
-                                         " not supported, in call to SetTransform\n" );
-    }
-
-    std::vector<std::string> transformName = { transform };
-    std::vector<short> transformIndices, parameters;
-    SetTransformsHelper( transformName, m_Transforms, m_DebugMode, transformIndices, parameters );
-    itGroup->second.AddTransform( variableName, *m_Transforms[ transformIndices[0] ], parameters[0] );
-}
-
-
-void ADIOS::DefineAttribute( const std::string groupName, const std::string attributeName,
-                             const std::string type, const std::string value )
-
-{
-    auto itGroup = m_Groups.find( groupName );
-    if( m_DebugMode == true )
-        CheckGroup( itGroup, groupName, " from call to CreateAttribute \n" );
-
-    itGroup->second.DefineAttribute( attributeName, type, value );
-}
-
-
-void ADIOS::DeclareMethod( const std::string methodName, const std::string type )
+Method& ADIOS::DeclareMethod( const std::string methodName, const std::string type )
 {
     if( m_DebugMode == true )
     {
@@ -126,44 +84,25 @@ void ADIOS::DeclareMethod( const std::string methodName, const std::string type
             throw std::invalid_argument( "ERROR: method " + methodName + " already declared, from DeclareMethod\n" );
     }
     m_Methods.emplace( methodName, Method( type, m_DebugMode ) );
+    return m_Methods.at( methodName );
 }
 
 
-void ADIOS::SetDefaultGroup( const std::string methodName, const std::string groupName )
-{
-    auto itMethod = m_Methods.find( methodName );
-    auto itGroup = m_Groups.find( groupName );
-
-    if( m_DebugMode == true )
-    {
-        if( m_Methods.count( methodName ) == 1 )
-            throw std::invalid_argument( "ERROR: method " + methodName + " already declared, from DeclareMethod\n" );
-
-        CheckGroup( itGroup, groupName, " in call to SetDefaultGroup.\n" );
-    }
-    itMethod->second.SetDefaultGroup( itGroup->second );
-}
-
-
-unsigned int ADIOS::Open( const std::string name, const std::string accessMode,
-                          MPI_Comm mpiComm, const std::string methodName, const unsigned int cores )
+std::shared_ptr<Engine> ADIOS::Open( const std::string name, const std::string accessMode, MPI_Comm mpiComm, const Method& method, const unsigned int cores )
 {
-    auto itMethod = m_Methods.find( methodName );
-
     if( m_DebugMode == true )
     {
-        CheckMethod( itMethod, methodName, " from call to Open\n" );
-
         if( m_EngineNames.count( name ) == 1 ) //Check if Engine already exists
             throw std::invalid_argument( "ERROR: engine name " + name + " already created by Open, in call from Open.\n" );
     }
 
-    ++m_EngineCounter;
-    const std::string type( itMethod->second.m_Type );
+    m_EngineNames.insert( name );
+
+    const std::string type( method.m_Type );
 
     if( type == "Writer" || type == "writer" )
     {
-        m_Engines.emplace( m_EngineCounter, std::make_shared<Writer>( name, accessMode, mpiComm, itMethod->second, cores ) );
+        return std::make_shared<Writer>( name, accessMode, mpiComm, method, cores );
     }
     else if( type == "SIRIUS" || type == "sirius" || type == "Sirius" )
     {
@@ -171,47 +110,43 @@ unsigned int ADIOS::Open( const std::string name, const std::string accessMode,
     }
     else if( type == "DataMan" )
     {
-    	m_Engines.emplace( m_EngineCounter, std::make_shared<engine::DataMan>( name, accessMode, mpiComm, itMethod->second, cores ) );
+    	return std::make_shared<engine::DataMan>( name, accessMode, mpiComm, method, cores );
     }
     else
     {
         if( m_DebugMode == true )
-            throw std::invalid_argument( "ERROR: type " + type + " not supported for method " + methodName + ", in call to Open\n" );
+            throw std::invalid_argument( "ERROR: method type " + type + " not supported for " + name + ", in call to Open\n" );
     }
 
-    return m_EngineCounter;
+    return nullptr; // if debug mode is off
 }
 
 
-unsigned int ADIOS::Open( const std::string streamName, const std::string accessMode, const std::string methodName,
-                          const unsigned int cores )
+std::shared_ptr<Engine> ADIOS::Open( const std::string streamName, const std::string accessMode, const Method& method,
+                                     const unsigned int cores )
 {
-    return Open( streamName, accessMode, m_MPIComm, methodName, cores );
+    return Open( streamName, accessMode, m_MPIComm, method, cores );
 }
 
 
-void ADIOS::SetDefaultGroup( const unsigned int handler, const std::string groupName )
+std::shared_ptr<Engine> ADIOS::Open( const std::string name, const std::string accessMode, MPI_Comm mpiComm,
+                                     const std::string methodName, const unsigned int cores )
 {
-    auto itEngine = m_Engines.find( handler );
-    auto itGroup = m_Groups.find( groupName );
+    auto itMethod = m_Methods.find( methodName );
 
     if( m_DebugMode == true )
     {
-        CheckEngine( itEngine, handler, " in call to SetDefaultGroup.\n" );
-        CheckGroup( itGroup, groupName, " in call to SetDefaultGroup.\n" );
+        CheckMethod( itMethod, methodName, " in call to Open\n" );
     }
 
-    itEngine->second->SetDefaultGroup( itGroup->second );
+    return Open( name, accessMode, mpiComm, itMethod->second, cores );
 }
 
 
-void ADIOS::Close( const unsigned int handler, const int transportIndex ) //close stream
+std::shared_ptr<Engine> ADIOS::Open( const std::string name, const std::string accessMode,
+                                     const std::string methodName, const unsigned int cores )
 {
-    auto itEngine = m_Engines.find( handler );
-    if( m_DebugMode == true )
-        CheckEngine( itEngine, handler, " in call to Close\n" );
-
-    itEngine->second->Close( transportIndex );
+    return Open( name, accessMode, m_MPIComm, methodName, cores );
 }
 
 
@@ -242,12 +177,4 @@ void ADIOS::CheckMethod( std::map< std::string, Method >::const_iterator itMetho
 }
 
 
-void ADIOS::CheckEngine( std::unordered_map< unsigned int, std::shared_ptr<Engine> >::const_iterator itEngine,
-                         const unsigned int handle, const std::string hint ) const
-{
-    if( itEngine == m_Engines.end() )
-        throw std::invalid_argument( "ERROR: stream (or file) from handle " + std::to_string( handle ) + " not created with Open , " + hint + "\n" );
-}
-
-
 } //end namespace
diff --git a/src/ADIOS_C.cpp b/src/ADIOS_C.cpp
index c1423fd10..b8e738014 100644
--- a/src/ADIOS_C.cpp
+++ b/src/ADIOS_C.cpp
@@ -15,15 +15,19 @@
 #include "ADIOS.h"
 #include "ADIOS_C.h"
 
+
+adios::ADIOS* adios;
+
+
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
 
-ADIOS* adios_init( const char* xmlConfigFile, const MPI_Comm mpiComm )
+void adios_init( const char* xmlConfigFile, const MPI_Comm mpiComm )
 {
-    adios::ADIOS* adios;
+
     int rank;
     MPI_Comm_rank( mpiComm, &rank );
 
@@ -47,7 +51,7 @@ ADIOS* adios_init( const char* xmlConfigFile, const MPI_Comm mpiComm )
             std::cout << "Exception, STOPPING PROGRAM\n" << e.what() << "\n";
     }
 
-    return ( ADIOS* ) ( adios );
+//    return ( ADIOS* ) ( adios );
 }
 
 
diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp
index 2b68f2c36..774a84ea9 100644
--- a/src/core/Engine.cpp
+++ b/src/core/Engine.cpp
@@ -23,6 +23,7 @@ Engine::Engine( const std::string engineType, const std::string name, const std:
     m_Name{ name },
     m_AccessMode{ accessMode },
     m_Method{ method },
+    m_Group{ method.m_Group },
     m_DebugMode{ debugMode },
     m_Cores{ cores },
     m_EndMessage{ endMessage }
@@ -98,6 +99,16 @@ void Engine::CheckParameter( const std::map<std::string, std::string>::const_ite
 
 
 
+void Engine::CheckDefaultGroup( ) const
+{
+    if( m_DebugMode == true )
+    {
+        if( m_Group == nullptr )
+            throw std::invalid_argument( "ERROR: default group in engine " + m_Name + " is nullptr, check Method\n" );
+    }
+}
+
+
 std::string Engine::GetName( const std::vector<std::string>& arguments ) const
 {
     bool isNameFound = false;
diff --git a/src/core/Group.cpp b/src/core/Group.cpp
index efce46fd9..710943be7 100644
--- a/src/core/Group.cpp
+++ b/src/core/Group.cpp
@@ -23,12 +23,14 @@ Group::Group( )
 { }
 
 
-Group::Group( const bool debugMode ):
+Group::Group( const std::string name, const bool debugMode ):
+    m_Name{ name },
     m_DebugMode{ debugMode }
 { }
 
 
-Group::Group( const std::string& xmlGroup, std::vector< std::shared_ptr<Transform> >& transforms, const bool debugMode ):
+Group::Group( const std::string name, const std::string& xmlGroup, std::vector< std::shared_ptr<Transform> >& transforms, const bool debugMode ):
+    m_Name{ name },
     m_DebugMode{ debugMode }
 {
     ParseXMLGroup( xmlGroup, transforms );
@@ -39,10 +41,10 @@ Group::~Group( )
 { }
 
 
-void Group::DefineVariable( const std::string variableName, const std::string type,
-                            const std::string dimensionsCSV,
-                            const std::string globalDimensionsCSV, const std::string globalOffsetsCSV,
-                            std::vector<Transform*> transforms, std::vector<int> parameters )
+Var Group::DefineVariable( const std::string variableName, const std::string type,
+                           const std::string dimensionsCSV,
+                           const std::string globalDimensionsCSV, const std::string globalOffsetsCSV,
+                           std::vector<Transform*> transforms, std::vector<int> parameters )
 {
     if( m_DebugMode == true )
     {
@@ -54,62 +56,62 @@ void Group::DefineVariable( const std::string variableName, const std::string ty
 
     if( IsTypeAlias( type, Support::DatatypesAliases.at("char") ) == true )
     {
-        m_Char.push_back( Variable<char>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_Char.push_back( Variable<char>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_Char.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("unsigned char") ) == true )
     {
-        m_UChar.push_back( Variable<unsigned char>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_UChar.push_back( Variable<unsigned char>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_UChar.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("short") ) == true )
     {
-        m_Short.push_back( Variable<short>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_Short.push_back( Variable<short>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_Short.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("unsigned short") ) == true )
     {
-        m_UShort.push_back( Variable<unsigned short>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_UShort.push_back( Variable<unsigned short>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_UShort.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("int") ) == true )
     {
-        m_Int.push_back( Variable<int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_Int.push_back( Variable<int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_Int.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("unsigned int") ) == true )
     {
-        m_UInt.push_back( Variable<unsigned int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_UInt.push_back( Variable<unsigned int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_UInt.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("long int") ) == true )
     {
-        m_LInt.push_back( Variable<long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_LInt.push_back( Variable<long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_LInt.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("unsigned long int") ) == true )
     {
-        m_ULInt.push_back( Variable<unsigned long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_ULInt.push_back( Variable<unsigned long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_ULInt.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("long long int") ) == true )
     {
-        m_LLInt.push_back( Variable<long long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_LLInt.push_back( Variable<long long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_LLInt.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("unsigned long long int") ) == true )
     {
-        m_ULLInt.push_back( Variable<unsigned long long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_ULLInt.push_back( Variable<unsigned long long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_ULLInt.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("float") ) == true )
     {
-        m_Float.push_back( Variable<float>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_Float.push_back( Variable<float>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_Float.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("double") ) == true )
     {
-        m_Double.push_back( Variable<double>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters } );
+        m_Double.push_back( Variable<double>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters  } );
         m_Variables[variableName] = std::make_pair( type, m_Double.size()-1 );
     }
     else if( IsTypeAlias( type, Support::DatatypesAliases.at("long double") ) == true )
@@ -122,8 +124,7 @@ void Group::DefineVariable( const std::string variableName, const std::string ty
         if( m_DebugMode == true )
             throw std::invalid_argument( "ERROR: type " + type + " not supported, in call to DefineVariable.\n" );
     }
-
-    m_SerialSize += variableName.size() + type.size() + dimensionsCSV.size() + 4 * sizeof( char ); //4, adding one more for globalBoundsIndex
+    return variableName;
 }
 
 
@@ -234,8 +235,6 @@ void Group::DefineAttribute( const std::string attributeName, const std::string
     {
         m_Attributes.emplace( attributeName, Attribute{ lf_GetTypeID( type, m_DebugMode ), value } );
     }
-
-    m_SerialSize += attributeName.size() + 1 + value.size() + 3 * sizeof( char ); //3 is one byte storing the size as a char
 }
 
 
diff --git a/src/core/Transform.cpp b/src/core/Transform.cpp
index 0002c8d8a..89b882e55 100644
--- a/src/core/Transform.cpp
+++ b/src/core/Transform.cpp
@@ -21,5 +21,12 @@ Transform::~Transform( )
 { }
 
 
+void Transform::Compress( const std::vector<char>& bufferIn, std::vector<char>& bufferOut )
+{ }
+
+
+void Transform::Decompress( const std::vector<char>& bufferIn, std::vector<char>& bufferOut )
+{ }
+
 
 } //end namespace
diff --git a/src/engine/writer/Writer.cpp b/src/engine/writer/Writer.cpp
index 73d3730b9..4fc6c5005 100644
--- a/src/engine/writer/Writer.cpp
+++ b/src/engine/writer/Writer.cpp
@@ -153,78 +153,91 @@ void Writer::Write( Group& group, const std::string variableName, const long dou
 
 void Writer::Write( const std::string variableName, const char* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const unsigned char* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const short* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const unsigned short* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const int* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const unsigned int* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const long int* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const unsigned long int* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const long long int* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const unsigned long long int* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const float* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const double* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
 
 void Writer::Write( const std::string variableName, const long double* values )
 {
+    CheckDefaultGroup( );
     Write( *m_Group, variableName, values );
 }
 
diff --git a/src/functions/adiosFunctions.cpp b/src/functions/adiosFunctions.cpp
index 67e089599..baea09006 100644
--- a/src/functions/adiosFunctions.cpp
+++ b/src/functions/adiosFunctions.cpp
@@ -269,7 +269,7 @@ void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, const b
                 throw std::invalid_argument( "ERROR: group " + groupName + " defined twice.\n" );
         }
 
-        groups.emplace( groupName, Group( xmlGroup, transforms, debugMode ) );
+        groups.emplace( groupName, Group( groupName, xmlGroup, transforms, debugMode ) );
 
         currentContent.erase( currentContent.find( xmlGroup ), xmlGroup.size() );
         currentPosition = 0;
-- 
GitLab