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

NREL / SolTrace / 21043968530

15 Jan 2026 07:39PM UTC coverage: 87.999% (+0.2%) from 87.815%
21043968530

Pull #96

github

web-flow
Merge 9b5253116 into e78d2bfb0
Pull Request #96: 95 implement embree runner

600 of 792 new or added lines in 17 files covered. (75.76%)

14 existing lines in 7 files now uncovered.

6255 of 7108 relevant lines covered (88.0%)

7221404.69 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 · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc