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

NREL / SolTrace / 19580451842

21 Nov 2025 06:52PM UTC coverage: 89.184% (+0.4%) from 88.811%
19580451842

push

github

web-flow
Merge pull request #85 from NREL/simdata_io_json

Add json import/export to SimulationData

423 of 451 new or added lines in 17 files covered. (93.79%)

9 existing lines in 3 files now uncovered.

5970 of 6694 relevant lines covered (89.18%)

7997777.28 hits per line

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

94.76
/coretrace/simulation_data/element.cpp
1

2
#include "element.hpp"
3

4
#include <math.h>
5

6
#include "constants.hpp"
7

8
namespace SolTrace::Data {
9

10
// ElementContainer ElementBase::empty_container;
11

12
ElementBase::ElementBase() : Element(),
20,122✔
13
                             coordinates_initialized(true),
20,122✔
14
                             active(true),
20,122✔
15
                             virtual_flag(false),
20,122✔
16
                             my_id(ELEMENT_ID_UNASSIGNED),
20,122✔
17
                             stage(-1),
20,122✔
18
                             zrot(0.0),
20,122✔
19
                             reference_element(nullptr)
20,122✔
20
{
21
    // Default local coordinates to match with the reference coordinates
22
    this->aim.set_values(0.0, 0.0, 1.0);
20,122✔
23
    this->origin.zero();
20,122✔
24

25
    this->euler_angles.zero();
20,122✔
26
    this->reference_to_local.identity();
20,122✔
27
    this->local_to_reference.identity();
20,122✔
28

29
    return;
20,122✔
30
}
×
31

32
ElementBase::ElementBase(const nlohmann::ordered_json& jnode) : ElementBase()
2,434✔
33
{
34
    if (jnode.at("active").get<bool>())
2,434✔
35
        this->enable();
2,434✔
36
    else
NEW
37
        this->disable();
×
38

39
    if (jnode.at("virtual_flag").get<bool>())
2,434✔
NEW
40
        this->mark_virtual();
×
41
    else
42
        this->unmark_virtual();
2,434✔
43

44
    //this->set_id(jnode["my_id"]);
45
    this->set_id(ELEMENT_ID_UNASSIGNED);
2,434✔
46
    this->set_stage(jnode.at("stage"));
2,434✔
47
    this->set_name(jnode.at("my_name"));
2,434✔
48

49
    std::array<double, 3> orig_arr = jnode.at("origin").get<std::array<double, 3>>();
2,434✔
50
    Vector3d orig_vec(orig_arr.data());
2,434✔
51
    this->set_origin(orig_vec);
2,434✔
52

53
    std::array<double, 3> aim_arr = jnode.at("aim").get<std::array<double, 3>>();
2,434✔
54
    Vector3d aim_vec(aim_arr.data());
2,434✔
55
    this->set_aim_vector(aim_vec);
2,434✔
56

57
    this->set_zrot(jnode.at("zrot"));
2,434✔
58

59
    this->coordinates_initialized = false;
2,434✔
60
    //this->compute_coordinate_rotations();
61
}
2,434✔
62

63
ElementBase::~ElementBase()
20,122✔
64
{
65
    this->reference_element = nullptr;
20,122✔
66
    return;
20,122✔
67
}
20,122✔
68

69
// ElementContainer::iterator ElementBase::get_iterator()
70
// {
71
//     return empty_container.get_iterator();
72
// }
73

74
// ElementContainer::const_iterator ElementBase::get_const_iterator()
75
// {
76
//     return empty_container.get_const_iterator();
77
// }
78

79
Vector3d ElementBase::get_origin_stage() const
14,708✔
80
{
81
    Vector3d origin_stage;
14,708✔
82
    auto ref_el = this->reference_element;
14,708✔
83
    if (this->is_stage())
14,708✔
84
    {
85
        // This is the stage element so the stage origin is zero.
86
        origin_stage.zero();
1✔
87
    }
88
    else if (ref_el == nullptr)
14,707✔
89
    {
90
        // We hit the end of the chain without finding a stage element.
91
        // Assume we are not using stages and return the global origin.
92
        origin_stage = this->origin;
7✔
93
    }
94
    else
95
    {
96
        ref_el->convert_local_to_stage(origin_stage, this->origin);
14,700✔
97
    }
98
    return origin_stage;
14,708✔
99
}
×
100

101
Vector3d ElementBase::get_origin_global() const
317✔
102
{
103
    Vector3d origin_global;
317✔
104
    auto ref_el = this->reference_element;
317✔
105
    if (ref_el == nullptr)
317✔
106
    {
107
        origin_global = this->origin;
41✔
108
    }
109
    else
110
    {
111
        ref_el->convert_local_to_global(origin_global, this->origin);
276✔
112
    }
113
    return origin_global;
317✔
114
}
×
115

116
Vector3d ElementBase::get_aim_vector_stage() const
14,708✔
117
{
118
    Vector3d aim_stage;
14,708✔
119
    if (this->reference_element == nullptr)
14,708✔
120
    {
121
        aim_stage = this->aim;
8✔
122
    }
123
    else
124
    {
125
        this->reference_element->convert_local_to_stage(
14,700✔
126
            aim_stage, this->aim);
14,700✔
127
    }
128
    return aim_stage;
14,708✔
129
}
×
130

131
Vector3d ElementBase::get_aim_vector_global() const
45✔
132
{
133
    Vector3d aim_global;
45✔
134
    if (this->reference_element == nullptr)
45✔
135
    {
136
        aim_global = this->aim;
37✔
137
    }
138
    else
139
    {
140
        this->reference_element->convert_local_to_global(
8✔
141
            aim_global, this->aim);
8✔
142
    }
143
    return aim_global;
45✔
144
}
×
145

146
Matrix3d ElementBase::get_reference_to_local() const
1✔
147
{
148
    return this->reference_to_local;
1✔
149
}
150

151
Matrix3d ElementBase::get_stage_to_local() const
31,333✔
152
{
153
    Matrix3d stage_to_local;
31,333✔
154
    if (this->is_stage())
31,333✔
155
    {
156
        // stage_to_local.set_value(0, 0, 1.0);
157
        // stage_to_local.set_value(1, 1, 1.0);
158
        // stage_to_local.set_value(2, 2, 1.0);
159
        stage_to_local.identity();
14,623✔
160
    }
161
    else if (this->reference_element == nullptr)
16,710✔
162
    {
163
        stage_to_local = this->reference_to_local;
81✔
164
    }
165
    else
166
    {
167
        Matrix3d R = this->reference_element->get_stage_to_local();
16,629✔
168
        matrix_matrix_product(this->reference_to_local, R, stage_to_local);
16,629✔
169
    }
16,629✔
170
    return stage_to_local;
31,333✔
171
}
×
172

173
Matrix3d ElementBase::get_global_to_local() const
35✔
174
{
175
    Matrix3d global_to_local;
35✔
176
    if (this->reference_element == nullptr)
35✔
177
    {
178
        global_to_local = this->reference_to_local;
34✔
179
    }
180
    else
181
    {
182
        Matrix3d R = this->reference_element->get_global_to_local();
1✔
183
        matrix_matrix_product(this->reference_to_local, R, global_to_local);
1✔
184
    }
1✔
185
    return global_to_local;
35✔
186
}
×
187

188
Matrix3d ElementBase::get_local_to_reference() const
1✔
189
{
190
    return this->local_to_reference;
1✔
191
}
192

193
Matrix3d ElementBase::get_local_to_stage() const
31,333✔
194
{
195
    Matrix3d local_to_stage;
31,333✔
196
    if (this->is_stage())
31,333✔
197
    {
198
        local_to_stage.set_value(0, 0, 1.0);
14,623✔
199
        local_to_stage.set_value(1, 1, 1.0);
14,623✔
200
        local_to_stage.set_value(2, 2, 1.0);
14,623✔
201
    }
202
    else if (this->reference_element == nullptr)
16,710✔
203
    {
204
        local_to_stage = this->local_to_reference;
81✔
205
    }
206
    else
207
    {
208
        Matrix3d R = this->reference_element->get_local_to_stage();
16,629✔
209
        matrix_matrix_product(R, this->local_to_reference, local_to_stage);
16,629✔
210
    }
16,629✔
211
    return local_to_stage;
31,333✔
212
}
×
213

214
Matrix3d ElementBase::get_local_to_global() const
35✔
215
{
216
    Matrix3d local_to_global;
35✔
217
    if (this->reference_element == nullptr)
35✔
218
    {
219
        local_to_global = this->local_to_reference;
34✔
220
    }
221
    else
222
    {
223
        Matrix3d R = this->reference_element->get_local_to_global();
1✔
224
        matrix_matrix_product(R, this->local_to_reference, local_to_global);
1✔
225
    }
1✔
226
    return local_to_global;
35✔
227
}
×
228

229
int ElementBase::compute_coordinate_rotations()
37,424✔
230
{
231
    int sts = 0;
37,424✔
232

233
    if (!this->coordinates_initialized)
37,424✔
234
    {
235
        Vector3d dr;
20,041✔
236
        vector_add(1.0, this->aim, -1.0, this->origin, dr);
20,041✔
237
        make_unit_vector(dr);
20,041✔
238

239
        this->euler_angles[0] = atan2(dr[0], dr[2]);
20,041✔
240
        this->euler_angles[1] = asin(dr[1]);
20,041✔
241
        this->euler_angles[2] = this->zrot * D2R;
20,041✔
242

243
        compute_transform_matrices(this->euler_angles,
20,041✔
244
                                   this->reference_to_local,
20,041✔
245
                                   this->local_to_reference);
20,041✔
246

247
        this->coordinates_initialized = true;
20,041✔
248
    }
20,041✔
249

250
    return sts;
37,424✔
251
}
252

253
int ElementBase::set_reference_frame_geometry(const Vector3d &origin,
17,264✔
254
                                              const Vector3d &aim,
255
                                              double zrot)
256
{
257
    this->coordinates_initialized = false;
17,264✔
258
    this->origin = origin;
17,264✔
259
    this->aim = aim;
17,264✔
260
    this->zrot = zrot;
17,264✔
261
    return this->compute_coordinate_rotations();
17,264✔
262
}
263

264
int ElementBase::convert_reference_to_local(Vector3d &local,
107,057✔
265
                                            const Vector3d &ref)
266
{
267
    Vector3d temp;
107,057✔
268
    vector_add(1.0, ref, -1.0, this->origin, temp);
107,057✔
269
    matrix_vector_product(this->reference_to_local, temp, local);
107,057✔
270
    return 0;
107,057✔
271
}
107,057✔
272

273
int ElementBase::convert_stage_to_local(Vector3d &local,
6✔
274
                                        const Vector3d &stage)
275
{
276
    if (this->is_stage())
6✔
277
    {
278
        // We are in the stage coordinate frame so the local coordinates
279
        // are the stage coordinates
280
        local = stage;
3✔
281
    }
282
    else if (this->reference_element == nullptr)
3✔
283
    {
284
        // No stage frame found so assume we are not using stages
285
        // and return the same answer as convert_global_to_local
286
        this->convert_reference_to_local(local, stage);
×
287
    }
288
    else
289
    {
290
        Vector3d ref;
3✔
291
        this->reference_element->convert_stage_to_local(ref, stage);
3✔
292
        convert_reference_to_local(local, ref);
3✔
293
    }
3✔
294
    return 0;
6✔
295
}
296

297
int ElementBase::convert_global_to_local(Vector3d &local,
107,054✔
298
                                         const Vector3d &global)
299
{
300
    auto ref_el = this->reference_element;
107,054✔
301
    if (ref_el == nullptr)
107,054✔
302
    {
303
        // We are at the global coordinate frame
304
        this->convert_reference_to_local(local, global);
107,051✔
305
    }
306
    else
307
    {
308
        Vector3d ref;
3✔
309
        ref_el->convert_global_to_local(ref, global);
3✔
310
        this->convert_reference_to_local(local, ref);
3✔
311
    }
3✔
312
    return 0;
107,054✔
313
}
314

315
int ElementBase::convert_local_to_reference(Vector3d &ref,
4,315✔
316
                                            const Vector3d &local)
317
{
318
    Vector3d temp;
4,315✔
319
    matrix_vector_product(this->local_to_reference, local, temp);
4,315✔
320
    vector_add(1.0, temp, 1.0, this->origin, ref);
4,315✔
321
    return 0;
4,315✔
322
}
4,315✔
323

324
int ElementBase::convert_local_to_stage(Vector3d &stage,
33,274✔
325
                                        const Vector3d &local)
326
{
327
    if (this->is_stage())
33,274✔
328
    {
329
        // We are in the stage coordinate frame so the local coordinates
330
        // are the stage coordinates
331
        stage = local;
29,257✔
332
    }
333
    else if (this->reference_element == nullptr)
4,017✔
334
    {
335
        // No stage has been found so assume we are not using stages
336
        // and convert to global coordinates
337
        this->convert_local_to_reference(stage, local);
149✔
338
        // TODO: This should probably return something other than 0...
339
    }
340
    else
341
    {
342
        Vector3d ref;
3,868✔
343
        this->convert_local_to_reference(ref, local);
3,868✔
344
        this->reference_element->convert_local_to_stage(stage, ref);
3,868✔
345
    }
3,868✔
346
    return 0;
33,274✔
347
}
348

349
int ElementBase::convert_local_to_global(Vector3d &global,
295✔
350
                                         const Vector3d &local)
351
{
352
    auto ref_el = this->reference_element;
295✔
353
    if (ref_el == nullptr)
295✔
354
    {
355
        this->convert_local_to_reference(global, local);
291✔
356
    }
357
    else
358
    {
359
        Vector3d ref;
4✔
360
        this->convert_local_to_reference(ref, local);
4✔
361
        ref_el->convert_local_to_global(global, ref);
4✔
362
    }
4✔
363
    return 0;
295✔
364
}
365

366
int ElementBase::convert_global_to_reference(Vector3d &ref,
107,065✔
367
                                             const Vector3d &global)
368
{
369
    if (this->reference_element == nullptr)
107,065✔
370
    {
371
        ref = global;
17✔
372
        return 0;
17✔
373
    }
374
    else
375
    {
376
        return this->reference_element->convert_global_to_local(ref, global);
107,048✔
377
    }
378
}
379

380
int ElementBase::convert_reference_to_global(Vector3d &global,
2✔
381
                                             const Vector3d &ref)
382
{
383
    if (this->reference_element == nullptr)
2✔
384
    {
385
        global = ref;
1✔
386
        return 0;
1✔
387
    }
388
    else
389
    {
390
        return this->reference_element->convert_local_to_global(global, ref);
1✔
391
    }
392
}
393

394
int ElementBase::convert_vector_reference_to_local(Vector3d &local,
106,817✔
395
                                                   const Vector3d &ref)
396
{
397
    matrix_vector_product(this->reference_to_local, ref, local);
106,817✔
398
    return 0;
106,817✔
399
}
400

401
int ElementBase::convert_vector_stage_to_local(Vector3d &local,
2✔
402
                                               const Vector3d &stage)
403
{
404
    if (this->is_stage())
2✔
405
    {
406
        // We are in the stage coordinate frame so the local coordinates
407
        // are the stage coordinates
408
        local = stage;
1✔
409
    }
410
    else if (this->reference_element == nullptr)
1✔
411
    {
412
        // No stage frame found so assume we are not using stages
413
        // and return the same answer as convert_global_to_local
414
        this->convert_vector_reference_to_local(local, stage);
×
415
    }
416
    else
417
    {
418
        Vector3d ref;
1✔
419
        this->reference_element->convert_vector_stage_to_local(ref, stage);
1✔
420
        convert_vector_reference_to_local(local, ref);
1✔
421
    }
1✔
422
    return 0;
2✔
423
}
424

425
int ElementBase::convert_vector_global_to_local(Vector3d &local,
106,816✔
426
                                                const Vector3d &global)
427
{
428
    auto ref_el = this->reference_element;
106,816✔
429
    if (ref_el == nullptr)
106,816✔
430
    {
431
        // We are at the global coordinate frame
432
        this->convert_vector_reference_to_local(local, global);
106,815✔
433
    }
434
    else
435
    {
436
        Vector3d ref;
1✔
437
        ref_el->convert_vector_global_to_local(ref, global);
1✔
438
        this->convert_vector_reference_to_local(local, ref);
1✔
439
    }
1✔
440
    return 0;
106,816✔
441
}
442

443
int ElementBase::convert_vector_local_to_reference(Vector3d &ref,
4✔
444
                                                   const Vector3d &local)
445
{
446
    matrix_vector_product(this->local_to_reference, local, ref);
4✔
447
    return 0;
4✔
448
}
449

450
int ElementBase::convert_vector_local_to_stage(Vector3d &stage,
2✔
451
                                               const Vector3d &local)
452
{
453
    if (this->is_stage())
2✔
454
    {
455
        // We are in the stage coordinate frame so the local coordinates
456
        // are the stage coordinates
457
        stage = local;
1✔
458
    }
459
    else if (this->reference_element == nullptr)
1✔
460
    {
461
        // No stage has been found so assume we are not using stages
462
        // and convert to global coordinates
463
        this->convert_vector_local_to_reference(stage, local);
×
464
        // TODO: This should probably return something other than 0...
465
    }
466
    else
467
    {
468
        Vector3d ref;
1✔
469
        this->convert_vector_local_to_reference(ref, local);
1✔
470
        this->reference_element->convert_vector_local_to_stage(stage, ref);
1✔
471
    }
1✔
472
    return 0;
2✔
473
}
474

475
int ElementBase::convert_vector_local_to_global(Vector3d &global,
3✔
476
                                                const Vector3d &local)
477
{
478
    auto ref_el = this->reference_element;
3✔
479
    if (ref_el == nullptr)
3✔
480
    {
481
        this->convert_vector_local_to_reference(global, local);
2✔
482
    }
483
    else
484
    {
485
        Vector3d ref;
1✔
486
        this->convert_vector_local_to_reference(ref, local);
1✔
487
        ref_el->convert_vector_local_to_global(global, ref);
1✔
488
    }
1✔
489
    return 0;
3✔
490
}
491

492
int ElementBase::convert_vector_global_to_reference(Vector3d &ref,
106,809✔
493
                                                    const Vector3d &global)
494
{
495
    if (this->reference_element == nullptr)
106,809✔
496
    {
497
        ref = global;
1✔
498
        return 0;
1✔
499
    }
500
    else
501
    {
502
        return this->reference_element->convert_vector_global_to_local(
106,808✔
503
            ref, global);
106,808✔
504
    }
505
}
506

507
int ElementBase::convert_vector_reference_to_global(Vector3d &global,
2✔
508
                                                    const Vector3d &ref)
509
{
510
    if (this->reference_element == nullptr)
2✔
511
    {
512
        global = ref;
1✔
513
        return 0;
1✔
514
    }
515
    else
516
    {
517
        return this->reference_element->convert_vector_local_to_global(
1✔
518
            global, ref);
1✔
519
    }
520
}
521

522
// const OpticalProperties & ElementBase::get_optical_properties() const
523
// {
524
//     return this->optics;
525
// }
526

527
// void ElementBase::set_optical_properties(const OpticalProperties &op)
528
// {
529
//     this->optics = op;
530
// }
531

532
void ElementBase::enforce_user_fields_set() const
39,812✔
533
{
534
    return;
39,812✔
535
}
536

537
void ElementBase::write_common_json(nlohmann::ordered_json& jnode) const
2,463✔
538
{
539
    jnode["active"] = this->active;
2,463✔
540
    jnode["virtual_flag"] = this->virtual_flag;
2,463✔
541
    jnode["my_id"] = this->my_id;
2,463✔
542
    jnode["stage"] = this->stage;
2,463✔
543
    jnode["my_name"] = this->my_name;
2,463✔
544

545
    jnode["origin"] = this->origin.data;
2,463✔
546
    jnode["aim"] = this->aim.data;
2,463✔
547
    jnode["zrot"] = this->zrot;
2,463✔
548
    
549
    // Not including calculated values
550
    //jnode["euler_angles"] = this->euler_angles.data;
551
}
2,463✔
552

553
} // namespace SolTrace::Data
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