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

NREL / SolTrace / 20967660491

13 Jan 2026 06:16PM UTC coverage: 87.346% (-0.5%) from 87.815%
20967660491

Pull #96

github

web-flow
Merge 944e17991 into e78d2bfb0
Pull Request #96: 95 implement embree runner

514 of 733 new or added lines in 14 files covered. (70.12%)

13 existing lines in 6 files now uncovered.

6178 of 7073 relevant lines covered (87.35%)

7222269.32 hits per line

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

65.49
/coretrace/simulation_data/surface.cpp
1

2
#include "surface.hpp"
3
#include "simdata_io.hpp"
4

5
#include <vector>
6

7
#include <utilities.hpp>
8

9
namespace SolTrace::Data
10
{
11

12
    surface_ptr make_surface_from_type(SurfaceType type, const std::vector<double> &args)
21,321✔
13
    {
14
        surface_ptr retval = nullptr;
21,321✔
15
        unsigned nargs = args.size();
21,321✔
16

17
        switch (type)
21,321✔
18
        {
19
        case SurfaceType::CONE:
3✔
20
            retval = nargs < 1 ? nullptr : make_surface<Cone>(args[0]);
3✔
21
            break;
3✔
22
        case SurfaceType::CYLINDER:
7✔
23
            retval = nargs < 1 ? nullptr : make_surface<Cylinder>(1.0 / args[0]);
7✔
24
            break;
7✔
25
        case SurfaceType::FLAT:
7✔
26
            retval = make_surface<Flat>();
7✔
27
            break;
7✔
28
        case SurfaceType::PARABOLA:
21,221✔
29
        {
30
            if (nargs < 2)
21,221✔
31
                retval = nullptr;
2✔
32
            else
33
            {
34
                double cx = args[0];
21,219✔
35
                double cy = args[1];
21,219✔
36
                double fx = 1.0 / (2.0 * cx);
21,219✔
37
                double fy = 1.0 / (2.0 * cy);
21,219✔
38
                retval = make_surface<Parabola>(fx, fy);
21,219✔
39
            }
40
            break;
21,221✔
41
        }
42
        case SurfaceType::SPHERE:
79✔
43
            retval = nargs < 1 ? nullptr : make_surface<Sphere>(args[0]);
79✔
44
            break;
79✔
45
        case SurfaceType::HYPER:
4✔
46
        case SurfaceType::GENERAL_SPENCER_MURTY:
47
        case SurfaceType::TORUS:
48
        default:
49
            retval = nullptr; // Not implemented yet
4✔
50
            break;
4✔
51
        }
52

53
        return retval;
21,321✔
NEW
54
    }
×
55

56
    surface_ptr make_surface_from_json(const nlohmann::ordered_json &jnode)
2,437✔
57
    {
58
        if (!jnode.contains("surface_type"))
2,437✔
59
            throw std::invalid_argument("Missing surface_type");
1✔
60
        std::string type_str = jnode.at("surface_type");
2,436✔
61
        SurfaceType surface_type = get_enum_from_string(type_str, SurfaceTypeMap, SurfaceType::SURFACE_UNKNOWN);
2,436✔
62
        if (surface_type == SurfaceType::SURFACE_UNKNOWN)
2,436✔
63
            throw std::invalid_argument("Unknown surface");
1✔
64
        switch (surface_type)
2,435✔
65
        {
66
        case SurfaceType::CONE:
2✔
67
            return make_surface<Cone>(jnode);
2✔
68
        case SurfaceType::CYLINDER:
3✔
69
            return make_surface<Cylinder>(jnode);
3✔
70
        case SurfaceType::FLAT:
6✔
71
            return make_surface<Flat>(jnode);
6✔
72
        case SurfaceType::PARABOLA:
2,372✔
73
            return make_surface<Parabola>(jnode);
2,372✔
74
        case SurfaceType::SPHERE:
52✔
75
            return make_surface<Sphere>(jnode);
52✔
76
        default:
×
77
            throw std::invalid_argument("Unsupported surface_type: " + type_str);
×
78
        }
79
    }
2,436✔
80

81
    Cone::Cone(const nlohmann::ordered_json &jnode)
2✔
82
        : Surface(SurfaceType::CONE)
2✔
83
    {
84
        this->half_angle = jnode.at("half_angle");
2✔
85
    }
2✔
86

NEW
87
    void Cone::bounding_box(const double x_minmax[2],
×
88
                            const double y_minmax[2],
89
                            double &z_min,
90
                            double &z_max) const
91
    {
NEW
92
        double theta = this->half_angle * D2R;
×
NEW
93
        double x_abs_max = abs_max(x_minmax, 2);
×
NEW
94
        double y_abs_max = abs_max(y_minmax, 2);
×
NEW
95
        z_min = 0.0;
×
NEW
96
        z_max = sqrt(x_abs_max * x_abs_max + y_abs_max * y_abs_max) / tan(theta);
×
NEW
97
        return;
×
98
    }
99

NEW
100
    surface_ptr Cone::make_copy() const
×
101
    {
NEW
102
        return make_surface<Cone>(*this);
×
103
    }
104

NEW
105
    void Cone::write_json(nlohmann::ordered_json &jnode) const
×
106
    {
NEW
107
        SurfaceType type = SurfaceType::CONE;
×
NEW
108
        jnode["surface_type"] = SurfaceTypeMap.at(type);
×
NEW
109
        jnode["half_angle"] = this->half_angle;
×
NEW
110
    }
×
111

112
    Cylinder::Cylinder(const nlohmann::ordered_json &jnode)
3✔
113
        : Surface(SurfaceType::CYLINDER)
3✔
114
    {
115
        this->radius = jnode.at("radius");
3✔
116
    }
3✔
117

NEW
118
    void Cylinder::bounding_box(const double x_minmax[2],
×
119
                                const double y_minmax[2],
120
                                double &z_min,
121
                                double &z_max) const
122
    {
NEW
123
        double r = this->radius;
×
NEW
124
        assert(is_approx(x_minmax[0], -r, 1e-6));
×
NEW
125
        assert(is_approx(x_minmax[1], r, 1e-6));
×
NEW
126
        z_min = 0.0;
×
NEW
127
        z_max = 2.0 * r;
×
NEW
128
        return;
×
129
    }
130

131
    surface_ptr Cylinder::make_copy() const
15✔
132
    {
133
        return make_surface<Cylinder>(*this);
15✔
134
    }
135

136
    void Cylinder::write_json(nlohmann::ordered_json &jnode) const
1✔
137
    {
138
        SurfaceType type = SurfaceType::CYLINDER;
1✔
139
        jnode["surface_type"] = SurfaceTypeMap.at(type);
1✔
140
        jnode["radius"] = this->radius;
1✔
141
    }
1✔
142

NEW
143
    void Flat::bounding_box(const double x_minmax[2],
×
144
                            const double y_minmax[2],
145
                            double &z_min,
146
                            double &z_max) const
147
    {
NEW
148
        z_min = -1e-4;
×
NEW
149
        z_max = 1e-4;
×
NEW
150
        return;
×
151
    }
152

153
    surface_ptr Flat::make_copy() const
77✔
154
    {
155
        return make_surface<Flat>(*this);
77✔
156
    }
157

158
    void Flat::write_json(nlohmann::ordered_json &jnode) const
6✔
159
    {
160
        SurfaceType type = SurfaceType::FLAT;
6✔
161
        jnode["surface_type"] = SurfaceTypeMap.at(type);
6✔
162
    }
6✔
163

164
    Parabola::Parabola(const nlohmann::ordered_json &jnode)
2,372✔
165
        : Surface(SurfaceType::PARABOLA)
2,372✔
166
    {
167
        this->focal_length_x = jnode.at("focal_length_x");
2,372✔
168
        this->focal_length_y = jnode.at("focal_length_y");
2,372✔
169
    }
2,372✔
170

NEW
171
    void Parabola::bounding_box(const double x_minmax[2],
×
172
                                const double y_minmax[2],
173
                                double &z_min,
174
                                double &z_max) const
175
    {
NEW
176
        double cx = 0.5 / this->focal_length_x;
×
NEW
177
        double cy = 0.5 / this->focal_length_y;
×
NEW
178
        double x_max = abs_max(x_minmax, 2);
×
NEW
179
        double y_max = abs_max(y_minmax, 2);
×
180

NEW
181
        z_min = 0.0;
×
NEW
182
        z_max = 0.5 * (cx * x_max * x_max + cy * y_max * y_max);
×
183

NEW
184
        return;
×
185
    }
186

187
    surface_ptr Parabola::make_copy() const
18,896✔
188
    {
189
        return make_surface<Parabola>(*this);
18,896✔
190
    }
191

192
    void Parabola::write_json(nlohmann::ordered_json &jnode) const
2,370✔
193
    {
194
        SurfaceType type = SurfaceType::PARABOLA;
2,370✔
195
        jnode["surface_type"] = SurfaceTypeMap.at(type);
2,370✔
196
        jnode["focal_length_x"] = this->focal_length_x;
2,370✔
197
        jnode["focal_length_y"] = this->focal_length_y;
2,370✔
198
    }
2,370✔
199

200
    Sphere::Sphere(const nlohmann::ordered_json &jnode)
52✔
201
        : Surface(SurfaceType::SPHERE)
52✔
202
    {
203
        this->vertex_curv = jnode.at("vertex_curv");
52✔
204
    }
52✔
205

NEW
206
    void Sphere::bounding_box(const double x_minmax[2],
×
207
                              const double y_minmax[2],
208
                              double &z_min,
209
                              double &z_max) const
210
    {
NEW
211
        z_min = 0.0;
×
NEW
212
        z_max = 1.0 / this->vertex_curv;
×
NEW
213
        return;
×
214
    }
215

216
    surface_ptr Sphere::make_copy() const
77✔
217
    {
218
        return make_surface<Sphere>(*this);
77✔
219
    }
220

221
    void Sphere::write_json(nlohmann::ordered_json &jnode) const
75✔
222
    {
223
        SurfaceType type = SurfaceType::SPHERE;
75✔
224
        jnode["surface_type"] = SurfaceTypeMap.at(type);
75✔
225
        jnode["vertex_curv"] = this->vertex_curv;
75✔
226
    }
75✔
227

NEW
228
    double Cone::z(double x, double y) const
×
229
    {
NEW
230
        return sqrt(x * x + y * y) / tan(half_angle);
×
231
    }
232

NEW
233
    double Cylinder::z(double x, double) const
×
234
    {
235
        // TODO: Fix ? This is really only the top half of the cylinder
236
        //       Clyinder breaks the model since it is a mulit-valued fuction: each
237
        //       x values produces two z values Returning only the positive root
NEW
238
        return radius + sqrt(x * x + radius * radius);
×
239
    }
240

NEW
241
    double Parabola::z(double x, double y) const
×
242
    {
243
        // z(x,y) = (cx * x^2 + cy * y^2) / 2
NEW
244
        return x * x / focal_length_x + y * y / focal_length_y;
×
245
    }
246

NEW
247
    double Sphere::z(double x, double y) const
×
248
    {
NEW
249
        return vertex_curv * (x * x + y * y) /
×
NEW
250
               (1 + sqrt(1 - vertex_curv * vertex_curv * (x * x + y * y)));
×
251
    }
252

253
} // 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