pythonfmu3 0.3.3__py3-none-any.whl → 0.3.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pythonfmu3/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.3.3"
1
+ __version__ = "0.3.4"
pythonfmu3/fmi3slave.py CHANGED
@@ -183,8 +183,7 @@ class Fmi3SlaveBase(object):
183
183
  initial_unknown = list(
184
184
  filter(lambda v: (v.causality == Fmi3Causality.output and (v.initial in allowed_variability))
185
185
  or v.causality == Fmi3Causality.calculatedParameter
186
- or v in continuous_state_derivatives and v.initial in allowed_variability
187
- or v.variability == Fmi3Variability.continuous and v.initial in allowed_variability and v.causality != Fmi3Causality.independent, self.vars.values())
186
+ or v in continuous_state_derivatives and v.initial in allowed_variability, self.vars.values())
188
187
  )
189
188
 
190
189
  for v in outputs:
@@ -282,10 +281,13 @@ class Fmi3SlaveBase(object):
282
281
  for vr in vrs:
283
282
  var = self.vars[vr]
284
283
  if isinstance(var, Int32):
285
- refs.append(int(var.getter()))
284
+ if len(var.dimensions) == 0:
285
+ refs.append(int(var.getter()))
286
+ else:
287
+ refs.extend(map(int, var.getter()))
286
288
  else:
287
289
  raise TypeError(
288
- f"Variable with valueReference={vr} is not of type Integer!"
290
+ f"Variable with valueReference={vr} is not of type Int32!"
289
291
  )
290
292
  return refs
291
293
 
@@ -294,7 +296,10 @@ class Fmi3SlaveBase(object):
294
296
  for vr in vrs:
295
297
  var = self.vars[vr]
296
298
  if isinstance(var, (Enumeration, Int64)):
297
- refs.append(int(var.getter()))
299
+ if len(var.dimensions) == 0:
300
+ refs.append(int(var.getter()))
301
+ else:
302
+ refs.extend(map(int, var.getter()))
298
303
  else:
