Flow123d  release_1.8.2-1603-g0109a2b
unit_si.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file unit_si.cc
15  * @brief
16  */
17 
18 #include <sstream>
19 
20 #include "fields/unit_si.hh"
21 #include "system/xio.h"
22 
23 
24 using namespace std;
25 
26 
28  exponents_.resize(UnitSI::n_base_units);
29  std::fill(exponents_.begin(), exponents_.end(), 0);
30  undef_ = true;
31 }
32 
34  static UnitSI unit = UnitSI().m().kg().s(-2);
35  return unit;
36 }
37 
39  static UnitSI unit = UnitSI().m(2).kg().s(-2);
40  return unit;
41 }
42 
44  static UnitSI unit = UnitSI().m(2).kg().s(-3);
45  return unit;
46 }
47 
49  static UnitSI unit = UnitSI().m(-1).kg().s(-2);
50  return unit;
51 }
52 
54  static UnitSI unit = UnitSI().m(0);
55  return unit;
56 }
57 
58 UnitSI & UnitSI::m(int exp) {
59  exponents_[UnitSI::order_m] = exp;
60  undef_ = false;
61  return *this;
62 }
63 
64 UnitSI & UnitSI::kg(int exp) {
65  exponents_[UnitSI::order_kg] = exp;
66  undef_ = false;
67  return *this;
68 }
69 
70 UnitSI & UnitSI::s(int exp) {
71  exponents_[UnitSI::order_s] = exp;
72  undef_ = false;
73  return *this;
74 }
75 
76 UnitSI & UnitSI::A(int exp) {
77  exponents_[UnitSI::order_A] = exp;
78  undef_ = false;
79  return *this;
80 }
81 
82 UnitSI & UnitSI::K(int exp) {
83  exponents_[UnitSI::order_K] = exp;
84  undef_ = false;
85  return *this;
86 }
87 
88 UnitSI & UnitSI::mol(int exp) {
89  exponents_[UnitSI::order_mol] = exp;
90  undef_ = false;
91  return *this;
92 }
93 
94 UnitSI & UnitSI::cd(int exp) {
95  exponents_[UnitSI::order_cd] = exp;
96  undef_ = false;
97  return *this;
98 }
99 
100 UnitSI & UnitSI::md(int exp) {
101  exponents_[UnitSI::order_md] = exp;
102  undef_ = false;
103  return *this;
104 }
105 
106 
107 
108 
109 
110 
111 std::string UnitSI::format_latex() const {
112  OutputFormat form;
113  form.exp_open="^{";
114  form.exp_close="}";
115  form.delimiter="";
116  return format(form);
117 }
118 
119 
120 
121 std::string UnitSI::format_text() const {
122  OutputFormat form;
123  form.exp_open="(";
124  form.exp_close=")";
125  form.delimiter=".";
126  return format(form);
127 }
128 
129 
130 // Symbols for base SI units.
131 const std::string &UnitSI::unit_symbol(unsigned int idx) {
132  static std::vector<std::string> unit_symbols={"m","md","kg","s","A","K","mol","cd" };
133  return unit_symbols[idx];
134 }
135 
136 
137 
138 std::string UnitSI::format(OutputFormat form) const {
139  OLD_ASSERT(is_def(), "UnitSI object must be defined!");
140 
141  std::stringstream output;
142 
143  // format of meter (can be m^{n} or m^{n-d})
144  if (exponents_[ UnitSI::order_m ] || exponents_[ UnitSI::order_md ]) {
145  output << unit_symbol( UnitSI::order_m );
146  if (exponents_[ UnitSI::order_m ]!=1 || exponents_[ UnitSI::order_md ]) {
147  output << form.exp_open;
148  if (exponents_[ UnitSI::order_m ]) {
149  output << exponents_[ UnitSI::order_m ];
150  if (exponents_[ UnitSI::order_md ]>0) output << "+";
151  }
152  if (exponents_[ UnitSI::order_md ]) {
153  if (exponents_[ UnitSI::order_md ]==-1) output << "-";
154  else if (exponents_[ UnitSI::order_md ]!=1) output << exponents_[ UnitSI::order_md ];
155  output << "d"; // Use 'd' for dimension in exponent, converting m^x md^y to m^(x+yd)
156  }
157  output << form.exp_close;
158  }
159  }
160 
161  // format of other units
162  for (unsigned int i=2; i<UnitSI::n_base_units; i++)
163  if (exponents_[i]) {
164  if (output.str().size() > 0) output << form.delimiter;
165  output << unit_symbol(i);
166  if (exponents_[i] != 1) output << form.exp_open << exponents_[i] << form.exp_close;
167  }
168 
169  if (output.str().size()==0) { //dimensionless quantity, contains only "$["
170  output << "-";
171  }
172 
173  return output.str();
174 }
175 
176 
177 std::string UnitSI::json() const {
178  stringstream ss;
179  ss << "{ ";
180  for(unsigned int i=0; i < n_base_units; i++ ) {
181  if (i!=0) ss << ", ";
182  ss << string("\"")
183  << unit_symbol(i)
184  << "\" : "
185  << exponents_[i];
186  }
187  ss << " }";
188  return ss.str();
189 }
190 
191 void UnitSI::undef(bool val) {
192  undef_ = val;
193 }
194 
195 bool UnitSI::is_def() const {
196  return !undef_;
197 }
198 
199 
200 UnitSI operator *(const UnitSI &a, const UnitSI &b) {
201  UnitSI tmp;
202 
203  if (a.is_def() && b.is_def()) {
204  tmp.undef_ = false;
205  for (unsigned int i=0; i<7; i++) {
206  tmp.exponents_[i] = a.exponents_[i] + b.exponents_[i];
207  }
208  }
209 
210  return tmp;
211 }
212 
213 UnitSI operator /(const UnitSI &a, const UnitSI &b) {
214  UnitSI tmp;
215 
216  if (a.is_def() && b.is_def()) {
217  tmp.undef_ = false;
218  for (unsigned int i=0; i<7; i++) {
219  tmp.exponents_[i] = a.exponents_[i] - b.exponents_[i];
220  }
221  }
222 
223  return tmp;
224 }
std::string format(OutputFormat form) const
Generic output formating method.
Definition: unit_si.cc:138
bool is_def() const
Return true if the unit is defined.
Definition: unit_si.cc:195
Variable parts of output format. Used in the format method.
Definition: unit_si.hh:110
std::string format_text() const
Definition: unit_si.cc:121
std::vector< int > exponents_
Definition: unit_si.hh:129
static UnitSI & Pa()
Returns Pascal.
Definition: unit_si.cc:48
std::string format_latex() const
Definition: unit_si.cc:111
UnitSI & K(int exp=1)
Definition: unit_si.cc:82
UnitSI & A(int exp=1)
Definition: unit_si.cc:76
I/O functions with filename storing, able to track current line in opened file. All standard stdio fu...
UnitSI operator*(const UnitSI &a, const UnitSI &b)
Product of two units.
Definition: unit_si.cc:200
#define OLD_ASSERT(...)
Definition: global_defs.h:128
UnitSI operator/(const UnitSI &a, const UnitSI &b)
Proportion of two units.
Definition: unit_si.cc:213
std::string delimiter
Definition: unit_si.hh:111
UnitSI & cd(int exp=1)
Definition: unit_si.cc:94
static UnitSI & W()
Returns Watt.
Definition: unit_si.cc:43
UnitSI & s(int exp=1)
Definition: unit_si.cc:70
UnitSI & kg(int exp=1)
Definition: unit_si.cc:64
static UnitSI & J()
Returns Joule.
Definition: unit_si.cc:38
std::string exp_close
Definition: unit_si.hh:111
static UnitSI & N()
Definition: unit_si.cc:33
static const std::string & unit_symbol(unsigned int idx)
Definition: unit_si.cc:131
bool undef_
Definition: unit_si.hh:137
UnitSI & mol(int exp=1)
Definition: unit_si.cc:88
UnitSI & m(int exp=1)
Methods set values of exponents for SI units with similar name.
Definition: unit_si.cc:58
Class for representation SI units of Fields.
Definition: unit_si.hh:40
UnitSI & md(int exp=-1)
The dimension dependent meter: md^y = m^(yd), where &#39;d&#39; is dimension.
Definition: unit_si.cc:100
static UnitSI & dimensionless()
Returns dimensionless unit.
Definition: unit_si.cc:53
void undef(bool val=true)
Definition: unit_si.cc:191
std::string exp_open
Definition: unit_si.hh:111
UnitSI()
Constructor.
Definition: unit_si.cc:27
std::string json() const
Definition: unit_si.cc:177