• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

NREL / SolTrace / 19979510856

06 Dec 2025 12:06AM UTC coverage: 87.255% (-1.9%) from 89.184%
19979510856

Pull #89

github

web-flow
Merge 5cb7cfc67 into a73a760a4
Pull Request #89: simulation_data changes to support UI-side constructions

0 of 148 new or added lines in 5 files covered. (0.0%)

1 existing line in 1 file now uncovered.

5970 of 6842 relevant lines covered (87.26%)

7824776.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.73
/coretrace/simulation_data/element.hpp
1
/**
2
 * @file element.hpp
3
 * @brief Base element class and element management
4
 *
5
 * Defines the base ElementBase class and element management utilities.
6
 * All optical elements in SolTrace derive from this base class, providing
7
 * common functionality for positioning, orientation, and optical properties.
8
 *
9
 * @defgroup elements Optical Elements
10
 * @{
11
 */
12

13
#ifndef SOLTRACE_ELEMENT_H
14
#define SOLTRACE_ELEMENT_H
15

16
// #include <memory>
17
#include <string>
18
#include <nlohmann/json.hpp>
19

20
#include "aperture.hpp"
21
#include "constants.hpp"
22
#include "container.hpp"
23
#include "optical_properties.hpp"
24
#include "ray_source.hpp"
25
#include "surface.hpp"
26
#include "vector3d.hpp"
27

