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

NREL / SolTrace / 21006557699

14 Jan 2026 07:09PM UTC coverage: 88.001% (+0.2%) from 87.815%
21006557699

Pull #96

github

web-flow
Merge 2d2b811d6 into e78d2bfb0
Pull Request #96: 95 implement embree runner

569 of 752 new or added lines in 16 files covered. (75.66%)

13 existing lines in 6 files now uncovered.

6241 of 7092 relevant lines covered (88.0%)

7203590.97 hits per line

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

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

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

100
    surface_ptr Cone::make_copy() const
1 ✔
101
    {
102
        return make_surface<Cone>(*this);
1 ✔
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

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

131
    surface_ptr Cylinder::make_copy() const
17 ✔
132
    {
133
        return make_surface<Cylinder>(*this);
17 ✔
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

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

153
    surface_ptr Flat::make_copy() const
79 ✔
154
    {
155
        return make_surface<Flat>(*this);
79 ✔
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

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

182
        if (x_minmax[0] <= 0.0 && 0.0 <= x_minmax[1] &&
4 ✔
183
            y_minmax[0] <= 0.0 && 0.0 <= y_minmax[1])
3 ✔
184
        {
185
            z_min = 0.0;
3 ✔
186
        }
187
        else
188
        {
189
            double x_min = abs_min(x_minmax, 2);
1 ✔
190
            double y_min = abs_min(y_minmax, 2);
1 ✔
191
            z_min = 0.5 * (cx * x_min * x_min + cy * y_min * y_min);
1 ✔
192
        }
193

194
        return;
4 ✔
195
    }
196

197
    surface_ptr Parabola::make_copy() const
18,897 ✔
198
    {
199
        return make_surface<Parabola>(*this);
18,897 ✔
200
    }
201

202
    void Parabola::write_json(nlohmann::ordered_json &jnode) const
2,370 ✔
203
    {
204
        SurfaceType type = SurfaceType::PARABOLA;
2,370 ✔
205
        jnode["surface_type"] = SurfaceTypeMap.at(type);
2,370 ✔
206
        jnode["focal_length_x"] = this->focal_length_x;
2,370 ✔
207
        jnode["focal_length_y"] = this->focal_length_y;
2,370 ✔
208
    }
2,370 ✔
209

210
    Sphere::Sphere(const nlohmann::ordered_json &jnode)
52 ✔
211
        : Surface(SurfaceType::SPHERE)
52 ✔
212
    {
213
        this->vertex_curv = jnode.at("vertex_curv");
52 ✔
214
    }
52 ✔
215

216
    void Sphere::bounding_box(const double x_minmax[2],
4 ✔
217
                              const double y_minmax[2],
218
                              double &z_min,
219
                              double &z_max) const
220
    {
221
        z_min = 0.0;
4 ✔
222
        double R = 1.0 / this->vertex_curv;
4 ✔
223
        double x_max = abs_max(x_minmax, 2);
4 ✔
224
        double y_max = abs_max(y_minmax, 2);
4 ✔
225
        double rsq = x_max * x_max + y_max * y_max;
4 ✔
226
        z_max = R > sqrt(rsq) ? R - sqrt(R * R - rsq) : R;
4 ✔
227
        return;
4 ✔
228
    }
229

230
    surface_ptr Sphere::make_copy() const
78 ✔
231
    {
232
        return make_surface<Sphere>(*this);
78 ✔
233
    }
234

235
    void Sphere::write_json(nlohmann::ordered_json &jnode) const
75 ✔
236
    {
237
        SurfaceType type = SurfaceType::SPHERE;
75 ✔
238
        jnode["surface_type"] = SurfaceTypeMap.at(type);
75 ✔
239
        jnode["vertex_curv"] = this->vertex_curv;
75 ✔
240
    }
75 ✔
241

242
    double Cone::z(double x, double y) const
2 ✔
243
    {
244
        return sqrt(x * x + y * y) / tan(half_angle);
2 ✔
245
    }
246

247
    double Cylinder::z(double x, double) const
2 ✔
248
    {
249
        // TODO: Fix ? This is really only the top half of the cylinder
250
        //       Clyinder breaks the model since it is a mulit-valued fuction: each
251
        //       x values produces two z values Returning only the positive root
252
        return radius + sqrt(x * x + radius * radius);
2 ✔
253
    }
254

255
    double Parabola::z(double x, double y) const
2 ✔
256
    {
257
        // z(x,y) = (cx * x^2 + cy * y^2) / 2
258
        return x * x / focal_length_x + y * y / focal_length_y;
2 ✔
259
    }
260

261
    double Sphere::z(double x, double y) const
2 ✔
262
    {
263
        return vertex_curv * (x * x + y * y) /
2 ✔
264
               (1 + sqrt(1 - vertex_curv * vertex_curv * (x * x + y * y)));
2 ✔
265
    }
266

267
} // namespace SolTrace::Data
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc