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

NREL / SolTrace / 18889752882

28 Oct 2025 09:28PM UTC coverage: 89.87% (-0.08%) from 89.946%
18889752882

Pull #76

github

web-flow
Merge e6c58895d into f6f121007
Pull Request #76: Fix NativeRunner ray tracing failure for parabola surface

944 of 994 new or added lines in 28 files covered. (94.97%)

2 existing lines in 1 file now uncovered.

4418 of 4916 relevant lines covered (89.87%)

10138914.15 hits per line

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

73.97
/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

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

27
namespace SolTrace::Data {
28

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

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

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

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

50
  Element() {};
8,946✔
51
  virtual ~Element() {};
8,946✔
52

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

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

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

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

87
  /**
88
   * @brief Get the element name
89
   * @return Reference to element name string
90
   */
91
  virtual const std::string &get_name() const = 0;
92

93
  /**
94
   * @brief Set the element name
95
   * @param name New name for the element
96
   */
97
  virtual void set_name(const std::string &name) = 0;
98

99
  /****************************************************************************
100
   * NOTE: For all coordinate functions below, the term "reference coordinates"
101
   * means the coordinate frame immediately above this elements. If Element
102
   * is a subelement of a CompositeElement the reference coordinates are the
103
   * CompositeElements even if that CompositeElement is then stored in a stage.
104
   ***************************************************************************/
105

106
  /**
107
   * @brief Get origin position in reference coordinates
108
   * @return Origin position vector in reference frame
109
   */
110
  virtual Vector3d get_origin_ref() const = 0;
111

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

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

124
  /**
125
   * @brief Set origin position (always relative to reference coordinates)
126
   * @param origin New origin position vector
127
   */
128
  virtual void set_origin(const Vector3d &) = 0;
129

130
  /**
131
   * @brief Set origin position (always relative to reference coordinates)
132
   * @param x X coordinate
133
   * @param y Y coordinate
134
   * @param z Z coordinate
135
   */
136
  virtual void set_origin(double, double, double) = 0;
137

138
  // virtual const Vector3d &get_global_origin() const = 0;
139
  // virtual void set_global_origin(const Vector3d &) = 0;
140

141
  /**
142
   * @brief Get aim vector in reference coordinates
143
   * @return Aim direction vector in reference frame
144
   */
145
  virtual Vector3d get_aim_vector_ref() const = 0;
146
  virtual Vector3d get_aim_vector_stage() const = 0;
147
  virtual Vector3d get_aim_vector_global() const = 0;
148
  // Always the aim vector with respect the reference coordinates
149
  virtual void set_aim_vector(const Vector3d &) = 0;
150
  virtual void set_aim_vector(double, double, double) = 0;
151
  // Always the Euler angles with respect the reference coordinates
152
  virtual const Vector3d &get_euler_angles() const = 0;
153
  // Always the ZRot with respect to the reference coordinates
154
  virtual double get_zrot() const = 0;
155
  virtual void set_zrot(double) = 0;
156
  virtual double get_zrot_radians() const = 0;
157
  virtual void set_zrot_radians(double) = 0;
158

159
  virtual Matrix3d get_reference_to_local() const = 0;
160
  virtual Matrix3d get_stage_to_local() const = 0;
161
  virtual Matrix3d get_global_to_local() const = 0;
162
  virtual Matrix3d get_local_to_reference() const = 0;
163
  virtual Matrix3d get_local_to_stage() const = 0;
164
  virtual Matrix3d get_local_to_global() const = 0;
165

166
  // virtual const Vector3d &get_upper_bounding_box() const = 0;
167
  // virtual const Vector3d &get_lower_bounding_box() const = 0;
168

169
  // Accessors for SingleElements
170
  virtual const aperture_ptr get_aperture() const = 0;
171
  virtual aperture_ptr get_aperture() = 0;
172
  virtual void set_aperture(aperture_ptr) = 0;
173
  virtual const surface_ptr get_surface() const = 0;
174
  virtual surface_ptr get_surface() = 0;
175
  virtual void set_surface(surface_ptr) = 0;
176

177
  // virtual const OpticalProperties &get_optical_properties() const = 0;
178
  // virtual void set_optical_properties(const OpticalProperties &) = 0;
179

180
  virtual const OpticalProperties *get_front_optical_properties() const = 0;
181
  virtual OpticalProperties *get_front_optical_properties() = 0;
182
  virtual void set_front_optical_properties(const OpticalProperties &) = 0;
183

184
  virtual const OpticalProperties *get_back_optical_properties() const = 0;
185
  virtual OpticalProperties *get_back_optical_properties() = 0;
186
  virtual void set_back_optical_properties(const OpticalProperties &) = 0;
187

188
  // Accessors for CompositeElements
189
  virtual uint_fast64_t get_number_of_elements() const = 0;
190
  // virtual ElementContainer::iterator get_iterator() = 0;
191
  // virtual ElementContainer::const_iterator get_const_iterator() = 0;
192
  // virtual bool is_at_end(ElementContainer::iterator iter) = 0;
193
  // virtual bool is_at_end(ElementContainer::const_iterator iter) = 0;
194

195
  // Coordinate transformation routines
196
  virtual int set_reference_frame_geometry(const Vector3d &origin,
197
                                           const Vector3d &aim,
198
                                           double zrot) = 0;
199

200
  /****************************************************************
201
   * These are point coordinate conversion routines. They convert a point
202
   * from one coordinate system to another. Assumes that the element
203
   * hierarchy is set and that `compute_coordinate_rotations` has been
204
   * called.
205
   ****************************************************************/
206

207
  // Convert `ref` to local coordinates and store the result in `local`
208
  virtual int convert_reference_to_local(Vector3d &local,
209
                                         const Vector3d &ref) = 0;
210
  // Convert `stage` to local coordinates and store the result in `local`
211
  virtual int convert_stage_to_local(Vector3d &local,
212
                                     const Vector3d &stage) = 0;
213
  // Convert `global` to local coordinates and store the result in `local`
214
  virtual int convert_global_to_local(Vector3d &local,
215
                                      const Vector3d &global) = 0;
216
  // Convert `local` to reference coordinates and store the result in `ref`
217
  virtual int convert_local_to_reference(Vector3d &ref,
218
                                         const Vector3d &local) = 0;
219
  // Convert `local` to stage coordinates and store the result in `stage`
220
  virtual int convert_local_to_stage(Vector3d &stage,
221
                                     const Vector3d &local) = 0;
222
  // Convert `local` to global coordinates and store the result in `global`
223
  virtual int convert_local_to_global(Vector3d &global,
224
                                      const Vector3d &local) = 0;
225

226
  // Convert global coordinates to reference coordinates
227
  virtual int convert_global_to_reference(Vector3d &ref,
228
                                          const Vector3d &global) = 0;
229
  // Convert reference coordinates to global
230
  virtual int convert_reference_to_global(Vector3d &global,
231
                                          const Vector3d &ref) = 0;
232

233
  /****************************************************************
234
   * These are vector coordinate conversion routines. They convert a
235
   * vector (i.e. origin is always the same) from one coordinate
236
   * system to another. Assumes that the element hierarchy is set
237
   * and that `compute_coordinate_rotations` has been called.
238
   ****************************************************************/
239

240
  // Convert `ref` to local coordinates and store the result in `local`
241
  virtual int convert_vector_reference_to_local(Vector3d &local,
242
                                                const Vector3d &ref) = 0;
243
  // Convert `stage` to local coordinates and store the result in `local`
244
  virtual int convert_vector_stage_to_local(Vector3d &local,
245
                                            const Vector3d &stage) = 0;
246
  // Convert `global` to local coordinates and store the result in `local`
247
  virtual int convert_vector_global_to_local(Vector3d &local,
248
                                             const Vector3d &global) = 0;
249
  // Convert `local` to reference coordinates and store the result in `ref`
250
  virtual int convert_vector_local_to_reference(Vector3d &ref,
251
                                                const Vector3d &local) = 0;
252
  // Convert `local` to stage coordinates and store the result in `stage`
253
  virtual int convert_vector_local_to_stage(Vector3d &stage,
254
                                            const Vector3d &local) = 0;
255
  // Convert `local` to global coordinates and store the result in `global`
256
  virtual int convert_vector_local_to_global(Vector3d &global,
257
                                             const Vector3d &local) = 0;
258

259
  // Convert global coordinates to reference coordinates
260
  virtual int convert_vector_global_to_reference(Vector3d &ref,
261
                                                 const Vector3d &global) = 0;
262
  // Convert reference coordinates to global
263
  virtual int convert_vector_reference_to_global(Vector3d &global,
264
                                                 const Vector3d &ref) = 0;
265

266
  // Other routines
267
  // Computes necessary coordinate transformation data. Expects
268
  // that the element hierarchy is set above this element.
269
  virtual int compute_coordinate_rotations() = 0;
270

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

275
  /// @brief Set the element id--used by SimulationData
276
  /// @param id id assigned and to set
277
  virtual void set_id(element_id id) = 0;
278
  virtual void set_reference_element(Element *reference) = 0;
279
  virtual void set_stage(int_fast64_t stage) = 0;
280

281
  // WARNING: The below Accessors should be used with care. They set
282
  // values that are set automatically -- these are here just in case...
283
  virtual void set_euler_angles(const Vector3d &) = 0;
284
  virtual void set_euler_angles(double, double, double) = 0;
285
  virtual void set_reference_to_local(const Matrix3d &) = 0;
286
  virtual void set_local_to_reference(const Matrix3d &) = 0;
287

288
  // Check that all required fields have been set
289
  virtual void enforce_user_fields_set() const = 0;
290

291
protected:
292
  // virtual int set_bounding_box() = 0;
293

294
private:
295
};
296

297
class ElementBase : public Element
298
{
299
public:
300
  ElementBase();
301
  // ElementBase(const Vector3d &origin, const Vector3d &aim);
302
  virtual ~ElementBase();
303

304
  virtual inline void disable() const override { this->active = false; }
×
305
  virtual inline void enable() const override { this->active = true; }
2,463✔
306
  virtual bool is_enabled() const override { return this->active; }
17,301✔
307

308
  virtual bool is_composite() const override { return false; }
16,916✔
309
  virtual bool is_single() const override { return false; }
259✔
310
  virtual bool is_stage() const override { return false; }
50,527✔
311

312
  virtual bool is_virtual() const override { return this->virtual_flag; }
17✔
NEW
313
  virtual void mark_virtual() const override {this->virtual_flag = true;}
×
NEW
314
  virtual void unmark_virtual() const override {this->virtual_flag = false;}
×
315

316
  // virtual ElementContainer::iterator get_iterator();
317
  // virtual ElementContainer::const_iterator get_const_iterator();
318
  // virtual bool is_at_end(ElementContainer::iterator iter) { return true; }
319
  // virtual bool is_at_end(ElementContainer::const_iterator iter) { return true; }
320
  virtual void set_reference_element(Element *reference) override
8,836✔
321
  {
322
    this->reference_element = reference;
8,836✔
323
  }
8,836✔
324

325
  virtual uint_fast64_t get_number_of_elements() const override { return 1; }
8,597✔
326

327
  virtual element_id get_id() const override { return this->my_id; }
17,064✔
328
  virtual void set_id(element_id id) override
8,658✔
329
  {
330
    this->my_id = id;
8,658✔
331
    return;
8,658✔
332
  }
333

334
  virtual int_fast64_t get_stage() override { return this->stage; }
8,311✔
335
  virtual void set_stage(int_fast64_t stage) override { this->stage = stage; }
8,282✔
336

337
  virtual const std::string &get_name() const override
8✔
338
  {
339
    return this->my_name;
8✔
340
  }
341
  virtual void set_name(const std::string &name) override
6,822✔
342
  {
343
    this->my_name = name;
6,822✔
344
  }
6,822✔
345

346
  virtual Vector3d get_origin_ref() const override { return this->origin; }
258✔
347
  virtual Vector3d get_origin_stage() const override;
348
  virtual Vector3d get_origin_global() const override;
349
  virtual void set_origin(const Vector3d &point) override
249✔
350
  {
351
    this->coordinates_initialized = false;
249✔
352
    this->origin = point;
249✔
353
    return;
249✔
354
  }
355
  virtual void set_origin(double x, double y, double z) override
55✔
356
  {
357
    this->coordinates_initialized = false;
55✔
358
    this->origin.set_values(x, y, z);
55✔
359
    return;
55✔
360
  }
361
  virtual Vector3d get_aim_vector_ref() const override { return this->aim; }
1✔
362
  virtual Vector3d get_aim_vector_stage() const override;
363
  virtual Vector3d get_aim_vector_global() const override;
364
  virtual void set_aim_vector(const Vector3d &direction) override
20✔
365
  {
366
    this->coordinates_initialized = false;
20✔
367
    this->aim = direction;
20✔
368
    return;
20✔
369
  }
370
  virtual void set_aim_vector(double x, double y, double z) override
39✔
371
  {
372
    this->coordinates_initialized = false;
39✔
373
    this->aim.set_values(x, y, z);
39✔
374
    return;
39✔
375
  }
376
  virtual const Vector3d &get_euler_angles() const override
×
377
  {
378
    return this->euler_angles;
×
379
  }
380
  // virtual void set_euler_angles(const Vector3d &angles)
381
  // {
382
  //   this->euler_angles = angles;
383
  //   return;
384
  // }
385
  virtual double get_zrot() const override { return this->zrot; }
8,368✔
386
  virtual void set_zrot(double rot) override
48✔
387
  {
388
    this->coordinates_initialized = false;
48✔
389
    this->zrot = rot;
48✔
390
    return;
48✔
391
  }
392

393
  virtual double get_zrot_radians() const override
×
394
  {
395
    return this->zrot * PI / 180.0;
×
396
  }
397
  virtual void set_zrot_radians(double zrad) override
250✔
398
  {
399
    this->coordinates_initialized = false;
250✔
400
    this->zrot = zrad * 180.0 / PI;
250✔
401
    return;
250✔
402
  }
403

404
  virtual Matrix3d get_reference_to_local() const override;
405
  virtual Matrix3d get_stage_to_local() const override;
406
  virtual Matrix3d get_global_to_local() const override;
407
  virtual Matrix3d get_local_to_reference() const override;
408
  virtual Matrix3d get_local_to_stage() const override;
409
  virtual Matrix3d get_local_to_global() const override;
410

411
  virtual int compute_coordinate_rotations() override;
412
  virtual int set_reference_frame_geometry(const Vector3d &origin,
413
                                           const Vector3d &aim,
414
                                           double zrot) override;
415

416
  // Convert `ref` to local coordinates and store the result in `local`
417
  virtual int convert_reference_to_local(Vector3d &local,
418
                                         const Vector3d &ref) override;
419
  // Convert `stage` to local coordinates and store the result in `local`
420
  virtual int convert_stage_to_local(Vector3d &local,
421
                                     const Vector3d &stage) override;
422
  // Convert `global` to local coordinates and store the result in `local`
423
  virtual int convert_global_to_local(Vector3d &local,
424
                                      const Vector3d &global) override;
425
  // Convert `local` to reference coordinates and store the result in `ref`
426
  virtual int convert_local_to_reference(Vector3d &ref,
427
                                         const Vector3d &local) override;
428
  // Convert `local` to stage coordinates and store the result in `stage`
429
  virtual int convert_local_to_stage(Vector3d &stage,
430
                                     const Vector3d &local) override;
431
  // Convert `local` to global coordinates and store the result in `global`
432
  virtual int convert_local_to_global(Vector3d &global,
433
                                      const Vector3d &local) override;
434

435
  // Convert global coordinates to reference coordinates
436
  virtual int convert_global_to_reference(Vector3d &ref,
437
                                          const Vector3d &global) override;
438
  // Convert reference coordinates to global
439
  virtual int convert_reference_to_global(Vector3d &global,
440
                                          const Vector3d &ref) override;
441

442
  // Convert `ref` to local coordinates and store the result in `local`
443
  virtual int convert_vector_reference_to_local(Vector3d &local,
444
                                                const Vector3d &ref) override;
445
  // Convert `stage` to local coordinates and store the result in `local`
446
  virtual int convert_vector_stage_to_local(Vector3d &local,
447
                                            const Vector3d &stage) override;
448
  // Convert `global` to local coordinates and store the result in `local`
449
  virtual int convert_vector_global_to_local(Vector3d &local,
450
                                             const Vector3d &global) override;
451
  // Convert `local` to reference coordinates and store the result in `ref`
452
  virtual int convert_vector_local_to_reference(Vector3d &ref,
453
                                                const Vector3d &local) override;
454
  // Convert `local` to stage coordinates and store the result in `stage`
455
  virtual int convert_vector_local_to_stage(Vector3d &stage,
456
                                            const Vector3d &local) override;
457
  // Convert `local` to global coordinates and store the result in `global`
458
  virtual int convert_vector_local_to_global(Vector3d &global,
459
                                             const Vector3d &local) override;
460

461
  // Convert global coordinates to reference coordinates
462
  virtual int convert_vector_global_to_reference(Vector3d &ref,
463
                                                 const Vector3d &global) override;
464
  // Convert reference coordinates to global
465
  virtual int convert_vector_reference_to_global(Vector3d &global,
466
                                                 const Vector3d &ref) override;
467

468
  // WARNING: The below Accessors should be used with care. They set
469
  // values that are set automatically -- these are here just in case...
470
  virtual void set_euler_angles(const Vector3d &ea) override
×
471
  {
472
    this->euler_angles = ea;
×
473
  }
×
474
  virtual void set_euler_angles(double alpha, double beta, double gamma) override
×
475
  {
476
    this->euler_angles.set_values(alpha, beta, gamma);
×
477
  }
×
478
  virtual void set_reference_to_local(const Matrix3d &rtol) override
×
479
  {
480
    this->reference_to_local = rtol;
×
481
  }
×
482
  virtual void set_local_to_reference(const Matrix3d &ltor) override
×
483
  {
484
    this->local_to_reference = ltor;
×
485
  }
×
486

487
  virtual void enforce_user_fields_set() const override;
488

489
protected:
490
  // TODO: Do these need to be mutable?
491
  mutable bool active;
492
  mutable bool virtual_flag;
493
  mutable element_id my_id;
494

495
  bool coordinates_initialized;
496

497
  int_fast64_t stage;
498
  std::string my_name;
499

500
  // Location of the origin in the reference coordinate system
501
  Vector3d origin;
502
  // Aim vector of element--aligns with the local (positive) z-axis
503
  Vector3d aim;
504
  // Rotation about the aim vector to set local x and y axes in degrees (ugh!)
505
  double zrot;
506

507
  Vector3d euler_angles;
508

509
  Matrix3d reference_to_local;
510
  Matrix3d local_to_reference;
511

512
  // element_ptr reference_element;
513
  Element *reference_element;
514

515
private:
516
  // static ElementContainer empty_container;
517
};
518

519
// using element_ptr = typename std::shared_ptr<Element>;
520
// using ElementContainer = std::map<element_id, element_ptr>;
521

522
template <typename C, typename... Args>
523
inline auto make_element(Args &&...args)
6✔
524
{
525
  return ElementContainer::make_pointer<C>(std::forward<Args>(args)...);
6✔
526
}
527

528
} // namespace SolTrace::Data
529

530
/**
531
 * @}
532
 */
533

534
#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