28
namespace SolTrace::Data {
29

30
using element_id = std::int_fast64_t;
31
const element_id ELEMENT_ERROR = -1;
32
const element_id ELEMENT_ID_UNASSIGNED = -2;
33
const element_id ELEMENT_ALREADY_REGISTERED = -3;
34
const element_id ELEMENT_INVALID_SETUP = -4;
35
const element_id ELEMENT_NULL = -5;
36

37
// Forward declaration of the Element class so we can define ElementContainer
38
class Element;
39

40
using ElementContainer = Container<element_id, Element>;
41
using element_ptr = ElementContainer::value_pointer;
42

43
class Element
44
{
45
public:
46
  static bool is_success(element_id id)
31,608✔
47
  {
48
    return id >= 0;
31,608✔
49
  }
50

51
  Element() {};
20,122✔
52
  virtual ~Element() {};
20,122✔
53

54
  // Accessors for any element
55
  /// @brief Disable the element for ray tracing
56
  virtual void disable() const = 0;
57
  /// @brief Enable the element for ray tracing
58
  virtual void enable() const = 0;
59
  /// @brief Check whether element is enabled/disabled
60
  /// @return true if enabled, false otherwise
61
  virtual bool is_enabled() const = 0;
62

63
  /// @brief Check whether the element is a CompositeElement
64
  /// @return true if CompositeElement, false otherwise
65
  virtual bool is_composite() const = 0;
66
  /// @brief Check whether the element is a SingleElement
67
  /// @return true if SingleElement, false otherwise
68
  virtual bool is_single() const = 0;
69
  /// @brief Check whether this element is a StageElement
70
  /// @return true if StageElement, false otherwise
71
  virtual bool is_stage() const = 0;
72
  /// @brief Check whether the element is a VirtualElement
73
  /// @return true if VirtualElement, false otherwise
74
  virtual bool is_virtual() const = 0;
75
  virtual void mark_virtual() const = 0;
76
  virtual void unmark_virtual() const = 0;
77

78
  /// @brief Get the element id assigned when registered with SimulationData
79
  /// @return id if registered with SimulationData, ELEMENT_ID_UNASSIGNED if not
80
  virtual element_id get_id() const = 0;
81

82
  /**
83
   * @brief Get the stage number this element belongs to
84
   * @return Stage number
85
   */
86
  virtual int_fast64_t get_stage() = 0;
87

88
  /**
89
   * @brief Get the parent this element belongs to
90
   * @return parent element ptr
91
   */
92
  virtual Element* get_reference_element() const = 0;
93

94
  /**
95
   * @brief Get the element name
96
   * @return Reference to element name string
97
   */
98
  virtual const std::string &get_name() const = 0;
99

100
  /**
101
   * @brief Set the element name
102
   * @param name New name for the element
103
   */
104
  virtual void set_name(const std::string &name) = 0;
105

106
  /****************************************************************************
107
   * NOTE: For all coordinate functions below, the term "reference coordinates"
108
   * means the coordinate frame immediately above this elements. If Element
109
   * is a subelement of a CompositeElement the reference coordinates are the
110
   * CompositeElements even if that CompositeElement is then stored in a stage.
111
   ***************************************************************************/
112

113
  /**
114
   * @brief Get origin position in reference coordinates
115
   * @return Origin position vector in reference frame
116
   */
117
  virtual Vector3d get_origin_ref() const = 0;
118

119
  /**
120
   * @brief Get origin position in stage coordinates
121
   * @return Origin position vector in stage frame
122
   */
123
  virtual Vector3d get_origin_stage() const = 0;
124

125
  /**
126
   * @brief Get origin position in global coordinates
127
   * @return Origin position vector in global frame
128
   */
129
  virtual Vector3d get_origin_global() const = 0;
130

131
  /**
132
   * @brief Set origin position (always relative to reference coordinates)
133
   * @param origin New origin position vector
134
   */
135
  virtual void set_origin(const Vector3d &) = 0;
136

137
  /**
138
   * @brief Set origin position (always relative to reference coordinates)
139
   * @param x X coordinate
140
   * @param y Y coordinate
141
   * @param z Z coordinate
142
   */
143
  virtual void set_origin(double, double, double) = 0;
144

145
  // virtual const Vector3d &get_global_origin() const = 0;
146
  // virtual void set_global_origin(const Vector3d &) = 0;
147

148
  /**
149
   * @brief Get aim vector in reference coordinates
150
   * @return Aim direction vector in reference frame
151
   */
152
  virtual Vector3d get_aim_vector_ref() const = 0;
153
  virtual Vector3d get_aim_vector_stage() const = 0;
154
  virtual Vector3d get_aim_vector_global() const = 0;
155
  // Always the aim vector with respect the reference coordinates
156
  virtual void set_aim_vector(const Vector3d &) = 0;
157
  virtual void set_aim_vector(double, double, double) = 0;
158
  // Always the Euler angles with respect the reference coordinates
159
  virtual const Vector3d &get_euler_angles() const = 0;
160
  // Always the ZRot with respect to the reference coordinates
161
  virtual double get_zrot() const = 0;
162
  virtual void set_zrot(double) = 0;
163
  virtual double get_zrot_radians() const = 0;
164
  virtual void set_zrot_radians(double) = 0;
165

166
  virtual Matrix3d get_reference_to_local() const = 0;
167
  virtual Matrix3d get_stage_to_local() const = 0;
168
  virtual Matrix3d get_global_to_local() const = 0;
169
  virtual Matrix3d get_local_to_reference() const = 0;
170
  virtual Matrix3d get_local_to_stage() const = 0;
171
  virtual Matrix3d get_local_to_global() const = 0;
172

173
  // virtual const Vector3d &get_upper_bounding_box() const = 0;
174
  // virtual const Vector3d &get_lower_bounding_box() const = 0;
175

176
  // Accessors for SingleElements
177
  virtual const aperture_ptr get_aperture() const = 0;
178
  virtual aperture_ptr get_aperture() = 0;
179
  virtual void set_aperture(aperture_ptr) = 0;
180
  virtual const surface_ptr get_surface() const = 0;
181
  virtual surface_ptr get_surface() = 0;
182
  virtual void set_surface(surface_ptr) = 0;
183

184
  // virtual const OpticalProperties &get_optical_properties() const = 0;
185
  // virtual void set_optical_properties(const OpticalProperties &) = 0;
186

187
  virtual const OpticalProperties *get_front_optical_properties() const = 0;
188
  virtual OpticalProperties *get_front_optical_properties() = 0;
189
  virtual void set_front_optical_properties(const OpticalProperties &) = 0;
190

191
  virtual const OpticalProperties *get_back_optical_properties() const = 0;
192
  virtual OpticalProperties *get_back_optical_properties() = 0;
193
  virtual void set_back_optical_properties(const OpticalProperties &) = 0;
194

195
  // Accessors for CompositeElements
196
  virtual uint_fast64_t get_number_of_elements() const = 0;
197
  // virtual ElementContainer::iterator get_iterator() = 0;
198
  // virtual ElementContainer::const_iterator get_const_iterator() = 0;
199
  // virtual bool is_at_end(ElementContainer::iterator iter) = 0;
200
  // virtual bool is_at_end(ElementContainer::const_iterator iter) = 0;
201

202
  // Coordinate transformation routines
203
  virtual int set_reference_frame_geometry(const Vector3d &origin,
204
                                           const Vector3d &aim,
205
                                           double zrot) = 0;
206

207
  /****************************************************************
208
   * These are point coordinate conversion routines. They convert a point
209
   * from one coordinate system to another. Assumes that the element
210
   * hierarchy is set and that `compute_coordinate_rotations` has been
211
   * called.
212
   ****************************************************************/
213

214
  // Convert `ref` to local coordinates and store the result in `local`
215
  virtual int convert_reference_to_local(Vector3d &local,
216
                                         const Vector3d &ref) = 0;
217
  // Convert `stage` to local coordinates and store the result in `local`
218
  virtual int convert_stage_to_local(Vector3d &local,
219
                                     const Vector3d &stage) = 0;
220
  // Convert `global` to local coordinates and store the result in `local`
221
  virtual int convert_global_to_local(Vector3d &local,
222
                                      const Vector3d &global) = 0;
223
  // Convert `local` to reference coordinates and store the result in `ref`
224
  virtual int convert_local_to_reference(Vector3d &ref,
225
                                         const Vector3d &local) = 0;
226
  // Convert `local` to stage coordinates and store the result in `stage`
227
  virtual int convert_local_to_stage(Vector3d &stage,
228
                                     const Vector3d &local) = 0;
229
  // Convert `local` to global coordinates and store the result in `global`
230
  virtual int convert_local_to_global(Vector3d &global,
231
                                      const Vector3d &local) = 0;
232

233
  // Convert global coordinates to reference coordinates
234
  virtual int convert_global_to_reference(Vector3d &ref,
235
                                          const Vector3d &global) = 0;
236
  // Convert reference coordinates to global
237
  virtual int convert_reference_to_global(Vector3d &global,
238
                                          const Vector3d &ref) = 0;
239

240
  /****************************************************************
241
   * These are vector coordinate conversion routines. They convert a
242
   * vector (i.e. origin is always the same) from one coordinate
243
   * system to another. Assumes that the element hierarchy is set
244
   * and that `compute_coordinate_rotations` has been called.
245
   ****************************************************************/
246

247
  // Convert `ref` to local coordinates and store the result in `local`
248
  virtual int convert_vector_reference_to_local(Vector3d &local,
249
                                                const Vector3d &ref) = 0;
250
  // Convert `stage` to local coordinates and store the result in `local`
251
  virtual int convert_vector_stage_to_local(Vector3d &local,
252
                                            const Vector3d &stage) = 0;
253
  // Convert `global` to local coordinates and store the result in `local`
254
  virtual int convert_vector_global_to_local(Vector3d &local,
255
                                             const Vector3d &global) = 0;
256
  // Convert `local` to reference coordinates and store the result in `ref`
257
  virtual int convert_vector_local_to_reference(Vector3d &ref,
258
                                                const Vector3d &local) = 0;
259
  // Convert `local` to stage coordinates and store the result in `stage`
260
  virtual int convert_vector_local_to_stage(Vector3d &stage,
261
                                            const Vector3d &local) = 0;
262
  // Convert `local` to global coordinates and store the result in `global`
263
  virtual int convert_vector_local_to_global(Vector3d &global,
264
                                             const Vector3d &local) = 0;
265

266
  // Convert global coordinates to reference coordinates
267
  virtual int convert_vector_global_to_reference(Vector3d &ref,
268
                                                 const Vector3d &global) = 0;
269
  // Convert reference coordinates to global
270
  virtual int convert_vector_reference_to_global(Vector3d &global,
271
                                                 const Vector3d &ref) = 0;
272

273
  // Other routines
274
  // Computes necessary coordinate transformation data. Expects
275
  // that the element hierarchy is set above this element.
276
  virtual int compute_coordinate_rotations() = 0;
277

278
  // WARNING: The below Accessors should be used with EXTREME caution!!!
279
  // These are used by other classes to set things up correctly and
280
  // not meant for the casual user. You have been warned!
281

282
  /// @brief Set the element id--used by SimulationData
283
  /// @param id id assigned and to set
284
  virtual void set_id(element_id id) = 0;
285
  virtual void set_reference_element(Element *reference) = 0;
286
  virtual void set_stage(int_fast64_t stage) = 0;
287

288
  // WARNING: The below Accessors should be used with care. They set
289
  // values that are set automatically -- these are here just in case...
290
  virtual void set_euler_angles(const Vector3d &) = 0;
291
  virtual void set_euler_angles(double, double, double) = 0;
292
  virtual void set_reference_to_local(const Matrix3d &) = 0;
293
  virtual void set_local_to_reference(const Matrix3d &) = 0;
294

295
  // Check that all required fields have been set
296
  virtual void enforce_user_fields_set() const = 0;
297

298
  // Write element to json node
299
  virtual void write_json(nlohmann::ordered_json& jnode) const = 0;
300

301
  virtual void write_common_json(nlohmann::ordered_json& jnode) const = 0;
302

303
  // Check if element has parent elements
304
  virtual bool is_top_level() = 0;
305

306
protected:
307
  // virtual int set_bounding_box() = 0;
308

309
private:
310
};
311

312
class ElementBase : public Element
313
{
314
public:
315
  ElementBase();
316
  // ElementBase(const Vector3d &origin, const Vector3d &aim);
317
  ElementBase(const nlohmann::ordered_json& jnode);
318
  virtual ~ElementBase();
319

320
  virtual inline void disable() const override { this->active = false; }
×
321
  virtual inline void enable() const override { this->active = true; }
2,463✔
322
  virtual bool is_enabled() const override { return this->active; }
29,909✔
323

324
  virtual bool is_composite() const override { return false; }
29,514✔
325
  virtual bool is_single() const override { return false; }
270✔
326
  virtual bool is_stage() const override { return false; }
87,088✔
327

328
  virtual bool is_virtual() const override { return this->virtual_flag; }
27✔
329
  virtual void mark_virtual() const override {this->virtual_flag = true;}
×
330
  virtual void unmark_virtual() const override {this->virtual_flag = false;}
×
331

332
  // virtual ElementContainer::iterator get_iterator();
333
  // virtual ElementContainer::const_iterator get_const_iterator();
334
  // virtual bool is_at_end(ElementContainer::iterator iter) { return true; }
335
  // virtual bool is_at_end(ElementContainer::const_iterator iter) { return true; }
336
  virtual void set_reference_element(Element *reference) override
19,985✔
337
  {
338
    this->reference_element = reference;
19,985✔
339
  }
19,985✔
NEW
340
  virtual Element* get_reference_element() const override
×
341
  {
NEW
342
      return reference_element;
×
343
  }
344

345
  virtual uint_fast64_t get_number_of_elements() const override { return 1; }
19,746✔
346

347
  virtual element_id get_id() const override { return this->my_id; }
34,592✔
348
  virtual void set_id(element_id id) override
22,267✔
349
  {
350
    this->my_id = id;
22,267✔
351
    return;
22,267✔
352
  }
353

354
  virtual int_fast64_t get_stage() override { return this->stage; }
14,696✔
355
  virtual void set_stage(int_fast64_t stage) override { this->stage = stage; }
21,865✔
356

357
  virtual const std::string &get_name() const override
8✔
358
  {
359
    return this->my_name;
8✔
360
  }
361
  virtual void set_name(const std::string &name) override
17,988✔
362
  {
363
    this->my_name = name;
17,988✔
364
  }
17,988✔
365

366
  virtual Vector3d get_origin_ref() const override { return this->origin; }
258✔
367
  virtual Vector3d get_origin_stage() const override;
368
  virtual Vector3d get_origin_global() const override;
369
  virtual void set_origin(const Vector3d &point) override
261✔
370
  {
371
    this->coordinates_initialized = false;
261✔
372
    this->origin = point;
261✔
373
    return;
261✔
374
  }
375
  virtual void set_origin(double x, double y, double z) override
77✔
376
  {
377
    this->coordinates_initialized = false;
77✔
378
    this->origin.set_values(x, y, z);
77✔
379
    return;
77✔
380
  }
381
  virtual Vector3d get_aim_vector_ref() const override { return this->aim; }
1✔
382
  virtual Vector3d get_aim_vector_stage() const override;
383
  virtual Vector3d get_aim_vector_global() const override;
384
  virtual void set_aim_vector(const Vector3d &direction) override
32✔
385
  {
386
    this->coordinates_initialized = false;
32✔
387
    this->aim = direction;
32✔
388
    return;
32✔
389
  }
390
  virtual void set_aim_vector(double x, double y, double z) override
61✔
391
  {
392
    this->coordinates_initialized = false;
61✔
393
    this->aim.set_values(x, y, z);
61✔
394
    return;
61✔
395
  }
396
  virtual const Vector3d &get_euler_angles() const override
×
397
  {
398
    return this->euler_angles;
×
399
  }
400
  // virtual void set_euler_angles(const Vector3d &angles)
401
  // {
402
  //   this->euler_angles = angles;
403
  //   return;
404
  // }
405
  virtual double get_zrot() const override { return this->zrot; }
14,677✔
406
  virtual void set_zrot(double rot) override
74✔
407
  {
408
    this->coordinates_initialized = false;
74✔
409
    this->zrot = rot;
74✔
410
    return;
74✔
411
  }
412

413
  virtual double get_zrot_radians() const override
×
414
  {
415
    return this->zrot * PI / 180.0;
×
416
  }
417
  virtual void set_zrot_radians(double zrad) override
250✔
418
  {
419
    this->coordinates_initialized = false;
250✔
420
    this->zrot = zrad * 180.0 / PI;
250✔
421
    return;
250✔
422
  }
423

424
  virtual Matrix3d get_reference_to_local() const override;
425
  virtual Matrix3d get_stage_to_local() const override;
426
  virtual Matrix3d get_global_to_local() const override;
427
  virtual Matrix3d get_local_to_reference() const override;
428
  virtual Matrix3d get_local_to_stage() const override;
429
  virtual Matrix3d get_local_to_global() const override;
430

431
  virtual int compute_coordinate_rotations() override;
432
  virtual int set_reference_frame_geometry(const Vector3d &origin,
433
                                           const Vector3d &aim,
434
                                           double zrot) override;
435

436
  // Convert `ref` to local coordinates and store the result in `local`
437
  virtual int convert_reference_to_local(Vector3d &local,
438
                                         const Vector3d &ref) override;
439
  // Convert `stage` to local coordinates and store the result in `local`
440
  virtual int convert_stage_to_local(Vector3d &local,
441
                                     const Vector3d &stage) override;
442
  // Convert `global` to local coordinates and store the result in `local`
443
  virtual int convert_global_to_local(Vector3d &local,
444
                                      const Vector3d &global) override;
445
  // Convert `local` to reference coordinates and store the result in `ref`
446
  virtual int convert_local_to_reference(Vector3d &ref,
447
                                         const Vector3d &local) override;
448
  // Convert `local` to stage coordinates and store the result in `stage`
449
  virtual int convert_local_to_stage(Vector3d &stage,
450
                                     const Vector3d &local) override;
451
  // Convert `local` to global coordinates and store the result in `global`
452
  virtual int convert_local_to_global(Vector3d &global,
453
                                      const Vector3d &local) override;
454

455
  // Convert global coordinates to reference coordinates
456
  virtual int convert_global_to_reference(Vector3d &ref,
457
                                          const Vector3d &global) override;
458
  // Convert reference coordinates to global
459
  virtual int convert_reference_to_global(Vector3d &global,
460
                                          const Vector3d &ref) override;
461

462
  // Convert `ref` to local coordinates and store the result in `local`
463
  virtual int convert_vector_reference_to_local(Vector3d &local,
464
                                                const Vector3d &ref) override;
465
  // Convert `stage` to local coordinates and store the result in `local`
466
  virtual int convert_vector_stage_to_local(Vector3d &local,
467
                                            const Vector3d &stage) override;
468
  // Convert `global` to local coordinates and store the result in `local`
469
  virtual int convert_vector_global_to_local(Vector3d &local,
470
                                             const Vector3d &global) override;
471
  // Convert `local` to reference coordinates and store the result in `ref`
472
  virtual int convert_vector_local_to_reference(Vector3d &ref,
473
                                                const Vector3d &local) override;
474
  // Convert `local` to stage coordinates and store the result in `stage`
475
  virtual int convert_vector_local_to_stage(Vector3d &stage,
476
                                            const Vector3d &local) override;
477
  // Convert `local` to global coordinates and store the result in `global`
478
  virtual int convert_vector_local_to_global(Vector3d &global,
479
                                             const Vector3d &local) override;
480

481
  // Convert global coordinates to reference coordinates
482
  virtual int convert_vector_global_to_reference(Vector3d &ref,
483
                                                 const Vector3d &global) override;
484
  // Convert reference coordinates to global
485
  virtual int convert_vector_reference_to_global(Vector3d &global,
486
                                                 const Vector3d &ref) override;
487

488
  // WARNING: The below Accessors should be used with care. They set
489
  // values that are set automatically -- these are here just in case...
490
  virtual void set_euler_angles(const Vector3d &ea) override
×
491
  {
492
    this->euler_angles = ea;
×
493
  }
×
494
  virtual void set_euler_angles(double alpha, double beta, double gamma) override
×
495
  {
496
    this->euler_angles.set_values(alpha, beta, gamma);
×
497
  }
×
498
  virtual void set_reference_to_local(const Matrix3d &rtol) override
×
499
  {
500
    this->reference_to_local = rtol;
×
501
  }
×
502
  virtual void set_local_to_reference(const Matrix3d &ltor) override
×
503
  {
504
    this->local_to_reference = ltor;
×
505
  }
×
506

507
  virtual void enforce_user_fields_set() const override;
508

509
  virtual void write_common_json(nlohmann::ordered_json& jnode) const override;
510

511
  virtual bool is_top_level() override
2,452✔
512
  {
513
      return this->reference_element == nullptr;
2,452✔
514
  }
515

516
protected:
517
  // TODO: Do these need to be mutable?
518
  mutable bool active;
519
  mutable bool virtual_flag;
520
  mutable element_id my_id;
521

522
  bool coordinates_initialized;
523

524
  int_fast64_t stage;
525
  std::string my_name;
526

527
  // Location of the origin in the reference coordinate system
528
  Vector3d origin;
529
  // Aim vector of element--aligns with the local (positive) z-axis
530
  Vector3d aim;
531
  // Rotation about the aim vector to set local x and y axes in degrees (ugh!)
532
  double zrot;
533

534
  Vector3d euler_angles;
535

536
  Matrix3d reference_to_local;
537
  Matrix3d local_to_reference;
538

539
  // element_ptr reference_element;
540
  Element *reference_element; // todo: this is a raw pointer, probably shouldn't be
541

542
private:
543
  // static ElementContainer empty_container;
544
};
545

546
// using element_ptr = typename std::shared_ptr<Element>;
547
// using ElementContainer = std::map<element_id, element_ptr>;
548

549
template <typename C, typename... Args>
550
inline auto make_element(Args &&...args)
2,441✔
551
{
552
  return ElementContainer::make_pointer<C>(std::forward<Args>(args)...);
2,441✔
553
}
554

555
} // namespace SolTrace::Data
556

557
/**
558
 * @}
559
 */
560

561
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc