MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
module-udunits.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/modules/module-udunits/module-udunits.cc,v 1.17 2017/01/12 14:58:21 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 /*
33  * Registers a namespace that adds support for unit conversion
34  * in math parser, based on UNIDATA's UDUNITS
35  * <http://www.unidata.ucar.edu/software/udunits/>
36  */
37 
38 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
39 
40 #include "mathp.h"
41 #include "dataman.h"
42 
43 extern "C" {
44 #include <udunits.h>
45 }
46 
48 protected:
50 
51 public:
52  UDUnitsNameSpace(const char *path);
53  ~UDUnitsNameSpace(void);
54 
55  bool IsFunc(const std::string& fname) const;
56  MathParser::MathFunc_t* GetFunc(const std::string& fname) const;
58  virtual Table* GetTable(void);
59 };
60 
61 static int
63 {
64  ASSERT(args.size() == 1 + 2 + 1);
65  ASSERT(args[0]->Type() == MathParser::AT_REAL);
66  ASSERT(args[1]->Type() == MathParser::AT_STRING);
67  ASSERT(args[2]->Type() == MathParser::AT_STRING);
68  ASSERT(args[3]->Type() == MathParser::AT_REAL);
69 
70  MathParser::MathArgReal_t *out = dynamic_cast<MathParser::MathArgReal_t *>(args[0]);
71  ASSERT(out != 0);
72 
73  MathParser::MathArgString_t *arg1 = dynamic_cast<MathParser::MathArgString_t *>(args[1]);
74  ASSERT(arg1 != 0);
75 
76  MathParser::MathArgString_t *arg2 = dynamic_cast<MathParser::MathArgString_t *>(args[2]);
77  ASSERT(arg2 != 0);
78 
79  MathParser::MathArgReal_t *arg3 = dynamic_cast<MathParser::MathArgReal_t *>(args[3]);
80  ASSERT(arg3 != 0);
81 
82  int rc;
83 
84  utUnit u_from;
85  rc = utScan((*arg1)().c_str(), &u_from);
86  switch (rc) {
87  case 0:
88  break;
89 
90  default:
91  /* TODO: handle specific errors */
92  silent_cerr("module-udunits: utScan could not interpret "
93  "unit \"" << (*arg1)() << "\" in first arg"
94  << std::endl);
96  }
97 
98  utUnit u_to;
99  rc = utScan((*arg2)().c_str(), &u_to);
100  switch (rc) {
101  case 0:
102  break;
103 
104  default:
105  silent_cerr("module-udunits: utScan could not interpret "
106  "unit \"" << (*arg2)() << "\" in second arg"
107  << std::endl);
109  }
110 
111  double slope, intercept;
112  rc = utConvert(&u_from, &u_to, &slope, &intercept);
113  switch (rc) {
114  case 0:
115  break;
116 
117  default:
118  silent_cerr("module-udunits: utConvert failed (rc=" << rc << ")" << std::endl);
120  }
121 
123  if (intercept != 0) {
124  silent_cerr("module-udunits: conversion between \"" << (*arg1)() << "\" "
125  "and \"" << (*arg2)() << "\" "
126  "has non-zero intercept" << std::endl);
128  }
129 
130  *out = slope;
131 
132  } else {
133  *out = (*arg3)()*slope + intercept;
134  }
135 
136  return 0;
137 }
138 
140 : MathParser::NameSpace("units")
141 {
142  int rc = utInit(path);
143 
144  if (path == 0) {
145  path = "<unspecified>";
146  }
147 
148  switch (rc) {
149  case 0:
150  // success
151  break;
152 
153  case UT_ENOFILE:
154  silent_cerr("utUnit could not find file \"" << path << "\""
155  << std::endl);
157 
158  case UT_ESYNTAX:
159  silent_cerr("utUnit found a syntax error "
160  "in file \"" << path << "\"" << std::endl);
162 
163  case UT_EUNKNOWN:
164  silent_cerr("utUnit found an unknown specification "
165  "in file \"" << path << "\"" << std::endl);
167 
168  case UT_EIO:
169  silent_cerr("utUnit hit an I/O error while reading "
170  "file \"" << path << "\"" << std::endl);
172 
173  case UT_EALLOC:
174  silent_cerr("utUnit ran out of memory while reading "
175  "file \"" << path << "\"" << std::endl);
177  }
178 
179  f.fname = "convert";
180  f.ns = this;
181  f.args.resize(1 + 3);
186  f.f = unit_convert;
187  f.t = 0;
188 }
189 
191 {
192  utTerm();
193 }
194 
195 bool
196 UDUnitsNameSpace::IsFunc(const std::string& fname) const
197 {
198  return (fname.compare(f.fname) == 0);
199 }
200 
202 UDUnitsNameSpace::GetFunc(const std::string& fname) const
203 {
204  if (fname.compare(f.fname) == 0) {
205  return new MathParser::MathFunc_t(f);
206  }
207 
208  return 0;
209 }
210 
211 TypedValue
213 {
214  f->f(f->args);
215 
216  return TypedValue((*dynamic_cast<MathParser::MathArgReal_t*>(f->args[0]))());
217 }
218 
219 Table*
221 {
222  return 0;
223 }
224 
225 extern "C" int
226 module_init(const char *module_name, void *pdm, void *php)
227 {
228  MBDynParser *pHP = (MBDynParser *)php;
229 
230  const char *path = 0;
231  if (pHP->IsArg()) {
232  path = pHP->GetFileName();
233  }
234 
235  /* registers unit conversion namespace */
236  MathParser::NameSpace *pNS = new UDUnitsNameSpace(path);
237  int rc = pHP->GetMathParser().RegisterNameSpace(pNS);
238  if (rc != 0) {
239  delete pNS;
240  }
241  return rc;
242 }
243 
MathArgPriv_t< Real, AT_REAL > MathArgReal_t
Definition: mathp.h:155
MathParser::MathFunc_t f
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
MathParser::MathFunc_t * GetFunc(const std::string &fname) const
int RegisterNameSpace(NameSpace *ns)
Definition: mathp.cc:4602
std::vector< MathArg_t * > MathArgs
Definition: mathp.h:158
virtual const char * GetFileName(enum Delims Del=DEFAULTDELIM)
Definition: parsinc.cc:673
TypedValue EvalFunc(MathParser::MathFunc_t *f) const
MathFunc_f f
Definition: mathp.h:170
MathFuncTest_f t
Definition: mathp.h:171
UDUnitsNameSpace(const char *path)
bool IsFunc(const std::string &fname) const
virtual MathParser & GetMathParser(void)
Definition: parser.cc:668
#define ASSERT(expression)
Definition: colamd.c:977
MathArgPriv_t< std::string, AT_STRING > MathArgString_t
Definition: mathp.h:156
virtual Table * GetTable(void)
int module_init(const char *module_name, void *pdm, void *php)
This function registers our user defined element for the math parser.
virtual bool IsArg(void)
Definition: parser.cc:807
NameSpace * ns
Definition: mathp.h:168
Definition: table.h:43
bool IsFlag(const MathParser::ArgFlag f) const
Definition: mathp.h:98
static std::stack< const HighParser * > pHP
Definition: parser.cc:598
static int unit_convert(const MathParser::MathArgs &args)
std::string fname
Definition: mathp.h:167
const char * path
Definition: autopilot.c:141