Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
UdunitsPhysicalUnitSystemService.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* UdunitsUnitSystem.h (C) 2000-2014 */
9/* */
10/* Gestion de système d'unité physique utilisant 'udunits2'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/NotImplementedException.h"
18#include "arcane/utils/FatalErrorException.h"
19#include "arcane/utils/ArgumentException.h"
20#include "arcane/utils/Array.h"
21#include "arcane/utils/TraceInfo.h"
22
23#include "arcane/FactoryService.h"
24#include "arcane/AbstractService.h"
25#include "arcane/IPhysicalUnitSystemService.h"
26#include "arcane/IPhysicalUnitSystem.h"
27#include "arcane/IPhysicalUnitConverter.h"
28#include "arcane/IPhysicalUnit.h"
29
30#include <udunits2.h>
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35ARCANE_BEGIN_NAMESPACE
36
37class UdunitsPhysicalUnitConverter;
38class UdunitsPhysicalUnit;
39class UdunitsPhysicalUnitSystem;
40
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
45: public IPhysicalUnit
46{
47 public:
48
49 friend class UdunitsPhysicalUnitSystem;
50
51 public:
52
54 const String& name)
55 : m_unit(unit)
56 {
57 // Pour garantir que la chaîne est allouée dynamiquement
58 m_name = String::fromUtf8(name.utf8());
59 }
60
61 UdunitsPhysicalUnit(::ut_unit* unit)
62 : m_unit(unit)
63 {
64 }
65
66 virtual ~UdunitsPhysicalUnit()
67 {
68 if (m_unit)
69 ut_free(m_unit);
70 }
71
72 virtual const String& name() const
73 {
74 return m_name;
75 }
76
77 private:
78
79 ::ut_unit* m_unit;
80 String m_name;
81};
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
88{
89 public:
90
94 ::cv_converter* converter)
95 : m_from_unit(from_unit), m_to_unit(to_unit), m_is_from_owned(true),
96 m_is_to_owned(true), m_converter(converter)
97 {
98 }
99
101 {
102 if (m_is_from_owned)
103 delete m_from_unit;
104 if (m_is_to_owned)
105 delete m_to_unit;
106 }
107
108 public:
109
110 virtual Real convert(Real value)
111 {
112 double new_value = cv_convert_double(m_converter,value);
113 return new_value;
114 }
115
118 {
119 Integer nb = input_values.size();
120 Integer nb_out = output_values.size();
121 if (nb!=nb_out)
122 throw ArgumentException(A_FUNCINFO,"input and ouput arrays do not have the same number of elements");
123 cv_convert_doubles(m_converter,input_values.data(),nb,output_values.data());
124 }
125
127 {
128 return m_from_unit;
129 }
130
132 {
133 return m_to_unit;
134 }
135
136 public:
137
138 private:
139 UdunitsPhysicalUnit* m_from_unit;
140 UdunitsPhysicalUnit* m_to_unit;
141 bool m_is_from_owned;
142 bool m_is_to_owned;
143 ::cv_converter* m_converter;
144};
145
146/*---------------------------------------------------------------------------*/
147/*---------------------------------------------------------------------------*/
148
150: public TraceAccessor
151, public IPhysicalUnitSystem
152{
153 public:
154
156 : TraceAccessor(tm), m_unit_system(0)
157 {
158 }
159
161 {
162 if (m_unit_system)
163 ut_free_system(m_unit_system);
164 }
165
167 {
168 // Normalement déjà créé.
169 _checkCreateUnitSystem();
172 if (!from_unit || !to_unit)
173 throw ArgumentException(A_FUNCINFO,"can not convert units to this system unit");
174 return _createConverter(from_unit,to_unit);
175 }
176
178 {
179 info() << "Create unit converter from='" << from << "' to='" << to << "'";
180 _checkCreateUnitSystem();
181 UdunitsPhysicalUnit* from_unit = _createUnit(from);
182 UdunitsPhysicalUnit* to_unit = _createUnit(to);
183 //TODO: detruire les unites en cas d'erreur.
184 return _createConverter(from_unit,to_unit);
185 }
186
187 private:
188
190 {
191 ::cv_converter* cv_cvt = ::ut_get_converter(from_unit->m_unit,to_unit->m_unit);
192 if (!cv_cvt)
193 throw FatalErrorException(A_FUNCINFO,
194 String::format("Can not convert from '{0}' to '{1}' because units are not convertible",
195 from_unit->name(),to_unit->name()));
197 return cvt;
198 }
199
200 void _checkCreateUnitSystem()
201 {
202 //TODO Ajouter lock...
203 if (!m_unit_system)
204 m_unit_system = ut_read_xml(0);
205 if (!m_unit_system)
206 throw FatalErrorException(A_FUNCINFO,"Can not load unit system");
207 }
208
209 UdunitsPhysicalUnit* _createUnit(const String& name)
210 {
211 ::ut_unit* unit = ut_parse(m_unit_system,(const char*)name.utf8().data(),UT_UTF8);
212 if (!unit)
213 throw FatalErrorException(A_FUNCINFO,String::format("Can not create unit from string '{0}'",name));
214 return new UdunitsPhysicalUnit(this,unit,name);
215 }
216
217 public:
218
219
220 private:
221
222 ::ut_system* m_unit_system;
223};
224
225/*---------------------------------------------------------------------------*/
226/*---------------------------------------------------------------------------*/
231: public AbstractService
233{
234 public:
235
237 virtual ~UdunitsUnitSystemService() {}
238
239 public:
240
241 virtual void build();
242
243 public:
244
246 {
248 return s;
249 }
250
251 private:
252
253};
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
261/*---------------------------------------------------------------------------*/
262/*---------------------------------------------------------------------------*/
263
264UdunitsUnitSystemService::
265UdunitsUnitSystemService(const ServiceBuildInfo& sbi)
266: AbstractService(sbi)
267{
268}
269
270/*---------------------------------------------------------------------------*/
271/*---------------------------------------------------------------------------*/
272
277
278/*---------------------------------------------------------------------------*/
279/*---------------------------------------------------------------------------*/
280
283 Udunits);
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
288ARCANE_END_NAMESPACE
289
290/*---------------------------------------------------------------------------*/
291/*---------------------------------------------------------------------------*/
#define ARCANE_REGISTER_APPLICATION_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Classe de base d'un service.
Interface d'un convertisseur d'unité.
Interface d'un service gérant un système d'unité.
Interface d'un système d'unité.
Unité physique.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Structure contenant les informations pour créer un service.
virtual IPhysicalUnit * fromUnit()
Unité de départ.
virtual void convert(RealConstArrayView input_values, RealArrayView output_values)
Retourne dans output_values les valeurs converties de input_values.
virtual Real convert(Real value)
Retourne la valeur convertie de value.
virtual IPhysicalUnit * toUnit()
Unité d'arrivée.
virtual IPhysicalUnitConverter * createConverter(const String &from, const String &to)
Créé un convertisseur entre deux unités. L'appelant doit détruire le convertisseur retourné.
virtual IPhysicalUnitConverter * createConverter(IPhysicalUnit *from, IPhysicalUnit *to)
Créé un convertisseur entre deux unités. L'appelant doit détruire le convertisseur retourné....
virtual const String & name() const
Nom de l'unité
Service de gestion de système d'unité physique utilisant 'udunits2'.
virtual void build()
Construction de niveau build du service.
virtual IPhysicalUnitSystem * createStandardUnitSystem()
Crée un système d'unité pour le Système International SI.
Exception lorsqu'un argument est invalide.
Vue modifiable d'un tableau d'un type T.
Vue constante d'un tableau de type T.
Exception lorsqu'une erreur fatale est survenue.
Interface du gestionnaire de traces.
Chaîne de caractères unicode.