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

NREL / SolTrace / 21046664913

15 Jan 2026 09:17PM UTC coverage: 87.999% (+0.2%) from 87.815%
21046664913

Pull #96

github

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

605 of 797 new or added lines in 17 files covered. (75.91%)

14 existing lines in 7 files now uncovered.

6255 of 7108 relevant lines covered (88.0%)

7221404.67 hits per line

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

91.3
/coretrace/simulation_data/surface.hpp
1
/**
2
 * @file surface.hpp
3
 * @brief Optical surface geometry definitions
4
 *
5
 * Defines various optical surface types (flat, parabolic, spherical, etc.)
6
 * and their mathematical representations for ray-surface intersection
7
 * calculations. Provides the foundation for ray tracing on different
8
 * geometric surface types used in concentrated solar power systems.
9
 *
10
 * @defgroup surfaces Optical Surfaces
11
 * @{
12
 */
13

14
#ifndef SOLTRACE_SURFACE_H
15
#define SOLTRACE_SURFACE_H
16

17
#include <memory>
18
#include <vector>
19
#include <nlohmann/json.hpp>
20

21
namespace SolTrace::Data
22
{
23

24
    enum SurfaceType
25
    {
26
        CONE,
27
        CYLINDER,
28
        FLAT,
29
        PARABOLA,
30
        SPHERE,
31

32
        HYPER,
33
        GENERAL_SPENCER_MURTY,
34
        TORUS,
35

36
        SURFACE_UNKNOWN
37
    };
38

39
    inline const std::map<SurfaceType, std::string> SurfaceTypeMap =
40
        {
41
            {SurfaceType::CONE, "CONE"},
42
            {SurfaceType::CYLINDER, "CYLINDER"},
43
            {SurfaceType::FLAT, "FLAT"},
44
            {SurfaceType::PARABOLA, "PARABOLA"},
45
            {SurfaceType::SPHERE, "SPHERE"},
46
            {SurfaceType::HYPER, "HYPER"},
47
            {SurfaceType::GENERAL_SPENCER_MURTY, "GENERAL_SPENCER_MURTY"},
48
            {SurfaceType::TORUS, "TORUS"},
49
            {SurfaceType::SURFACE_UNKNOWN, "SURFACE_UNKNOWN"}};
50

51
    struct Surface;
52
    using surface_ptr = std::shared_ptr<Surface>;
53

54
    template <typename S, typename... Args>
55
    inline auto make_surface(Args &&...args)
42,992✔
56
    {
57
        return std::make_shared<S>(std::forward<Args>(args)...);
42,992✔
58
    }
59

60
    struct Surface
61
    {
62
    public:
63
        SurfaceType my_type;
64

65
        Surface(SurfaceType st) : my_type(st) {}
6,310✔
66
        virtual ~Surface() {}
11,554✔
67

68
        SurfaceType get_type() { return my_type; }
19,020✔
69

70
        virtual void bounding_box(const double x_minmax[2],
71
                                  const double y_minmax[2],
72
                                  double &z_min,
73
                                  double &z_max) const = 0;
74

75
        virtual surface_ptr make_copy() const = 0;
76

77
        virtual void write_json(nlohmann::ordered_json &jnode) const = 0;
78

NEW
79
        virtual double z(double x, double y) const { return 0; }
×
80

81
        inline std::string get_type_string() const
82
        {
83
            switch (my_type)
84
            {
85
            case CONE:
86
                return "Cone";
87
            case CYLINDER:
88
                return "Cylinder";
89
            case FLAT:
90
                return "Flat";
91
            case PARABOLA:
92
                return "Parabola";
93
            case SPHERE:
94
                return "Sphere";
95
            case HYPER:
96
                return "Hyper";
97
            case GENERAL_SPENCER_MURTY:
98
                return "General Spencer Murty";
99
            case TORUS:
100
                return "Torus";
101
            case SURFACE_UNKNOWN:
102
                return "Unknown";
103
            }
104
            return "Unknown";
105
        }
106
    };
107

108
    struct Cone : public Surface
109
    {
110
        // z(x,y) = sqrt(x^2 + y^2) / tan(theta)
111
        // where theta = half_angle
112
        double half_angle;
NEW
113
        Cone(double ha) : Surface(SurfaceType::CONE), half_angle(ha) {}
×
114
        Cone(const nlohmann::ordered_json &jnode);
115
        virtual ~Cone() {}
10✔
116
        virtual void bounding_box(const double x_minmax[2],
117
                                  const double y_minmax[2],
118
                                  double &z_min,
119
                                  double &z_max) const override;
120
        virtual surface_ptr make_copy() const override;
121
        virtual void write_json(nlohmann::ordered_json &jnode) const override;
122

123
        virtual double z(double x, double y) const override;
124
    };
125

126
    struct Cylinder : public Surface
127
    {
128
        // x^2 + (z - r)^2 = r^2
129
        // where r = radius
130
        double radius;
131
        Cylinder(double r) : Surface(SurfaceType::CYLINDER), radius(r)
43✔
132
        {
133
        }
43✔
134
        Cylinder(const nlohmann::ordered_json &jnode);
135
        virtual ~Cylinder() {}
73✔
136
        virtual void bounding_box(const double x_minmax[2],
137
                                  const double y_minmax[2],
138
                                  double &z_min,
139
                                  double &z_max) const override;
140
        virtual surface_ptr make_copy() const override;
141
        virtual void write_json(nlohmann::ordered_json &jnode) const override;
142

143
        virtual double z(double x, double y) const override;
144
    };
145

146
    struct Flat : public Surface
147
    {
148
        Flat() : Surface(SurfaceType::FLAT) {}
2✔
149
        Flat(const nlohmann::ordered_json &jnode) : Surface(SurfaceType::FLAT) {};
6✔
150
        virtual ~Flat() {}
188✔
151
        virtual void bounding_box(const double x_minmax[2],
152
                                  const double y_minmax[2],
153
                                  double &z_min,
154
                                  double &z_max) const override;
155
        virtual surface_ptr make_copy() const override;
156
        virtual void write_json(nlohmann::ordered_json &jnode) const override;
157
    };
158

159
    struct Parabola : public Surface
160
    {
161
        // z(x,y) = (cx * x^2 + cy * y^2) / 2
162
        // TODO: Assuming that vertex_x_curv gives cx and
163
        // that vertex_y_curv gives cy
164
        double focal_length_x;
165
        double focal_length_y;
166

167
        Parabola(double focal_x, double focal_y) : Surface(SurfaceType::PARABOLA),
6,478✔
168
                                                   focal_length_x(focal_x),
6,478✔
169
                                                   focal_length_y(focal_y)
6,478✔
170
        {
171
        }
6,478✔
172
        Parabola(const nlohmann::ordered_json &jnode);
173
        virtual ~Parabola() {}
23,810✔
174
        virtual void bounding_box(const double x_minmax[2],
175
                                  const double y_minmax[2],
176
                                  double &z_min,
177
                                  double &z_max) const override;
178
        virtual surface_ptr make_copy() const override;
179
        virtual void write_json(nlohmann::ordered_json &jnode) const override;
180

181
        virtual double z(double x, double y) const override;
182
    };
183

184
    struct Sphere : public Surface
185
    {
186
        // z(x,y) = c(x^2 + y^2) / [1 + sqrt(1 - c^2{x^2 + y^2})]
187
        // where c = 1/R.
188
        // TODO: This form seems to be unnecessarily complicated.
189
        // Could easily just use one of the equations
190
        // z(x,y) = (1 - sqrt(1 - c^2 (x^2 + y^2))) / c
191
        //        = R - sqrt(R^2 - (x^2 + y^2))
192
        // Need to check on this.
193
        double vertex_curv;
194

195
        Sphere(double curv) : Surface(SurfaceType::SPHERE),
25✔
196
                              vertex_curv(curv)
25✔
197
        {
198
        }
25✔
199
        Sphere(const nlohmann::ordered_json &jnode);
200
        virtual ~Sphere() {}
151✔
201
        virtual void bounding_box(const double x_minmax[2],
202
                                  const double y_minmax[2],
203
                                  double &z_min,
204
                                  double &z_max) const override;
205
        virtual surface_ptr make_copy() const override;
206
        virtual void write_json(nlohmann::ordered_json &jnode) const override;
207

208
        virtual double z(double x, double y) const override;
209
    };
210

211
    // TODO: Add other surface types. Documentation has the following:
212
    // 1. Hyperboloid/Ellipsoid
213
    // 2. Zernike Series
214
    // 3. VSHOT data
215
    // 4. Finite Element data
216
    // 5. General Spencer & Murty Equation
217
    // 6. Polynomial Series (rotationally symmetric)
218
    // 7. Cubic Spline Interpolation (rotationally symmetric)
219

220
    surface_ptr make_surface_from_type(SurfaceType type,
221
                                       const std::vector<double> &args);
222

223
    surface_ptr make_surface_from_json(const nlohmann::ordered_json &jnode);
224

225
} // namespace SolTrace::Data
226

227
/**
228
 * @}
229
 */
230

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