[Debian-astro-commits] [gyoto] 110/221: New Property type: std::vector<double> (used in NumericalMetricLorene)

Thibaut Jean-Claude Paumard thibaut at moszumanska.debian.org
Fri May 22 20:52:38 UTC 2015


This is an automated email from the git hooks/post-receive script.

thibaut pushed a commit to branch master
in repository gyoto.

commit f4996d72f9cc03a1ab27fa6b4d6108ad246348de
Author: Thibaut Paumard <paumard at users.sourceforge.net>
Date:   Wed Nov 26 16:11:34 2014 +0100

    New Property type: std::vector<double> (used in NumericalMetricLorene)
---
 include/GyotoFactory.h               |  6 +++++
 include/GyotoFactoryMessenger.h      | 11 +++++++++
 include/GyotoNumericalMetricLorene.h |  7 ++----
 include/GyotoObject.h                | 24 ++++++++++++++++++-
 lib/Factory.C                        | 45 ++++++++++++++++++++++++++++++++++++
 lib/NumericalMetricLorene.C          | 39 +++++++++++--------------------
 lib/Object.C                         | 35 ++++++++++++++++++++++++++++
 yorick/gyoto_utils.C                 | 19 +++++++++++++++
 8 files changed, 154 insertions(+), 32 deletions(-)

diff --git a/include/GyotoFactory.h b/include/GyotoFactory.h
index b5d92d9..aa0d018 100644
--- a/include/GyotoFactory.h
+++ b/include/GyotoFactory.h
@@ -29,6 +29,8 @@
 #ifndef __GyotoFactory_H_
 #define __GyotoFactory_H_
 
+#include <vector>
+
 #include "GyotoConfig.h"
 
 /// Xerces internal.
@@ -391,6 +393,10 @@ class Gyoto::Factory
 		    xercesc::DOMElement* pel,
 		    FactoryMessenger **child = NULL);
 
+  void setParameter(std::string name, std::vector<double> const &val,
+		    xercesc::DOMElement* pel,
+		    FactoryMessenger **child = NULL);
+
   /// Transform relative path into absolute path.
   /**
    * relpath is interpreted as follows:
diff --git a/include/GyotoFactoryMessenger.h b/include/GyotoFactoryMessenger.h
index 7ec704c..c9826c6 100644
--- a/include/GyotoFactoryMessenger.h
+++ b/include/GyotoFactoryMessenger.h
@@ -34,6 +34,7 @@
 #define XERCES_INCLUDE_WCHAR_H 0
 #endif
 #include <xercesc/dom/DOMElement.hpp>
+#include <vector>
 #include <string>
 #include <GyotoDefs.h>
 #include <GyotoSmartPointer.h>
@@ -392,6 +393,9 @@ class Gyoto::FactoryMessenger {
 		    FactoryMessenger** child= NULL);
   ///< Output an array of parameters
 
+  void setParameter(std::string name, std::vector<double> const &val,
+		    FactoryMessenger** child= NULL);
+  ///< Output a vector of parameters
 
   /**
    * For instance Spectrometer::fillElement() sets its "kind"
@@ -466,6 +470,13 @@ class Gyoto::FactoryMessenger {
    */
   static size_t parseArray(std::string src, double dst[], size_t max_tokens);
 
+  /**
+   * \brief Parse string into array
+   *
+   * Parse tokens from string src, returns them into a
+   * std::vector<double>.
+   */
+  static std::vector<double> parseArray(std::string src);
 };
 
 #endif
diff --git a/include/GyotoNumericalMetricLorene.h b/include/GyotoNumericalMetricLorene.h
index 8580c52..fc5fcc4 100644
--- a/include/GyotoNumericalMetricLorene.h
+++ b/include/GyotoNumericalMetricLorene.h
@@ -100,6 +100,8 @@ class Gyoto::Metric::NumericalMetricLorene
   void specifyMarginalOrbits(bool s);
   bool mapEt() const;
   void mapEt(bool s);
+  std::vector<double> refineIntegStep() const;
+  void refineIntegStep(std::vector<double> const&);
 
   char const * getFileName() const;
   Lorene::Vector** getShift_tab() const;
@@ -190,11 +192,6 @@ class Gyoto::Metric::NumericalMetricLorene
   int diff(double tt, const double y[7], double res[7]) const ;
   virtual int diff(const double y[7], double res[7], int indice_time) const ;
 
