From 9b4aa9e05febbb0472524a12938c597f420652b0 Mon Sep 17 00:00:00 2001
From: David Andrs <david.andrs@inl.gov>
Date: Tue, 23 Aug 2011 10:51:43 -0600
Subject: [PATCH 2/2] Storing subdomain ids in and XDA solution file

---
 include/base/libmesh_common.h     |    3 ++
 include/base/variable.h           |    8 ++++++-
 include/utils/xdr_cxx.h           |   14 ++++++++++++
 src/systems/equation_systems_io.C |   14 ++++++++++-
 src/systems/system_io.C           |   42 ++++++++++++++++++++++++++++++++++--
 5 files changed, 75 insertions(+), 6 deletions(-)

diff --git a/include/base/libmesh_common.h b/include/base/libmesh_common.h
index fccc08d..7bf4c4a 100644
--- a/include/base/libmesh_common.h
+++ b/include/base/libmesh_common.h
@@ -385,6 +385,9 @@ inline Tnew libmesh_cast_ptr (Told* oldvar)
 template<class T> inline void libmesh_ignore( const T& ) { }
 
 
+// build a integer representation of version
+#define LIBMESH_VERSION(major,minor,patch) (((major) << 16) | ((minor) << 8) | ((patch) & 0xFF))
+
 } // namespace libMesh
 
 #endif // #define __libmesh_common_h__
diff --git a/include/base/variable.h b/include/base/variable.h
index 9c6592d..952fcec 100644
--- a/include/base/variable.h
+++ b/include/base/variable.h
@@ -104,7 +104,13 @@ public:
    */
   bool implicitly_active () const
   { return _active_subdomains.empty(); }
-  
+
+  /**
+   * Returns set of subdomain ids this variable lives on
+   */
+  const std::set<subdomain_id_type> & active_subdomains() const
+  { return _active_subdomains; }
+
 private:
   std::string             _name; 
   unsigned int            _number;
diff --git a/include/utils/xdr_cxx.h b/include/utils/xdr_cxx.h
index 2ff8397..952ced7 100644
--- a/include/utils/xdr_cxx.h
+++ b/include/utils/xdr_cxx.h
@@ -145,6 +145,15 @@ public:
    */   
   void comment (std::string &);
   
+  /**
+   * Sets the version of the file that is being read
+   */
+  void set_version(int ver) { version_number = ver; }
+
+  /**
+   * Gets the version of the file that is being read
+   */
+  int version() const { return version_number; }
 
 private:
 
@@ -225,6 +234,11 @@ private:
    * Are we reading/writing zipped files?
    */
   bool gzipped_file, bzipped_file, xzipped_file;
+
+  /**
+   * Version of the file being read
+   */
+  int version_number;
 };
 
 
diff --git a/src/systems/equation_systems_io.C b/src/systems/equation_systems_io.C
index 2e5e6db..55f2663 100644
--- a/src/systems/equation_systems_io.C
+++ b/src/systems/equation_systems_io.C
@@ -236,10 +236,12 @@ void EquationSystems::_read_impl (const std::string& name,
       {
 	if (libMesh::processor_id() == 0) io.data(version);	
 	Parallel::broadcast(version);
+	std::cerr << version << std::endl;
 	
 	// All processors have the version header, if it does not contain
 	// "libMesh" something then it is a legacy file.
-	if (!(version.find("libMesh") < version.size()))
+	int lm_pos = version.find("libMesh");
+	if (!(lm_pos < version.size()))
 	  {
 	    io.close();
 	    
@@ -249,6 +251,14 @@ void EquationSystems::_read_impl (const std::string& name,
 	    return;
 	  }
 
+	// Figure out the libMesh version that created this file
+	std::istringstream iss(version.substr(lm_pos + 8));
+	int ver_major = 0, ver_minor = 0, ver_patch = 0;
+	char dot;
+	iss >> ver_major >> dot >> ver_minor >> dot >> ver_patch;
+	io.set_version(LIBMESH_VERSION(ver_major, ver_minor, ver_patch));
+
+
 	read_parallel_files = (version.rfind(" parallel") < version.size());
 
 	// If requested that we try to read infinite element information,
@@ -479,7 +489,7 @@ void EquationSystems::write(const std::string& name,
       {
 	// 1.)
 	// Write the version header
-	std::string version = "libMesh-0.7.0+";
+	std::string version = "libMesh-0.7.2";
 	if (write_parallel_files) version += " parallel";
 	
 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
diff --git a/src/systems/system_io.C b/src/systems/system_io.C
index a7891e7..d02dac8 100644
--- a/src/systems/system_io.C
+++ b/src/systems/system_io.C
@@ -100,6 +100,8 @@ void System::read_header (Xdr& io,
   //   for each variable in the system
   //     
   //     6.) The name of the variable (string)
+  //
+  //     6.1.) Variable subdmains
   //     
   //     7.) Combined in an FEType:
   //         - The approximation order(s) of the variable 
@@ -147,6 +149,17 @@ void System::read_header (Xdr& io,
 	if (libMesh::processor_id() == 0) io.data (var_name);
 	Parallel::broadcast(var_name);
 	      	
+	// 6.1.)
+	std::set<subdomain_id_type> domains;
+	if (io.version() >= LIBMESH_VERSION(0,7,2))
+	{
+	  std::vector<subdomain_id_type> domain_array;
+	  if (libMesh::processor_id() == 0) io.data (domain_array);
+	  for (std::vector<subdomain_id_type>::iterator it = domain_array.begin(); it != domain_array.end(); ++it)
+		  domains.insert(*it);
+	}
+	Parallel::broadcast(domains);
+
 	// 7.)
 	// Read the approximation order(s) of the var-th variable 
 	int order=0;	  
@@ -208,9 +221,14 @@ void System::read_header (Xdr& io,
 
 #endif
 
-	if (read_header) 
-	  _written_var_indices[var] = this->add_variable (var_name, type);
-        else
+	if (read_header)
+	{
+	  if (domains.empty())
+	    _written_var_indices[var] = this->add_variable (var_name, type);
+	  else
+	    _written_var_indices[var] = this->add_variable (var_name, type, &domains);
+	}
+    else
 	  _written_var_indices[var] = this->variable_number(var_name);
       }
   }
@@ -969,6 +987,8 @@ void System::write_header (Xdr& io,
    *     
    *     6.) The name of the variable (string)
    *     
+   *     6.1.) subdomain where the variable lives
+   *
    *     7.) Combined in an FEType:
    *         - The approximation order(s) of the variable 
    *           (Order Enum, cast to int/s)
@@ -1027,6 +1047,22 @@ void System::write_header (Xdr& io,
 	io.data (var_name, comment.c_str());
       }
       
+      // 6.1.) Variable subdomains
+      {
+        // set up the comment
+		comment  = "#     Subdomains, Variable \"";
+		std::sprintf(buf, "%s", this->variable_name(var).c_str());
+		comment += buf;
+		comment += "\", System \"";
+		comment += this->name();
+		comment += "\"";
+
+		const std::set<subdomain_id_type> & domains = this->variable(var).active_subdomains();
+		std::vector<subdomain_id_type> domain_array;
+		domain_array.assign(domains.begin(), domains.end());
+		io.data (domain_array, comment.c_str());
+      }
+
       // 7.)
       // Write the approximation order of the var-th variable 
       // in this system
-- 
1.7.5.4