299
304
  raise TypeError(
300
305
  f"Variable with valueReference={vr} is not of type Int64!"
@@ -306,11 +311,14 @@ class Fmi3SlaveBase(object):
306
311
  for vr in vrs:
307
312
  var = self.vars[vr]
308
313
  if isinstance(var, UInt64):
309
- val = var.getter()
310
- refs.append(val if isinstance(val, ctypes.c_uint64) else ctypes.c_uint64(val))
314
+ if len(var.dimensions) == 0:
315
+ val = var.getter()
316
+ refs.append(ctypes.c_uint64(val) if not isinstance(val, ctypes.c_uint64) else val)
317
+ else:
318
+ refs.extend(map(ctypes.c_uint64, var.getter()))
311
319
  else:
312
320
  raise TypeError(
313
- f"Variable with valueReference={vr} is not of type UInt64!"
321
+ f"Variable with valueReference={vr} is not of type Uint64!"
314
322
  )
315
323
  return refs
316
324
 
@@ -325,7 +333,7 @@ class Fmi3SlaveBase(object):
325
333
  refs.extend(var.getter())
326
334
  else:
327
335
  raise TypeError(
328
- f"Variable with valueReference={vr} is not of type Real!"
336
+ f"Variable with valueReference={vr} is not of type Float64!"
329
337
  )
330
338
  return refs
331
339
 
@@ -334,7 +342,11 @@ class Fmi3SlaveBase(object):
334
342
  for vr in vrs:
335
343
  var = self.vars[vr]
336
344
  if isinstance(var, Boolean):
337
- refs.append(bool(var.getter()))
345
+ if len(var.dimensions) == 0:
346
+ refs.append(bool(var.getter()))
347
+ else:
348
+ refs.extend(var.getter())
349
+
338
350
  else:
339
351
  raise TypeError(
340
352
  f"Variable with valueReference={vr} is not of type Boolean!"
@@ -354,30 +366,48 @@ class Fmi3SlaveBase(object):
354
366
  return refs
355
367
 
356
368
  def set_int32(self, vrs: List[int], values: List[int]):
357
- for vr, value in zip(vrs, values):
369
+ offset = 0
370
+ for vr in vrs:
358
371
  var = self.vars[vr]
359
372
  if isinstance(var, Int32):
360
- var.setter(value)
373
+ size = var.size(self.vars)
374
+ if size > 1:
375
+ var.setter(values[offset:offset+size])
376
+ else:
377
+ var.setter(values[offset])
378
+ offset += size
361
379
  else:
362
380
  raise TypeError(
363
- f"Variable with valueReference={vr} is not of type Integer!"
381
+ f"Variable with valueReference={vr} is not of type Int32!"
364
382
  )
365
383
 
366
384
  def set_int64(self, vrs: List[int], values: List[int]):
367
- for vr, value in zip(vrs, values):
385
+ offset = 0
386
+ for vr in vrs:
368
387
  var = self.vars[vr]
369
388
  if isinstance(var, (Enumeration, Int64)):
370
- var.setter(value)
389
+ size = var.size(self.vars)
390
+ if size > 1:
391
+ var.setter(values[offset:offset+size])
392
+ else:
393
+ var.setter(values[offset])
394
+ offset += size
371
395
  else:
372
396
  raise TypeError(
373
- f"Variable with valueReference={vr} is not of type Integer!"
397
+ f"Variable with valueReference={vr} is not of type Int64!"
374
398
  )
375
399
 
376
400
  def set_uint64(self, vrs: List[int], values: List[int]):
377
- for vr, value in zip(vrs, values):
401
+ offset = 0
402
+ for vr in vrs:
378
403
  var = self.vars[vr]
379
404
  if isinstance(var, UInt64):
380
- var.setter(value)
405
+ size = var.size(self.vars)
406
+ if size > 1:
407
+ var.setter(values[offset:offset+size])
408
+ else:
409
+ var.setter(values[offset])
410
+ offset += size
381
411
  else:
382
412
  raise TypeError(
383
413
  f"Variable with valueReference={vr} is not of type UInt64!"
@@ -396,14 +426,20 @@ class Fmi3SlaveBase(object):
396
426
  offset += size
397
427
  else:
398
428
  raise TypeError(
399
- f"Variable with valueReference={vr} is not of type Real!"
429
+ f"Variable with valueReference={vr} is not of type Float64!"
400
430
  )
401
431
 
402
432
  def set_boolean(self, vrs: List[int], values: List[bool]):
403
- for vr, value in zip(vrs, values):
433
+ offset = 0
434
+ for vr in vrs:
404
435
  var = self.vars[vr]
405
436
  if isinstance(var, Boolean):
406
- var.setter(value)
437
+ size = var.size(self.vars)
438
+ if size > 1:
439
+ var.setter(values[offset:offset+size])
440
+ else:
441
+ var.setter(values[offset])
442
+ offset += size
407
443
  else:
408
444
  raise TypeError(
409
445
  f"Variable with valueReference={vr} is not of type Boolean!"
@@ -66,7 +66,8 @@ void SlaveInstance::SetFloat64(
66
66
  void SlaveInstance::SetInt32(
67
67
  const FMIValueReference /*vr*/[],
68
68
  std::size_t nvr,
69
- const FMIInt32 /*value*/[])
69
+ const FMIInt32 /*value*/[],
70
+ std::size_t nValues)
70
71
  {
71
72
  if (nvr != 0) {
72
73
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -76,7 +77,8 @@ void SlaveInstance::SetInt32(
76
77
  void SlaveInstance::SetInt64(
77
78
  const FMIValueReference /*vr*/[],
78
79
  std::size_t nvr,
79
- const FMIInt64 /*value*/[])
80
+ const FMIInt64 /*value*/[],
81
+ std::size_t nValues)
80
82
  {
81
83
  if (nvr != 0) {
82
84
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -86,7 +88,8 @@ void SlaveInstance::SetInt64(
86
88
  void SlaveInstance::SetUInt64(
87
89
  const FMIValueReference /*vr*/[],
88
90
  std::size_t nvr,
89
- const FMIUInt64 /*value*/[])
91
+ const FMIUInt64 /*value*/[],
92
+ std::size_t nValues)
90
93
  {
91
94
  if (nvr != 0) {
92
95
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -97,7 +100,8 @@ void SlaveInstance::SetUInt64(
97
100
  void SlaveInstance::SetBoolean(
98
101
  const FMIValueReference /*vr*/[],
99
102
  std::size_t nvr,
100
- const FMIBoolean /*value*/[])
103
+ const FMIBoolean /*value*/[],
104
+ std::size_t nValues)
101
105
  {
102
106
  if (nvr != 0) {
103
107
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -108,7 +112,8 @@ void SlaveInstance::SetBoolean(
108
112
  void SlaveInstance::SetString(
109
113
  const FMIValueReference /*vr*/[],
110
114
  std::size_t nvr,
111
- const FMIString /*value*/[])
115
+ const FMIString /*value*/[],
116
+ std::size_t nValues)
112
117
  {
113
118
  if (nvr != 0) {
114
119
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -131,7 +136,8 @@ void SlaveInstance::GetFloat64(
131
136
  void SlaveInstance::GetInt32(
132
137
  const FMIValueReference /*vr*/[],
133
138
  std::size_t nvr,
134
- FMIInt32 /*value*/[]) const
139
+ FMIInt32 /*value*/[],
140
+ std::size_t nValues) const
135
141
  {
136
142
  if (nvr != 0) {
137
143
  throw std::logic_error("Attempted to get nonexistent variable");
@@ -142,7 +148,8 @@ void SlaveInstance::GetInt32(
142
148
  void SlaveInstance::GetInt64(
143
149
  const FMIValueReference /*vr*/[],
144
150
  std::size_t nvr,
145
- FMIInt64 /*value*/[]) const
151
+ FMIInt64 /*value*/[],
152
+ std::size_t nValues) const
146
153
  {
147
154
  if (nvr != 0) {
148
155
  throw std::logic_error("Attempted to get nonexistent variable");
@@ -153,7 +160,8 @@ void SlaveInstance::GetInt64(
153
160
  void SlaveInstance::GetUInt64(
154
161
  const FMIValueReference /*vr*/[],
155
162
  std::size_t nvr,
156
- FMIUInt64 /*value*/[]) const
163
+ FMIUInt64 /*value*/[],
164
+ std::size_t nValues) const
157
165
  {
158
166
  if (nvr != 0) {
159
167
  throw std::logic_error("Attempted to get nonexistent variable");
@@ -164,7 +172,8 @@ void SlaveInstance::GetUInt64(
164
172
  void SlaveInstance::GetBoolean(
165
173
  const FMIValueReference /*vr*/[],
166
174
  std::size_t nvr,
167
- FMIBoolean /*value*/[]) const
175
+ FMIBoolean /*value*/[],
176
+ std::size_t nValues) const
168
177
  {
169
178
  if (nvr != 0) {
170
179
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -175,7 +184,8 @@ void SlaveInstance::GetBoolean(
175
184
  void SlaveInstance::GetString(
176
185
  const FMIValueReference /*vr*/[],
177
186
  std::size_t nvr,
178
- FMIString /*value*/[]) const
187
+ FMIString /*value*/[],
188
+ std::size_t nValues) const
179
189
  {
180
190
  if (nvr != 0) {
181
191
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -76,23 +76,28 @@ public:
76
76
  virtual void SetInt32(
77
77
  const FMIValueReference vr[],
78
78
  std::size_t nvr,
79
- const FMIInt32 value[]);
79
+ const FMIInt32 value[],
80
+ std::size_t nValues);
80
81
  virtual void SetInt64(
81
82
  const FMIValueReference vr[],
82
83
  std::size_t nvr,
83
- const FMIInt64 value[]);
84
+ const FMIInt64 value[],
85
+ std::size_t nValues);
84
86
  virtual void SetUInt64(
85
87
  const FMIValueReference vr[],
86
88
  std::size_t nvr,
87
- const FMIUInt64 value[]);
89
+ const FMIUInt64 value[],
90
+ std::size_t nValues);
88
91
  virtual void SetBoolean(
89
92
  const FMIValueReference vr[],
90
93
  std::size_t nvr,
91
- const FMIBoolean value[]);
94
+ const FMIBoolean value[],
95
+ std::size_t nValues);
92
96
  virtual void SetString(
93
97
  const FMIValueReference vr[],
94
98
  std::size_t nvr,
95
- const FMIString value[]);
99
+ const FMIString value[],
100
+ std::size_t nValues);
96
101
 
97
102
  /* Called from fmi3GetXxx()/fmiGetXxx().
98
103
  * Throws std::logic_error by default.
@@ -105,23 +110,28 @@ public:
105
110
  virtual void GetInt32(
106
111
  const FMIValueReference vr[],
107
112
  std::size_t nvr,
108
- FMIInt32 value[]) const;
113
+ FMIInt32 value[],
114
+ std::size_t nValues) const;
109
115
  virtual void GetInt64(
110
116
  const FMIValueReference vr[],
111
117
  std::size_t nvr,
112
- FMIInt64 value[]) const;
118
+ FMIInt64 value[],
119
+ std::size_t nValues) const;
113
120
  virtual void GetUInt64(
114
121
  const FMIValueReference vr[],
115
122
  std::size_t nvr,
116
- FMIUInt64 value[]) const;
123
+ FMIUInt64 value[],
124
+ std::size_t nValues) const;
117
125
  virtual void GetBoolean(
118
126
  const FMIValueReference vr[],
119
127
  std::size_t nvr,
120
- FMIBoolean value[]) const;
128
+ FMIBoolean value[],
129
+ std::size_t nValues) const;
121
130
  virtual void GetString(
122
131
  const FMIValueReference vr[],
123
132
  std::size_t nvr,
124
- FMIString value[]) const;
133
+ FMIString value[],
134
+ std::size_t nValues) const;
125
135
 
126
136
  // Called from fmi3DoStep()/fmiDoStep(). Must be implemented in model code.
127
137
  virtual FMIStatus DoStep(
@@ -334,7 +334,7 @@ fmi3Status fmi3GetInt32(
334
334
  {
335
335
  const auto component = reinterpret_cast<Component*>(c);
336
336
  try {
337
- component->slave->GetInt32(vr, nvr, values);
337
+ component->slave->GetInt32(vr, nvr, values, nValues);
338
338
  return fmi3OK;
339
339
  } catch (const cppfmu::FatalError& e) {
340
340
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -354,7 +354,7 @@ fmi3Status fmi3GetInt64(
354
354
  {
355
355
  const auto component = reinterpret_cast<Component*>(c);
356
356
  try {
357
- component->slave->GetInt64(vr, nvr, values);
357
+ component->slave->GetInt64(vr, nvr, values, nValues);
358
358
  return fmi3OK;
359
359
  } catch (const cppfmu::FatalError& e) {
360
360
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -374,7 +374,7 @@ fmi3Status fmi3GetUInt64(
374
374
  {
375
375
  const auto component = reinterpret_cast<Component*>(c);
376
376
  try {
377
- component->slave->GetUInt64(vr, nvr, values);
377
+ component->slave->GetUInt64(vr, nvr, values, nValues);
378
378
  return fmi3OK;
379
379
  } catch (const cppfmu::FatalError& e) {
380
380
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -394,7 +394,7 @@ fmi3Status fmi3GetBoolean(
394
394
  {
395
395
  const auto component = reinterpret_cast<Component*>(c);
396
396
  try {
397
- component->slave->GetBoolean(vr, nvr, values);
397
+ component->slave->GetBoolean(vr, nvr, values, nValues);
398
398
  return fmi3OK;
399
399
  } catch (const cppfmu::FatalError& e) {
400
400
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -414,7 +414,7 @@ fmi3Status fmi3GetString(
414
414
  {
415
415
  const auto component = reinterpret_cast<Component*>(c);
416
416
  try {
417
- component->slave->GetString(vr, nvr, values);
417
+ component->slave->GetString(vr, nvr, values, nValues);
418
418
  return fmi3OK;
419
419
  } catch (const cppfmu::FatalError& e) {
420
420
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -455,7 +455,7 @@ fmi3Status fmi3SetInt32(
455
455
  {
456
456
  const auto component = reinterpret_cast<Component*>(c);
457
457
  try {
458
- component->slave->SetInt32(vr, nvr, values);
458
+ component->slave->SetInt32(vr, nvr, values, nValues);
459
459
  return fmi3OK;
460
460
  } catch (const cppfmu::FatalError& e) {
461
461
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -475,7 +475,7 @@ fmi3Status fmi3SetInt64(
475
475
  {
476
476
  const auto component = reinterpret_cast<Component*>(c);
477
477
  try {
478
- component->slave->SetInt64(vr, nvr, values);
478
+ component->slave->SetInt64(vr, nvr, values, nValues);
479
479
  return fmi3OK;
480
480
  } catch (const cppfmu::FatalError& e) {
481
481
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -495,7 +495,7 @@ fmi3Status fmi3SetUInt64(
495
495
  {
496
496
  const auto component = reinterpret_cast<Component*>(c);
497
497
  try {
498
- component->slave->SetUInt64(vr, nvr, values);
498
+ component->slave->SetUInt64(vr, nvr, values, nValues);
499
499
  return fmi3OK;
500
500
  } catch (const cppfmu::FatalError& e) {
501
501
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -515,7 +515,7 @@ fmi3Status fmi3SetBoolean(
515
515
  {
516
516
  const auto component = reinterpret_cast<Component*>(c);
517
517
  try {
518
- component->slave->SetBoolean(vr, nvr, values);
518
+ component->slave->SetBoolean(vr, nvr, values, nValues);
519
519
  return fmi3OK;
520
520
  } catch (const cppfmu::FatalError& e) {
521
521
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -535,7 +535,7 @@ fmi3Status fmi3SetString(
535
535
  {
536
536
  const auto component = reinterpret_cast<Component*>(c);
537
537
  try {
538
- component->slave->SetString(vr, nvr, values);
538
+ component->slave->SetString(vr, nvr, values, nValues);
539
539
  return fmi3OK;
540
540
  } catch (const cppfmu::FatalError& e) {
541
541
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -285,13 +285,16 @@ void PySlaveInstance::SetFloat64(const cppfmu::FMIValueReference* vr, std::size_
285
285
  });
286
286
  }
287
287
 
288
- void PySlaveInstance::SetInt32(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIInt32* values)
288
+ void PySlaveInstance::SetInt32(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIInt32* values, std::size_t nValues)
289
289
  {
290
- py_safe_run([this, &vr, nvr, &values](PyGILState_STATE gilState) {
290
+ py_safe_run([this, &vr, nvr, &values, nValues](PyGILState_STATE gilState) {
291
291
  PyObject* vrs = PyList_New(nvr);
292
- PyObject* refs = PyList_New(nvr);
292
+ PyObject* refs = PyList_New(nValues);
293
293
  for (int i = 0; i < nvr; i++) {
294
294
  PyList_SetItem(vrs, i, Py_BuildValue("i", vr[i]));
295
+ }
296
+
297
+ for (int i = 0; i < nValues; i++) {
295
298
  PyList_SetItem(refs, i, Py_BuildValue("i", values[i]));
296
299
  }
297
300
 
@@ -306,13 +309,15 @@ void PySlaveInstance::SetInt32(const cppfmu::FMIValueReference* vr, std::size_t
306
309
  });
307
310
  }
308
311
 
309
- void PySlaveInstance::SetInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIInt64* values)
312
+ void PySlaveInstance::SetInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIInt64* values, std::size_t nValues)
310
313
  {
311
- py_safe_run([this, &vr, nvr, &values](PyGILState_STATE gilState) {
314
+ py_safe_run([this, &vr, nvr, &values, nValues](PyGILState_STATE gilState) {
312
315
  PyObject* vrs = PyList_New(nvr);
313
- PyObject* refs = PyList_New(nvr);
316
+ PyObject* refs = PyList_New(nValues);
314
317
  for (int i = 0; i < nvr; i++) {
315
318
  PyList_SetItem(vrs, i, Py_BuildValue("i", vr[i]));
319
+ }
320
+ for (int i = 0; i < nValues; i++) {
316
321
  PyList_SetItem(refs, i, Py_BuildValue("L", values[i]));
317
322
  }
318
323
 
@@ -327,13 +332,15 @@ void PySlaveInstance::SetInt64(const cppfmu::FMIValueReference* vr, std::size_t
327
332
  });
328
333
  }
329
334
 
330
- void PySlaveInstance::SetUInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIUInt64* values)
335
+ void PySlaveInstance::SetUInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIUInt64* values, std::size_t nValues)
331
336
  {
332
- py_safe_run([this, &vr, nvr, &values](PyGILState_STATE gilState) {
337
+ py_safe_run([this, &vr, nvr, &values, nValues](PyGILState_STATE gilState) {
333
338
  PyObject* vrs = PyList_New(nvr);
334
- PyObject* refs = PyList_New(nvr);
339
+ PyObject* refs = PyList_New(nValues);
335
340
  for (int i = 0; i < nvr; i++) {
336
341
  PyList_SetItem(vrs, i, Py_BuildValue("i", vr[i]));
342
+ }
343
+ for (int i = 0; i < nValues; i++) {
337
344
  PyList_SetItem(refs, i, Py_BuildValue("K", values[i]));
338
345
  }
339
346
 
@@ -348,13 +355,15 @@ void PySlaveInstance::SetUInt64(const cppfmu::FMIValueReference* vr, std::size_t
348
355
  });
349
356
  }
350
357
 
351
- void PySlaveInstance::SetBoolean(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIBoolean* values)
358
+ void PySlaveInstance::SetBoolean(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIBoolean* values, std::size_t nValues)
352
359
  {
353
- py_safe_run([this, &vr, nvr, &values](PyGILState_STATE gilState) {
360
+ py_safe_run([this, &vr, nvr, &values, nValues](PyGILState_STATE gilState) {
354
361
  PyObject* vrs = PyList_New(nvr);
355
- PyObject* refs = PyList_New(nvr);
362
+ PyObject* refs = PyList_New(nValues);
356
363
  for (int i = 0; i < nvr; i++) {
357
364
  PyList_SetItem(vrs, i, Py_BuildValue("i", vr[i]));
365
+ }
366
+ for (int i = 0; i < nValues; i++) {
358
367
  PyList_SetItem(refs, i, PyBool_FromLong(values[i]));
359
368
  }
360
369
 
@@ -369,13 +378,15 @@ void PySlaveInstance::SetBoolean(const cppfmu::FMIValueReference* vr, std::size_
369
378
  });
370
379
  }
371
380
 
372
- void PySlaveInstance::SetString(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIString const* values)
381
+ void PySlaveInstance::SetString(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIString const* values, std::size_t nValues)
373
382
  {
374
- py_safe_run([this, &vr, nvr, &values](PyGILState_STATE gilState) {
383
+ py_safe_run([this, &vr, nvr, &values, nValues](PyGILState_STATE gilState) {
375
384
  PyObject* vrs = PyList_New(nvr);
376
385
  PyObject* refs = PyList_New(nvr);
377
386
  for (int i = 0; i < nvr; i++) {
378
387
  PyList_SetItem(vrs, i, Py_BuildValue("i", vr[i]));
388
+ }
389
+ for (int i = 0; i < nValues; i++) {
379
390
  PyList_SetItem(refs, i, Py_BuildValue("s", values[i]));
380
391
  }
381
392
 
@@ -413,9 +424,9 @@ void PySlaveInstance::GetFloat64(const cppfmu::FMIValueReference* vr, std::size_
413
424
  });
414
425
  }
415
426
 
416
- void PySlaveInstance::GetInt32(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIInt32* values) const
427
+ void PySlaveInstance::GetInt32(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIInt32* values, std::size_t nValues) const
417
428
  {
418
- py_safe_run([this, &vr, nvr, &values](PyGILState_STATE gilState) {
429
+ py_safe_run([this, &vr, nvr, &values, nValues](PyGILState_STATE gilState) {
419
430
  PyObject* vrs = PyList_New(nvr);
420
431
  for (int i = 0; i < nvr; i++) {
421
432
  PyList_SetItem(vrs, i, Py_BuildValue("i", vr[i]));
@@ -426,7 +437,7 @@ void PySlaveInstance::GetInt32(const cppfmu::FMIValueReference* vr, std::size_t
426
437
  handle_py_exception("[getInt32] PyObject_CallMethod", gilState);
427
438
  }
428
439
 
429
- for (int i = 0; i < nvr; i++) {
440
+ for (int i = 0; i < nValues; i++) {
430
441
  PyObject* value = PyList_GetItem(refs, i);
431
442
  values[i] = static_cast<cppfmu::FMIInt32>(PyLong_AsLong(value));
432
443
  }
@@ -435,9 +446,9 @@ void PySlaveInstance::GetInt32(const cppfmu::FMIValueReference* vr, std::size_t
435
446
  });
436
447
  }
437
448
 
438
- void PySlaveInstance::GetInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIInt64* values) const
449
+ void PySlaveInstance::GetInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIInt64* values, std::size_t nValues) const
439
450
  {
440
- py_safe_run([this, &vr, nvr, &values](PyGILState_STATE gilState) {
451
+ py_safe_run([this, &vr, nvr, &values, nValues](PyGILState_STATE gilState) {
441
452
  PyObject* vrs = PyList_New(nvr);
442
453
  for (int i = 0; i < nvr; i++) {
443
454
  PyList_SetItem(vrs, i, Py_BuildValue("i", vr[i]));
@@ -448,7 +459,7 @@ void PySlaveInstance::GetInt64(const cppfmu::FMIValueReference* vr, std::size_t
448
459
  handle_py_exception("[getInt64] PyObject_CallMethod", gilState);
449
460
  }
450
461
 
451
- for (int i = 0; i < nvr; i++) {
462
+ for (int i = 0; i < nValues; i++) {
452
463
  PyObject* value = PyList_GetItem(refs, i);
453
464
  values[i] = static_cast<cppfmu::FMIInt64>(PyLong_AsLongLong(value));
454
465
  }
@@ -457,9 +468,9 @@ void PySlaveInstance::GetInt64(const cppfmu::FMIValueReference* vr, std::size_t
457
468
  });
458
469
  }
459
470
 
460
- void PySlaveInstance::GetUInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIUInt64* values) const
471
+ void PySlaveInstance::GetUInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIUInt64* values, std::size_t nValues) const
461
472
  {
462
- py_safe_run([this, &vr, nvr, &values](PyGILState_STATE gilState) {
473
+ py_safe_run([this, &vr, nvr, &values, nValues](PyGILState_STATE gilState) {
463
474
  PyObject* vrs = PyList_New(nvr);
464
475
  for (int i = 0; i < nvr; i++) {
465
476
  PyList_SetItem(vrs, i, Py_BuildValue("i", vr[i]));
@@ -470,7 +481,7 @@ void PySlaveInstance::GetUInt64(const cppfmu::FMIValueReference* vr, std::size_t
470
481
  handle_py_exception("[getUInt64] PyObject_CallMethod", gilState);
471
482
  }
472
483
 
473
- for (int i = 0; i < nvr; i++) {
484
+ for (int i = 0; i < nValues; i++) {
474
485
  PyObject* item = PyList_GetItem(refs, i);
475
486
  PyObject* value = PyObject_GetAttrString(item, "value");
476
487
  if (value && PyLong_Check(value))
@@ -484,9 +495,9 @@ void PySlaveInstance::GetUInt64(const cppfmu::FMIValueReference* vr, std::size_t
484
495
  });
485
496
  }
486
497
 
487
- void PySlaveInstance::GetBoolean(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIBoolean* values) const
498
+ void PySlaveInstance::GetBoolean(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIBoolean* values, std::size_t nValues) const
488
499
  {
489
- py_safe_run([this, &vr, nvr, &values](PyGILState_STATE gilState) {
500
+ py_safe_run([this, &vr, nvr, &values, nValues](PyGILState_STATE gilState) {
490
501
  PyObject* vrs = PyList_New(nvr);
491
502
  for (int i = 0; i < nvr; i++) {
492
503
  PyList_SetItem(vrs, i, Py_BuildValue("i", vr[i]));
@@ -497,7 +508,7 @@ void PySlaveInstance::GetBoolean(const cppfmu::FMIValueReference* vr, std::size_
497
508
  handle_py_exception("[getBoolean] PyObject_CallMethod", gilState);
498
509
  }
499
510
 
500
- for (int i = 0; i < nvr; i++) {
511
+ for (int i = 0; i < nValues; i++) {
501
512
  PyObject* value = PyList_GetItem(refs, i);
502
513
  values[i] = PyObject_IsTrue(value);
503
514
  }
@@ -506,9 +517,9 @@ void PySlaveInstance::GetBoolean(const cppfmu::FMIValueReference* vr, std::size_
506
517
  });
507
518
  }
508
519
 
509
- void PySlaveInstance::GetString(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIString* values) const
520
+ void PySlaveInstance::GetString(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIString* values, std::size_t nValues) const
510
521
  {
511
- py_safe_run([this, &vr, nvr, &values](PyGILState_STATE gilState) {
522
+ py_safe_run([this, &vr, nvr, &values, nValues](PyGILState_STATE gilState) {
512
523
  clearStrBuffer();
513
524
  PyObject* vrs = PyList_New(nvr);
514
525
  for (int i = 0; i < nvr; i++) {
@@ -520,7 +531,7 @@ void PySlaveInstance::GetString(const cppfmu::FMIValueReference* vr, std::size_t
520
531
  handle_py_exception("[getString] PyObject_CallMethod", gilState);
521
532
  }
522
533
 
523
- for (int i = 0; i < nvr; i++) {
534
+ for (int i = 0; i < nValues; i++) {
524
535
  PyObject* value = PyUnicode_AsEncodedString(PyList_GetItem(refs, i), "utf-8", nullptr);
525
536
  values[i] = PyBytes_AsString(value);
526
537
  strBuffer.emplace_back(value);
@@ -34,18 +34,18 @@ public:
34
34
  cppfmu::FMIFloat64& endOfStep) override;
35
35
 
36
36
  void SetFloat64(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIFloat64* value, std::size_t nValues) override;
37
- void SetInt32(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIInt32* value) override;
38
- void SetInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIInt64* value) override;
39
- void SetUInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIUInt64* value) override;
40
- void SetBoolean(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIBoolean* value) override;
41
- void SetString(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIString const* value) override;
37
+ void SetInt32(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIInt32* value, std::size_t nValues) override;
38
+ void SetInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIInt64* value, std::size_t nValues) override;
39
+ void SetUInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIUInt64* value, std::size_t nValues) override;
40
+ void SetBoolean(const cppfmu::FMIValueReference* vr, std::size_t nvr, const cppfmu::FMIBoolean* value, std::size_t nValues) override;
41
+ void SetString(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIString const* value, std::size_t nValues) override;
42
42
 
43
43
  void GetFloat64(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIFloat64* value, std::size_t nValues) const override;
44
- void GetInt32(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIInt32* value) const override;
45
- void GetInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIInt64* value) const override;
46
- void GetUInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIUInt64* value) const override;
47
- void GetBoolean(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIBoolean* value) const override;
48
- void GetString(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIString* value) const override;
44
+ void GetInt32(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIInt32* value, std::size_t nValues) const override;
45
+ void GetInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIInt64* value, std::size_t nValues) const override;
46
+ void GetUInt64(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIUInt64* value, std::size_t nValues) const override;
47
+ void GetBoolean(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIBoolean* value, std::size_t nValues) const override;
48
+ void GetString(const cppfmu::FMIValueReference* vr, std::size_t nvr, cppfmu::FMIString* value, std::size_t nValues) const override;
49
49
 
50
50
  void GetFMUstate(fmi3FMUState& State) override;
51
51
  void SetFMUstate(const fmi3FMUState& State) override;
@@ -0,0 +1,80 @@
1
+
2
+ from pythonfmu3 import Fmi3Causality, Fmi3Variability, Dimension, Fmi3Slave, Fmi3Status, Float64, Int32, Int64, UInt64, String, Boolean
3
+
4
+ import numpy as np
5
+
6
+ SIZE = 10
7
+
8
+ TYPES = [UInt64, Float64, Boolean, Int32, Int64]
9
+ CAUSALITY = [Fmi3Causality.output, Fmi3Causality.input]
10
+
11
+ TYPE_MAP = {
12
+ UInt64: np.uint64,
13
+ Float64: np.float64,
14
+ Int32: np.int32,
15
+ Int64: np.int64,
16
+ Boolean: bool
17
+ }
18
+
19
+ def var_names(var_type, causality):
20
+ return f"{var_type.__name__.lower()}_{causality.name.lower()}"
21
+
22
+
23
+ def init_var(var_type, causality, array=True):
24
+ if array:
25
+ return np.zeros(SIZE, dtype=TYPE_MAP[var_type])
26
+ else:
27
+ return TYPE_MAP[var_type]()
28
+
29
+
30
+ def create_vars(self):
31
+ dimensions = [Dimension(start=str(SIZE))]
32
+ for var_type in TYPES:
33
+ for causality in CAUSALITY:
34
+ name = var_names(var_type, causality)
35
+ if var_type == Float64:
36
+ var = var_type(name, causality=causality, variability=Fmi3Variability.continuous, dimensions=dimensions)
37
+ else:
38
+ var = var_type(name, causality=causality, variability=Fmi3Variability.discrete, dimensions=dimensions)
39
+ setattr(self, name, init_var(var_type, causality))
40
+ self.register_variable(var)
41
+
42
+
43
+ def generate_data(self):
44
+ for var_type in TYPES:
45
+ causality = Fmi3Causality.output
46
+ name = var_names(var_type, causality)
47
+ var = getattr(self, name)
48
+ if var_type == Boolean:
49
+ data = [False, True, False, True, True, False, False, True, False, True]
50
+ setattr(self, name, np.array(data).astype(bool))
51
+ elif var_type == Int32 or var_type == Int64 or var_type == UInt64:
52
+ data = [1,2,3,4,5,6,7,8,9,10]
53
+ setattr(self, name, np.array(data).astype(TYPE_MAP[var_type]))
54
+ else:
55
+ data = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
56
+ setattr(self, name, np.array(data).astype(TYPE_MAP[var_type]))
57
+
58
+ class ArrayTypes(Fmi3Slave):
59
+
60
+
61
+ def __init__(self, **kwargs):
62
+ super().__init__(**kwargs)
63
+
64
+ self.author = "Tester"
65
+ self.description = "FMU with all basic types as arrays"
66
+
67
+ self.time = 0.0
68
+
69
+ self.register_variable(Float64("time", causality=Fmi3Causality.independent, variability=Fmi3Variability.continuous))
70
+
71
+ create_vars(self)
72
+
73
+ generate_data(self)
74
+
75
+
76
+ def do_step(self, current_time: float, step_size: float) -> Fmi3Status:
77
+ generate_data(self)
78
+ return True
79
+
80
+
@@ -280,6 +280,57 @@ def test_integration_get(tmp_path):
280
280
  model.terminate()
281
281
  model.freeInstance()
282
282
 
283
+ @pytest.mark.integration
284
+ def test_integration_get_array(tmp_path):
285
+ script_file = Path(__file__).parent / "slaves/pythonslave_arraytypes.py"
286
+ fmu = FmuBuilder.build_FMU(script_file, dest=tmp_path, needsExecutionTool="false")
287
+ assert fmu.exists()
288
+
289
+ md = fmpy.read_model_description(fmu)
290
+ unzip_dir = fmpy.extract(fmu)
291
+
292
+ model = fmpy.fmi3.FMU3Slave(
293
+ guid=md.guid,
294
+ unzipDirectory=unzip_dir,
295
+ modelIdentifier=md.coSimulation.modelIdentifier,
296
+ instanceName='instance1')
297
+
298
+ model.instantiate()
299
+ model.enterInitializationMode()
300
+ model.exitInitializationMode()
301
+
302
+ to_test = {
303
+ "int32_output": [1,2,3,4,5,6,7,8,9,10],
304
+ "int64_output": [1,2,3,4,5,6,7,8,9,10],
305
+ "uint64_output": [1,2,3,4,5,6,7,8,9,10],
306
+ "float64_output": [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0],
307
+ "boolean_output": [False, True, False, True, True, False, False, True, False, True]
308
+ }
309
+
310
+ model_value = None
311
+ variables = mapped(md)
312
+ for key, value in to_test.items():
313
+ var = variables[key]
314
+ vrs = [var.valueReference]
315
+ if var.type == "Int32":
316
+ model_values = model.getInt32(vrs, nValues=10)
317
+ elif var.type == "Int64":
318
+ model_values = model.getInt64(vrs, nValues=10)
319
+ elif var.type == "UInt64":
320
+ model_values = model.getUInt64(vrs, nValues=10)
321
+ elif var.type == "Float64":
322
+ model_values = model.getFloat64(vrs, nValues=10)
323
+ elif var.type == "Boolean":
324
+ model_values = model.getBoolean(vrs, nValues=10)
325
+ else:
326
+ pytest.xfail("Unsupported type")
327
+
328
+ assert len(model_values) == len(value)
329
+ assert model_values == value
330
+
331
+ model.terminate()
332
+ model.freeInstance()
333
+
283
334
 
284
335
  @pytest.mark.integration
285
336
  def test_integration_read_from_file(tmp_path):
@@ -367,6 +418,61 @@ def test_integration_set(tmp_path):
367
418
  model.terminate()
368
419
  model.freeInstance()
369
420
 
421
+ @pytest.mark.integration
422
+ def test_integration_set_array(tmp_path):
423
+ script_file = Path(__file__).parent / "slaves/pythonslave_arraytypes.py"
424
+ fmu = FmuBuilder.build_FMU(script_file, dest=tmp_path, needsExecutionTool="false")
425
+ assert fmu.exists()
426
+
427
+ md = fmpy.read_model_description(fmu)
428
+ unzip_dir = fmpy.extract(fmu)
429
+
430
+ model = fmpy.fmi3.FMU3Slave(
431
+ guid=md.guid,
432
+ unzipDirectory=unzip_dir,
433
+ modelIdentifier=md.coSimulation.modelIdentifier,
434
+ instanceName='instance1')
435
+
436
+ model.instantiate()
437
+ model.enterInitializationMode()
438
+ model.exitInitializationMode()
439
+
440
+ to_test = {
441
+ "int32_input": [1,2,3,4,5,6,7,8,9,10],
442
+ "int64_input": [1,2,3,4,5,6,7,8,9,10],
443
+ "uint64_input": [1,2,3,4,5,6,7,8,9,10],
444
+ "float64_input": [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0],
445
+ "boolean_input": [False, True, False, True, True, False, False, True, False, True]
446
+ }
447
+
448
+ model_value = None
449
+ variables = mapped(md)
450
+ for key, value in to_test.items():
451
+ var = variables[key]
452
+ vrs = [var.valueReference]
453
+ if var.type == "Int32":
454
+ model.setInt32(vrs, value)
455
+ model_value = model.getInt32(vrs, nValues=10)
456
+ elif var.type == "Int64":
457
+ model.setInt64(vrs, value)
458
+ model_value = model.getInt64(vrs, nValues=10)
459
+ elif var.type == "UInt64":
460
+ model.setUInt64(vrs, value)
461
+ model_value = model.getUInt64(vrs, nValues=10)
462
+ elif var.type == "Float64":
463
+ model.setFloat64(vrs, value)
464
+ model_value = model.getFloat64(vrs,nValues=10)
465
+ elif var.type == "Boolean":
466
+ model.setBoolean(vrs, value)
467
+ model_value = model.getBoolean(vrs, nValues=10)
468
+ else:
469
+ pytest.xfail("Unsupported type")
470
+
471
+ assert list(model_value) == value
472
+
473
+ model.terminate()
474
+ model.freeInstance()
475
+
370
476
 
371
477
  @pytest.mark.integration
372
478
  def test_simple_integration_fmpy(tmp_path):
pythonfmu3/variables.py CHANGED
@@ -50,6 +50,11 @@ class ModelVariable(ABC):
50
50
  self.setter = setter
51
51
  self._type = None
52
52
  self.local_name = name.split(".")[-1]
53
+
54
+ # demanagle names
55
+ self.local_name = self.local_name.lstrip('_')
56
+
57
+
53
58
  self.__attrs = {
54
59
  "name": name,
55
60
  "valueReference": None,
@@ -151,7 +156,6 @@ class Start(object):
151
156
  attrib["value"] = self.value
152
157
  return Element("Start", attrib)
153
158
 
154
-
155
159
  class Dimension(object):
156
160
  def __init__(self, start: str = "", valueReference: str = ""):
157
161
  if start and valueReference and any((start, valueReference)):
@@ -177,15 +181,38 @@ class Dimension(object):
177
181
  ele = Element("Dimension", attrib)
178
182
  return ele
179
183
 
180
- class Float64(ModelVariable):
184
+ class Arrayable(object):
185
+ def __init__(self, dimensions : List[Dimension] = [], **kwargs):
186
+ if dimensions:
187
+ check_numpy()
188
+ self._dimensions = dimensions
189
+
190
+ @property
191
+ def dimensions(self) -> List[Dimension]:
192
+ return self._dimensions
193
+
194
+ def get_start_str(self, value, formatter):
195
+ if len(self.dimensions) > 0:
196
+ output = " ".join([formatter(val) for val in flatten(value)])
197
+ if len(output) > MAX_LENGTH:
198
+ output = output[0]
199
+ return output
200
+ else:
201
+ return formatter(value)
202
+
203
+ def dimensions_xml(self) -> List[Element]:
204
+ return [dim.to_xml() for dim in self._dimensions]
205
+
206
+ def size(self, vars):
207
+ return reduce(lambda x, dim: x * int(dim.size(vars)), self._dimensions, 1)
208
+
209
+ class Float64(ModelVariable, Arrayable):
181
210
  def __init__(self, name: str, start: Optional[Any] = None, derivative: Optional[Any] = None, dimensions: List[Dimension] = [], unit: Optional[str] = None, **kwargs):
182
- super().__init__(name, **kwargs)
211
+ ModelVariable.__init__(self, name, **kwargs)
212
+ Arrayable.__init__(self, dimensions)
183
213
  self.__attrs = {"start": start, "derivative": derivative}
184
214
  self._type = "Float64"
185
215
  self._unit = unit
186
- if dimensions:
187
- check_numpy()
188
- self.__dimensions = dimensions
189
216
 
190
217
  @property
191
218
  def start(self) -> Optional[Any]:
@@ -206,11 +233,6 @@ class Float64(ModelVariable):
206
233
  @property
207
234
  def derivative(self):
208
235
  return self.__attrs["derivative"]
209
-
210
- @property
211
- def dimensions(self) -> List[Dimension]:
212
- return self.__dimensions
213
-
214
236
 
215
237
  def to_xml(self) -> Element:
216
238
  attrib = dict()
@@ -218,13 +240,7 @@ class Float64(ModelVariable):
218
240
  if value is not None:
219
241
  # In order to not loose precision, a number of this type should be
220
242
  # stored on an XML file with at least 16 significant digits
221
- output = ""
222
- if len(self.dimensions) > 0:
223
- output = " ".join([f"{val:.16g}" for val in flatten(value)])
224
- if len(output) > MAX_LENGTH:
225
- output = output[0]
226
- else:
227
- output = f"{value:.16g}"
243
+ output = self.get_start_str(value, lambda v: f"{v:.16g}")
228
244
  attrib[key] = output
229
245
 
230
246
  if self.unit:
@@ -233,18 +249,15 @@ class Float64(ModelVariable):
233
249
  self._extras = attrib
234
250
  parent = super().to_xml()
235
251
 
236
- for dimension in self.__dimensions:
237
- parent.append(dimension.to_xml())
252
+ parent.extend(self.dimensions_xml())
238
253
 
239
254
  return parent
240
255
 
241
- def size(self, vars):
242
- return reduce(lambda x, dim: x * int(dim.size(vars)), self.__dimensions, 1)
243
-
244
256
 
245
- class Int32(ModelVariable):
246
- def __init__(self, name: str, start: Optional[Any] = None, **kwargs):
247
- super().__init__(name, **kwargs)
257
+ class Int32(ModelVariable, Arrayable):
258
+ def __init__(self, name: str, start: Optional[Any] = None, dimensions: List[Dimension] = [], **kwargs):
259
+ ModelVariable.__init__(self, name, **kwargs)
260
+ Arrayable.__init__(self, dimensions, **kwargs)
248
261
  self.__attrs = {"start": start}
249
262
  self._type = "Int32";
250
263
 
@@ -260,15 +273,18 @@ class Int32(ModelVariable):
260
273
  attrib = dict()
261
274
  for key, value in self.__attrs.items():
262
275
  if value is not None:
263
- attrib[key] = str(value)
276
+ attrib[key] = self.get_start_str(value, lambda v: str(v))
264
277
  self._extras = attrib
265
278
  parent = super().to_xml()
279
+
280
+ parent.extend(self.dimensions_xml())
266
281
 
267
282
  return parent
268
283
 
269
- class Int64(ModelVariable):
270
- def __init__(self, name: str, start: Optional[Any] = None, **kwargs):
271
- super().__init__(name, **kwargs)
284
+ class Int64(ModelVariable, Arrayable):
285
+ def __init__(self, name: str, start: Optional[Any] = None, dimensions: List[Dimension] = [], **kwargs):
286
+ ModelVariable.__init__(self, name, **kwargs)
287
+ Arrayable.__init__(self, dimensions, **kwargs)
272
288
  self.__attrs = {"start": start}
273
289
  self._type = "Int64";
274
290
 
@@ -284,15 +300,18 @@ class Int64(ModelVariable):
284
300
  attrib = dict()
285
301
  for key, value in self.__attrs.items():
286
302
  if value is not None:
287
- attrib[key] = str(value)
303
+ attrib[key] = self.get_start_str(value, lambda v: str(v))
288
304
  self._extras = attrib
289
305
  parent = super().to_xml()
290
306
 
307
+ parent.extend(self.dimensions_xml())
308
+
291
309
  return parent
292
310
 
293
- class UInt64(ModelVariable):
294
- def __init__(self, name: str, start: Optional[Any] = None, **kwargs):
295
- super().__init__(name, **kwargs)
311
+ class UInt64(ModelVariable, Arrayable):
312
+ def __init__(self, name: str, start: Optional[Any] = None, dimensions: List[Dimension] = [], **kwargs):
313
+ ModelVariable.__init__(self, name, **kwargs)
314
+ Arrayable.__init__(self, dimensions, **kwargs)
296
315
  self.__attrs = {"start": start}
297
316
  self._type = "UInt64";
298
317
 
@@ -308,15 +327,18 @@ class UInt64(ModelVariable):
308
327
  attrib = dict()
309
328
  for key, value in self.__attrs.items():
310
329
  if value is not None:
311
- attrib[key] = str(value)
330
+ attrib[key] = self.get_start_str(value, lambda v: str(v))
312
331
  self._extras = attrib
313
332
  parent = super().to_xml()
314
333
 
315
- return parent
334
+ parent.extend(self.dimensions_xml())
316
335
 
317
- class Boolean(ModelVariable):
318
- def __init__(self, name: str, start: Optional[Any] = None, **kwargs):
319
- super().__init__(name, **kwargs)
336
+ return parent
337
+
338
+ class Boolean(ModelVariable, Arrayable):
339
+ def __init__(self, name: str, start: Optional[Any] = None, dimensions: List[Dimension] = [], **kwargs):
340
+ ModelVariable.__init__(self, name, **kwargs)
341
+ Arrayable.__init__(self, dimensions, **kwargs)
320
342
  self.__attrs = {"start": start}
321
343
  self._type = "Boolean"
322
344
 
@@ -332,16 +354,18 @@ class Boolean(ModelVariable):
332
354
  attrib = dict()
333
355
  for key, value in self.__attrs.items():
334
356
  if value is not None:
335
- attrib[key] = str(value).lower()
357
+ attrib[key] = self.get_start_str(value, lambda v: str(v).lower())
336
358
  self._extras = attrib
337
359
  parent = super().to_xml()
360
+
361
+ parent.extend(self.dimensions_xml())
338
362
 
339
363
  return parent
340
364
 
341
365
 
342
366
  class String(ModelVariable):
343
- def __init__(self, name: str, start: Optional[Any] = None, **kwargs):
344
- super().__init__(name, **kwargs)
367
+ def __init__(self, name: str, start: Optional[Any] = None, dimensions: List[Dimension] = [], **kwargs):
368
+ ModelVariable.__init__(self, name, **kwargs)
345
369
  self.__attrs = dict()
346
370
  self._type = "String"
347
371
  self._start = Start(start)
@@ -358,13 +382,13 @@ class String(ModelVariable):
358
382
  attrib = dict()
359
383
  for key, value in self.__attrs.items():
360
384
  if value is not None:
361
- attrib[key] = str(value)
385
+ attrib[key] = str(value, lambda v: str(v))
362
386
  self._extras = attrib
363
387
  parent = super().to_xml()
364
388
 
365
389
  if self.start is not None:
366
390
  parent.append(self._start.to_xml())
367
-
391
+
368
392
  return parent
369
393
 
370
394
  class Enumeration(ModelVariable):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonfmu3
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: A lightweight framework that enables the packaging of Python3.x code as co-simulation FMUs.
5
5
  Home-page: https://github.com/stephensmith25/PythonFMU3
6
6
  Author: Stephen Smith
@@ -1,43 +1,43 @@
1
1
  pythonfmu3/__init__.py,sha256=VJ4QqOZTU8sBI8xhiRVD540Hsp381ma24xGWHABZ724,551
2
2
  pythonfmu3/__main__.py,sha256=gC1T8x2d02hhqshyNQGSS70SyCk-3I3t8zPqoRo2Xd8,1543
3
- pythonfmu3/_version.py,sha256=8KcCYTXH99C2-gCLuPILJvtT9YftRWJsartIx6TQ2ZY,22
3
+ pythonfmu3/_version.py,sha256=oYLGMpySamd16KLiaBTfRyrAS7_oyp-TOEHmzmeumwg,22
4
4
  pythonfmu3/builder.py,sha256=DLpy6Hd9ZmbeQLVMw_FcxnS5LB_-yRXzkPjlupyiYsg,11060
5
5
  pythonfmu3/cosimulation.py,sha256=EZ5pa_5hy1AwoaZRzZqNz_IX8kjxoFM9sPgeqrUiRuw,179
6
6
  pythonfmu3/default_experiment.py,sha256=FJ0l0FpU7pT4Pox2RiA2y-Cb_e7DE2XlbWKySRYQaVk,293
7
7
  pythonfmu3/deploy.py,sha256=eqFWVxZUkJCLvmq1-GuMNjn2j0VCGoaXPhRWrCk2Vxg,3741
8
8
  pythonfmu3/enums.py,sha256=ZmC6vGeBTGt7HarPQ4uYV10ezPsvIxAHH1ypjNq7G3E,729
9
- pythonfmu3/fmi3slave.py,sha256=LmVDNKJjuUuzepBMijudqsjMFZoZAhAAPxlcgKGz_So,19688
9
+ pythonfmu3/fmi3slave.py,sha256=JpN_zeaXpEIk2Hnnd7LvV2cs5IOD6x1GEAYdNy9TMWU,20844
10
10
  pythonfmu3/logmsg.py,sha256=0wn11GLwq0LLWqyC2ktLRjQFWlpj07wWliZ8rUHx1gg,359
11
11
  pythonfmu3/modelexchange.py,sha256=pdC3gvr-vCXA8qvJ_urWplJZWEi1YKjMcNczme7GOOo,1884
12
12
  pythonfmu3/osutil.py,sha256=1qN6qudN4zCupZwc15pzp52WObkqi6jGy9a-MehNt9Q,656
13
13
  pythonfmu3/unit.py,sha256=SjOaywb5lVQbAO_iLjc_7Ly3nYrmAvIW2_hAGt12UFU,1475
14
14
  pythonfmu3/variable_types.py,sha256=Q0D4wlGi3i3zE5UsmGJEpNh7SV_W8mn_8p_WIkwrLQA,2881
15
- pythonfmu3/variables.py,sha256=GDAbR_BSRsiBlcqpMKE_uvehNiRczgL7xC4BMEj-BJo,12254
15
+ pythonfmu3/variables.py,sha256=U4ESws0jx6QNlzvT9d7If2HEgp6ujpFi225GO9FgHaM,13500
16
16
  pythonfmu3/pythonfmu-export/.clang-format,sha256=ApbsHWYwilCXJ1iBux4nqOjLkaqgbGLsVrc_U3hX7WI,944
17
17
  pythonfmu3/pythonfmu-export/CMakeLists.txt,sha256=WLFfomT1rj9eWJMSXLtSbh5HLIu0DR5VCiYdCl8Cxrw,1854
18
18
  pythonfmu3/pythonfmu-export/build_unix.sh,sha256=I5RrF2O6y0hRG_SN4ExKN_CCFYaa2l-ngKzqmBXnHmA,73
19
19
  pythonfmu3/pythonfmu-export/build_win.sh,sha256=UzmAcWqFmwBu6mvYne2Dx3UK8iPwTtP4HpjICsjUaJA,97
20
20
  pythonfmu3/pythonfmu-export/src/CMakeLists.txt,sha256=fOVlV7hy9c0wx_Qp4K51tQaQ5xy9lL4qtyGl15ZXfGs,1208
21
21
  pythonfmu3/pythonfmu-export/src/cppfmu/cppfmu_common.hpp,sha256=cgrlZa5L-bbjZeVi0pmy4JKE5UJ2GszzuyOqTdRcBRQ,4353
22
- pythonfmu3/pythonfmu-export/src/cppfmu/cppfmu_cs.cpp,sha256=EsUIevwmCzX9hsui3i8x1crSnSOG8dEK15Zm1ZIavYQ,3843
23
- pythonfmu3/pythonfmu-export/src/cppfmu/cppfmu_cs.hpp,sha256=tEz_LIZT1CuXi21S4e_ggM9RJh-ZKukjD-5QHxfZXAk,7444
24
- pythonfmu3/pythonfmu-export/src/cppfmu/fmi_functions.cpp,sha256=nAb0bPGMf44z6aXzH7dGZDrX8N92l8gx-SkQrq3jIik,30015
22
+ pythonfmu3/pythonfmu-export/src/cppfmu/cppfmu_cs.cpp,sha256=explSkxXPayKgSMHxadQ8_Gd8IMYwSnOw5SBItTimuE,4093
23
+ pythonfmu3/pythonfmu-export/src/cppfmu/cppfmu_cs.hpp,sha256=FO2ugz1-YFE8St2AO7k_cXtT7qM5ktrejv_SEKjDRf4,7734
24
+ pythonfmu3/pythonfmu-export/src/cppfmu/fmi_functions.cpp,sha256=oetqW88dlZd75suBoScD0AcA4yktCBSaRfx0vHD_Lyw,30105
25
25
  pythonfmu3/pythonfmu-export/src/fmi/fmi3FunctionTypes.h,sha256=Tk1WY0nAYBGiOAQ8zVbmqRAfdQttITWsLba7udhBwG4,30050
26
26
  pythonfmu3/pythonfmu-export/src/fmi/fmi3Functions.h,sha256=NsHuclp20wcuUInYf-91UXZbljTeu2cPXENqNEORdgU,16262
27
27
  pythonfmu3/pythonfmu-export/src/fmi/fmi3PlatformTypes.h,sha256=ZCQLJgSbRGrMsBiQ4auaYCY4J3Hck6g3t1iZp5NEguw,4251
28
28
  pythonfmu3/pythonfmu-export/src/pythonfmu/IPyState.hpp,sha256=GLiOjhKLDVEICersnqVwezwEshbxfdh_cyMxBJGFbu8,456
29
- pythonfmu3/pythonfmu-export/src/pythonfmu/PySlaveInstance.cpp,sha256=Dmnvn7CprYxECYYXZCI2t81VNw3qscsKOIb6kMm3mNA,33301
30
- pythonfmu3/pythonfmu-export/src/pythonfmu/PySlaveInstance.hpp,sha256=kdLzY-vrRyRnJfqZ0ZQiz7g7i3gP1MLzmvUD7u0ylPM,5392
29
+ pythonfmu3/pythonfmu-export/src/pythonfmu/PySlaveInstance.cpp,sha256=3VTCxq4uXBJW8Ut6oMHHSUGO8OMtSSPoK2VsPGtuT3U,33908
30
+ pythonfmu3/pythonfmu-export/src/pythonfmu/PySlaveInstance.hpp,sha256=59icfvAVdq5rFaeAE1PgEqpknyZHgSQMEBXnZz3efAw,5602
31
31
  pythonfmu3/pythonfmu-export/src/pythonfmu/PyState.hpp,sha256=CjFEIrZu8b1jxQAIgfI_o36hyItW_SdQ5VSkImf7JNs,2977
32
- pythonfmu3/resources/binaries/x86_64-linux/libpythonfmu-export.so,sha256=MYOFAGHaNBGS-o7DFQPmdYrfSgG1QXkhznwlh7fsRfY,367904
33
- pythonfmu3/resources/binaries/x86_64-windows/pythonfmu-export.dll,sha256=MTUolw2jI9rDWEQmqt0XyI_xmu2F880RHfcxpb85Fok,427008
32
+ pythonfmu3/resources/binaries/x86_64-linux/libpythonfmu-export.so,sha256=U_1xuoNMGN6i3xXX5ns6QkQeemB3V8tayCX_mLUFtYA,367944
33
+ pythonfmu3/resources/binaries/x86_64-windows/pythonfmu-export.dll,sha256=SFtJHFYRgW8kp6faJ78HKCYOYaPQVXhtG6SUR3Zv5Iw,427008
34
34
  pythonfmu3/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  pythonfmu3/tests/conftest.py,sha256=B6XxTnBdeF_tEJ3w2DlfPKUfvlk-oULgIhQtXkgOJIc,171
36
36
  pythonfmu3/tests/test_builder.py,sha256=GrD4ziin3RLOe_36rBQCMnKrSkhc3IqnxE1a6kCFPok,6842
37
37
  pythonfmu3/tests/test_deploy.py,sha256=JCDo-O93-izxrP9Q4K0njBcfZ-gAXYx9aZ4plgctz7k,1783
38
38
  pythonfmu3/tests/test_docs.py,sha256=VZZFUj2j35mBKvWATIUzJnWNDfiETsLdHZnRZGutOVM,3134
39
39
  pythonfmu3/tests/test_fmi3slave.py,sha256=VSd3o3ejOcTG6TlnqxVK7YQc4QCKFTCQnpIgleaxJl4,4801
40
- pythonfmu3/tests/test_integration.py,sha256=34rus-OU9S5FlAVAfpZyoHrXoziG14d4_yw4Wdt5uVU,12513
40
+ pythonfmu3/tests/test_integration.py,sha256=0WdI02SmzGB2G5oBnPYgmUnvkKNQ_CpIyfdsUVWfDis,16194
41
41
  pythonfmu3/tests/test_logger.py,sha256=OcHQhxUtNBPH-0zdmheC4I9OWz1yu48W8MYDshNVkf8,5765
42
42
  pythonfmu3/tests/test_multiple_fmus.py,sha256=-sthCm2YUZiRkdfvpLQNgquPBForUKQ7HGqfFBdrRas,3942
43
43
  pythonfmu3/tests/test_variables.py,sha256=FL7eUCXH4RmH0rK0k6qXDnyDzthW_wAWJBHEmC-u8SI,10384
@@ -49,11 +49,12 @@ pythonfmu3/tests/slaves/localmodule.py,sha256=-q5Lmh2I88MG7nLTscms0n5xhHLkUDed1I
49
49
  pythonfmu3/tests/slaves/pythonslave.py,sha256=uzrTQmfk0QBalxNTviGMZNph_YgVmcbxPqKgX5rSvXg,2172
50
50
  pythonfmu3/tests/slaves/pythonslaveMX.py,sha256=rmtiKWj-7DNCEGKAzCoS-6ybkWKabYMhatpn14r7UpA,1167
51
51
  pythonfmu3/tests/slaves/pythonslaveMXCS.py,sha256=P1aKY92obd-y9VGwDRin9fwmnAlSmdHguFW8E5-LU4I,1417
52
+ pythonfmu3/tests/slaves/pythonslave_arraytypes.py,sha256=l5DB0HI0CH_saLwoe1BvZUXgEzxGGYUHiaG3npt2vDk,2429
52
53
  pythonfmu3/tests/slaves/pythonslave_read_file.py,sha256=t2sDaZSr2veD91gdqCO9W9CN-AN3TyXABXXfV9Rt0Xs,791
53
54
  pythonfmu3/tests/slaves/slavewithdep.py,sha256=hHDFB0dw8wkHiGzxeAVbz9O5LR6ghsFeONgRFdiK_t0,812
54
- pythonfmu3-0.3.3.dist-info/licenses/LICENSE,sha256=RL2018BU2DKcTi8Eb4ODF-XF3wnr7SDKvMP5S49x4rQ,1188
55
- pythonfmu3-0.3.3.dist-info/METADATA,sha256=IXN1NfJJ8MAqrE9a7wOmHD95jpATxsMaCLMi3TTayyM,9375
56
- pythonfmu3-0.3.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
57
- pythonfmu3-0.3.3.dist-info/entry_points.txt,sha256=GgkWYs0DKGHLcijMEYZGkhkHOK2RVUpjGwvl1fwyDwQ,60
58
- pythonfmu3-0.3.3.dist-info/top_level.txt,sha256=6ne7bh_cME1hepxCx1BG8N5QVhVAufrp7LLok6vq7nE,11
59
- pythonfmu3-0.3.3.dist-info/RECORD,,
55
+ pythonfmu3-0.3.4.dist-info/licenses/LICENSE,sha256=RL2018BU2DKcTi8Eb4ODF-XF3wnr7SDKvMP5S49x4rQ,1188
56
+ pythonfmu3-0.3.4.dist-info/METADATA,sha256=ydejh5qlluJ22V1R33dKaQQ_TR7-K2BBmHuDcq9lo0E,9375
57
+ pythonfmu3-0.3.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
58
+ pythonfmu3-0.3.4.dist-info/entry_points.txt,sha256=GgkWYs0DKGHLcijMEYZGkhkHOK2RVUpjGwvl1fwyDwQ,60
59
+ pythonfmu3-0.3.4.dist-info/top_level.txt,sha256=6ne7bh_cME1hepxCx1BG8N5QVhVAufrp7LLok6vq7nE,11
60
+ pythonfmu3-0.3.4.dist-info/RECORD,,