-  virtual int setParameter(std::string, std::string, std::string);
-#ifdef GYOTO_USE_XERCES
-  virtual void fillElement(FactoryMessenger *fmp); /// < called from Factory
-#endif
-
 };
 
 #endif
diff --git a/include/GyotoObject.h b/include/GyotoObject.h
index 1be811d..2f1b4bb 100644
--- a/include/GyotoObject.h
+++ b/include/GyotoObject.h
@@ -28,6 +28,7 @@
 
 #include "GyotoConfig.h"
 #include <string>
+#include <vector>
 
 namespace Gyoto {
   class Object;
@@ -100,6 +101,15 @@ namespace Gyoto {
 	   (Gyoto::Property::get_string_t)&class::fname,	\
          name##_ancestors, false)
 
+/// Define a Property of type String
+#define GYOTO_PROPERTY_VECTOR_DOUBLE(class, name, fname, ancestor)	\
+  GYOTO_PROPERTY_MAKE_ANCESTORS(name, ancestor); \
+  Property const name \
+        (#name, \
+	   (Gyoto::Property::set_vector_double_t)&class::fname,	\
+	   (Gyoto::Property::get_vector_double_t)&class::fname,	\
+         name##_ancestors)
+
 /// Define class::properties and class::getProperties() 
 #define GYOTO_PROPERTY_FINALIZE(class, property)		\
   Property const * const class::properties = &property;		\
@@ -131,11 +141,13 @@ class Gyoto::Object
   void set(Property const &p, double val, std::string const &unit);
   void set(Property const &p, bool val);
   void set(Property const &p, std::string const &val);
+  void set(Property const &p, std::vector<double> const &val);
   //void set(std::string const pname, double val);
   void get(Property const &p, double &val) const ;
   void get(Property const &p, double &val, std::string const &unit) const ;
   void get(Property const &p, bool &val) const ;
   void get(Property const &p, std::string &val) const ;
+  void get(Property const &p, std::vector<double> &val) const;
   //void get(std::string const pname, double &val);
   Property const * property(std::string const pname) const;
   virtual Property const * getProperties() const;
@@ -216,7 +228,8 @@ class Gyoto::Property
  private:
 
  public:
-  enum type_e {double_t, long_t, bool_t, string_t, filename_t};
+  enum type_e {double_t, long_t, bool_t, string_t, filename_t,
+	       vector_double_t};
   std::string name;
   std::string name_false;
   int type;
@@ -233,17 +246,21 @@ class Gyoto::Property
   typedef std::string (Object::* get_string_t)() const;
   typedef void (Object::* set_fname_t)(std::string const&);
   typedef std::string (Object::* get_fname_t)() const;
+  typedef void (Object::* set_vector_double_t)(std::vector<double> const&);
+  typedef std::vector<double> (Object::* get_vector_double_t)() const;
   union setter_t {
     set_double_t set_double;
     set_long_t set_long;
     set_bool_t set_bool;
     set_string_t set_string;
+    set_vector_double_t set_vdouble;
   };
   union getter_t {
     get_double_t get_double;
     get_long_t get_long;
     get_bool_t get_bool;
     get_string_t get_string;
+    get_vector_double_t get_vdouble;
   };
   union setter_unit_t {set_double_unit_t set_double;};
   union getter_unit_t {get_double_unit_t get_double;};
@@ -277,6 +294,11 @@ class Gyoto::Property
 	   Property const * const * ancestors,
 	   bool is_filename=false);
 
+  Property(std::string name,
+	   set_vector_double_t set_vdouble,
+	   get_vector_double_t get_vdouble,
+	   Property const * const * ancestors);
+
   Property const * find(std::string name) const;
 
 };
diff --git a/lib/Factory.C b/lib/Factory.C
index d1f3fcf..4a313ce 100644
--- a/lib/Factory.C
+++ b/lib/Factory.C
@@ -763,6 +763,23 @@ void Factory::setParameter(std::string name, double val[],
 
 }
 
+void Factory::setParameter(std::string name,
+			   std::vector<double> const &val,
+			   DOMElement *pel, FactoryMessenger **child){
+
+  ostringstream ss;
+  ss << setprecision(GYOTO_PREC) << setw(GYOTO_WIDTH) << val[0];
+  size_t n=val.size();
+  for (size_t i=1; i<n; ++i) {
+    ss << " " << setprecision(GYOTO_PREC) << setw(GYOTO_WIDTH) << val[i];
+  }
+  DOMElement*  el = doc_->createElement(X(name.c_str()));
+  pel -> appendChild(el);
+  el->appendChild( doc_->createTextNode(X(ss.str().c_str())) );
+  if (child) *child = new FactoryMessenger(this, el);
+
+}
+
 void Factory::setContent(std::string content, DOMElement *el) {
   el -> appendChild( doc_->createTextNode( X( content.c_str() ) ) );
 }
@@ -927,6 +944,11 @@ void FactoryMessenger::setParameter(std::string name, double val[], size_t n,
 				    FactoryMessenger **child){
   employer_ -> setParameter(name, val, n, element_, child);
 }
+void FactoryMessenger::setParameter(std::string name,
+				    std::vector<double> const &val,
+				    FactoryMessenger **child){
+  employer_ -> setParameter(name, val, element_, child);
+}
 
 size_t FactoryMessenger::parseArray(std::string content, double val[], size_t max_tokens)
 {
@@ -952,6 +974,29 @@ size_t FactoryMessenger::parseArray(std::string content, double val[], size_t ma
   return n;
 }
 
+std::vector<double> FactoryMessenger::parseArray(std::string content)
+{
+  std::vector<double> result;
+  char const * const delim = " \t\n" ;
+  char const * const c_content=content.c_str();
+  size_t len=strlen(c_content);
+  if (len==0) return result;
+
+  size_t n=0;
+  char * const tc = new char[len+1];
+  memcpy(tc, c_content, len+1);
+  char * sub = strtok(tc, delim);
+
+  while (sub) {
+    result.push_back(Gyoto::atof(sub));
+    sub = strtok(NULL, delim);
+  }
+  
+  delete [] tc;
+
+  return result;
+}
+
 std::string FactoryMessenger::fullPath(std::string fname) {
   return employer_ -> fullPath(fname);
 }
diff --git a/lib/NumericalMetricLorene.C b/lib/NumericalMetricLorene.C
index 8558256..50daaf6 100644
--- a/lib/NumericalMetricLorene.C
+++ b/lib/NumericalMetricLorene.C
@@ -31,8 +31,11 @@ using namespace Gyoto::Metric;
 // Keep File first here, so it is processed last in fillElement() 
 GYOTO_PROPERTY_FILENAME(NumericalMetricLorene,
 			File, directory, Generic::properties);
+GYOTO_PROPERTY_VECTOR_DOUBLE(NumericalMetricLorene,
+			     RefineIntegStep, refineIntegStep,
+			     &File);
 GYOTO_PROPERTY_DOUBLE(NumericalMetricLorene,
-		      Time, initialTime, &File);
+		      Time, initialTime, &RefineIntegStep);
 GYOTO_PROPERTY_DOUBLE(NumericalMetricLorene,
 		      Horizon, horizon, &Time);
 GYOTO_PROPERTY_BOOL(NumericalMetricLorene,
@@ -1647,30 +1650,14 @@ void NumericalMetricLorene::initialTime(double t0) {initial_time_=t0;}
 double NumericalMetricLorene::horizon() const {return horizon_;}
 void NumericalMetricLorene::horizon(double r0) {horizon_=r0;}
 
-int  NumericalMetricLorene::setParameter(string name,
-					  string content,
-					  string unit) {
-  GYOTO_DEBUG << endl;
-  if (name=="RefineIntegStep"){
-    refine_=1;
-    double parms[2];
-    if (FactoryMessenger::parseArray(content, parms, 2) != 2)
-      throwError("NumericalMetricLorene \"RefineIntegStep\" requires exactly 2 tokens");
-    r_refine_  = parms[0];
-    h0_refine_ = parms[1];
-  }
-  else  return Generic::setParameter(name, content, unit);
-  return 0;
+vector<double> NumericalMetricLorene::refineIntegStep() const {
+  vector<double> v (2, r_refine_); // set both elements to r_refine_
+  v[1] = h0_refine_;               // then set the second one to h0_refine_
+  return v;
 }
-
-#ifdef GYOTO_USE_XERCES
-void NumericalMetricLorene::fillElement(Gyoto::FactoryMessenger *fmp) {
-  GYOTO_DEBUG << endl;
-  if (refine_) {
-    double parms[2] = {r_refine_, h0_refine_};
-    fmp -> setParameter("RefineIntegStep", parms, 2);
-  }
-  Generic::fillElement(fmp);
+void NumericalMetricLorene::refineIntegStep(vector<double> const &v) {
+  if (v.size() != 2)
+      throwError("NumericalMetricLorene \"RefineIntegStep\" requires exactly 2 tokens");
+  r_refine_  = v[0];
+  h0_refine_ = v[1];
 }
-
-#endif
diff --git a/lib/Object.C b/lib/Object.C
index 3db6577..454de64 100644
--- a/lib/Object.C
+++ b/lib/Object.C
@@ -56,6 +56,14 @@ void Object::set(Property const &p, string const &val) {
   } else throwError("Cannot set this Property from a string");
 }
 
+void Object::set(Property const &p, vector<double> const &val) {
+  if (p.type != Property::vector_double_t)
+    throwError("Property is not a vector<double>");
+  Property::set_vector_double_t set = p.setter.set_vdouble;
+  if (!set) throwError("Can't set this Property");
+  (this->*set)(val);
+}
+
 // void Object::set(std::string const pname, double val) {
 //   Property const * const p = property(pname);
 //   if (!p) throwError ("No such Property");
@@ -105,6 +113,14 @@ void Object::get(Property const &p, string &val) const {
   }
 }
 
+void Object::get(Property const &p, vector<double> &val) const {
+  if (p.type != Property::vector_double_t)
+    throwError("Property is not a vector<double>");
+  Property::get_vector_double_t get = p.getter.get_vdouble;
+  if (!get) throwError("Can't get this Property");
+  val = (this->*get)();
+}
+
 // void Object::get(std::string const pname, double &val) {
 //   Property const * const p = property(pname);
 //   if (!p) throwError ("No such Property");
@@ -146,6 +162,13 @@ void Object::fillProperty(Gyoto::FactoryMessenger *fmp, Property const &p) {
       fmp->setParameter(name, val);
     }
     break;
+  case Property::vector_double_t:
+    {
+      std::vector<double> val;
+      get(p, val);
+      fmp->setParameter(name, val);
+    }
+    break;
   default:
     throwError("Property type unimplemented in Object::fillProperty()");
   }
@@ -199,6 +222,9 @@ void Object::setParameter(Property const &p, string const &name,
   case Property::string_t:
     set(p, content);
     return;
+  case Property::vector_double_t:
+    set(p, FactoryMessenger::parseArray(content));
+    return;
   default:
     throwError("Property type unimplemented in Object::setParameter()");
   }
@@ -247,6 +273,15 @@ Property::Property(string n, set_string_t set, get_string_t get,
   getter.get_string=get;
 }
 
+Property::Property(string n,
+		   set_vector_double_t set,
+		   get_vector_double_t get,
+		   Property const * const * ancestors)
+  : name(n), type(vector_double_t), parents(ancestors) {
+  setter.set_vdouble=set;
+  getter.get_vdouble=get;
+}
+
 Property const * Property::find(std::string n) const {
   if (this == NULL) return NULL;
   if (name == n || (type == bool_t && name_false == n)) return this;
diff --git a/yorick/gyoto_utils.C b/yorick/gyoto_utils.C
index 8ee8477..ffa91e8 100644
--- a/yorick/gyoto_utils.C
+++ b/yorick/gyoto_utils.C
@@ -377,6 +377,16 @@ void ypush_property(Gyoto::SmartPointer<Gyoto::SmartPointee> ptr,
       *ypush_q(0) = p_strcpy(val.c_str());
     }
     break;
+  case Gyoto::Property::vector_double_t:
+    {
+      std::vector<double> val;
+      ptr->get(p, val);
+      size_t n=val.size();
+      long dims[]={1, long(n)};
+      double * buf = ypush_d(dims);
+      for (size_t i=0; i<n; ++i) buf[i]=val[i];
+    }
+    break;
   default:
     y_error("Property type unimplemented in ypush_property()");
    }
@@ -400,6 +410,15 @@ void yget_property(Gyoto::SmartPointer<Gyoto::SmartPointee> ptr,
   case Gyoto::Property::string_t:
     ptr -> set(p, string(ygets_q(iarg)));
     return;
+  case Gyoto::Property::vector_double_t:
+    {
+      long n;
+      double *buf = ygeta_d(iarg, &n, NULL);
+      std::vector<double> val(n, 0.);
+      for (size_t i=0; i<n; ++i) val[i]=buf[i];
+      ptr -> set(p, val);
+    }
+    return;
   default:
     y_error("Property type unimplemented in yget_property()");
    }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-astro/packages/gyoto.git



More information about the Debian-astro-commits mailing list