From 38bb80026a92418932dac754f9f8edfe271fd67b Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Thu, 22 Jan 2026 14:15:14 -0700 Subject: [PATCH 01/23] First commit of port to GLM --- CMakeLists.txt | 2 + cmake/CPM.cmake | 24 + coretrace/simulation_data/CMakeLists.txt | 33 +- .../cst_templates/heliostat.cpp | 50 +- .../cst_templates/heliostat.hpp | 10 +- .../cst_templates/linear_fresnel.cpp | 103 ++-- .../cst_templates/linear_fresnel.hpp | 12 +- .../cst_templates/parabolic_dish.cpp | 18 +- .../cst_templates/parabolic_dish.hpp | 7 +- .../cst_templates/parabolic_trough.cpp | 69 +-- .../cst_templates/parabolic_trough.hpp | 23 +- .../cst_templates/utilities.cpp | 77 ++- .../cst_templates/utilities.hpp | 38 +- coretrace/simulation_data/element.cpp | 186 ++++---- coretrace/simulation_data/element.hpp | 241 +++++----- coretrace/simulation_data/json_helpers.hpp | 14 + coretrace/simulation_data/matvec.cpp | 92 ++++ coretrace/simulation_data/matvec.hpp | 22 + coretrace/simulation_data/ray_source.hpp | 10 +- coretrace/simulation_data/simdata_io.cpp | 21 +- .../simulation_data/simulation_data_api.hpp | 3 +- .../simulation_data_export.hpp | 14 - coretrace/simulation_data/single_element.cpp | 1 - coretrace/simulation_data/sun.hpp | 18 +- coretrace/simulation_data/vector3d.cpp | 85 ++-- coretrace/simulation_data/vector3d.hpp | 77 +-- coretrace/simulation_data/vector_utility.hpp | 38 ++ .../simulation_results/simulation_result.cpp | 19 +- .../simulation_results/simulation_result.hpp | 19 +- .../native_runner/cylinder_calculator.cpp | 32 +- .../native_runner/cylinder_calculator.hpp | 12 +- .../determine_element_intersection_new.cpp | 23 +- .../determine_element_intersection_new.hpp | 10 +- .../native_runner/find_element_hit.cpp | 74 +-- .../native_runner/find_element_hit.hpp | 14 +- .../native_runner/flat_calculator.cpp | 18 +- .../native_runner/flat_calculator.hpp | 10 +- .../native_runner/generate_ray.cpp | 42 +- .../native_runner/generate_ray.hpp | 17 +- .../native_runner/native_runner.cpp | 8 +- .../native_runner/native_runner_types.cpp | 51 +- .../native_runner/native_runner_types.hpp | 78 +-- .../native_runner/newton_calculator.cpp | 42 +- .../native_runner/newton_calculator.hpp | 16 +- .../native_runner/parabola_calculator.cpp | 46 +- .../native_runner/parabola_calculator.hpp | 12 +- .../native_runner/process_interaction.cpp | 229 ++++----- .../native_runner/process_interaction.hpp | 37 +- .../native_runner/pt_optimizations.cpp | 446 +++++++++--------- .../native_runner/pt_optimizations.hpp | 10 +- .../native_runner/sphere_calculator.cpp | 38 +- .../native_runner/sphere_calculator.hpp | 12 +- .../native_runner/sun_to_primary_stage.cpp | 33 +- .../native_runner/sun_to_primary_stage.hpp | 8 +- .../surface_intersection_calculator.hpp | 14 +- .../simulation_runner/native_runner/trace.cpp | 250 +++++----- .../simulation_runner/native_runner/trace.hpp | 35 +- .../native_runner/tracing_errors.cpp | 143 +++--- .../native_runner/tracing_errors.hpp | 23 +- .../native_runner_validation_test.cpp | 34 +- .../test_tools/count_absorbed_native.cpp | 4 +- google-tests/unit-tests/common/common.cpp | 28 +- google-tests/unit-tests/common/common.hpp | 14 +- .../cst-templates/heliostat_test.cpp | 81 ++-- .../cst-templates/linear_fresnel_test.cpp | 31 +- .../cst-templates/parabolic_dish_test.cpp | 4 +- .../cst-templates/parabolic_trough_test.cpp | 32 +- .../cst-templates/utilities_test.cpp | 25 +- .../simulation_data/element_test.cpp | 381 ++++++++------- .../simulation_data/file_io_test.cpp | 10 +- .../simulation_data/linear_algebra_test.cpp | 278 ++++++----- .../unit-tests/simulation_data/sun_test.cpp | 6 +- .../simulation_result_test.cpp | 47 +- .../cylinder_calculator_test.cpp | 72 +-- .../native_runner/flat_calculator_test.cpp | 65 ++- .../native_runner/native_runner_test.cpp | 63 ++- .../native_runner/newton_calculator_test.cpp | 37 +- .../parabola_calculator_test.cpp | 88 ++-- .../native_runner/sphere_calculator_test.cpp | 124 +++-- .../native_runner/tower_demo.cpp | 22 +- 80 files changed, 2356 insertions(+), 2199 deletions(-) create mode 100644 cmake/CPM.cmake create mode 100644 coretrace/simulation_data/vector_utility.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 03a18b50..0960ec3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.19) Project(soltrace_ui VERSION 1.0.0) +include(cmake/CPM.cmake) + set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake new file mode 100644 index 00000000..9a66dd83 --- /dev/null +++ b/cmake/CPM.cmake @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors + +set(CPM_DOWNLOAD_VERSION 0.42.1) +set(CPM_HASH_SUM "f3a6dcc6a04ce9e7f51a127307fa4f699fb2bade357a8eb4c5b45df76e1dc6a5") + +if(CPM_SOURCE_CACHE) + set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +elseif(DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +else() + set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +endif() + +# Expand relative path. This is important if the provided path contains a tilde (~) +get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) + +file(DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake + ${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM} +) + +include(${CPM_DOWNLOAD_LOCATION}) diff --git a/coretrace/simulation_data/CMakeLists.txt b/coretrace/simulation_data/CMakeLists.txt index 8380658a..f5043b74 100644 --- a/coretrace/simulation_data/CMakeLists.txt +++ b/coretrace/simulation_data/CMakeLists.txt @@ -4,14 +4,20 @@ include_directories(.) include_directories(cst_templates) include_directories(solar_position_calculators) -include(FetchContent) - FetchContent_Declare( - nlohmann_json - GIT_REPOSITORY https://github.com/nlohmann/json.git - GIT_TAG v3.11.3 - GIT_SHALLOW TRUE - ) - FetchContent_MakeAvailable(nlohmann_json) +CPMAddPackage( + GITHUB_REPOSITORY "nlohmann/json" + GIT_TAG "v3.11.3" + GIT_SHALLOW TRUE + OPTIONS "JSON_BuildTests OFF" +) + +CPMAddPackage( + GITHUB_REPOSITORY "g-truc/glm" + GIT_TAG "1.0.3" + GIT_SHALLOW TRUE + OPTIONS + "GLM_ENABLE_CXX_17 ON" +) set(SIMDATA_SRC aperture.cpp @@ -26,7 +32,6 @@ set(SIMDATA_SRC sun.cpp surface.cpp virtual_element.cpp - vector3d.cpp cst_templates/arclength.cpp cst_templates/heliostat.cpp cst_templates/linear_fresnel.cpp @@ -60,7 +65,7 @@ set(SIMDATA_HDRS stage_element.hpp sun.hpp surface.hpp - vector3d.hpp + vector_utility.hpp # virtual_element.hpp cst_templates/arclength.hpp cst_templates/heliostat.hpp @@ -90,8 +95,12 @@ set_target_properties(simdata PREFIX "" ) -# Link JSON (propagates its include directory) -target_link_libraries(simdata PUBLIC nlohmann_json::nlohmann_json) +# Link dependencies +target_link_libraries(simdata + PUBLIC + nlohmann_json::nlohmann_json + glm::glm +) if (NOT APPLE AND ENABLE_COVERAGE) # SET(CMAKE_CXX_FLAGS "-O0 -coverage -fkeep-inline-functions") diff --git a/coretrace/simulation_data/cst_templates/heliostat.cpp b/coretrace/simulation_data/cst_templates/heliostat.cpp index bf731d3e..8c9c66ca 100644 --- a/coretrace/simulation_data/cst_templates/heliostat.cpp +++ b/coretrace/simulation_data/cst_templates/heliostat.cpp @@ -27,10 +27,13 @@ namespace SolTrace::Data heliostat_area(-1.0), tracking_azimuth(-1.0), tracking_elevation(-1.0), + elevation_axis(0.0), + sun_position(0.0), + target_pos(0.0), target_set(false) { - this->elevation_axis.set_values(1.0, 0.0, 0.0); - this->sun_position.set_values(0.0, 0.0, 1.0); + this->elevation_axis = {1.0, 0.0, 0.0}; + this->sun_position = {0.0, 0.0, 1.0}; this->optics_mirror.set_ideal_reflection(); return; } @@ -68,8 +71,8 @@ namespace SolTrace::Data double panel_y = -0.5 * (this->aperture_size_y - panel_len_y); single_element_ptr elem; - Vector3d origin; - Vector3d aim; + glm::dvec3 origin; + glm::dvec3 aim; aperture_ptr ap; surface_ptr surf; element_id sts; @@ -83,21 +86,21 @@ namespace SolTrace::Data if (this->canting_method == NONE) { - origin.set_values(panel_x, panel_y, 0.0); - aim.set_values(panel_x, panel_y, 1000.0); + origin = {panel_x, panel_y, 0.0}; + aim = {panel_x, panel_y, 1000.0}; } else if (this->canting_method == ON_AXIS) { c = 0.5 / (this->onaxis_canting_distance); z = 0.5 * c * (panel_x * panel_x + panel_y * panel_y); - origin.set_values(panel_x, panel_y, z); - aim.set_values(0.0, 0.0, 2.0 * this->onaxis_canting_distance); + origin = {panel_x, panel_y, z}; + aim = {0.0, 0.0, 2.0 * this->onaxis_canting_distance}; } else if (this->canting_method == OFF_AXIS) { - origin.set_values(panel_x, panel_y, 0.0); + origin = {panel_x, panel_y, 0.0}; // TODO: Set aim vector values - aim.set_values(0.0, 0.0, 1.0); + aim = {0.0, 0.0, 1.0}; throw std::runtime_error("OFF_AXIS is not yet implemented"); } else if (this->canting_method == UNSET) @@ -184,24 +187,23 @@ namespace SolTrace::Data this->tracking_elevation = elevation; sun_position_vector_degrees(this->sun_position, azimuth, elevation); - Vector3d target_dir; - vector_add(1.0, this->target_pos, - -1.0, this->get_origin_global(), - target_dir); - - Vector3d aim_vector; - this->sun_position.make_unit(); - target_dir.make_unit(); - vector_add(1.0, target_dir, 1.0, this->sun_position, aim_vector); - aim_vector.make_unit(); + glm::dvec3 target_dir = this->target_pos + + -1.0 * this->get_origin_global(); + + glm::dvec3 aim_vector; + this->sun_position = glm::normalize(this->sun_position); + + target_dir = glm::normalize(target_dir); + aim_vector = glm::normalize(target_dir + this->sun_position); + this->convert_global_to_reference(this->aim, aim_vector); aim_vector = this->aim; - vector_add(1.0, this->get_origin_ref(), - 1000.0, this->aim); + this->aim = this->get_origin_ref() + + 1000.0 *this->aim; // Project into xy-plane aim_vector[2] = 0.0; - double theta = acos(aim_vector[0] / vector_norm(aim_vector)); + double theta = acos(aim_vector[0] / glm::length(aim_vector)); this->set_zrot_radians(theta); // std::cout << "Origin: " << this->origin @@ -371,7 +373,7 @@ namespace SolTrace::Data return; } - void Heliostat::set_target_position(const Vector3d &pos) + void Heliostat::set_target_position(const glm::dvec3 &pos) { this->target_pos = pos; this->target_set = true; diff --git a/coretrace/simulation_data/cst_templates/heliostat.hpp b/coretrace/simulation_data/cst_templates/heliostat.hpp index a0bca437..d6f19a4e 100644 --- a/coretrace/simulation_data/cst_templates/heliostat.hpp +++ b/coretrace/simulation_data/cst_templates/heliostat.hpp @@ -47,11 +47,11 @@ class Heliostat : public CompositeElement // void set_onaxis_canting_distance(double dist); // void set_offaxis_canting_sun_position(double azimuth, double zenith); void set_canting(CantingType ct, double val1, double val2); - void set_target_position(const Vector3d &pos); + void set_target_position(const glm::dvec3 &pos); void set_tracking_limits(double az_lower, double az_upper, double el_lower, double el_upper); - Vector3d get_elevation_axis() const + glm::dvec3 get_elevation_axis() const { return this->elevation_axis; } @@ -80,11 +80,11 @@ class Heliostat : public CompositeElement double heliostat_area; double tracking_azimuth; double tracking_elevation; - Vector3d elevation_axis; + glm::dvec3 elevation_axis; // Sun position in global coordinates - Vector3d sun_position; + glm::dvec3 sun_position; // Target position in global coordinates - Vector3d target_pos; + glm::dvec3 target_pos; bool target_set; std::vector facets; diff --git a/coretrace/simulation_data/cst_templates/linear_fresnel.cpp b/coretrace/simulation_data/cst_templates/linear_fresnel.cpp index 85636c79..fa619507 100644 --- a/coretrace/simulation_data/cst_templates/linear_fresnel.cpp +++ b/coretrace/simulation_data/cst_templates/linear_fresnel.cpp @@ -39,9 +39,9 @@ namespace SolTrace::Data this->optics_env_out.set_ideal_transmission(); this->optics_env_in.set_ideal_transmission(); - this->tracking_origin.set_values(1.0, 0.0, 0.0); - this->rotation_axis.set_values(0.0, 1.0, 0.0); - this->neutral_normal.set_values(0.0, 0.0, 1.0); + this->tracking_origin = {1.0, 0.0, 0.0}; + this->rotation_axis = {0.0, 1.0, 0.0}; + this->neutral_normal = {0.0, 0.0, 1.0}; } LinearFresnel::~LinearFresnel() @@ -94,18 +94,19 @@ namespace SolTrace::Data // Convert spherical coordinates to cartesian coordinates // y-axis - this->rotation_axis.set_values(sin(inc) * cos(pol), + this->rotation_axis = { sin(inc) * cos(pol), sin(inc) * sin(pol), - cos(inc)); + cos(inc) }; // z-axis - this->neutral_normal.set_values(sin(-el) * cos(pol), + this->neutral_normal = { sin(-el) * cos(pol), sin(-el) * sin(pol), - cos(-el)); + cos(-el) }; - cross_product(this->rotation_axis, - this->neutral_normal, - this->tracking_origin); + this->tracking_origin = glm::cross( + this->rotation_axis, + this->neutral_normal + ); return; } @@ -307,16 +308,16 @@ namespace SolTrace::Data panel_len_y /= this->num_panels_y; element_id sts; - Vector3d origin; - Vector3d aim; - Vector3d receiver_pos(0.0, + glm::dvec3 origin; + glm::dvec3 aim; + glm::dvec3 receiver_pos(0.0, 0.0, this->receiver_height); double panel_y, flen; single_element_ptr mirror; aperture_ptr ap; surface_ptr surf; - Vector3d khat(0.0, 0.0, 1.0); + glm::dvec3 khat(0.0, 0.0, 1.0); for (int_fast64_t i = 0; i < this->num_panels_x; ++i) { @@ -325,18 +326,18 @@ namespace SolTrace::Data { mirror = make_element(); - origin.set_values(panel_x, panel_y, 0.0); - vector_add(1.0, receiver_pos, -1.0, origin, aim); + origin = {panel_x, panel_y, 0.0}; + aim = 1.0 * receiver_pos + -1.0 * origin; // Project into xz-plane aim[1] = 0.0; - make_unit_vector(aim); + aim = glm::normalize(aim); // std::cout << "Panel x: " << panel_x // << "\nPanel y: " << panel_y // << "\nRec: " << aim // << std::endl; - vector_add(0.5, khat, 0.5, aim); + aim = 0.5 * khat + 0.5 * aim; // std::cout << "Aim: " << aim << std::endl; - vector_add(1.0, origin, 1000.0, aim); + aim = 1.0 * origin + 1000.0 * aim; // std::cout << "Aim Point: " << aim << std::endl; // std::cout << "Origin: " << origin << std::endl; mirror->set_reference_frame_geometry(origin, aim, 0.0); @@ -391,10 +392,13 @@ namespace SolTrace::Data // TODO: Single element at the moment. Break up into multiple tubes. auto abs = make_element(); abs->set_name("Absorber"); - origin.set_values(0.0, 0.0, - this->receiver_height - 0.5 * this->abs_diameter); - aim.set_values(0.0, 0.0, 1.0); - vector_add(1.0, origin, 1.0, aim); + origin = { + 0.0, + 0.0, + this->receiver_height - 0.5 * this->abs_diameter + }; + aim = {0.0, 0.0, 1.0}; + aim = 1.0 * origin + 1.0 * aim; abs->set_reference_frame_geometry(origin, aim, 0.0); abs->set_aperture(make_aperture(this->abs_diameter, this->aperture_size_y)); @@ -414,10 +418,13 @@ namespace SolTrace::Data // Envelope -- Outer auto envout = make_element(); envout->set_name("EnvelopeOuter"); - origin.set_values(0.0, 0.0, - this->receiver_height - 0.5 * this->env_diameter); - aim.set_values(0.0, 0.0, 1.0); - vector_add(1.0, origin, 1.0, aim); + origin = { + 0.0, + 0.0, + this->receiver_height - 0.5 * this->env_diameter + }; + aim = {0.0, 0.0, 1.0}; + aim = 1.0 * origin + 1.0 * aim; envout->set_reference_frame_geometry(origin, aim, 0.0); envout->set_aperture(make_aperture(this->env_diameter, this->aperture_size_y)); @@ -436,11 +443,13 @@ namespace SolTrace::Data // Envelope -- Inner auto envin = make_element(); envin->set_name("EnvelopeInner"); - origin.set_values(0.0, 0.0, - this->receiver_height - - 0.5 * this->env_diameter + this->env_thickness); - aim.set_values(0.0, 0.0, 1.0); - vector_add(1.0, origin, 1.0, aim); + origin = { + 0.0, + 0.0, + this->receiver_height - + 0.5 * this->env_diameter + this->env_thickness}; + aim = {0.0, 0.0, 1.0}; + aim = 1.0 * origin + 1.0 * aim; envin->set_reference_frame_geometry(origin, aim, 0.0); double ap_x = this->env_diameter - 2 * this->env_thickness; double ap_y = this->aperture_size_y; @@ -493,10 +502,10 @@ namespace SolTrace::Data // here at the cost of repeating ourselves. // Set aim point - Vector3d z_axis_ref, y_axis_ref; + glm::dvec3 z_axis_ref, y_axis_ref; this->convert_global_to_reference(z_axis_ref, this->neutral_normal); this->convert_global_to_reference(y_axis_ref, this->rotation_axis); - vector_add(1000.0, z_axis_ref, 1.0, this->origin, this->aim); + this->aim = 1000.0 * z_axis_ref + 1.0 * this->origin; // Set z-rotation double beta = asin(z_axis_ref[1]); @@ -522,41 +531,39 @@ namespace SolTrace::Data // Sun position projected into rotation plane and converted // to LinearFresnel object coordinates - Vector3d sun_pos, sun_proj_local; + glm::dvec3 sun_pos, sun_proj_local; sun_position_vector_degrees(sun_pos, azimuth, elevation); this->convert_vector_global_to_local(sun_proj_local, sun_pos); // Project to rotation plane sun_proj_local[1] = 0.0; - sun_proj_local.make_unit(); + sun_proj_local = glm::normalize(sun_proj_local); // std::cout << "Sun Position: " << sun_pos // << "\nSun Proj Local: " << sun_proj_local // << std::endl; // Set aimpoint for mirrors - Vector3d aim_mirror_ref; + glm::dvec3 aim_mirror_ref; // Absorber position projected into the plane of rotation (the xz-plane) - Vector3d origin_abs_proj(0.0, + glm::dvec3 origin_abs_proj(0.0, 0.0, this->receiver_height); // origin_abs_proj.make_unit(); - for (auto iter : this->mirrors) + for (auto& iter : this->mirrors) { // Get mirror to to receiver vector - vector_add(1.0, origin_abs_proj, - -1.0, iter->get_origin_ref(), - aim_mirror_ref); + aim_mirror_ref = origin_abs_proj - iter->get_origin_ref(); // Project onto the rotation plane aim_mirror_ref[1] = 0.0; - aim_mirror_ref.make_unit(); + aim_mirror_ref = glm::normalize(aim_mirror_ref); // std::cout << "Origin: " << iter->get_origin_ref() // << "\nMirror to Receiver: " << aim_mirror_ref // << std::endl; // Take bisector vector with the sun - vector_add(1.0, sun_proj_local, 1.0, aim_mirror_ref); - aim_mirror_ref.make_unit(); + aim_mirror_ref = sun_proj_local + aim_mirror_ref; + aim_mirror_ref = glm::normalize(aim_mirror_ref); // std::cout << "Sun Proj Local: " << sun_proj_local // << "\nAim Mirror Ref: " << aim_mirror_ref // << std::endl; @@ -571,12 +578,12 @@ namespace SolTrace::Data if (theta < this->tracking_limit_lower) { theta = this->tracking_limit_lower * D2R; - aim_mirror_ref.set_values(sin(theta), 0.0, cos(theta)); + aim_mirror_ref = {sin(theta), 0.0, cos(theta)}; } else if (theta > this->tracking_limit_upper) { theta = this->tracking_limit_upper * D2R; - aim_mirror_ref.set_values(sin(theta), 0.0, cos(theta)); + aim_mirror_ref = {sin(theta), 0.0, cos(theta)}; } // std::cout << "Theta 2: " << theta * R2D @@ -584,7 +591,7 @@ namespace SolTrace::Data // << std::endl; // Add origin of mirror - vector_add(1.0, iter->get_origin_ref(), 1000.0, aim_mirror_ref); + aim_mirror_ref = iter->get_origin_ref() + 1000.0 * aim_mirror_ref; // aim_mirror_ref.scalar_mult(1000.0); // Set aim point diff --git a/coretrace/simulation_data/cst_templates/linear_fresnel.hpp b/coretrace/simulation_data/cst_templates/linear_fresnel.hpp index c320a1cc..d2a11a6d 100644 --- a/coretrace/simulation_data/cst_templates/linear_fresnel.hpp +++ b/coretrace/simulation_data/cst_templates/linear_fresnel.hpp @@ -50,15 +50,15 @@ class LinearFresnel : public CompositeElement void create_geometry(); void update_geometry(double azimuth, double elevation); - Vector3d get_tracking_origin() const + glm::dvec3 get_tracking_origin() const { return this->tracking_origin; } - Vector3d get_rotation_vector() const + glm::dvec3 get_rotation_vector() const { return this->rotation_axis; } - Vector3d get_neutral_normal() const + glm::dvec3 get_neutral_normal() const { return this->neutral_normal; } @@ -105,9 +105,9 @@ class LinearFresnel : public CompositeElement // double tracking_angle; double tracking_limit_lower; double tracking_limit_upper; - Vector3d rotation_axis; - Vector3d neutral_normal; - Vector3d tracking_origin; + glm::dvec3 rotation_axis; + glm::dvec3 neutral_normal; + glm::dvec3 tracking_origin; std::vector mirrors; std::vector absorbers; diff --git a/coretrace/simulation_data/cst_templates/parabolic_dish.cpp b/coretrace/simulation_data/cst_templates/parabolic_dish.cpp index aebb4511..3dae35e7 100644 --- a/coretrace/simulation_data/cst_templates/parabolic_dish.cpp +++ b/coretrace/simulation_data/cst_templates/parabolic_dish.cpp @@ -32,7 +32,7 @@ ParabolicDish::ParabolicDish() : CompositeElement(), tracking_azimuth(90.0) { // Default position is pointing straight up and facing the east - this->elevation_axis.set_values(1.0, 0.0, 0.0); + this->elevation_axis = {1.0, 0.0, 0.0}; sun_position_vector_degrees(this->sun_position, this->tracking_azimuth, this->tracking_elevation); @@ -87,8 +87,8 @@ void ParabolicDish::create_geometry() } single_element_ptr mirror; - Vector3d origin(0.0, 0.0, 0.0); - Vector3d aim(0.0, 0.0, 1000.0); + glm::dvec3 origin(0.0, 0.0, 0.0); + glm::dvec3 aim(0.0, 0.0, 1000.0); double zrot = 0.0; if (this->gap_center <= 0.0 && @@ -142,8 +142,8 @@ void ParabolicDish::create_geometry() /**** Create absorber element(s) ****/ single_element_ptr abs = make_element(); - origin.set_values(0.0, 0.0, this->abs_distance); - aim.set_values(0.0, 0.0, this->abs_distance - 1.0); + origin = {0.0, 0.0, this->abs_distance}; + aim = {0.0, 0.0, this->abs_distance - 1.0}; abs->set_reference_frame_geometry(origin, aim, 0.0); abs->set_aperture(make_aperture(this->abs_diameter)); abs->set_surface(make_surface()); @@ -196,15 +196,15 @@ void ParabolicDish::update_geometry(double azimuth, double elevation) this->tracking_elevation = elevation; sun_position_vector_degrees(this->sun_position, azimuth, elevation); - this->sun_position.scalar_mult(1000.0); + this->sun_position *= 1000.0; this->convert_global_to_reference(this->aim, this->sun_position); - Vector3d aim_proj; + glm::dvec3 aim_proj; // Get aim direction (not point) - vector_add(-1.0, this->origin, 1.0, this->aim, aim_proj); + aim_proj = -1.0 * this->origin + this->aim; // Project into reference xy-plane aim_proj[2] = 0.0; - double theta = acos(aim_proj[0] / vector_norm(aim_proj)); + double theta = acos(aim_proj[0] / glm::length(aim_proj)); this->set_zrot_radians(theta); this->compute_coordinate_rotations(); diff --git a/coretrace/simulation_data/cst_templates/parabolic_dish.hpp b/coretrace/simulation_data/cst_templates/parabolic_dish.hpp index 71c60e1f..356a7612 100644 --- a/coretrace/simulation_data/cst_templates/parabolic_dish.hpp +++ b/coretrace/simulation_data/cst_templates/parabolic_dish.hpp @@ -19,7 +19,6 @@ #include #include "single_element.hpp" -#include "vector3d.hpp" namespace SolTrace::Data { @@ -46,7 +45,7 @@ class ParabolicDish : public CompositeElement virtual void enforce_user_fields_set() const override; - const Vector3d &get_elevation_axis() const + const glm::dvec3 &get_elevation_axis() const { return this->elevation_axis; } @@ -77,8 +76,8 @@ class ParabolicDish : public CompositeElement double tracking_elevation; double tracking_azimuth; // Defines the direction about which the dish can change its elevation - Vector3d elevation_axis; - Vector3d sun_position; + glm::dvec3 elevation_axis; + glm::dvec3 sun_position; std::vector mirrors; std::vector absorbers; diff --git a/coretrace/simulation_data/cst_templates/parabolic_trough.cpp b/coretrace/simulation_data/cst_templates/parabolic_trough.cpp index 9ee465ef..0122f8e5 100644 --- a/coretrace/simulation_data/cst_templates/parabolic_trough.cpp +++ b/coretrace/simulation_data/cst_templates/parabolic_trough.cpp @@ -35,9 +35,9 @@ ParabolicTrough::ParabolicTrough() tracking_limit_lower(-180.0), tracking_limit_upper(180.0) { - this->tracking_origin.set_values(1.0, 0.0, 0.0); - this->rotation_axis.set_values(0.0, 1.0, 0.0); - this->neutral_normal.set_values(0.0, 0.0, 1.0); + this->tracking_origin = {1.0, 0.0, 0.0}; + this->rotation_axis = {0.0, 1.0, 0.0}; + this->neutral_normal = {0.0, 0.0, 1.0}; return; } @@ -67,8 +67,8 @@ void ParabolicTrough::create_geometry() aperture_ptr ap = nullptr; single_element_ptr panel = nullptr; surface_ptr surf = nullptr; - Vector3d origin; - Vector3d aim; + glm::dvec3 origin; + glm::dvec3 aim; double xstop; double gap; double ystart, ycoord; @@ -106,8 +106,8 @@ void ParabolicTrough::create_geometry() // << "\narc_len = " << arc_length // << std::endl; - origin.set_values(0.0, ycoord, 0.0); - aim.set_values(0.0, ycoord, 1000.0); + origin = {0.0, ycoord, 0.0}; + aim = {0.0, ycoord, 1000.0}; panel = make_element(); panel->set_name("ParabolicMirror"); @@ -204,20 +204,20 @@ void ParabolicTrough::create_geometry() this->enable(); - this->rotation_axis.make_unit(); - this->tracking_origin.make_unit(); + this->rotation_axis = glm::normalize(this->rotation_axis); + this->tracking_origin = glm::normalize(this->tracking_origin); rotate_vector_degrees(this->rotation_axis, this->tracking_origin, -this->tracking_limit_lower, this->vector_lower_limit); - this->vector_lower_limit.make_unit(); + this->vector_lower_limit = glm::normalize(this->vector_lower_limit); rotate_vector_degrees(this->rotation_axis, this->tracking_origin, -this->tracking_limit_upper, this->vector_upper_limit); - this->vector_upper_limit.make_unit(); + this->vector_upper_limit = glm::normalize(this->vector_upper_limit); this->initialized = true; @@ -254,20 +254,20 @@ void ParabolicTrough::update_geometry(double azimuth, this->coordinates_initialized = false; - Vector3d sun_pos; + glm::dvec3 sun_pos; sun_position_vector_degrees(sun_pos, azimuth, elevation); - make_unit_vector(sun_pos); + sun_pos = glm::normalize(sun_pos); // Project into the plane defined by rotation axis as the normal - Vector3d sun_proj; + glm::dvec3 sun_proj; project_onto_plane(this->rotation_axis, sun_pos, sun_proj); - make_unit_vector(sun_proj); + sun_proj = glm::normalize(sun_proj); - assert(dot_product(sun_proj, this->rotation_axis) < 1e-12); + assert(glm::dot(sun_proj, this->rotation_axis) < 1e-12); - // double theta = acos(dot_product(sun_proj, this->tracking_origin)) * R2D; - double theta = acos(dot_product(sun_proj, this->neutral_normal)) * R2D; - if (dot_product(sun_proj, this->tracking_origin) < 0.0) + // double theta = acos(glm::dot(sun_proj, this->tracking_origin)) * R2D; + double theta = acos(glm::dot(sun_proj, this->neutral_normal)) * R2D; + if (glm::dot(sun_proj, this->tracking_origin) < 0.0) theta = -theta; if (theta < this->tracking_limit_lower) @@ -288,16 +288,16 @@ void ParabolicTrough::update_geometry(double azimuth, this->convert_global_to_reference(this->aim, sun_proj); } - Vector3d rotation_axis_ref; - this->aim.make_unit(); + glm::dvec3 rotation_axis_ref; + this->aim = glm::normalize(this->aim); double beta = asin(this->aim[1]); this->convert_global_to_reference(rotation_axis_ref, this->rotation_axis); double gamma = acos(rotation_axis_ref[1] / cos(beta)); this->set_zrot_radians(gamma); - this->aim.scalar_mult(1000.0); - vector_add(1.0, this->origin, 1.0, this->aim); + this->aim *= 1000.0; + this->aim = this->origin + this->aim; this->compute_coordinate_rotations(); @@ -350,19 +350,24 @@ void ParabolicTrough::set_angles(double azimuth, double tilt) // Convert spherical coordinates to cartesian coordinates // y-axis - this->rotation_axis.set_values(sin(inc) * cos(pol), - sin(inc) * sin(pol), - cos(inc)); + this->rotation_axis = { + sin(inc) * cos(pol), + sin(inc) * sin(pol), + cos(inc) + }; // z-axis - this->neutral_normal.set_values(sin(-el) * cos(pol), - sin(-el) * sin(pol), - cos(-el)); + this->neutral_normal = { + sin(-el) * cos(pol), + sin(-el) * sin(pol), + cos(-el) + }; // x-axis - cross_product(this->rotation_axis, - this->neutral_normal, - this->tracking_origin); + this->tracking_origin = glm::cross( + this->rotation_axis, + this->neutral_normal + ); return; } diff --git a/coretrace/simulation_data/cst_templates/parabolic_trough.hpp b/coretrace/simulation_data/cst_templates/parabolic_trough.hpp index 959e08ff..4178d7fc 100644 --- a/coretrace/simulation_data/cst_templates/parabolic_trough.hpp +++ b/coretrace/simulation_data/cst_templates/parabolic_trough.hpp @@ -25,7 +25,6 @@ #include "simulation_data.hpp" #include "single_element.hpp" // #include "surface.hpp" -#include "vector3d.hpp" namespace SolTrace::Data { @@ -56,7 +55,7 @@ class ParabolicTrough : public CompositeElement const OpticalProperties &absorber, const OpticalProperties &envelope_inner, const OpticalProperties &envelope_outer); - // void set_position(const Vector3d &pos) + // void set_position(const glm::dvec3 &pos) // { // this->position = pos; // return; @@ -68,23 +67,23 @@ class ParabolicTrough : public CompositeElement virtual void enforce_user_fields_set() const override; - Vector3d get_tracking_origin() const + glm::dvec3 get_tracking_origin() const { return this->tracking_origin; } - Vector3d get_rotation_vector() const + glm::dvec3 get_rotation_vector() const { return this->rotation_axis; } - Vector3d get_neutral_normal() const + glm::dvec3 get_neutral_normal() const { return this->neutral_normal; } - Vector3d get_tracking_limit_lower() const + glm::dvec3 get_tracking_limit_lower() const { return this->vector_lower_limit; } - Vector3d get_tracking_limit_upper() const + glm::dvec3 get_tracking_limit_upper() const { return this->vector_upper_limit; } @@ -102,11 +101,11 @@ class ParabolicTrough : public CompositeElement // Degrees from ground plane (GLOBAL z-axis) double tilt; // Aperture normal when tracking angle is 0.0 (GLOBAL coordinates) - Vector3d tracking_origin; + glm::dvec3 tracking_origin; // Axis trough rotates about (GLOBAL coordinates) - Vector3d rotation_axis; + glm::dvec3 rotation_axis; // Aperture normal when tracking angle is 90.0 (GLOBAL coordinates) - Vector3d neutral_normal; + glm::dvec3 neutral_normal; // Reflector(s) Characteristic(s) double aperture_size_x; @@ -134,9 +133,9 @@ class ParabolicTrough : public CompositeElement double tracking_limit_lower; double tracking_limit_upper; // Aperture normal at lower limit in global coordinate - Vector3d vector_lower_limit; + glm::dvec3 vector_lower_limit; // Aperture normal at upper limit in global coordinate - Vector3d vector_upper_limit; + glm::dvec3 vector_upper_limit; // Element Management // composite_element_ptr elements; diff --git a/coretrace/simulation_data/cst_templates/utilities.cpp b/coretrace/simulation_data/cst_templates/utilities.cpp index cf7b55a0..33084f9f 100644 --- a/coretrace/simulation_data/cst_templates/utilities.cpp +++ b/coretrace/simulation_data/cst_templates/utilities.cpp @@ -5,77 +5,76 @@ #include #include "constants.hpp" -#include "vector3d.hpp" + +#include namespace SolTrace::Data { -void project_onto_plane(const Vector3d &n, - const Vector3d &u, - Vector3d &uproj) +void project_onto_plane(const glm::dvec3 &n, + const glm::dvec3 &u, + glm::dvec3 &uproj) { - double nmag = n.norm(); - double coef = -dot_product(n, u) / (nmag * nmag); - vector_add(1.0, u, coef, n, uproj); + double nmag = glm::length(n); + double coef = -glm::dot(n, u) / (nmag * nmag); + uproj = u + coef * n; return; } -void project_onto_plane(const Vector3d &n, - Vector3d &u) +void project_onto_plane(const glm::dvec3 &n, + glm::dvec3 &u) { - double nmag = n.norm(); - double coef = -dot_product(n, u) / (nmag * nmag); - // vector_add(1.0, u, coef, n, uproj); - vector_add(coef, n, 1.0, u); + double nmag = glm::length(n); + double coef = -glm::dot(n,u) / (nmag * nmag); + u = coef * n + u; return; } -void project_onto_vector(const Vector3d &u, - const Vector3d &v, - Vector3d &vproj) +void project_onto_vector(const glm::dvec3 &u, + const glm::dvec3 &v, + glm::dvec3 &vproj) { - double umag = u.norm(); - double coef = dot_product(u, v) / (umag * umag); - vector_add(coef, u, 0.0, vproj); + double umag = glm::length(u); + double coef = glm::dot(u, v) / (umag * umag); + vproj = coef * u; return; } -void project_onto_vector(const Vector3d &u, - Vector3d &v) +void project_onto_vector(const glm::dvec3 &u, + glm::dvec3 &v) { - double umag = u.norm(); - double coef = dot_product(u, v) / (umag * umag); - vector_add(coef, u, 0.0, v); + double umag = glm::length(u); + double coef = glm::dot(u, v) / (umag * umag); + v = coef * u; return; } -void rotate_vector_degrees(const Vector3d &k, - const Vector3d &v, +void rotate_vector_degrees(const glm::dvec3 &k, + const glm::dvec3 &v, double theta, - Vector3d &vrot) + glm::dvec3 &vrot) { theta *= D2R; return rotate_vector_radians(k, v, theta, vrot); } -void rotate_vector_radians(const Vector3d &k, - const Vector3d &v, +void rotate_vector_radians(const glm::dvec3 &k, + const glm::dvec3 &v, double theta, - Vector3d &vrot) + glm::dvec3 &vrot) { - assert(fabs(k.norm() - 1.0) < 1e-12); + assert(fabs(glm::length(k) - 1.0) < 1e-12); - Vector3d scratch; + glm::dvec3 scratch = glm::cross(k,v); - cross_product(k, v, scratch); - vector_add(sin(theta), scratch, cos(theta), v, vrot); + vrot = sin(theta) * scratch + cos(theta) * v; - double coef = (1.0 - cos(theta)) * dot_product(k, v); - vector_add(coef, k, 1.0, vrot); + double coef = (1.0 - cos(theta)) * glm::dot(k, v); + vrot = coef* k + vrot; return; } -void sun_position_vector_degrees(Vector3d &sun_pos, +void sun_position_vector_degrees(glm::dvec3 &sun_pos, double azimuth, double elevation) { @@ -84,14 +83,14 @@ void sun_position_vector_degrees(Vector3d &sun_pos, D2R * elevation); } -void sun_position_vector_radians(Vector3d &sun_pos, +void sun_position_vector_radians(glm::dvec3 &sun_pos, double azimuth, double elevation) { double x = sin(azimuth) * cos(elevation); double y = cos(azimuth) * cos(elevation); double z = sin(elevation); - sun_pos.set_values(x, y, z); + sun_pos = glm::dvec3(x, y, z); return; } diff --git a/coretrace/simulation_data/cst_templates/utilities.hpp b/coretrace/simulation_data/cst_templates/utilities.hpp index 78bad606..33743b80 100644 --- a/coretrace/simulation_data/cst_templates/utilities.hpp +++ b/coretrace/simulation_data/cst_templates/utilities.hpp @@ -2,39 +2,39 @@ #ifndef SOLTRACE_UTILITIES_H #define SOLTRACE_UTILITIES_H -#include "vector3d.hpp" +#include namespace SolTrace::Data { -void project_onto_plane(const Vector3d &n, - const Vector3d &u, - Vector3d &uproj); +void project_onto_plane(const glm::dvec3 &n, + const glm::dvec3 &u, + glm::dvec3 &uproj); -void project_onto_plane(const Vector3d &n, - Vector3d &u); +void project_onto_plane(const glm::dvec3 &n, + glm::dvec3 &u); -void project_onto_vector(const Vector3d &u, - const Vector3d &v, - Vector3d &vproj); +void project_onto_vector(const glm::dvec3 &u, + const glm::dvec3 &v, + glm::dvec3 &vproj); -void project_onto_vector(const Vector3d &u, - Vector3d &v); +void project_onto_vector(const glm::dvec3 &u, + glm::dvec3 &v); -void rotate_vector_degrees(const Vector3d &k, - const Vector3d &v, +void rotate_vector_degrees(const glm::dvec3 &k, + const glm::dvec3 &v, double theta, - Vector3d &vrot); + glm::dvec3 &vrot); -void rotate_vector_radians(const Vector3d &k, - const Vector3d &v, +void rotate_vector_radians(const glm::dvec3 &k, + const glm::dvec3 &v, double theta, - Vector3d &vrot); + glm::dvec3 &vrot); -void sun_position_vector_degrees(Vector3d &sun_pos, +void sun_position_vector_degrees(glm::dvec3 &sun_pos, double azimuth, double elevation); -void sun_position_vector_radians(Vector3d &sun_pos, +void sun_position_vector_radians(glm::dvec3 &sun_pos, double azimuth, double elevation); diff --git a/coretrace/simulation_data/element.cpp b/coretrace/simulation_data/element.cpp index 1aa92228..6294ed8b 100644 --- a/coretrace/simulation_data/element.cpp +++ b/coretrace/simulation_data/element.cpp @@ -4,6 +4,8 @@ #include #include "constants.hpp" +#include "json_helpers.hpp" +#include "matvec.hpp" namespace SolTrace::Data { @@ -19,12 +21,12 @@ ElementBase::ElementBase() : Element(), reference_element(nullptr) { // Default local coordinates to match with the reference coordinates - this->aim.set_values(0.0, 0.0, 1.0); - this->origin.zero(); + this->aim = {0.0, 0.0, 1.0}; + this->origin = glm::dvec3(0.0); - this->euler_angles.zero(); - this->reference_to_local.identity(); - this->local_to_reference.identity(); + this->euler_angles = glm::dvec3(0.0); + this->reference_to_local = glm::mat3(); + this->local_to_reference = glm::mat3(); return; } @@ -47,11 +49,11 @@ ElementBase::ElementBase(const nlohmann::ordered_json& jnode) : ElementBase() this->set_name(jnode.at("my_name")); std::array orig_arr = jnode.at("origin").get>(); - Vector3d orig_vec(orig_arr.data()); + glm::dvec3 orig_vec = from_array(orig_arr); this->set_origin(orig_vec); std::array aim_arr = jnode.at("aim").get>(); - Vector3d aim_vec(aim_arr.data()); + glm::dvec3 aim_vec = from_array(aim_arr); this->set_aim_vector(aim_vec); this->set_zrot(jnode.at("zrot")); @@ -76,14 +78,14 @@ ElementBase::~ElementBase() // return empty_container.get_const_iterator(); // } -Vector3d ElementBase::get_origin_stage() const +glm::dvec3 ElementBase::get_origin_stage() const { - Vector3d origin_stage; + glm::dvec3 origin_stage; auto ref_el = this->reference_element; if (this->is_stage()) { // This is the stage element so the stage origin is zero. - origin_stage.zero(); + origin_stage = glm::dvec3(0.0); } else if (ref_el == nullptr) { @@ -98,9 +100,9 @@ Vector3d ElementBase::get_origin_stage() const return origin_stage; } -Vector3d ElementBase::get_origin_global() const +glm::dvec3 ElementBase::get_origin_global() const { - Vector3d origin_global; + glm::dvec3 origin_global; auto ref_el = this->reference_element; if (ref_el == nullptr) { @@ -113,9 +115,9 @@ Vector3d ElementBase::get_origin_global() const return origin_global; } -Vector3d ElementBase::get_aim_vector_stage() const +glm::dvec3 ElementBase::get_aim_vector_stage() const { - Vector3d aim_stage; + glm::dvec3 aim_stage; if (this->reference_element == nullptr) { aim_stage = this->aim; @@ -128,9 +130,9 @@ Vector3d ElementBase::get_aim_vector_stage() const return aim_stage; } -Vector3d ElementBase::get_aim_vector_global() const +glm::dvec3 ElementBase::get_aim_vector_global() const { - Vector3d aim_global; + glm::dvec3 aim_global; if (this->reference_element == nullptr) { aim_global = this->aim; @@ -143,20 +145,20 @@ Vector3d ElementBase::get_aim_vector_global() const return aim_global; } -Matrix3d ElementBase::get_reference_to_local() const +glm::dmat3 ElementBase::get_reference_to_local() const { return this->reference_to_local; } -Matrix3d ElementBase::get_stage_to_local() const +glm::dmat3 ElementBase::get_stage_to_local() const { - Matrix3d stage_to_local; + glm::dmat3 stage_to_local; if (this->is_stage()) { // stage_to_local.set_value(0, 0, 1.0); // stage_to_local.set_value(1, 1, 1.0); // stage_to_local.set_value(2, 2, 1.0); - stage_to_local.identity(); + stage_to_local = {}; } else if (this->reference_element == nullptr) { @@ -164,40 +166,40 @@ Matrix3d ElementBase::get_stage_to_local() const } else { - Matrix3d R = this->reference_element->get_stage_to_local(); - matrix_matrix_product(this->reference_to_local, R, stage_to_local); + glm::dmat3 R = this->reference_element->get_stage_to_local(); + stage_to_local = this->reference_to_local * R; } return stage_to_local; } -Matrix3d ElementBase::get_global_to_local() const +glm::dmat3 ElementBase::get_global_to_local() const { - Matrix3d global_to_local; + glm::dmat3 global_to_local; if (this->reference_element == nullptr) { global_to_local = this->reference_to_local; } else { - Matrix3d R = this->reference_element->get_global_to_local(); - matrix_matrix_product(this->reference_to_local, R, global_to_local); + glm::dmat3 R = this->reference_element->get_global_to_local(); + global_to_local = this->reference_to_local * R; } return global_to_local; } -Matrix3d ElementBase::get_local_to_reference() const +glm::dmat3 ElementBase::get_local_to_reference() const { return this->local_to_reference; } -Matrix3d ElementBase::get_local_to_stage() const +glm::dmat3 ElementBase::get_local_to_stage() const { - Matrix3d local_to_stage; + glm::dmat3 local_to_stage; if (this->is_stage()) { - local_to_stage.set_value(0, 0, 1.0); - local_to_stage.set_value(1, 1, 1.0); - local_to_stage.set_value(2, 2, 1.0); + local_to_stage[0][0] = 1.0; + local_to_stage[1][1] = 1.0; + local_to_stage[2][2] = 1.0; } else if (this->reference_element == nullptr) { @@ -205,23 +207,23 @@ Matrix3d ElementBase::get_local_to_stage() const } else { - Matrix3d R = this->reference_element->get_local_to_stage(); - matrix_matrix_product(R, this->local_to_reference, local_to_stage); + glm::dmat3 R = this->reference_element->get_local_to_stage(); + local_to_stage = R * this->local_to_reference; } return local_to_stage; } -Matrix3d ElementBase::get_local_to_global() const +glm::dmat3 ElementBase::get_local_to_global() const { - Matrix3d local_to_global; + glm::dmat3 local_to_global; if (this->reference_element == nullptr) { local_to_global = this->local_to_reference; } else { - Matrix3d R = this->reference_element->get_local_to_global(); - matrix_matrix_product(R, this->local_to_reference, local_to_global); + glm::dmat3 R = this->reference_element->get_local_to_global(); + local_to_global = R * this->local_to_reference; } return local_to_global; } @@ -232,15 +234,13 @@ int ElementBase::compute_coordinate_rotations() if (!this->coordinates_initialized) { - Vector3d dr; - vector_add(1.0, this->aim, -1.0, this->origin, dr); - make_unit_vector(dr); + glm::dvec3 dr = glm::normalize(this->aim + -1.0 * this->origin); this->euler_angles[0] = atan2(dr[0], dr[2]); this->euler_angles[1] = asin(dr[1]); this->euler_angles[2] = this->zrot * D2R; - compute_transform_matrices(this->euler_angles, + CalculateTransformMatrices(this->euler_angles, this->reference_to_local, this->local_to_reference); @@ -250,8 +250,8 @@ int ElementBase::compute_coordinate_rotations() return sts; } -int ElementBase::set_reference_frame_geometry(const Vector3d &origin, - const Vector3d &aim, +int ElementBase::set_reference_frame_geometry(const glm::dvec3 &origin, + const glm::dvec3 &aim, double zrot) { this->coordinates_initialized = false; @@ -261,17 +261,16 @@ int ElementBase::set_reference_frame_geometry(const Vector3d &origin, return this->compute_coordinate_rotations(); } -int ElementBase::convert_reference_to_local(Vector3d &local, - const Vector3d &ref) +int ElementBase::convert_reference_to_local(glm::dvec3 &local, + const glm::dvec3 &ref) { - Vector3d temp; - vector_add(1.0, ref, -1.0, this->origin, temp); - matrix_vector_product(this->reference_to_local, temp, local); + glm::dvec3 temp = ref + -1.0 * this->origin; + local = this->reference_to_local * temp; return 0; } -int ElementBase::convert_stage_to_local(Vector3d &local, - const Vector3d &stage) +int ElementBase::convert_stage_to_local(glm::dvec3 &local, + const glm::dvec3 &stage) { if (this->is_stage()) { @@ -287,15 +286,15 @@ int ElementBase::convert_stage_to_local(Vector3d &local, } else { - Vector3d ref; + glm::dvec3 ref; this->reference_element->convert_stage_to_local(ref, stage); convert_reference_to_local(local, ref); } return 0; } -int ElementBase::convert_global_to_local(Vector3d &local, - const Vector3d &global) +int ElementBase::convert_global_to_local(glm::dvec3 &local, + const glm::dvec3 &global) { auto ref_el = this->reference_element; if (ref_el == nullptr) @@ -305,24 +304,23 @@ int ElementBase::convert_global_to_local(Vector3d &local, } else { - Vector3d ref; + glm::dvec3 ref; ref_el->convert_global_to_local(ref, global); this->convert_reference_to_local(local, ref); } return 0; } -int ElementBase::convert_local_to_reference(Vector3d &ref, - const Vector3d &local) +int ElementBase::convert_local_to_reference(glm::dvec3 &ref, + const glm::dvec3 &local) { - Vector3d temp; - matrix_vector_product(this->local_to_reference, local, temp); - vector_add(1.0, temp, 1.0, this->origin, ref); + glm::dvec3 temp = this->local_to_reference * local; + ref = temp + this->origin; return 0; } -int ElementBase::convert_local_to_stage(Vector3d &stage, - const Vector3d &local) +int ElementBase::convert_local_to_stage(glm::dvec3 &stage, + const glm::dvec3 &local) { if (this->is_stage()) { @@ -339,15 +337,15 @@ int ElementBase::convert_local_to_stage(Vector3d &stage, } else { - Vector3d ref; + glm::dvec3 ref; this->convert_local_to_reference(ref, local); this->reference_element->convert_local_to_stage(stage, ref); } return 0; } -int ElementBase::convert_local_to_global(Vector3d &global, - const Vector3d &local) +int ElementBase::convert_local_to_global(glm::dvec3 &global, + const glm::dvec3 &local) { auto ref_el = this->reference_element; if (ref_el == nullptr) @@ -356,15 +354,15 @@ int ElementBase::convert_local_to_global(Vector3d &global, } else { - Vector3d ref; + glm::dvec3 ref; this->convert_local_to_reference(ref, local); ref_el->convert_local_to_global(global, ref); } return 0; } -int ElementBase::convert_global_to_reference(Vector3d &ref, - const Vector3d &global) +int ElementBase::convert_global_to_reference(glm::dvec3 &ref, + const glm::dvec3 &global) { if (this->reference_element == nullptr) { @@ -377,8 +375,8 @@ int ElementBase::convert_global_to_reference(Vector3d &ref, } } -int ElementBase::convert_reference_to_global(Vector3d &global, - const Vector3d &ref) +int ElementBase::convert_reference_to_global(glm::dvec3 &global, + const glm::dvec3 &ref) { if (this->reference_element == nullptr) { @@ -391,15 +389,15 @@ int ElementBase::convert_reference_to_global(Vector3d &global, } } -int ElementBase::convert_vector_reference_to_local(Vector3d &local, - const Vector3d &ref) +int ElementBase::convert_vector_reference_to_local(glm::dvec3 &local, + const glm::dvec3 &ref) { - matrix_vector_product(this->reference_to_local, ref, local); + local = this->reference_to_local * ref; return 0; } -int ElementBase::convert_vector_stage_to_local(Vector3d &local, - const Vector3d &stage) +int ElementBase::convert_vector_stage_to_local(glm::dvec3 &local, + const glm::dvec3 &stage) { if (this->is_stage()) { @@ -415,15 +413,15 @@ int ElementBase::convert_vector_stage_to_local(Vector3d &local, } else { - Vector3d ref; + glm::dvec3 ref; this->reference_element->convert_vector_stage_to_local(ref, stage); convert_vector_reference_to_local(local, ref); } return 0; } -int ElementBase::convert_vector_global_to_local(Vector3d &local, - const Vector3d &global) +int ElementBase::convert_vector_global_to_local(glm::dvec3 &local, + const glm::dvec3 &global) { auto ref_el = this->reference_element; if (ref_el == nullptr) @@ -433,22 +431,22 @@ int ElementBase::convert_vector_global_to_local(Vector3d &local, } else { - Vector3d ref; + glm::dvec3 ref; ref_el->convert_vector_global_to_local(ref, global); this->convert_vector_reference_to_local(local, ref); } return 0; } -int ElementBase::convert_vector_local_to_reference(Vector3d &ref, - const Vector3d &local) +int ElementBase::convert_vector_local_to_reference(glm::dvec3 &ref, + const glm::dvec3 &local) { - matrix_vector_product(this->local_to_reference, local, ref); + ref = this->local_to_reference * local; return 0; } -int ElementBase::convert_vector_local_to_stage(Vector3d &stage, - const Vector3d &local) +int ElementBase::convert_vector_local_to_stage(glm::dvec3 &stage, + const glm::dvec3 &local) { if (this->is_stage()) { @@ -465,15 +463,15 @@ int ElementBase::convert_vector_local_to_stage(Vector3d &stage, } else { - Vector3d ref; + glm::dvec3 ref; this->convert_vector_local_to_reference(ref, local); this->reference_element->convert_vector_local_to_stage(stage, ref); } return 0; } -int ElementBase::convert_vector_local_to_global(Vector3d &global, - const Vector3d &local) +int ElementBase::convert_vector_local_to_global(glm::dvec3 &global, + const glm::dvec3 &local) { auto ref_el = this->reference_element; if (ref_el == nullptr) @@ -482,15 +480,15 @@ int ElementBase::convert_vector_local_to_global(Vector3d &global, } else { - Vector3d ref; + glm::dvec3 ref; this->convert_vector_local_to_reference(ref, local); ref_el->convert_vector_local_to_global(global, ref); } return 0; } -int ElementBase::convert_vector_global_to_reference(Vector3d &ref, - const Vector3d &global) +int ElementBase::convert_vector_global_to_reference(glm::dvec3 &ref, + const glm::dvec3 &global) { if (this->reference_element == nullptr) { @@ -504,8 +502,8 @@ int ElementBase::convert_vector_global_to_reference(Vector3d &ref, } } -int ElementBase::convert_vector_reference_to_global(Vector3d &global, - const Vector3d &ref) +int ElementBase::convert_vector_reference_to_global(glm::dvec3 &global, + const glm::dvec3 &ref) { if (this->reference_element == nullptr) { @@ -542,8 +540,8 @@ void ElementBase::write_common_json(nlohmann::ordered_json& jnode) const jnode["stage"] = this->stage; jnode["my_name"] = this->my_name; - jnode["origin"] = this->origin.data; - jnode["aim"] = this->aim.data; + jnode["origin"] = to_array(this->origin); + jnode["aim"] = to_array(this->aim); jnode["zrot"] = this->zrot; // Not including calculated values diff --git a/coretrace/simulation_data/element.hpp b/coretrace/simulation_data/element.hpp index f034f06e..e62c54c8 100644 --- a/coretrace/simulation_data/element.hpp +++ b/coretrace/simulation_data/element.hpp @@ -15,7 +15,10 @@ // #include #include + #include +#include +#include #include "aperture.hpp" #include "constants.hpp" @@ -23,7 +26,7 @@ #include "optical_properties.hpp" #include "ray_source.hpp" #include "surface.hpp" -#include "vector3d.hpp" + namespace SolTrace::Data { @@ -114,25 +117,25 @@ class Element * @brief Get origin position in reference coordinates * @return Origin position vector in reference frame */ - virtual Vector3d get_origin_ref() const = 0; + virtual glm::dvec3 get_origin_ref() const = 0; /** * @brief Get origin position in stage coordinates * @return Origin position vector in stage frame */ - virtual Vector3d get_origin_stage() const = 0; + virtual glm::dvec3 get_origin_stage() const = 0; /** * @brief Get origin position in global coordinates * @return Origin position vector in global frame */ - virtual Vector3d get_origin_global() const = 0; + virtual glm::dvec3 get_origin_global() const = 0; /** * @brief Set origin position (always relative to reference coordinates) * @param origin New origin position vector */ - virtual void set_origin(const Vector3d &) = 0; + virtual void set_origin(const glm::dvec3 &) = 0; /** * @brief Set origin position (always relative to reference coordinates) @@ -142,36 +145,36 @@ class Element */ virtual void set_origin(double, double, double) = 0; - // virtual const Vector3d &get_global_origin() const = 0; - // virtual void set_global_origin(const Vector3d &) = 0; + // virtual const glm::dvec3 &get_global_origin() const = 0; + // virtual void set_global_origin(const glm::dvec3 &) = 0; /** * @brief Get aim vector in reference coordinates * @return Aim direction vector in reference frame */ - virtual Vector3d get_aim_vector_ref() const = 0; - virtual Vector3d get_aim_vector_stage() const = 0; - virtual Vector3d get_aim_vector_global() const = 0; + virtual glm::dvec3 get_aim_vector_ref() const = 0; + virtual glm::dvec3 get_aim_vector_stage() const = 0; + virtual glm::dvec3 get_aim_vector_global() const = 0; // Always the aim vector with respect the reference coordinates - virtual void set_aim_vector(const Vector3d &) = 0; + virtual void set_aim_vector(const glm::dvec3 &) = 0; virtual void set_aim_vector(double, double, double) = 0; // Always the Euler angles with respect the reference coordinates - virtual const Vector3d &get_euler_angles() const = 0; + virtual const glm::dvec3 &get_euler_angles() const = 0; // Always the ZRot with respect to the reference coordinates virtual double get_zrot() const = 0; virtual void set_zrot(double) = 0; virtual double get_zrot_radians() const = 0; virtual void set_zrot_radians(double) = 0; - virtual Matrix3d get_reference_to_local() const = 0; - virtual Matrix3d get_stage_to_local() const = 0; - virtual Matrix3d get_global_to_local() const = 0; - virtual Matrix3d get_local_to_reference() const = 0; - virtual Matrix3d get_local_to_stage() const = 0; - virtual Matrix3d get_local_to_global() const = 0; + virtual glm::dmat3 get_reference_to_local() const = 0; + virtual glm::dmat3 get_stage_to_local() const = 0; + virtual glm::dmat3 get_global_to_local() const = 0; + virtual glm::dmat3 get_local_to_reference() const = 0; + virtual glm::dmat3 get_local_to_stage() const = 0; + virtual glm::dmat3 get_local_to_global() const = 0; - // virtual const Vector3d &get_upper_bounding_box() const = 0; - // virtual const Vector3d &get_lower_bounding_box() const = 0; + // virtual const glm::dvec3 &get_upper_bounding_box() const = 0; + // virtual const glm::dvec3 &get_lower_bounding_box() const = 0; // Accessors for SingleElements virtual const aperture_ptr get_aperture() const = 0; @@ -200,8 +203,8 @@ class Element // virtual bool is_at_end(ElementContainer::const_iterator iter) = 0; // Coordinate transformation routines - virtual int set_reference_frame_geometry(const Vector3d &origin, - const Vector3d &aim, + virtual int set_reference_frame_geometry(const glm::dvec3 &origin, + const glm::dvec3 &aim, double zrot) = 0; /**************************************************************** @@ -212,30 +215,30 @@ class Element ****************************************************************/ // Convert `ref` to local coordinates and store the result in `local` - virtual int convert_reference_to_local(Vector3d &local, - const Vector3d &ref) = 0; + virtual int convert_reference_to_local(glm::dvec3 &local, + const glm::dvec3 &ref) = 0; // Convert `stage` to local coordinates and store the result in `local` - virtual int convert_stage_to_local(Vector3d &local, - const Vector3d &stage) = 0; + virtual int convert_stage_to_local(glm::dvec3 &local, + const glm::dvec3 &stage) = 0; // Convert `global` to local coordinates and store the result in `local` - virtual int convert_global_to_local(Vector3d &local, - const Vector3d &global) = 0; + virtual int convert_global_to_local(glm::dvec3 &local, + const glm::dvec3 &global) = 0; // Convert `local` to reference coordinates and store the result in `ref` - virtual int convert_local_to_reference(Vector3d &ref, - const Vector3d &local) = 0; + virtual int convert_local_to_reference(glm::dvec3 &ref, + const glm::dvec3 &local) = 0; // Convert `local` to stage coordinates and store the result in `stage` - virtual int convert_local_to_stage(Vector3d &stage, - const Vector3d &local) = 0; + virtual int convert_local_to_stage(glm::dvec3 &stage, + const glm::dvec3 &local) = 0; // Convert `local` to global coordinates and store the result in `global` - virtual int convert_local_to_global(Vector3d &global, - const Vector3d &local) = 0; + virtual int convert_local_to_global(glm::dvec3 &global, + const glm::dvec3 &local) = 0; // Convert global coordinates to reference coordinates - virtual int convert_global_to_reference(Vector3d &ref, - const Vector3d &global) = 0; + virtual int convert_global_to_reference(glm::dvec3 &ref, + const glm::dvec3 &global) = 0; // Convert reference coordinates to global - virtual int convert_reference_to_global(Vector3d &global, - const Vector3d &ref) = 0; + virtual int convert_reference_to_global(glm::dvec3 &global, + const glm::dvec3 &ref) = 0; /**************************************************************** * These are vector coordinate conversion routines. They convert a @@ -245,30 +248,30 @@ class Element ****************************************************************/ // Convert `ref` to local coordinates and store the result in `local` - virtual int convert_vector_reference_to_local(Vector3d &local, - const Vector3d &ref) = 0; + virtual int convert_vector_reference_to_local(glm::dvec3 &local, + const glm::dvec3 &ref) = 0; // Convert `stage` to local coordinates and store the result in `local` - virtual int convert_vector_stage_to_local(Vector3d &local, - const Vector3d &stage) = 0; + virtual int convert_vector_stage_to_local(glm::dvec3 &local, + const glm::dvec3 &stage) = 0; // Convert `global` to local coordinates and store the result in `local` - virtual int convert_vector_global_to_local(Vector3d &local, - const Vector3d &global) = 0; + virtual int convert_vector_global_to_local(glm::dvec3 &local, + const glm::dvec3 &global) = 0; // Convert `local` to reference coordinates and store the result in `ref` - virtual int convert_vector_local_to_reference(Vector3d &ref, - const Vector3d &local) = 0; + virtual int convert_vector_local_to_reference(glm::dvec3 &ref, + const glm::dvec3 &local) = 0; // Convert `local` to stage coordinates and store the result in `stage` - virtual int convert_vector_local_to_stage(Vector3d &stage, - const Vector3d &local) = 0; + virtual int convert_vector_local_to_stage(glm::dvec3 &stage, + const glm::dvec3 &local) = 0; // Convert `local` to global coordinates and store the result in `global` - virtual int convert_vector_local_to_global(Vector3d &global, - const Vector3d &local) = 0; + virtual int convert_vector_local_to_global(glm::dvec3 &global, + const glm::dvec3 &local) = 0; // Convert global coordinates to reference coordinates - virtual int convert_vector_global_to_reference(Vector3d &ref, - const Vector3d &global) = 0; + virtual int convert_vector_global_to_reference(glm::dvec3 &ref, + const glm::dvec3 &global) = 0; // Convert reference coordinates to global - virtual int convert_vector_reference_to_global(Vector3d &global, - const Vector3d &ref) = 0; + virtual int convert_vector_reference_to_global(glm::dvec3 &global, + const glm::dvec3 &ref) = 0; // Other routines // Computes necessary coordinate transformation data. Expects @@ -287,10 +290,10 @@ class Element // WARNING: The below Accessors should be used with care. They set // values that are set automatically -- these are here just in case... - virtual void set_euler_angles(const Vector3d &) = 0; + virtual void set_euler_angles(const glm::dvec3 &) = 0; virtual void set_euler_angles(double, double, double) = 0; - virtual void set_reference_to_local(const Matrix3d &) = 0; - virtual void set_local_to_reference(const Matrix3d &) = 0; + virtual void set_reference_to_local(const glm::dmat3 &) = 0; + virtual void set_local_to_reference(const glm::dmat3 &) = 0; // Check that all required fields have been set virtual void enforce_user_fields_set() const = 0; @@ -313,7 +316,7 @@ class ElementBase : public Element { public: ElementBase(); - // ElementBase(const Vector3d &origin, const Vector3d &aim); + // ElementBase(const glm::dvec3 &origin, const glm::dvec3 &aim); ElementBase(const nlohmann::ordered_json& jnode); virtual ~ElementBase(); @@ -363,10 +366,10 @@ class ElementBase : public Element this->my_name = name; } - virtual Vector3d get_origin_ref() const override { return this->origin; } - virtual Vector3d get_origin_stage() const override; - virtual Vector3d get_origin_global() const override; - virtual void set_origin(const Vector3d &point) override + virtual glm::dvec3 get_origin_ref() const override { return this->origin; } + virtual glm::dvec3 get_origin_stage() const override; + virtual glm::dvec3 get_origin_global() const override; + virtual void set_origin(const glm::dvec3 &point) override { this->coordinates_initialized = false; this->origin = point; @@ -375,13 +378,13 @@ class ElementBase : public Element virtual void set_origin(double x, double y, double z) override { this->coordinates_initialized = false; - this->origin.set_values(x, y, z); + this->origin = {x, y, z}; return; } - virtual Vector3d get_aim_vector_ref() const override { return this->aim; } - virtual Vector3d get_aim_vector_stage() const override; - virtual Vector3d get_aim_vector_global() const override; - virtual void set_aim_vector(const Vector3d &direction) override + virtual glm::dvec3 get_aim_vector_ref() const override { return this->aim; } + virtual glm::dvec3 get_aim_vector_stage() const override; + virtual glm::dvec3 get_aim_vector_global() const override; + virtual void set_aim_vector(const glm::dvec3 &direction) override { this->coordinates_initialized = false; this->aim = direction; @@ -390,14 +393,14 @@ class ElementBase : public Element virtual void set_aim_vector(double x, double y, double z) override { this->coordinates_initialized = false; - this->aim.set_values(x, y, z); + this->aim = {x, y, z}; return; } - virtual const Vector3d &get_euler_angles() const override + virtual const glm::dvec3 &get_euler_angles() const override { return this->euler_angles; } - // virtual void set_euler_angles(const Vector3d &angles) + // virtual void set_euler_angles(const glm::dvec3 &angles) // { // this->euler_angles = angles; // return; @@ -421,85 +424,85 @@ class ElementBase : public Element return; } - virtual Matrix3d get_reference_to_local() const override; - virtual Matrix3d get_stage_to_local() const override; - virtual Matrix3d get_global_to_local() const override; - virtual Matrix3d get_local_to_reference() const override; - virtual Matrix3d get_local_to_stage() const override; - virtual Matrix3d get_local_to_global() const override; + virtual glm::dmat3 get_reference_to_local() const override; + virtual glm::dmat3 get_stage_to_local() const override; + virtual glm::dmat3 get_global_to_local() const override; + virtual glm::dmat3 get_local_to_reference() const override; + virtual glm::dmat3 get_local_to_stage() const override; + virtual glm::dmat3 get_local_to_global() const override; virtual int compute_coordinate_rotations() override; - virtual int set_reference_frame_geometry(const Vector3d &origin, - const Vector3d &aim, + virtual int set_reference_frame_geometry(const glm::dvec3 &origin, + const glm::dvec3 &aim, double zrot) override; // Convert `ref` to local coordinates and store the result in `local` - virtual int convert_reference_to_local(Vector3d &local, - const Vector3d &ref) override; + virtual int convert_reference_to_local(glm::dvec3 &local, + const glm::dvec3 &ref) override; // Convert `stage` to local coordinates and store the result in `local` - virtual int convert_stage_to_local(Vector3d &local, - const Vector3d &stage) override; + virtual int convert_stage_to_local(glm::dvec3 &local, + const glm::dvec3 &stage) override; // Convert `global` to local coordinates and store the result in `local` - virtual int convert_global_to_local(Vector3d &local, - const Vector3d &global) override; + virtual int convert_global_to_local(glm::dvec3 &local, + const glm::dvec3 &global) override; // Convert `local` to reference coordinates and store the result in `ref` - virtual int convert_local_to_reference(Vector3d &ref, - const Vector3d &local) override; + virtual int convert_local_to_reference(glm::dvec3 &ref, + const glm::dvec3 &local) override; // Convert `local` to stage coordinates and store the result in `stage` - virtual int convert_local_to_stage(Vector3d &stage, - const Vector3d &local) override; + virtual int convert_local_to_stage(glm::dvec3 &stage, + const glm::dvec3 &local) override; // Convert `local` to global coordinates and store the result in `global` - virtual int convert_local_to_global(Vector3d &global, - const Vector3d &local) override; + virtual int convert_local_to_global(glm::dvec3 &global, + const glm::dvec3 &local) override; // Convert global coordinates to reference coordinates - virtual int convert_global_to_reference(Vector3d &ref, - const Vector3d &global) override; + virtual int convert_global_to_reference(glm::dvec3 &ref, + const glm::dvec3 &global) override; // Convert reference coordinates to global - virtual int convert_reference_to_global(Vector3d &global, - const Vector3d &ref) override; + virtual int convert_reference_to_global(glm::dvec3 &global, + const glm::dvec3 &ref) override; // Convert `ref` to local coordinates and store the result in `local` - virtual int convert_vector_reference_to_local(Vector3d &local, - const Vector3d &ref) override; + virtual int convert_vector_reference_to_local(glm::dvec3 &local, + const glm::dvec3 &ref) override; // Convert `stage` to local coordinates and store the result in `local` - virtual int convert_vector_stage_to_local(Vector3d &local, - const Vector3d &stage) override; + virtual int convert_vector_stage_to_local(glm::dvec3 &local, + const glm::dvec3 &stage) override; // Convert `global` to local coordinates and store the result in `local` - virtual int convert_vector_global_to_local(Vector3d &local, - const Vector3d &global) override; + virtual int convert_vector_global_to_local(glm::dvec3 &local, + const glm::dvec3 &global) override; // Convert `local` to reference coordinates and store the result in `ref` - virtual int convert_vector_local_to_reference(Vector3d &ref, - const Vector3d &local) override; + virtual int convert_vector_local_to_reference(glm::dvec3 &ref, + const glm::dvec3 &local) override; // Convert `local` to stage coordinates and store the result in `stage` - virtual int convert_vector_local_to_stage(Vector3d &stage, - const Vector3d &local) override; + virtual int convert_vector_local_to_stage(glm::dvec3 &stage, + const glm::dvec3 &local) override; // Convert `local` to global coordinates and store the result in `global` - virtual int convert_vector_local_to_global(Vector3d &global, - const Vector3d &local) override; + virtual int convert_vector_local_to_global(glm::dvec3 &global, + const glm::dvec3 &local) override; // Convert global coordinates to reference coordinates - virtual int convert_vector_global_to_reference(Vector3d &ref, - const Vector3d &global) override; + virtual int convert_vector_global_to_reference(glm::dvec3 &ref, + const glm::dvec3 &global) override; // Convert reference coordinates to global - virtual int convert_vector_reference_to_global(Vector3d &global, - const Vector3d &ref) override; + virtual int convert_vector_reference_to_global(glm::dvec3 &global, + const glm::dvec3 &ref) override; // WARNING: The below Accessors should be used with care. They set // values that are set automatically -- these are here just in case... - virtual void set_euler_angles(const Vector3d &ea) override + virtual void set_euler_angles(const glm::dvec3 &ea) override { this->euler_angles = ea; } virtual void set_euler_angles(double alpha, double beta, double gamma) override { - this->euler_angles.set_values(alpha, beta, gamma); + this->euler_angles = {alpha, beta, gamma}; } - virtual void set_reference_to_local(const Matrix3d &rtol) override + virtual void set_reference_to_local(const glm::dmat3 &rtol) override { this->reference_to_local = rtol; } - virtual void set_local_to_reference(const Matrix3d <or) override + virtual void set_local_to_reference(const glm::dmat3 <or) override { this->local_to_reference = ltor; } @@ -525,16 +528,16 @@ class ElementBase : public Element std::string my_name; // Location of the origin in the reference coordinate system - Vector3d origin; + glm::dvec3 origin; // Aim vector of element--aligns with the local (positive) z-axis - Vector3d aim; + glm::dvec3 aim; // Rotation about the aim vector to set local x and y axes in degrees (ugh!) double zrot; - Vector3d euler_angles; + glm::dvec3 euler_angles; - Matrix3d reference_to_local; - Matrix3d local_to_reference; + glm::dmat3 reference_to_local; + glm::dmat3 local_to_reference; // element_ptr reference_element; Element *reference_element; // todo: this is a raw pointer, probably shouldn't be diff --git a/coretrace/simulation_data/json_helpers.hpp b/coretrace/simulation_data/json_helpers.hpp index 26ff7e75..b42db749 100644 --- a/coretrace/simulation_data/json_helpers.hpp +++ b/coretrace/simulation_data/json_helpers.hpp @@ -15,6 +15,9 @@ #include +#include +#include + namespace SolTrace::Data { const std::string kSchemaVersion = "2025.11.12"; @@ -30,6 +33,17 @@ namespace SolTrace::Data { return jval; } + inline + std::array to_array(glm::dvec3 v) + { + return {v.x, v.y, v.z}; + } + + inline + glm::dvec3 from_array(std::array array) + { + return {array[0], array[1], array[2]}; + } } // namespace SolTrace::Data diff --git a/coretrace/simulation_data/matvec.cpp b/coretrace/simulation_data/matvec.cpp index fd4e961e..3dd7d212 100644 --- a/coretrace/simulation_data/matvec.cpp +++ b/coretrace/simulation_data/matvec.cpp @@ -280,6 +280,98 @@ namespace SolTrace::Data MatrixTranspose(RRefToLoc, 3, RLocToRef); } + void TransformToLocal(const glm::dvec3& PosRef, + const glm::dvec3& CosRef, + const glm::dvec3& Origin, + const glm::dmat3& RRefToLoc, + glm::dvec3& PosLoc, + glm::dvec3& CosLoc) + { + /*{Multiply the position vector and the direction cosine vector by the transformation + matrix to get the new vectors in the local system. The position vector is first + referenced to the origin of the local frame.}*/ + glm::dvec3 PosDum = PosRef - Origin; + + PosLoc = RRefToLoc * PosDum; + CosLoc = RRefToLoc * CosRef; + } + + void TransformToReference(const glm::dvec3& PosLoc, + const glm::dvec3& CosLoc, + const glm::dvec3& Origin, + const glm::dmat3& RLocToRef, + glm::dvec3& PosRef, + glm::dvec3& CosRef) + { + /*{Purpose: To perform coordinate transformation from local system to reference + system. + Input - + PosLoc = X,Y,Z coordinates of ray point in local system + CosLoc = Direction cosines of ray in Loc system + Origin = X,Y,Z coordinates of origin of local system as measured + in reference system + RLocToRef = Rotation matrices required for coordinate transform + from local to reference (inverse of reference to + local transformation) + Output - + PosRef = X,Y,Z coordinates of ray point in reference system + CosRef = Direction cosines of ray in reference system}*/ + + /*{Use previously calculated RLocToRef matrix (in TransformToLocal) to obtain the + inverse transformation back to Reference system.}*/ + + glm::dvec3 PosDum = RLocToRef * PosLoc; + CosRef = RLocToRef * CosLoc; + + PosRef = PosDum + Origin; + } + + void CalculateTransformMatrices(const glm::dvec3& Euler, + glm::dmat3& RRefToLoc, + glm::dmat3& RLocToRef) + { + /*{input: Euler = Euler angles + output: RRefToLoc = Transformation matrix from Reference to Local system + RLocToRef = "" "" "" Local to Reference system (transpose of above)} */ + double Alpha = 0.0; + double Beta = 0.0; + double Gamma = 0.0; + double CosAlpha = 0.0; + double CosBeta = 0.0; + double CosGamma = 0.0; + double SinAlpha = 0.0; + double SinBeta = 0.0; + double SinGamma = 0.0; + + /*{Offload Alpha, Beta and Gamma: the three Euler rotations from Ref frame to Local + frame. Also calculate their cosines.}*/ + Alpha = Euler.x; + Beta = Euler.y; + Gamma = Euler.z; + CosAlpha = cos(Alpha); + CosBeta = cos(Beta); + CosGamma = cos(Gamma); + SinAlpha = sin(Alpha); + SinBeta = sin(Beta); + SinGamma = sin(Gamma); + + /*{Fill in elements of the transformation matrix as per Spencer and Murty paper + page 673 equation (2)}*/ + RRefToLoc[0][0] = CosAlpha * CosGamma + SinAlpha * SinBeta * SinGamma; + RRefToLoc[0][1] = -CosBeta * SinGamma; + RRefToLoc[0][2] = -SinAlpha * CosGamma + CosAlpha * SinBeta * SinGamma; + RRefToLoc[1][0] = CosAlpha * SinGamma - SinAlpha * SinBeta * CosGamma; + RRefToLoc[1][1] = CosBeta * CosGamma; + RRefToLoc[1][2] = -SinAlpha * SinGamma - CosAlpha * SinBeta * CosGamma; + RRefToLoc[2][0] = SinAlpha * CosBeta; + RRefToLoc[2][1] = SinBeta; + RRefToLoc[2][2] = CosAlpha * CosBeta; + + /*{Transpose the matrix to get the inverse transformation matrix for going back + to reference system. This is used by the TransformToReference procedure.}*/ + RLocToRef = glm::transpose(RRefToLoc); + } + // void AddVec3(double a, const double x[3], // double b, double y[3]) // { diff --git a/coretrace/simulation_data/matvec.hpp b/coretrace/simulation_data/matvec.hpp index 1562a0ee..4d2b79e1 100644 --- a/coretrace/simulation_data/matvec.hpp +++ b/coretrace/simulation_data/matvec.hpp @@ -64,6 +64,9 @@ #include #include +#include +#include + namespace SolTrace::Data { @@ -97,6 +100,25 @@ namespace SolTrace::Data double RRefToLoc[3][3], double RLocToRef[3][3]); + void TransformToLocal(const glm::dvec3& PosRef, + const glm::dvec3& CosRef, + const glm::dvec3& Origin, + const glm::dmat3& RRefToLoc, + glm::dvec3& PosLoc, + glm::dvec3& CosLoc); + + void TransformToReference(const glm::dvec3& PosLoc, + const glm::dvec3& CosLoc, + const glm::dvec3& Origin, + const glm::dmat3& RLocToRef, + glm::dvec3& PosRef, + glm::dvec3& CosRef); + + void CalculateTransformMatrices(const glm::dvec3& Euler, + glm::dmat3& RRefToLoc, + glm::dmat3& RLocToRef); + + // inline void CopyVec3(double dest[3], const std::vector &src); // inline void CopyVec3(std::vector &dest, const double src[3]); // inline void CopyVec3(double dest[3], const double src[3]); diff --git a/coretrace/simulation_data/ray_source.hpp b/coretrace/simulation_data/ray_source.hpp index d8bef9fa..5387499e 100644 --- a/coretrace/simulation_data/ray_source.hpp +++ b/coretrace/simulation_data/ray_source.hpp @@ -14,9 +14,11 @@ #include #include +#include + #include "container.hpp" #include "datetime.hpp" -#include "vector3d.hpp" + namespace SolTrace::Data { @@ -47,9 +49,9 @@ class RaySource RaySource() {} virtual ~RaySource() {} - virtual const Vector3d &get_position() const = 0; - virtual Vector3d &get_position() = 0; - virtual void set_position(const Vector3d &) = 0; + virtual const glm::dvec3 &get_position() const = 0; + virtual glm::dvec3 &get_position() = 0; + virtual void set_position(const glm::dvec3 &) = 0; virtual void set_position(double, double, double) = 0; virtual void set_position(const DateTime &, double lat, double long) = 0; virtual SunShape get_shape() const = 0; diff --git a/coretrace/simulation_data/simdata_io.cpp b/coretrace/simulation_data/simdata_io.cpp index da3a1bf5..8876ebc4 100644 --- a/coretrace/simulation_data/simdata_io.cpp +++ b/coretrace/simulation_data/simdata_io.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "constants.hpp" @@ -425,14 +426,16 @@ bool read_element( } bool enabled = atoi(tok[0].c_str()) ? 1 : 0; - double xyz[3] = { + glm::dvec3 xyz = { atof(tok[1].c_str()), atof(tok[2].c_str()), - atof(tok[3].c_str())}; - double aim[3] = { + atof(tok[3].c_str()) + }; + glm::dvec3 aim = { atof(tok[4].c_str()), atof(tok[5].c_str()), - atof(tok[6].c_str())}; + atof(tok[6].c_str()) + }; double zrot = atof(tok[7].c_str()); char ShapeIndex = ' '; @@ -531,8 +534,8 @@ bool read_element( } // Set element position and orientation - el->set_reference_frame_geometry(Vector3d(xyz), - Vector3d(aim), + el->set_reference_frame_geometry(glm::dvec3(xyz), + glm::dvec3(aim), zrot); // Set optical properties @@ -743,8 +746,8 @@ void write_json_file(SimulationData& sd, std::string filename) jsrc["user_angle"] = user_angle; // vector jsrc["user_intensity"] = user_intensity; // vector - Vector3d pos = sun_ptr->get_position(); - jsrc["pos"] = pos.data; + glm::dvec3 pos = sun_ptr->get_position(); + jsrc["pos"] = to_array(pos); } else { @@ -849,7 +852,7 @@ void load_json_file(SimulationData& sd, std::string filename) std::vector user_intensity = jsrc.at("user_intensity"); std::array pos_arr = jsrc.at("pos").get>(); - Vector3d pos_vec(pos_arr.data()); + glm::dvec3 pos_vec = from_array(pos_arr); // Make sun for simulation data auto sun = make_ray_source(); diff --git a/coretrace/simulation_data/simulation_data_api.hpp b/coretrace/simulation_data/simulation_data_api.hpp index 1130e746..192b7280 100644 --- a/coretrace/simulation_data/simulation_data_api.hpp +++ b/coretrace/simulation_data/simulation_data_api.hpp @@ -11,9 +11,8 @@ #include "stage_element.hpp" #include "sun.hpp" #include "surface.hpp" -#include "vector3d.hpp" #include "virtual_element.hpp" - +#include "matvec.hpp" #include "cst_templates/heliostat.hpp" #include "cst_templates/linear_fresnel.hpp" #include "cst_templates/parabolic_dish.hpp" diff --git a/coretrace/simulation_data/simulation_data_export.hpp b/coretrace/simulation_data/simulation_data_export.hpp index a6bd03db..e336ed92 100644 --- a/coretrace/simulation_data/simulation_data_export.hpp +++ b/coretrace/simulation_data/simulation_data_export.hpp @@ -17,7 +17,6 @@ using SolTrace::Data::Hexagon; using SolTrace::Data::InteractionType; using SolTrace::Data::IrregularQuadrilateral; using SolTrace::Data::IrregularTriangle; -using SolTrace::Data::Matrix3d; using SolTrace::Data::OpticalProperties; using SolTrace::Data::Parabola; using SolTrace::Data::Rectangle; @@ -31,7 +30,6 @@ using SolTrace::Data::Sun; using SolTrace::Data::SolarPositionCalculator; using SolTrace::Data::Surface; using SolTrace::Data::SurfaceType; -using SolTrace::Data::Vector3d; using SolTrace::Data::VirtualElement; using SolTrace::Data::VirtualPlane; @@ -59,13 +57,6 @@ using SolTrace::Data::make_surface; using SolTrace::Data::make_surface_from_type; // Matrix-Vector Functions -using SolTrace::Data::dot_product; -using SolTrace::Data::matrix_copy; -using SolTrace::Data::matrix_matrix_product; -using SolTrace::Data::matrix_vector_product; -using SolTrace::Data::vector_add; -using SolTrace::Data::vector_copy; -using SolTrace::Data::vector_norm; using SolTrace::Data::AddVec3; using SolTrace::Data::CopyVec3; using SolTrace::Data::DOT; @@ -73,11 +64,6 @@ using SolTrace::Data::IdentityMat3; using SolTrace::Data::SetVec3; using SolTrace::Data::ZeroVec3; -// Coordinate Transform Functions -using SolTrace::Data::CalculateTransformMatrices; -using SolTrace::Data::TransformToLocal; -using SolTrace::Data::TransformToReference; - // Status Constants using SolTrace::Data::ELEMENT_ERROR; using SolTrace::Data::ELEMENT_ID_UNASSIGNED; diff --git a/coretrace/simulation_data/single_element.cpp b/coretrace/simulation_data/single_element.cpp index 228b8930..7afba808 100644 --- a/coretrace/simulation_data/single_element.cpp +++ b/coretrace/simulation_data/single_element.cpp @@ -7,7 +7,6 @@ #include "aperture.hpp" #include "element.hpp" -#include "vector3d.hpp" namespace SolTrace::Data { diff --git a/coretrace/simulation_data/sun.hpp b/coretrace/simulation_data/sun.hpp index f2d3efba..5926311c 100644 --- a/coretrace/simulation_data/sun.hpp +++ b/coretrace/simulation_data/sun.hpp @@ -13,7 +13,8 @@ #include "ray_source.hpp" #include "datetime.hpp" -#include "vector3d.hpp" + +#include namespace SolTrace::Data { @@ -21,28 +22,25 @@ class Sun : public RaySource { public: Sun() : my_shape(SunShape::UNKNOWN), - my_position(Vector3d(std::numeric_limits::quiet_NaN(), - std::numeric_limits::quiet_NaN(), - std::numeric_limits::quiet_NaN())) - { this->my_position.zero(); } + my_position(0.0) {} virtual ~Sun() {} - virtual const Vector3d &get_position() const + virtual const glm::dvec3 &get_position() const { return this->my_position; } - virtual Vector3d &get_position() + virtual glm::dvec3 &get_position() { return this->my_position; } - virtual void set_position(const Vector3d &pos) + virtual void set_position(const glm::dvec3 &pos) { this->my_position = pos; return; } virtual void set_position(double x, double y, double z) { - this->my_position.set_values(x, y, z); + this->my_position = glm::dvec3(x, y, z); return; } virtual void set_position(const DateTime &, double lat, double long) {} @@ -66,7 +64,7 @@ class Sun : public RaySource std::vector _user_intensity); SunShape my_shape; - Vector3d my_position; + glm::dvec3 my_position; }; } // namespace SolTrace::Data diff --git a/coretrace/simulation_data/vector3d.cpp b/coretrace/simulation_data/vector3d.cpp index 539f4093..001b0143 100644 --- a/coretrace/simulation_data/vector3d.cpp +++ b/coretrace/simulation_data/vector3d.cpp @@ -1,59 +1,60 @@ - -#include "vector3d.hpp" +#include "glm::dvec3.hpp" // #include #include #include +#if 0 + #include "matvec.hpp" namespace SolTrace::Data { - // inline void vector_copy(double data[3], const Vector3d &x) + // inline void vector_copy(double data[3], const glm::dvec3 &x) // { // CopyVec3(data, x.data); // return; // } - // inline void vector_copy(std::vector &dest, const Vector3d &x) + // inline void vector_copy(std::vector &dest, const glm::dvec3 &x) // { // CopyVec3(dest, x.data); // return; // } - Vector3d::Vector3d() + glm::dvec3::glm::dvec3() { this->zero(); return; } - Vector3d::Vector3d(const double data[3]) + glm::dvec3::glm::dvec3(const double data[3]) { for (int i = 0; i < 3; ++i) this->data[i] = data[i]; return; } - Vector3d::Vector3d(double x, double y, double z) + glm::dvec3::glm::dvec3(double x, double y, double z) { this->data[0] = x; this->data[1] = y; this->data[2] = z; return; } - Vector3d::~Vector3d() + glm::dvec3::~glm::dvec3() { return; } - void Vector3d::zero() + void glm::dvec3::zero() { for (int i = 0; i < 3; ++i) this->data[i] = 0.0; return; } - void Vector3d::set_values(double x, double y, double z) + void glm::dvec3::set_values(double x, double y, double z) { this->data[0] = x; this->data[1] = y; @@ -61,37 +62,37 @@ namespace SolTrace::Data return; } - void Vector3d::scalar_mult(double alpha) + void glm::dvec3::scalar_mult(double alpha) { for (int i = 0; i < 3; ++i) this->data[i] *= alpha; return; } - void Vector3d::make_unit() + void glm::dvec3::make_unit() { make_unit_vector(*this); return; } - double Vector3d::norm() const + double glm::dvec3::norm() const { return vector_norm(*this); } - const double &Vector3d::operator[](int idx) const + const double &glm::dvec3::operator[](int idx) const { assert(idx >= 0 && idx < 3); return this->data[idx]; } - double &Vector3d::operator[](int idx) + double &glm::dvec3::operator[](int idx) { assert(idx >= 0 && idx < 3); return this->data[idx]; } - std::ostream &operator<<(std::ostream &os, const Vector3d &x) + std::ostream &operator<<(std::ostream &os, const glm::dvec3 &x) { os << "[" << x.data[0] << ", " << x.data[1] << ", " @@ -170,7 +171,7 @@ namespace SolTrace::Data } // Compute y = A*x placing the result in y - void matrix_vector_product(const Matrix3d &A, const Vector3d &x, Vector3d &y) + void matrix_vector_product(const Matrix3d &A, const glm::dvec3 &x, glm::dvec3 &y) { MatrixVectorMult(A.data, x.data, y.data); return; @@ -182,9 +183,9 @@ namespace SolTrace::Data return; } - void vector_add(double a, const Vector3d &x, - double b, const Vector3d &y, - Vector3d &z) + void vector_add(double a, const glm::dvec3 &x, + double b, const glm::dvec3 &y, + glm::dvec3 &z) { for (int i = 0; i < 3; ++i) { @@ -193,8 +194,8 @@ namespace SolTrace::Data return; } - void vector_add(double a, const Vector3d &x, - double b, Vector3d &y) + void vector_add(double a, const glm::dvec3 &x, + double b, glm::dvec3 &y) { for (int i = 0; i < 3; ++i) { @@ -203,7 +204,7 @@ namespace SolTrace::Data return; } - void vector_max(const Vector3d &x, const Vector3d &y, Vector3d &max) + void vector_max(const glm::dvec3 &x, const glm::dvec3 &y, glm::dvec3 &max) { for (int i = 0; i < 3; ++i) { @@ -212,7 +213,7 @@ namespace SolTrace::Data return; } - void vector_min(const Vector3d &x, const Vector3d &y, Vector3d &min) + void vector_min(const glm::dvec3 &x, const glm::dvec3 &y, glm::dvec3 &min) { for (int i = 0; i < 3; ++i) { @@ -222,12 +223,12 @@ namespace SolTrace::Data } // Compute standard Euclidean dot product - double dot_product(const Vector3d &x, const Vector3d &y) + double dot_product(const glm::dvec3 &x, const glm::dvec3 &y) { return DOT(x.data, y.data); } - void cross_product(const Vector3d &u, const Vector3d &v, Vector3d &w) + void cross_product(const glm::dvec3 &u, const glm::dvec3 &v, glm::dvec3 &w) { double w0 = u[1] * v[2] - u[2] * v[1]; double w1 = u[2] * v[0] - u[0] * v[2]; @@ -236,7 +237,7 @@ namespace SolTrace::Data return; } - double error(const Vector3d &u, const Vector3d &v) + double error(const glm::dvec3 &u, const glm::dvec3 &v) { double err = 0.0; double dx; @@ -248,7 +249,7 @@ namespace SolTrace::Data return sqrt(err); } - double error_inf(const Vector3d &u, const Vector3d &v) + double error_inf(const glm::dvec3 &u, const glm::dvec3 &v) { double err = 0.0; for (int i = 0; i < 3; ++i) @@ -258,12 +259,12 @@ namespace SolTrace::Data return err; } - double vector_norm(const Vector3d &x) + double vector_norm(const glm::dvec3 &x) { return sqrt(DOT(x.data, x.data)); } - void make_unit_vector(Vector3d &x) + void make_unit_vector(glm::dvec3 &x) { double mag = vector_norm(x); assert(mag > 0.0); @@ -275,12 +276,12 @@ namespace SolTrace::Data return; } - // void transform_to_local(Vector3d &pos_ref, - // Vector3d &cos_ref, - // Vector3d &origin, + // void transform_to_local(glm::dvec3 &pos_ref, + // glm::dvec3 &cos_ref, + // glm::dvec3 &origin, // Matrix3d &ref_to_local, - // Vector3d &pos_local, - // Vector3d &cos_local) + // glm::dvec3 &pos_local, + // glm::dvec3 &cos_local) // { // TransformToLocal(pos_ref.data, cos_ref.data, // origin.data, ref_to_local.data, @@ -288,12 +289,12 @@ namespace SolTrace::Data // return; // } - // void transform_to_reference(Vector3d &pos_local, - // Vector3d &cos_local, - // Vector3d &origin, + // void transform_to_reference(glm::dvec3 &pos_local, + // glm::dvec3 &cos_local, + // glm::dvec3 &origin, // Matrix3d &local_to_ref, - // Vector3d &pos_ref, - // Vector3d &cos_ref) + // glm::dvec3 &pos_ref, + // glm::dvec3 &cos_ref) // { // TransformToReference(pos_local.data, cos_local.data, // origin.data, local_to_ref.data, @@ -301,7 +302,7 @@ namespace SolTrace::Data // return; // } - void compute_transform_matrices(Vector3d &euler, + void compute_transform_matrices(glm::dvec3 &euler, Matrix3d &ref_to_local, Matrix3d &local_to_ref) { @@ -312,3 +313,5 @@ namespace SolTrace::Data } } // namespace SolTrace::Data + +#endif diff --git a/coretrace/simulation_data/vector3d.hpp b/coretrace/simulation_data/vector3d.hpp index 2c500ad1..086682df 100644 --- a/coretrace/simulation_data/vector3d.hpp +++ b/coretrace/simulation_data/vector3d.hpp @@ -1,8 +1,8 @@ /** - * @file vector3d.hpp + * @file glm::dvec3.hpp * @brief 3D vector and matrix classes * - * Provides Vector3d and Matrix3d classes for 3D geometric operations, + * Provides glm::dvec3 and Matrix3d classes for 3D geometric operations, * coordinate transformations, and linear algebra computations. * These classes form the mathematical foundation for ray tracing * calculations and geometric transformations in SolTrace. @@ -11,29 +11,29 @@ * @{ */ -#ifndef SOLTRACE_VECTOR3D_H -#define SOLTRACE_VECTOR3D_H +#ifndef SOLTRACE_glm_vec3 +#define SOLTRACE_glm_vec3 #include #include - +#if 0 #include "matvec.hpp" namespace SolTrace::Data { -class Vector3d +class glm::dvec3 { public: /** * @brief Default constructor - initializes to zero vector */ - Vector3d(); + glm::dvec3(); /** * @brief Constructor from array * @param data Array of 3 doubles [x, y, z] */ - Vector3d(const double data[3]); + glm::dvec3(const double data[3]); /** * @brief Constructor from components @@ -41,8 +41,8 @@ class Vector3d * @param y Y component * @param z Z component */ - Vector3d(double x, double y, double z); - ~Vector3d(); + glm::dvec3(double x, double y, double z); + ~glm::dvec3(); /** * @brief Set all components to zero @@ -94,7 +94,7 @@ class Vector3d * @param x Vector to output * @return Reference to output stream */ - friend std::ostream &operator<<(std::ostream &os, const Vector3d &x); + friend std::ostream &operator<<(std::ostream &os, const glm::dvec3 &x); double data[3]; @@ -144,12 +144,12 @@ class Matrix3d private: }; -inline void vector_copy(double data[3], const Vector3d &x) +inline void vector_copy(double data[3], const glm::dvec3 &x) { CopyVec3(data, x.data); return; } -inline void vector_copy(std::vector &dest, const Vector3d &x) +inline void vector_copy(std::vector &dest, const glm::dvec3 &x) { CopyVec3(dest, x.data); return; @@ -162,14 +162,14 @@ inline void matrix_copy(double data[3][3], const Matrix3d &A) } // Compute y = A*x placing the result in y -void matrix_vector_product(const Matrix3d &A, const Vector3d &x, Vector3d &y); +void matrix_vector_product(const Matrix3d &A, const glm::dvec3 &x, glm::dvec3 &y); // Compute C = A * B placing result in C void matrix_matrix_product(const Matrix3d &A, const Matrix3d &B, Matrix3d &C); // Compute z = a*x + b*y (result stored in z) -void vector_add(double a, const Vector3d &x, - double b, const Vector3d &y, - Vector3d &z); +void vector_add(double a, const glm::dvec3 &x, + double b, const glm::dvec3 &y, + glm::dvec3 &z); /** * @brief Compute linear combination y = a*x + b*y (result stored in y) * @param a Scalar multiplier for vector x @@ -177,8 +177,8 @@ void vector_add(double a, const Vector3d &x, * @param b Scalar multiplier for vector y * @param y Second vector (modified in-place with result) */ -void vector_add(double a, const Vector3d &x, - double b, Vector3d &y); +void vector_add(double a, const glm::dvec3 &x, + double b, glm::dvec3 &y); /** * @brief Compute element-wise maximum of two vectors @@ -186,7 +186,7 @@ void vector_add(double a, const Vector3d &x, * @param y Second vector * @param max Output vector containing element-wise maximum */ -void vector_max(const Vector3d &x, const Vector3d &y, Vector3d &max); +void vector_max(const glm::dvec3 &x, const glm::dvec3 &y, glm::dvec3 &max); /** * @brief Compute element-wise minimum of two vectors @@ -194,7 +194,7 @@ void vector_max(const Vector3d &x, const Vector3d &y, Vector3d &max); * @param y Second vector * @param min Output vector containing element-wise minimum */ -void vector_min(const Vector3d &x, const Vector3d &y, Vector3d &min); +void vector_min(const glm::dvec3 &x, const glm::dvec3 &y, glm::dvec3 &min); /** * @brief Compute standard Euclidean dot product @@ -202,7 +202,7 @@ void vector_min(const Vector3d &x, const Vector3d &y, Vector3d &min); * @param y Second vector * @return Dot product x·y */ -double dot_product(const Vector3d &x, const Vector3d &y); +double dot_product(const glm::dvec3 &x, const glm::dvec3 &y); /** * @brief Compute standard Euclidean cross product @@ -210,35 +210,35 @@ double dot_product(const Vector3d &x, const Vector3d &y); * @param v Second vector * @param w Result vector */ -void cross_product(const Vector3d &u, const Vector3d &v, Vector3d &w); +void cross_product(const glm::dvec3 &u, const glm::dvec3 &v, glm::dvec3 &w); -double error(const Vector3d &u, const Vector3d &v); -double error_inf(const Vector3d &u, const Vector3d &v); +double error(const glm::dvec3 &u, const glm::dvec3 &v); +double error_inf(const glm::dvec3 &u, const glm::dvec3 &v); /** * @brief Compute Euclidean norm (length) of vector * @param x Input vector * @return ||x||₂ (L2 norm) */ -double vector_norm(const Vector3d &x); +double vector_norm(const glm::dvec3 &x); /** * @brief Normalize vector to unit length (modifies vector in-place) * @param x Vector to normalize */ -void make_unit_vector(Vector3d &x); -// void transform_to_local(Vector3d &pos_ref, -// Vector3d &cos_ref, -// Vector3d &origin, +void make_unit_vector(glm::dvec3 &x); +// void transform_to_local(glm::dvec3 &pos_ref, +// glm::dvec3 &cos_ref, +// glm::dvec3 &origin, // Matrix3d &ref_to_local, -// Vector3d &pos_local, -// Vector3d &cos_local); -// void transform_to_reference(Vector3d &pos_local, -// Vector3d &cos_local, -// Vector3d &origin, +// glm::dvec3 &pos_local, +// glm::dvec3 &cos_local); +// void transform_to_reference(glm::dvec3 &pos_local, +// glm::dvec3 &cos_local, +// glm::dvec3 &origin, // Matrix3d &local_to_ref, -// Vector3d &pos_ref, -// Vector3d &cos_ref); +// glm::dvec3 &pos_ref, +// glm::dvec3 &cos_ref); /** * @brief Compute transformation matrices from Euler angles @@ -246,7 +246,7 @@ void make_unit_vector(Vector3d &x); * @param ref_to_local Output matrix for reference-to-local transformation * @param local_to_ref Output matrix for local-to-reference transformation */ -void compute_transform_matrices(Vector3d &euler, +void compute_transform_matrices(glm::dvec3 &euler, Matrix3d &ref_to_local, Matrix3d &local_to_ref); @@ -255,5 +255,6 @@ void compute_transform_matrices(Vector3d &euler, /** * @} */ +#endif #endif diff --git a/coretrace/simulation_data/vector_utility.hpp b/coretrace/simulation_data/vector_utility.hpp new file mode 100644 index 00000000..9fe784da --- /dev/null +++ b/coretrace/simulation_data/vector_utility.hpp @@ -0,0 +1,38 @@ +#pragma once + +#define GLM_ENABLE_EXPERIMENTAL 1 +#include +#include +#include + +#include + +namespace SolTrace::Data { + +inline double error(const glm::dvec3 &u, const glm::dvec3 &v) +{ + double err = 0.0; + double dx; + for (int i = 0; i < 3; ++i) { + dx = u[i] - v[i]; + err += dx * dx; + } + return sqrt(err); +} + +inline double error_inf(const glm::dvec3 &u, const glm::dvec3 &v) +{ + double err = 0.0; + for (int i = 0; i < 3; ++i) { + err = std::max(err, fabs(u[i] - v[i])); + } + return err; +} + +inline void normalize_inplace(glm::dvec3 &v) +{ + assert(glm::length2(v) > 0.0); + v = glm::normalize(v); +} + +} // namespace SolTrace::Data diff --git a/coretrace/simulation_results/simulation_result.cpp b/coretrace/simulation_results/simulation_result.cpp index 92d4f666..9971bc2a 100644 --- a/coretrace/simulation_results/simulation_result.cpp +++ b/coretrace/simulation_results/simulation_result.cpp @@ -1,5 +1,8 @@ #include "simulation_result.hpp" +#define GLM_ENABLE_EXPERIMENTAL 1 +#include + #include #include #include @@ -8,13 +11,11 @@ #include #include "element.hpp" -#include "vector3d.hpp" namespace SolTrace::Result { using element_id = SolTrace::Data::element_id; - using Vector3d = SolTrace::Data::Vector3d; const std::string &ray_event_string(const RayEvent rev) { @@ -32,8 +33,8 @@ namespace SolTrace::Result InteractionRecord::InteractionRecord( element_id el, RayEvent rev, - const Vector3d &location, - const Vector3d &direction) + const glm::dvec3 &location, + const glm::dvec3 &direction) // : index(-1), : element(el), event(rev), @@ -88,28 +89,28 @@ namespace SolTrace::Result return; } - void RayRecord::get_position(const interaction_ptr ip, Vector3d &pos) + void RayRecord::get_position(const interaction_ptr ip, glm::dvec3 &pos) { pos = ip->location; return; } - void RayRecord::get_position(int_fast64_t idx, Vector3d &pos) + void RayRecord::get_position(int_fast64_t idx, glm::dvec3 &pos) { const interaction_ptr ip0 = this->interactions[idx]; return this->get_position(ip0, pos); } void RayRecord::get_direction(const interaction_ptr ip, - Vector3d &cos) + glm::dvec3 &cos) { cos = ip->direction; - make_unit_vector(cos); + cos = glm::normalize(cos); return; } void RayRecord::get_direction(int_fast64_t idx, - Vector3d &cos) + glm::dvec3 &cos) { const interaction_ptr ip0 = this->interactions[idx]; this->get_direction(ip0, cos); diff --git a/coretrace/simulation_results/simulation_result.hpp b/coretrace/simulation_results/simulation_result.hpp index 59c0575b..54cd4027 100644 --- a/coretrace/simulation_results/simulation_result.hpp +++ b/coretrace/simulation_results/simulation_result.hpp @@ -7,8 +7,9 @@ #include #include +#include + #include "element.hpp" -#include "vector3d.hpp" namespace SolTrace::Result { @@ -41,12 +42,12 @@ namespace SolTrace::Result // int_fast64_t index; SolTrace::Data::element_id element; RayEvent event; - SolTrace::Data::Vector3d location; - SolTrace::Data::Vector3d direction; + glm::dvec3 location; + glm::dvec3 direction; InteractionRecord(SolTrace::Data::element_id el, RayEvent rev, - const SolTrace::Data::Vector3d &location, - const SolTrace::Data::Vector3d &direction); + const glm::dvec3 &location, + const glm::dvec3 &direction); InteractionRecord(SolTrace::Data::element_id el, RayEvent rev, double px, double py, double pz, double dx, double dy, double dz); @@ -91,10 +92,10 @@ namespace SolTrace::Result return get_event(this->interactions[idx]); } - void get_position(const interaction_ptr ip, SolTrace::Data::Vector3d &pos); - void get_position(int_fast64_t idx, SolTrace::Data::Vector3d &pos); - void get_direction(const interaction_ptr ip, SolTrace::Data::Vector3d &cos); - void get_direction(int_fast64_t idx, SolTrace::Data::Vector3d &cos); + void get_position(const interaction_ptr ip, glm::dvec3 &pos); + void get_position(int_fast64_t idx, glm::dvec3 &pos); + void get_direction(const interaction_ptr ip, glm::dvec3 &cos); + void get_direction(int_fast64_t idx, glm::dvec3 &cos); uint_fast64_t get_number_of_interactions() { diff --git a/coretrace/simulation_runner/native_runner/cylinder_calculator.cpp b/coretrace/simulation_runner/native_runner/cylinder_calculator.cpp index ddf09f48..d14750e8 100644 --- a/coretrace/simulation_runner/native_runner/cylinder_calculator.cpp +++ b/coretrace/simulation_runner/native_runner/cylinder_calculator.cpp @@ -90,11 +90,11 @@ namespace SolTrace::NativeRunner { } - int CylinderCalculator::intersect(const double PosLoc[3], - const double CosLoc[3], - double PosXYZ[3], - double CosKLM[3], - double DFXYZ[3], + int CylinderCalculator::intersect(const glm::dvec3 PosLoc, + const glm::dvec3 CosLoc, + glm::dvec3& PosXYZ, + glm::dvec3& CosKLM, + glm::dvec3& DFXYZ, double *PathLength) { // std::cout << "Computing cylinder intersection" << std::endl; @@ -110,15 +110,15 @@ namespace SolTrace::NativeRunner double a, b, c; // double y1, y2; - Vector3d p1, p2; + glm::dvec3 p1, p2; c = x0 * x0 + z0 * z0 - 2.0 * z0 * r; b = 2.0 * (x0 * mx + (z0 - r) * mz); a = mx * mx + mz * mz; - ZeroVec3(PosXYZ); - ZeroVec3(CosKLM); - ZeroVec3(DFXYZ); + PosXYZ = {}; + CosKLM = {}; + DFXYZ = {}; if (fabs(a) < 1e-12) { @@ -145,8 +145,8 @@ namespace SolTrace::NativeRunner // y1 = y0 + t1 * my; // y2 = y0 + t2 * my; - AddVec3(1.0, PosLoc, t1, CosLoc, p1.data); - AddVec3(1.0, PosLoc, t2, CosLoc, p2.data); + p1 = PosLoc + t1 * CosLoc; + p2 = PosLoc + t2 * CosLoc; if (t1 > 0.0 && this->aper->is_in(p1[0], p1[1])) { @@ -156,7 +156,7 @@ namespace SolTrace::NativeRunner // SetVec3(PosXYZ, x0 + t1 * mx, y1, z0 + t1 * mz); // AddVec3(1.0, PosLoc, t1, CosLoc, PosXYZ); // this->surface_normal(PosXYZ, DFXYZ); - CopyVec3(PosXYZ, p1.data); + PosXYZ = p1; } else if (t2 > 0.0 && this->aper->is_in(p2[0], p2[1])) { @@ -167,7 +167,7 @@ namespace SolTrace::NativeRunner // SetVec3(PosXYZ, x0 + t2 * mx, y2, z0 + t2 * mz); // AddVec3(1.0, PosLoc, t2, CosLoc, PosXYZ); // this->surface_normal(PosXYZ, DFXYZ); - CopyVec3(PosXYZ, p2.data); + PosXYZ = p2; } else { @@ -181,7 +181,7 @@ namespace SolTrace::NativeRunner if (sts == 0) { - CopyVec3(CosKLM, CosLoc); + CosKLM = CosLoc; this->surface_normal(PosXYZ, DFXYZ); } @@ -190,8 +190,8 @@ namespace SolTrace::NativeRunner return sts; } - void CylinderCalculator::surface_normal(const double PosXYZ[3], - double DFXYZ[3]) + void CylinderCalculator::surface_normal(const glm::dvec3 PosXYZ, + glm::dvec3& DFXYZ) { // TODO: Need to default to returning the surface normal of // whatever is the "front". Is that the inside of the cylinder diff --git a/coretrace/simulation_runner/native_runner/cylinder_calculator.hpp b/coretrace/simulation_runner/native_runner/cylinder_calculator.hpp index 3c2faa35..819bba77 100644 --- a/coretrace/simulation_runner/native_runner/cylinder_calculator.hpp +++ b/coretrace/simulation_runner/native_runner/cylinder_calculator.hpp @@ -13,14 +13,14 @@ class CylinderCalculator : public SurfaceIntersectionCalculator public: CylinderCalculator(SolTrace::Data::surface_ptr surf, SolTrace::Data::aperture_ptr ap); virtual ~CylinderCalculator(); - virtual int intersect(const double PosLoc[3], - const double CosLoc[3], - double PosXYZ[3], - double CosKLM[3], - double DFXYZ[3], + virtual int intersect(const glm::dvec3 PosLoc, + const glm::dvec3 CosLoc, + glm::dvec3 &PosXYZ, + glm::dvec3 &CosKLM, + glm::dvec3 &DFXYZ, double *PathLength); - void surface_normal(const double PosXYZ[3], double DFXYZ[3]); + void surface_normal(const glm::dvec3 PosXYZ, glm::dvec3 &DFXYZ); virtual double compute_z_aperture(SolTrace::Data::aperture_ptr ap); diff --git a/coretrace/simulation_runner/native_runner/determine_element_intersection_new.cpp b/coretrace/simulation_runner/native_runner/determine_element_intersection_new.cpp index 430cbd09..a68874d5 100644 --- a/coretrace/simulation_runner/native_runner/determine_element_intersection_new.cpp +++ b/coretrace/simulation_runner/native_runner/determine_element_intersection_new.cpp @@ -4,17 +4,16 @@ namespace SolTrace::NativeRunner { -void DetermineElementIntersectionNew( - TElement *Element, - double PosRayIn[3], - double CosRayIn[3], - double PosRayOut[3], - double CosRayOut[3], - double DFXYZ[3], - double *PathLength, - int *ErrorFlag, - int *Intercept, - int *BacksideFlag) +void DetermineElementIntersectionNew(TElement *Element, + glm::dvec3 PosRayIn, + glm::dvec3 CosRayIn, + glm::dvec3 &PosRayOut, + glm::dvec3 &CosRayOut, + glm::dvec3 &DFXYZ, + double *PathLength, + int *ErrorFlag, + int *Intercept, + int *BacksideFlag) { // double x, y; @@ -74,7 +73,7 @@ void DetermineElementIntersectionNew( // *BacksideFlag = 0; // } - *BacksideFlag = DOT(CosRayIn, DFXYZ) < 0.0 ? 0 : 1; + *BacksideFlag = glm::dot(CosRayIn, DFXYZ) < 0.0 ? 0 : 1; *Intercept = 1; // if hit on backside of element then slope of surface is reversed diff --git a/coretrace/simulation_runner/native_runner/determine_element_intersection_new.hpp b/coretrace/simulation_runner/native_runner/determine_element_intersection_new.hpp index b1fc9941..50c19601 100644 --- a/coretrace/simulation_runner/native_runner/determine_element_intersection_new.hpp +++ b/coretrace/simulation_runner/native_runner/determine_element_intersection_new.hpp @@ -6,11 +6,11 @@ namespace SolTrace::NativeRunner { void DetermineElementIntersectionNew(TElement *Element, - double PosRayIn[3], - double CosRayIn[3], - double PosRayOut[3], - double CosRayOut[3], - double DFXYZ[3], + glm::dvec3 PosRayIn, + glm::dvec3 CosRayIn, + glm::dvec3& PosRayOut, + glm::dvec3& CosRayOut, + glm::dvec3& DFXYZ, double *PathLength, int *ErrorFlag, int *Intercept, diff --git a/coretrace/simulation_runner/native_runner/find_element_hit.cpp b/coretrace/simulation_runner/native_runner/find_element_hit.cpp index 88a49335..212236d2 100644 --- a/coretrace/simulation_runner/native_runner/find_element_hit.cpp +++ b/coretrace/simulation_runner/native_runner/find_element_hit.cpp @@ -18,19 +18,19 @@ namespace SolTrace::NativeRunner const int nintelements, const std::vector &sunint_elements, const std::vector &reflint_elements, - // ray info - const int RayNumber, - const bool in_multi_hit_loop, - double (&PosRayStage)[3], - double (&CosRayStage)[3], - // outputs - double (&LastPosRaySurfElement)[3], - double (&LastCosRaySurfElement)[3], - double (&LastDFXYZ)[3], - uint_fast64_t &LastElementNumber, - uint_fast64_t &LastRayNumber, - double (&LastPosRaySurfStage)[3], - double (&LastCosRaySurfStage)[3], + // ray info + const int RayNumber, + const bool in_multi_hit_loop, + glm::dvec3 &PosRayStage, + glm::dvec3 &CosRayStage, + // outputs + glm::dvec3 &LastPosRaySurfElement, + glm::dvec3 &LastCosRaySurfElement, + glm::dvec3 &LastDFXYZ, + uint_fast64_t &LastElementNumber, + uint_fast64_t &LastRayNumber, + glm::dvec3 &LastPosRaySurfStage, + glm::dvec3 &LastCosRaySurfStage, int &ErrorFlag, int &LastHitBackSide, bool &StageHit) @@ -39,13 +39,13 @@ namespace SolTrace::NativeRunner double LastPathLength = 1e99; int HitBackSide = 0; int InterceptFlag = 0; - double DFXYZ[3] = {0.0, 0.0, 0.0}; - double PosRayElement[3] = {0.0, 0.0, 0.0}; - double CosRayElement[3] = {0.0, 0.0, 0.0}; - double PosRaySurfStage[3] = {0.0, 0.0, 0.0}; - double CosRaySurfStage[3] = {0.0, 0.0, 0.0}; - double PosRaySurfElement[3] = {0.0, 0.0, 0.0}; - double CosRaySurfElement[3] = {0.0, 0.0, 0.0}; + glm::dvec3 DFXYZ = {0.0, 0.0, 0.0}; + glm::dvec3 PosRayElement = {0.0, 0.0, 0.0}; + glm::dvec3 CosRayElement = {0.0, 0.0, 0.0}; + glm::dvec3 PosRaySurfStage = {0.0, 0.0, 0.0}; + glm::dvec3 CosRaySurfStage = {0.0, 0.0, 0.0}; + glm::dvec3 PosRaySurfElement = {0.0, 0.0, 0.0}; + glm::dvec3 CosRaySurfElement = {0.0, 0.0, 0.0}; StageHit = false; for (uint_fast64_t j = 0; j < nintelements; j++) @@ -78,13 +78,16 @@ namespace SolTrace::NativeRunner // continue; // {Transform ray to element[j] coord system of Stage[i]} - TransformToLocal(PosRayStage, CosRayStage, - Element->Origin, Element->RRefToLoc, - PosRayElement, CosRayElement); + Data::TransformToLocal(PosRayStage, + CosRayStage, + Element->Origin, + Element->RRefToLoc, + PosRayElement, + CosRayElement); - ErrorFlag = 0; - HitBackSide = 0; - InterceptFlag = 0; + ErrorFlag = 0; + HitBackSide = 0; + InterceptFlag = 0; double PathLength = 0; // increment position by tiny amount to get off the element @@ -124,18 +127,21 @@ namespace SolTrace::NativeRunner { StageHit = true; LastPathLength = PathLength; - CopyVec3(LastPosRaySurfElement, PosRaySurfElement); - CopyVec3(LastCosRaySurfElement, CosRaySurfElement); - CopyVec3(LastDFXYZ, DFXYZ); + LastPosRaySurfElement = PosRaySurfElement; + LastCosRaySurfElement = CosRaySurfElement; + LastDFXYZ = DFXYZ; // LastElementNumber = ((i == 0 && !PT_override) ? Element->element_number : j + 1); // mjw change from j index to element id LastElementNumber = Element->element_number; LastRayNumber = RayNumber; - TransformToReference(PosRaySurfElement, CosRaySurfElement, - Element->Origin, Element->RLocToRef, - PosRaySurfStage, CosRaySurfStage); + Data::TransformToReference(PosRaySurfElement, + CosRaySurfElement, + Element->Origin, + Element->RLocToRef, + PosRaySurfStage, + CosRaySurfStage); - CopyVec3(LastPosRaySurfStage, PosRaySurfStage); - CopyVec3(LastCosRaySurfStage, CosRaySurfStage); + LastPosRaySurfStage = PosRaySurfStage; + LastCosRaySurfStage = CosRaySurfStage; LastHitBackSide = HitBackSide; } } diff --git a/coretrace/simulation_runner/native_runner/find_element_hit.hpp b/coretrace/simulation_runner/native_runner/find_element_hit.hpp index 4214746a..6cdc3486 100644 --- a/coretrace/simulation_runner/native_runner/find_element_hit.hpp +++ b/coretrace/simulation_runner/native_runner/find_element_hit.hpp @@ -18,16 +18,16 @@ void FindElementHit( // ray info const int RayNumber, const bool in_multi_hit_loop, - double (&PosRayStage)[3], - double (&CosRayStage)[3], + glm::dvec3 &PosRayStage, + glm::dvec3 &CosRayStage, // outputs - double (&LastPosRaySurfElement)[3], - double (&LastCosRaySurfElement)[3], - double (&LastDFXYZ)[3], + glm::dvec3 &LastPosRaySurfElement, + glm::dvec3 &LastCosRaySurfElement, + glm::dvec3 &LastDFXYZ, uint_fast64_t &LastElementNumber, uint_fast64_t &LastRayNumber, - double (&LastPosRaySurfStage)[3], - double (&LastCosRaySurfStage)[3], + glm::dvec3 &LastPosRaySurfStage, + glm::dvec3 &LastCosRaySurfStage, int &ErrorFlag, int &LastHitBackSide, bool &StageHit); diff --git a/coretrace/simulation_runner/native_runner/flat_calculator.cpp b/coretrace/simulation_runner/native_runner/flat_calculator.cpp index 81743955..70bfeedb 100644 --- a/coretrace/simulation_runner/native_runner/flat_calculator.cpp +++ b/coretrace/simulation_runner/native_runner/flat_calculator.cpp @@ -36,11 +36,11 @@ namespace SolTrace::NativeRunner FlatCalculator::~FlatCalculator() {} - int FlatCalculator::intersect(const double PosLoc[3], - const double CosLoc[3], - double PosXYZ[3], - double CosKLM[3], - double DFXYZ[3], + int FlatCalculator::intersect(const glm::dvec3 PosLoc, + const glm::dvec3 CosLoc, + glm::dvec3 &PosXYZ, + glm::dvec3 &CosKLM, + glm::dvec3 &DFXYZ, double *PathLength) { int sts = 0; @@ -54,9 +54,9 @@ namespace SolTrace::NativeRunner double mz = CosLoc[2]; double t; - ZeroVec3(PosXYZ); - ZeroVec3(DFXYZ); - ZeroVec3(CosKLM); + PosXYZ = {}; + CosKLM = {}; + DFXYZ = {}; if (fabs(mz) < 1e-12) { @@ -73,7 +73,7 @@ namespace SolTrace::NativeRunner if (t > 0.0 && this->aper->is_in(x0, y0)) { - CopyVec3(CosKLM, CosLoc); + CosKLM = CosLoc; PosXYZ[0] = x0; PosXYZ[1] = y0; diff --git a/coretrace/simulation_runner/native_runner/flat_calculator.hpp b/coretrace/simulation_runner/native_runner/flat_calculator.hpp index b22cbea8..47ec7954 100644 --- a/coretrace/simulation_runner/native_runner/flat_calculator.hpp +++ b/coretrace/simulation_runner/native_runner/flat_calculator.hpp @@ -14,11 +14,11 @@ namespace SolTrace::NativeRunner FlatCalculator(SolTrace::Data::surface_ptr surf, SolTrace::Data::aperture_ptr ap); virtual ~FlatCalculator(); - virtual int intersect(const double PosLoc[3], - const double CosLoc[3], - double PosXYZ[3], - double CosKLM[3], - double DFXYZ[3], + virtual int intersect(const glm::dvec3 PosLoc, + const glm::dvec3 CosLoc, + glm::dvec3 &PosXYZ, + glm::dvec3 &CosKLM, + glm::dvec3 &DFXYZ, double *PathLength); virtual double compute_z_aperture(SolTrace::Data::aperture_ptr ap); diff --git a/coretrace/simulation_runner/native_runner/generate_ray.cpp b/coretrace/simulation_runner/native_runner/generate_ray.cpp index 24a8a48f..333b3809 100644 --- a/coretrace/simulation_runner/native_runner/generate_ray.cpp +++ b/coretrace/simulation_runner/native_runner/generate_ray.cpp @@ -6,14 +6,14 @@ namespace SolTrace::NativeRunner { void GenerateRay( - MTRand &myrng, - const double PosSunStage[3], - double Origin[3], - double RLocToRef[3][3], - TSun *Sun, - double PosRayGlobal[3], - double CosRayGlobal[3], - double PosRaySun[3]) + MTRand& myrng, + const glm::dvec3& PosSunStage, + glm::dvec3& Origin, + glm::dmat3& RLocToRef, + TSun* Sun, + glm::dvec3& PosRayGlobal, + glm::dvec3& CosRayGlobal, + glm::dvec3& PosRaySun) { /*{This procedure generates a randomly located ray in the x-y plane of the sun coordinate system in the z direction of the sun coord. system, checks to see that the ray is within the region of interest @@ -31,9 +31,9 @@ void GenerateRay( - CosRayGlobal = Direction cosines of ray in Global coordinate system} */ double XRaySun = 0.0, YRaySun = 0.0, ZRaySun = 0.0; - double CosRaySun[3] = {0.0, 0.0, 0.0}; - double PosRayStage[3] = {0.0, 0.0, 0.0}; - double CosRayStage[3] = {0.0, 0.0, 0.0}; + glm::dvec3 CosRaySun(0.0, 0.0, 0.0); + glm::dvec3 PosRayStage(0.0, 0.0, 0.0); + glm::dvec3 CosRayStage(0.0, 0.0, 0.0); int NegPosSign = 0; PosRaySun[0] = 0.; PosRaySun[1] = 0.; @@ -112,11 +112,21 @@ void GenerateRay( CosRaySun[2] = 1.0; //{Transform ray locations and dir cosines into Stage system} - TransformToReference(PosRaySun, CosRaySun, PosSunStage, Sun->RLocToRef, PosRayStage, CosRayStage); - - //{Transform ray locations and dir cosines into global system} - TransformToReference(PosRayStage, CosRayStage, Origin, RLocToRef, PosRayGlobal, CosRayGlobal); - } + Data::TransformToReference(PosRaySun, + CosRaySun, + PosSunStage, + Sun->RLocToRef, + PosRayStage, + CosRayStage); + + //{Transform ray locations and dir cosines into global system} + Data::TransformToReference(PosRayStage, + CosRayStage, + Origin, + RLocToRef, + PosRayGlobal, + CosRayGlobal); + } return; } diff --git a/coretrace/simulation_runner/native_runner/generate_ray.hpp b/coretrace/simulation_runner/native_runner/generate_ray.hpp index 5daaf413..52c7c800 100644 --- a/coretrace/simulation_runner/native_runner/generate_ray.hpp +++ b/coretrace/simulation_runner/native_runner/generate_ray.hpp @@ -6,14 +6,15 @@ namespace SolTrace::NativeRunner { -void GenerateRay(MTRand &myrng, - const double PosSunStage[3], - double Origin[3], - double RLocToRef[3][3], - TSun *Sun, - double PosRayGlobal[3], - double CosRayGlobal[3], - double PosRaySun[3]); +void GenerateRay(MTRand& myrng, + const glm::dvec3& PosSunStage, + glm::dvec3& Origin, + glm::dmat3& RLocToRef, + TSun* Sun, + glm::dvec3& PosRayGlobal, + glm::dvec3& CosRayGlobal, + glm::dvec3& PosRaySun); + } // namespace SolTrace::NativeRunner diff --git a/coretrace/simulation_runner/native_runner/native_runner.cpp b/coretrace/simulation_runner/native_runner/native_runner.cpp index 2328035d..d4e8b179 100644 --- a/coretrace/simulation_runner/native_runner/native_runner.cpp +++ b/coretrace/simulation_runner/native_runner/native_runner.cpp @@ -79,7 +79,7 @@ namespace SolTrace::NativeRunner } ray_source_ptr sun = data->get_ray_source(); - vector_copy(this->tsys.Sun.Origin, sun->get_position()); + this->tsys.Sun.Origin = sun->get_position(); this->tsys.Sun.ShapeIndex = sun->get_shape(); // Set sunshape data @@ -333,7 +333,7 @@ namespace SolTrace::NativeRunner uint_fast64_t ndata = ray_data.Count(); bool sts; - Vector3d point, cosines; + glm::dvec3 point, cosines; int element; int stage; uint_fast64_t raynum; @@ -349,8 +349,8 @@ namespace SolTrace::NativeRunner for (uint_fast64_t ii = 0; ii < ndata; ++ii) { sts = ray_data.Query(ii, - point.data, - cosines.data, + point, + cosines, &element, &stage, &raynum, diff --git a/coretrace/simulation_runner/native_runner/native_runner_types.cpp b/coretrace/simulation_runner/native_runner/native_runner_types.cpp index 38acacce..239d3292 100644 --- a/coretrace/simulation_runner/native_runner/native_runner_types.cpp +++ b/coretrace/simulation_runner/native_runner/native_runner_types.cpp @@ -266,8 +266,8 @@ namespace SolTrace::NativeRunner } TRayData::ray_t_ptr TRayData::Append(unsigned thread_id, - double pos[3], - double cos[3], + glm::dvec3& pos, + glm::dvec3& cos, int element, int stage, uint_fast64_t raynum, @@ -283,8 +283,8 @@ namespace SolTrace::NativeRunner if (r != nullptr) { - std::memcpy(&r->pos, pos, sizeof(double) * 3); - std::memcpy(&r->cos, cos, sizeof(double) * 3); + r->pos = pos; + r->cos = cos; r->element = element; r->stage = stage; r->raynum = this->GetRayId(thread_id, raynum); @@ -324,11 +324,11 @@ namespace SolTrace::NativeRunner } bool TRayData::Query(uint_fast64_t idx, - double pos[3], - double cos[3], - int *element, - int *stage, - uint_fast64_t *raynum, + glm::dvec3& pos, + glm::dvec3& cos, + int* element, + int* stage, + uint_fast64_t* raynum, SolTrace::Result::RayEvent *rev) const { @@ -336,10 +336,9 @@ namespace SolTrace::NativeRunner if (r != nullptr) { - if (pos != nullptr) - std::memcpy(pos, r->pos, sizeof(double) * 3); - if (cos != nullptr) - std::memcpy(cos, r->cos, sizeof(double) * 3); + pos = r->pos; + cos = r->cos; + if (element != nullptr) *element = r->element; if (stage != nullptr) @@ -400,7 +399,7 @@ namespace SolTrace::NativeRunner for (uint_fast64_t i = 0; i < n; ++i) { - double pos[3], cos[3]; + glm::dvec3 pos, cos; int elm, stage; uint_fast64_t ray; SolTrace::Result::RayEvent rev; @@ -478,13 +477,13 @@ namespace SolTrace::NativeRunner // << std::endl; telement_ptr telem = std::make_shared(); - vector_copy(telem->Origin, el->get_origin_stage()); - vector_copy(telem->AimPoint, el->get_aim_vector_stage()); + telem->Origin = el->get_origin_stage(); + telem->AimPoint = el->get_aim_vector_stage(); telem->ZRot = el->get_zrot(); // vector_copy(telem->Euler, el->get_euler_angles()); - matrix_copy(telem->RRefToLoc, el->get_stage_to_local()); - matrix_copy(telem->RLocToRef, el->get_local_to_stage()); + telem->RRefToLoc = el->get_stage_to_local(); + telem->RLocToRef = el->get_local_to_stage(); telem->aperture = el->get_aperture()->make_copy(); telem->icalc = @@ -508,12 +507,12 @@ namespace SolTrace::NativeRunner tstage_ptr my_stage = std::make_shared(); // Use global coordinates as stage coordinates - ZeroVec3(my_stage->Origin); - ZeroVec3(my_stage->AimPoint); + my_stage->Origin = {}; + my_stage->AimPoint = {}; my_stage->AimPoint[2] = 1.0; my_stage->ZRot = 0.0; - IdentityMat3(my_stage->RRefToLoc); - IdentityMat3(my_stage->RLocToRef); + my_stage->RRefToLoc = {}; + my_stage->RLocToRef = {}; return my_stage; } @@ -533,11 +532,11 @@ namespace SolTrace::NativeRunner my_stage->stage_id = stage_el->get_stage(); // Add coordinate stuff - vector_copy(my_stage->Origin, stage_el->get_origin_global()); - vector_copy(my_stage->AimPoint, stage_el->get_aim_vector_global()); + my_stage->Origin = stage_el->get_origin_global(); + my_stage->AimPoint = stage_el->get_aim_vector_global(); my_stage->ZRot = stage_el->get_zrot(); - matrix_copy(my_stage->RRefToLoc, stage_el->get_global_to_local()); - matrix_copy(my_stage->RLocToRef, stage_el->get_local_to_global()); + my_stage->RRefToLoc = stage_el->get_global_to_local(); + my_stage->RLocToRef = stage_el->get_local_to_global(); return my_stage; } diff --git a/coretrace/simulation_runner/native_runner/native_runner_types.hpp b/coretrace/simulation_runner/native_runner/native_runner_types.hpp index efd3fd62..39bf405f 100644 --- a/coretrace/simulation_runner/native_runner/native_runner_types.hpp +++ b/coretrace/simulation_runner/native_runner/native_runner_types.hpp @@ -150,12 +150,12 @@ namespace SolTrace::NativeRunner // bool Enabled; /////////// ORIENTATION PARAMETERS /////////////// - double Origin[3]; - double AimPoint[3]; - double ZRot; - double RRefToLoc[3][3]; - double RLocToRef[3][3]; - double PosSunCoords[3]; // calculated -- position in sun plane coordinates - mw + glm::dvec3 Origin; + glm::dvec3 AimPoint; + double ZRot; + glm::dmat3 RRefToLoc; + glm::dmat3 RLocToRef; + glm::dvec3 PosSunCoords; // calculated -- position in sun plane coordinates - mw /////////// APERTURE PARAMETERS ////////////// double ZAperture; // calculated @@ -206,12 +206,12 @@ namespace SolTrace::NativeRunner double buie_kappa; // Buie CSR model kappa parameter double buie_gamma; // Buie CSR model gamma parameter - double Origin[3]; + glm::dvec3 Origin; - // calculated - double Euler[3]; - double RRefToLoc[3][3]; - double RLocToRef[3][3]; + // calculated + glm::dvec3 Euler; + glm::dmat3 RRefToLoc; + glm::dmat3 RLocToRef; double MaxRad; double Xcm; @@ -230,9 +230,9 @@ namespace SolTrace::NativeRunner struct ray_t { - double pos[3]; - double cos[3]; - int element; + glm::dvec3 pos = {0, 0, 0}; + glm::dvec3 cos = {0, 0, 0}; + int element; int stage; // unsigned int raynum; SolTrace::Result::ray_id raynum; @@ -240,21 +240,21 @@ namespace SolTrace::NativeRunner }; using ray_t_ptr = std::shared_ptr; - ray_t_ptr Append(unsigned thread_id, - double pos[3], - double cos[3], - int element, - int stage, - uint_fast64_t raynum, - SolTrace::Result::RayEvent rev); - - bool Query(uint_fast64_t idx, - double pos[3], - double cos[3], - int *element, - int *stage, - uint_fast64_t *raynum, - SolTrace::Result::RayEvent *it) const; + ray_t_ptr Append(unsigned thread_id, + glm::dvec3& pos, + glm::dvec3& cos, + int element, + int stage, + uint_fast64_t raynum, + SolTrace::Result::RayEvent rev); + + bool Query(uint_fast64_t idx, + glm::dvec3& pos, + glm::dvec3& cos, + int* element, + int* stage, + uint_fast64_t* raynum, + SolTrace::Result::RayEvent* it) const; void Clear(); @@ -310,18 +310,18 @@ namespace SolTrace::NativeRunner bool Virtual; bool TraceThrough; - double Origin[3]; - double AimPoint[3]; - double ZRot; + glm::dvec3 Origin; + glm::dvec3 AimPoint; + double ZRot; - // std::vector ElementList; - std::vector ElementList; - // std::map ElementList; + // std::vector ElementList; + std::vector ElementList; + // std::map ElementList; - // calculated - double Euler[3]; - double RRefToLoc[3][3]; - double RLocToRef[3][3]; + // calculated + glm::dvec3 Euler; + glm::dmat3 RRefToLoc; + glm::dmat3 RLocToRef; // TRayData RayData; diff --git a/coretrace/simulation_runner/native_runner/newton_calculator.cpp b/coretrace/simulation_runner/native_runner/newton_calculator.cpp index 3dfd4012..ee71b439 100644 --- a/coretrace/simulation_runner/native_runner/newton_calculator.cpp +++ b/coretrace/simulation_runner/native_runner/newton_calculator.cpp @@ -5,7 +5,7 @@ #include #include "simulation_data_export.hpp" -// #include "vector3d.hpp" +// #include "glm::dvec3.hpp" namespace SolTrace::NativeRunner { @@ -20,11 +20,11 @@ namespace SolTrace::NativeRunner { } - int NewtonCalculator::intersect(const double PosLoc[3], - const double CosLoc[3], - double PosXYZ[3], - double CosKLM[3], - double DFXYZ[3], + int NewtonCalculator::intersect(const glm::dvec3 PosLoc, + const glm::dvec3 CosLoc, + glm::dvec3 &PosXYZ, + glm::dvec3 &CosKLM, + glm::dvec3 &DFXYZ, double *PathLength) { int sts = 1; @@ -32,25 +32,25 @@ namespace SolTrace::NativeRunner // double x0 = PosLoc[0], y0 = PosLoc[1], z0 = PosLoc[2]; // double mx = CosLoc[0], my = CosLoc[1], mz = CosLoc[2]; - Vector3d u0(PosLoc); - Vector3d dt(CosLoc); + glm::dvec3 u0(PosLoc); + glm::dvec3 dt(CosLoc); double t0 = 0.0; double delta = 0.0; // double res; double fvalue; double fprime; - Vector3d v0(PosLoc); - Vector3d dv; + glm::dvec3 v0(PosLoc); + glm::dvec3 dv; *PathLength = 0.0; - ZeroVec3(PosXYZ); - ZeroVec3(CosKLM); - ZeroVec3(DFXYZ); + PosXYZ = {}; + CosKLM = {}; + DFXYZ = {}; // this->set_zstart(v0.data); - this->surface_and_jacobian(v0.data, &fvalue, dv.data); - fprime = dot_product(dv, dt); + this->surface_and_jacobian(v0, &fvalue, dv); + fprime = glm::dot(dv, dt); // std::cout << "Tolerance: " << this->tolerance << std::endl; @@ -66,9 +66,9 @@ namespace SolTrace::NativeRunner delta = fvalue / fprime; t0 -= delta; // Updates v0 to (x0, y0, z0) + t0 * (mx, my, mz) - vector_add(1.0, u0, t0, dt, v0); - this->surface_and_jacobian(v0.data, &fvalue, dv.data); - fprime = dot_product(dv, dt); + v0 = u0 + t0 * dt; + this->surface_and_jacobian(v0, &fvalue, dv); + fprime = glm::dot(dv, dt); ++count; } @@ -77,9 +77,9 @@ namespace SolTrace::NativeRunner { sts = 0; *PathLength = t0; - CopyVec3(CosKLM, CosLoc); - CopyVec3(PosXYZ, v0.data); - CopyVec3(DFXYZ, dv.data); + CosKLM = CosLoc; + PosXYZ = v0; + DFXYZ = dv; } return sts; diff --git a/coretrace/simulation_runner/native_runner/newton_calculator.hpp b/coretrace/simulation_runner/native_runner/newton_calculator.hpp index f69e0be1..534b6866 100644 --- a/coretrace/simulation_runner/native_runner/newton_calculator.hpp +++ b/coretrace/simulation_runner/native_runner/newton_calculator.hpp @@ -19,19 +19,19 @@ namespace SolTrace::NativeRunner uint_fast64_t max_iters = 20); virtual ~NewtonCalculator() {} - virtual int intersect(const double PosLoc[3], - const double CosLoc[3], - double PosXYZ[3], - double CosKLM[3], - double DFXYZ[3], + virtual int intersect(const glm::dvec3 PosLoc, + const glm::dvec3 CosLoc, + glm::dvec3 &PosXYZ, + glm::dvec3 &CosKLM, + glm::dvec3 &DFXYZ, double *PathLength); // For x = PosXYZ[0], y = PosXYZ[1], make a guess at // value of z and place in PosXYZ[2]. - virtual void set_zstart(double PosXYZ[3]) = 0; - virtual void surface_and_jacobian(const double PosXYZ[3], + virtual void set_zstart(glm::dvec3 &PosXYZ) = 0; + virtual void surface_and_jacobian(glm::dvec3 PosXYZ, double *F, - double DFXYZ[3]) = 0; + glm::dvec3 &DFXYZ) = 0; inline double get_tolerance() const { diff --git a/coretrace/simulation_runner/native_runner/parabola_calculator.cpp b/coretrace/simulation_runner/native_runner/parabola_calculator.cpp index 26b79b0b..b1365411 100644 --- a/coretrace/simulation_runner/native_runner/parabola_calculator.cpp +++ b/coretrace/simulation_runner/native_runner/parabola_calculator.cpp @@ -10,7 +10,7 @@ #include "matvec.hpp" #include "simulation_data_export.hpp" #include "surface.hpp" -// #include "vector3d.hpp" +// #include "glm::dvec3.hpp" namespace SolTrace::NativeRunner { @@ -66,11 +66,11 @@ namespace SolTrace::NativeRunner { } - int ParabolaCalculator::intersect(const double PosLoc[3], - const double CosLoc[3], - double PosXYZ[3], - double CosKLM[3], - double DFXYZ[3], + int ParabolaCalculator::intersect(const glm::dvec3 PosLoc, + const glm::dvec3 CosLoc, + glm::dvec3& PosXYZ, + glm::dvec3& CosKLM, + glm::dvec3& DFXYZ, double *PathLength) { int sts = 0; @@ -82,15 +82,15 @@ namespace SolTrace::NativeRunner double cx = this->cx, cy = this->cy; double t1, t2; double a, b, c; - Vector3d p1, p2; + glm::dvec3 p1, p2; c = 0.5 * (cx * x0 * x0 + cy * y0 * y0) - z0; b = (x0 * cx * mx + y0 * cy * my - mz); a = 0.5 * (cx * mx * mx + cy * my * my); - ZeroVec3(PosXYZ); - ZeroVec3(CosKLM); - ZeroVec3(DFXYZ); + PosXYZ = {}; + CosKLM = {}; + DFXYZ = {}; // std::cout << "a: " << a // << " b: " << b @@ -101,14 +101,14 @@ namespace SolTrace::NativeRunner { // This should only happen if mx == my == 0.0 t1 = -c / b; - AddVec3(1.0, PosLoc, t1, CosLoc, p1.data); + p1 = PosLoc + t1 * CosLoc; if (t1 > 0.0 && this->aper->is_in(p1[0], p1[1])) { *PathLength = t1; // SetVec3(PosXYZ, x0 + t1 * mx, y0 + t1 * my, z0 + t1 * mz); // AddVec3(1.0, PosLoc, t1, CosLoc, PosXYZ); - CopyVec3(PosXYZ, p1.data); + PosXYZ = p1; } else { @@ -140,8 +140,8 @@ namespace SolTrace::NativeRunner // Positive root t2 = -0.5 * (b - scratch) / a; - AddVec3(1.0, PosLoc, t1, CosLoc, p1.data); - AddVec3(1.0, PosLoc, t2, CosLoc, p2.data); + p1 = PosLoc + t1 * CosLoc; + p2 = PosLoc + t2 * CosLoc; // std::cout << "P1: " << p1 // << "\nP2: " << p2 @@ -152,14 +152,14 @@ namespace SolTrace::NativeRunner *PathLength = t1; // SetVec3(PosXYZ, x0 + t1 * mx, y0 + t1 * my, z0 + t1 * mz); // AddVec3(1.0, PosLoc, t1, CosLoc, PosXYZ); - CopyVec3(PosXYZ, p1.data); + PosXYZ = p1; } else if (t2 > 0.0 && this->aper->is_in(p2[0], p2[1])) { *PathLength = t2; // SetVec3(PosXYZ, x0 + t2 * mx, y0 + t2 * my, z0 + t2 * mz); // AddVec3(1.0, PosLoc, t2, CosLoc, PosXYZ); - CopyVec3(PosXYZ, p2.data); + PosXYZ = p2; } else { @@ -172,11 +172,11 @@ namespace SolTrace::NativeRunner if (sts == 0) { this->surface_normal(PosXYZ, DFXYZ); - CopyVec3(CosKLM, CosLoc); + CosKLM = CosLoc; } - // Vector3d grad(DFXYZ); - // Vector3d pos(PosXYZ); + // glm::dvec3 grad(DFXYZ); + // glm::dvec3 pos(PosXYZ); // std::cout << "Surface normal: " << grad // << "\nPosition: " << pos // << std::endl; @@ -186,17 +186,15 @@ namespace SolTrace::NativeRunner return sts; } - void ParabolaCalculator::surface_normal(const double PosXYZ[3], - double DFXYZ[3]) + void ParabolaCalculator::surface_normal(const glm::dvec3 PosXYZ, + glm::dvec3& DFXYZ) { // TODO: Need to default to returning the surface normal of // whatever is the "front". Is that the inside of the parabola // (which is used currently) or the outside? double cx = this->cx; double cy = this->cy; - DFXYZ[0] = -cx * PosXYZ[0]; - DFXYZ[1] = -cy * PosXYZ[1]; - DFXYZ[2] = 1.0; + DFXYZ = {-cx * PosXYZ[0], -cy * PosXYZ[1], 1.0}; return; } diff --git a/coretrace/simulation_runner/native_runner/parabola_calculator.hpp b/coretrace/simulation_runner/native_runner/parabola_calculator.hpp index a40200a3..616ec5ed 100644 --- a/coretrace/simulation_runner/native_runner/parabola_calculator.hpp +++ b/coretrace/simulation_runner/native_runner/parabola_calculator.hpp @@ -15,14 +15,14 @@ namespace SolTrace::NativeRunner ParabolaCalculator(SolTrace::Data::surface_ptr surf, SolTrace::Data::aperture_ptr ap); virtual ~ParabolaCalculator(); - virtual int intersect(const double PosLoc[3], - const double CosLoc[3], - double PosXYZ[3], - double CosKLM[3], - double DFXYZ[3], + virtual int intersect(const glm::dvec3 PosLoc, + const glm::dvec3 CosLoc, + glm::dvec3 &PosXYZ, + glm::dvec3 &CosKLM, + glm::dvec3 &DFXYZ, double *PathLength); - void surface_normal(const double PosXYZ[3], double DFXYZ[3]); + void surface_normal(const glm::dvec3 PosXYZ, glm::dvec3& DFXYZ); virtual double compute_z_aperture(SolTrace::Data::aperture_ptr ap); diff --git a/coretrace/simulation_runner/native_runner/process_interaction.cpp b/coretrace/simulation_runner/native_runner/process_interaction.cpp index 4ed5b17e..aaf7e63d 100644 --- a/coretrace/simulation_runner/native_runner/process_interaction.cpp +++ b/coretrace/simulation_runner/native_runner/process_interaction.cpp @@ -1,4 +1,3 @@ - #include "process_interaction.hpp" // SimulationData headers @@ -10,112 +9,115 @@ namespace SolTrace::NativeRunner { - void ProcessInteraction( - // system info - TSystem *System, - MTRand &myrng, - const bool IncludeSunShape, - const OpticalProperties *optics, - const bool IncludeErrors, - // stage info - const int i, - // const TStage *Stage, - const tstage_ptr Stage, - // const telement_ptr Elem, - // const int k, - // ray info - const uint_fast64_t MultipleHitCount, - double (&LastDFXYZ)[3], - // Outputs - double (&LastCosRaySurfElement)[3], - int &ErrorFlag, - double (&CosRayOutElement)[3], - double (&LastPosRaySurfElement)[3], - double (&PosRayOutElement)[3]) - { - // Initialize - double CosIn[3] = {0.0, 0.0, 0.0}; - double CosOut[3] = {0.0, 0.0, 0.0}; - - if (!Stage->Virtual) - { - // change to account for first hit only in primary stage 8-11-31 - if (IncludeSunShape && i == 0 && MultipleHitCount == 1) - { - // Apply sunshape to UNPERTURBED ray at intersection point - // only apply sunshape error once for primary stage - CopyVec3(CosIn, LastCosRaySurfElement); - // sun shape - Errors(myrng, CosIn, 1, &System->Sun, - optics, CosOut, LastDFXYZ); - CopyVec3(LastCosRaySurfElement, CosOut); - } - - //{Determine interaction at surface and direction of perturbed ray} - ErrorFlag = 0; +void ProcessInteraction( + // system info + TSystem *System, + MTRand &myrng, + const bool IncludeSunShape, + const SolTrace::Data::OpticalProperties *optics, + const bool IncludeErrors, + // stage info + const int i, + // const TStage *Stage, + const tstage_ptr Stage, + // const telement_ptr Elem, + // const int k, + // ray info + const uint_fast64_t MultipleHitCount, + glm::dvec3 &LastDFXYZ, + // Outputs + glm::dvec3 &LastCosRaySurfElement, + int &ErrorFlag, + glm::dvec3 &CosRayOutElement, + glm::dvec3 &LastPosRaySurfElement, + glm::dvec3 &PosRayOutElement) +{ + // Initialize + glm::dvec3 CosIn(0.0, 0.0, 0.0); + glm::dvec3 CosOut(0.0, 0.0, 0.0); + + if (!Stage->Virtual) { + // change to account for first hit only in primary stage 8-11-31 + if (IncludeSunShape && i == 0 && MultipleHitCount == 1) { + // Apply sunshape to UNPERTURBED ray at intersection point + // only apply sunshape error once for primary stage + CosIn = LastCosRaySurfElement; + // sun shape + Errors(myrng, CosIn, 1, &System->Sun, optics, CosOut, LastDFXYZ); + LastCosRaySurfElement = CosOut; + } - // {Apply surface normal errors to surface normal before interaction - // ray at intersection point - Wendelin 11-23-09} - if (IncludeErrors) - { - CopyVec3(CosIn, CosRayOutElement); - // surface normal errors - SurfaceNormalErrors(myrng, LastDFXYZ, optics, CosOut); - // myrng_counter++; - CopyVec3(LastDFXYZ, CosOut); - } + //{Determine interaction at surface and direction of perturbed ray} + ErrorFlag = 0; - Interaction(myrng, LastPosRaySurfElement, LastCosRaySurfElement, - LastDFXYZ, // Stage->ElementList[k]->InteractionType, - optics, 630.0, PosRayOutElement, CosRayOutElement, - &ErrorFlag); + // {Apply surface normal errors to surface normal before interaction + // ray at intersection point - Wendelin 11-23-09} + if (IncludeErrors) { + CosIn = CosRayOutElement; + // surface normal errors + SurfaceNormalErrors(myrng, LastDFXYZ, optics, CosOut); // myrng_counter++; + LastDFXYZ = CosOut; + } - // {Apply specularity optical error to PERTURBED (i.e. after - // interaction) ray at intersection point} - if (IncludeErrors) - { - // if (optics->error_distribution_type == 'F' || - // optics->error_distribution_type == 'f') - // { - // // Apply diffuse errors relative to surface normal - // CopyVec3(CosIn, LastDFXYZ); - // } - // else - // { - // // Apply all other errors relative to the specularly-reflected - // // direction - // CopyVec3(CosIn, CosRayOutElement); - // } - - // TODO: Not sure what error distribution type 'F' is? - // Do we need to implement it? For now just use the 'else' - // clause from the above. - CopyVec3(CosIn, CosRayOutElement); - - // optical errors - Errors(myrng, CosIn, 2, &System->Sun, - // Stage->ElementList[k].get(), - optics, CosOut, LastDFXYZ); - // myrng_counter++; - CopyVec3(CosRayOutElement, CosOut); - } + Interaction(myrng, + LastPosRaySurfElement, + LastCosRaySurfElement, + LastDFXYZ, // Stage->ElementList[k]->InteractionType, + optics, + 630.0, + PosRayOutElement, + CosRayOutElement, + &ErrorFlag); + // myrng_counter++; + + // {Apply specularity optical error to PERTURBED (i.e. after + // interaction) ray at intersection point} + if (IncludeErrors) { + // if (optics->error_distribution_type == 'F' || + // optics->error_distribution_type == 'f') + // { + // // Apply diffuse errors relative to surface normal + // CopyVec3(CosIn, LastDFXYZ); + // } + // else + // { + // // Apply all other errors relative to the specularly-reflected + // // direction + // CopyVec3(CosIn, CosRayOutElement); + // } + + // TODO: Not sure what error distribution type 'F' is? + // Do we need to implement it? For now just use the 'else' + // clause from the above. + CosIn = CosRayOutElement; + + // optical errors + Errors(myrng, + CosIn, + 2, + &System->Sun, + // Stage->ElementList[k].get(), + optics, + CosOut, + LastDFXYZ); + // myrng_counter++; + CosRayOutElement = CosOut; } } + } inline double sqr(double x) { return (x) * (x); } - void Interaction( - MTRand &myrng, - const double PosXYZ[3], - const double CosKLM[3], - const double DFXYZ[3], - // int InteractionType, - const OpticalProperties *Opticl, - double Wavelength, - double PosOut[3], - double CosOut[3], - int *ErrorFlag) + void Interaction(MTRand &myrng, + const glm::dvec3 &PosXYZ, + const glm::dvec3 &CosKLM, + const glm::dvec3 &DFXYZ, + const SolTrace::Data::OpticalProperties *Opticl, + double Wavelength, + glm::dvec3 &PosOut, + glm::dvec3 &CosOut, + int *ErrorFlag) { /* {Purpose: To compute the direction cosines of the ray due to optical interaction at the intersection point of the ray with the surface @@ -161,16 +163,20 @@ namespace SolTrace::NativeRunner }*/ int i = 0; - double CosUVW[3] = {0.0, 0.0, 0.0}; + glm::dvec3 CosUVW(0.0, 0.0, 0.0); + int NIter = 0, IType = 0, NMord = 0; double Epsilon = 0.0, Refr1 = 0.0, Refr2 = 0.0, RMU = 0.0, RM2 = 0.0; double D2 = 0.0, B = 0.0, A = 0.0, A2 = 0.0; double Gamn = 0.0, Gamn1 = 0.0; double X = 0.0, Y = 0.0, A1 = 0.0, B1 = 0.0, Ellips = 0.0, B2 = 0.0; double RK = 0.0, RL = 0.0, RM = 0.0, Denom, U = 0, V = 0, W = 0; - double Varr = 0, GFactr = 0, Rho2 = 0.0, Rho = 0.0, Term = 0.0, G = 0.0, D = 0.0, XX = 0.0, Ordiff = 0.0, RLamda = 0.0; + double Varr = 0, GFactr = 0, Rho2 = 0.0, Rho = 0.0, Term = 0.0, G = 0.0, D = 0.0, XX = 0.0, + Ordiff = 0.0, RLamda = 0.0; double Rave = 0.0, Rs = 0.0, Rp = 0.0; - double UnitDFXYZ[3] = {0.0, 0.0, 0.0}, IncidentAngle = 0.0; + + glm::dvec3 UnitDFXYZ(0.0, 0.0, 0.0); + double IncidentAngle = 0.0; NIter = 10; Epsilon = 0.000005; @@ -193,23 +199,22 @@ namespace SolTrace::NativeRunner Refr1 = Opticl->refraction_index_front; Refr2 = Opticl->refraction_index_back; RMU = Refr1 / Refr2; - D2 = DOT(DFXYZ, DFXYZ); + D2 = glm::dot(DFXYZ, DFXYZ); B = (RMU * RMU - 1.0) / D2; - A = RMU * DOT(CosKLM, DFXYZ) / D2; + A = RMU * glm::dot(CosKLM, DFXYZ) / D2; A2 = A * A; if (B > A2) // Total internal reflection { - A = DOT(CosKLM, DFXYZ) / DOT(DFXYZ, DFXYZ); - for (i = 0; i < 3; i++) - CosOut[i] = CosKLM[i] - 2.0 * A * DFXYZ[i]; + A = glm::dot(CosKLM, DFXYZ) / glm::dot(DFXYZ, DFXYZ); + CosOut = CosKLM - 2.0 * A * DFXYZ; return; } // fresnel equations - UnitDFXYZ[0] = -DFXYZ[0] / sqrt(DOT(DFXYZ, DFXYZ)); // unit surface normals - UnitDFXYZ[1] = -DFXYZ[1] / sqrt(DOT(DFXYZ, DFXYZ)); - UnitDFXYZ[2] = -DFXYZ[2] / sqrt(DOT(DFXYZ, DFXYZ)); - IncidentAngle = acos(DOT(CosKLM, UnitDFXYZ)); + UnitDFXYZ[0] = -DFXYZ[0] / sqrt(glm::dot(DFXYZ, DFXYZ)); // unit surface normals + UnitDFXYZ[1] = -DFXYZ[1] / sqrt(glm::dot(DFXYZ, DFXYZ)); + UnitDFXYZ[2] = -DFXYZ[2] / sqrt(glm::dot(DFXYZ, DFXYZ)); + IncidentAngle = acos(glm::dot(CosKLM, UnitDFXYZ)); Rs = sqr(((Refr1 * cos(IncidentAngle) - Refr2 * sqrt(1 - sqr(Refr1 * sin(IncidentAngle) / Refr2)))) / ((Refr1 * cos(IncidentAngle) + Refr2 * sqrt(1 - sqr(Refr1 * sin(IncidentAngle) / Refr2))))); Rp = sqr(((Refr1 * sqrt(1 - sqr(Refr1 * sin(IncidentAngle) / Refr2))) - Refr2 * cos(IncidentAngle)) / @@ -246,7 +251,7 @@ namespace SolTrace::NativeRunner } else // reflected from surface { - A = DOT(CosKLM, DFXYZ) / DOT(DFXYZ, DFXYZ); + A = glm::dot(CosKLM, DFXYZ) / glm::dot(DFXYZ, DFXYZ); for (i = 0; i < 3; i++) CosOut[i] = CosKLM[i] - 2.0 * A * DFXYZ[i]; } @@ -258,7 +263,7 @@ namespace SolTrace::NativeRunner ===============================================================================}*/ case InteractionType::REFLECTION: { - A = DOT(CosKLM, DFXYZ) / DOT(DFXYZ, DFXYZ); + A = glm::dot(CosKLM, DFXYZ) / glm::dot(DFXYZ, DFXYZ); // Compute direction cosines for reflected ray for (i = 0; i < 3; i++) CosOut[i] = CosKLM[i] - 2.0 * A * DFXYZ[i]; diff --git a/coretrace/simulation_runner/native_runner/process_interaction.hpp b/coretrace/simulation_runner/native_runner/process_interaction.hpp index 90e0a58e..c1625998 100644 --- a/coretrace/simulation_runner/native_runner/process_interaction.hpp +++ b/coretrace/simulation_runner/native_runner/process_interaction.hpp @@ -12,10 +12,10 @@ namespace SolTrace::NativeRunner { void ProcessInteraction( // system info - TSystem *System, - MTRand &myrng, + TSystem* System, + MTRand& myrng, const bool IncludeSunShape, - const SolTrace::Data::OpticalProperties *optics, + const SolTrace::Data::OpticalProperties* optics, const bool IncludeErrors, // stage info const int i, @@ -25,23 +25,24 @@ void ProcessInteraction( // const int k, // ray info const uint_fast64_t MultipleHitCount, - double (&LastDFXYZ)[3], + glm::dvec3& LastDFXYZ, // Outputs - double (&LastCosRaySurfElement)[3], - int &ErrorFlag, - double (&CosRayOutElement)[3], - double (&LastPosRaySurfElement)[3], - double (&PosRayOutElement)[3]); - -void Interaction(MTRand &myrng, - const double PosXYZ[3], - const double CosKLM[3], - const double DFXYZ[3], - const SolTrace::Data::OpticalProperties *Opticl, + glm::dvec3& LastCosRaySurfElement, + int& ErrorFlag, + glm::dvec3& CosRayOutElement, + glm::dvec3& LastPosRaySurfElement, + glm::dvec3& PosRayOutElement); + +void Interaction(MTRand& myrng, + const glm::dvec3& PosXYZ, + const glm::dvec3& CosKLM, + const glm::dvec3& DFXYZ, + const SolTrace::Data::OpticalProperties* Opticl, double Wavelength, - double PosOut[3], - double CosOut[3], - int *ErrorFlag); + glm::dvec3& PosOut, + glm::dvec3& CosOut, + int* ErrorFlag); + } // namespace SolTrace::NativeRunner diff --git a/coretrace/simulation_runner/native_runner/pt_optimizations.cpp b/coretrace/simulation_runner/native_runner/pt_optimizations.cpp index 2c099ddb..f4ce69b7 100644 --- a/coretrace/simulation_runner/native_runner/pt_optimizations.cpp +++ b/coretrace/simulation_runner/native_runner/pt_optimizations.cpp @@ -9,230 +9,240 @@ namespace SolTrace::NativeRunner { - void SetupPTOptimizations( - // system info - TSystem *System, const bool AsPowerTower, - // outputs - st_hash_tree &sun_hash, - st_hash_tree &rec_hash, - double (&reccm_helio)[3]) - { - // Calculate the center of mass of the receiver stage (StageList[1]) in - // heliostat stage coordinates. - double reccm[] = {0., 0., 0.}; - int nelrec = 0; - if (AsPowerTower) - { - for (uint_fast64_t j = 0; j < System->StageList[1]->ElementList.size(); j++) - { - TElement *el = System->StageList[1]->ElementList.at(j).get(); - - // if (!el->Enabled) - // continue; - - nelrec++; - - for (int jj = 0; jj < 3; jj++) - reccm[jj] += el->Origin[jj]; - } - for (int jj = 0; jj < 3; jj++) - reccm[jj] /= (double)nelrec; // average - - // Transform to reference - double dum1[] = {0., 0., 1.}; - double dum2[3]; - double reccm_global[3]; - TransformToReference(reccm, dum1, System->StageList[1]->Origin, - System->StageList[1]->RLocToRef, reccm_global, dum2); - - // Transform to local (heliostat). reccm_helio is the x,y,z position - // of the receiver centroid in heliostat stage coordinates. - TransformToLocal(reccm_global, dum1, System->StageList[0]->Origin, - System->StageList[0]->RRefToLoc, reccm_helio, dum2); - } - // Create an array that stores the element address and the projected size - // in polar coordinates - std::vector el_proj_dat; - el_proj_dat.reserve(System->StageList[0]->ElementList.size()); - - // calculate the smallest zone size. This should be on the order of the - // largest element in the stage. load stage 0 elements into the mesh - double d_elm_max = -9.e9; - double d_elm; - - for (uint_fast64_t i = 0; i < System->StageList[0]->ElementList.size(); i++) - { - TElement *el = System->StageList[0]->ElementList.at(i).get(); - - // el->element_number = i + 1; // use index for element number - - d_elm = el->aperture->diameter_circumscribed_circle(); - - // double d_elm; - - // switch (el->ShapeIndex) - // { - // // circular aperture - // case 'c': - // case 'C': - // // hexagonal aperture - // case 'h': - // case 'H': - // // triangular aperture - // case 't': - // case 'T': - // d_elm = el->ParameterA; - // break; - // // rectangular aperture - // case 'r': - // case 'R': - // d_elm = sqrt(el->ParameterA * el->ParameterA + el->ParameterB * el->ParameterB); - // break; - // // annular aperture - // case 'a': - // case 'A': - // d_elm = el->ParameterB; - // break; - // case 'l': - // case 'L': - // // off axis aperture section of line focus trough or cylinder - // d_elm = sqrt(el->ParameterB * el->ParameterB * 4. + el->ParameterC * el->ParameterC); - // break; - // // Irregular triangle - // case 'i': - // case 'I': - // // irregular quadrilateral - // case 'q': - // case 'Q': - // { - // double xmax = fmax(el->ParameterA, fmax(el->ParameterC, el->ParameterE)); - // double xmin = fmin(el->ParameterA, fmin(el->ParameterC, el->ParameterE)); - // double ymax = fmax(el->ParameterB, fmax(el->ParameterD, el->ParameterF)); - // double ymin = fmin(el->ParameterB, fmin(el->ParameterD, el->ParameterF)); - - // if (el->ShapeIndex == 'q' || el->ShapeIndex == 'Q') - // { - // xmax = fmax(xmax, el->ParameterG); - // xmin = fmin(xmin, el->ParameterG); - // ymax = fmax(ymax, el->ParameterH); - // ymin = fmin(ymin, el->ParameterH); - // } - - // double dx = xmax - xmin; - // double dy = ymax - ymin; - - // d_elm = sqrt(dx * dx + dy * dy); - - // break; - // } - // default: - // break; - // } - - d_elm_max = fmax(d_elm_max, d_elm); - - if (AsPowerTower) - { - // Calculate the distance from the receiver to the element and the max projected size - double dX[3]; - for (int jj = 0; jj < 3; jj++) - dX[jj] = el->Origin[jj] - reccm_helio[jj]; // vector from receiver to heliostat (not unitized) - double r_elm = 0.; - for (int jj = 0; jj < 3; jj++) - r_elm += dX[jj] * dX[jj]; - r_elm = sqrt(r_elm); // vector length - double d_elm_proj = d_elm / r_elm; // Projected size of the element from the view of the receiver (radians) - - // calculate az,zen coordinate - double az, zen; - az = atan2(dX[0] / r_elm, dX[1] / r_elm); // Az coordinate of the heliostat from the receiver's perspective - zen = asin(dX[2] / r_elm); // Zen coordinate """" - - el_proj_dat.push_back(eprojdat(el, d_elm_proj, az, zen)); - } - } - - if (AsPowerTower) - { - // Sort the polar projections by size, largest to smallest - std::sort(el_proj_dat.begin(), el_proj_dat.end(), eprojdat_compare_refactored); - } - - // set up the layout data object that provides configuration details for - // the hash tree - KDLayoutData sun_ld; - sun_ld.xlim[0] = System->Sun.MinXSun; - sun_ld.xlim[1] = System->Sun.MaxXSun; - sun_ld.ylim[0] = System->Sun.MinYSun; - sun_ld.ylim[1] = System->Sun.MaxYSun; - sun_ld.min_unit_dx = d_elm_max; - sun_ld.min_unit_dy = d_elm_max; - - sun_hash.create_mesh(sun_ld); - - // load stage 0 elements into the mesh - for (uint_fast64_t i = 0; i < System->StageList[0]->ElementList.size(); i++) - { - TElement *el = System->StageList[0]->ElementList.at(i).get(); - sun_hash.add_object((void *)el, el->PosSunCoords[0], el->PosSunCoords[1]); - } - - // calculate and associate neighbors with each zone - sun_hash.add_neighborhood_data(); - - if (AsPowerTower) - { - // Set things up for the polar coordinate tree - KDLayoutData rec_ld; - rec_ld.xlim[0] = -PI; - rec_ld.xlim[1] = PI; - rec_ld.ylim[0] = -PI / 2.; - rec_ld.ylim[1] = PI / 2.; - // use smallest element to set the minimum size - rec_ld.min_unit_dx = rec_ld.min_unit_dy = el_proj_dat.back().d_proj; // radians at equator - - rec_hash.create_mesh(rec_ld); - - // load stage 0 elements into the receiver mesh in the order of largest projection to smallest - for (int i = 0; i < el_proj_dat.size(); i++) - { - eprojdat *D = &el_proj_dat.at(i); - - // Calculate the angular span of the element - double angspan[2]; - double adjmult = 1.5; - angspan[0] = D->d_proj / cos(fabs(D->zen)) * adjmult; // azimuthal span - angspan[0] = fmin(angspan[0], 2. * PI); // limit to circumference - angspan[1] = D->d_proj / PI * adjmult; // zenithal span - rec_hash.add_object((void *)D->el_addr, D->az, D->zen, angspan); - } - - // associate neighbors with each zone - rec_hash.add_neighborhood_data(); - } + void SetupPTOptimizations( + // system info + TSystem *System, const bool AsPowerTower, + // outputs + st_hash_tree &sun_hash, + st_hash_tree &rec_hash, + glm::dvec3& reccm_helio) + { + // Calculate the center of mass of the receiver stage (StageList[1]) in + // heliostat stage coordinates. + glm::dvec3 reccm(0.0, 0.0, 0.0); + + int nelrec = 0; + if (AsPowerTower) + { + for (uint_fast64_t j = 0; j < System->StageList[1]->ElementList.size(); j++) + { + TElement *el = System->StageList[1]->ElementList.at(j).get(); + + // if (!el->Enabled) + // continue; + + nelrec++; + + for (int jj = 0; jj < 3; jj++) + reccm[jj] += el->Origin[jj]; + } + for (int jj = 0; jj < 3; jj++) + reccm[jj] /= (double)nelrec; // average + + // Transform to reference + glm::dvec3 dum1(0.0, 0.0, 1.0); + glm::dvec3 dum2; + glm::dvec3 reccm_global; + + Data::TransformToReference(reccm, + dum1, + System->StageList[1]->Origin, + System->StageList[1]->RLocToRef, + reccm_global, + dum2); + + // Transform to local (heliostat). reccm_helio is the x,y,z position + // of the receiver centroid in heliostat stage coordinates. + Data::TransformToLocal(reccm_global, + dum1, + System->StageList[0]->Origin, + System->StageList[0]->RRefToLoc, + reccm_helio, + dum2); + } + // Create an array that stores the element address and the projected size + // in polar coordinates + std::vector el_proj_dat; + el_proj_dat.reserve(System->StageList[0]->ElementList.size()); + + // calculate the smallest zone size. This should be on the order of the + // largest element in the stage. load stage 0 elements into the mesh + double d_elm_max = -9.e9; + double d_elm; + + for (uint_fast64_t i = 0; i < System->StageList[0]->ElementList.size(); i++) + { + TElement *el = System->StageList[0]->ElementList.at(i).get(); + + // el->element_number = i + 1; // use index for element number + + d_elm = el->aperture->diameter_circumscribed_circle(); + + // double d_elm; + + // switch (el->ShapeIndex) + // { + // // circular aperture + // case 'c': + // case 'C': + // // hexagonal aperture + // case 'h': + // case 'H': + // // triangular aperture + // case 't': + // case 'T': + // d_elm = el->ParameterA; + // break; + // // rectangular aperture + // case 'r': + // case 'R': + // d_elm = sqrt(el->ParameterA * el->ParameterA + el->ParameterB * el->ParameterB); + // break; + // // annular aperture + // case 'a': + // case 'A': + // d_elm = el->ParameterB; + // break; + // case 'l': + // case 'L': + // // off axis aperture section of line focus trough or cylinder + // d_elm = sqrt(el->ParameterB * el->ParameterB * 4. + el->ParameterC * el->ParameterC); + // break; + // // Irregular triangle + // case 'i': + // case 'I': + // // irregular quadrilateral + // case 'q': + // case 'Q': + // { + // double xmax = fmax(el->ParameterA, fmax(el->ParameterC, el->ParameterE)); + // double xmin = fmin(el->ParameterA, fmin(el->ParameterC, el->ParameterE)); + // double ymax = fmax(el->ParameterB, fmax(el->ParameterD, el->ParameterF)); + // double ymin = fmin(el->ParameterB, fmin(el->ParameterD, el->ParameterF)); + + // if (el->ShapeIndex == 'q' || el->ShapeIndex == 'Q') + // { + // xmax = fmax(xmax, el->ParameterG); + // xmin = fmin(xmin, el->ParameterG); + // ymax = fmax(ymax, el->ParameterH); + // ymin = fmin(ymin, el->ParameterH); + // } + + // double dx = xmax - xmin; + // double dy = ymax - ymin; + + // d_elm = sqrt(dx * dx + dy * dy); + + // break; + // } + // default: + // break; + // } + + d_elm_max = fmax(d_elm_max, d_elm); + + if (AsPowerTower) + { + // Calculate the distance from the receiver to the element and the max projected size + double dX[3]; + for (int jj = 0; jj < 3; jj++) + dX[jj] = el->Origin[jj] - reccm_helio[jj]; // vector from receiver to heliostat (not unitized) + double r_elm = 0.; + for (int jj = 0; jj < 3; jj++) + r_elm += dX[jj] * dX[jj]; + r_elm = sqrt(r_elm); // vector length + double d_elm_proj = d_elm / r_elm; // Projected size of the element from the view of the receiver (radians) + + // calculate az,zen coordinate + double az, zen; + az = atan2(dX[0] / r_elm, dX[1] / r_elm); // Az coordinate of the heliostat from the receiver's perspective + zen = asin(dX[2] / r_elm); // Zen coordinate """" + + el_proj_dat.push_back(eprojdat(el, d_elm_proj, az, zen)); + } + } + + if (AsPowerTower) + { + // Sort the polar projections by size, largest to smallest + std::sort(el_proj_dat.begin(), el_proj_dat.end(), eprojdat_compare_refactored); + } + + // set up the layout data object that provides configuration details for + // the hash tree + KDLayoutData sun_ld; + sun_ld.xlim[0] = System->Sun.MinXSun; + sun_ld.xlim[1] = System->Sun.MaxXSun; + sun_ld.ylim[0] = System->Sun.MinYSun; + sun_ld.ylim[1] = System->Sun.MaxYSun; + sun_ld.min_unit_dx = d_elm_max; + sun_ld.min_unit_dy = d_elm_max; + + sun_hash.create_mesh(sun_ld); + + // load stage 0 elements into the mesh + for (uint_fast64_t i = 0; i < System->StageList[0]->ElementList.size(); i++) + { + TElement *el = System->StageList[0]->ElementList.at(i).get(); + sun_hash.add_object((void *)el, el->PosSunCoords[0], el->PosSunCoords[1]); + } + + // calculate and associate neighbors with each zone + sun_hash.add_neighborhood_data(); + + if (AsPowerTower) + { + // Set things up for the polar coordinate tree + KDLayoutData rec_ld; + rec_ld.xlim[0] = -PI; + rec_ld.xlim[1] = PI; + rec_ld.ylim[0] = -PI / 2.; + rec_ld.ylim[1] = PI / 2.; + // use smallest element to set the minimum size + rec_ld.min_unit_dx = rec_ld.min_unit_dy = el_proj_dat.back().d_proj; // radians at equator + + rec_hash.create_mesh(rec_ld); + + // load stage 0 elements into the receiver mesh in the order of largest projection to smallest + for (int i = 0; i < el_proj_dat.size(); i++) + { + eprojdat *D = &el_proj_dat.at(i); + + // Calculate the angular span of the element + double angspan[2]; + double adjmult = 1.5; + angspan[0] = D->d_proj / cos(fabs(D->zen)) * adjmult; // azimuthal span + angspan[0] = fmin(angspan[0], 2. * PI); // limit to circumference + angspan[1] = D->d_proj / PI * adjmult; // zenithal span + rec_hash.add_object((void *)D->el_addr, D->az, D->zen, angspan); + } + + // associate neighbors with each zone + rec_hash.add_neighborhood_data(); + } } - uint_fast64_t GetPTElements( - // system info - const bool AsPowerTower, + uint_fast64_t GetPTElements( + // system info + const bool AsPowerTower, - // Stage info - // const TStage *Stage - const tstage_ptr Stage, - const int i, + // Stage info + // const TStage *Stage + const tstage_ptr Stage, + const int i, - // Ray info - const bool in_multi_hit_loop, - const double (&PosRayStage)[3], - const double (&reccm_helio)[3], - st_hash_tree *rec_hash, + // Ray info + const bool in_multi_hit_loop, + const glm::dvec3& PosRayStage, + const glm::dvec3& reccm_helio, + st_hash_tree* rec_hash, - const std::vector &sunint_elements, + const std::vector& sunint_elements, - // Outputs - std::vector &reflint_elements, - bool &has_elements) - { + // Outputs + std::vector& reflint_elements, + bool& has_elements) + { uint_fast64_t nintelements = 0; if (i == 0) diff --git a/coretrace/simulation_runner/native_runner/pt_optimizations.hpp b/coretrace/simulation_runner/native_runner/pt_optimizations.hpp index bee4536a..ae38c6db 100644 --- a/coretrace/simulation_runner/native_runner/pt_optimizations.hpp +++ b/coretrace/simulation_runner/native_runner/pt_optimizations.hpp @@ -34,16 +34,16 @@ void SetupPTOptimizations(TSystem *System, const bool AsPowerTower, st_hash_tree &sun_hash, st_hash_tree &rec_hash, - double (&reccm_helio)[3]); + glm::dvec3 &reccm_helio); uint_fast64_t GetPTElements(const bool AsPowerTower, const tstage_ptr Stage, const int i, - const bool in_multi_hit_loop, - const double (&PosRayStage)[3], - const double (&reccm_helio)[3], + const bool in_multi_hit_loop, + const glm::dvec3 &PosRayStage, + const glm::dvec3 &reccm_helio, st_hash_tree *rec_hash, - const std::vector &sunint_elements, + const std::vector &suntint_elements, std::vector &reflint_elements, bool &has_elements); diff --git a/coretrace/simulation_runner/native_runner/sphere_calculator.cpp b/coretrace/simulation_runner/native_runner/sphere_calculator.cpp index af0719a7..01c32d25 100644 --- a/coretrace/simulation_runner/native_runner/sphere_calculator.cpp +++ b/coretrace/simulation_runner/native_runner/sphere_calculator.cpp @@ -11,7 +11,7 @@ #include "simulation_data_export.hpp" #include "surface.hpp" -// #include "vector3d.hpp" +// #include "glm::dvec3.hpp" namespace SolTrace::NativeRunner { @@ -58,11 +58,11 @@ namespace SolTrace::NativeRunner return; } - int SphereCalculator::intersect(const double PosLoc[3], - const double CosLoc[3], - double PosXYZ[3], - double CosKLM[3], - double DFXYZ[3], + int SphereCalculator::intersect(const glm::dvec3 PosLoc, + const glm::dvec3 CosLoc, + glm::dvec3& PosXYZ, + glm::dvec3& CosKLM, + glm::dvec3& DFXYZ, double *PathLength) { // std::cout << "SphereCalculator" << std::endl; @@ -77,15 +77,15 @@ namespace SolTrace::NativeRunner double a, b, c; double scratch; - Vector3d p1, p2; + glm::dvec3 p1, p2; c = x0 * x0 + y0 * y0 + z0 * z0 - 2.0 * r * z0; b = 2.0 * (alpha * x0 + beta * y0 + gamma * (z0 - r)); a = alpha * alpha + beta * beta + gamma * gamma; - ZeroVec3(PosXYZ); - ZeroVec3(CosKLM); - ZeroVec3(DFXYZ); + PosXYZ = {}; + CosKLM = {}; + DFXYZ = {}; scratch = b * b - 4.0 * a * c; @@ -105,8 +105,8 @@ namespace SolTrace::NativeRunner // z1 = z0 + gamma * t1; // z2 = z0 + gamma * t2; - AddVec3(1.0, PosLoc, t1, CosLoc, p1.data); - AddVec3(1.0, PosLoc, t2, CosLoc, p2.data); + p1 = PosLoc + t1 * CosLoc; + p2 = PosLoc + t2 * CosLoc; // std::cout << "P1: " << p1 // << "\nP2: " << p2 @@ -116,14 +116,14 @@ namespace SolTrace::NativeRunner { // SetVec3(PosXYZ, x0 + t1 * alpha, y0 + t1 * beta, z1); // AddVec3(1.0, PosLoc, t1, CosLoc, PosXYZ); - CopyVec3(PosXYZ, p1.data); + PosXYZ = p1; *PathLength = t1; } else if (t2 > 0.0 && p2[2] <= r && this->aper->is_in(p2[0], p2[1])) { // SetVec3(PosXYZ, x0 + t2 * alpha, y0 + t2 * beta, z2); // AddVec3(1.0, PosLoc, t2, CosLoc, PosXYZ); - CopyVec3(PosXYZ, p2.data); + PosXYZ = p2; *PathLength = t2; } else @@ -136,13 +136,13 @@ namespace SolTrace::NativeRunner if (sts == 0) { this->surface_normal(PosXYZ, DFXYZ); - CopyVec3(CosKLM, CosLoc); + CosKLM = CosLoc; } // if (sts == 0) // { - // Vector3d p0(PosLoc), v0(CosLoc); - // Vector3d p1(PosXYZ), n0(DFXYZ); + // glm::dvec3 p0(PosLoc), v0(CosLoc); + // glm::dvec3 p1(PosXYZ), n0(DFXYZ); // std::cout << "Ray Position: " << p0 // << "\nRay Direction: " << v0 @@ -155,8 +155,8 @@ namespace SolTrace::NativeRunner return sts; } - void SphereCalculator::surface_normal(const double PosXYZ[3], - double DFXYZ[3]) + void SphereCalculator::surface_normal(const glm::dvec3 PosXYZ, + glm::dvec3 &DFXYZ) { double x0 = PosXYZ[0]; double y0 = PosXYZ[1]; diff --git a/coretrace/simulation_runner/native_runner/sphere_calculator.hpp b/coretrace/simulation_runner/native_runner/sphere_calculator.hpp index a5e45cd3..5bc96e04 100644 --- a/coretrace/simulation_runner/native_runner/sphere_calculator.hpp +++ b/coretrace/simulation_runner/native_runner/sphere_calculator.hpp @@ -15,14 +15,14 @@ namespace SolTrace::NativeRunner SphereCalculator(SolTrace::Data::surface_ptr surf, SolTrace::Data::aperture_ptr ap); virtual ~SphereCalculator() {} - virtual int intersect(const double PosLoc[3], - const double CosLoc[3], - double PosXYZ[3], - double CosKLM[3], - double DFXYZ[3], + virtual int intersect(const glm::dvec3 PosLoc, + const glm::dvec3 CosLoc, + glm::dvec3& PosXYZ, + glm::dvec3& CosKLM, + glm::dvec3& DFXYZ, double *PathLength); - void surface_normal(const double PosXYZ[3], double DFXYZ[3]); + void surface_normal(const glm::dvec3 PosXYZ, glm::dvec3& DFXYZ); virtual double compute_z_aperture(SolTrace::Data::aperture_ptr ap); diff --git a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp index 190a1799..857554d1 100644 --- a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp +++ b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp @@ -13,7 +13,7 @@ namespace SolTrace::NativeRunner TSystem *System, TStage *Stage, TSun *Sun, - double PosSunStage[3]) + glm::dvec3 PosSunStage) { /*{Purpose: To compute the sun position within primary sage and the maximum radius of a cicle seen from sun which encircles @@ -29,17 +29,17 @@ namespace SolTrace::NativeRunner }*/ double dx = 0, dy = 0, dz = 0, dtot = 0; - double CosSunGlob[3] = {0.0, 0.0, 0.0}; - double PosSunGlob[3] = {0.0, 0.0, 0.0}; - double CosSunStage[3] = {0.0, 0.0, 0.0}; + glm::dvec3 CosSunGlob(0.0, 0.0, 0.0); + glm::dvec3 PosSunGlob(0.0, 0.0, 0.0); + glm::dvec3 CosSunStage(0.0, 0.0, 0.0); uint_fast64_t i = 0; double x = 0, y = 0, radius = 0; - double Origin[3] = {0.0, 0.0, 0.0}; - double CosDum[3] = {0.0, 0.0, 0.0}; - double PosLoc[3] = {0.0, 0.0, 0.0}; - double CosLoc[3] = {0.0, 0.0, 0.0}; - double RRefToLoc[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; + glm::dvec3 Origin(0.0, 0.0, 0.0); + glm::dvec3 CosDum(0.0, 0.0, 0.0); + glm::dvec3 PosLoc(0.0, 0.0, 0.0); + glm::dvec3 CosLoc(0.0, 0.0, 0.0); + glm::dmat3 RRefToLoc(0.0); double radius1 = 0.0, radius2 = 0.0, radius3 = 0.0, radius4 = 0.0, radiustemp = 0.0; double Xsum = 0.0, Ysum = 0.0, xminsun = 0.0, yminsun = 0.0, xmaxsun = 0.0, ymaxsun = 0.0; double XLegofRadius = 0.0; @@ -75,7 +75,12 @@ namespace SolTrace::NativeRunner // Transform sun direction vector to Stage system; CosSunStage is dir cosines of sun ray in Stage coord. system // PosSunStage is position of sun coord. system origin in Stage system - TransformToLocal(PosSunGlob, CosSunGlob, Stage->Origin, Stage->RRefToLoc, PosSunStage, CosSunStage); + Data::TransformToLocal(PosSunGlob, + CosSunGlob, + Stage->Origin, + Stage->RRefToLoc, + PosSunStage, + CosSunStage); Sun->Euler[0] = atan2(CosSunStage[0], CosSunStage[2]); // Euler angles relating sun to Stage system Sun->Euler[1] = asin(CosSunStage[1]); @@ -101,7 +106,7 @@ namespace SolTrace::NativeRunner Sun->MaxYSun = -1.0e20; Sun->MinYSun = 1.0e20; - CalculateTransformMatrices(Sun->Euler, RRefToLoc, Sun->RLocToRef); + Data::CalculateTransformMatrices(Sun->Euler, RRefToLoc, Sun->RLocToRef); //{Now calculate center of mass of projected distribution. Added 09/26/05} Xsum = 0.0; @@ -124,8 +129,7 @@ namespace SolTrace::NativeRunner // TransformToLocal(iter->second->Origin, CosDum, Origin, // RRefToLoc, PosLoc, CosLoc); elem = *iter; - TransformToLocal(elem->Origin, CosDum, Origin, - RRefToLoc, PosLoc, CosLoc); + Data::TransformToLocal(elem->Origin, CosDum, Origin, RRefToLoc, PosLoc, CosLoc); Xsum += PosLoc[0]; Ysum += PosLoc[1]; } @@ -150,8 +154,7 @@ namespace SolTrace::NativeRunner elem = *iter; // TransformToLocal(Stage->ElementList[i]->Origin, CosDum, Origin, RRefToLoc, PosLoc, CosLoc); - TransformToLocal(elem->Origin, CosDum, Origin, - RRefToLoc, PosLoc, CosLoc); + Data::TransformToLocal(elem->Origin, CosDum, Origin, RRefToLoc, PosLoc, CosLoc); // Now have PosLoc which is the projected position of element[i] in xy plane of sun coord. system x = PosLoc[0] - Sun->Xcm; // changes origin to center of mass of all elements 09/26/05 y = PosLoc[1] - Sun->Ycm; diff --git a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp index 2d23f6cc..3617bae6 100644 --- a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp +++ b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp @@ -7,12 +7,8 @@ namespace SolTrace::NativeRunner { - bool SunToPrimaryStage( - thread_manager_ptr manager, - TSystem *System, - TStage *Stage, - TSun *Sun, - double PosSunStage[3]); +bool SunToPrimaryStage( + thread_manager_ptr manager, TSystem *System, TStage *Stage, TSun *Sun, glm::dvec3 PosSunStage); } // namespace SolTrace::NativeRunner diff --git a/coretrace/simulation_runner/native_runner/surface_intersection_calculator.hpp b/coretrace/simulation_runner/native_runner/surface_intersection_calculator.hpp index 6169bd25..6df6744e 100644 --- a/coretrace/simulation_runner/native_runner/surface_intersection_calculator.hpp +++ b/coretrace/simulation_runner/native_runner/surface_intersection_calculator.hpp @@ -3,6 +3,8 @@ #include +#include + #include "aperture.hpp" namespace SolTrace::NativeRunner { @@ -13,14 +15,12 @@ class SurfaceIntersectionCalculator SurfaceIntersectionCalculator() {} ~SurfaceIntersectionCalculator() {} - // TODO: Should probably move these to using Vector3d rather - // than arrays of doubles... // TODO: Not sure what purpose CosKLM serves here. Investigate... - virtual int intersect(const double PosLoc[3], - const double CosLoc[3], - double PosXYZ[3], - double CosKLM[3], - double DFXYZ[3], + virtual int intersect(const glm::dvec3 PosLoc, + const glm::dvec3 CosLoc, + glm::dvec3& PosXYZ, + glm::dvec3& CosKLM, + glm::dvec3& DFXYZ, double *PathLength) = 0; virtual double compute_z_aperture(SolTrace::Data::aperture_ptr ap) = 0; diff --git a/coretrace/simulation_runner/native_runner/trace.cpp b/coretrace/simulation_runner/native_runner/trace.cpp index 7bbef786..07150df8 100644 --- a/coretrace/simulation_runner/native_runner/trace.cpp +++ b/coretrace/simulation_runner/native_runner/trace.cpp @@ -93,15 +93,15 @@ namespace SolTrace::NativeRunner bool AsPowerTower) { // Initialize Sun - Vector3d PosSunStage; - if (!SunToPrimaryStage(manager, - System, - System->StageList[0].get(), - &System->Sun, - PosSunStage.data)) - return RunnerStatus::ERROR; - - // Determine if PT optimizations should be applied + glm::dvec3 PosSunStage; + if (!SunToPrimaryStage(manager, + System, + System->StageList[0].get(), + &System->Sun, + PosSunStage)) + return RunnerStatus::ERROR; + + // Determine if PT optimizations should be applied bool PT_override = false; if (System->StageList.size() > 0 && (System->StageList[0]->ElementList.size() < 10 || System->StageList.size() == 1)) @@ -113,14 +113,13 @@ namespace SolTrace::NativeRunner st_hash_tree sun_hash; st_hash_tree rec_hash; // double reccm_helio[3]; // receiver centroid in heliostat field coordinates - Vector3d reccm_helio; + glm::dvec3 reccm_helio; if (!PT_override) { - SetupPTOptimizations(System, AsPowerTower, sun_hash, - rec_hash, reccm_helio.data); - } + SetupPTOptimizations(System, AsPowerTower, sun_hash, rec_hash, reccm_helio); + } - // Bundle many args into a struct because the compiler was + // Bundle many args into a struct because the compiler was // having trouble with all the arguments... ThreadInfo my_info; my_info.manager = manager; @@ -170,10 +169,10 @@ namespace SolTrace::NativeRunner bool IncludeSunShape, bool IncludeErrors, bool AsPowerTower, - const Vector3d &PosSunStage, + const glm::dvec3 &PosSunStage, st_hash_tree *sun_hash, st_hash_tree *rec_hash, - const Vector3d &reccm_helio) + const glm::dvec3 &reccm_helio) { // Initialize variables MTRand myrng(seed); @@ -240,16 +239,16 @@ namespace SolTrace::NativeRunner // Loop through rays while (StageHasRays) { - // Initialize Global Coordinates - double PosRayGlob[3] = {0.0, 0.0, 0.0}; - double CosRayGlob[3] = {0.0, 0.0, 0.0}; + // Initialize Global Coordinates + glm::dvec3 PosRayGlob(0.0, 0.0, 0.0); + glm::dvec3 CosRayGlob(0.0, 0.0, 0.0); - // Initialize Stage Coordinates - double PosRayStage[3] = {0.0, 0.0, 0.0}; - double CosRayStage[3] = {0.0, 0.0, 0.0}; + // Initialize Stage Coordinates + glm::dvec3 PosRayStage(0.0, 0.0, 0.0); + glm::dvec3 CosRayStage(0.0, 0.0, 0.0); - // Initialize PT Optimization variables - bool has_elements = true; + // Initialize PT Optimization variables + bool has_elements = true; std::vector sunint_elements; // Get Ray @@ -259,13 +258,18 @@ namespace SolTrace::NativeRunner // argument. Should fix that. // Make ray (if first stage) - double PosRaySun[3]; - GenerateRay(myrng, PosSunStage.data, Stage->Origin, - Stage->RLocToRef, &System->Sun, - PosRayGlob, CosRayGlob, PosRaySun); - sun_ray_count_local++; - - // If using PT optimizations, check if stage has elements + glm::dvec3 PosRaySun; + GenerateRay(myrng, + PosSunStage, + Stage->Origin, + Stage->RLocToRef, + &System->Sun, + PosRayGlob, + CosRayGlob, + PosRaySun); + sun_ray_count_local++; + + // If using PT optimizations, check if stage has elements // that could interact with ray if (!PT_override) { @@ -279,35 +283,42 @@ namespace SolTrace::NativeRunner { // Get ray from previous stage RayNumber = IncomingRays[StageDataArrayIndex].Num; - CopyVec3(PosRayGlob, IncomingRays[StageDataArrayIndex].Pos); - CopyVec3(CosRayGlob, IncomingRays[StageDataArrayIndex].Cos); - StageDataArrayIndex++; - } + PosRayGlob = IncomingRays[StageDataArrayIndex].Pos; + CosRayGlob = IncomingRays[StageDataArrayIndex].Cos; + StageDataArrayIndex++; + } // transform the global incoming ray to local stage coordinates - TransformToLocal(PosRayGlob, CosRayGlob, - Stage->Origin, Stage->RRefToLoc, - PosRayStage, CosRayStage); - - // Initialize internal variables for ray intersection tracing - bool RayInStage = true; - bool in_multi_hit_loop = false; - double LastPosRaySurfElement[3] = {0.0, 0.0, 0.0}; - double LastCosRaySurfElement[3] = {0.0, 0.0, 0.0}; - double LastPosRaySurfStage[3] = {0.0, 0.0, 0.0}; - double LastCosRaySurfStage[3] = {0.0, 0.0, 0.0}; - double LastDFXYZ[3] = {0.0, 0.0, 0.0}; - uint_fast64_t LastElementNumber = 0; - uint_fast64_t LastRayNumber = 0; - int ErrorFlag; - int LastHitBackSide; - bool StageHit; - int MultipleHitCount = 0; - double PosRayOutElement[3] = {0.0, 0.0, 0.0}; - double CosRayOutElement[3] = {0.0, 0.0, 0.0}; - - // Start Loop to trace ray until it leaves stage - bool RayIsAbsorbed = false; + Data::TransformToLocal(PosRayGlob, + CosRayGlob, + Stage->Origin, + Stage->RRefToLoc, + PosRayStage, + CosRayStage); + + // Initialize internal variables for ray intersection tracing + bool RayInStage = true; + bool in_multi_hit_loop = false; + + glm::dvec3 LastPosRaySurfElement(0.0, 0.0, 0.0); + glm::dvec3 LastCosRaySurfElement(0.0, 0.0, 0.0); + glm::dvec3 LastPosRaySurfStage(0.0, 0.0, 0.0); + glm::dvec3 LastCosRaySurfStage(0.0, 0.0, 0.0); + glm::dvec3 LastDFXYZ(0.0, 0.0, 0.0); + + uint_fast64_t LastElementNumber = 0; + uint_fast64_t LastRayNumber = 0; + + int ErrorFlag; + int LastHitBackSide; + bool StageHit; + int MultipleHitCount = 0; + + glm::dvec3 PosRayOutElement(0.0, 0.0, 0.0); + glm::dvec3 CosRayOutElement(0.0, 0.0, 0.0); + + // Start Loop to trace ray until it leaves stage + bool RayIsAbsorbed = false; while (RayInStage) { // Set number of elements to search through @@ -315,18 +326,21 @@ namespace SolTrace::NativeRunner std::vector reflint_elements; if (!PT_override) // if using opt AND first stage { - nintelements = GetPTElements(AsPowerTower, Stage, i, - in_multi_hit_loop, PosRayStage, - reccm_helio.data, rec_hash, - sunint_elements, - reflint_elements, has_elements); - } - else - { - nintelements = Stage->ElementList.size(); - } - - // Find the element the ray hits + nintelements = GetPTElements(AsPowerTower, + Stage, + i, + in_multi_hit_loop, + PosRayStage, + reccm_helio, + rec_hash, + sunint_elements, + reflint_elements, + has_elements); + } else { + nintelements = Stage->ElementList.size(); + } + + // Find the element the ray hits FindElementHit(i, Stage, PT_override, AsPowerTower, nintelements, sunint_elements, reflint_elements, @@ -373,12 +387,10 @@ namespace SolTrace::NativeRunner if (Stage->Virtual) { // If stage is virtual, there is no interaction - CopyVec3(PosRayOutElement, LastPosRaySurfElement); - CopyVec3(CosRayOutElement, LastCosRaySurfElement); - } - else - { - // trace through the interaction + PosRayOutElement = LastPosRaySurfElement; + CosRayOutElement = LastCosRaySurfElement; + } else { + // trace through the interaction telement_ptr optelm = Stage->ElementList[LastElementNumber - 1]; if (LastHitBackSide) @@ -387,9 +399,9 @@ namespace SolTrace::NativeRunner optics = &optelm->Optics.Front; double TestValue; - double UnitLastDFXYZ[3] = {0.0, 0.0, 0.0}; - double IncidentAngle = 0; - // switch (optelm->InteractionType) + glm::dvec3 UnitLastDFXYZ(0.0, 0.0, 0.0); + double IncidentAngle = 0; + // switch (optelm->InteractionType) switch (optics->my_type) { case InteractionType::REFRACTION: // refraction @@ -474,9 +486,9 @@ namespace SolTrace::NativeRunner RayIsAbsorbed = true; break; } - } + } - // Process Interaction + // Process Interaction int_fast64_t k = LastElementNumber - 1; ProcessInteraction(System, myrng, @@ -493,28 +505,28 @@ namespace SolTrace::NativeRunner PosRayOutElement); // Transform ray back to stage coordinate system - TransformToReference(PosRayOutElement, - CosRayOutElement, - Stage->ElementList[k]->Origin, - Stage->ElementList[k]->RLocToRef, - PosRayStage, - CosRayStage); - TransformToReference(PosRayStage, - CosRayStage, - Stage->Origin, - Stage->RLocToRef, - PosRayGlob, - CosRayGlob); - - System->RayData.Append(thread_id, - PosRayGlob, - CosRayGlob, - LastElementNumber, - i + 1, - LastRayNumber, - rev); - - // Break out if multiple hits are not allowed + Data::TransformToReference(PosRayOutElement, + CosRayOutElement, + Stage->ElementList[k]->Origin, + Stage->ElementList[k]->RLocToRef, + PosRayStage, + CosRayStage); + Data::TransformToReference(PosRayStage, + CosRayStage, + Stage->Origin, + Stage->RLocToRef, + PosRayGlob, + CosRayGlob); + + System->RayData.Append(thread_id, + PosRayGlob, + CosRayGlob, + LastElementNumber, + i + 1, + LastRayNumber, + rev); + + // Break out if multiple hits are not allowed if (!Stage->MultiHitsPerRay) { StageHit = false; @@ -538,14 +550,14 @@ namespace SolTrace::NativeRunner // Handle if Ray was absorbed if (RayIsAbsorbed) { - TransformToReference(LastPosRaySurfStage, - LastCosRaySurfStage, - Stage->Origin, - Stage->RLocToRef, - PosRayGlob, - CosRayGlob); - - System->RayData.Append(thread_id, + Data::TransformToReference(LastPosRaySurfStage, + LastCosRaySurfStage, + Stage->Origin, + Stage->RLocToRef, + PosRayGlob, + CosRayGlob); + + System->RayData.Append(thread_id, PosRayGlob, CosRayGlob, LastElementNumber, @@ -594,11 +606,9 @@ namespace SolTrace::NativeRunner else { // Ray hit an element, so save it for next stage - CopyVec3(IncomingRays[PreviousStageDataArrayIndex].Pos, - PosRayGlob); - CopyVec3(IncomingRays[PreviousStageDataArrayIndex].Cos, - CosRayGlob); - IncomingRays[PreviousStageDataArrayIndex].Num = RayNumber; + IncomingRays[PreviousStageDataArrayIndex].Pos = PosRayGlob; + IncomingRays[PreviousStageDataArrayIndex].Cos = CosRayGlob; + IncomingRays[PreviousStageDataArrayIndex].Num = RayNumber; // Is Ray the last in the stage? if (RayNumber == NumberOfRays) @@ -622,11 +632,9 @@ namespace SolTrace::NativeRunner if (Stage->TraceThrough || MultipleHitCount > 0) { // Ray is saved for the next stage - CopyVec3(IncomingRays[PreviousStageDataArrayIndex].Pos, - PosRayGlob); - CopyVec3(IncomingRays[PreviousStageDataArrayIndex].Cos, - CosRayGlob); - IncomingRays[PreviousStageDataArrayIndex].Num = RayNumber; + IncomingRays[PreviousStageDataArrayIndex].Pos = PosRayGlob; + IncomingRays[PreviousStageDataArrayIndex].Cos = CosRayGlob; + IncomingRays[PreviousStageDataArrayIndex].Num = RayNumber; // Check if ray is last in stage if (RayNumber == LastRayNumberInPreviousStage) diff --git a/coretrace/simulation_runner/native_runner/trace.hpp b/coretrace/simulation_runner/native_runner/trace.hpp index 99c10598..4337d9df 100644 --- a/coretrace/simulation_runner/native_runner/trace.hpp +++ b/coretrace/simulation_runner/native_runner/trace.hpp @@ -25,8 +25,8 @@ namespace SolTrace::NativeRunner Pos[i] = Cos[i] = 0.0; } - double Pos[3]; - double Cos[3]; + glm::dvec3 Pos; + glm::dvec3 Cos; uint_fast64_t Num; // bool active; }; @@ -143,20 +143,19 @@ namespace SolTrace::NativeRunner bool IncludeErrors, bool AsPowerTower); - SolTrace::Runner::RunnerStatus trace_single_thread( - unsigned thread_id, - thread_manager_ptr manager, - TSystem *System, - unsigned seed, - uint_fast64_t NumberOfRays, - uint_fast64_t MaxNumberOfRays, - bool IncludeSunShape, - bool IncludeErrors, - bool AsPowerTower, - const SolTrace::Data::Vector3d &PosSunStage, - st_hash_tree *sun_hash, - st_hash_tree *rec_hash, - const SolTrace::Data::Vector3d &reccm_helio); + SolTrace::Runner::RunnerStatus trace_single_thread(unsigned thread_id, + thread_manager_ptr manager, + TSystem *System, + unsigned seed, + uint_fast64_t NumberOfRays, + uint_fast64_t MaxNumberOfRays, + bool IncludeSunShape, + bool IncludeErrors, + bool AsPowerTower, + const glm::dvec3 &PosSunStage, + st_hash_tree *sun_hash, + st_hash_tree *rec_hash, + const glm::dvec3 &reccm_helio); struct ThreadInfo { @@ -168,10 +167,10 @@ namespace SolTrace::NativeRunner bool IncludeSunShape; bool IncludeErrors; bool AsPowerTower; - SolTrace::Data::Vector3d PosSunStage; + glm::dvec3 PosSunStage; st_hash_tree *sun_hash; st_hash_tree *rec_hash; - SolTrace::Data::Vector3d reccm_helio; + glm::dvec3 reccm_helio; }; // Hack to get around stupid compiler issue diff --git a/coretrace/simulation_runner/native_runner/tracing_errors.cpp b/coretrace/simulation_runner/native_runner/tracing_errors.cpp index be26e4ba..8489468a 100644 --- a/coretrace/simulation_runner/native_runner/tracing_errors.cpp +++ b/coretrace/simulation_runner/native_runner/tracing_errors.cpp @@ -19,9 +19,9 @@ namespace SolTrace::NativeRunner { // - Reduce the random number calls. I.e., sample theta directly rather than thetax and thetay -> this will break tests because the number of RNG calls will change. void SurfaceNormalErrors(MTRand &myrng, - double CosIn[3], - const OpticalProperties *OptProperties, - double CosOut[3]) noexcept(false) // throw(nanexcept) + glm::dvec3 &CosIn, + const SolTrace::Data::OpticalProperties *OptProperties, + glm::dvec3 &CosOut) noexcept(false) // throw(nanexcept) { /*{Purpose: To add error terms to the surface normal vector at the surface in question @@ -34,49 +34,42 @@ void SurfaceNormalErrors(MTRand &myrng, Output - CosOut = Output direction cosine vector of surface normal after error terms have been included }*/ - int i = 0; - double Origin[3] = {0.0, 0.0, 0.0}, - Euler[3] = {0.0, 0.0, 0.0}; - double PosIn[3] = {0.0, 0.0, 0.0}, - PosOut[3] = {0.0, 0.0, 0.0}; - DistributionType dist; - double delop = 0.0, thetax = 0.0, - thetay = 0.0, theta2 = 0.0, - phi = 0.0, theta = 0.0; - double RRefToLoc[3][3] = {{0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0}}; - double RLocToRef[3][3] = {{0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0}}; + int i = 0; - if (CosIn[2] == 0.0) - { - if (CosIn[0] == 0.0) - { - Euler[0] = 0.0; + glm::dvec3 Origin(0.0, 0.0, 0.0); + glm::dvec3 Euler(0.0, 0.0, 0.0); + + glm::dvec3 PosIn(0.0, 0.0, 0.0); + glm::dvec3 PosOut(0.0, 0.0, 0.0); + + DistributionType dist; + + double delop = 0.0, thetax = 0.0, thetay = 0.0, theta2 = 0.0, phi = 0.0, theta = 0.0; + + glm::dmat3 RRefToLoc(0.0); + glm::dmat3 RLocToRef(0.0); + + if (CosIn[2] == 0.0) { + if (CosIn[0] == 0.0) { + Euler[0] = 0.0; Euler[1] = PI / 2.0; - } - else - { - Euler[0] = PI / 2.0; + } else { + Euler[0] = PI / 2.0; Euler[1] = atan2(CosIn[1], sqrt(CosIn[0] * CosIn[0] + CosIn[2] * CosIn[2])); - } - } - else - { - Euler[0] = atan2(CosIn[0], CosIn[2]); - Euler[1] = atan2(CosIn[1], sqrt(CosIn[0] * CosIn[0] + CosIn[2] * CosIn[2])); - } + } + } else { + Euler[0] = atan2(CosIn[0], CosIn[2]); + Euler[1] = atan2(CosIn[1], sqrt(CosIn[0] * CosIn[0] + CosIn[2] * CosIn[2])); + } - Euler[2] = 0.0; + Euler[2] = 0.0; - CalculateTransformMatrices(Euler, RRefToLoc, RLocToRef); + Data::CalculateTransformMatrices(Euler, RRefToLoc, RLocToRef); - // TODO: Add distribution type to optical properties - // dist = OptProperties->DistributionType; - dist = OptProperties->error_distribution_type; - // delop = OptProperties->RMSSlopeError / 1000.0; + // TODO: Add distribution type to optical properties + // dist = OptProperties->DistributionType; + dist = OptProperties->error_distribution_type; + // delop = OptProperties->RMSSlopeError / 1000.0; delop = OptProperties->slope_error / 1000.0; switch (dist) @@ -105,11 +98,11 @@ void SurfaceNormalErrors(MTRand &myrng, /* {Transform to local coordinate system of ray to set up rotation matrices for coord and inverse transforms} */ - TransformToLocal(PosIn, CosIn, Origin, RRefToLoc, PosOut, CosOut); + Data::TransformToLocal(PosIn, CosIn, Origin, RRefToLoc, PosOut, CosOut); - /* {Generate errors in terms of direction cosines in local ray coordinate system} */ - theta = sqrt(theta2); - // phi = atan2(thetay, thetax); //This function appears to present irregularities that bias results incorrectly for small values of thetay or thetax + /* {Generate errors in terms of direction cosines in local ray coordinate system} */ + theta = sqrt(theta2); + // phi = atan2(thetay, thetax); //This function appears to present irregularities that bias results incorrectly for small values of thetay or thetax phi = myrng() * 2.0 * PI; // Therefore have chosen to randomize phi rather than calculate from randomized theta components // obtained from the distribution. The two approaches are equivalent save for this issue with arctan2. wendelin 01-12-11 @@ -124,20 +117,19 @@ void SurfaceNormalErrors(MTRand &myrng, } /*{Transform perturbed ray back to element system}*/ - TransformToReference(PosIn, CosIn, Origin, RLocToRef, PosOut, CosOut); + Data::TransformToReference(PosIn, CosIn, Origin, RLocToRef, PosOut, CosOut); } void Errors( - MTRand &myrng, - double CosIn[3], - int Source, - TSun *Sun, - // telement_ptr Element, - const OpticalProperties *OptProperties, - // TElement *Element, - // TOpticalProperties *OptProperties, - double CosOut[3], - double DFXYZ[3]) + MTRand& myrng, + glm::dvec3& CosIn, + int Source, + TSun* Sun, + // TElement *Element, + // TOpticalProperties *OptProperties, + const SolTrace::Data::OpticalProperties* OptProperties, + glm::dvec3& CosOut, + glm::dvec3& DFXYZ) { /*{Purpose: To add error terms to the perturbed ray at the surface in question @@ -157,15 +149,18 @@ void Errors( Output - CosOut = Output direction cosine vector of ray after error terms have been included }*/ - double Origin[3] = {0.0, 0.0, 0.0}; - double Euler[3] = {0.0, 0.0, 0.0}; - double PosIn[3] = {0.0, 0.0, 0.0}; - double PosOut[3] = {0.0, 0.0, 0.0}; - // char dist = 'g'; - double delop = 0, thetax = 0, thetay = 0, theta2 = 0, phi = 0, theta = 0, stest = 0; - uint_fast64_t i; - double RRefToLoc[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; - double RLocToRef[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; + glm::dvec3 Origin(0.0, 0.0, 0.0); + glm::dvec3 Euler(0.0, 0.0, 0.0); + glm::dvec3 PosIn(0.0, 0.0, 0.0); + glm::dvec3 PosOut(0.0, 0.0, 0.0); + + // char dist = 'g'; + double delop = 0.0, thetax = 0.0, thetay = 0.0, theta2 = 0.0, phi = 0.0, theta = 0.0, stest = 0.0; + uint_fast64_t i; + + glm::dmat3 RRefToLoc(0.0); + glm::dmat3 RLocToRef(0.0); + if (CosIn[2] == 0.0) { @@ -188,9 +183,9 @@ void Errors( Euler[2] = 0.0; - CalculateTransformMatrices(Euler, RRefToLoc, RLocToRef); + Data::CalculateTransformMatrices(Euler, RRefToLoc, RLocToRef); - unsigned int maxcall = 0; + unsigned int maxcall = 0; // g,p,d if (Source == 1) // sun error { @@ -313,12 +308,12 @@ void Errors( } // {Transform to local coordinate system of ray to set up rotation matrices for coordinate and inverse transforms} - TransformToLocal(PosIn, CosIn, Origin, RRefToLoc, PosOut, CosOut); + Data::TransformToLocal(PosIn, CosIn, Origin, RRefToLoc, PosOut, CosOut); - // {Generate errors in terms of direction cosines in local ray coordinate system} - theta = sqrt(theta2); + // {Generate errors in terms of direction cosines in local ray coordinate system} + theta = sqrt(theta2); - // phi = atan2(thetay, thetax); //This function appears to present irregularities that bias results incorrectly for small values of thetay or thetax + // phi = atan2(thetay, thetax); //This function appears to present irregularities that bias results incorrectly for small values of thetay or thetax phi = myrng() * 2.0 * PI; // Therefore have chosen to randomize phi rather than calculate from randomized theta components // obtained from the distribution. The two approaches are equivalent save for this issue with arctan2. wendelin 01-12-11 @@ -333,15 +328,15 @@ void Errors( } //{Transform perturbed ray back to element system} - TransformToReference(PosIn, CosIn, Origin, RLocToRef, PosOut, CosOut); + Data::TransformToReference(PosIn, CosIn, Origin, RLocToRef, PosOut, CosOut); - // TODO: Remove goto, should we always do dot product check? // We could move this out of the function and into the caller. + // TODO: Remove goto, should we always do dot product check? // We could move this out of the function and into the caller. - /*{If reflection error application and new ray direction (after errors) physically goes through opaque surface, + /*{If reflection error application and new ray direction (after errors) physically goes through opaque surface, then go back and get new perturbation 06-12-07}*/ if ((Source == 2) && (OptProperties->my_type == InteractionType::REFLECTION) && - (DOT(CosOut, DFXYZ) < 0) && + (glm::dot(CosOut, DFXYZ) < 0) && maxcall++ < 50000) { goto Label_50; diff --git a/coretrace/simulation_runner/native_runner/tracing_errors.hpp b/coretrace/simulation_runner/native_runner/tracing_errors.hpp index cdf2eb83..cdb2ee42 100644 --- a/coretrace/simulation_runner/native_runner/tracing_errors.hpp +++ b/coretrace/simulation_runner/native_runner/tracing_errors.hpp @@ -8,20 +8,21 @@ namespace SolTrace::NativeRunner { -void Errors(MTRand &myrng, - double CosIn[3], +void Errors(MTRand& myrng, + glm::dvec3& CosIn, int Source, - TSun *Sun, + TSun* Sun, // TElement *Element, // TOpticalProperties *OptProperties, - const SolTrace::Data::OpticalProperties *OptProperties, - double CosOut[3], - double DFXYZ[3]); - -void SurfaceNormalErrors(MTRand &myrng, - double CosIn[3], - const SolTrace::Data::OpticalProperties *OptProperties, - double CosOut[3]) noexcept(false); // throw(nanexcept); + const SolTrace::Data::OpticalProperties* OptProperties, + glm::dvec3& CosOut, + glm::dvec3& DFXYZ); + +void SurfaceNormalErrors(MTRand& myrng, + glm::dvec3& CosIn, + const SolTrace::Data::OpticalProperties* OptProperties, + glm::dvec3& CosOut) noexcept(false); // throw(nanexcept); + } // namespace SolTrace::NativeRunner diff --git a/google-tests/regression-tests/native_runner_validation_test.cpp b/google-tests/regression-tests/native_runner_validation_test.cpp index 1e62f269..ee8ded90 100644 --- a/google-tests/regression-tests/native_runner_validation_test.cpp +++ b/google-tests/regression-tests/native_runner_validation_test.cpp @@ -147,9 +147,9 @@ TEST(NativeRunner, ValidationTest1) EXPECT_EQ(sts, RunnerStatus::SUCCESS); EXPECT_EQ(result.get_number_of_records(), NRAYS); - Vector3d point, cosines; - Vector3d pos_stage, dir_stage; - Vector3d temp; + glm::dvec3 point, cosines; + glm::dvec3 pos_stage, dir_stage; + glm::dvec3 temp; int_fast64_t element; int_fast64_t stage; uint_fast64_t rayidx; @@ -286,17 +286,17 @@ TEST(NativeRunner, ValidationTest1) // if (fabs(pos_stage[0] - stod(ground_raydata[0][i]) > TOL)) // { - // Vector3d pos_csv(stod(ground_raydata[0][i]), + // glm::dvec3 pos_csv(stod(ground_raydata[0][i]), // stod(ground_raydata[1][i]), // stod(ground_raydata[2][i])); - // Vector3d dir_csv(stod(ground_raydata[3][i]), + // glm::dvec3 dir_csv(stod(ground_raydata[3][i]), // stod(ground_raydata[4][i]), // stod(ground_raydata[5][i])); - // Vector3d pos_loc; - // Vector3d dir_loc; + // glm::dvec3 pos_loc; + // glm::dvec3 dir_loc; - // Vector3d csv_glob; + // glm::dvec3 csv_glob; // el->convert_stage_to_local(temp, pos_csv); // el->convert_local_to_global(csv_glob, temp); @@ -478,9 +478,9 @@ TEST(NativeRunner, ValidationTest2) // result.write_csv_file("native_runner_result_dump.csv"); - Vector3d point, cosines; - Vector3d pos_stage, dir_stage; - Vector3d temp; + glm::dvec3 point, cosines; + glm::dvec3 pos_stage, dir_stage; + glm::dvec3 temp; int_fast64_t element; int_fast64_t stage; uint_fast64_t rayidx; @@ -620,7 +620,7 @@ TEST(NativeRunner, ValidationTest2) // See previous comment about coordinates el->convert_vector_global_to_reference(dir_stage, cosines); - RTOL = vector_norm(pos_stage) * TOL; + RTOL = glm::length(pos_stage) * TOL; EXPECT_NEAR(pos_stage[0], stod(ground_raydata[0][i]), RTOL); EXPECT_NEAR(pos_stage[1], stod(ground_raydata[1][i]), RTOL); EXPECT_NEAR(pos_stage[2], stod(ground_raydata[2][i]), RTOL); @@ -645,17 +645,17 @@ TEST(NativeRunner, ValidationTest2) // if (fabs(pos_stage[0] - stod(ground_raydata[0][i]) > TOL)) // { - // Vector3d pos_csv(stod(ground_raydata[0][i]), + // glm::dvec3 pos_csv(stod(ground_raydata[0][i]), // stod(ground_raydata[1][i]), // stod(ground_raydata[2][i])); - // Vector3d dir_csv(stod(ground_raydata[3][i]), + // glm::dvec3 dir_csv(stod(ground_raydata[3][i]), // stod(ground_raydata[4][i]), // stod(ground_raydata[5][i])); - // Vector3d pos_loc; - // Vector3d dir_loc; + // glm::dvec3 pos_loc; + // glm::dvec3 dir_loc; - // Vector3d csv_glob; + // glm::dvec3 csv_glob; // el->convert_stage_to_local(temp, pos_csv); // el->convert_local_to_global(csv_glob, temp); diff --git a/google-tests/test_tools/count_absorbed_native.cpp b/google-tests/test_tools/count_absorbed_native.cpp index 95674cda..8d998404 100644 --- a/google-tests/test_tools/count_absorbed_native.cpp +++ b/google-tests/test_tools/count_absorbed_native.cpp @@ -17,7 +17,7 @@ uint_fast64_t count_event_native(const SolTrace::NativeRunner::TRayData *ray_dat size_t n = ray_data->Count(); for (size_t i = 0; i < n; i++) { - double pos[3], cos[3]; + glm::dvec3 pos, cos; int elm, stage; uint_fast64_t ray; SolTrace::Result::RayEvent rev; @@ -36,7 +36,7 @@ void scan_events_native(const SolTrace::NativeRunner::TRayData *ray_data) std::map ray_end; for (size_t i = 0; i < n; i++) { - double pos[3], cos[3]; + glm::dvec3 pos, cos; int elm, stage; uint_fast64_t ray; SolTrace::Result::RayEvent rev; diff --git a/google-tests/unit-tests/common/common.cpp b/google-tests/unit-tests/common/common.cpp index de0b32b9..77e82a25 100644 --- a/google-tests/unit-tests/common/common.cpp +++ b/google-tests/unit-tests/common/common.cpp @@ -7,35 +7,23 @@ #include #include #include -#include -bool is_identical(const Vector3d &x, const Vector3d &y) +bool is_identical(const glm::dvec3 &x, const glm::dvec3 &y) { - return ( - x.data[0] == y.data[0] && - x.data[1] == y.data[1] && - x.data[2] == y.data[2]); + return x == y; } -bool is_identical(const Vector3d &x, const Vector3d &y, double tol) +bool is_identical(const glm::dvec3 &x, const glm::dvec3 &y, double tol) { return ( - fabs(x.data[0] - y.data[0]) <= tol && - fabs(x.data[1] - y.data[1]) <= tol && - fabs(x.data[2] - y.data[2]) <= tol); + fabs(x.x - y.x) <= tol && + fabs(x.y - y.y) <= tol && + fabs(x.z - y.z) <= tol); } -bool is_identical(const Matrix3d &A, const Matrix3d &B) +bool is_identical(const glm::dmat3 &A, const glm::dmat3 &B) { - bool all_identical = true; - for (int i = 0; i < 3; ++i) - { - for (int j = 0; j < 3; ++j) - { - all_identical &= A.data[i][j] == B.data[i][j]; - } - } - return all_identical; + return A == B; } element_ptr make_configured_element() diff --git a/google-tests/unit-tests/common/common.hpp b/google-tests/unit-tests/common/common.hpp index 7223e8e3..dfed582b 100644 --- a/google-tests/unit-tests/common/common.hpp +++ b/google-tests/unit-tests/common/common.hpp @@ -3,17 +3,17 @@ #include #include -#include +#include // Vectors exactly match component-wise -bool is_identical(const SolTrace::Data::Vector3d &x, - const SolTrace::Data::Vector3d &y); +bool is_identical(const glm::dvec3 &x, + const glm::dvec3 &y); // Each vector component are within `tol` of each other so ||x - y||_\infty <= tol -bool is_identical(const SolTrace::Data::Vector3d &x, - const SolTrace::Data::Vector3d &y, +bool is_identical(const glm::dvec3 &x, + const glm::dvec3 &y, double tol); -bool is_identical(const SolTrace::Data::Matrix3d &A, - const SolTrace::Data::Matrix3d &B); +bool is_identical(const glm::dmat3 &A, + const glm::dmat3 &B); // Convenience function for making element with all // required fields are set. Used when the test does not diff --git a/google-tests/unit-tests/simulation_data/cst-templates/heliostat_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/heliostat_test.cpp index fe852c95..89e9d86b 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/heliostat_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/heliostat_test.cpp @@ -139,7 +139,7 @@ TEST(Heliostat, ErrorChecking_CreateGeometryWithoutParameters) hs->set_canting(SolTrace::Data::Heliostat::NONE, 0.0, 0.0); EXPECT_THROW(hs->create_geometry(), std::invalid_argument); - hs->set_target_position(Vector3d(0.0, 0.0, 10.0)); + hs->set_target_position(glm::dvec3(0.0, 0.0, 10.0)); EXPECT_NO_THROW(hs->create_geometry()); } @@ -158,7 +158,7 @@ TEST(Heliostat, BuildParabolaNone) hs->set_focal_length(156.06); // hs->set_focal_point(0.0, 0.0, 156.06); hs->set_canting(Heliostat::NONE, 0.0, 0.0); - hs->set_target_position(Vector3d(0.0, 0.0, 1.0)); + hs->set_target_position(glm::dvec3(0.0, 0.0, 1.0)); hs->create_geometry(); // TODO: Check that everything ends up in the proper position @@ -177,9 +177,9 @@ TEST(Heliostat, BuildFlatOnAxis) hs->set_number_panels(3, 4); hs->set_gaps(0.1, 0.1); hs->set_focal_length(0.0); - // hs->set_focal_point(Vector3d(0.0, 0.0, 10.0)); + // hs->set_focal_point(glm::dvec3(0.0, 0.0, 10.0)); hs->set_canting(Heliostat::NONE, 0.0, 0.0); - hs->set_target_position(Vector3d(0.0, 0.0, 1.0)); + hs->set_target_position(glm::dvec3(0.0, 0.0, 1.0)); hs->create_geometry(); // TODO: Check that everything ends up in the proper position @@ -189,8 +189,8 @@ TEST(Heliostat, Trace) { constexpr uint_fast64_t NRAYS = 10000; constexpr uint_fast64_t N_ABSORBED_THRESH = NRAYS / 10; - const Vector3d zero(0.0, 0.0, 0.0); - const Vector3d khat(0.0, 0.0, 1.0); + const glm::dvec3 zero(0.0, 0.0, 0.0); + const glm::dvec3 khat(0.0, 0.0, 1.0); SimulationData my_sim; // Set parameters @@ -213,17 +213,14 @@ TEST(Heliostat, Trace) stage_ptr st2 = SolTrace::Data::make_stage(2); st2->set_reference_frame_geometry(zero, khat, 0.0); - Vector3d sun_pos(0.0, 0.0, 1000.0); - Vector3d hs_origin(1.0, 1.0, 0.0); - Vector3d abs_origin(0.0, 0.0, 10.0); - Vector3d v1; - Vector3d v2; - Vector3d aim; - Vector3d aim_point; - vector_add(1.0, sun_pos, -1.0, hs_origin, v1); - vector_add(1.0, abs_origin, -1.0, hs_origin, v2); - vector_add(0.5, v1, 0.5, v2, aim); - vector_add(1.0, hs_origin, 1.0, aim, aim_point); + glm::dvec3 sun_pos(0.0, 0.0, 1000.0); + glm::dvec3 hs_origin(1.0, 1.0, 0.0); + glm::dvec3 abs_origin(0.0, 0.0, 10.0); + + glm::dvec3 v1 = sun_pos - hs_origin; + glm::dvec3 v2 = abs_origin - hs_origin; + glm::dvec3 aim = 0.5 * v1 + 0.5 * v2; + glm::dvec3 aim_point = hs_origin + aim; auto hs = SolTrace::Data::make_element(); hs->set_optics(mirror); @@ -256,8 +253,8 @@ TEST(Heliostat, Trace) // absorb->set_zrot(0.0); // absorb->compute_coordinate_rotations(); // aim.scalar_mult(-1.0); - vector_add(1.0, hs_origin, -1.0, abs_origin, aim); - vector_add(1.0, abs_origin, 1.0, aim, aim_point); + aim = hs_origin - abs_origin; + aim_point = abs_origin + aim; absorb->set_reference_frame_geometry(abs_origin, aim_point, 0.0); absorb->set_name("Absorber"); absorb->enable(); @@ -335,17 +332,13 @@ TEST(Heliostat, ErrorChecking_UpdateGeometry) OpticalProperties mirror; mirror.set_ideal_reflection(); - Vector3d sun_pos(0.0, 0.0, 1000.0); - Vector3d hs_origin(1.0, 1.0, 0.0); - Vector3d abs_origin(0.0, 0.0, 10.0); - Vector3d v1; - Vector3d v2; - Vector3d aim; - Vector3d aim_point; - vector_add(1.0, sun_pos, -1.0, hs_origin, v1); - vector_add(1.0, abs_origin, -1.0, hs_origin, v2); - vector_add(0.5, v1, 0.5, v2, aim); - vector_add(1.0, hs_origin, 1.0, aim, aim_point); + glm::dvec3 sun_pos(0.0, 0.0, 1000.0); + glm::dvec3 hs_origin(1.0, 1.0, 0.0); + glm::dvec3 abs_origin(0.0, 0.0, 10.0); + glm::dvec3 v1 = sun_pos - hs_origin; + glm::dvec3 v2 = abs_origin - hs_origin; + glm::dvec3 aim = 0.5 * v1 + 0.5 * v2; + glm::dvec3 aim_point = hs_origin + aim; auto hs = SolTrace::Data::make_element(); hs->set_optics(mirror); @@ -400,10 +393,10 @@ TEST(Heliostat, UpdateGeometry) OpticalProperties mirror; mirror.set_ideal_reflection(); - Vector3d sun_pos; - sun_position_vector_degrees(sun_pos, sun_az, sun_el); - // Vector3d hs_origin(1.0, 1.0, 0.0); - Vector3d abs_origin(0.0, 0.0, 2.0); + glm::dvec3 sun_pos; + SolTrace::Data::sun_position_vector_degrees(sun_pos, sun_az, sun_el); + // glm::dvec3 hs_origin(1.0, 1.0, 0.0); + glm::dvec3 abs_origin(0.0, 0.0, 2.0); auto hs = SolTrace::Data::make_element(); hs->set_optics(mirror); @@ -422,17 +415,11 @@ TEST(Heliostat, UpdateGeometry) EXPECT_TRUE(SolTrace::Data::Element::is_success(ret)); hs->update_geometry(sun_az, sun_el); - Vector3d result; - vector_add(-1.0, hs->get_origin_global(), - 1.0, hs->get_aim_vector_global(), - result); - result.make_unit(); - Vector3d temp; - vector_add(1.0, abs_origin, -1.0, hs->get_origin_global(), temp); - temp.make_unit(); - double phi1 = acos(dot_product(result, sun_pos)) * SolTrace::Data::R2D; - double phi2 = acos(dot_product(result, temp)) * SolTrace::Data::R2D; - double phi3 = acos(dot_product(sun_pos, temp)) * SolTrace::Data::R2D; + glm::dvec3 result = glm::normalize(-hs->get_origin_global() + hs->get_aim_vector_global()); + glm::dvec3 temp = glm::normalize(abs_origin - hs->get_origin_global()); + double phi1 = acos(glm::dot(result, sun_pos)) * SolTrace::Data::R2D; + double phi2 = acos(glm::dot(result, temp)) * SolTrace::Data::R2D; + double phi3 = acos(glm::dot(sun_pos, temp)) * SolTrace::Data::R2D; EXPECT_NEAR(phi1, phi2, TOL); EXPECT_NEAR(phi1 + phi2, phi3, TOL); @@ -451,8 +438,8 @@ TEST(Heliostat, UpdateGeometry) // aim.scalar_mult(-1.0); // vector_add(1.0, hs_origin, -1.0, abs_origin, aim); // vector_add(1.0, abs_origin, 1.0, aim, aim_point); - Vector3d aim_point(0.0, 0.0, 1.0); - vector_add(1.0, abs_origin, 1.0, aim_point); + glm::dvec3 aim_point(0.0, 0.0, 1.0); + aim_point = abs_origin + aim_point; absorb->set_reference_frame_geometry(abs_origin, aim_point, 0.0); absorb->set_name("Absorber"); absorb->enable(); diff --git a/google-tests/unit-tests/simulation_data/cst-templates/linear_fresnel_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/linear_fresnel_test.cpp index 81141cc3..abf50019 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/linear_fresnel_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/linear_fresnel_test.cpp @@ -256,7 +256,7 @@ TEST(LinearFresnel, Tracing) my_sim.add_ray_source(sun); // Assumes that reference and global coordinates are the same - // Vector3d pt_aim_point; + // glm::dvec3 pt_aim_point; // vector_add(1.0, sun->get_position(), -1.0, lf->get_origin_ref(), pt_aim_point); // lf->set_aim_vector(pt_aim_point); lf->set_aim_vector(sun->get_position()); @@ -383,9 +383,9 @@ TEST(LinearFresnel, UpdateGeometry) envelop_in.specularity_error = 1e-4; auto sun = SolTrace::Data::make_ray_source(); - Vector3d sun_pos; - sun_position_vector_degrees(sun_pos, sun_az, sun_el); - sun_pos.scalar_mult(1000.0); + glm::dvec3 sun_pos; + SolTrace::Data::sun_position_vector_degrees(sun_pos, sun_az, sun_el); + sun_pos *= 1000.0; sun->set_position(sun_pos); sun->set_shape(SolTrace::Data::SunShape::GAUSSIAN, 1.0, 0.0, 0.0); my_sim.add_ray_source(sun); @@ -413,13 +413,13 @@ TEST(LinearFresnel, UpdateGeometry) // lf->get_neutral_normal()), // 0.0, 1e-12); - EXPECT_NEAR(dot_product(lf->get_tracking_origin(), + EXPECT_NEAR(glm::dot(lf->get_tracking_origin(), lf->get_rotation_vector()), 0.0, TOL); - EXPECT_NEAR(dot_product(lf->get_tracking_origin(), + EXPECT_NEAR(glm::dot(lf->get_tracking_origin(), lf->get_neutral_normal()), 0.0, TOL); - EXPECT_NEAR(dot_product(lf->get_rotation_vector(), + EXPECT_NEAR(glm::dot(lf->get_rotation_vector(), lf->get_neutral_normal()), 0.0, TOL); @@ -507,17 +507,16 @@ TEST(LinearFresnel, UpdateGeometry_TrackingLimits) lf->set_name("LinearFresnel"); lf->enable(); - Vector3d normal; + glm::dvec3 normal; double theta; lf->update_geometry(-sun_az, sun_el); for (auto citer : lf->get_mirrors()) { - vector_add(1.0, citer->get_aim_vector_global(), - -1.0, citer->get_origin_global(), - normal); - normal.make_unit(); + normal = citer->get_aim_vector_global() + + -1.0 * citer->get_origin_global(); + SolTrace::Data::normalize_inplace(normal); // Dot product with [0, 0, 1] theta = acos(normal[2]); if (normal[0] < 0.0) @@ -532,10 +531,10 @@ TEST(LinearFresnel, UpdateGeometry_TrackingLimits) lf->update_geometry(sun_az, sun_el); for (auto citer : lf->get_mirrors()) { - vector_add(1.0, citer->get_aim_vector_global(), - -1.0, citer->get_origin_global(), - normal); - normal.make_unit(); + normal = citer->get_aim_vector_global() - citer->get_origin_global(); + + SolTrace::Data::normalize_inplace(normal); + // Dot product with [1, 0, 0] theta = acos(normal[2]); if (normal[0] < 0.0) diff --git a/google-tests/unit-tests/simulation_data/cst-templates/parabolic_dish_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/parabolic_dish_test.cpp index 52a917c3..adc4ac7f 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/parabolic_dish_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/parabolic_dish_test.cpp @@ -213,7 +213,7 @@ TEST(ParabolicDish, UpdateGeometry) // sun->set_position(0.0, 0.0, 1000.0); // double NaN = std::numeric_limits::quiet_NaN(); sun->set_shape(SolTrace::Data::SunShape::PILLBOX, 0.0, 1.0, 0.0); - sun_position_vector_degrees(sun->get_position(), sun_az, sun_el); + SolTrace::Data::sun_position_vector_degrees(sun->get_position(), sun_az, sun_el); // sun->get_position().scalar_mult(1000.0); // std::cout << "Sun Position: " << sun->get_position() << std::endl; my_sim.add_ray_source(sun); @@ -255,7 +255,7 @@ TEST(ParabolicDish, UpdateGeometry) // else if (el->is_composite()) // { // dish = std::dynamic_pointer_cast(el); - // Vector3d aim_loc; + // glm::dvec3 aim_loc; // dish->convert_reference_to_local(aim_loc, dish->get_aim_vector_ref()); // std::cout << "\nElevation Axis: " << dish->get_elevation_axis() // << "\nAim (local): " << aim_loc diff --git a/google-tests/unit-tests/simulation_data/cst-templates/parabolic_trough_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/parabolic_trough_test.cpp index 56dacec0..1e88b242 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/parabolic_trough_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/parabolic_trough_test.cpp @@ -12,6 +12,8 @@ #include "common.hpp" #include "count_absorbed_native.h" +#include + using ParabolicTrough = SolTrace::Data::ParabolicTrough; using SolTrace::Runner::RunnerStatus; @@ -258,7 +260,7 @@ TEST(ParabolicTrough, Tracing) my_sim.add_ray_source(sun); // Assumes that reference and global coordinates are the same - // Vector3d pt_aim_point; + // glm::dvec3 pt_aim_point; // vector_add(1.0, sun->get_position(), -1.0, pt->get_origin_ref(), pt_aim_point); // pt->set_aim_vector(pt_aim_point); pt->set_aim_vector(sun->get_position()); @@ -384,9 +386,9 @@ TEST(ParabolicTrough, UpdateGeometry) pt->update_geometry(sun_az, sun_el); - Vector3d sun_pos; - sun_position_vector_degrees(sun_pos, sun_az, sun_el); - sun_pos.scalar_mult(1000.0); + glm::dvec3 sun_pos; + SolTrace::Data::sun_position_vector_degrees(sun_pos, sun_az, sun_el); + sun_pos *= 1000.0; auto sun = SolTrace::Data::make_ray_source(); sun->set_position(sun_pos); sun->set_shape(SolTrace::Data::SunShape::PILLBOX, 0.0, 1.0, 0.0); @@ -401,12 +403,12 @@ TEST(ParabolicTrough, UpdateGeometry) << "\nZ-Rotation: " << pt->get_zrot() << std::endl; - EXPECT_NEAR(dot_product(pt->get_tracking_origin(), pt->get_rotation_vector()), 0.0, TOL); - EXPECT_NEAR(dot_product(pt->get_tracking_origin(), pt->get_neutral_normal()), 0.0, TOL); - EXPECT_NEAR(dot_product(pt->get_rotation_vector(), pt->get_neutral_normal()), 0.0, TOL); + EXPECT_NEAR(glm::dot(pt->get_tracking_origin(), pt->get_rotation_vector()), 0.0, TOL); + EXPECT_NEAR(glm::dot(pt->get_tracking_origin(), pt->get_neutral_normal()), 0.0, TOL); + EXPECT_NEAR(glm::dot(pt->get_rotation_vector(), pt->get_neutral_normal()), 0.0, TOL); - Vector3d temp, result; - rotate_vector_degrees(pt->get_rotation_vector(), + glm::dvec3 temp, result; + SolTrace::Data::rotate_vector_degrees(pt->get_rotation_vector(), pt->get_tracking_origin(), pt->get_tracking_angle_degrees(), temp); @@ -422,7 +424,7 @@ TEST(ParabolicTrough, UpdateGeometry) EXPECT_NEAR(result[1], 1.0, TOL); EXPECT_NEAR(result[2], 0.0, TOL); - rotate_vector_degrees(pt->get_rotation_vector(), + SolTrace::Data::rotate_vector_degrees(pt->get_rotation_vector(), pt->get_neutral_normal(), pt->get_tracking_angle_degrees(), temp); @@ -519,12 +521,11 @@ TEST(ParabolicTrough, UpdateGeometry_TrackingLimits) // << "\nZ-Rotation: " << pt->get_zrot() // << std::endl; EXPECT_NEAR(pt->get_tracking_angle_degrees(), UPPER, TOL); - Vector3d normal = pt->get_aim_vector_global(); - normal.make_unit(); + glm::dvec3 normal = glm::normalize(pt->get_aim_vector_global()); EXPECT_NEAR(normal[0], cos(UPPER * D2R), TOL); EXPECT_NEAR(normal[1], 0.0, TOL); EXPECT_NEAR(normal[2], sin(UPPER * D2R), TOL); - Vector3d upper = pt->get_tracking_limit_upper(); + glm::dvec3 upper = pt->get_tracking_limit_upper(); for (unsigned k = 0; k < 3; ++k) { EXPECT_NEAR(normal[k], upper[k], TOL); @@ -532,12 +533,11 @@ TEST(ParabolicTrough, UpdateGeometry_TrackingLimits) pt->update_geometry(-sun_az, sun_el); EXPECT_NEAR(pt->get_tracking_angle_degrees(), LOWER, TOL); - normal = pt->get_aim_vector_global(); - normal.make_unit(); + normal = glm::normalize(pt->get_aim_vector_global()); EXPECT_NEAR(normal[0], cos(LOWER * D2R), TOL); EXPECT_NEAR(normal[1], 0.0, TOL); EXPECT_NEAR(normal[2], sin(LOWER * D2R), TOL); - Vector3d lower = pt->get_tracking_limit_lower(); + glm::dvec3 lower = pt->get_tracking_limit_lower(); for (unsigned k = 0; k < 3; ++k) { EXPECT_NEAR(normal[k], lower[k], TOL); diff --git a/google-tests/unit-tests/simulation_data/cst-templates/utilities_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/utilities_test.cpp index 87e4a602..b97695c1 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/utilities_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/utilities_test.cpp @@ -2,34 +2,33 @@ #include -#include #include #include "common.hpp" TEST(Utilities, Projection) { - Vector3d v(1.0, 1.0, 1.0); - Vector3d u(5.0, -2.0, -3.0); + glm::dvec3 v(1.0, 1.0, 1.0); + glm::dvec3 u(5.0, -2.0, -3.0); - Vector3d u_para; - Vector3d u_perp; - Vector3d scratch, temp1, temp2; + glm::dvec3 u_para; + glm::dvec3 u_perp; + glm::dvec3 scratch, temp1, temp2; - project_onto_vector(v, u, u_para); - project_onto_plane(v, u, u_perp); + SolTrace::Data::project_onto_vector(v, u, u_para); + SolTrace::Data::project_onto_plane(v, u, u_perp); - EXPECT_DOUBLE_EQ(dot_product(v, u_perp), 0.0); - EXPECT_DOUBLE_EQ(dot_product(u_para, u_perp), 0.0); + EXPECT_DOUBLE_EQ(glm::dot(v, u_perp), 0.0); + EXPECT_DOUBLE_EQ(glm::dot(u_para, u_perp), 0.0); temp1 = u; temp2 = u; // Inplace project operations - project_onto_vector(v, temp1); - project_onto_plane(v, temp2); + SolTrace::Data::project_onto_vector(v, temp1); + SolTrace::Data::project_onto_plane(v, temp2); - vector_add(1.0, u_para, 1.0, u_perp, scratch); + scratch = u_para + u_perp; for(unsigned k=0; k < 3; ++k) { EXPECT_DOUBLE_EQ(scratch[k], u[k]); diff --git a/google-tests/unit-tests/simulation_data/element_test.cpp b/google-tests/unit-tests/simulation_data/element_test.cpp index 96b78a50..f23a4596 100644 --- a/google-tests/unit-tests/simulation_data/element_test.cpp +++ b/google-tests/unit-tests/simulation_data/element_test.cpp @@ -29,8 +29,8 @@ TEST(Element, ConstructionSmokeTest) TEST(Element, SingleElementAccessors) { SingleElement ref; - Vector3d zero(0.0, 0.0, 0.0); - Vector3d khat(0.0, 0.0, 1.0); + glm::dvec3 zero(0.0, 0.0, 0.0); + glm::dvec3 khat(0.0, 0.0, 1.0); EXPECT_TRUE(is_identical(ref.get_origin_ref(), zero)); EXPECT_TRUE(is_identical(ref.get_aim_vector_ref(), khat)); EXPECT_TRUE(is_identical(ref.get_euler_angles(), zero)); @@ -53,15 +53,15 @@ TEST(Element, SingleElementAccessors) ref.unmark_virtual(); EXPECT_FALSE(ref.is_virtual()); - auto pos = Vector3d(2.0, 1.0, -3.0); + auto pos = glm::dvec3(2.0, 1.0, -3.0); ref.set_origin(pos); EXPECT_TRUE(is_identical(ref.get_origin_ref(), pos)); - auto aim = Vector3d(-1.0, 0.0, 1.0); + auto aim = glm::dvec3(-1.0, 0.0, 1.0); ref.set_aim_vector(aim); EXPECT_TRUE(is_identical(ref.get_aim_vector_ref(), aim)); - // auto eulers = Vector3d(0.1, 0.2, -0.3); + // auto eulers = glm::dvec3(0.1, 0.2, -0.3); // // ref.set_euler_angles(eulers); // EXPECT_TRUE(is_identical(ref.get_euler_angles(), eulers)); @@ -306,12 +306,12 @@ TEST(Element, CoordinateComputationsIdentity) { auto el = make_configured_element(); auto st = SolTrace::Data::make_stage(0); - Vector3d origin(0.0, 0.0, 0.0); - Vector3d aim(0.0, 0.0, 1.0); - Vector3d local(1.0, 1.0, 1.0); - Vector3d ref(1.0, 1.0, 1.0); - Vector3d result; - result.zero(); + glm::dvec3 origin(0.0, 0.0, 0.0); + glm::dvec3 aim(0.0, 0.0, 1.0); + glm::dvec3 local(1.0, 1.0, 1.0); + glm::dvec3 ref(1.0, 1.0, 1.0); + glm::dvec3 result; + result = glm::dvec3(0.0); double zrot = 0.0; el->set_reference_frame_geometry(origin, aim, zrot); @@ -320,34 +320,34 @@ TEST(Element, CoordinateComputationsIdentity) // Conversion test el->convert_local_to_global(result, local); EXPECT_TRUE(is_identical(ref, result)); - result.zero(); + result = glm::dvec3(0.0); el->convert_local_to_stage(result, local); EXPECT_TRUE(is_identical(ref, result)); - result.zero(); + result = glm::dvec3(0.0); el->convert_local_to_reference(result, local); EXPECT_TRUE(is_identical(ref, result)); - result.zero(); + result = glm::dvec3(0.0); st->convert_local_to_global(result, local); EXPECT_TRUE(is_identical(ref, result)); - result.zero(); + result = glm::dvec3(0.0); st->convert_local_to_stage(result, local); EXPECT_TRUE(is_identical(ref, result)); - result.zero(); + result = glm::dvec3(0.0); st->convert_local_to_reference(result, local); EXPECT_TRUE(is_identical(ref, result)); - result.zero(); + result = glm::dvec3(0.0); st->add_element(el); el->convert_local_to_global(result, local); EXPECT_TRUE(is_identical(ref, result)); - result.zero(); + result = glm::dvec3(0.0); el->convert_local_to_stage(result, local); EXPECT_TRUE(is_identical(ref, result)); - result.zero(); + result = glm::dvec3(0.0); el->convert_local_to_reference(result, local); EXPECT_TRUE(is_identical(ref, result)); - result.zero(); + result = glm::dvec3(0.0); // Origin location tests EXPECT_TRUE(is_identical(origin, st->get_origin_ref())); @@ -368,19 +368,19 @@ TEST(Element, CoordinateComputationsIdentity) EXPECT_TRUE(is_identical(aim, el->get_aim_vector_global())); // Operators - Matrix3d Q; - Q.identity(); - Matrix3d RtoL = el->get_reference_to_local(); + glm::dmat3 Q = {}; + + glm::dmat3 RtoL = el->get_reference_to_local(); EXPECT_TRUE(is_identical(RtoL, Q)); - Matrix3d LtoR = el->get_local_to_reference(); + glm::dmat3 LtoR = el->get_local_to_reference(); EXPECT_TRUE(is_identical(LtoR, Q)); - Matrix3d StoL = el->get_stage_to_local(); + glm::dmat3 StoL = el->get_stage_to_local(); EXPECT_TRUE(is_identical(StoL, Q)); - Matrix3d LtoS = el->get_local_to_stage(); + glm::dmat3 LtoS = el->get_local_to_stage(); EXPECT_TRUE(is_identical(LtoS, Q)); - Matrix3d GtoL = el->get_global_to_local(); + glm::dmat3 GtoL = el->get_global_to_local(); EXPECT_TRUE(is_identical(GtoL, Q)); - Matrix3d LtoG = el->get_local_to_global(); + glm::dmat3 LtoG = el->get_local_to_global(); EXPECT_TRUE(is_identical(LtoG, Q)); } @@ -391,50 +391,48 @@ TEST(Element, CoordinateComputationsRotations) // **** Setup Answers **** // // Origin - Vector3d Origin; - Origin.zero(); + glm::dvec3 Origin; + Origin = {}; // Coordinate transform matrix - Matrix3d Q1; - Q1.set_value(0, 0, 0.5); - Q1.set_value(1, 0, sqrt(3.0) / 2.0); - Q1.set_value(2, 0, 0.0); - Q1.set_value(0, 1, -1.0 / sqrt(2.0)); - Q1.set_value(1, 1, 1.0 / sqrt(6.0)); - Q1.set_value(2, 1, -1.0 / sqrt(3.0)); - Q1.set_value(0, 2, -0.5); - Q1.set_value(1, 2, sqrt(3.0) / 6.0); - Q1.set_value(2, 2, sqrt(6.0) / 3.0); - Matrix3d Q1t; - MatrixTranspose(Q1.data, 3, Q1t.data); + glm::dmat3 Q1; + Q1[0][0] = 0.5; + Q1[1][0] = sqrt(3.0) / 2.0; + Q1[2][0] = 0.0; + Q1[0][1] = -1.0 / sqrt(2.0); + Q1[1][1] = 1.0 / sqrt(6.0); + Q1[2][1] = -1.0 / sqrt(3.0); + Q1[0][2] = -0.5; + Q1[1][2] = sqrt(3.0) / 6.0; + Q1[2][2] = sqrt(6.0) / 3.0; + glm::dmat3 Q1t = glm::transpose(Q1); // Corresponding Euler angles in radians const double a1 = 0.0; const double b1 = asin(-1.0 / sqrt(3.0)); const double g1 = acos(1.0 / cos(b1) * 1.0 / sqrt(6.0)); // approximately 0.615 // Corresponding aim vector (local z-axis in reference coordinates) - // Vector3d aim1(0.0, -sqrt(3.0) / 2.0, sqrt(2.0 / 3.0)); - Vector3d aim1(0.0, -1.0 / sqrt(3.0), sqrt(2.0 / 3.0)); + // glm::dvec3 aim1(0.0, -sqrt(3.0) / 2.0, sqrt(2.0 / 3.0)); + glm::dvec3 aim1(0.0, -1.0 / sqrt(3.0), sqrt(2.0 / 3.0)); // Z-Rotation is the last of the Euler angles but in degrees const double zrot1 = g1 * 180.0 / PI; - Matrix3d Q2; - Q2.set_value(0, 0, (sqrt(8.0) + sqrt(6.0)) / 8.0); - Q2.set_value(0, 1, -0.75); - Q2.set_value(0, 2, (sqrt(6.0) - sqrt(8.0)) / 8.0); - Q2.set_value(1, 0, (2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0); - Q2.set_value(1, 1, sqrt(3.0) / 4.0); - Q2.set_value(1, 2, (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0); - Q2.set_value(2, 0, sqrt(6.0) / 4.0); - Q2.set_value(2, 1, 0.5); - Q2.set_value(2, 2, sqrt(6.0) / 4.0); - Matrix3d Q2t; - MatrixTranspose(Q2.data, 3, Q2t.data); + glm::dmat3 Q2; + Q2[0][0] = (sqrt(8.0) + sqrt(6.0)) / 8.0; + Q2[0][1] = -0.75; + Q2[0][2] = (sqrt(6.0) - sqrt(8.0)) / 8.0; + Q2[1][0] = (2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; + Q2[1][1] = sqrt(3.0) / 4.0; + Q2[1][2] = (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; + Q2[2][0] = sqrt(6.0) / 4.0; + Q2[2][1] = 0.5; + Q2[2][2] = sqrt(6.0) / 4.0; + glm::dmat3 Q2t = glm::transpose(Q2); // Corresponding Euler angles in radians const double a2 = PI / 4.0; const double b2 = PI / 6.0; const double g2 = PI / 3.0; // Corresponding aim vector (local z-axis in reference coordinates) - Vector3d aim2(sqrt(3.0 / 8.0), 0.5, sqrt(3.0 / 8.0)); + glm::dvec3 aim2(sqrt(3.0 / 8.0), 0.5, sqrt(3.0 / 8.0)); // Z-Rotation is the last of the Euler angles but in degrees const double zrot2 = 60.0; @@ -449,9 +447,9 @@ TEST(Element, CoordinateComputationsRotations) // **** Tests **** // const double TOL = 1e-12; - Vector3d scratch; - Vector3d result_vec; - Matrix3d result_mat; + glm::dvec3 scratch; + glm::dvec3 result_vec; + glm::dmat3 result_mat; // Origin tests EXPECT_TRUE(is_identical(el->get_origin_stage(), el->get_origin_ref())); EXPECT_TRUE(is_identical(el->get_origin_ref(), Origin)); @@ -470,28 +468,28 @@ TEST(Element, CoordinateComputationsRotations) // Aim vector tests EXPECT_TRUE(is_identical(el->get_aim_vector_ref(), aim1, TOL)); EXPECT_TRUE(is_identical(el->get_aim_vector_stage(), el->get_aim_vector_ref(), TOL)); - matrix_vector_product(Q2t, aim1, result_vec); + result_vec = Q2t * aim1; EXPECT_TRUE(is_identical(el->get_aim_vector_global(), result_vec, TOL)); - Vector3d v_local(-1.0, 2.0, 4.0); - Vector3d v_stage; - Vector3d v_global; - matrix_vector_product(Q1t, v_local, v_stage); - matrix_vector_product(Q2t, v_stage, v_global); + glm::dvec3 v_local(-1.0, 2.0, 4.0); + glm::dvec3 v_stage; + glm::dvec3 v_global; + v_stage = Q1t * v_local; + v_global = Q2t * v_stage; - Vector3d result; + glm::dvec3 result; el->convert_local_to_stage(result, v_local); EXPECT_TRUE(is_identical(result, v_stage, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_stage_to_local(result, v_stage); EXPECT_TRUE(is_identical(result, v_local, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_local_to_global(result, v_local); EXPECT_TRUE(is_identical(result, v_global, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_global_to_local(result, v_global); EXPECT_TRUE(is_identical(result, v_local, TOL)); @@ -501,24 +499,24 @@ TEST(Element, CoordinateComputationsTranslations) { // **** Setup Answers **** // // Origin - Vector3d Origin1(1.0, 2.0, 3.0); + glm::dvec3 Origin1(1.0, 2.0, 3.0); // Corresponding Euler angles in radians const double a = 0.0; const double b = 0.0; const double g = 0.0; // Corresponding aim vector (local z-axis in reference coordinates) - // Vector3d aim1(0.0, -sqrt(3.0) / 2.0, sqrt(2.0 / 3.0)); - Vector3d aim1(0.0, 0.0, 1.0); - vector_add(1.0, Origin1, 1.0, aim1); + // glm::dvec3 aim1(0.0, -sqrt(3.0) / 2.0, sqrt(2.0 / 3.0)); + glm::dvec3 aim1(0.0, 0.0, 1.0); + aim1 = 1.0 * Origin1 + 1.0 * aim1; // Z-Rotation is the last of the Euler angles but in degrees const double zrot = 0.0; // Origin - Vector3d Origin2(-3.0, 1.0, -5.0); + glm::dvec3 Origin2(-3.0, 1.0, -5.0); // Corresponding aim vector (local z-axis in reference coordinates) - Vector3d aim2(0.0, 0.0, 1.0); - vector_add(1.0, Origin2, 1.0, aim2); + glm::dvec3 aim2(0.0, 0.0, 1.0); + aim2 = 1.0 * Origin2 + 1.0 * aim2; // **** Setup Elements **** // auto el = make_configured_element(); @@ -530,13 +528,13 @@ TEST(Element, CoordinateComputationsTranslations) // **** Tests **** // const double TOL = 1e-12; - Vector3d scratch; - Vector3d result_vec; - Matrix3d result_mat; + glm::dvec3 scratch; + glm::dvec3 result_vec; + glm::dmat3 result_mat; // Origin tests EXPECT_TRUE(is_identical(el->get_origin_stage(), el->get_origin_ref())); EXPECT_TRUE(is_identical(el->get_origin_ref(), Origin1)); - vector_add(1.0, Origin1, 1.0, Origin2, result_vec); + result_vec = 1.0 * Origin1 + 1.0 * Origin2; EXPECT_TRUE(is_identical(el->get_origin_global(), result_vec)); // Euler angles tests @@ -552,28 +550,28 @@ TEST(Element, CoordinateComputationsTranslations) // Aim vector tests EXPECT_TRUE(is_identical(el->get_aim_vector_ref(), aim1, TOL)); EXPECT_TRUE(is_identical(el->get_aim_vector_stage(), el->get_aim_vector_ref(), TOL)); - vector_add(1.0, Origin2, 1.0, aim1, result_vec); + result_vec = 1.0 * Origin2 + 1.0 * aim1; EXPECT_TRUE(is_identical(el->get_aim_vector_global(), result_vec, TOL)); - Vector3d v_local(-1.0, 2.0, 4.0); - Vector3d v_stage; - Vector3d v_global; - vector_add(1.0, Origin1, 1.0, v_local, v_stage); - vector_add(1.0, Origin2, 1.0, v_stage, v_global); + glm::dvec3 v_local(-1.0, 2.0, 4.0); + glm::dvec3 v_stage; + glm::dvec3 v_global; + v_stage = 1.0 * Origin1 + 1.0 * v_local; + v_global = 1.0 * Origin2 + 1.0 * v_stage; - Vector3d result; + glm::dvec3 result; el->convert_local_to_stage(result, v_local); EXPECT_TRUE(is_identical(result, v_stage, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_stage_to_local(result, v_stage); EXPECT_TRUE(is_identical(result, v_local, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_local_to_global(result, v_local); EXPECT_TRUE(is_identical(result, v_global, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_global_to_local(result, v_global); EXPECT_TRUE(is_identical(result, v_local, TOL)); @@ -586,56 +584,55 @@ TEST(Element, CoordinateComputations) // **** Setup Answers **** // // Origin - Vector3d Origin1(1.0, 2.0, 3.0); + glm::dvec3 Origin1(1.0, 2.0, 3.0); // Coordinate transform matrix -- stage to local - Matrix3d Q1; - Q1.set_value(0, 0, 0.5); - Q1.set_value(1, 0, sqrt(3.0) / 2.0); - Q1.set_value(2, 0, 0.0); - Q1.set_value(0, 1, -1.0 / sqrt(2.0)); - Q1.set_value(1, 1, 1.0 / sqrt(6.0)); - Q1.set_value(2, 1, -1.0 / sqrt(3.0)); - Q1.set_value(0, 2, -0.5); - Q1.set_value(1, 2, sqrt(3.0) / 6.0); - Q1.set_value(2, 2, sqrt(6.0) / 3.0); + glm::dmat3 Q1; + Q1[0][0] = 0.5; + Q1[1][0] = sqrt(3.0) / 2.0; + Q1[2][0] = 0.0; + Q1[0][1] = -1.0 / sqrt(2.0); + Q1[1][1] = 1.0 / sqrt(6.0); + Q1[2][1] = -1.0 / sqrt(3.0); + Q1[0][2] = -0.5; + Q1[1][2] = sqrt(3.0) / 6.0; + Q1[2][2] = sqrt(6.0) / 3.0; // Local to stage matrix - Matrix3d Q1t; - MatrixTranspose(Q1.data, 3, Q1t.data); + glm::dmat3 Q1t = glm::transpose(Q1); // Corresponding Euler angles in radians const double a1 = 0.0; const double b1 = asin(-1.0 / sqrt(3.0)); const double g1 = acos(1.0 / cos(b1) * 1.0 / sqrt(6.0)); // approximately 0.615 // Corresponding aim vector (local z-axis in reference coordinates) - // Vector3d aim1(0.0, -sqrt(3.0) / 2.0, sqrt(2.0 / 3.0)); - Vector3d aim1(0.0, -1.0 / sqrt(3.0), sqrt(2.0 / 3.0)); - vector_add(1.0, Origin1, 1.0, aim1); + // glm::dvec3 aim1(0.0, -sqrt(3.0) / 2.0, sqrt(2.0 / 3.0)); + glm::dvec3 aim1(0.0, -1.0 / sqrt(3.0), sqrt(2.0 / 3.0)); + aim1 = 1.0 * Origin1 + 1.0 * aim1; // Z-Rotation is the last of the Euler angles but in degrees const double zrot1 = g1 * 180.0 / PI; // Origin - Vector3d Origin2(-3.0, 1.0, -5.0); + glm::dvec3 Origin2(-3.0, 1.0, -5.0); // Global to stage matrix - Matrix3d Q2; - Q2.set_value(0, 0, (sqrt(8.0) + sqrt(6.0)) / 8.0); - Q2.set_value(0, 1, -0.75); - Q2.set_value(0, 2, (sqrt(6.0) - sqrt(8.0)) / 8.0); - Q2.set_value(1, 0, (2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0); - Q2.set_value(1, 1, sqrt(3.0) / 4.0); - Q2.set_value(1, 2, (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0); - Q2.set_value(2, 0, sqrt(6.0) / 4.0); - Q2.set_value(2, 1, 0.5); - Q2.set_value(2, 2, sqrt(6.0) / 4.0); + glm::dmat3 Q2; + Q2[0][0] = (sqrt(8.0) + sqrt(6.0)) / 8.0; + Q2[0][1] = -0.75; + Q2[0][2] = (sqrt(6.0) - sqrt(8.0)) / 8.0; + Q2[1][0] = (2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; + Q2[1][1] = sqrt(3.0) / 4.0; + Q2[1][2] = (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; + Q2[2][0] = sqrt(6.0) / 4.0; + Q2[2][1] = 0.5; + Q2[2][2] = sqrt(6.0) / 4.0; // Stage to global matrix - Matrix3d Q2t; - MatrixTranspose(Q2.data, 3, Q2t.data); + glm::dmat3 Q2t = glm::transpose(Q2); + ; // Corresponding Euler angles in radians const double a2 = PI / 4.0; const double b2 = PI / 6.0; const double g2 = PI / 3.0; // Corresponding aim vector (local z-axis in reference coordinates) - Vector3d aim2(sqrt(3.0 / 8.0), 0.5, sqrt(3.0 / 8.0)); - vector_add(1.0, Origin2, 1.0, aim2); + glm::dvec3 aim2(sqrt(3.0 / 8.0), 0.5, sqrt(3.0 / 8.0)); + aim2 = 1.0 * Origin2 + 1.0 * aim2; // Z-Rotation is the last of the Euler angles but in degrees const double zrot2 = 60.0; @@ -650,15 +647,15 @@ TEST(Element, CoordinateComputations) // **** Tests **** // const double TOL = 1e-12; - Vector3d scratch; - Vector3d result_vec; - Matrix3d result_mat; + glm::dvec3 scratch; + glm::dvec3 result_vec; + glm::dmat3 result_mat; // Origin tests EXPECT_TRUE(is_identical(el->get_origin_stage(), el->get_origin_ref())); EXPECT_TRUE(is_identical(el->get_origin_ref(), Origin1)); // vector_add(1.0, Origin1, 1.0, Origin2, result_vec); - matrix_vector_product(Q2t, Origin1, result_vec); - vector_add(1.0, Origin2, 1.0, result_vec); + result_vec = Q2t * Origin1; + result_vec = Origin2 + result_vec; EXPECT_TRUE(is_identical(el->get_origin_global(), result_vec)); // Euler angles tests @@ -674,35 +671,35 @@ TEST(Element, CoordinateComputations) // Aim vector tests EXPECT_TRUE(is_identical(el->get_aim_vector_ref(), aim1, TOL)); EXPECT_TRUE(is_identical(el->get_aim_vector_stage(), el->get_aim_vector_ref(), TOL)); - matrix_vector_product(Q2t, aim1, result_vec); - vector_add(1.0, Origin2, 1.0, result_vec); + result_vec = Q2t * aim1; + result_vec = Origin2 + result_vec; EXPECT_TRUE(is_identical(el->get_aim_vector_global(), result_vec, TOL)); - Vector3d v_local(-1.0, 2.0, 4.0); - Vector3d v_stage; - Vector3d v_global; - matrix_vector_product(Q1t, v_local, v_stage); - vector_add(1.0, Origin1, 1.0, v_stage); - matrix_vector_product(Q2t, v_stage, v_global); - vector_add(1.0, Origin2, 1.0, v_global); + glm::dvec3 v_local(-1.0, 2.0, 4.0); + glm::dvec3 v_stage; + glm::dvec3 v_global; + v_stage = Q1t * v_local; + v_stage = Origin1 + v_stage; + v_global = Q2t * v_stage; + v_global = Origin2 * v_global; - Vector3d result; + glm::dvec3 result; el->convert_local_to_stage(result, v_local); EXPECT_TRUE(is_identical(result, v_stage, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_stage_to_local(result, v_stage); EXPECT_TRUE(is_identical(result, v_local, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_local_to_global(result, v_local); EXPECT_TRUE(is_identical(result, v_global, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_global_to_local(result, v_global); EXPECT_TRUE(is_identical(result, v_local, TOL)); - result.zero(); + result = glm::dvec3(0.0); // Note: Global to reference and reference to global // use other conversion routines so just need to test @@ -711,20 +708,20 @@ TEST(Element, CoordinateComputations) // Stage coordinates are the reference coordinates el->convert_global_to_reference(result, v_global); EXPECT_TRUE(is_identical(result, v_stage, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_reference_to_global(result, v_stage); EXPECT_TRUE(is_identical(result, v_global, TOL)); - result.zero(); + result = glm::dvec3(0.0); // Global coordinates are reference coordinates st->convert_global_to_reference(result, v_global); EXPECT_TRUE(is_identical(result, v_global, TOL)); - result.zero(); + result = glm::dvec3(0.0); st->convert_reference_to_global(result, v_global); EXPECT_TRUE(is_identical(result, v_global, TOL)); - result.zero(); + result = glm::dvec3(0.0); } TEST(Element, VectorCoordinateComputations) @@ -734,56 +731,54 @@ TEST(Element, VectorCoordinateComputations) // **** Setup Answers **** // // Origin - Vector3d Origin1(1.0, 2.0, 3.0); + glm::dvec3 Origin1(1.0, 2.0, 3.0); // Coordinate transform matrix -- stage to local - Matrix3d Q1; - Q1.set_value(0, 0, 0.5); - Q1.set_value(1, 0, sqrt(3.0) / 2.0); - Q1.set_value(2, 0, 0.0); - Q1.set_value(0, 1, -1.0 / sqrt(2.0)); - Q1.set_value(1, 1, 1.0 / sqrt(6.0)); - Q1.set_value(2, 1, -1.0 / sqrt(3.0)); - Q1.set_value(0, 2, -0.5); - Q1.set_value(1, 2, sqrt(3.0) / 6.0); - Q1.set_value(2, 2, sqrt(6.0) / 3.0); + glm::dmat3 Q1; + Q1[0][0] = 0.5; + Q1[1][0] = sqrt(3.0) / 2.0; + Q1[2][0] = 0.0; + Q1[0][1] = -1.0 / sqrt(2.0); + Q1[1][1] = 1.0 / sqrt(6.0); + Q1[2][1] = -1.0 / sqrt(3.0); + Q1[0][2] = -0.5; + Q1[1][2] = sqrt(3.0) / 6.0; + Q1[2][2] = sqrt(6.0) / 3.0; // Local to stage matrix - Matrix3d Q1t; - MatrixTranspose(Q1.data, 3, Q1t.data); + glm::dmat3 Q1t = glm::transpose(Q1); // Corresponding Euler angles in radians const double a1 = 0.0; const double b1 = asin(-1.0 / sqrt(3.0)); const double g1 = acos(1.0 / cos(b1) * 1.0 / sqrt(6.0)); // approximately 0.615 // Corresponding aim vector (local z-axis in reference coordinates) - // Vector3d aim1(0.0, -sqrt(3.0) / 2.0, sqrt(2.0 / 3.0)); - Vector3d aim1(0.0, -1.0 / sqrt(3.0), sqrt(2.0 / 3.0)); - vector_add(1.0, Origin1, 1.0, aim1); + // glm::dvec3 aim1(0.0, -sqrt(3.0) / 2.0, sqrt(2.0 / 3.0)); + glm::dvec3 aim1(0.0, -1.0 / sqrt(3.0), sqrt(2.0 / 3.0)); + aim1 = Origin1 + aim1; // Z-Rotation is the last of the Euler angles but in degrees const double zrot1 = g1 * 180.0 / PI; // Origin - Vector3d Origin2(-3.0, 1.0, -5.0); + glm::dvec3 Origin2(-3.0, 1.0, -5.0); // Global to stage matrix - Matrix3d Q2; - Q2.set_value(0, 0, (sqrt(8.0) + sqrt(6.0)) / 8.0); - Q2.set_value(0, 1, -0.75); - Q2.set_value(0, 2, (sqrt(6.0) - sqrt(8.0)) / 8.0); - Q2.set_value(1, 0, (2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0); - Q2.set_value(1, 1, sqrt(3.0) / 4.0); - Q2.set_value(1, 2, (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0); - Q2.set_value(2, 0, sqrt(6.0) / 4.0); - Q2.set_value(2, 1, 0.5); - Q2.set_value(2, 2, sqrt(6.0) / 4.0); + glm::dmat3 Q2; + Q2[0][0] = (sqrt(8.0) + sqrt(6.0)) / 8.0; + Q2[0][1] = -0.75; + Q2[0][2] = (sqrt(6.0) - sqrt(8.0)) / 8.0; + Q2[1][0] = (2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; + Q2[1][1] = sqrt(3.0) / 4.0; + Q2[1][2] = (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; + Q2[2][0] = sqrt(6.0) / 4.0; + Q2[2][1] = 0.5; + Q2[2][2] = sqrt(6.0) / 4.0; // Stage to global matrix - Matrix3d Q2t; - MatrixTranspose(Q2.data, 3, Q2t.data); + glm::dmat3 Q2t = glm::transpose(Q2); // Corresponding Euler angles in radians const double a2 = PI / 4.0; const double b2 = PI / 6.0; const double g2 = PI / 3.0; // Corresponding aim vector (local z-axis in reference coordinates) - Vector3d aim2(sqrt(3.0 / 8.0), 0.5, sqrt(3.0 / 8.0)); - vector_add(1.0, Origin2, 1.0, aim2); + glm::dvec3 aim2(sqrt(3.0 / 8.0), 0.5, sqrt(3.0 / 8.0)); + aim2 = Origin2 * aim2; // Z-Rotation is the last of the Euler angles but in degrees const double zrot2 = 60.0; @@ -798,9 +793,9 @@ TEST(Element, VectorCoordinateComputations) // **** Tests **** // const double TOL = 1e-12; - Vector3d scratch; - Vector3d result_vec; - Matrix3d result_mat; + glm::dvec3 scratch; + glm::dvec3 result_vec; + glm::dmat3 result_mat; // Euler angles tests result_vec = el->get_euler_angles(); @@ -812,29 +807,29 @@ TEST(Element, VectorCoordinateComputations) EXPECT_NEAR(result_vec[1], b2, TOL); EXPECT_NEAR(result_vec[2], g2, TOL); - Vector3d v_local(-1.0, 2.0, 4.0); - Vector3d v_stage; - Vector3d v_global; - matrix_vector_product(Q1t, v_local, v_stage); - matrix_vector_product(Q2t, v_stage, v_global); + glm::dvec3 v_local(-1.0, 2.0, 4.0); + glm::dvec3 v_stage; + glm::dvec3 v_global; + v_stage = Q1t * v_local; + v_global = Q2t * v_stage; - Vector3d result; + glm::dvec3 result; el->convert_vector_local_to_stage(result, v_local); EXPECT_TRUE(is_identical(result, v_stage, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_vector_stage_to_local(result, v_stage); EXPECT_TRUE(is_identical(result, v_local, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_vector_local_to_global(result, v_local); EXPECT_TRUE(is_identical(result, v_global, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_vector_global_to_local(result, v_global); EXPECT_TRUE(is_identical(result, v_local, TOL)); - result.zero(); + result = glm::dvec3(0.0); // Note: Global to reference and reference to global // use other conversion routines so just need to test @@ -843,20 +838,20 @@ TEST(Element, VectorCoordinateComputations) // Stage coordinates are the reference coordinates el->convert_vector_global_to_reference(result, v_global); EXPECT_TRUE(is_identical(result, v_stage, TOL)); - result.zero(); + result = glm::dvec3(0.0); el->convert_vector_reference_to_global(result, v_stage); EXPECT_TRUE(is_identical(result, v_global, TOL)); - result.zero(); + result = glm::dvec3(0.0); // Global coordinates are reference coordinates st->convert_vector_global_to_reference(result, v_global); EXPECT_TRUE(is_identical(result, v_global, TOL)); - result.zero(); + result = glm::dvec3(0.0); st->convert_vector_reference_to_global(result, v_global); EXPECT_TRUE(is_identical(result, v_global, TOL)); - result.zero(); + result = glm::dvec3(0.0); } TEST(Element, SingleElementEnforceUserFieldsSet) diff --git a/google-tests/unit-tests/simulation_data/file_io_test.cpp b/google-tests/unit-tests/simulation_data/file_io_test.cpp index b0f822e6..ddd41d32 100644 --- a/google-tests/unit-tests/simulation_data/file_io_test.cpp +++ b/google-tests/unit-tests/simulation_data/file_io_test.cpp @@ -19,8 +19,8 @@ void get_default_element_base(nlohmann::ordered_json& jnode) jnode["my_id"] = 1; jnode["my_name"] = ""; jnode["stage"] = 0; - jnode["origin"] = Vector3d(0, 0, 0).data; - jnode["aim"] = Vector3d(0, 0, 0).data; + jnode["origin"] = SolTrace::Data::to_array(glm::dvec3(0, 0, 0)); + jnode["aim"] = SolTrace::Data::to_array(glm::dvec3(0, 0, 0)); jnode["zrot"] = 0; } @@ -420,7 +420,7 @@ TEST(io_json, performance_comparison) ASSERT_EQ(rr_o->get_element(k), rr_r->get_element(k)); // Positions - Vector3d pos_o; Vector3d pos_r; + glm::dvec3 pos_o; glm::dvec3 pos_r; rr_o->get_position(k, pos_o); rr_r->get_position(k, pos_r); EXPECT_DOUBLE_EQ(pos_o[0], pos_r[0]); @@ -428,7 +428,7 @@ TEST(io_json, performance_comparison) EXPECT_DOUBLE_EQ(pos_o[2], pos_r[2]); // Directions - Vector3d dir_o; Vector3d dir_r; + glm::dvec3 dir_o; glm::dvec3 dir_r; rr_o->get_direction(k, dir_o); rr_r->get_direction(k, dir_r); EXPECT_DOUBLE_EQ(dir_o[0], dir_r[0]); @@ -762,4 +762,4 @@ TEST(io_json, stage_read_fail) // Try to make stage EXPECT_THROW(make_stage(jstage), std::invalid_argument); -} \ No newline at end of file +} diff --git a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp index 5069037e..6ba6d708 100644 --- a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp +++ b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp @@ -4,68 +4,68 @@ #include #include -#include - #include "common.hpp" +#include + TEST(LinearAlgebra, VectorBasics) { const double TOL = 1e-12; - Vector3d x(1.0, 1.0, 3.0); - Vector3d y(-1.0, 2.0, -1.0); - Vector3d z; + glm::dvec3 x(1.0, 1.0, 3.0); + glm::dvec3 y(-1.0, 2.0, -1.0); + glm::dvec3 z = glm::dvec3(0.0); EXPECT_EQ(z[0], 0.0); EXPECT_EQ(z[1], 0.0); EXPECT_EQ(z[2], 0.0); - vector_add(1.0, x, 1.0, y, z); + z = 1.0 * x + 1.0 * y; EXPECT_NEAR(z[0], 0.0, TOL); EXPECT_NEAR(z[1], 3.0, TOL); EXPECT_NEAR(z[2], 2.0, TOL); - vector_add(0.5, x, -2.0, y, z); + z = 0.5 * x + -2.0 * y; EXPECT_NEAR(z[0], 2.5, TOL); EXPECT_NEAR(z[1], -3.5, TOL); EXPECT_NEAR(z[2], 3.5, TOL); - vector_max(x, y, z); + z = glm::max(x, y); EXPECT_EQ(z[0], 1.0); EXPECT_EQ(z[1], 2.0); EXPECT_EQ(z[2], 3.0); - vector_min(x, y, z); + z = glm::min(x, y); EXPECT_EQ(z[0], -1.0); EXPECT_EQ(z[1], 1.0); EXPECT_EQ(z[2], -1.0); - z.set_values(1.0, 2.0, 3.0); - z.scalar_mult(-0.5); + z = {1.0, 2.0, 3.0}; + z *= -0.5; EXPECT_NEAR(z[0], -0.5, TOL); EXPECT_NEAR(z[1], -1.0, TOL); EXPECT_NEAR(z[2], -1.5, TOL); - double dp = dot_product(x, y); + double dp = glm::dot(x, y); EXPECT_NEAR(dp, -2.0, TOL); - double mag = vector_norm(x); + double mag = glm::length(x); EXPECT_NEAR(mag, sqrt(11.0), TOL); - make_unit_vector(x); + x = glm::normalize(x); EXPECT_NEAR(x[0], 1.0 / mag, TOL); EXPECT_NEAR(x[1], 1.0 / mag, TOL); EXPECT_NEAR(x[2], 3.0 / mag, TOL); - mag = vector_norm(y); + mag = glm::length(y); EXPECT_NEAR(mag, sqrt(6.0), TOL); - make_unit_vector(y); + y = glm::normalize(y); EXPECT_NEAR(y[0], -1.0 / mag, TOL); EXPECT_NEAR(y[1], 2.0 / mag, TOL); EXPECT_NEAR(y[2], -1.0 / mag, TOL); - z.zero(); + z = {}; EXPECT_EQ(z[0], 0.0); EXPECT_EQ(z[1], 0.0); EXPECT_EQ(z[2], 0.0); @@ -77,55 +77,55 @@ TEST(LinearAlgebra, VectorBasics) EXPECT_EQ(z[1], 2.0); EXPECT_EQ(z[2], 3.0); - Vector3d u(z.data); + glm::dvec3 u(z); EXPECT_EQ(z[0], u[0]); EXPECT_EQ(z[1], u[1]); EXPECT_EQ(z[2], u[2]); - Vector3d ihat(1.0, 0.0, 0.0); - Vector3d jhat(0.0, 1.0, 0.0); - Vector3d khat(0.0, 0.0, 1.0); - Vector3d result; - cross_product(ihat, jhat, result); + glm::dvec3 ihat(1.0, 0.0, 0.0); + glm::dvec3 jhat(0.0, 1.0, 0.0); + glm::dvec3 khat(0.0, 0.0, 1.0); + glm::dvec3 result; + result = glm::cross(ihat, jhat); EXPECT_NEAR(result[0], 0.0, TOL); EXPECT_NEAR(result[1], 0.0, TOL); EXPECT_NEAR(result[2], 1.0, TOL); - result.zero(); + result = glm::dvec3(0.0); - cross_product(ihat, khat, result); + result = glm::cross(ihat, khat); EXPECT_NEAR(result[0], 0.0, TOL); EXPECT_NEAR(result[1], -1.0, TOL); EXPECT_NEAR(result[2], 0.0, TOL); - result.zero(); + result = glm::dvec3(0.0); - cross_product(jhat, khat, result); + result = glm::cross(jhat, khat); EXPECT_NEAR(result[0], 1.0, TOL); EXPECT_NEAR(result[1], 0.0, TOL); EXPECT_NEAR(result[2], 0.0, TOL); - result.zero(); + result = glm::dvec3(0.0); - double l2 = error(ihat, jhat); + double l2 = SolTrace::Data::error(ihat, jhat); EXPECT_NEAR(l2, sqrt(2.0), TOL); - double linf = error_inf(ihat, jhat); + double linf = SolTrace::Data::error_inf(ihat, jhat); EXPECT_NEAR(linf, 1.0, TOL); } TEST(LinearAlgebra, MatrixVectorProduct) { - Vector3d x(0.5, 1.0, -2.0); - Vector3d y; + glm::dvec3 x(0.5, 1.0, -2.0); + glm::dvec3 y; - Matrix3d A; - A.set_value(0, 0, 1.0); - A.set_value(1, 1, 1.0); - A.set_value(2, 2, 1.0); + glm::dmat3 A; + A[0][0] = 1.0; + A[1][1] = 1.0; + A[2][2] = 1.0; - matrix_vector_product(A, x, y); + y = A * x; EXPECT_TRUE(is_identical(x, y)); - A.set_value(0, 1, 2.0); - A.set_value(1, 2, 3.0); - matrix_vector_product(A, x, y); + A[0][1] = 2.0; + A[1][2] = 3.0; + y = A * x; EXPECT_NEAR(y[0], 2.5, 1e-12); EXPECT_NEAR(y[1], -5.0, 1e-12); EXPECT_NEAR(y[2], -2.0, 1e-12); @@ -133,33 +133,32 @@ TEST(LinearAlgebra, MatrixVectorProduct) TEST(LinearAlgebra, MatrixMatrixProduct) { - Matrix3d A; - A.set_value(0, 1, 1.0); - A.set_value(0, 2, 2.0); - A.set_value(1, 0, -1.0); - A.set_value(1, 1, 1.0); - A.set_value(2, 0, 2.0); - A.set_value(2, 2, 1.0); - - Matrix3d B; - B.set_value(0, 0, -1.0); - B.set_value(0, 1, 1.0); - B.set_value(1, 1, 1.0); - B.set_value(1, 2, -2.0); - B.set_value(2, 2, 1.0); - - Matrix3d Ctrue; - Ctrue.set_value(0, 1, 1.0); - Ctrue.set_value(1, 0, 1.0); - Ctrue.set_value(1, 2, -2.0); - Ctrue.set_value(2, 0, -2.0); - Ctrue.set_value(2, 1, 2.0); - Ctrue.set_value(2, 2, 1.0); - - Matrix3d C; - C.zero(); - - matrix_matrix_product(A, B, C); + glm::dmat3 A; + A[0][1] = 1.0; + A[0][2] = 2.0; + A[1][0] = -1.0; + A[1][1] = 1.0; + A[2][0] = 2.0; + A[2][2] = 1.0; + + glm::dmat3 B; + B[0][0] = -1.0; + B[0][1] = 1.0; + B[1][1] = 1.0; + B[1][2] = -2.0; + B[2][2] = 1.0; + + glm::dmat3 Ctrue; + Ctrue[0][1] = 1.0; + Ctrue[1][0] = 1.0; + Ctrue[1][2] = -2.0; + Ctrue[2][0] = -2.0; + Ctrue[2][1] = 2.0; + Ctrue[2][2] = 1.0; + + glm::dmat3 C{0.0}; + + C = A * B; EXPECT_TRUE(is_identical(C, Ctrue)); } @@ -167,17 +166,17 @@ TEST(LinearAlgebra, CoordinateTransforms) { // TODO: Implement tests for compute_transform_matrices, // transform_to_local, and transform_to_reference functions - Matrix3d A; - Matrix3d B; + glm::dmat3 A; + glm::dmat3 B; EXPECT_TRUE(is_identical(A, B)); } -TEST(LinearAlgebra, Vector3dOutputOperator) +TEST(LinearAlgebra, dvec3OutputOperator) { - Vector3d v1(1.0, 2.0, 3.0); - Vector3d v2(-0.5, 0.0, 10.5); - Vector3d v3(0.0, 0.0, 0.0); + glm::dvec3 v1(1.0, 2.0, 3.0); + glm::dvec3 v2(-0.5, 0.0, 10.5); + glm::dvec3 v3(0.0, 0.0, 0.0); std::ostringstream oss1; oss1 << v1; @@ -192,115 +191,110 @@ TEST(LinearAlgebra, Vector3dOutputOperator) EXPECT_EQ(oss3.str(), "[0, 0, 0]"); // Test with different precision - Vector3d v4(1.23456789, -2.34567891, 3.45678912); + glm::dvec3 v4(1.23456789, -2.34567891, 3.45678912); std::ostringstream oss4; oss4 << std::fixed << std::setprecision(3) << v4; EXPECT_EQ(oss4.str(), "[1.235, -2.346, 3.457]"); } -TEST(LinearAlgebra, Matrix3dOutputOperator) +TEST(LinearAlgebra, dmat3OutputOperator) { - Matrix3d A; - A.zero(); - A.set_value(0, 0, 1.0); - A.set_value(0, 1, 2.0); - A.set_value(0, 2, 3.0); - A.set_value(1, 0, 4.0); - A.set_value(1, 1, 5.0); - A.set_value(1, 2, 6.0); - A.set_value(2, 0, 7.0); - A.set_value(2, 1, 8.0); - A.set_value(2, 2, 9.0); + glm::dmat3 A(1.0); + A[0][0] = 1.0; + A[0][1] = 2.0; + A[0][2] = 3.0; + A[1][0] = 4.0; + A[1][1] = 5.0; + A[1][2] = 6.0; + A[2][0] = 7.0; + A[2][1] = 8.0; + A[2][2] = 9.0; std::ostringstream oss; oss << A; EXPECT_EQ(oss.str(), "[1, 2, 3; 4, 5, 6; 7, 8, 9]"); // Test identity matrix - Matrix3d I; - I.identity(); + glm::dmat3 I; std::ostringstream oss_identity; oss_identity << I; EXPECT_EQ(oss_identity.str(), "[1, 0, 0; 0, 1, 0; 0, 0, 1]"); // Test zero matrix - Matrix3d Z; - Z.zero(); + glm::dmat3 Z(0.0); std::ostringstream oss_zero; oss_zero << Z; EXPECT_EQ(oss_zero.str(), "[0, 0, 0; 0, 0, 0; 0, 0, 0]"); // Test with negative values and different precision - Matrix3d B; - B.set_value(0, 0, -1.5); - B.set_value(0, 1, 2.25); - B.set_value(0, 2, -3.75); - B.set_value(1, 0, 0.0); - B.set_value(1, 1, -0.5); - B.set_value(1, 2, 1.0); - B.set_value(2, 0, 10.0); - B.set_value(2, 1, -20.0); - B.set_value(2, 2, 30.0); + glm::dmat3 B; + B[0][0] = -1.5; + B[0][1] = 2.25; + B[0][2] = -3.75; + B[1][0] = 0.0; + B[1][1] = -0.5; + B[1][2] = 1.0; + B[2][0] = 10.0; + B[2][1] = -20.0; + B[2][2] = 30.0; std::ostringstream oss_negative; oss_negative << std::fixed << std::setprecision(2) << B; EXPECT_EQ(oss_negative.str(), "[-1.50, 2.25, -3.75; 0.00, -0.50, 1.00; 10.00, -20.00, 30.00]"); } -TEST(LinearAlgebra, Matrix3dGetValue) +TEST(LinearAlgebra, dmat3GetValue) { - Matrix3d A; - A.zero(); - + glm::dmat3 A(0.0); + // Test getting values from zero matrix for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - EXPECT_EQ(A.get_value(i, j), 0.0); + EXPECT_EQ(A[i][j], 0.0); } } // Set specific values and test retrieval - A.set_value(0, 0, 1.5); - A.set_value(0, 1, -2.5); - A.set_value(0, 2, 3.7); - A.set_value(1, 0, -4.2); - A.set_value(1, 1, 5.8); - A.set_value(1, 2, -6.1); - A.set_value(2, 0, 7.9); - A.set_value(2, 1, -8.4); - A.set_value(2, 2, 9.6); - - EXPECT_DOUBLE_EQ(A.get_value(0, 0), 1.5); - EXPECT_DOUBLE_EQ(A.get_value(0, 1), -2.5); - EXPECT_DOUBLE_EQ(A.get_value(0, 2), 3.7); - EXPECT_DOUBLE_EQ(A.get_value(1, 0), -4.2); - EXPECT_DOUBLE_EQ(A.get_value(1, 1), 5.8); - EXPECT_DOUBLE_EQ(A.get_value(1, 2), -6.1); - EXPECT_DOUBLE_EQ(A.get_value(2, 0), 7.9); - EXPECT_DOUBLE_EQ(A.get_value(2, 1), -8.4); - EXPECT_DOUBLE_EQ(A.get_value(2, 2), 9.6); + A[0][0] = 1.5; + A[0][1] = -2.5; + A[0][2] = 3.7; + A[1][0] = -4.2; + A[1][1] = 5.8; + A[1][2] = -6.1; + A[2][0] = 7.9; + A[2][1] = -8.4; + A[2][2] = 9.6; + + EXPECT_DOUBLE_EQ(A[0][0], 1.5); + EXPECT_DOUBLE_EQ(A[0][1], -2.5); + EXPECT_DOUBLE_EQ(A[0][2], 3.7); + EXPECT_DOUBLE_EQ(A[1][0], -4.2); + EXPECT_DOUBLE_EQ(A[1][1], 5.8); + EXPECT_DOUBLE_EQ(A[1][2], -6.1); + EXPECT_DOUBLE_EQ(A[2][0], 7.9); + EXPECT_DOUBLE_EQ(A[2][1], -8.4); + EXPECT_DOUBLE_EQ(A[2][2], 9.6); // Test identity matrix - Matrix3d I; - I.identity(); - EXPECT_DOUBLE_EQ(I.get_value(0, 0), 1.0); - EXPECT_DOUBLE_EQ(I.get_value(0, 1), 0.0); - EXPECT_DOUBLE_EQ(I.get_value(0, 2), 0.0); - EXPECT_DOUBLE_EQ(I.get_value(1, 0), 0.0); - EXPECT_DOUBLE_EQ(I.get_value(1, 1), 1.0); - EXPECT_DOUBLE_EQ(I.get_value(1, 2), 0.0); - EXPECT_DOUBLE_EQ(I.get_value(2, 0), 0.0); - EXPECT_DOUBLE_EQ(I.get_value(2, 1), 0.0); - EXPECT_DOUBLE_EQ(I.get_value(2, 2), 1.0); + glm::dmat3 I; + EXPECT_DOUBLE_EQ(I[0][0], 1.0); + EXPECT_DOUBLE_EQ(I[0][1], 0.0); + EXPECT_DOUBLE_EQ(I[0][2], 0.0); + EXPECT_DOUBLE_EQ(I[1][0], 0.0); + EXPECT_DOUBLE_EQ(I[1][1], 1.0); + EXPECT_DOUBLE_EQ(I[1][2], 0.0); + EXPECT_DOUBLE_EQ(I[2][0], 0.0); + EXPECT_DOUBLE_EQ(I[2][1], 0.0); + EXPECT_DOUBLE_EQ(I[2][2], 1.0); // Test very small and very large values - A.set_value(0, 0, 1e-15); - A.set_value(1, 1, 1e15); - A.set_value(2, 2, -1e-10); - - EXPECT_DOUBLE_EQ(A.get_value(0, 0), 1e-15); - EXPECT_DOUBLE_EQ(A.get_value(1, 1), 1e15); - EXPECT_DOUBLE_EQ(A.get_value(2, 2), -1e-10); + A[0][0] = 1e-15; + A[1][1] = 1e15; + A[2][2] = -1e-10; + + EXPECT_DOUBLE_EQ(A[0][0], 1e-15); + EXPECT_DOUBLE_EQ(A[1][1], 1e15); + EXPECT_DOUBLE_EQ(A[2][2], -1e-10); } diff --git a/google-tests/unit-tests/simulation_data/sun_test.cpp b/google-tests/unit-tests/simulation_data/sun_test.cpp index dc4f2313..bd9c6587 100644 --- a/google-tests/unit-tests/simulation_data/sun_test.cpp +++ b/google-tests/unit-tests/simulation_data/sun_test.cpp @@ -218,13 +218,13 @@ TEST(Sun, BasicFunctionality) // Test position setting and getting sun.set_position(1.0, 2.0, 3.0); - Vector3d pos = sun.get_position(); + glm::dvec3 pos = sun.get_position(); EXPECT_DOUBLE_EQ(pos[0], 1.0); EXPECT_DOUBLE_EQ(pos[1], 2.0); EXPECT_DOUBLE_EQ(pos[2], 3.0); - // Test position setting with Vector3d - Vector3d new_pos(4.0, 5.0, 6.0); + // Test position setting with glm::dvec3 + glm::dvec3 new_pos(4.0, 5.0, 6.0); sun.set_position(new_pos); pos = sun.get_position(); EXPECT_DOUBLE_EQ(pos[0], 4.0); diff --git a/google-tests/unit-tests/simulation_results/simulation_result_test.cpp b/google-tests/unit-tests/simulation_results/simulation_result_test.cpp index b878c249..91f3eb3d 100644 --- a/google-tests/unit-tests/simulation_results/simulation_result_test.cpp +++ b/google-tests/unit-tests/simulation_results/simulation_result_test.cpp @@ -4,7 +4,6 @@ #include #include -#include #include "common.hpp" @@ -23,8 +22,8 @@ TEST(InteractionRecord, Constructors) { element_id elid = 5; RayEvent it = RayEvent::ABSORB; - Vector3d loc(-3.2, -2.5, 1.2); - Vector3d dir(-1.0, 1.5, -2.5); + glm::dvec3 loc(-3.2, -2.5, 1.2); + glm::dvec3 dir(-1.0, 1.5, -2.5); InteractionRecord ir1(elid, it, loc, dir); InteractionRecord ir2(elid, it, loc[0], loc[1], loc[2], @@ -43,8 +42,8 @@ TEST(InteractionRecord, OutputOperator) { element_id elid = 5; RayEvent it = RayEvent::ABSORB; - Vector3d loc(-3.2, -2.5, 1.2); - Vector3d dir(-1.0, 1.5, -2.5); + glm::dvec3 loc(-3.2, -2.5, 1.2); + glm::dvec3 dir(-1.0, 1.5, -2.5); InteractionRecord ir1(elid, it, loc, dir); // Basic test to see that the output operator is there @@ -82,8 +81,8 @@ TEST(RayRecord, Accessors) ray_record_ptr rr = make_ray_record(ID); for (uint_fast32_t ell = 0; ell < NINTER; ++ell) { - Vector3d loc(1.0 * ell * ell, 2.0 * ell * ell, 3.0 * ell * ell); - Vector3d dir(2.0 * ell + 1.0, 4.0 * ell + 2.0, 6.0 * ell + 3.0); + glm::dvec3 loc(1.0 * ell * ell, 2.0 * ell * ell, 3.0 * ell * ell); + glm::dvec3 dir(2.0 * ell + 1.0, 4.0 * ell + 2.0, 6.0 * ell + 3.0); RayEvent it = my_types[ell]; interaction_ptr ir = make_interaction_record(ell, it, loc, dir); rr->add_interaction_record(ir); @@ -92,9 +91,9 @@ TEST(RayRecord, Accessors) // Getting direction cosines and indexing int_fast64_t idx = 0; - Vector3d ret1; - Vector3d ret2; - Vector3d lcos; + glm::dvec3 ret1; + glm::dvec3 ret2; + glm::dvec3 lcos; for (auto iter = rr->interactions.cbegin(); iter != rr->interactions.cend(); ++iter) @@ -105,15 +104,15 @@ TEST(RayRecord, Accessors) rr->get_direction(*iter, ret2); EXPECT_TRUE(is_identical(ret1, ret2)); - lcos.set_values(1.0, 2.0, 3.0); - lcos.scalar_mult(2 * idx + 1); + lcos = {1.0, 2.0, 3.0}; + lcos *= 2 * idx + 1; - SolTrace::Data::make_unit_vector(lcos); + SolTrace::Data::normalize_inplace(lcos); EXPECT_NEAR(ret1[0], lcos[0], TOL); EXPECT_NEAR(ret1[1], lcos[1], TOL); EXPECT_NEAR(ret1[2], lcos[2], TOL); - ret1.zero(); + ret1 = glm::dvec3(0.0); rr->get_position(idx, ret1); rr->get_position(*iter, ret2); EXPECT_TRUE(is_identical(ret1, ret2)); @@ -144,8 +143,8 @@ TEST(RayRecord, OutputOperator) RayRecord rr(ID); for (uint_fast32_t ell = 0; ell < NINTER; ++ell) { - Vector3d loc(1.0 * ell * ell, 2.0 * ell * ell, 3.0 * ell * ell); - Vector3d dir(2.0 * ell + 1.0, 4.0 * ell + 2.0, 6.0 * ell + 3.0); + glm::dvec3 loc(1.0 * ell * ell, 2.0 * ell * ell, 3.0 * ell * ell); + glm::dvec3 dir(2.0 * ell + 1.0, 4.0 * ell + 2.0, 6.0 * ell + 3.0); RayEvent it = my_types[ell]; interaction_ptr ir = make_interaction_record(ell, it, loc, dir); rr.add_interaction_record(ir); @@ -175,8 +174,8 @@ TEST(SimulationResult, Accessors) ray_record_ptr rr = make_ray_record(k); for (uint_fast32_t ell = 0; ell < NINTER; ++ell) { - Vector3d loc(1.0 * ell, 2.0 * ell, 3.0 * ell); - Vector3d dir(1.0, 2.0, 3.0); + glm::dvec3 loc(1.0 * ell, 2.0 * ell, 3.0 * ell); + glm::dvec3 dir(1.0, 2.0, 3.0); RayEvent it = my_types[ell]; interaction_ptr ir = make_interaction_record(ell, it, loc, dir); rr->add_interaction_record(ir); @@ -215,8 +214,8 @@ TEST(SimulationResult, OstreamOperator) ray_record_ptr rr = make_ray_record(k); for (uint_fast32_t ell = 0; ell < NINTER; ++ell) { - Vector3d loc(1.0 * ell, 2.0 * ell, 3.0 * ell); - Vector3d dir(1.0, 2.0, 3.0); + glm::dvec3 loc(1.0 * ell, 2.0 * ell, 3.0 * ell); + glm::dvec3 dir(1.0, 2.0, 3.0); RayEvent it = my_types[ell]; interaction_ptr ir = make_interaction_record(ell, it, loc, dir); rr->add_interaction_record(ir); @@ -250,8 +249,8 @@ TEST(SimulationResult, IndexOperator) ray_record_ptr rr = make_ray_record(k); for (uint_fast32_t ell = 0; ell < NINTER; ++ell) { - Vector3d loc(1.0 * ell, 2.0 * ell, 3.0 * ell); - Vector3d dir(1.0, 2.0, 3.0); + glm::dvec3 loc(1.0 * ell, 2.0 * ell, 3.0 * ell); + glm::dvec3 dir(1.0, 2.0, 3.0); RayEvent it = my_types[ell]; interaction_ptr ir = make_interaction_record(ell, it, loc, dir); rr->add_interaction_record(ir); @@ -292,8 +291,8 @@ TEST(SimulationResult, WriteCSV) ray_record_ptr rr = make_ray_record(k); for (uint_fast32_t ell = 0; ell < NINTER; ++ell) { - Vector3d loc(1.0 * ell, 2.0 * ell, 3.0 * ell); - Vector3d dir(1.0, 2.0, 3.0); + glm::dvec3 loc(1.0 * ell, 2.0 * ell, 3.0 * ell); + glm::dvec3 dir(1.0, 2.0, 3.0); RayEvent it = my_types[ell]; interaction_ptr ir = make_interaction_record(ell, it, loc, dir); rr->add_interaction_record(ir); diff --git a/google-tests/unit-tests/simulation_runner/native_runner/cylinder_calculator_test.cpp b/google-tests/unit-tests/simulation_runner/native_runner/cylinder_calculator_test.cpp index 8b8330c1..d2281633 100644 --- a/google-tests/unit-tests/simulation_runner/native_runner/cylinder_calculator_test.cpp +++ b/google-tests/unit-tests/simulation_runner/native_runner/cylinder_calculator_test.cpp @@ -36,16 +36,16 @@ TEST(CylinderCalculator, Case1) CylinderCalculator calc(surface, aperture); // Ray position and direction - Vector3d x0(-1.0, -1.0, -1.0); - Vector3d m(0.0, 1.0, 0.0); + glm::dvec3 x0(-1.0, -1.0, -1.0); + glm::dvec3 m(0.0, 1.0, 0.0); // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; - int result = calc.intersect(x0.data, m.data, xt.data, mt.data, gradf.data, &t); + int result = calc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(result, 1); EXPECT_EQ(t, 0.0); @@ -61,16 +61,16 @@ TEST(CylinderCalculator, Case2) CylinderCalculator calc(surface, aperture); // Ray position and direction - Vector3d x0(5.0, 0.0, 1.0); - Vector3d m(-1.0, 1.0, 1.0); + glm::dvec3 x0(5.0, 0.0, 1.0); + glm::dvec3 m(-1.0, 1.0, 1.0); // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; - int result = calc.intersect(x0.data, m.data, xt.data, mt.data, gradf.data, &t); + int result = calc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(result, 1); EXPECT_EQ(t, 0.0); @@ -87,16 +87,16 @@ TEST(CylinderCalculator, Case3) CylinderCalculator calc(surface, aperture); // Ray position and direction - Vector3d x0(5.0, -3.0, 1.0); - Vector3d m(-1.0, 1.0, 0.0); + glm::dvec3 x0(5.0, -3.0, 1.0); + glm::dvec3 m(-1.0, 1.0, 0.0); // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; - int result = calc.intersect(x0.data, m.data, xt.data, mt.data, gradf.data, &t); + int result = calc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(result, 0); EXPECT_NEAR(t, 4.0, TOL); @@ -119,16 +119,16 @@ TEST(CylinderCalculator, Case4) CylinderCalculator calc(surface, aperture); // Ray position and direction - Vector3d x0(0.0, -1.0, 1.0); - Vector3d m(-1.0, 1.0, 0.0); + glm::dvec3 x0(0.0, -1.0, 1.0); + glm::dvec3 m(-1.0, 1.0, 0.0); // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; - int result = calc.intersect(x0.data, m.data, xt.data, mt.data, gradf.data, &t); + int result = calc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(result, 0); EXPECT_NEAR(t, 1.0, TOL); @@ -150,16 +150,16 @@ TEST(CylinderCalculator, Case5) CylinderCalculator calc(surface, aperture); // Ray position and direction - Vector3d x0(5.0, ymax, 1.0); - Vector3d m(-1.0, 1.0, 0.0); + glm::dvec3 x0(5.0, ymax, 1.0); + glm::dvec3 m(-1.0, 1.0, 0.0); // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; - int result = calc.intersect(x0.data, m.data, xt.data, mt.data, gradf.data, &t); + int result = calc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(result, 1); EXPECT_EQ(t, 0.0); @@ -175,16 +175,16 @@ TEST(CylinderCalculator, Case6) CylinderCalculator calc(surface, aperture); // Ray position and direction - Vector3d x0(5.0, ymax, 1.0); - Vector3d m(-1.0, 1.0, 0.0); + glm::dvec3 x0(5.0, ymax, 1.0); + glm::dvec3 m(-1.0, 1.0, 0.0); // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; - int result = calc.intersect(x0.data, m.data, xt.data, mt.data, gradf.data, &t); + int result = calc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(result, 1); EXPECT_EQ(t, 0.0); diff --git a/google-tests/unit-tests/simulation_runner/native_runner/flat_calculator_test.cpp b/google-tests/unit-tests/simulation_runner/native_runner/flat_calculator_test.cpp index b6d3aec5..d6f13915 100644 --- a/google-tests/unit-tests/simulation_runner/native_runner/flat_calculator_test.cpp +++ b/google-tests/unit-tests/simulation_runner/native_runner/flat_calculator_test.cpp @@ -4,7 +4,6 @@ #include #include -#include #include "common.hpp" @@ -43,22 +42,20 @@ TEST(FlatCalculator, ConstructorValid) TEST(FlatCalculator, Case1) { // Case: mz = 0, parallel to plane -- returns no solution - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Ray position - Vector3d x0(2.0, 1.0, -3.0); + glm::dvec3 x0(2.0, 1.0, -3.0); // Ray direction - Vector3d m(1.0, 1.0, 0.0); + glm::dvec3 m(1.0, 1.0, 0.0); // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; FlatCalculator fcalc(create_flat_surface(), create_rectangle_aperture()); - int sts = fcalc.intersect(x0.data, m.data, - xt.data, mt.data, gradf.data, &t); + int sts = fcalc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 1); EXPECT_EQ(t, 0.0); EXPECT_TRUE(is_identical(xt, zero)); @@ -69,22 +66,20 @@ TEST(FlatCalculator, Case1) TEST(FlatCalculator, Case2) { // Case: t < 0.0 -- returns no solution - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Ray position - Vector3d x0(2.0, 1.0, -3.0); + glm::dvec3 x0(2.0, 1.0, -3.0); // Ray direction - Vector3d m(1.0, 1.0, -2.0); + glm::dvec3 m(1.0, 1.0, -2.0); // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; FlatCalculator fcalc(create_flat_surface(), create_rectangle_aperture()); - int sts = fcalc.intersect(x0.data, m.data, - xt.data, mt.data, gradf.data, &t); + int sts = fcalc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 1); EXPECT_EQ(t, 0.0); EXPECT_TRUE(is_identical(xt, zero)); @@ -95,26 +90,24 @@ TEST(FlatCalculator, Case2) TEST(FlatCalculator, Case3) { // Case: t > 0.0 -- returns solution - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Ray position - Vector3d x0(2.0, 1.0, -3.0); + glm::dvec3 x0(2.0, 1.0, -3.0); // Ray direction - Vector3d m(1.0, 1.0, 2.0); + glm::dvec3 m(1.0, 1.0, 2.0); // Solution const double T = 1.5; const double TOL = 1e-12; // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; FlatCalculator fcalc(create_flat_surface(), create_rectangle_aperture(10.0, 10.0)); - int sts = fcalc.intersect(x0.data, m.data, - xt.data, mt.data, gradf.data, &t); + int sts = fcalc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 0); EXPECT_NEAR(t, T, TOL); EXPECT_NEAR(xt[0], x0[0] + m[0] * T, TOL); @@ -130,26 +123,24 @@ TEST(FlatCalculator, Case3) TEST(FlatCalculator, Case4) { // Case: t > 0.0, outside aperture -- returns no solution - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Ray position - Vector3d x0(2.0, 1.0, -3.0); + glm::dvec3 x0(2.0, 1.0, -3.0); // Ray direction - Vector3d m(1.0, 1.0, 2.0); + glm::dvec3 m(1.0, 1.0, 2.0); // Solution const double T = 1.5; // const double TOL = 1e-12; // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; FlatCalculator fcalc(create_flat_surface(), create_rectangle_aperture(1.0, 1.0)); - int sts = fcalc.intersect(x0.data, m.data, - xt.data, mt.data, gradf.data, &t); + int sts = fcalc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 1); EXPECT_EQ(t, 0.0); diff --git a/google-tests/unit-tests/simulation_runner/native_runner/native_runner_test.cpp b/google-tests/unit-tests/simulation_runner/native_runner/native_runner_test.cpp index f89a283c..3be50d80 100644 --- a/google-tests/unit-tests/simulation_runner/native_runner/native_runner_test.cpp +++ b/google-tests/unit-tests/simulation_runner/native_runner/native_runner_test.cpp @@ -63,7 +63,7 @@ TEST(NativeRunnerTypes, TSun) SimulationData my_sim; auto sun = SolTrace::Data::make_ray_source(); - Vector3d spos(1.0, 2.0, 3.0); + glm::dvec3 spos(1.0, 2.0, 3.0); sun->set_position(spos); sun->set_shape(SunShape::PILLBOX, -1.0, 1.0, 0.0); my_sim.add_ray_source(sun); @@ -90,25 +90,25 @@ TEST(NativeRunnerTypes, MakeStage) // // SimulationData my_sim; // // // **** Setup Answers **** // // // // Origin -// // Vector3d Origin1(1.0, 2.0, 3.0); +// // glm::dvec3 Origin1(1.0, 2.0, 3.0); // // // Corresponding Euler angles in radians // // const double a1 = 0.0; // // const double b1 = asin(-1.0 / sqrt(3.0)); // // const double g1 = acos(1.0 / cos(b1) * 1.0 / sqrt(6.0)); // approximately 0.615 // // // Corresponding aim vector (local z-axis in reference coordinates) -// // Vector3d aim1(0.0, -1.0 / sqrt(3.0), sqrt(2.0 / 3.0)); +// // glm::dvec3 aim1(0.0, -1.0 / sqrt(3.0), sqrt(2.0 / 3.0)); // // vector_add(1.0, Origin1, 1.0, aim1); // // // Z-Rotation is the last of the Euler angles but in degrees // // const double zrot1 = g1 * 180.0 / PI; // // // Origin -// // Vector3d Origin2(-3.0, 1.0, -5.0); +// // glm::dvec3 Origin2(-3.0, 1.0, -5.0); // // const double a2 = PI / 4.0; // // const double b2 = PI / 6.0; // // const double g2 = PI / 3.0; // // // Corresponding aim vector (local z-axis in reference coordinates) -// // Vector3d aim2(sqrt(3.0 / 8.0), 0.5, sqrt(3.0 / 8.0)); +// // glm::dvec3 aim2(sqrt(3.0 / 8.0), 0.5, sqrt(3.0 / 8.0)); // // vector_add(1.0, Origin2, 1.0, aim2); // // // Z-Rotation is the last of the Euler angles but in degrees @@ -171,8 +171,8 @@ TEST(NativeRunner, SmokeTest) element_ptr el = SolTrace::Data::make_element(); el->set_aperture(SolTrace::Data::make_aperture(2.0)); el->set_surface(SolTrace::Data::make_surface()); - el->set_reference_frame_geometry(Vector3d(x[k], y[k], 0.0), - Vector3d(-x[k], -y[k], 1.0), + el->set_reference_frame_geometry(glm::dvec3(x[k], y[k], 0.0), + glm::dvec3(-x[k], -y[k], 1.0), 0.0); el->set_front_optical_properties(optics); el->set_back_optical_properties(optics); @@ -270,8 +270,8 @@ TEST(NativeRunner, PowerTowerSmokeTest) st0->set_origin(0.0, 0.0, 0.0); st0->set_aim_vector(0.0, 0.0, 1.0); - Vector3d rvec, svec, avec; - Vector3d aim, pos; + glm::dvec3 rvec, svec, avec; + glm::dvec3 aim, pos; const int NUM_ELEMENTS = 10; for (int k = 0; k < NUM_ELEMENTS; ++k) @@ -280,17 +280,12 @@ TEST(NativeRunner, PowerTowerSmokeTest) foptics = el->get_front_optical_properties(); foptics->reflectivity = 1.0; - pos.set_values(5 * sin(k * PI * 2.0 / NUM_ELEMENTS), - 5 * cos(k * PI * 2.0 / NUM_ELEMENTS), - 0.0); - vector_add(1.0, absorber->get_origin_global(), - -1.0, pos, - rvec); - make_unit_vector(rvec); - svec = sun->get_position(); - make_unit_vector(svec); - vector_add(0.5, rvec, 0.5, svec, avec); - vector_add(1.0, pos, 100.0, avec, aim); + pos = {5 * sin(k * PI * 2.0 / NUM_ELEMENTS), 5 * cos(k * PI * 2.0 / NUM_ELEMENTS), 0.0}; + rvec = glm::normalize(absorber->get_origin_global() - pos); + svec = glm::normalize(sun->get_position()); + + avec = 0.5 * rvec + 0.5 * svec; + aim = pos + 100.0 * avec; el->set_reference_frame_geometry(pos, aim, 0.0); @@ -375,12 +370,12 @@ TEST(NativeRunner, SingleRayValidationTest) double zref = R - sqrt(R * R - (x * x + y * y)); double z = z0 - zref; - Vector3d u(0.0, 0.0, -1.0); - Vector3d v(2.0 * x, 2.0 * y, -2.0 * (z0 - z - R)); - v.make_unit(); - Vector3d w; - double alpha = dot_product(u, v); - vector_add(1.0, u, -2.0 * alpha, v, w); + glm::dvec3 u(0.0, 0.0, -1.0); + glm::dvec3 v(2.0 * x, 2.0 * y, -2.0 * (z0 - z - R)); + SolTrace::Data::normalize_inplace(v); + + double alpha = glm::dot(u, v); + glm::dvec3 w = u + (-2.0 * alpha * v); SimulationData sd; @@ -400,8 +395,8 @@ TEST(NativeRunner, SingleRayValidationTest) sd.add_ray_source(sun); auto sph = SolTrace::Data::make_element(); - Vector3d origin(0.0, 0.0, z0); - Vector3d aim(0.0, 0.0, -1.0); + glm::dvec3 origin(0.0, 0.0, z0); + glm::dvec3 aim(0.0, 0.0, -1.0); double zrot = 0.0; sph->set_reference_frame_geometry(origin, aim, zrot); sph->set_aperture(SolTrace::Data::make_aperture(20.0)); @@ -412,8 +407,8 @@ TEST(NativeRunner, SingleRayValidationTest) sd.add_element(sph); auto para = SolTrace::Data::make_element(); - origin.set_values(0.0, 0.0, -1.0); - aim.set_values(0.0, 0.0, 0.0); + origin = {0.0, 0.0, -1.0}; + aim = {}; zrot = 0.0; para->set_reference_frame_geometry(origin, aim, zrot); para->set_aperture(SolTrace::Data::make_aperture(31.0, 31.0)); @@ -438,12 +433,11 @@ TEST(NativeRunner, SingleRayValidationTest) EXPECT_EQ(n, 3); - Vector3d ipoint, idir; + glm::dvec3 ipoint, idir; int element, stage; uint_fast64_t raynum; SolTrace::Result::RayEvent rev; - sys->RayData.Query(0, ipoint.data, idir.data, - &element, &stage, &raynum, &rev); + sys->RayData.Query(0, ipoint, idir, &element, &stage, &raynum, &rev); EXPECT_EQ(raynum, 1); EXPECT_EQ(rev, SolTrace::Result::RayEvent::CREATE); @@ -456,8 +450,7 @@ TEST(NativeRunner, SingleRayValidationTest) EXPECT_NEAR(idir[1], u[1], TOL); EXPECT_NEAR(idir[2], u[2], TOL); - sys->RayData.Query(1, ipoint.data, idir.data, - &element, &stage, &raynum, &rev); + sys->RayData.Query(1, ipoint, idir, &element, &stage, &raynum, &rev); EXPECT_EQ(raynum, 1); EXPECT_EQ(rev, SolTrace::Result::RayEvent::REFLECT); diff --git a/google-tests/unit-tests/simulation_runner/native_runner/newton_calculator_test.cpp b/google-tests/unit-tests/simulation_runner/native_runner/newton_calculator_test.cpp index d509969b..9418dbed 100644 --- a/google-tests/unit-tests/simulation_runner/native_runner/newton_calculator_test.cpp +++ b/google-tests/unit-tests/simulation_runner/native_runner/newton_calculator_test.cpp @@ -3,7 +3,6 @@ #include #include -#include #include @@ -23,14 +22,12 @@ class ParabolaNewton : public NewtonCalculator { } virtual ~ParabolaNewton() {} - virtual void set_zstart(double PosXYZ[3]) + virtual void set_zstart(glm::dvec3 &PosXYZ) { PosXYZ[2] = 0.0; return; } - virtual void surface_and_jacobian(const double PosXYZ[3], - double *F, - double DFXYZ[3]) + virtual void surface_and_jacobian(glm::dvec3 PosXYZ, double *F, glm::dvec3 &DFXYZ) { double x0 = PosXYZ[0]; double y0 = PosXYZ[1]; @@ -55,9 +52,9 @@ TEST(NewtonCalculator, Case1) { // Case: newton's method converges // Ray location - Vector3d x0(-2.0, 1.0, 0.0); + glm::dvec3 x0(-2.0, 1.0, 0.0); // Ray direction - Vector3d m(2.0, 0.5, 3.0); + glm::dvec3 m(2.0, 0.5, 3.0); // Intersection point const double T = 2.0 / 3.0; const double TOL = 1e-12; @@ -69,15 +66,13 @@ TEST(NewtonCalculator, Case1) // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; auto rect = create_rectangle_aperture(20.0, 20.0); ParabolaNewton pnewt(cx, cy, rect, TOL, MAX_ITERS); - int sts = pnewt.intersect(x0.data, m.data, - xt.data, mt.data, - gradf.data, &t); + int sts = pnewt.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 0); EXPECT_NEAR(t, T, TOL); EXPECT_NEAR(xt[0], m[0] * T + x0[0], TOL); @@ -93,12 +88,11 @@ TEST(NewtonCalculator, Case1) TEST(NewtonCalculator, Case2) { // Case: newton's method diverges - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Ray location - Vector3d x0(-2.0, 1.0, 0.0); + glm::dvec3 x0(-2.0, 1.0, 0.0); // Ray direction - Vector3d m(1.0, 1.0, 1.0); + glm::dvec3 m(1.0, 1.0, 1.0); // Parabola constants and newton constants const double TOL = 1e-12; @@ -108,14 +102,13 @@ TEST(NewtonCalculator, Case2) // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; auto rect = create_rectangle_aperture(20.0, 20.0); ParabolaNewton pnewt(cx, cy, rect, TOL, MAX_ITERS); - int sts = pnewt.intersect(x0.data, m.data, - xt.data, mt.data, gradf.data, &t); + int sts = pnewt.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 1); EXPECT_EQ(t, 0.0); EXPECT_TRUE(is_identical(xt, zero)); diff --git a/google-tests/unit-tests/simulation_runner/native_runner/parabola_calculator_test.cpp b/google-tests/unit-tests/simulation_runner/native_runner/parabola_calculator_test.cpp index b070a8d9..f83f5435 100644 --- a/google-tests/unit-tests/simulation_runner/native_runner/parabola_calculator_test.cpp +++ b/google-tests/unit-tests/simulation_runner/native_runner/parabola_calculator_test.cpp @@ -6,7 +6,6 @@ #include #include #include -#include using SolTrace::NativeRunner::ParabolaCalculator; @@ -94,24 +93,22 @@ TEST(ParabolaCalculator, ConstructorValidFocalLength) TEST(ParabolaCalculator, Case1) { // Case: a == 0, t <= 0 -- returns no solution - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Ray location - Vector3d x0(0.0, 0.0, 1.0); + glm::dvec3 x0(0.0, 0.0, 1.0); // Ray direction - Vector3d m(0.0, 0.0, 1.0); + glm::dvec3 m(0.0, 0.0, 1.0); // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; auto parabola = SolTrace::Data::make_surface(0.5, 0.25); auto circ = create_circle_aperture(10.0); ParabolaCalculator pcalc(parabola, circ); - int sts = pcalc.intersect(x0.data, m.data, - xt.data, mt.data, gradf.data, &t); + int sts = pcalc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 1); EXPECT_EQ(t, 0.0); EXPECT_TRUE(is_identical(xt, zero)); @@ -124,9 +121,9 @@ TEST(ParabolaCalculator, Case2) // Case: a == 0, t > 0 -- returns t // NOTE: Here the quadratic equation reduces to a linear equation // Ray location - Vector3d x0(0.0, 0.0, -1.0); + glm::dvec3 x0(0.0, 0.0, -1.0); // Ray direction - Vector3d m(0.0, 0.0, 1.0); + glm::dvec3 m(0.0, 0.0, 1.0); // Intersection point const double T = 1.0; const double TOL = 1e-12; @@ -136,15 +133,14 @@ TEST(ParabolaCalculator, Case2) // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; auto parabola = SolTrace::Data::make_surface(0.5, 0.25); auto circ = create_circle_aperture(10.0); ParabolaCalculator pcalc(parabola, circ); - int sts = pcalc.intersect(x0.data, m.data, - xt.data, mt.data, gradf.data, &t); + int sts = pcalc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 0); EXPECT_NEAR(t, T, TOL); EXPECT_NEAR(xt[0], 0.0, TOL); @@ -160,24 +156,22 @@ TEST(ParabolaCalculator, Case2) TEST(ParabolaCalculator, Case3) { // Case: a != 0, Delta = b^2 - 4ac < 0 -- returns no solution - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Ray location - Vector3d x0(-2.0, 1.0, 0.0); + glm::dvec3 x0(-2.0, 1.0, 0.0); // Ray direction - Vector3d m(1.0, 1.0, 1.0); + glm::dvec3 m(1.0, 1.0, 1.0); // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; auto parabola = SolTrace::Data::make_surface(0.5, 0.25); auto circ = create_circle_aperture(10.0); ParabolaCalculator pcalc(parabola, circ); - int sts = pcalc.intersect(x0.data, m.data, - xt.data, mt.data, gradf.data, &t); + int sts = pcalc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 1); EXPECT_EQ(t, 0.0); EXPECT_TRUE(is_identical(xt, zero)); @@ -189,9 +183,9 @@ TEST(ParabolaCalculator, Case4) { // Case: a != 0, Delta >= 0, t1 > 0 -- returns t1 // Ray location - Vector3d x0(-2.0, 1.0, 0.0); + glm::dvec3 x0(-2.0, 1.0, 0.0); // Ray direction - Vector3d m(2.0, 0.5, 3.0); + glm::dvec3 m(2.0, 0.5, 3.0); // Intersection point const double T = 2.0 / 3.0; const double TOL = 1e-12; @@ -201,16 +195,15 @@ TEST(ParabolaCalculator, Case4) // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; auto parabola = SolTrace::Data::make_surface(focal_length(cx), focal_length(cy)); auto circ = create_circle_aperture(10.0); ParabolaCalculator pcalc(parabola, circ); - int sts = pcalc.intersect(x0.data, m.data, - xt.data, mt.data, gradf.data, &t); + int sts = pcalc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 0); EXPECT_NEAR(t, T, TOL); EXPECT_NEAR(xt[0], m[0] * T + x0[0], TOL); @@ -227,9 +220,9 @@ TEST(ParabolaCalculator, Case5) { // Case: a != 0, Delta >= 0, t1 < 0, t2 > 0 -- returns t2 // Ray location - Vector3d x0(1.0, -1.0, 3.0); + glm::dvec3 x0(1.0, -1.0, 3.0); // Ray direction - Vector3d m(1.0, 0.0, 2.0); + glm::dvec3 m(1.0, 0.0, 2.0); // Intersection point const double T = 3.0; const double TOL = 1e-12; @@ -239,16 +232,15 @@ TEST(ParabolaCalculator, Case5) // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; auto parabola = SolTrace::Data::make_surface(focal_length(cx), focal_length(cy)); auto circ = create_circle_aperture(10.0); ParabolaCalculator pcalc(parabola, circ); - int sts = pcalc.intersect(x0.data, m.data, - xt.data, mt.data, gradf.data, &t); + int sts = pcalc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 0); EXPECT_NEAR(t, T, TOL); EXPECT_NEAR(xt[0], m[0] * T + x0[0], TOL); @@ -264,12 +256,11 @@ TEST(ParabolaCalculator, Case5) TEST(ParabolaCalculator, Case6) { // Case: a != 0, Delta >= 0, t1 < 0, t2 < 0 -- returns no solution - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Ray location - Vector3d x0(3.0, 1.0, 2.0); + glm::dvec3 x0(3.0, 1.0, 2.0); // Ray direction - Vector3d m(1.0, -1.0, -4.0); + glm::dvec3 m(1.0, -1.0, -4.0); // Intersection point const double T = 1.0 + sqrt(8.0); const double TOL = 1e-12; @@ -279,16 +270,15 @@ TEST(ParabolaCalculator, Case6) // Solution values double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; auto parabola = SolTrace::Data::make_surface(focal_length(cx), focal_length(cy)); auto circ = create_circle_aperture(10.0); ParabolaCalculator pcalc(parabola, circ); - int sts = pcalc.intersect(x0.data, m.data, - xt.data, mt.data, gradf.data, &t); + int sts = pcalc.intersect(x0, m, xt, mt, gradf, &t); EXPECT_EQ(sts, 1); EXPECT_EQ(t, 0.0); EXPECT_TRUE(is_identical(xt, zero)); diff --git a/google-tests/unit-tests/simulation_runner/native_runner/sphere_calculator_test.cpp b/google-tests/unit-tests/simulation_runner/native_runner/sphere_calculator_test.cpp index 3da0a380..e4b85637 100644 --- a/google-tests/unit-tests/simulation_runner/native_runner/sphere_calculator_test.cpp +++ b/google-tests/unit-tests/simulation_runner/native_runner/sphere_calculator_test.cpp @@ -99,24 +99,23 @@ TEST(SphereCalculator, ConstructorValid) TEST(SphereCalculator, Case1) { // Delta < 0 -- returns no solution - Vector3d r0(3.0, -1.0, 1.0); - Vector3d rd(-3.0, 1.0, -2.0); + glm::dvec3 r0(3.0, -1.0, 1.0); + glm::dvec3 rd(-3.0, 1.0, -2.0); double radius = 1.0; - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Solution values int sts; double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; surface_ptr sph = make_surface(1.0 / radius); auto circ = create_circle_aperture(radius); SphereCalculator scalc(sph, circ); - sts = scalc.intersect(r0.data, rd.data, xt.data, mt.data, gradf.data, &t); + sts = scalc.intersect(r0, rd, xt, mt, gradf, &t); EXPECT_EQ(sts, 1); EXPECT_EQ(t, 0.0); EXPECT_TRUE(is_identical(xt, zero)); @@ -129,24 +128,24 @@ TEST(SphereCalculator, Case2) // t1 > 0 -- returns t1 const double TOL = 1e-12; - Vector3d r0(3.0, -1.0, 1.0); - Vector3d rd(-3.0, 1.0, -0.5); + glm::dvec3 r0(3.0, -1.0, 1.0); + glm::dvec3 rd(-3.0, 1.0, -0.5); double radius = 1.0; double T = 0.5 * (20 - sqrt(31)) / 10.25; - Vector3d s0(0.0, 0.0, radius); + glm::dvec3 s0(0.0, 0.0, radius); // Solution values int sts; double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; - Vector3d r; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; + glm::dvec3 r; surface_ptr sph = make_surface(1.0 / radius); auto circ = create_circle_aperture(radius); SphereCalculator scalc(sph, circ); - sts = scalc.intersect(r0.data, rd.data, xt.data, mt.data, gradf.data, &t); + sts = scalc.intersect(r0, rd, xt, mt, gradf, &t); EXPECT_EQ(sts, 0); EXPECT_NEAR(t, T, TOL); @@ -158,8 +157,8 @@ TEST(SphereCalculator, Case2) EXPECT_NEAR(gradf[1], -2.0 * (rd[1] * T + r0[1]), TOL); EXPECT_NEAR(gradf[2], -2.0 * (rd[2] * T + r0[2] - radius), TOL); - vector_add(1.0, xt, -1.0, s0, r); - EXPECT_NEAR(vector_norm(r), radius, TOL); + r = xt - s0; + EXPECT_NEAR(glm::length(r), radius, TOL); } TEST(SphereCalculator, Case3) @@ -167,24 +166,24 @@ TEST(SphereCalculator, Case3) // t1 > 0, z1 > r, t2 > 0, z2 < r -- returns t2 const double TOL = 1e-12; - Vector3d r0(3.0, -1.0, 2.0); - Vector3d rd(-3.0, 1.0, -1.0); + glm::dvec3 r0(3.0, -1.0, 2.0); + glm::dvec3 rd(-3.0, 1.0, -1.0); double radius = 1.0; double T = 0.5 * (22 + sqrt(44)) / 11; - Vector3d s0(0.0, 0.0, radius); + glm::dvec3 s0(0.0, 0.0, radius); // Solution values int sts; double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; - Vector3d r; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; + glm::dvec3 r; surface_ptr sph = make_surface(1.0 / radius); auto circ = create_circle_aperture(radius); SphereCalculator scalc(sph, circ); - sts = scalc.intersect(r0.data, rd.data, xt.data, mt.data, gradf.data, &t); + sts = scalc.intersect(r0, rd, xt, mt, gradf, &t); EXPECT_EQ(sts, 0); EXPECT_NEAR(t, T, TOL); @@ -196,31 +195,30 @@ TEST(SphereCalculator, Case3) EXPECT_NEAR(gradf[1], -2.0 * (rd[1] * T + r0[1]), TOL); EXPECT_NEAR(gradf[2], -2.0 * (rd[2] * T + r0[2] - radius), TOL); - vector_add(1.0, xt, -1.0, s0, r); - EXPECT_NEAR(vector_norm(r), radius, TOL); + r = xt - s0; + EXPECT_NEAR(glm::length(r), radius, TOL); } TEST(SphereCalculator, Case4) { // t1, t2 > 0, z1, z2 > r -- returns no solution - Vector3d r0(3.0, -1.0, 2.0); - Vector3d rd(-3.0, 1.0, -0.5); + glm::dvec3 r0(3.0, -1.0, 2.0); + glm::dvec3 rd(-3.0, 1.0, -0.5); double radius = 1.0; - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Solution values int sts; double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; surface_ptr sph = make_surface(1.0 / radius); auto circ = create_circle_aperture(radius); SphereCalculator scalc(sph, circ); - sts = scalc.intersect(r0.data, rd.data, xt.data, mt.data, gradf.data, &t); + sts = scalc.intersect(r0, rd, xt, mt, gradf, &t); EXPECT_EQ(sts, 1); EXPECT_EQ(t, 0.0); EXPECT_TRUE(is_identical(xt, zero)); @@ -233,22 +231,22 @@ TEST(SphereCalculator, Case5) // t1 < 0, t2 > 0, z2 < r -- returns t2 const double TOL = 1e-12; - Vector3d r0(-0.5, 0.5, 0.5); - Vector3d rd(-3.0, 1.0, -0.5); + glm::dvec3 r0(-0.5, 0.5, 0.5); + glm::dvec3 rd(-3.0, 1.0, -0.5); double radius = 1.0; double T = 0.5 * (-4.5 + sqrt(30.5)) / 10.25; // Solution values int sts; double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; surface_ptr sph = make_surface(1.0 / radius); auto circ = create_circle_aperture(radius); SphereCalculator scalc(sph, circ); - sts = scalc.intersect(r0.data, rd.data, xt.data, mt.data, gradf.data, &t); + sts = scalc.intersect(r0, rd, xt, mt, gradf, &t); EXPECT_EQ(sts, 0); EXPECT_NEAR(t, T, TOL); @@ -264,24 +262,23 @@ TEST(SphereCalculator, Case5) TEST(SphereCalculator, Case6) { // t1 < 0, t2 > 0, z2 > r -- returns no intersection - Vector3d r0(-0.5, 0.5, 0.5); - Vector3d rd(-1.0, 1.0, 5.0); + glm::dvec3 r0(-0.5, 0.5, 0.5); + glm::dvec3 rd(-1.0, 1.0, 5.0); double radius = 1.0; - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Solution values int sts; double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; surface_ptr sph = make_surface(1.0 / radius); auto circ = create_circle_aperture(radius); SphereCalculator scalc(sph, circ); - sts = scalc.intersect(r0.data, rd.data, xt.data, mt.data, gradf.data, &t); + sts = scalc.intersect(r0, rd, xt, mt, gradf, &t); EXPECT_EQ(sts, 1); EXPECT_EQ(t, 0.0); EXPECT_TRUE(is_identical(xt, zero)); @@ -292,24 +289,23 @@ TEST(SphereCalculator, Case6) TEST(SphereCalculator, Case7) { // t1 < 0, t2 < 0 -- returns no intersection - Vector3d r0(-0.5, 0.5, 3.0); - Vector3d rd(-1.0, 1.0, 5.0); + glm::dvec3 r0(-0.5, 0.5, 3.0); + glm::dvec3 rd(-1.0, 1.0, 5.0); double radius = 1.0; - Vector3d zero; - zero.zero(); + glm::dvec3 zero(0.0); // Solution values int sts; double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; surface_ptr sph = make_surface(1.0 / radius); auto circ = create_circle_aperture(radius); SphereCalculator scalc(sph, circ); - sts = scalc.intersect(r0.data, rd.data, xt.data, mt.data, gradf.data, &t); + sts = scalc.intersect(r0, rd, xt, mt, gradf, &t); EXPECT_EQ(sts, 1); EXPECT_EQ(t, 0.0); EXPECT_TRUE(is_identical(xt, zero)); @@ -322,22 +318,22 @@ TEST(SphereCalculator, Case8) // t1 == t2 > 0 -- returns t1 const double TOL = 1e-12; - Vector3d r0(-1.0, -1.0, 0.0); - Vector3d rd(1.0, 1.0, 0.0); + glm::dvec3 r0(-1.0, -1.0, 0.0); + glm::dvec3 rd(1.0, 1.0, 0.0); double radius = 1.0; double T = 0.5 * (4.0 - sqrt(0)) / 2; // Solution values int sts; double t; - Vector3d xt; - Vector3d mt; - Vector3d gradf; + glm::dvec3 xt; + glm::dvec3 mt; + glm::dvec3 gradf; surface_ptr sph = make_surface(1.0 / radius); auto circ = create_circle_aperture(radius); SphereCalculator scalc(sph, circ); - sts = scalc.intersect(r0.data, rd.data, xt.data, mt.data, gradf.data, &t); + sts = scalc.intersect(r0, rd, xt, mt, gradf, &t); EXPECT_EQ(sts, 0); EXPECT_NEAR(t, T, TOL); diff --git a/google-tests/unit-tests/simulation_runner/native_runner/tower_demo.cpp b/google-tests/unit-tests/simulation_runner/native_runner/tower_demo.cpp index bbceeb5d..f1f51106 100644 --- a/google-tests/unit-tests/simulation_runner/native_runner/tower_demo.cpp +++ b/google-tests/unit-tests/simulation_runner/native_runner/tower_demo.cpp @@ -8,7 +8,7 @@ #include // #include // #include -// #include +// #include #include #include @@ -73,8 +73,8 @@ SimulationData create_tower_demo_simulation_data(bool create_stages) sd.add_element(absorber); } - Vector3d rvec, svec, avec; - Vector3d aim, pos; + glm::dvec3 rvec, svec, avec; + glm::dvec3 aim, pos; for (int i = -1; i < 2; ++i) { @@ -82,19 +82,15 @@ SimulationData create_tower_demo_simulation_data(bool create_stages) foptics = el->get_front_optical_properties(); foptics->reflectivity = 1.0; - pos.set_values(5 * sin(i * PI / 2.0), - 5 * cos(i * PI / 2.0), - 0.0); + pos = {5 * sin(i * PI / 2.0), 5 * cos(i * PI / 2.0), 0.0}; el->set_origin(pos); - vector_add(1.0, absorber->get_origin_global(), - -1.0, pos, - rvec); - make_unit_vector(rvec); + rvec = absorber->get_origin_global() - pos; + SolTrace::Data::normalize_inplace(rvec); svec = sun->get_position(); - make_unit_vector(svec); - vector_add(0.5, rvec, 0.5, svec, avec); + SolTrace::Data::normalize_inplace(svec); + avec = 0.5 * rvec + 0.5 * svec; - vector_add(1.0, pos, 100.0, avec, aim); + aim = pos + 100.0 * avec; el->set_aim_vector(aim); // TODO: Set zrot as in python file? From 52258c40ac6d41a8041b17a7d17d8ff6c19aa100 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Fri, 23 Jan 2026 14:27:24 -0700 Subject: [PATCH 02/23] Passes tests, but is a bit slow --- coretrace/simulation_data/element.cpp | 33 +++--- coretrace/simulation_data/matvec.cpp | 40 ++++--- .../determine_element_intersection_new.cpp | 19 ++- .../native_runner/find_element_hit.cpp | 9 +- .../native_runner/generate_ray.cpp | 16 +-- .../native_runner/native_runner_types.cpp | 34 +++--- .../native_runner/parabola_calculator.cpp | 24 ++-- .../native_runner_validation_test.cpp | 61 ++++++++++ google-tests/unit-tests/common/common.cpp | 17 ++- .../simulation_data/element_test.cpp | 65 ++++++----- .../simulation_data/linear_algebra_test.cpp | 110 ++++++++++-------- 11 files changed, 249 insertions(+), 179 deletions(-) diff --git a/coretrace/simulation_data/element.cpp b/coretrace/simulation_data/element.cpp index 6294ed8b..2e000e27 100644 --- a/coretrace/simulation_data/element.cpp +++ b/coretrace/simulation_data/element.cpp @@ -7,6 +7,10 @@ #include "json_helpers.hpp" #include "matvec.hpp" +#define GLM_ENABLE_EXPERIMENTAL 1 +#include +#include + namespace SolTrace::Data { // ElementContainer ElementBase::empty_container; @@ -25,8 +29,8 @@ ElementBase::ElementBase() : Element(), this->origin = glm::dvec3(0.0); this->euler_angles = glm::dvec3(0.0); - this->reference_to_local = glm::mat3(); - this->local_to_reference = glm::mat3(); + this->reference_to_local = glm::identity(); + this->local_to_reference = glm::identity(); return; } @@ -152,13 +156,13 @@ glm::dmat3 ElementBase::get_reference_to_local() const glm::dmat3 ElementBase::get_stage_to_local() const { - glm::dmat3 stage_to_local; + glm::dmat3 stage_to_local = glm::dmat3(0.0); if (this->is_stage()) { // stage_to_local.set_value(0, 0, 1.0); // stage_to_local.set_value(1, 1, 1.0); // stage_to_local.set_value(2, 2, 1.0); - stage_to_local = {}; + stage_to_local = glm::identity(); } else if (this->reference_element == nullptr) { @@ -174,13 +178,10 @@ glm::dmat3 ElementBase::get_stage_to_local() const glm::dmat3 ElementBase::get_global_to_local() const { - glm::dmat3 global_to_local; - if (this->reference_element == nullptr) - { + glm::dmat3 global_to_local = glm::dmat3(0.0); + if (this->reference_element == nullptr) { global_to_local = this->reference_to_local; - } - else - { + } else { glm::dmat3 R = this->reference_element->get_global_to_local(); global_to_local = this->reference_to_local * R; } @@ -194,12 +195,10 @@ glm::dmat3 ElementBase::get_local_to_reference() const glm::dmat3 ElementBase::get_local_to_stage() const { - glm::dmat3 local_to_stage; + glm::dmat3 local_to_stage = glm::dmat3(0.0); if (this->is_stage()) { - local_to_stage[0][0] = 1.0; - local_to_stage[1][1] = 1.0; - local_to_stage[2][2] = 1.0; + local_to_stage = glm::identity(); } else if (this->reference_element == nullptr) { @@ -215,7 +214,7 @@ glm::dmat3 ElementBase::get_local_to_stage() const glm::dmat3 ElementBase::get_local_to_global() const { - glm::dmat3 local_to_global; + glm::dmat3 local_to_global = glm::dmat3(0.0); if (this->reference_element == nullptr) { local_to_global = this->local_to_reference; @@ -234,7 +233,7 @@ int ElementBase::compute_coordinate_rotations() if (!this->coordinates_initialized) { - glm::dvec3 dr = glm::normalize(this->aim + -1.0 * this->origin); + glm::dvec3 dr = glm::normalize(this->aim - this->origin); this->euler_angles[0] = atan2(dr[0], dr[2]); this->euler_angles[1] = asin(dr[1]); @@ -264,7 +263,7 @@ int ElementBase::set_reference_frame_geometry(const glm::dvec3 &origin, int ElementBase::convert_reference_to_local(glm::dvec3 &local, const glm::dvec3 &ref) { - glm::dvec3 temp = ref + -1.0 * this->origin; + glm::dvec3 temp = ref - this->origin; local = this->reference_to_local * temp; return 0; } diff --git a/coretrace/simulation_data/matvec.cpp b/coretrace/simulation_data/matvec.cpp index 3dd7d212..b2216b18 100644 --- a/coretrace/simulation_data/matvec.cpp +++ b/coretrace/simulation_data/matvec.cpp @@ -266,13 +266,13 @@ namespace SolTrace::Data /*{Fill in elements of the transformation matrix as per Spencer and Murty paper page 673 equation (2)}*/ RRefToLoc[0][0] = CosAlpha * CosGamma + SinAlpha * SinBeta * SinGamma; - RRefToLoc[0][1] = -CosBeta * SinGamma; - RRefToLoc[0][2] = -SinAlpha * CosGamma + CosAlpha * SinBeta * SinGamma; - RRefToLoc[1][0] = CosAlpha * SinGamma - SinAlpha * SinBeta * CosGamma; + RRefToLoc[1][0] = -CosBeta * SinGamma; + RRefToLoc[2][0] = -SinAlpha * CosGamma + CosAlpha * SinBeta * SinGamma; + RRefToLoc[0][1] = CosAlpha * SinGamma - SinAlpha * SinBeta * CosGamma; RRefToLoc[1][1] = CosBeta * CosGamma; - RRefToLoc[1][2] = -SinAlpha * SinGamma - CosAlpha * SinBeta * CosGamma; - RRefToLoc[2][0] = SinAlpha * CosBeta; - RRefToLoc[2][1] = SinBeta; + RRefToLoc[2][1] = -SinAlpha * SinGamma - CosAlpha * SinBeta * CosGamma; + RRefToLoc[0][2] = SinAlpha * CosBeta; + RRefToLoc[1][2] = SinBeta; RRefToLoc[2][2] = CosAlpha * CosBeta; /*{Transpose the matrix to get the inverse transformation matrix for going back @@ -357,15 +357,25 @@ namespace SolTrace::Data /*{Fill in elements of the transformation matrix as per Spencer and Murty paper page 673 equation (2)}*/ - RRefToLoc[0][0] = CosAlpha * CosGamma + SinAlpha * SinBeta * SinGamma; - RRefToLoc[0][1] = -CosBeta * SinGamma; - RRefToLoc[0][2] = -SinAlpha * CosGamma + CosAlpha * SinBeta * SinGamma; - RRefToLoc[1][0] = CosAlpha * SinGamma - SinAlpha * SinBeta * CosGamma; - RRefToLoc[1][1] = CosBeta * CosGamma; - RRefToLoc[1][2] = -SinAlpha * SinGamma - CosAlpha * SinBeta * CosGamma; - RRefToLoc[2][0] = SinAlpha * CosBeta; - RRefToLoc[2][1] = SinBeta; - RRefToLoc[2][2] = CosAlpha * CosBeta; + // RRefToLoc[0][0] = CosAlpha * CosGamma + SinAlpha * SinBeta * SinGamma; + // RRefToLoc[1][0] = -CosBeta * SinGamma; + // RRefToLoc[2][0] = -SinAlpha * CosGamma + CosAlpha * SinBeta * SinGamma; + // RRefToLoc[0][1] = CosAlpha * SinGamma - SinAlpha * SinBeta * CosGamma; + // RRefToLoc[1][1] = CosBeta * CosGamma; + // RRefToLoc[2][1] = -SinAlpha * SinGamma - CosAlpha * SinBeta * CosGamma; + // RRefToLoc[0][2] = SinAlpha * CosBeta; + // RRefToLoc[1][2] = SinBeta; + // RRefToLoc[2][2] = CosAlpha * CosBeta; + + RRefToLoc[0] = {CosAlpha * CosGamma + SinAlpha * SinBeta * SinGamma, + CosAlpha * SinGamma - SinAlpha * SinBeta * CosGamma, + SinAlpha * CosBeta}; + + RRefToLoc[1] = {-CosBeta * SinGamma, CosBeta * CosGamma, SinBeta}; + + RRefToLoc[2] = {-SinAlpha * CosGamma + CosAlpha * SinBeta * SinGamma, + -SinAlpha * SinGamma - CosAlpha * SinBeta * CosGamma, + CosAlpha * CosBeta}; /*{Transpose the matrix to get the inverse transformation matrix for going back to reference system. This is used by the TransformToReference procedure.}*/ diff --git a/coretrace/simulation_runner/native_runner/determine_element_intersection_new.cpp b/coretrace/simulation_runner/native_runner/determine_element_intersection_new.cpp index a68874d5..695167a1 100644 --- a/coretrace/simulation_runner/native_runner/determine_element_intersection_new.cpp +++ b/coretrace/simulation_runner/native_runner/determine_element_intersection_new.cpp @@ -28,15 +28,9 @@ void DetermineElementIntersectionNew(TElement *Element, if (*ErrorFlag > 0 || *PathLength < 0) { *Intercept = 0; - PosRayOut[0] = 0.0; - PosRayOut[1] = 0.0; - PosRayOut[2] = 0.0; - CosRayOut[0] = 0.0; - CosRayOut[1] = 0.0; - CosRayOut[2] = 0.0; - DFXYZ[0] = 0.0; - DFXYZ[1] = 0.0; - DFXYZ[2] = 0.0; + PosRayOut = glm::dvec3{0.0}; + CosRayOut = glm::dvec3{0.0}; + DFXYZ = glm::dvec3{0.0}; *BacksideFlag = 0; *PathLength = 0.0; return; @@ -79,9 +73,10 @@ void DetermineElementIntersectionNew(TElement *Element, // if hit on backside of element then slope of surface is reversed if (*BacksideFlag) { - DFXYZ[0] = -DFXYZ[0]; - DFXYZ[1] = -DFXYZ[1]; - DFXYZ[2] = -DFXYZ[2]; + DFXYZ = -DFXYZ; + // DFXYZ[0] = -DFXYZ[0]; + // DFXYZ[1] = -DFXYZ[1]; + // DFXYZ[2] = -DFXYZ[2]; } return; diff --git a/coretrace/simulation_runner/native_runner/find_element_hit.cpp b/coretrace/simulation_runner/native_runner/find_element_hit.cpp index 212236d2..dc78898a 100644 --- a/coretrace/simulation_runner/native_runner/find_element_hit.cpp +++ b/coretrace/simulation_runner/native_runner/find_element_hit.cpp @@ -92,11 +92,12 @@ namespace SolTrace::NativeRunner // increment position by tiny amount to get off the element // if tracing to the same element - PosRayElement[0] = PosRayElement[0] + 1.0e-5 * CosRayElement[0]; - PosRayElement[1] = PosRayElement[1] + 1.0e-5 * CosRayElement[1]; - PosRayElement[2] = PosRayElement[2] + 1.0e-5 * CosRayElement[2]; + PosRayElement = PosRayElement + 1.0e-5 * CosRayElement; + // PosRayElement[0] = PosRayElement[0] + 1.0e-5 * CosRayElement[0]; + // PosRayElement[1] = PosRayElement[1] + 1.0e-5 * CosRayElement[1]; + // PosRayElement[2] = PosRayElement[2] + 1.0e-5 * CosRayElement[2]; - // {Determine if ray intersects element[j]; if so, Find intersection + // {Determine if ray intersects element[j]; if so, Find intersection // point with surface of element[j] } DetermineElementIntersectionNew(Element, PosRayElement, diff --git a/coretrace/simulation_runner/native_runner/generate_ray.cpp b/coretrace/simulation_runner/native_runner/generate_ray.cpp index 333b3809..664ce32a 100644 --- a/coretrace/simulation_runner/native_runner/generate_ray.cpp +++ b/coretrace/simulation_runner/native_runner/generate_ray.cpp @@ -48,11 +48,9 @@ void GenerateRay( if (Sun->PointSource) // fixed this on 3-18-13 { - PosRayGlobal[0] = Sun->Origin[0]; - PosRayGlobal[1] = Sun->Origin[1]; - PosRayGlobal[2] = Sun->Origin[2]; + PosRayGlobal = Sun->Origin; - if (myrng() <= 0.5) + if (myrng() <= 0.5) NegPosSign = -1; else NegPosSign = 1; @@ -73,14 +71,10 @@ void GenerateRay( CosRayGlobal[2] = NegPosSign * myrng(); // random direction for z part of ray vector - double CosRayGMag = sqrt(CosRayGlobal[0] * CosRayGlobal[0] + - CosRayGlobal[1] * CosRayGlobal[1] + - CosRayGlobal[2] * CosRayGlobal[2]); + double CosRayGMag = glm::length(CosRayGlobal); - CosRayGlobal[0] = CosRayGlobal[0] / CosRayGMag; // obtain unit vector by dividing by magnitude - CosRayGlobal[1] = CosRayGlobal[1] / CosRayGMag; - CosRayGlobal[2] = CosRayGlobal[2] / CosRayGMag; - } + CosRayGlobal /= CosRayGMag; + } else { // following changed on 09/26/05 to more efficiently generate rays relative to element center of mass in primary stage diff --git a/coretrace/simulation_runner/native_runner/native_runner_types.cpp b/coretrace/simulation_runner/native_runner/native_runner_types.cpp index 239d3292..f69e50df 100644 --- a/coretrace/simulation_runner/native_runner/native_runner_types.cpp +++ b/coretrace/simulation_runner/native_runner/native_runner_types.cpp @@ -128,16 +128,12 @@ namespace SolTrace::NativeRunner icalc(nullptr), Optics() { - int i, j; - for (i = 0; i < 3; i++) - { - // Origin[i] = AimPoint[i] = Euler[i] = PosSunCoords[i] = 0; - Origin[i] = AimPoint[i] = PosSunCoords[i] = 0; - // PosSunCoords[i] = 0; - } - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - RRefToLoc[i][j] = RLocToRef[i][j] = 0; + Origin = glm::dvec3{0.0}; + AimPoint = glm::dvec3{0.0}; + PosSunCoords = glm::dvec3{0.0}; + + RRefToLoc = {0.0}; + RLocToRef = {0.0}; // ZRot = 0; ZAperture = 0; @@ -161,12 +157,10 @@ namespace SolTrace::NativeRunner void TSun::Reset() { - int i, j; - for (i = 0; i < 3; i++) - Origin[i] = Euler[i] = 0; - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - RRefToLoc[i][j] = RLocToRef[i][j] = 0; + Origin = glm::dvec3{0.0}; + Euler = glm::dvec3{0.0}; + RRefToLoc = {0.0}; + RLocToRef = {0.0}; PointSource = false; // ShapeIndex = ' '; @@ -507,12 +501,12 @@ namespace SolTrace::NativeRunner tstage_ptr my_stage = std::make_shared(); // Use global coordinates as stage coordinates - my_stage->Origin = {}; - my_stage->AimPoint = {}; + my_stage->Origin = glm::dvec3{0.0}; + my_stage->AimPoint = glm::dvec3{0.0}; my_stage->AimPoint[2] = 1.0; my_stage->ZRot = 0.0; - my_stage->RRefToLoc = {}; - my_stage->RLocToRef = {}; + my_stage->RRefToLoc = glm::dmat3{0.0}; + my_stage->RLocToRef = glm::dmat3{0.0}; return my_stage; } diff --git a/coretrace/simulation_runner/native_runner/parabola_calculator.cpp b/coretrace/simulation_runner/native_runner/parabola_calculator.cpp index b1365411..7c6f4f0a 100644 --- a/coretrace/simulation_runner/native_runner/parabola_calculator.cpp +++ b/coretrace/simulation_runner/native_runner/parabola_calculator.cpp @@ -77,8 +77,8 @@ namespace SolTrace::NativeRunner // std::cout << "Computing parabola intersection" << std::endl; - double x0 = PosLoc[0], y0 = PosLoc[1], z0 = PosLoc[2]; - double mx = CosLoc[0], my = CosLoc[1], mz = CosLoc[2]; + double x0 = PosLoc.x, y0 = PosLoc.y, z0 = PosLoc.z; + double mx = CosLoc.x, my = CosLoc.y, mz = CosLoc.z; double cx = this->cx, cy = this->cy; double t1, t2; double a, b, c; @@ -103,15 +103,12 @@ namespace SolTrace::NativeRunner t1 = -c / b; p1 = PosLoc + t1 * CosLoc; - if (t1 > 0.0 && this->aper->is_in(p1[0], p1[1])) - { + if (t1 > 0.0 && this->aper->is_in(p1.x, p1.y)) { *PathLength = t1; // SetVec3(PosXYZ, x0 + t1 * mx, y0 + t1 * my, z0 + t1 * mz); // AddVec3(1.0, PosLoc, t1, CosLoc, PosXYZ); PosXYZ = p1; - } - else - { + } else { // Intersection is behind the ray -- same as // no solution. sts = 1; @@ -147,22 +144,17 @@ namespace SolTrace::NativeRunner // << "\nP2: " << p2 // << std::endl; - if (t1 > 0.0 && this->aper->is_in(p1[0], p1[1])) - { + if (t1 > 0.0 && this->aper->is_in(p1.x, p1.y)) { *PathLength = t1; // SetVec3(PosXYZ, x0 + t1 * mx, y0 + t1 * my, z0 + t1 * mz); // AddVec3(1.0, PosLoc, t1, CosLoc, PosXYZ); PosXYZ = p1; - } - else if (t2 > 0.0 && this->aper->is_in(p2[0], p2[1])) - { + } else if (t2 > 0.0 && this->aper->is_in(p2.x, p2.y)) { *PathLength = t2; // SetVec3(PosXYZ, x0 + t2 * mx, y0 + t2 * my, z0 + t2 * mz); // AddVec3(1.0, PosLoc, t2, CosLoc, PosXYZ); PosXYZ = p2; - } - else - { + } else { sts = 1; *PathLength = 0.0; } @@ -194,7 +186,7 @@ namespace SolTrace::NativeRunner // (which is used currently) or the outside? double cx = this->cx; double cy = this->cy; - DFXYZ = {-cx * PosXYZ[0], -cy * PosXYZ[1], 1.0}; + DFXYZ = {-cx * PosXYZ.x, -cy * PosXYZ.y, 1.0}; return; } diff --git a/google-tests/regression-tests/native_runner_validation_test.cpp b/google-tests/regression-tests/native_runner_validation_test.cpp index ee8ded90..ac77cb39 100644 --- a/google-tests/regression-tests/native_runner_validation_test.cpp +++ b/google-tests/regression-tests/native_runner_validation_test.cpp @@ -7,6 +7,9 @@ #include #include +#define GLM_ENABLE_EXPERIMENTAL 1 +#include + #include "split_csv.h" @@ -276,6 +279,64 @@ TEST(NativeRunner, ValidationTest1) // See previous comment about coordinates el->convert_vector_global_to_reference(dir_stage, cosines); +#if 0 + { + glm::dvec3 local; + el->convert_global_to_local(local, point); + el->convert_local_to_stage(pos_stage, local); + + glm::dvec3 dir_local; + el->convert_vector_global_to_local(dir_local, cosines); + el->convert_vector_local_to_stage(dir_stage, dir_local); + + { + glm::dvec3 pos_alt = el->get_reference_to_local() * point; + glm::dvec3 dir_alt = el->get_reference_to_local() * cosines; + glm::dvec3 pos_alt_t = glm::transpose(el->get_reference_to_local()) * point; + glm::dvec3 dir_alt_t = glm::transpose(el->get_reference_to_local()) * cosines; + + std::cout << "CSV Line: " << i + 1 << "\nRay Number: " << rayidx + 1 + << "\nElement: " << rr->get_element(iidx) << " CSV Element: " << element + << " Runner Element: " << run_element << "\nCSV Stage: " << stage + << " Runner Stage: " << run_stage << "\nCSV Pos: [" + << ground_raydata[0][i] << ", " << ground_raydata[1][i] << ", " + << ground_raydata[2][i] << "]" + << "\nCSV Dir: [" << ground_raydata[3][i] << ", " << ground_raydata[4][i] + << ", " << ground_raydata[5][i] << "]" + << "\nPos Stage (current): " << pos_stage + << "\nDir Stage (current): " << dir_stage + << "\nPos Alt (RRefToLoc * global): " << pos_alt + << "\nDir Alt (RRefToLoc * global): " << dir_alt + << "\nPos Alt T (RRefToLoc^T * global): " << pos_alt_t + << "\nDir Alt T (RRefToLoc^T * global): " << dir_alt_t + << "\nREF_T_L: " << el->get_reference_to_local() + << "\nGLO_T_L: " << el->get_global_to_local() << std::endl; + + std::cout << pos_stage << point << std::endl; + std::cout << el->get_reference_to_local() << std::endl; + std::cout << el->get_origin_ref() << std::endl; + std::cout << el->get_aim_vector_ref() << std::endl; + std::cout << el->get_zrot() << std::endl; + std::cout << "BLAH\n"; + std::cout << el->get_origin_global() << std::endl; + std::cout << el->get_aim_vector_global() << std::endl; + + std::cout << "OMG\n"; + std::cout << local << std::endl; + std::cout << dir_local << std::endl; + + if (el->get_reference_element()) { + std::cout << "REF\n"; + auto e = el->get_reference_element(); + + std::cout << e->get_origin_ref() << std::endl; + std::cout << e->get_aim_vector_ref() << std::endl; + std::cout << e->get_zrot() << std::endl; + } + } + } +#endif + EXPECT_NEAR(pos_stage[0], stod(ground_raydata[0][i]), TOL); EXPECT_NEAR(pos_stage[1], stod(ground_raydata[1][i]), TOL); EXPECT_NEAR(pos_stage[2], stod(ground_raydata[2][i]), TOL); diff --git a/google-tests/unit-tests/common/common.cpp b/google-tests/unit-tests/common/common.cpp index 77e82a25..d7302ff0 100644 --- a/google-tests/unit-tests/common/common.cpp +++ b/google-tests/unit-tests/common/common.cpp @@ -8,6 +8,9 @@ #include #include +#include +#include + bool is_identical(const glm::dvec3 &x, const glm::dvec3 &y) { return x == y; @@ -15,6 +18,11 @@ bool is_identical(const glm::dvec3 &x, const glm::dvec3 &y) bool is_identical(const glm::dvec3 &x, const glm::dvec3 &y, double tol) { + bool check = (fabs(x.x - y.x) <= tol && fabs(x.y - y.y) <= tol && fabs(x.z - y.z) <= tol); + + if (!check) { + std::cout << "Vectors not equal: A = " << x << ", B = " << y << std::endl; + } return ( fabs(x.x - y.x) <= tol && fabs(x.y - y.y) <= tol && @@ -23,7 +31,14 @@ bool is_identical(const glm::dvec3 &x, const glm::dvec3 &y, double tol) bool is_identical(const glm::dmat3 &A, const glm::dmat3 &B) { - return A == B; + double maxAbs = 0.0f; + for (int c = 0; c < 3; ++c) { + for (int r = 0; r < 3; ++r) { + maxAbs = std::max(maxAbs, std::abs(A[c][r] - B[c][r])); + } + } + + return maxAbs < 1E-300; } element_ptr make_configured_element() diff --git a/google-tests/unit-tests/simulation_data/element_test.cpp b/google-tests/unit-tests/simulation_data/element_test.cpp index f23a4596..1acbc645 100644 --- a/google-tests/unit-tests/simulation_data/element_test.cpp +++ b/google-tests/unit-tests/simulation_data/element_test.cpp @@ -6,6 +6,8 @@ #include "common.hpp" +#include + TEST(OpticalProperties, OutputOperator) { std::stringstream ss; @@ -368,7 +370,7 @@ TEST(Element, CoordinateComputationsIdentity) EXPECT_TRUE(is_identical(aim, el->get_aim_vector_global())); // Operators - glm::dmat3 Q = {}; + glm::dmat3 Q = glm::identity(); glm::dmat3 RtoL = el->get_reference_to_local(); EXPECT_TRUE(is_identical(RtoL, Q)); @@ -386,7 +388,6 @@ TEST(Element, CoordinateComputationsIdentity) TEST(Element, CoordinateComputationsRotations) { - using SolTrace::Data::MatrixTranspose; using SolTrace::Data::PI; // **** Setup Answers **** // @@ -404,7 +405,7 @@ TEST(Element, CoordinateComputationsRotations) Q1[0][2] = -0.5; Q1[1][2] = sqrt(3.0) / 6.0; Q1[2][2] = sqrt(6.0) / 3.0; - glm::dmat3 Q1t = glm::transpose(Q1); + //glm::dmat3 Q1t = glm::transpose(Q1); // Corresponding Euler angles in radians const double a1 = 0.0; const double b1 = asin(-1.0 / sqrt(3.0)); @@ -418,15 +419,15 @@ TEST(Element, CoordinateComputationsRotations) glm::dmat3 Q2; Q2[0][0] = (sqrt(8.0) + sqrt(6.0)) / 8.0; - Q2[0][1] = -0.75; - Q2[0][2] = (sqrt(6.0) - sqrt(8.0)) / 8.0; Q2[1][0] = (2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; - Q2[1][1] = sqrt(3.0) / 4.0; - Q2[1][2] = (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; Q2[2][0] = sqrt(6.0) / 4.0; + Q2[0][1] = -0.75; + Q2[1][1] = sqrt(3.0) / 4.0; Q2[2][1] = 0.5; + Q2[0][2] = (sqrt(6.0) - sqrt(8.0)) / 8.0; + Q2[1][2] = (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; Q2[2][2] = sqrt(6.0) / 4.0; - glm::dmat3 Q2t = glm::transpose(Q2); + //glm::dmat3 Q2t = glm::transpose(Q2); // Corresponding Euler angles in radians const double a2 = PI / 4.0; const double b2 = PI / 6.0; @@ -468,14 +469,14 @@ TEST(Element, CoordinateComputationsRotations) // Aim vector tests EXPECT_TRUE(is_identical(el->get_aim_vector_ref(), aim1, TOL)); EXPECT_TRUE(is_identical(el->get_aim_vector_stage(), el->get_aim_vector_ref(), TOL)); - result_vec = Q2t * aim1; + result_vec = Q2 * aim1; EXPECT_TRUE(is_identical(el->get_aim_vector_global(), result_vec, TOL)); glm::dvec3 v_local(-1.0, 2.0, 4.0); glm::dvec3 v_stage; glm::dvec3 v_global; - v_stage = Q1t * v_local; - v_global = Q2t * v_stage; + v_stage = Q1 * v_local; + v_global = Q2 * v_stage; glm::dvec3 result; @@ -597,7 +598,7 @@ TEST(Element, CoordinateComputations) Q1[1][2] = sqrt(3.0) / 6.0; Q1[2][2] = sqrt(6.0) / 3.0; // Local to stage matrix - glm::dmat3 Q1t = glm::transpose(Q1); + //glm::dmat3 Q1t = glm::transpose(Q1); // Corresponding Euler angles in radians const double a1 = 0.0; const double b1 = asin(-1.0 / sqrt(3.0)); @@ -615,16 +616,16 @@ TEST(Element, CoordinateComputations) // Global to stage matrix glm::dmat3 Q2; Q2[0][0] = (sqrt(8.0) + sqrt(6.0)) / 8.0; - Q2[0][1] = -0.75; - Q2[0][2] = (sqrt(6.0) - sqrt(8.0)) / 8.0; Q2[1][0] = (2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; - Q2[1][1] = sqrt(3.0) / 4.0; - Q2[1][2] = (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; Q2[2][0] = sqrt(6.0) / 4.0; + Q2[0][1] = -0.75; + Q2[1][1] = sqrt(3.0) / 4.0; Q2[2][1] = 0.5; + Q2[0][2] = (sqrt(6.0) - sqrt(8.0)) / 8.0; + Q2[1][2] = (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; Q2[2][2] = sqrt(6.0) / 4.0; // Stage to global matrix - glm::dmat3 Q2t = glm::transpose(Q2); + //glm::dmat3 Q2t = glm::transpose(Q2); ; // Corresponding Euler angles in radians const double a2 = PI / 4.0; @@ -654,9 +655,9 @@ TEST(Element, CoordinateComputations) EXPECT_TRUE(is_identical(el->get_origin_stage(), el->get_origin_ref())); EXPECT_TRUE(is_identical(el->get_origin_ref(), Origin1)); // vector_add(1.0, Origin1, 1.0, Origin2, result_vec); - result_vec = Q2t * Origin1; + result_vec = Q2 * Origin1; result_vec = Origin2 + result_vec; - EXPECT_TRUE(is_identical(el->get_origin_global(), result_vec)); + EXPECT_TRUE(is_identical(el->get_origin_global(), result_vec, TOL)); // Euler angles tests result_vec = el->get_euler_angles(); @@ -671,17 +672,17 @@ TEST(Element, CoordinateComputations) // Aim vector tests EXPECT_TRUE(is_identical(el->get_aim_vector_ref(), aim1, TOL)); EXPECT_TRUE(is_identical(el->get_aim_vector_stage(), el->get_aim_vector_ref(), TOL)); - result_vec = Q2t * aim1; + result_vec = Q2 * aim1; result_vec = Origin2 + result_vec; EXPECT_TRUE(is_identical(el->get_aim_vector_global(), result_vec, TOL)); glm::dvec3 v_local(-1.0, 2.0, 4.0); glm::dvec3 v_stage; glm::dvec3 v_global; - v_stage = Q1t * v_local; + v_stage = Q1 * v_local; v_stage = Origin1 + v_stage; - v_global = Q2t * v_stage; - v_global = Origin2 * v_global; + v_global = Q2 * v_stage; + v_global = Origin2 + v_global; glm::dvec3 result; @@ -744,7 +745,7 @@ TEST(Element, VectorCoordinateComputations) Q1[1][2] = sqrt(3.0) / 6.0; Q1[2][2] = sqrt(6.0) / 3.0; // Local to stage matrix - glm::dmat3 Q1t = glm::transpose(Q1); + //glm::dmat3 Q1t = glm::transpose(Q1); // Corresponding Euler angles in radians const double a1 = 0.0; const double b1 = asin(-1.0 / sqrt(3.0)); @@ -762,23 +763,23 @@ TEST(Element, VectorCoordinateComputations) // Global to stage matrix glm::dmat3 Q2; Q2[0][0] = (sqrt(8.0) + sqrt(6.0)) / 8.0; - Q2[0][1] = -0.75; - Q2[0][2] = (sqrt(6.0) - sqrt(8.0)) / 8.0; Q2[1][0] = (2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; - Q2[1][1] = sqrt(3.0) / 4.0; - Q2[1][2] = (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; Q2[2][0] = sqrt(6.0) / 4.0; + Q2[0][1] = -0.75; + Q2[1][1] = sqrt(3.0) / 4.0; Q2[2][1] = 0.5; + Q2[0][2] = (sqrt(6.0) - sqrt(8.0)) / 8.0; + Q2[1][2] = (-2.0 * sqrt(6.0) - sqrt(2.0)) / 8.0; Q2[2][2] = sqrt(6.0) / 4.0; // Stage to global matrix - glm::dmat3 Q2t = glm::transpose(Q2); + //glm::dmat3 Q2t = glm::transpose(Q2); // Corresponding Euler angles in radians const double a2 = PI / 4.0; const double b2 = PI / 6.0; const double g2 = PI / 3.0; // Corresponding aim vector (local z-axis in reference coordinates) glm::dvec3 aim2(sqrt(3.0 / 8.0), 0.5, sqrt(3.0 / 8.0)); - aim2 = Origin2 * aim2; + aim2 = Origin2 + aim2; // Z-Rotation is the last of the Euler angles but in degrees const double zrot2 = 60.0; @@ -810,8 +811,8 @@ TEST(Element, VectorCoordinateComputations) glm::dvec3 v_local(-1.0, 2.0, 4.0); glm::dvec3 v_stage; glm::dvec3 v_global; - v_stage = Q1t * v_local; - v_global = Q2t * v_stage; + v_stage = Q1 * v_local; + v_global = Q2 * v_stage; glm::dvec3 result; diff --git a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp index 6ba6d708..9a6efd55 100644 --- a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp +++ b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp @@ -123,8 +123,8 @@ TEST(LinearAlgebra, MatrixVectorProduct) y = A * x; EXPECT_TRUE(is_identical(x, y)); - A[0][1] = 2.0; - A[1][2] = 3.0; + A[1][0] = 2.0; + A[2][1] = 3.0; y = A * x; EXPECT_NEAR(y[0], 2.5, 1e-12); EXPECT_NEAR(y[1], -5.0, 1e-12); @@ -134,26 +134,26 @@ TEST(LinearAlgebra, MatrixVectorProduct) TEST(LinearAlgebra, MatrixMatrixProduct) { glm::dmat3 A; - A[0][1] = 1.0; - A[0][2] = 2.0; - A[1][0] = -1.0; - A[1][1] = 1.0; + A[1][0] = 1.0; A[2][0] = 2.0; + A[0][1] = -1.0; + A[1][1] = 1.0; + A[0][2] = 2.0; A[2][2] = 1.0; glm::dmat3 B; B[0][0] = -1.0; - B[0][1] = 1.0; + B[1][0] = 1.0; B[1][1] = 1.0; - B[1][2] = -2.0; + B[2][1] = -2.0; B[2][2] = 1.0; glm::dmat3 Ctrue; - Ctrue[0][1] = 1.0; Ctrue[1][0] = 1.0; - Ctrue[1][2] = -2.0; - Ctrue[2][0] = -2.0; - Ctrue[2][1] = 2.0; + Ctrue[0][1] = 1.0; + Ctrue[2][1] = -2.0; + Ctrue[0][2] = -2.0; + Ctrue[1][2] = 2.0; Ctrue[2][2] = 1.0; glm::dmat3 C{0.0}; @@ -180,67 +180,75 @@ TEST(LinearAlgebra, dvec3OutputOperator) std::ostringstream oss1; oss1 << v1; - EXPECT_EQ(oss1.str(), "[1, 2, 3]"); + EXPECT_EQ(oss1.str(), "[ 1.000, 2.000, 3.000]"); std::ostringstream oss2; oss2 << v2; - EXPECT_EQ(oss2.str(), "[-0.5, 0, 10.5]"); + EXPECT_EQ(oss2.str(), "[ -0.500, 0.000, 10.500]"); std::ostringstream oss3; oss3 << v3; - EXPECT_EQ(oss3.str(), "[0, 0, 0]"); + EXPECT_EQ(oss3.str(), "[ 0.000, 0.000, 0.000]"); // Test with different precision glm::dvec3 v4(1.23456789, -2.34567891, 3.45678912); std::ostringstream oss4; oss4 << std::fixed << std::setprecision(3) << v4; - EXPECT_EQ(oss4.str(), "[1.235, -2.346, 3.457]"); + EXPECT_EQ(oss4.str(), "[ 1.235, -2.346, 3.457]"); } TEST(LinearAlgebra, dmat3OutputOperator) { - glm::dmat3 A(1.0); + glm::dmat3 A; A[0][0] = 1.0; - A[0][1] = 2.0; - A[0][2] = 3.0; - A[1][0] = 4.0; + A[1][0] = 2.0; + A[2][0] = 3.0; + A[0][1] = 4.0; A[1][1] = 5.0; - A[1][2] = 6.0; - A[2][0] = 7.0; - A[2][1] = 8.0; + A[2][1] = 6.0; + A[0][2] = 7.0; + A[1][2] = 8.0; A[2][2] = 9.0; std::ostringstream oss; oss << A; - EXPECT_EQ(oss.str(), "[1, 2, 3; 4, 5, 6; 7, 8, 9]"); + EXPECT_EQ(oss.str(), + "\n[[ 1.000, 2.000, 3.000]\n [ 4.000, 5.000, 6.000]\n [ 7.000, " + " 8.000, 9.000]]"); // Test identity matrix - glm::dmat3 I; + glm::dmat3 I = glm::identity(); std::ostringstream oss_identity; oss_identity << I; - EXPECT_EQ(oss_identity.str(), "[1, 0, 0; 0, 1, 0; 0, 0, 1]"); + EXPECT_EQ(oss_identity.str(), + "\n[[ 1.000, 0.000, 0.000]\n [ 0.000, 1.000, 0.000]\n [ 0.000, " + " 0.000, 1.000]]"); // Test zero matrix glm::dmat3 Z(0.0); std::ostringstream oss_zero; oss_zero << Z; - EXPECT_EQ(oss_zero.str(), "[0, 0, 0; 0, 0, 0; 0, 0, 0]"); + EXPECT_EQ(oss_zero.str(), + "\n[[ 0.000, 0.000, 0.000]\n [ 0.000, 0.000, 0.000]\n [ 0.000, " + " 0.000, 0.000]]"); // Test with negative values and different precision glm::dmat3 B; B[0][0] = -1.5; - B[0][1] = 2.25; - B[0][2] = -3.75; - B[1][0] = 0.0; + B[1][0] = 2.25; + B[2][0] = -3.75; + B[0][1] = 0.0; B[1][1] = -0.5; - B[1][2] = 1.0; - B[2][0] = 10.0; - B[2][1] = -20.0; + B[2][1] = 1.0; + B[0][2] = 10.0; + B[1][2] = -20.0; B[2][2] = 30.0; std::ostringstream oss_negative; oss_negative << std::fixed << std::setprecision(2) << B; - EXPECT_EQ(oss_negative.str(), "[-1.50, 2.25, -3.75; 0.00, -0.50, 1.00; 10.00, -20.00, 30.00]"); + EXPECT_EQ(oss_negative.str(), + "\n[[ -1.500, 2.250, -3.750]\n [ 0.000, -0.500, 1.000]\n [ 10.000, " + "-20.000, 30.000]]"); } TEST(LinearAlgebra, dmat3GetValue) @@ -258,35 +266,35 @@ TEST(LinearAlgebra, dmat3GetValue) // Set specific values and test retrieval A[0][0] = 1.5; - A[0][1] = -2.5; - A[0][2] = 3.7; - A[1][0] = -4.2; + A[1][0] = -2.5; + A[2][0] = 3.7; + A[0][1] = -4.2; A[1][1] = 5.8; - A[1][2] = -6.1; - A[2][0] = 7.9; - A[2][1] = -8.4; + A[2][1] = -6.1; + A[0][2] = 7.9; + A[1][2] = -8.4; A[2][2] = 9.6; EXPECT_DOUBLE_EQ(A[0][0], 1.5); - EXPECT_DOUBLE_EQ(A[0][1], -2.5); - EXPECT_DOUBLE_EQ(A[0][2], 3.7); - EXPECT_DOUBLE_EQ(A[1][0], -4.2); + EXPECT_DOUBLE_EQ(A[1][0], -2.5); + EXPECT_DOUBLE_EQ(A[2][0], 3.7); + EXPECT_DOUBLE_EQ(A[0][1], -4.2); EXPECT_DOUBLE_EQ(A[1][1], 5.8); - EXPECT_DOUBLE_EQ(A[1][2], -6.1); - EXPECT_DOUBLE_EQ(A[2][0], 7.9); - EXPECT_DOUBLE_EQ(A[2][1], -8.4); + EXPECT_DOUBLE_EQ(A[2][1], -6.1); + EXPECT_DOUBLE_EQ(A[0][2], 7.9); + EXPECT_DOUBLE_EQ(A[1][2], -8.4); EXPECT_DOUBLE_EQ(A[2][2], 9.6); // Test identity matrix - glm::dmat3 I; + glm::dmat3 I = glm::identity(); EXPECT_DOUBLE_EQ(I[0][0], 1.0); - EXPECT_DOUBLE_EQ(I[0][1], 0.0); - EXPECT_DOUBLE_EQ(I[0][2], 0.0); EXPECT_DOUBLE_EQ(I[1][0], 0.0); - EXPECT_DOUBLE_EQ(I[1][1], 1.0); - EXPECT_DOUBLE_EQ(I[1][2], 0.0); EXPECT_DOUBLE_EQ(I[2][0], 0.0); + EXPECT_DOUBLE_EQ(I[0][1], 0.0); + EXPECT_DOUBLE_EQ(I[1][1], 1.0); EXPECT_DOUBLE_EQ(I[2][1], 0.0); + EXPECT_DOUBLE_EQ(I[0][2], 0.0); + EXPECT_DOUBLE_EQ(I[1][2], 0.0); EXPECT_DOUBLE_EQ(I[2][2], 1.0); // Test very small and very large values From c49c5664e60e14c9dc787c4a6725d65356c2d367 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Fri, 23 Jan 2026 15:00:34 -0700 Subject: [PATCH 03/23] Clean up from merge --- .../cst_templates/heliostat.cpp | 27 +++---- .../native_runner_performance_test.cpp | 24 +++--- .../cst-templates/heliostat_field_test.cpp | 74 +++++++++---------- .../cst-templates/heliostat_test.cpp | 19 +++-- .../cst-templates/single_heliostat_test.cpp | 60 +++++++-------- 5 files changed, 94 insertions(+), 110 deletions(-) diff --git a/coretrace/simulation_data/cst_templates/heliostat.cpp b/coretrace/simulation_data/cst_templates/heliostat.cpp index 28b0057c..c3578338 100644 --- a/coretrace/simulation_data/cst_templates/heliostat.cpp +++ b/coretrace/simulation_data/cst_templates/heliostat.cpp @@ -73,14 +73,11 @@ namespace SolTrace::Data sun_position_vector_degrees(sun_vec, this->offaxis_canting_sun_position_azimuth, 90.0 - this->offaxis_canting_sun_position_zenith); - glm::dvec3 target_dir; - vector_add(1.0, this->target_pos, // TODO: is target pos set? - -1.0, this->get_origin_global(), - target_dir); - target_dir.make_unit(); - glm::dvec3 aim_vector; - vector_add(1.0, target_dir, 1.0, sun_vec, aim_vector); - aim_vector.make_unit(); + glm::dvec3 target_dir = + this->target_pos - this->get_origin_global(); // TODO: is target pos set? + normalize_inplace(target_dir); + glm::dvec3 aim_vector = glm::normalize(target_dir + sun_vec); + // Calculate the tracking azimuth and elevation from the aim vector tracking_azimuth = atan2(aim_vector[0], aim_vector[1]); @@ -151,7 +148,7 @@ namespace SolTrace::Data // Scale aim to target and translate to panel position scratch = this->target_pos - panel_pos; double scale = 2.0 * glm::length(scratch); - aim = scale * panel_norm + origin,; + aim = scale * panel_norm + origin; } else if (this->canting_method == UNSET) { @@ -252,26 +249,22 @@ namespace SolTrace::Data 1000.0 *this->aim; // Project into xy-plane -<<<<<<< HEAD aim_vector[2] = 0.0; double theta = acos(aim_vector[0] / glm::length(aim_vector)); this->set_zrot_radians(theta); -======= double aim_azimuth = atan2(aim_vector[0], aim_vector[1]); ->>>>>>> origin/develop // Elevation axis - Vector3d elevation_axis = { 1.0, 0.0, 0.0 }; - Vector3d rotated_elevation_axis; + glm::dvec3 elevation_axis = { 1.0, 0.0, 0.0 }; + glm::dvec3 rotated_elevation_axis; rotate_vector_radians( { 0.0, 0.0, 1.0 }, elevation_axis, -aim_azimuth, rotated_elevation_axis); - Vector3d helio_y_axis; - cross_product(aim_vector, rotated_elevation_axis, helio_y_axis); - helio_y_axis.make_unit(); + glm::dvec3 helio_y_axis = glm::normalize( + glm::cross(aim_vector, rotated_elevation_axis)); double gamma = 0.0; if (aim_vector[1] != 1.0 && aim_vector[1] != -1.0) diff --git a/google-tests/regression-tests/native_runner_performance_test.cpp b/google-tests/regression-tests/native_runner_performance_test.cpp index 01189d78..6d5e5e1e 100644 --- a/google-tests/regression-tests/native_runner_performance_test.cpp +++ b/google-tests/regression-tests/native_runner_performance_test.cpp @@ -25,8 +25,8 @@ using SolTrace::NativeRunner::TSystem; TEST(NativeRunner, PerformanceTest) { const uint_fast64_t NRAYS = 100000; - const Vector3d zero(0.0, 0.0, 0.0); - const Vector3d khat(0.0, 0.0, 1.0); + const glm::dvec3 zero(0.0, 0.0, 0.0); + const glm::dvec3 khat(0.0, 0.0, 1.0); const uint_fast64_t NX = 4; const uint_fast64_t NY = 2; @@ -63,13 +63,13 @@ TEST(NativeRunner, PerformanceTest) stage_ptr st2 = make_stage(2); st2->set_reference_frame_geometry(zero, khat, 0.0); - Vector3d sun_pos(0.0, 0.0, 10000.0); - Vector3d abs_origin(0.0, 0.0, 10.0); - Vector3d hs_origin; - Vector3d v1; - Vector3d v2; - Vector3d aim; - Vector3d aim_point; + glm::dvec3 sun_pos(0.0, 0.0, 10000.0); + glm::dvec3 abs_origin(0.0, 0.0, 10.0); + glm::dvec3 hs_origin; + glm::dvec3 v1; + glm::dvec3 v2; + glm::dvec3 aim; + glm::dvec3 aim_point; // double xpos = -1.0 * LX; // double ypos = -1.0 * LY; @@ -81,7 +81,7 @@ TEST(NativeRunner, PerformanceTest) for (auto jy = 0; jy < NHY; ++jy) { ypos = dy * jy - LY; - hs_origin.set_values(xpos, ypos, 0.0); + hs_origin = {xpos, ypos, 0.0}; // vector_add(1.0, sun_pos, -1.0, hs_origin, v1); // vector_add(1.0, abs_origin, -1.0, hs_origin, v2); @@ -126,7 +126,7 @@ TEST(NativeRunner, PerformanceTest) // absorb->set_surface(make_surface()); aim_point = abs_origin; - aim_point[2] += vector_norm(aim_point); + aim_point[2] += glm::length(aim_point); absorb->set_reference_frame_geometry(abs_origin, aim_point, 0.0); absorb->set_name("Absorber"); absorb->enable(); @@ -253,7 +253,7 @@ TEST(NativeRunner, PerformanceTest) // // const TRayData *ray_data = &(sys->AllRayData); // // size_t nrdata = ray_data->Count(); -// // Vector3d point, cosines; +// // glm::dvec3 point, cosines; // // int element; // // int stage; // // unsigned int raynum; diff --git a/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp index ff5a284d..002a645e 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp @@ -37,11 +37,11 @@ class HeliostatFieldSimulation : public ::testing::Test { bool save_results = false; // Saves flux map results to CSV files bool save_raydata = false; // Saves ray data to CSV file - const Vector3d zero = { 0.0, 0.0, 0.0 }; // Global origin - const Vector3d khat = { 0.0, 0.0, 1.0 }; // Global z-axis + const glm::dvec3 zero = {0.0, 0.0, 0.0}; // Global origin + const glm::dvec3 khat = {0.0, 0.0, 1.0}; // Global z-axis // Receiver parameters - Vector3d rec_origin = { 0.0, 0.0, 180.33 }; // This is the receiver center + glm::dvec3 rec_origin = {0.0, 0.0, 180.33}; // This is the receiver center double rec_radius = 15.45 / 2.0; double rec_height = 18.59; double rec_heat_shield_height = 3.2331; @@ -123,12 +123,10 @@ class HeliostatFieldSimulation : public ::testing::Test { receiver->get_back_optical_properties()->set_ideal_reflection(); receiver->set_aperture(SolTrace::Data::make_aperture(rec_radius * 2.0, rec_height)); receiver->set_surface(SolTrace::Data::make_surface(rec_radius)); - Vector3d offset = { 0.0, rec_radius, 0.0 }; // Cylinder origin is on the edge - Vector3d rec_origin_offset; - vector_add(1.0, rec_origin, 1.0, offset, rec_origin_offset); - Vector3d v1 = { 0.0, -1.0, 0.0 }; - Vector3d aim_point; - vector_add(1.0, rec_origin_offset, 1.0, v1, aim_point); + glm::dvec3 offset = {0.0, rec_radius, 0.0}; // Cylinder origin is on the edge + glm::dvec3 rec_origin_offset = rec_origin + offset; + glm::dvec3 v1 = {0.0, -1.0, 0.0}; + glm::dvec3 aim_point = rec_origin_offset + v1; receiver->set_reference_frame_geometry(rec_origin_offset, aim_point, 180.0); receiver->set_name("Receiver"); receiver->enable(); @@ -139,8 +137,8 @@ class HeliostatFieldSimulation : public ::testing::Test { top_heat_shield->set_aperture(SolTrace::Data::make_aperture(rec_radius * 2.0, rec_heat_shield_height)); top_heat_shield->set_surface(SolTrace::Data::make_surface(rec_radius)); offset = { 0.0, rec_radius, (rec_height + rec_heat_shield_height)/2.}; // Cylinder origin is on the edge - vector_add(1.0, rec_origin, 1.0, offset, rec_origin_offset); - vector_add(1.0, rec_origin_offset, 1.0, v1, aim_point); + rec_origin_offset = rec_origin + offset; + aim_point = rec_origin_offset + v1; top_heat_shield->set_reference_frame_geometry(rec_origin_offset, aim_point, 0.0); top_heat_shield->set_name("Top Heat Shield"); top_heat_shield->enable(); @@ -151,8 +149,8 @@ class HeliostatFieldSimulation : public ::testing::Test { bottom_heat_shield->set_aperture(SolTrace::Data::make_aperture(rec_radius * 2.0, rec_heat_shield_height)); bottom_heat_shield->set_surface(SolTrace::Data::make_surface(rec_radius)); offset = { 0.0, rec_radius, -(rec_height + rec_heat_shield_height) / 2. }; // Cylinder origin is on the edge - vector_add(1.0, rec_origin, 1.0, offset, rec_origin_offset); - vector_add(1.0, rec_origin_offset, 1.0, v1, aim_point); + rec_origin_offset = rec_origin + offset; + aim_point = rec_origin_offset + v1; bottom_heat_shield->set_reference_frame_geometry(rec_origin_offset, aim_point, 0.0); bottom_heat_shield->set_name("Bottom Heat Shield"); bottom_heat_shield->enable(); @@ -210,7 +208,7 @@ class HeliostatFieldSimulation : public ::testing::Test { // Generate heliostat field heliostat_field.clear(); for (size_t i = 0; i < x_coords.size(); i++) { - Vector3d heliostat_origin(x_coords[i], y_coords[i], 4.49); + glm::dvec3 heliostat_origin(x_coords[i], y_coords[i], 4.49); auto heliostat = SolTrace::Data::make_element(); heliostat->set_optics(mirror, mirror_back); heliostat->set_reference_frame_geometry(heliostat_origin, khat, 0.0); @@ -220,14 +218,13 @@ class HeliostatFieldSimulation : public ::testing::Test { heliostat->set_canting(Heliostat::NONE, 0.0, 0.0); // Set aim point on the receiver surface double distance = sqrt(pow(x_coords[i], 2) + pow(y_coords[i], 2)); - Vector3d aim_point = { rec_radius * (x_coords[i] / distance), - rec_radius * (y_coords[i] / distance), - rec_origin[2]}; + glm::dvec3 aim_point = {rec_radius * (x_coords[i] / distance), + rec_radius * (y_coords[i] / distance), + rec_origin[2]}; heliostat->set_target_position(aim_point); // At-slant focal length - to center of receiver - Vector3d slant; - vector_add(-1.0, rec_origin, 1.0, heliostat_origin, slant); //aim_point - double focal_length = vector_norm(slant); + glm::dvec3 slant = -rec_origin + heliostat_origin; //aim_point + double focal_length = glm::length(slant); heliostat->set_focal_length(focal_length); heliostat->create_geometry(); @@ -240,11 +237,11 @@ class HeliostatFieldSimulation : public ::testing::Test { void set_scatter_aimpoints() { int helio_idx = 0; for (const auto& heliostat : heliostat_field) { - Vector3d heliostat_origin = heliostat->get_origin_global(); + glm::dvec3 heliostat_origin = heliostat->get_origin_global(); double distance = sqrt(pow(heliostat_origin[0], 2) + pow(heliostat_origin[1], 2)); - Vector3d aim_point = { rec_radius * (heliostat_origin[0] / distance), - rec_radius * (heliostat_origin[1] / distance), - rec_origin[2] + scatter_aim_elevation[helio_idx] }; + glm::dvec3 aim_point = {rec_radius * (heliostat_origin[0] / distance), + rec_radius * (heliostat_origin[1] / distance), + rec_origin[2] + scatter_aim_elevation[helio_idx]}; heliostat->set_target_position(aim_point); heliostat->create_geometry(); helio_idx++; @@ -253,7 +250,7 @@ class HeliostatFieldSimulation : public ::testing::Test { void assign_focal_lengths_banded() { for (const auto& heliostat : heliostat_field) { - Vector3d heliostat_origin = heliostat->get_origin_global(); + glm::dvec3 heliostat_origin = heliostat->get_origin_global(); double distance = sqrt(pow(heliostat_origin[0], 2) + pow(heliostat_origin[1], 2)); double focal_length = 0.0; if (distance <= 502.5) @@ -275,7 +272,7 @@ class HeliostatFieldSimulation : public ::testing::Test { void assign_focal_lengths_canting_banded() { // NOTE: This was created for task 1b where the focal lengths were set to the canting distances. for (const auto& heliostat : heliostat_field) { - Vector3d heliostat_origin = heliostat->get_origin_global(); + glm::dvec3 heliostat_origin = heliostat->get_origin_global(); double distance = sqrt(pow(heliostat_origin[0], 2) + pow(heliostat_origin[1], 2)); double focal_length = 0.0; if (distance <= 502.0) @@ -296,9 +293,8 @@ class HeliostatFieldSimulation : public ::testing::Test { void assign_canted_slant(bool flat_facets) { for (const auto& heliostat : heliostat_field) { - Vector3d slant; - vector_add(-1.0, rec_origin, 1.0, heliostat->get_origin_global(), slant); - double slant_distance = vector_norm(slant); + glm::dvec3 slant = -rec_origin + heliostat->get_origin_global(); + double slant_distance = glm::length(slant); heliostat->set_number_panels(6, 5); heliostat->set_gaps(0.02, 0.02); heliostat->set_canting(Heliostat::CantingType::ON_AXIS, slant_distance, 0.0); @@ -312,7 +308,7 @@ class HeliostatFieldSimulation : public ::testing::Test { void assign_canted_banded(bool flat_facets) { // Modify heliostat canting to bands - to center of receiver for (const auto& heliostat : heliostat_field) { - Vector3d heliostat_origin = heliostat->get_origin_global(); + glm::dvec3 heliostat_origin = heliostat->get_origin_global(); double distance = sqrt(pow(heliostat_origin[0], 2) + pow(heliostat_origin[1], 2)); double cant_distance = 0.0; if (distance <= 502.0) @@ -336,7 +332,7 @@ class HeliostatFieldSimulation : public ::testing::Test { void setup_simData() { // Set up sun - Vector3d sun_pos = { 0.0, 0.0, 1000.0 }; + glm::dvec3 sun_pos = {0.0, 0.0, 1000.0}; sun = SolTrace::Data::make_ray_source(); sun->set_position(sun_pos); sun->set_shape(SolTrace::Data::SunShape::PILLBOX, 0.0, 4.65, 0.0); @@ -365,8 +361,8 @@ class HeliostatFieldSimulation : public ::testing::Test { void update_simulation_geometry(double azimuth, double elevation) { // Set sun position - Vector3d sun_pos; - sun_position_vector_degrees(sun_pos, azimuth, elevation); + glm::dvec3 sun_pos; + SolTrace::Data::sun_position_vector_degrees(sun_pos, azimuth, elevation); sun->set_position(sun_pos); // Update heliostat positions for (const auto& heliostat : heliostat_field) { @@ -586,14 +582,14 @@ class HeliostatFieldSimulation : public ::testing::Test { double minx, maxx, miny, maxy; minx = maxx = miny = maxy = 0.0; - Vector3d rec_origin = receiver->get_origin_global(); + glm::dvec3 rec_origin = receiver->get_origin_global(); // Autoscale if (true) { minx = miny = 1e199; maxx = maxy = -1e199; - Vector3d local_position; - Vector3d global_position; + glm::dvec3 local_position; + glm::dvec3 global_position; // automatically size the min/max x and y for (size_t i = 0; i < result.get_number_of_records(); i++) { @@ -648,8 +644,8 @@ class HeliostatFieldSimulation : public ::testing::Test { fluxGrid.fill(0.0); for (size_t i = 0; i < result.get_number_of_records(); i++) { - Vector3d local_position; - Vector3d global_position; + glm::dvec3 local_position; + glm::dvec3 global_position; const ray_record_ptr rr = result[i]; for (size_t j = 0; j < rr->interactions.size(); j++) { @@ -995,4 +991,4 @@ TEST_F(HeliostatFieldSimulation, multiFacet_BandFocused_BandCanted) set_scatter_aimpoints(); simulate_check_outputs("3b", "2", "8"); simulate_check_outputs("3b", "2", "12"); -} \ No newline at end of file +} diff --git a/google-tests/unit-tests/simulation_data/cst-templates/heliostat_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/heliostat_test.cpp index 1e8f2ce1..77127332 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/heliostat_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/heliostat_test.cpp @@ -333,8 +333,8 @@ TEST(Heliostat, TraceOffAxisCanting) { constexpr uint_fast64_t NRAYS = 10000; constexpr uint_fast64_t N_ABSORBED_THRESH = NRAYS / 10; - const Vector3d zero(0.0, 0.0, 0.0); - const Vector3d khat(0.0, 0.0, 1.0); + const glm::dvec3 zero(0.0); + const glm::dvec3 khat(0.0, 0.0, 1.0); SimulationData my_sim; // Set parameters @@ -357,8 +357,8 @@ TEST(Heliostat, TraceOffAxisCanting) stage_ptr st2 = SolTrace::Data::make_stage(2); st2->set_reference_frame_geometry(zero, khat, 0.0); - Vector3d hs_origin(50.0, 50.0, 5.0); - Vector3d abs_origin(0.0, 0.0, 5.0); + glm::dvec3 hs_origin(50.0, 50.0, 5.0); + glm::dvec3 abs_origin(0.0, 0.0, 5.0); double canting_azimuth = 135.0; double canting_zenith = 90.0; @@ -384,9 +384,8 @@ TEST(Heliostat, TraceOffAxisCanting) absorb->get_back_optical_properties()->set_ideal_absorption(); absorb->set_aperture(SolTrace::Data::make_aperture(10.0, 10.0)); // TODO: Set a tight aperture (2.35, 1.55) absorb->set_surface(SolTrace::Data::make_surface()); - Vector3d v1 = { 0.0, 1.0, 0.0 }; - Vector3d aim_point; - vector_add(1.0, abs_origin, 1.0, v1, aim_point); + glm::dvec3 v1 = {0.0, 1.0, 0.0}; + glm::dvec3 aim_point = abs_origin + v1; absorb->set_reference_frame_geometry(abs_origin, aim_point, 0.0); absorb->set_name("Absorber"); absorb->enable(); @@ -396,8 +395,8 @@ TEST(Heliostat, TraceOffAxisCanting) my_sim.add_stage(st1); my_sim.add_stage(st2); - Vector3d sun_pos; - sun_position_vector_degrees(sun_pos, canting_azimuth, 90.0 - canting_zenith); + glm::dvec3 sun_pos; + SolTrace::Data::sun_position_vector_degrees(sun_pos, canting_azimuth, 90.0 - canting_zenith); auto sun = SolTrace::Data::make_ray_source(); sun->set_position(sun_pos); sun->set_shape(SolTrace::Data::SunShape::PILLBOX, 0.0, 4.65, 0.0); @@ -647,4 +646,4 @@ TEST(Heliostat, UpdateGeometry) EXPECT_TRUE(n >= NRAYS); EXPECT_TRUE(num_absorbed > N_ABSORBED_THRESH); -} \ No newline at end of file +} diff --git a/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp index ea1abaaf..aeea59d5 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp @@ -33,8 +33,8 @@ class SingleHeliostatSimulation : public ::testing::Test { bool print_info = false; // Prints information on from simulation results (sun calculations, ray counts, flux calculations) bool save_results = false; // Saves flux map results to CSV files - const Vector3d zero = { 0.0, 0.0, 0.0 }; // Global origin - const Vector3d khat = { 0.0, 0.0, 1.0 }; // Global z-axis + const glm::dvec3 zero = {0.0, 0.0, 0.0}; // Global origin + const glm::dvec3 khat = {0.0, 0.0, 1.0}; // Global z-axis double solar_azimuth = 180.0; double solar_elevation = 59.96377; @@ -107,8 +107,8 @@ class SingleHeliostatSimulation : public ::testing::Test { mirror_back.set_ideal_absorption(); // Initial setup of heliostat - Vector3d heliostat_origin(0.0, 500.0, 5.65); - Vector3d rec_origin(0.0, 0.0, 169.0); + glm::dvec3 heliostat_origin(0.0, 500.0, 5.65); + glm::dvec3 rec_origin(0.0, 0.0, 169.0); heliostat = SolTrace::Data::make_element(); heliostat->set_optics(mirror, mirror_back); heliostat->set_reference_frame_geometry(heliostat_origin, khat, 0.0); @@ -128,9 +128,8 @@ class SingleHeliostatSimulation : public ::testing::Test { receiver->get_back_optical_properties()->set_ideal_reflection(); receiver->set_aperture(SolTrace::Data::make_aperture(12.0, 18.0)); receiver->set_surface(SolTrace::Data::make_surface()); - Vector3d v1 = { 0.0, 1.0, 0.0 }; // Pointing North TODO: change to point towards heliostat - Vector3d aim_point; - vector_add(1.0, rec_origin, 1.0, v1, aim_point); + glm::dvec3 v1 = {0.0, 1.0, 0.0}; // Pointing North TODO: change to point towards heliostat + glm::dvec3 aim_point = rec_origin + v1; receiver->set_reference_frame_geometry(rec_origin, aim_point, 0.0); receiver->set_name("Receiver"); receiver->enable(); @@ -144,7 +143,7 @@ class SingleHeliostatSimulation : public ::testing::Test { void setup_simData() { // Set up sun - Vector3d sun_pos = { 0.0, 0.0, 1000.0 }; + glm::dvec3 sun_pos = {0.0, 0.0, 1000.0}; sun = SolTrace::Data::make_ray_source(); sun->set_position(sun_pos); sun->set_shape(SolTrace::Data::SunShape::PILLBOX, 0.0, 4.65, 0.0); @@ -167,22 +166,20 @@ class SingleHeliostatSimulation : public ::testing::Test { void set_heliostat_to_southeast() { // Update heliostat position to southeast of tower - Vector3d helio_origin(200.0, -200.0, 5.65); // Southeast of tower + glm::dvec3 helio_origin(200.0, -200.0, 5.65); // Southeast of tower heliostat->set_reference_frame_geometry(helio_origin, khat, 0.0); // Point receiver to heliostat without tilting down helio_origin[2] = 0.0; // Project to ground plane - Vector3d rec_origin = receiver->get_origin_ref(); - Vector3d aim_point; - vector_add(1.0, rec_origin, 1.0, helio_origin, aim_point); + glm::dvec3 rec_origin = receiver->get_origin_ref(); + glm::dvec3 aim_point = rec_origin + helio_origin; receiver->set_reference_frame_geometry(rec_origin, aim_point, 90.0); } void set_slant_focal_length() { // Set focal length to slant range - Vector3d distance; - vector_add(-1.0, receiver->get_origin_global(), 1.0, heliostat->get_origin_global(), distance); - double focal_length = vector_norm(distance); + glm::dvec3 distance = -receiver->get_origin_global() + heliostat->get_origin_global(); + double focal_length = glm::length(distance); heliostat->set_focal_length(focal_length); heliostat->create_geometry(); } @@ -197,17 +194,16 @@ class SingleHeliostatSimulation : public ::testing::Test { heliostat->set_number_panels(7, 5); heliostat->set_gaps(0.03, 0.03); // Set on-axis canting to slant range - Vector3d distance; - vector_add(-1.0, receiver->get_origin_global(), 1.0, heliostat->get_origin_global(), distance); - double focal_length = vector_norm(distance); + glm::dvec3 distance = -receiver->get_origin_global() + heliostat->get_origin_global(); + double focal_length = glm::length(distance); heliostat->set_canting(Heliostat::CantingType::ON_AXIS, focal_length, 0.0); heliostat->create_geometry(); } void update_simulation_geometry(double azimuth, double elevation) { // Set sun position - Vector3d sun_pos; - sun_position_vector_degrees(sun_pos, azimuth, elevation); + glm::dvec3 sun_pos; + SolTrace::Data::sun_position_vector_degrees(sun_pos, azimuth, elevation); sun->set_position(sun_pos); // Update heliostat position heliostat->update_geometry(azimuth, elevation); @@ -375,14 +371,14 @@ class SingleHeliostatSimulation : public ::testing::Test { double minx, maxx, miny, maxy; minx = maxx = miny = maxy = 0.0; - Vector3d rec_origin = receiver->get_origin_global(); + glm::dvec3 rec_origin = receiver->get_origin_global(); // Autoscale if (true) { minx = miny = 1e199; maxx = maxy = -1e199; - Vector3d local_position; - Vector3d global_position; + glm::dvec3 local_position; + glm::dvec3 global_position; // automatically size the min/max x and y for (size_t i = 0; i < result.get_number_of_records(); i++) { @@ -437,8 +433,8 @@ class SingleHeliostatSimulation : public ::testing::Test { fluxGrid.fill(0.0); for (size_t i = 0; i < result.get_number_of_records(); i++) { - Vector3d local_position; - Vector3d global_position; + glm::dvec3 local_position; + glm::dvec3 global_position; const ray_record_ptr rr = result[i]; for (size_t j = 0; j < rr->interactions.size(); j++) { @@ -565,15 +561,15 @@ class SingleHeliostatSimulation : public ::testing::Test { void check_outputs(SimulationResult result, std::string position) { // Check heliostat aim vector and z-rotation if (position == "N") { - EXPECT_NEAR(heliostat->get_aim_vector_ref().data[0], 0.0, 1.e-3); - EXPECT_NEAR(heliostat->get_aim_vector_ref().data[1], -276.838, 1.e-3); - EXPECT_NEAR(heliostat->get_aim_vector_ref().data[2], 635.35, 1.e-3); + EXPECT_NEAR(heliostat->get_aim_vector_ref().x, 0.0, 1.e-3); + EXPECT_NEAR(heliostat->get_aim_vector_ref().y, -276.838, 1.e-3); + EXPECT_NEAR(heliostat->get_aim_vector_ref().z, 635.35, 1.e-3); EXPECT_NEAR(heliostat->get_zrot(), 180.0, 1.e-4); // TODO: This should be zero } else if (position == "SE") { - EXPECT_NEAR(heliostat->get_aim_vector_ref().data[0], -207.952, 1.e-3); - EXPECT_NEAR(heliostat->get_aim_vector_ref().data[1], -125.53, 1.e-3); - EXPECT_NEAR(heliostat->get_aim_vector_ref().data[2], 915.611, 1.e-3); + EXPECT_NEAR(heliostat->get_aim_vector_ref().x, -207.952, 1.e-3); + EXPECT_NEAR(heliostat->get_aim_vector_ref().y, -125.53, 1.e-3); + EXPECT_NEAR(heliostat->get_aim_vector_ref().z, 915.611, 1.e-3); EXPECT_NEAR(heliostat->get_zrot(), -80.5688, 1.e-4); } @@ -792,4 +788,4 @@ TEST_F(SingleHeliostatSimulation, MultiFacetFocused_SlantCanting_Southeast) EXPECT_NEAR(sun_height, 11.5183, 1.e-3); } -// TODO: add off-axis cases \ No newline at end of file +// TODO: add off-axis cases From 41e3ac3d01b84407177e6498ef2ca1940353e61f Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sat, 24 Jan 2026 10:09:18 -0700 Subject: [PATCH 04/23] Fix more tests --- .../native_runner/find_element_hit.cpp | 28 ++-- .../native_runner/generate_ray.cpp | 43 +++--- .../native_runner/native_runner_types.cpp | 6 +- .../native_runner/sun_to_primary_stage.cpp | 36 ++--- .../simulation_runner/native_runner/trace.cpp | 139 ++++++++---------- .../simulation_data/linear_algebra_test.cpp | 2 +- 6 files changed, 116 insertions(+), 138 deletions(-) diff --git a/coretrace/simulation_runner/native_runner/find_element_hit.cpp b/coretrace/simulation_runner/native_runner/find_element_hit.cpp index dc78898a..bd50927f 100644 --- a/coretrace/simulation_runner/native_runner/find_element_hit.cpp +++ b/coretrace/simulation_runner/native_runner/find_element_hit.cpp @@ -39,16 +39,16 @@ namespace SolTrace::NativeRunner double LastPathLength = 1e99; int HitBackSide = 0; int InterceptFlag = 0; - glm::dvec3 DFXYZ = {0.0, 0.0, 0.0}; - glm::dvec3 PosRayElement = {0.0, 0.0, 0.0}; - glm::dvec3 CosRayElement = {0.0, 0.0, 0.0}; - glm::dvec3 PosRaySurfStage = {0.0, 0.0, 0.0}; - glm::dvec3 CosRaySurfStage = {0.0, 0.0, 0.0}; - glm::dvec3 PosRaySurfElement = {0.0, 0.0, 0.0}; - glm::dvec3 CosRaySurfElement = {0.0, 0.0, 0.0}; - StageHit = false; + glm::dvec3 DFXYZ = glm::dvec3{0.0}; + glm::dvec3 PosRayElement = glm::dvec3{0.0}; + glm::dvec3 CosRayElement = glm::dvec3{0.0}; + glm::dvec3 PosRaySurfStage = glm::dvec3{0.0}; + glm::dvec3 CosRaySurfStage = glm::dvec3{0.0}; + glm::dvec3 PosRaySurfElement = glm::dvec3{0.0}; + glm::dvec3 CosRaySurfElement = glm::dvec3{0.0}; + StageHit = false; - for (uint_fast64_t j = 0; j < nintelements; j++) + for (uint_fast64_t j = 0; j < nintelements; j++) { TElement *Element; // = Stage->ElementList[j]; if (i == 0 && !PT_override) @@ -124,9 +124,9 @@ namespace SolTrace::NativeRunner // Element->SurfaceIndex == 'r' || // Element->SurfaceIndex == 'R') // TODO: Is this the correct thing to do? - if (PosRaySurfElement[2] <= Element->ZAperture) - { - StageHit = true; + if (PosRaySurfElement.z <= Element->ZAperture) + { + StageHit = true; LastPathLength = PathLength; LastPosRaySurfElement = PosRaySurfElement; LastCosRaySurfElement = CosRaySurfElement; @@ -144,8 +144,8 @@ namespace SolTrace::NativeRunner LastPosRaySurfStage = PosRaySurfStage; LastCosRaySurfStage = CosRaySurfStage; LastHitBackSide = HitBackSide; - } - } + } + } } } } diff --git a/coretrace/simulation_runner/native_runner/generate_ray.cpp b/coretrace/simulation_runner/native_runner/generate_ray.cpp index 664ce32a..e4817645 100644 --- a/coretrace/simulation_runner/native_runner/generate_ray.cpp +++ b/coretrace/simulation_runner/native_runner/generate_ray.cpp @@ -35,19 +35,17 @@ void GenerateRay( glm::dvec3 PosRayStage(0.0, 0.0, 0.0); glm::dvec3 CosRayStage(0.0, 0.0, 0.0); int NegPosSign = 0; - PosRaySun[0] = 0.; - PosRaySun[1] = 0.; - PosRaySun[2] = 0.; + PosRaySun = glm::dvec3(0.0); - // ZRaySun := 0.0; //Origin of rays in xy plane of sun coord system. - ZRaySun = -10000.0; // changed 5/1/00. rays originate from well bebind the sun coordinate system xy - // plane which has been translated to primary stage origin. This value has been reduced signficantly because of numerical issues in tracing rays from sun - // to the closer form solution for a cylinder. It used to 1e6 and has been reduced to 1e4, which should still be sufficient. 10-26-09 Wendelin + // ZRaySun := 0.0; //Origin of rays in xy plane of sun coord system. + ZRaySun = -10000.0; // changed 5/1/00. rays originate from well bebind the sun coordinate system xy + // plane which has been translated to primary stage origin. This value has been reduced signficantly because of numerical issues in tracing rays from sun + // to the closer form solution for a cylinder. It used to 1e6 and has been reduced to 1e4, which should still be sufficient. 10-26-09 Wendelin - //{Generate random rays inside of region of interest or from point source} + //{Generate random rays inside of region of interest or from point source} - if (Sun->PointSource) // fixed this on 3-18-13 - { + if (Sun->PointSource) // fixed this on 3-18-13 + { PosRayGlobal = Sun->Origin; if (myrng() <= 0.5) @@ -75,16 +73,15 @@ void GenerateRay( CosRayGlobal /= CosRayGMag; } - else - { - // following changed on 09/26/05 to more efficiently generate rays relative to element center of mass in primary stage + else + { + // following changed on 09/26/05 to more efficiently generate rays relative to element center of mass in primary stage /*{XRaySun := 2.0*MaxRad*ran3(Seed) - MaxRad; //ran3 produces results independent of platform. YRaySun := 2.0*MaxRad*ran3(Seed) - MaxRad; if (XRaySun*XRaySun + YRaySun*YRaySun) > MaxRad*MaxRad then goto GENRAY; XRaySun := Xcm + XRaySun; //adjust location of generated rays about element center of mass - YRaySun := Ycm + YRaySun;}*/ - - XRaySun = Sun->MinXSun + (Sun->MaxXSun - Sun->MinXSun) * myrng(); // uses a rectangular region of interest about the primary + YRaySun := Ycm + YRaySun;}*/ + XRaySun = Sun->MinXSun + (Sun->MaxXSun - Sun->MinXSun) * myrng(); // uses a rectangular region of interest about the primary YRaySun = Sun->MinYSun + (Sun->MaxYSun - Sun->MinYSun) * myrng(); // stage. Added 09/26/05 // std::cout << "MinXSun: " << Sun->MinXSun @@ -98,14 +95,10 @@ void GenerateRay( // << std::endl; //{Offload ray location and direction cosines into sun array} - PosRaySun[0] = XRaySun; - PosRaySun[1] = YRaySun; - PosRaySun[2] = ZRaySun; - CosRaySun[0] = 0.0; - CosRaySun[1] = 0.0; - CosRaySun[2] = 1.0; - - //{Transform ray locations and dir cosines into Stage system} + PosRaySun = {XRaySun, YRaySun, ZRaySun}; + CosRaySun = {0.0, 0.0, 1.0}; + + //{Transform ray locations and dir cosines into Stage system} Data::TransformToReference(PosRaySun, CosRaySun, PosSunStage, @@ -122,7 +115,7 @@ void GenerateRay( CosRayGlobal); } - return; + return; } } // namespace SolTrace::NativeRunner diff --git a/coretrace/simulation_runner/native_runner/native_runner_types.cpp b/coretrace/simulation_runner/native_runner/native_runner_types.cpp index f69e50df..88421c4e 100644 --- a/coretrace/simulation_runner/native_runner/native_runner_types.cpp +++ b/coretrace/simulation_runner/native_runner/native_runner_types.cpp @@ -52,6 +52,8 @@ #include #include +#include "glm/ext/matrix_transform.hpp" + #include "calculator_factory.hpp" #include "matvec.hpp" #include "native_runner_types.hpp" @@ -505,8 +507,8 @@ namespace SolTrace::NativeRunner my_stage->AimPoint = glm::dvec3{0.0}; my_stage->AimPoint[2] = 1.0; my_stage->ZRot = 0.0; - my_stage->RRefToLoc = glm::dmat3{0.0}; - my_stage->RLocToRef = glm::dmat3{0.0}; + my_stage->RRefToLoc = glm::identity(); + my_stage->RLocToRef = glm::identity(); return my_stage; } diff --git a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp index 857554d1..6ff1dc8d 100644 --- a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp +++ b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp @@ -49,9 +49,7 @@ namespace SolTrace::NativeRunner // PosSunGlob[0] = Sun.Origin[0];//Position of sun coord. system origin in global system // PosSunGlob[1] = Sun.Origin[1]; //changed 5/1/00 to place sun at primary stage origin; direction vector // PosSunGlob[2] = Sun.Origin[2]; //calculated below from difference between entered sun position and global - PosSunGlob[0] = Stage->Origin[0]; // origin - PosSunGlob[1] = Stage->Origin[1]; - PosSunGlob[2] = Stage->Origin[2]; + PosSunGlob = Stage->Origin; // First calculate direction cosines of sun z-axis in global coord. system dx = 0.0 - Sun->Origin[0]; // changed 5/1/00 to tie the sun direction to global coordinate system origin @@ -69,9 +67,8 @@ namespace SolTrace::NativeRunner dy = dy / dtot; dz = dz / dtot; - CosSunGlob[0] = dx; // direction cosines of sun Z-axis in global system. - CosSunGlob[1] = dy; - CosSunGlob[2] = dz; + // direction cosines of sun Z-axis in global system. + CosSunGlob = {dx, dy, dz}; // Transform sun direction vector to Stage system; CosSunStage is dir cosines of sun ray in Stage coord. system // PosSunStage is position of sun coord. system origin in Stage system @@ -82,21 +79,19 @@ namespace SolTrace::NativeRunner PosSunStage, CosSunStage); - Sun->Euler[0] = atan2(CosSunStage[0], CosSunStage[2]); // Euler angles relating sun to Stage system - Sun->Euler[1] = asin(CosSunStage[1]); - Sun->Euler[2] = 0.0; + Sun->Euler = {atan2(CosSunStage.x, + CosSunStage.z), // Euler angles relating sun to Stage system + asin(CosSunStage.y), + 0.0}; /* {Now we have the Euler angles from Stage to the sun coordinate system. We have to now transform the element locations in the stage system to the sun coordinate system and find the smallest circle in the xy plane of the sun system that completely encompasses the projected images of the elements onto that plane}*/ - Origin[0] = 0.0; // Origin of transformed system and stage system the same - Origin[1] = 0.0; - Origin[2] = 0.0; + Origin = glm::dvec3(0.0); // Origin of transformed system and stage system the same + + CosDum = glm::dvec3(0.0); // direction cosines not important; only interested in point locations - CosDum[0] = 0.0; // direction cosines not important; only interested in point locations - CosDum[1] = 0.0; - CosDum[2] = 1.0; Sun->MaxRad = 0.0; Sun->Xcm = 0.0; @@ -130,8 +125,8 @@ namespace SolTrace::NativeRunner // RRefToLoc, PosLoc, CosLoc); elem = *iter; Data::TransformToLocal(elem->Origin, CosDum, Origin, RRefToLoc, PosLoc, CosLoc); - Xsum += PosLoc[0]; - Ysum += PosLoc[1]; + Xsum += PosLoc.x; + Ysum += PosLoc.y; } // center of mass of distribution of element locations as projected @@ -139,10 +134,9 @@ namespace SolTrace::NativeRunner Sun->Xcm = Xsum / Stage->ElementList.size(); Sun->Ycm = Ysum / Stage->ElementList.size(); - // std::cout << "Xcm = " << Sun->Xcm - // << "\nYcm = " << Sun->Ycm - // << "\nnelement = " << Stage->ElementList.size() - // << std::endl; + // std::cout << "Xcm = " << Sun->Xcm << "\nYcm = " << Sun->Ycm + // << "\nnelement = " << Stage->ElementList.size() << "\nXsum = " << Xsum + // << std::endl; size_t nelements = 0; elem = nullptr; diff --git a/coretrace/simulation_runner/native_runner/trace.cpp b/coretrace/simulation_runner/native_runner/trace.cpp index 07150df8..fabd3475 100644 --- a/coretrace/simulation_runner/native_runner/trace.cpp +++ b/coretrace/simulation_runner/native_runner/trace.cpp @@ -216,12 +216,11 @@ namespace SolTrace::NativeRunner uint_fast64_t StageDataArrayIndex = 0; uint_fast64_t PreviousStageDataArrayIndex = 0; uint_fast64_t n_rays_active = NumberOfRays; - uint_fast64_t sun_ray_count_local = 0; + uint_fast64_t sun_ray_count_local = 0; - // Loop through stages - for (uint_fast64_t i = 0; i < System->StageList.size(); i++) - { - // std::cout << "Processing stage " << i << "..." << std::endl; + // Loop through stages + for (uint_fast64_t i = 0; i < System->StageList.size(); i++) { + // std::cout << "Processing stage " << i << "..." << std::endl; // Check if previous stage has rays bool StageHasRays = true; if (i > 0 && PreviousStageHasRays == false) @@ -240,12 +239,12 @@ namespace SolTrace::NativeRunner while (StageHasRays) { // Initialize Global Coordinates - glm::dvec3 PosRayGlob(0.0, 0.0, 0.0); - glm::dvec3 CosRayGlob(0.0, 0.0, 0.0); + glm::dvec3 PosRayGlob(0.0); + glm::dvec3 CosRayGlob(0.0); // Initialize Stage Coordinates - glm::dvec3 PosRayStage(0.0, 0.0, 0.0); - glm::dvec3 CosRayStage(0.0, 0.0, 0.0); + glm::dvec3 PosRayStage(0.0); + glm::dvec3 CosRayStage(0.0); // Initialize PT Optimization variables bool has_elements = true; @@ -273,22 +272,19 @@ namespace SolTrace::NativeRunner // that could interact with ray if (!PT_override) { - has_elements = - sun_hash->get_all_data_at_loc(sunint_elements, - PosRaySun[0], - PosRaySun[1]); - } - } - else - { - // Get ray from previous stage - RayNumber = IncomingRays[StageDataArrayIndex].Num; + has_elements = sun_hash->get_all_data_at_loc(sunint_elements, + PosRaySun.x, + PosRaySun.y); + } + } else { + // Get ray from previous stage + RayNumber = IncomingRays[StageDataArrayIndex].Num; PosRayGlob = IncomingRays[StageDataArrayIndex].Pos; CosRayGlob = IncomingRays[StageDataArrayIndex].Cos; StageDataArrayIndex++; } - // transform the global incoming ray to local stage coordinates + // transform the global incoming ray to local stage coordinates Data::TransformToLocal(PosRayGlob, CosRayGlob, Stage->Origin, @@ -300,11 +296,11 @@ namespace SolTrace::NativeRunner bool RayInStage = true; bool in_multi_hit_loop = false; - glm::dvec3 LastPosRaySurfElement(0.0, 0.0, 0.0); - glm::dvec3 LastCosRaySurfElement(0.0, 0.0, 0.0); - glm::dvec3 LastPosRaySurfStage(0.0, 0.0, 0.0); - glm::dvec3 LastCosRaySurfStage(0.0, 0.0, 0.0); - glm::dvec3 LastDFXYZ(0.0, 0.0, 0.0); + glm::dvec3 LastPosRaySurfElement(0.0); + glm::dvec3 LastCosRaySurfElement(0.0); + glm::dvec3 LastPosRaySurfStage(0.0); + glm::dvec3 LastCosRaySurfStage(0.0); + glm::dvec3 LastDFXYZ(0.0); uint_fast64_t LastElementNumber = 0; uint_fast64_t LastRayNumber = 0; @@ -314,18 +310,17 @@ namespace SolTrace::NativeRunner bool StageHit; int MultipleHitCount = 0; - glm::dvec3 PosRayOutElement(0.0, 0.0, 0.0); - glm::dvec3 CosRayOutElement(0.0, 0.0, 0.0); + glm::dvec3 PosRayOutElement(0.0); + glm::dvec3 CosRayOutElement(0.0); // Start Loop to trace ray until it leaves stage bool RayIsAbsorbed = false; - while (RayInStage) - { - // Set number of elements to search through - uint_fast64_t nintelements = 0; - std::vector reflint_elements; - if (!PT_override) // if using opt AND first stage - { + while (RayInStage) { + // Set number of elements to search through + uint_fast64_t nintelements = 0; + std::vector reflint_elements; // TODO Hoist + if (!PT_override) // if using opt AND first stage + { nintelements = GetPTElements(AsPowerTower, Stage, i, @@ -353,40 +348,35 @@ namespace SolTrace::NativeRunner LastPosRaySurfStage, LastCosRaySurfStage, ErrorFlag, LastHitBackSide, StageHit); - // Breakout if ray left stage - if (!StageHit) - { - RayInStage = false; - break; - } - - // Increment MultipleHitCount - MultipleHitCount++; + // Breakout if ray left stage + if (!StageHit) { + RayInStage = false; + break; + } - if (i == 0 && MultipleHitCount == 1) - { - auto r = System->RayData.Append(thread_id, - PosRayGlob, - CosRayGlob, - ELEMENT_NULL, - i + 1, - LastRayNumber, - RayEvent::CREATE); - if (r == nullptr) - { - std::stringstream ss; - ss << "Thread " << thread_id - << " failed to record ray data.\n"; - manager->error_log(ss.str()); - } - } + // Increment MultipleHitCount + MultipleHitCount++; + + if (i == 0 && MultipleHitCount == 1) { + auto r = System->RayData.Append(thread_id, + PosRayGlob, + CosRayGlob, + ELEMENT_NULL, + i + 1, + LastRayNumber, + RayEvent::CREATE); + if (r == nullptr) { + std::stringstream ss; + ss << "Thread " << thread_id << " failed to record ray data.\n"; + manager->error_log(ss.str()); + } + } - // Get optics and check for absorption - const OpticalProperties *optics = 0; - RayEvent rev = RayEvent::VIRTUAL; - if (Stage->Virtual) - { - // If stage is virtual, there is no interaction + // Get optics and check for absorption + const OpticalProperties *optics = 0; + RayEvent rev = RayEvent::VIRTUAL; + if (Stage->Virtual) { + // If stage is virtual, there is no interaction PosRayOutElement = LastPosRaySurfElement; CosRayOutElement = LastCosRaySurfElement; } else { @@ -536,18 +526,17 @@ namespace SolTrace::NativeRunner { in_multi_hit_loop = true; } - } + } - ++update_count; - if (update_count % update_rate == 0) - { - double progress = update_count / total_work; + ++update_count; + if (update_count % update_rate == 0) { + double progress = update_count / total_work; manager->progress_update(thread_id, progress); if (manager->terminate(thread_id)) return RunnerStatus::CANCEL; - } + } - // Handle if Ray was absorbed + // Handle if Ray was absorbed if (RayIsAbsorbed) { Data::TransformToReference(LastPosRaySurfStage, @@ -725,9 +714,9 @@ namespace SolTrace::NativeRunner { return RunnerStatus::ERROR; } - } + } - // Close out any remaining rays as misses + // Close out any remaining rays as misses unsigned idx = System->StageList.size() - 1; tstage_ptr Stage = System->StageList[idx]; for (uint_fast64_t k = 0; k < n_rays_active; ++k) diff --git a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp index 9a6efd55..eee27129 100644 --- a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp +++ b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp @@ -115,7 +115,7 @@ TEST(LinearAlgebra, MatrixVectorProduct) glm::dvec3 x(0.5, 1.0, -2.0); glm::dvec3 y; - glm::dmat3 A; + glm::dmat3 A = {0.0}; A[0][0] = 1.0; A[1][1] = 1.0; A[2][2] = 1.0; From d99f085070d6b2bd8d28da53088fa00b1682dc8f Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sat, 24 Jan 2026 11:44:09 -0700 Subject: [PATCH 05/23] Performance and bugfix --- coretrace/simulation_data/aperture.cpp | 54 +++++++++---------- coretrace/simulation_data/aperture.hpp | 43 ++++++++++++--- .../cst_templates/heliostat.cpp | 3 -- coretrace/simulation_data/simdata_io.cpp | 4 +- .../native_runner/cylinder_calculator.cpp | 8 +-- .../native_runner/sun_to_primary_stage.cpp | 2 +- .../native_runner/sun_to_primary_stage.hpp | 2 +- .../simulation_data/element_test.cpp | 8 +-- .../simulation_data/file_io_test.cpp | 8 +-- 9 files changed, 76 insertions(+), 56 deletions(-) diff --git a/coretrace/simulation_data/aperture.cpp b/coretrace/simulation_data/aperture.cpp index 689aca2d..039440df 100644 --- a/coretrace/simulation_data/aperture.cpp +++ b/coretrace/simulation_data/aperture.cpp @@ -9,6 +9,7 @@ // #include #include "constants.hpp" +#include "vector_utility.hpp" namespace SolTrace::Data { @@ -668,33 +669,32 @@ void IrregularQuadrilateral::write_json(nlohmann::ordered_json& jnode) const } Rectangle::Rectangle(double xlen, double ylen) - : Aperture(ApertureType::RECTANGLE), - x_length(xlen), - y_length(ylen) + : Aperture(ApertureType::RECTANGLE) + , m_length(xlen, ylen) { // Default to rectangle centered at the origin. - this->x_coord = -0.5 * this->x_length; - this->y_coord = -0.5 * this->y_length; - return; + m_coord = -0.5 * m_length; + update_cached(); } Rectangle::Rectangle(const nlohmann::ordered_json& jnode) : Aperture(ApertureType::RECTANGLE) { - this->x_length = jnode.at("x_length"); - this->y_length = jnode.at("y_length"); - this->x_coord = jnode.at("x_coord"); - this->y_coord = jnode.at("y_coord"); + this->m_length.x = jnode.at("x_length"); + this->m_length.y = jnode.at("y_length"); + this->m_coord.x = jnode.at("x_coord"); + this->m_coord.y = jnode.at("y_coord"); + update_cached(); } double Rectangle::aperture_area() const { - return this->x_length * this->y_length; + return glm::compMul(m_length); } double Rectangle::diameter_circumscribed_circle() const { - return sqrt(x_length * x_length + y_length * y_length); + return glm::length(m_length); } aperture_ptr Rectangle::make_copy() const @@ -705,30 +705,25 @@ aperture_ptr Rectangle::make_copy() const bool Rectangle::is_in(double x, double y) const { - double xl = this->x_coord; - double yl = this->y_coord; - double xu = xl + this->x_length; - double yu = yl + this->y_length; - return (xl <= x && x <= xu && yl <= y && y <= yu); + return (m_coord.x <= x && x <= m_cached_range.x && m_coord.y <= y && y <= m_cached_range.y); } Rectangle::Rectangle(double xlen, double ylen, double xl, double yl) - : Aperture(ApertureType::RECTANGLE), - x_length(xlen), - y_length(ylen), - x_coord(xl), - y_coord(yl) + : Aperture(ApertureType::RECTANGLE) + , m_length(xlen, ylen) + , m_coord(xl, yl) { + update_cached(); } void Rectangle::write_json(nlohmann::ordered_json& jnode) const { ApertureType type = ApertureType::RECTANGLE; jnode["aperture_type"] = ApertureTypeMap.at(type); - jnode["x_length"] = this->x_length; - jnode["y_length"] = this->y_length; - jnode["x_coord"] = this->x_coord; - jnode["y_coord"] = this->y_coord; + jnode["x_length"] = this->m_length.x; + jnode["y_length"] = this->m_length.y; + jnode["x_coord"] = this->m_coord.x; + jnode["y_coord"] = this->m_coord.y; } @@ -739,10 +734,9 @@ Rectangle::triangulation() const { std::vector indices; for (int i = 0; i <= segments; ++i) { for (int j = 0; j <= segments; ++j) { - const double x = i * x_length / segments + x_coord; - const double y = j * y_length / segments + y_coord; - verts.push_back(x); - verts.push_back(y); + auto p = glm::dvec2(i, j) * m_length / double(segments) + m_coord; + verts.push_back(p.x); + verts.push_back(p.y); } } for (int i = 0; i < segments; ++i) { diff --git a/coretrace/simulation_data/aperture.hpp b/coretrace/simulation_data/aperture.hpp index d4a961be..b92c3663 100644 --- a/coretrace/simulation_data/aperture.hpp +++ b/coretrace/simulation_data/aperture.hpp @@ -16,6 +16,8 @@ #include #include #include + +#include #include #include "constants.hpp" @@ -299,8 +301,6 @@ namespace SolTrace::Data { double diameter; - // Circle() : Aperture(CIRCLE), diameter(0.0) {} - /** * @brief Constructor for circular aperture * @param d Diameter of the circle @@ -483,15 +483,18 @@ namespace SolTrace::Data triangulation() const override; }; - struct Rectangle : public Aperture + class Rectangle : public Aperture { - double x_length; - double y_length; + glm::dvec2 m_length; // NOTE: The point (x_coord, y_coord) gives the location of the // lower left hand corner of the rectangle in the xy-plane. - double x_coord; - double y_coord; + glm::dvec2 m_coord; + + glm::dvec2 m_cached_range; + + void update_cached() { m_cached_range = m_coord + m_length; } + public: /** * @brief Constructor for centered rectangular aperture * @param xlen Length in x direction @@ -516,6 +519,32 @@ namespace SolTrace::Data virtual ~Rectangle() {} + double x_length() const { return m_length.x; } + double y_length() const { return m_length.y; } + double x_coord() const { return m_coord.x; } + double y_coord() const { return m_coord.y; } + + void set_x_length(double x_length) + { + m_length.x = x_length; + update_cached(); + } + void set_y_length(double y_length) + { + m_length.y = y_length; + update_cached(); + } + void set_x_coord(double x_coord) + { + m_coord.x = x_coord; + update_cached(); + } + void set_y_coord(double y_coord) + { + m_coord.y = y_coord; + update_cached(); + } + /** * @brief Calculate rectangular aperture area * @return Area of the rectangular aperture diff --git a/coretrace/simulation_data/cst_templates/heliostat.cpp b/coretrace/simulation_data/cst_templates/heliostat.cpp index c3578338..dd0a2d6d 100644 --- a/coretrace/simulation_data/cst_templates/heliostat.cpp +++ b/coretrace/simulation_data/cst_templates/heliostat.cpp @@ -249,9 +249,6 @@ namespace SolTrace::Data 1000.0 *this->aim; // Project into xy-plane - aim_vector[2] = 0.0; - double theta = acos(aim_vector[0] / glm::length(aim_vector)); - this->set_zrot_radians(theta); double aim_azimuth = atan2(aim_vector[0], aim_vector[1]); // Elevation axis diff --git a/coretrace/simulation_data/simdata_io.cpp b/coretrace/simulation_data/simdata_io.cpp index 8876ebc4..b0b56a4a 100644 --- a/coretrace/simulation_data/simdata_io.cpp +++ b/coretrace/simulation_data/simdata_io.cpp @@ -529,8 +529,8 @@ bool read_element( { throw std::invalid_argument("This should not happen!"); } - rect->x_length = 2.0 * cyl->radius; - rect->x_coord = -1.0 * cyl->radius; + rect->set_x_length(2.0 * cyl->radius); + rect->set_x_coord(-1.0 * cyl->radius); } // Set element position and orientation diff --git a/coretrace/simulation_runner/native_runner/cylinder_calculator.cpp b/coretrace/simulation_runner/native_runner/cylinder_calculator.cpp index d14750e8..127c5129 100644 --- a/coretrace/simulation_runner/native_runner/cylinder_calculator.cpp +++ b/coretrace/simulation_runner/native_runner/cylinder_calculator.cpp @@ -54,20 +54,20 @@ namespace SolTrace::NativeRunner } // Validate rectangle dimensions - if (rect->x_length <= 0.0 || rect->y_length <= 0.0) + if (rect->x_length() <= 0.0 || rect->y_length() <= 0.0) { std::stringstream ss; ss << "CylinderCalculator: Rectangle dimensions must be positive, got: (" - << rect->x_length << ", " << rect->y_length << ")"; + << rect->x_length() << ", " << rect->y_length() << ")"; throw std::invalid_argument(ss.str()); } // Validate that rectangle x_length matches cylinder diameter double expected_x_length = 2.0 * cylinder->radius; - if (fabs(expected_x_length - rect->x_length) > 1e-8) + if (fabs(expected_x_length - rect->x_length()) > 1e-8) { std::stringstream ss; - ss << "CylinderCalculator: Rectangle x_length (" << rect->x_length + ss << "CylinderCalculator: Rectangle x_length (" << rect->x_length() << ") must equal cylinder diameter (" << expected_x_length << ")"; throw std::invalid_argument(ss.str()); } diff --git a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp index 6ff1dc8d..fd1df309 100644 --- a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp +++ b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.cpp @@ -13,7 +13,7 @@ namespace SolTrace::NativeRunner TSystem *System, TStage *Stage, TSun *Sun, - glm::dvec3 PosSunStage) + glm::dvec3& PosSunStage) { /*{Purpose: To compute the sun position within primary sage and the maximum radius of a cicle seen from sun which encircles diff --git a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp index 3617bae6..d5530e05 100644 --- a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp +++ b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp @@ -8,7 +8,7 @@ namespace SolTrace::NativeRunner { bool SunToPrimaryStage( - thread_manager_ptr manager, TSystem *System, TStage *Stage, TSun *Sun, glm::dvec3 PosSunStage); + thread_manager_ptr manager, TSystem *System, TStage *Stage, TSun *Sun, glm::dvec3 &PosSunStage); } // namespace SolTrace::NativeRunner diff --git a/google-tests/unit-tests/simulation_data/element_test.cpp b/google-tests/unit-tests/simulation_data/element_test.cpp index 1acbc645..f2dfb7d6 100644 --- a/google-tests/unit-tests/simulation_data/element_test.cpp +++ b/google-tests/unit-tests/simulation_data/element_test.cpp @@ -127,8 +127,8 @@ TEST(Element, VirtualElement) EXPECT_NE(rptr, nullptr); if (rptr != nullptr) { - EXPECT_EQ(rptr->x_length, LX); - EXPECT_EQ(rptr->y_length, LY); + EXPECT_EQ(rptr->x_length(), LX); + EXPECT_EQ(rptr->y_length(), LY); } ve.set_surface(make_surface()); @@ -175,8 +175,8 @@ TEST(Element, VirtualPlane) EXPECT_NE(rptr, nullptr); if (rptr != nullptr) { - EXPECT_EQ(rptr->x_length, LX); - EXPECT_EQ(rptr->y_length, LY); + EXPECT_EQ(rptr->x_length(), LX); + EXPECT_EQ(rptr->y_length(), LY); } // These functions should have no effects diff --git a/google-tests/unit-tests/simulation_data/file_io_test.cpp b/google-tests/unit-tests/simulation_data/file_io_test.cpp index ddd41d32..d961f85f 100644 --- a/google-tests/unit-tests/simulation_data/file_io_test.cpp +++ b/google-tests/unit-tests/simulation_data/file_io_test.cpp @@ -531,10 +531,10 @@ TEST(io_json, apertures_read) auto rect_ptr = Aperture::make_aperture_from_json(jrectangle); auto rect_cast = dynamic_cast(rect_ptr.get()); ASSERT_TRUE(rect_cast != nullptr); - EXPECT_DOUBLE_EQ(4, rect_cast->x_length); - EXPECT_DOUBLE_EQ(5, rect_cast->y_length); - EXPECT_DOUBLE_EQ(-2, rect_cast->x_coord); - EXPECT_DOUBLE_EQ(-2.5, rect_cast->y_coord); + EXPECT_DOUBLE_EQ(4, rect_cast->x_length()); + EXPECT_DOUBLE_EQ(5, rect_cast->y_length()); + EXPECT_DOUBLE_EQ(-2, rect_cast->x_coord()); + EXPECT_DOUBLE_EQ(-2.5, rect_cast->y_coord()); // EQUILATERAL_TRIANGLE json jtriangle_eq; From 2acc79f644361e154768cd2350313a196d82e615 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sat, 24 Jan 2026 14:48:10 -0700 Subject: [PATCH 06/23] Remove old vec files and patch optix --- coretrace/simulation_data/vector3d.cpp | 317 ------------------ coretrace/simulation_data/vector3d.hpp | 260 -------------- .../optix_runner/optix_runner.cpp | 5 +- .../optix_runner/optix_runner.hpp | 2 +- 4 files changed, 3 insertions(+), 581 deletions(-) delete mode 100644 coretrace/simulation_data/vector3d.cpp delete mode 100644 coretrace/simulation_data/vector3d.hpp diff --git a/coretrace/simulation_data/vector3d.cpp b/coretrace/simulation_data/vector3d.cpp deleted file mode 100644 index 001b0143..00000000 --- a/coretrace/simulation_data/vector3d.cpp +++ /dev/null @@ -1,317 +0,0 @@ -#include "glm::dvec3.hpp" - -// #include - -#include -#include - -#if 0 - -#include "matvec.hpp" - -namespace SolTrace::Data -{ - - // inline void vector_copy(double data[3], const glm::dvec3 &x) - // { - // CopyVec3(data, x.data); - // return; - // } - // inline void vector_copy(std::vector &dest, const glm::dvec3 &x) - // { - // CopyVec3(dest, x.data); - // return; - // } - - glm::dvec3::glm::dvec3() - { - this->zero(); - return; - } - - glm::dvec3::glm::dvec3(const double data[3]) - { - for (int i = 0; i < 3; ++i) - this->data[i] = data[i]; - return; - } - glm::dvec3::glm::dvec3(double x, double y, double z) - { - this->data[0] = x; - this->data[1] = y; - this->data[2] = z; - return; - } - glm::dvec3::~glm::dvec3() - { - return; - } - - void glm::dvec3::zero() - { - for (int i = 0; i < 3; ++i) - this->data[i] = 0.0; - return; - } - - void glm::dvec3::set_values(double x, double y, double z) - { - this->data[0] = x; - this->data[1] = y; - this->data[2] = z; - return; - } - - void glm::dvec3::scalar_mult(double alpha) - { - for (int i = 0; i < 3; ++i) - this->data[i] *= alpha; - return; - } - - void glm::dvec3::make_unit() - { - make_unit_vector(*this); - return; - } - - double glm::dvec3::norm() const - { - return vector_norm(*this); - } - - const double &glm::dvec3::operator[](int idx) const - { - assert(idx >= 0 && idx < 3); - return this->data[idx]; - } - - double &glm::dvec3::operator[](int idx) - { - assert(idx >= 0 && idx < 3); - return this->data[idx]; - } - - std::ostream &operator<<(std::ostream &os, const glm::dvec3 &x) - { - os << "[" << x.data[0] << ", " - << x.data[1] << ", " - << x.data[2] << "]"; - return os; - } - - Matrix3d::Matrix3d() - { - // for (int i = 0; i < 3; ++i) - // for (int j = 0; j < 3; ++j) - // this->data[i][j] = 0.0; - this->zero(); - } - Matrix3d::~Matrix3d() {} - - void Matrix3d::set_value(int i, int j, double val) - { - assert(i >= 0 && i < 3); - assert(j >= 0 && j < 3); - this->data[i][j] = val; - } - - double Matrix3d::get_value(int i, int j) const - { - assert(i >= 0 && i < 3); - assert(j >= 0 && j < 3); - return this->data[i][j]; - } - - void Matrix3d::zero() - { - for (int i = 0; i < 3; ++i) - { - for (int j = 0; j < 3; ++j) - { - data[i][j] = 0.0; - } - } - } - - void Matrix3d::identity() - { - for (int i = 0; i < 3; ++i) - { - for (int j = 0; j < 3; ++j) - { - data[i][j] = (i == j ? 1.0 : 0.0); - } - } - } - - std::ostream &operator<<(std::ostream &os, const Matrix3d &A) - { - // os << "[" << x.data[0] << ", " - // << x.data[1] << ", " - // << x.data[2] << "]"; - os << "["; - for (int i = 0; i < 3; ++i) - { - for (int j = 0; j < 3; ++j) - { - os << A.data[i][j]; - if (j < 2) - { - os << ", "; - } - } - if (i < 2) - { - os << "; "; - } - } - os << "]"; - return os; - } - - // Compute y = A*x placing the result in y - void matrix_vector_product(const Matrix3d &A, const glm::dvec3 &x, glm::dvec3 &y) - { - MatrixVectorMult(A.data, x.data, y.data); - return; - } - - void matrix_matrix_product(const Matrix3d &A, const Matrix3d &B, Matrix3d &C) - { - MatrixMatrixMult(A.data, B.data, C.data); - return; - } - - void vector_add(double a, const glm::dvec3 &x, - double b, const glm::dvec3 &y, - glm::dvec3 &z) - { - for (int i = 0; i < 3; ++i) - { - z[i] = a * x[i] + b * y[i]; - } - return; - } - - void vector_add(double a, const glm::dvec3 &x, - double b, glm::dvec3 &y) - { - for (int i = 0; i < 3; ++i) - { - y[i] = a * x[i] + b * y[i]; - } - return; - } - - void vector_max(const glm::dvec3 &x, const glm::dvec3 &y, glm::dvec3 &max) - { - for (int i = 0; i < 3; ++i) - { - max[i] = fmax(x[i], y[i]); - } - return; - } - - void vector_min(const glm::dvec3 &x, const glm::dvec3 &y, glm::dvec3 &min) - { - for (int i = 0; i < 3; ++i) - { - min[i] = fmin(x[i], y[i]); - } - return; - } - - // Compute standard Euclidean dot product - double dot_product(const glm::dvec3 &x, const glm::dvec3 &y) - { - return DOT(x.data, y.data); - } - - void cross_product(const glm::dvec3 &u, const glm::dvec3 &v, glm::dvec3 &w) - { - double w0 = u[1] * v[2] - u[2] * v[1]; - double w1 = u[2] * v[0] - u[0] * v[2]; - double w2 = u[0] * v[1] - u[1] * v[0]; - w.set_values(w0, w1, w2); - return; - } - - double error(const glm::dvec3 &u, const glm::dvec3 &v) - { - double err = 0.0; - double dx; - for (int i = 0; i < 3; ++i) - { - dx = u[i] - v[i]; - err += dx * dx; - } - return sqrt(err); - } - - double error_inf(const glm::dvec3 &u, const glm::dvec3 &v) - { - double err = 0.0; - for (int i = 0; i < 3; ++i) - { - err = std::max(err, fabs(u[i] - v[i])); - } - return err; - } - - double vector_norm(const glm::dvec3 &x) - { - return sqrt(DOT(x.data, x.data)); - } - - void make_unit_vector(glm::dvec3 &x) - { - double mag = vector_norm(x); - assert(mag > 0.0); - x.scalar_mult(1.0 / mag); - // for (int i = 0; i < 3; ++i) - // { - // x.data[i] /= mag; - // } - return; - } - - // void transform_to_local(glm::dvec3 &pos_ref, - // glm::dvec3 &cos_ref, - // glm::dvec3 &origin, - // Matrix3d &ref_to_local, - // glm::dvec3 &pos_local, - // glm::dvec3 &cos_local) - // { - // TransformToLocal(pos_ref.data, cos_ref.data, - // origin.data, ref_to_local.data, - // pos_local.data, cos_local.data); - // return; - // } - - // void transform_to_reference(glm::dvec3 &pos_local, - // glm::dvec3 &cos_local, - // glm::dvec3 &origin, - // Matrix3d &local_to_ref, - // glm::dvec3 &pos_ref, - // glm::dvec3 &cos_ref) - // { - // TransformToReference(pos_local.data, cos_local.data, - // origin.data, local_to_ref.data, - // pos_ref.data, cos_ref.data); - // return; - // } - - void compute_transform_matrices(glm::dvec3 &euler, - Matrix3d &ref_to_local, - Matrix3d &local_to_ref) - { - CalculateTransformMatrices(euler.data, - ref_to_local.data, - local_to_ref.data); - return; - } - -} // namespace SolTrace::Data - -#endif diff --git a/coretrace/simulation_data/vector3d.hpp b/coretrace/simulation_data/vector3d.hpp deleted file mode 100644 index 086682df..00000000 --- a/coretrace/simulation_data/vector3d.hpp +++ /dev/null @@ -1,260 +0,0 @@ -/** - * @file glm::dvec3.hpp - * @brief 3D vector and matrix classes - * - * Provides glm::dvec3 and Matrix3d classes for 3D geometric operations, - * coordinate transformations, and linear algebra computations. - * These classes form the mathematical foundation for ray tracing - * calculations and geometric transformations in SolTrace. - * - * @defgroup math Mathematical Operations - * @{ - */ - -#ifndef SOLTRACE_glm_vec3 -#define SOLTRACE_glm_vec3 - -#include -#include -#if 0 -#include "matvec.hpp" - -namespace SolTrace::Data { - -class glm::dvec3 -{ -public: - /** - * @brief Default constructor - initializes to zero vector - */ - glm::dvec3(); - - /** - * @brief Constructor from array - * @param data Array of 3 doubles [x, y, z] - */ - glm::dvec3(const double data[3]); - - /** - * @brief Constructor from components - * @param x X component - * @param y Y component - * @param z Z component - */ - glm::dvec3(double x, double y, double z); - ~glm::dvec3(); - - /** - * @brief Set all components to zero - */ - void zero(); - - /** - * @brief Set vector components - * @param x X component - * @param y Y component - * @param z Z component - */ - void set_values(double x, double y, double z); - - /** - * @brief Multiply vector by scalar - * @param alpha Scalar multiplier - */ - void scalar_mult(double alpha); - - /** - * @brief Make the vector a unit vector - */ - void make_unit(); - - /** - * @brief Compute Euclidean vector norm - * @return Euclidean norm - */ - double norm() const; - - /** - * @brief Const access operator - * @param idx Component index (0=x, 1=y, 2=z) - * @return Const reference to component - */ - const double &operator[](int idx) const; - - /** - * @brief Access operator - * @param idx Component index (0=x, 1=y, 2=z) - * @return Reference to component - */ - double &operator[](int idx); - - /** - * @brief Stream output operator - * @param os Output stream - * @param x Vector to output - * @return Reference to output stream - */ - friend std::ostream &operator<<(std::ostream &os, const glm::dvec3 &x); - - double data[3]; - -private: -}; - -class Matrix3d -{ -public: - /** - * @brief Default constructor - initializes to zero matrix - */ - Matrix3d(); - ~Matrix3d(); - - /** - * @brief Set matrix element value - * @param i Row index (0-2) - * @param j Column index (0-2) - * @param val Value to set - */ - void set_value(int i, int j, double val); - - /** - * @brief Get matrix element value - * @param i Row index (0-2) - * @param j Column index (0-2) - * @return Matrix element value - */ - double get_value(int i, int j) const; - - /** - * @brief Set all matrix elements to zero - */ - void zero(); - - /** - * @brief Set matrix to identity (diagonal = 1, off-diagonal = 0) - */ - void identity(); - - // double data[9]; - double data[3][3]; - - friend std::ostream &operator<<(std::ostream &os, const Matrix3d &A); - -private: -}; - -inline void vector_copy(double data[3], const glm::dvec3 &x) -{ - CopyVec3(data, x.data); - return; -} -inline void vector_copy(std::vector &dest, const glm::dvec3 &x) -{ - CopyVec3(dest, x.data); - return; -} - -inline void matrix_copy(double data[3][3], const Matrix3d &A) -{ - CopyMat3(data, A.data); - return; -} - -// Compute y = A*x placing the result in y -void matrix_vector_product(const Matrix3d &A, const glm::dvec3 &x, glm::dvec3 &y); -// Compute C = A * B placing result in C -void matrix_matrix_product(const Matrix3d &A, const Matrix3d &B, Matrix3d &C); - -// Compute z = a*x + b*y (result stored in z) -void vector_add(double a, const glm::dvec3 &x, - double b, const glm::dvec3 &y, - glm::dvec3 &z); -/** - * @brief Compute linear combination y = a*x + b*y (result stored in y) - * @param a Scalar multiplier for vector x - * @param x First vector - * @param b Scalar multiplier for vector y - * @param y Second vector (modified in-place with result) - */ -void vector_add(double a, const glm::dvec3 &x, - double b, glm::dvec3 &y); - -/** - * @brief Compute element-wise maximum of two vectors - * @param x First vector - * @param y Second vector - * @param max Output vector containing element-wise maximum - */ -void vector_max(const glm::dvec3 &x, const glm::dvec3 &y, glm::dvec3 &max); - -/** - * @brief Compute element-wise minimum of two vectors - * @param x First vector - * @param y Second vector - * @param min Output vector containing element-wise minimum - */ -void vector_min(const glm::dvec3 &x, const glm::dvec3 &y, glm::dvec3 &min); - -/** - * @brief Compute standard Euclidean dot product - * @param x First vector - * @param y Second vector - * @return Dot product x·y - */ -double dot_product(const glm::dvec3 &x, const glm::dvec3 &y); - -/** - * @brief Compute standard Euclidean cross product - * @param u First vector - * @param v Second vector - * @param w Result vector - */ -void cross_product(const glm::dvec3 &u, const glm::dvec3 &v, glm::dvec3 &w); - -double error(const glm::dvec3 &u, const glm::dvec3 &v); -double error_inf(const glm::dvec3 &u, const glm::dvec3 &v); - -/** - * @brief Compute Euclidean norm (length) of vector - * @param x Input vector - * @return ||x||₂ (L2 norm) - */ -double vector_norm(const glm::dvec3 &x); - -/** - * @brief Normalize vector to unit length (modifies vector in-place) - * @param x Vector to normalize - */ -void make_unit_vector(glm::dvec3 &x); -// void transform_to_local(glm::dvec3 &pos_ref, -// glm::dvec3 &cos_ref, -// glm::dvec3 &origin, -// Matrix3d &ref_to_local, -// glm::dvec3 &pos_local, -// glm::dvec3 &cos_local); -// void transform_to_reference(glm::dvec3 &pos_local, -// glm::dvec3 &cos_local, -// glm::dvec3 &origin, -// Matrix3d &local_to_ref, -// glm::dvec3 &pos_ref, -// glm::dvec3 &cos_ref); - -/** - * @brief Compute transformation matrices from Euler angles - * @param euler Euler angles vector [rotation_x, rotation_y, rotation_z] in radians - * @param ref_to_local Output matrix for reference-to-local transformation - * @param local_to_ref Output matrix for local-to-reference transformation - */ -void compute_transform_matrices(glm::dvec3 &euler, - Matrix3d &ref_to_local, - Matrix3d &local_to_ref); - -} // namespace SolTrace::Data - -/** - * @} - */ -#endif - -#endif diff --git a/coretrace/simulation_runner/optix_runner/optix_runner.cpp b/coretrace/simulation_runner/optix_runner/optix_runner.cpp index 8b9fe765..a732842b 100644 --- a/coretrace/simulation_runner/optix_runner/optix_runner.cpp +++ b/coretrace/simulation_runner/optix_runner/optix_runner.cpp @@ -191,9 +191,8 @@ RunnerStatus OptixRunner::report_simulation(SimulationResult *result, return RunnerStatus::SUCCESS; } -OptixCSP::Vec3d OptixRunner::ToVec3d(Vector3d v) +OptixCSP::Vec3d OptixRunner::ToVec3d(glm::dvec3 v) { - - OptixCSP::Vec3d vec(v[0], v[1], v[2]); + OptixCSP::Vec3d vec(v.x, , v.y, v.z); return vec; } diff --git a/coretrace/simulation_runner/optix_runner/optix_runner.hpp b/coretrace/simulation_runner/optix_runner/optix_runner.hpp index 9d53b7ca..8d80d24e 100644 --- a/coretrace/simulation_runner/optix_runner/optix_runner.hpp +++ b/coretrace/simulation_runner/optix_runner/optix_runner.hpp @@ -47,7 +47,7 @@ class OptixRunner : public SolTrace::Runner::SimulationRunner const SolTrace::Data::SimulationData *data); // helper function, convert Vector3d to Optix::Vec3d - OptixCSP::Vec3d ToVec3d(SolTrace::Data::Vector3d v); + OptixCSP::Vec3d ToVec3d(glm::dvec3 v); }; #endif From 20ffa4e8a780194434f0c9fa55653598767baaa0 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sat, 24 Jan 2026 15:00:09 -0700 Subject: [PATCH 07/23] Compile fixes for optix --- coretrace/simulation_data/ray_source.hpp | 2 ++ .../optix_runner/optix_runner.cpp | 6 ++--- .../optix_runner/gpu_tower_demo.cpp | 25 ++++++++----------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/coretrace/simulation_data/ray_source.hpp b/coretrace/simulation_data/ray_source.hpp index 5387499e..ba560564 100644 --- a/coretrace/simulation_data/ray_source.hpp +++ b/coretrace/simulation_data/ray_source.hpp @@ -13,6 +13,8 @@ #include #include +#include +#include #include diff --git a/coretrace/simulation_runner/optix_runner/optix_runner.cpp b/coretrace/simulation_runner/optix_runner/optix_runner.cpp index a732842b..4f829eff 100644 --- a/coretrace/simulation_runner/optix_runner/optix_runner.cpp +++ b/coretrace/simulation_runner/optix_runner/optix_runner.cpp @@ -84,8 +84,8 @@ RunnerStatus OptixRunner::setup_elements(const SimulationData *data) if (el->is_enabled()) { auto optix_el = std::make_shared(); - Vector3d origin = el->get_origin_global(); - OptixCSP::Vec3d origin_vec(origin[0], origin[1], origin[2]); + auto origin = el->get_origin_global(); + OptixCSP::Vec3d origin_vec(origin.x, origin.y, origin.z); optix_el->set_origin(ToVec3d(origin)); optix_el->set_aim_point(ToVec3d(el->get_aim_vector_global())); @@ -193,6 +193,6 @@ RunnerStatus OptixRunner::report_simulation(SimulationResult *result, OptixCSP::Vec3d OptixRunner::ToVec3d(glm::dvec3 v) { - OptixCSP::Vec3d vec(v.x, , v.y, v.z); + OptixCSP::Vec3d vec(v.x, v.y, v.z); return vec; } diff --git a/google-tests/unit-tests/simulation_runner/optix_runner/gpu_tower_demo.cpp b/google-tests/unit-tests/simulation_runner/optix_runner/gpu_tower_demo.cpp index a60e0321..dc8af7a4 100644 --- a/google-tests/unit-tests/simulation_runner/optix_runner/gpu_tower_demo.cpp +++ b/google-tests/unit-tests/simulation_runner/optix_runner/gpu_tower_demo.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -67,8 +66,8 @@ TEST(GpuTowerDemo, OptixRunnerWithStages) st0->set_aim_vector(0.0, 0.0, 1.0); st0->set_name("Stage 0--Reflectors"); - Vector3d rvec, svec, avec; - Vector3d aim, pos; + glm::dvec3 rvec, svec, avec; + glm::dvec3 aim, pos; double spacing = PI / 4.0; @@ -78,19 +77,15 @@ TEST(GpuTowerDemo, OptixRunnerWithStages) foptics = el->get_front_optical_properties(); foptics->reflectivity = 1.0; - pos.set_values(5 * sin(i * spacing), - 5 * cos(i * spacing), - 0.0); + pos = {5 * sin(i * spacing), + 5 * cos(i * spacing), + 0.0}; el->set_origin(pos); - vector_add(1.0, absorber->get_origin_global(), - -1.0, pos, - rvec); - make_unit_vector(rvec); - svec = sun->get_position(); - make_unit_vector(svec); - vector_add(0.5, rvec, 0.5, svec, avec); - - vector_add(1.0, pos, 100.0, avec, aim); + rvec = glm::normalize(absorber->get_origin_global() - pos); + svec = glm::normalize(sun->get_position()); + avec = 0.5 * rvec + 0.5 * svec; + + aim = pos + 100.0 * avec; el->set_aim_vector(aim); // TODO: Set zrot as in python file? From 599c005e317f1bfa1a9b56541dee794a8ee5b579 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sat, 24 Jan 2026 15:02:42 -0700 Subject: [PATCH 08/23] More detail for gcc issues --- google-tests/unit-tests/common/common.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/google-tests/unit-tests/common/common.cpp b/google-tests/unit-tests/common/common.cpp index d7302ff0..1b717222 100644 --- a/google-tests/unit-tests/common/common.cpp +++ b/google-tests/unit-tests/common/common.cpp @@ -38,7 +38,14 @@ bool is_identical(const glm::dmat3 &A, const glm::dmat3 &B) } } - return maxAbs < 1E-300; + bool check = maxAbs < 1E-300; + + if (!check) { + std::cout << "Matrix not equal: A = " << A << ", B = " << B << std::endl; + std::cout << "Tolerance = " << maxAbs << std::endl; + } + + return check; } element_ptr make_configured_element() From 5f4688130785853dba23049db1e3e70cc52888ba Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sat, 24 Jan 2026 15:04:06 -0700 Subject: [PATCH 09/23] Uninitialized read in gcc --- .../unit-tests/simulation_data/linear_algebra_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp index eee27129..1f9bc143 100644 --- a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp +++ b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp @@ -133,7 +133,7 @@ TEST(LinearAlgebra, MatrixVectorProduct) TEST(LinearAlgebra, MatrixMatrixProduct) { - glm::dmat3 A; + glm::dmat3 A = {0.0}; A[1][0] = 1.0; A[2][0] = 2.0; A[0][1] = -1.0; @@ -141,7 +141,7 @@ TEST(LinearAlgebra, MatrixMatrixProduct) A[0][2] = 2.0; A[2][2] = 1.0; - glm::dmat3 B; + glm::dmat3 B = {0.0}; B[0][0] = -1.0; B[1][0] = 1.0; B[1][1] = 1.0; From ef138315527124f873ac20c412b5eeff4ca5cfca Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sat, 24 Jan 2026 15:48:42 -0700 Subject: [PATCH 10/23] Fix uninit and duration test --- .../regression-tests/native_runner_validation_test.cpp | 5 +++++ .../unit-tests/simulation_data/linear_algebra_test.cpp | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/google-tests/regression-tests/native_runner_validation_test.cpp b/google-tests/regression-tests/native_runner_validation_test.cpp index ac77cb39..05be9ca9 100644 --- a/google-tests/regression-tests/native_runner_validation_test.cpp +++ b/google-tests/regression-tests/native_runner_validation_test.cpp @@ -510,7 +510,12 @@ TEST(NativeRunner, ValidationTest2) EXPECT_EQ(sts, RunnerStatus::SUCCESS); std::chrono::duration dur = t1 - t0; +#ifdef NDEBUG EXPECT_TRUE(dur.count() < 75000.0); +#else + // Debug builds can go very slowly on some machines and compilers + EXPECT_TRUE(dur.count() < 250000.0); +#endif std::cout << "Time: " << dur.count() << " ms" << std::endl; diff --git a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp index 1f9bc143..be93c14c 100644 --- a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp +++ b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp @@ -166,8 +166,8 @@ TEST(LinearAlgebra, CoordinateTransforms) { // TODO: Implement tests for compute_transform_matrices, // transform_to_local, and transform_to_reference functions - glm::dmat3 A; - glm::dmat3 B; + glm::dmat3 A = {0.0}; + glm::dmat3 B = {0.0}; EXPECT_TRUE(is_identical(A, B)); } From 09db2d4d47aaf45028540345425a835b2dddb6aa Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sun, 25 Jan 2026 06:33:38 -0700 Subject: [PATCH 11/23] Bump test timing. Another uninit. --- google-tests/regression-tests/native_runner_validation_test.cpp | 2 +- google-tests/unit-tests/simulation_data/linear_algebra_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/google-tests/regression-tests/native_runner_validation_test.cpp b/google-tests/regression-tests/native_runner_validation_test.cpp index 05be9ca9..f99f0586 100644 --- a/google-tests/regression-tests/native_runner_validation_test.cpp +++ b/google-tests/regression-tests/native_runner_validation_test.cpp @@ -514,7 +514,7 @@ TEST(NativeRunner, ValidationTest2) EXPECT_TRUE(dur.count() < 75000.0); #else // Debug builds can go very slowly on some machines and compilers - EXPECT_TRUE(dur.count() < 250000.0); + EXPECT_TRUE(dur.count() < 300000.0); #endif std::cout << "Time: " << dur.count() << " ms" << std::endl; diff --git a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp index be93c14c..010cc002 100644 --- a/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp +++ b/google-tests/unit-tests/simulation_data/linear_algebra_test.cpp @@ -148,7 +148,7 @@ TEST(LinearAlgebra, MatrixMatrixProduct) B[2][1] = -2.0; B[2][2] = 1.0; - glm::dmat3 Ctrue; + glm::dmat3 Ctrue = {0.0}; Ctrue[1][0] = 1.0; Ctrue[0][1] = 1.0; Ctrue[2][1] = -2.0; From 6da668acee494d5dd819a0aa5da9e693d85fb2a0 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sun, 8 Feb 2026 09:50:28 -0700 Subject: [PATCH 12/23] Update gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index a0af2623..b9915692 100644 --- a/.gitignore +++ b/.gitignore @@ -317,3 +317,7 @@ build* google-tests/*.stinput google-tests/*.mon google-tests/*.csv + +**/*.DS_Store +**/strace +**/straced \ No newline at end of file From c8dbb1585154ca967ee508bf43de7be834b10e6a Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sun, 8 Feb 2026 11:46:19 -0700 Subject: [PATCH 13/23] Multiple fixes to compile and execute - Fix unconditional embree include - Fix broken merge - Update CI to remove Debug --- .github/workflows/CI.yml | 2 +- coretrace/simulation_data/CMakeLists.txt | 4 - .../determine_interaction_type.cpp | 21 +- .../determine_interaction_type.hpp | 4 +- .../native_runner/native_runner_types.hpp | 26 +- .../native_runner/sun_to_primary_stage.hpp | 2 +- .../simulation_runner/native_runner/trace.cpp | 1205 ++++++++--------- .../native_runner_validation_test.cpp | 3 - .../cst-templates/CMakeLists.txt | 9 +- .../cst-templates/heliostat_field_test.cpp | 89 +- .../cst-templates/single_heliostat_test.cpp | 23 +- .../simulation_data/utilities_test.cpp | 2 - 12 files changed, 666 insertions(+), 724 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 56b6cdb6..2f1d7112 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -24,7 +24,7 @@ jobs: # To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list. matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - build_type: [Release, Debug] + build_type: [Release, RelWithDebInfo] c_compiler: [gcc, clang, cl] include: - os: windows-latest diff --git a/coretrace/simulation_data/CMakeLists.txt b/coretrace/simulation_data/CMakeLists.txt index 3429e317..a9becca7 100644 --- a/coretrace/simulation_data/CMakeLists.txt +++ b/coretrace/simulation_data/CMakeLists.txt @@ -31,11 +31,7 @@ set(SIMDATA_SRC stage_element.cpp sun.cpp surface.cpp -<<<<<<< HEAD -======= utilities.cpp - vector3d.cpp ->>>>>>> origin/develop virtual_element.cpp cst_templates/arclength.cpp cst_templates/heliostat.cpp diff --git a/coretrace/simulation_runner/native_runner/determine_interaction_type.cpp b/coretrace/simulation_runner/native_runner/determine_interaction_type.cpp index 0170a357..39ce2b6c 100644 --- a/coretrace/simulation_runner/native_runner/determine_interaction_type.cpp +++ b/coretrace/simulation_runner/native_runner/determine_interaction_type.cpp @@ -12,22 +12,21 @@ namespace SolTrace::NativeRunner { using SolTrace::Result::RayEvent; - bool determine_interaction_type( - trace_logger_ptr logger, - int_fast64_t stage, - unsigned thread_id, - MTRand &myrng, - const OpticalProperties *optics, - const double (&LastDFXYZ)[3], - const double (&LastCosRaySurfElement)[3], - // bool LastHitBackSide, - RayEvent &rev) + bool determine_interaction_type(trace_logger_ptr logger, + int_fast64_t stage, + unsigned thread_id, + MTRand &myrng, + const OpticalProperties *optics, + const glm::dvec3 &LastDFXYZ, + const glm::dvec3 &LastCosRaySurfElement, + // bool LastHitBackSide, + RayEvent &rev) { bool good = true; rev = RayEvent::VIRTUAL; double TestValue; - double UnitLastDFXYZ[3] = {0.0, 0.0, 0.0}; + auto UnitLastDFXYZ = glm::dvec3{0.0}; double IncidentAngle = 0; // TODO: Implement tables... switch (optics->my_type) diff --git a/coretrace/simulation_runner/native_runner/determine_interaction_type.hpp b/coretrace/simulation_runner/native_runner/determine_interaction_type.hpp index d05def09..95a6e309 100644 --- a/coretrace/simulation_runner/native_runner/determine_interaction_type.hpp +++ b/coretrace/simulation_runner/native_runner/determine_interaction_type.hpp @@ -17,8 +17,8 @@ namespace SolTrace::NativeRunner unsigned thread_id, MTRand &myrng, const SolTrace::Data::OpticalProperties *optics, - const double (&LastDFXYZ)[3], - const double (&LastCosRaySurfElement)[3], + glm::dvec3 const& LastDFXYZ, + glm::dvec3 const& LastCosRaySurfElement, // bool LastHitBackSide, SolTrace::Result::RayEvent &rev); diff --git a/coretrace/simulation_runner/native_runner/native_runner_types.hpp b/coretrace/simulation_runner/native_runner/native_runner_types.hpp index 87cb9a1f..77fa688e 100644 --- a/coretrace/simulation_runner/native_runner/native_runner_types.hpp +++ b/coretrace/simulation_runner/native_runner/native_runner_types.hpp @@ -69,23 +69,15 @@ namespace SolTrace::NativeRunner { - class GlobalRay_refactored - { - public: - GlobalRay_refactored() // : active(true) - { - Num = 0; - for (int i = 0; i < 3; i++) - Pos[i] = Cos[i] = 0.0; - } - - double Pos[3]; - double Cos[3]; - uint_fast64_t Num; - // bool active; - }; - - // #define ACOSM1O180 0.017453292519943295 // acos(-1)/180.0 + struct GlobalRay_refactored + { + glm::dvec3 Pos = glm::dvec3{0}; + glm::dvec3 Cos = glm::dvec3{0}; + uint_fast64_t Num = 0; + // bool active; + }; + + // #define ACOSM1O180 0.017453292519943295 // acos(-1)/180.0 // #endif // class nanexcept : public std::exception diff --git a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp index 37b5643f..c4dec33d 100644 --- a/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp +++ b/coretrace/simulation_runner/native_runner/sun_to_primary_stage.hpp @@ -8,7 +8,7 @@ namespace SolTrace::NativeRunner { bool SunToPrimaryStage( - thread_manager_ptr manager, + trace_logger_ptr logger, TSystem *System, TStage *Stage, TSun *Sun, diff --git a/coretrace/simulation_runner/native_runner/trace.cpp b/coretrace/simulation_runner/native_runner/trace.cpp index 3dfc2bed..6e53e698 100644 --- a/coretrace/simulation_runner/native_runner/trace.cpp +++ b/coretrace/simulation_runner/native_runner/trace.cpp @@ -79,665 +79,602 @@ namespace SolTrace::NativeRunner { - using SolTrace::Result::RayEvent; - using SolTrace::Runner::RunnerStatus; - - // Trace method - RunnerStatus trace_native( - thread_manager_ptr manager, - trace_logger_ptr logger, - TSystem *System, - const std::vector &seeds, - unsigned nthreads, - uint_fast64_t NumberOfRays, - uint_fast64_t MaxNumberOfRays, - bool IncludeSunShape, - bool IncludeErrors, - bool AsPowerTower) - { - // Initialize Sun - glm::dvec3 PosSunStage; - if (!SunToPrimaryStage(logger, - System, - System->StageList[0].get(), - &System->Sun, - PosSunStage)) - return RunnerStatus::ERROR; - - // Determine if PT optimizations should be applied - bool PT_override = false; - if (System->StageList.size() > 0 && - (System->StageList[0]->ElementList.size() < 10 || System->StageList.size() == 1)) - { - PT_override = true; - } - - // Calculate hash tree for reflection to receiver plane(polar coordinates). - st_hash_tree sun_hash; - st_hash_tree rec_hash; - // double reccm_helio[3]; // receiver centroid in heliostat field coordinates - glm::dvec3 reccm_helio; - if (!PT_override) - { - SetupPTOptimizations(System, AsPowerTower, sun_hash, rec_hash, reccm_helio); +using SolTrace::Result::RayEvent; +using SolTrace::Runner::RunnerStatus; + +// Trace method +RunnerStatus trace_native( + thread_manager_ptr manager, + trace_logger_ptr logger, + TSystem *System, + const std::vector &seeds, + unsigned nthreads, + uint_fast64_t NumberOfRays, + uint_fast64_t MaxNumberOfRays, + bool IncludeSunShape, + bool IncludeErrors, + bool AsPowerTower) +{ + // Initialize Sun + glm::dvec3 PosSunStage; + if (!SunToPrimaryStage(logger, + System, + System->StageList[0].get(), + &System->Sun, + PosSunStage)) + return RunnerStatus::ERROR; + + // Determine if PT optimizations should be applied + bool PT_override = false; + if (System->StageList.size() > 0 && + (System->StageList[0]->ElementList.size() < 10 || System->StageList.size() == 1)) + { + PT_override = true; + } + + // Calculate hash tree for reflection to receiver plane(polar coordinates). + st_hash_tree sun_hash; + st_hash_tree rec_hash; + // double reccm_helio[3]; // receiver centroid in heliostat field coordinates + glm::dvec3 reccm_helio; + if (!PT_override) + { + SetupPTOptimizations(System, AsPowerTower, sun_hash, + rec_hash, reccm_helio); + } + + // Bundle many args into a struct because the compiler was + // having trouble with all the arguments... + ThreadInfo my_info; + my_info.manager = manager; + my_info.logger = logger; + my_info.System = System; + // my_info.NumberOfRays = NumberOfRays / nthreads; + uint_fast64_t rem = NumberOfRays % nthreads; + uint_fast64_t nrays_per_thread = NumberOfRays / nthreads; + + my_info.MaxNumberOfRays = MaxNumberOfRays / nthreads + 1; + my_info.IncludeSunShape = IncludeSunShape; + my_info.IncludeErrors = IncludeErrors; + my_info.AsPowerTower = AsPowerTower; + my_info.PosSunStage = PosSunStage; + my_info.sun_hash = &sun_hash; + my_info.rec_hash = &rec_hash; + my_info.reccm_helio = reccm_helio; + + System->RayData.SetUp(nthreads, NumberOfRays); + System->SunRayCount = 0; + + for (unsigned int k = 0; k < nthreads; ++k) + { + my_info.NumberOfRays = (k < rem + ? nrays_per_thread + 1 + : nrays_per_thread); + + ThreadManager::future my_future = std::async( + std::launch::async, + trace_single_compact, + k, + seeds[k], + my_info); + + manager->manage(k, std::move(my_future)); + } + + return manager->monitor_until_completion(); +} + +RunnerStatus trace_single_thread( + unsigned thread_id, + thread_manager_ptr manager, + trace_logger_ptr logger, + TSystem *System, + unsigned int seed, + uint_fast64_t NumberOfRays, + uint_fast64_t MaxNumberOfRays, + bool IncludeSunShape, + bool IncludeErrors, + bool AsPowerTower, + const glm::dvec3 &PosSunStage, + st_hash_tree *sun_hash, + st_hash_tree *rec_hash, + const glm::dvec3 &reccm_helio) +{ + // Initialize variables + MTRand myrng(seed); + + // std::stringstream ss; + // ss << "Thread " << thread_id + // << " tracing " << NumberOfRays << " rays" + // << std::endl; + // std::cout << ss.str(); + + // Determine if PT optimizations should be applied + bool PT_override = false; + if (System->StageList.size() > 0 && + (System->StageList[0]->ElementList.size() < 10 || + System->StageList.size() == 1)) + { + PT_override = true; + } + + uint_fast64_t update_rate = std::min( + std::max(static_cast(1), NumberOfRays / 10), + static_cast(1000)); + uint_fast64_t update_count = 0; + double total_work = System->StageList.size() * NumberOfRays; + + // Initialize Internal State Variables + uint_fast64_t RayNumber = 1; // Ray Number of current ray + bool PreviousStageHasRays = false; + uint_fast64_t LastRayNumberInPreviousStage = NumberOfRays; + + // Define IncomingRays + std::vector IncomingRays; // Vector of rays from previous stage, going into next stage + IncomingRays.resize(NumberOfRays); + + // Initialize stage variables + uint_fast64_t StageDataArrayIndex = 0; + uint_fast64_t PreviousStageDataArrayIndex = 0; + uint_fast64_t n_rays_active = NumberOfRays; + uint_fast64_t sun_ray_count_local = 0; + + // Loop through stages + for (uint_fast64_t i = 0; i < System->StageList.size(); i++) + { + // std::cout << "Processing stage " << i << "..." << std::endl; + // Check if previous stage has rays + bool StageHasRays = true; + if (i > 0 && PreviousStageHasRays == false) + { + StageHasRays = false; } - // Bundle many args into a struct because the compiler was - // having trouble with all the arguments... - ThreadInfo my_info; - my_info.manager = manager; - my_info.logger = logger; - my_info.System = System; - // my_info.NumberOfRays = NumberOfRays / nthreads; - uint_fast64_t rem = NumberOfRays % nthreads; - uint_fast64_t nrays_per_thread = NumberOfRays / nthreads; - - my_info.MaxNumberOfRays = MaxNumberOfRays / nthreads + 1; - my_info.IncludeSunShape = IncludeSunShape; - my_info.IncludeErrors = IncludeErrors; - my_info.AsPowerTower = AsPowerTower; - my_info.PosSunStage = PosSunStage; - my_info.sun_hash = &sun_hash; - my_info.rec_hash = &rec_hash; - my_info.reccm_helio = reccm_helio; - - System->RayData.SetUp(nthreads, NumberOfRays); - System->SunRayCount = 0; - - for (unsigned int k = 0; k < nthreads; ++k) - { - my_info.NumberOfRays = (k < rem - ? nrays_per_thread + 1 - : nrays_per_thread); - - ThreadManager::future my_future = std::async( - std::launch::async, - trace_single_compact, - k, - seeds[k], - my_info); - - manager->manage(k, std::move(my_future)); - } - - return manager->monitor_until_completion(); - } - - RunnerStatus trace_single_thread( - unsigned thread_id, - thread_manager_ptr manager, - trace_logger_ptr logger, - TSystem *System, - unsigned int seed, - uint_fast64_t NumberOfRays, - uint_fast64_t MaxNumberOfRays, - bool IncludeSunShape, - bool IncludeErrors, - bool AsPowerTower, - const glm::dvec3 &PosSunStage, - st_hash_tree *sun_hash, - st_hash_tree *rec_hash, - const glm::dvec3 &reccm_helio) - { - // Initialize variables - MTRand myrng(seed); - - // std::stringstream ss; - // ss << "Thread " << thread_id - // << " tracing " << NumberOfRays << " rays" - // << std::endl; - // std::cout << ss.str(); - - // Determine if PT optimizations should be applied - bool PT_override = false; - if (System->StageList.size() > 0 && - (System->StageList[0]->ElementList.size() < 10 || - System->StageList.size() == 1)) - { - PT_override = true; - } - - uint_fast64_t update_rate = std::min( - std::max(static_cast(1), NumberOfRays / 10), - static_cast(1000)); - uint_fast64_t update_count = 0; - double total_work = System->StageList.size() * NumberOfRays; - - // Initialize Internal State Variables - uint_fast64_t RayNumber = 1; // Ray Number of current ray - bool PreviousStageHasRays = false; - uint_fast64_t LastRayNumberInPreviousStage = NumberOfRays; - - // Define IncomingRays - std::vector IncomingRays; // Vector of rays from previous stage, going into next stage - IncomingRays.resize(NumberOfRays); - - // Initialize stage variables - uint_fast64_t StageDataArrayIndex = 0; - uint_fast64_t PreviousStageDataArrayIndex = 0; - uint_fast64_t n_rays_active = NumberOfRays; - uint_fast64_t sun_ray_count_local = 0; - - // Loop through stages - for (uint_fast64_t i = 0; i < System->StageList.size(); i++) { - // std::cout << "Processing stage " << i << "..." << std::endl; - // Check if previous stage has rays - bool StageHasRays = true; - if (i > 0 && PreviousStageHasRays == false) - { - StageHasRays = false; - } - - // Get Current Stage - tstage_ptr Stage = System->StageList[i]; - - // Initialize stage variables - StageDataArrayIndex = 0; - PreviousStageDataArrayIndex = 0; - - // Loop through rays - while (StageHasRays) - { - // Initialize Global Coordinates - glm::dvec3 PosRayGlob(0.0); - glm::dvec3 CosRayGlob(0.0); - - // Initialize Stage Coordinates - glm::dvec3 PosRayStage(0.0); - glm::dvec3 CosRayStage(0.0); - - // Initialize PT Optimization variables - bool has_elements = true; - std::vector sunint_elements; - - // Get Ray - if (i == 0) - { - // TODO: This function seems to ignore the MaxNumberOfRays - // argument. Should fix that. - - // Make ray (if first stage) - glm::dvec3 PosRaySun; - GenerateRay(myrng, - PosSunStage, - Stage->Origin, - Stage->RLocToRef, - &System->Sun, - PosRayGlob, - CosRayGlob, - PosRaySun); - sun_ray_count_local++; - - // If using PT optimizations, check if stage has elements - // that could interact with ray - if (!PT_override) - { - has_elements = sun_hash->get_all_data_at_loc(sunint_elements, - PosRaySun.x, - PosRaySun.y); + // Get Current Stage + tstage_ptr Stage = System->StageList[i]; + + // Initialize stage variables + StageDataArrayIndex = 0; + PreviousStageDataArrayIndex = 0; + + // Loop through rays + while (StageHasRays) + { + // Initialize Global Coordinates + glm::dvec3 PosRayGlob = {0.0, 0.0, 0.0}; + glm::dvec3 CosRayGlob = {0.0, 0.0, 0.0}; + + // Initialize Stage Coordinates + glm::dvec3 PosRayStage = {0.0, 0.0, 0.0}; + glm::dvec3 CosRayStage = {0.0, 0.0, 0.0}; + + // Initialize PT Optimization variables + bool has_elements = true; + std::vector sunint_elements; + + // Get Ray + if (i == 0) + { + // TODO: This function seems to ignore the MaxNumberOfRays + // argument. Should fix that. + + // Make ray (if first stage) + glm::dvec3 PosRaySun; + GenerateRay(myrng, PosSunStage, Stage->Origin, + Stage->RLocToRef, &System->Sun, + PosRayGlob, CosRayGlob, PosRaySun); + sun_ray_count_local++; + + // If using PT optimizations, check if stage has elements + // that could interact with ray + if (!PT_override) + { + has_elements = + sun_hash->get_all_data_at_loc(sunint_elements, + PosRaySun.x, + PosRaySun.y); + } + } + else + { + // Get ray from previous stage + RayNumber = IncomingRays[StageDataArrayIndex].Num; + PosRayGlob = IncomingRays[StageDataArrayIndex].Pos; + CosRayGlob = IncomingRays[StageDataArrayIndex].Cos; + StageDataArrayIndex++; + } + + // transform the global incoming ray to local stage coordinates + TransformToLocal(PosRayGlob, CosRayGlob, + Stage->Origin, Stage->RRefToLoc, + PosRayStage, CosRayStage); + + // Initialize internal variables for ray intersection tracing + bool RayInStage = true; + bool in_multi_hit_loop = false; + + glm::dvec3 LastPosRaySurfElement(0.0); + glm::dvec3 LastCosRaySurfElement(0.0); + glm::dvec3 LastPosRaySurfStage(0.0); + glm::dvec3 LastCosRaySurfStage(0.0); + glm::dvec3 LastDFXYZ(0.0); + + uint_fast64_t LastElementNumber = 0; + uint_fast64_t LastRayNumber = 0; + + int ErrorFlag; + int LastHitBackSide; + bool StageHit; + int MultipleHitCount = 0; + + glm::dvec3 PosRayOutElement(0.0); + glm::dvec3 CosRayOutElement(0.0); + + + // Start Loop to trace ray until it leaves stage + bool RayIsAbsorbed = false; + while (RayInStage) + { + // Set number of elements to search through + uint_fast64_t nintelements = 0; + std::vector reflint_elements; + if (!PT_override) // if using opt AND first stage + { + nintelements = GetPTElements(AsPowerTower, Stage, i, + in_multi_hit_loop, PosRayStage, + reccm_helio, rec_hash, + sunint_elements, + reflint_elements, has_elements); + } + else + { + nintelements = Stage->ElementList.size(); + } + + // Find the element the ray hits + FindElementHit(i, Stage, PT_override, AsPowerTower, + nintelements, sunint_elements, + reflint_elements, + RayNumber, in_multi_hit_loop, + PosRayStage, CosRayStage, + LastPosRaySurfElement, + LastCosRaySurfElement, + LastDFXYZ, + LastElementNumber, LastRayNumber, + LastPosRaySurfStage, LastCosRaySurfStage, + ErrorFlag, LastHitBackSide, StageHit); + + // Breakout if ray left stage + if (!StageHit) + { + RayInStage = false; + break; + } + + // Increment MultipleHitCount + MultipleHitCount++; + + if (i == 0 && MultipleHitCount == 1) + { + auto r = System->RayData.Append(thread_id, + PosRayGlob, + CosRayGlob, + ELEMENT_NULL, + i + 1, + LastRayNumber, + RayEvent::CREATE); + if (r == nullptr) + { + std::stringstream ss; + ss << "Thread " << thread_id + << " failed to record ray data.\n"; + logger->error_log(ss.str()); } - } else { - // Get ray from previous stage - RayNumber = IncomingRays[StageDataArrayIndex].Num; - PosRayGlob = IncomingRays[StageDataArrayIndex].Pos; - CosRayGlob = IncomingRays[StageDataArrayIndex].Cos; - StageDataArrayIndex++; } - // transform the global incoming ray to local stage coordinates - Data::TransformToLocal(PosRayGlob, + // Get optics and check for absorption + const OpticalProperties *optics = 0; + RayEvent rev = RayEvent::VIRTUAL; + if (Stage->Virtual) + { + // If stage is virtual, there is no interaction + PosRayOutElement = LastPosRaySurfElement; + CosRayOutElement = LastCosRaySurfElement; + } + else + { + // trace through the interaction + telement_ptr optelm = + Stage->ElementList[LastElementNumber - 1]; + + if (LastHitBackSide) + optics = &optelm->Optics.Back; + else + optics = &optelm->Optics.Front; + + bool good = determine_interaction_type( + logger, + i, + 0, + myrng, + optics, + LastDFXYZ, + LastCosRaySurfElement, + rev); + + if (!good) + { + return RunnerStatus::ERROR; + } + + if (rev == RayEvent::ABSORB) + { + RayIsAbsorbed = true; + break; + } + } + + // Process Interaction + int_fast64_t k = LastElementNumber - 1; + ProcessInteraction(System, + myrng, + IncludeSunShape, + optics, + IncludeErrors, + i, + Stage, + MultipleHitCount, + LastDFXYZ, + LastCosRaySurfElement, + ErrorFlag, + CosRayOutElement, + LastPosRaySurfElement, + PosRayOutElement); + + // Transform ray back to stage coordinate system + TransformToReference(PosRayOutElement, + CosRayOutElement, + Stage->ElementList[k]->Origin, + Stage->ElementList[k]->RLocToRef, + PosRayStage, + CosRayStage); + TransformToReference(PosRayStage, + CosRayStage, + Stage->Origin, + Stage->RLocToRef, + PosRayGlob, + CosRayGlob); + + System->RayData.Append(thread_id, + PosRayGlob, CosRayGlob, - Stage->Origin, - Stage->RRefToLoc, - PosRayStage, - CosRayStage); - - // Initialize internal variables for ray intersection tracing - bool RayInStage = true; - bool in_multi_hit_loop = false; - - glm::dvec3 LastPosRaySurfElement(0.0); - glm::dvec3 LastCosRaySurfElement(0.0); - glm::dvec3 LastPosRaySurfStage(0.0); - glm::dvec3 LastCosRaySurfStage(0.0); - glm::dvec3 LastDFXYZ(0.0); - - uint_fast64_t LastElementNumber = 0; - uint_fast64_t LastRayNumber = 0; - - int ErrorFlag; - int LastHitBackSide; - bool StageHit; - int MultipleHitCount = 0; - - glm::dvec3 PosRayOutElement(0.0); - glm::dvec3 CosRayOutElement(0.0); - - // Start Loop to trace ray until it leaves stage - bool RayIsAbsorbed = false; - while (RayInStage) { - // Set number of elements to search through - uint_fast64_t nintelements = 0; - std::vector reflint_elements; // TODO Hoist - if (!PT_override) // if using opt AND first stage + LastElementNumber, + i + 1, + LastRayNumber, + rev); + + // Break out if multiple hits are not allowed + if (!Stage->MultiHitsPerRay) + { + StageHit = false; + break; + } + else + { + in_multi_hit_loop = true; + } + } + + if (MultipleHitCount > 0) + ++update_count; + + if (update_count % update_rate == 0) + { + double progress = update_count / total_work; + manager->progress_update(thread_id, progress); + if (manager->terminate(thread_id)) + return RunnerStatus::CANCEL; + } + + // Handle if Ray was absorbed + if (RayIsAbsorbed) + { + TransformToReference(LastPosRaySurfStage, + LastCosRaySurfStage, + Stage->Origin, + Stage->RLocToRef, + PosRayGlob, + CosRayGlob); + + System->RayData.Append(thread_id, + PosRayGlob, + CosRayGlob, + LastElementNumber, + i + 1, + LastRayNumber, + RayEvent::ABSORB); + + n_rays_active--; + + // ray was fully absorbed + if (RayNumber == LastRayNumberInPreviousStage) + { + PreviousStageHasRays = false; + if (PreviousStageDataArrayIndex > 0) + { + PreviousStageDataArrayIndex--; + PreviousStageHasRays = true; + } + break; + } + else + { + if (i == 0) + { + if (RayNumber == NumberOfRays) + break; + else + RayNumber++; + } + + // Next ray in loop + continue; + } + } + + // Ray has left the stage + bool FlagMiss = false; + if (i == 0) + { + if (MultipleHitCount == 0) + { + // Ray in first stage missed stage entirely + // Generate new ray + continue; + } + else + { + // Ray hit an element, so save it for next stage + IncomingRays[PreviousStageDataArrayIndex].Pos = PosRayGlob; + IncomingRays[PreviousStageDataArrayIndex].Cos = CosRayGlob; + IncomingRays[PreviousStageDataArrayIndex].Num = RayNumber; + + // Is Ray the last in the stage? + if (RayNumber == NumberOfRays) { - nintelements = GetPTElements(AsPowerTower, - Stage, - i, - in_multi_hit_loop, - PosRayStage, - reccm_helio, - rec_hash, - sunint_elements, - reflint_elements, - has_elements); - } else { - nintelements = Stage->ElementList.size(); + StageHasRays = false; + break; } - // Find the element the ray hits - FindElementHit(i, Stage, PT_override, AsPowerTower, - nintelements, sunint_elements, - reflint_elements, - RayNumber, in_multi_hit_loop, - PosRayStage, CosRayStage, - LastPosRaySurfElement, - LastCosRaySurfElement, - LastDFXYZ, - LastElementNumber, LastRayNumber, - LastPosRaySurfStage, LastCosRaySurfStage, - ErrorFlag, LastHitBackSide, StageHit); - - // Breakout if ray left stage - if (!StageHit) { - RayInStage = false; + PreviousStageDataArrayIndex++; + PreviousStageHasRays = true; + + // Move on to next ray + RayNumber++; + continue; + } + } + else + { + // After the first stage + // Ray hit element OR is traced through stage + if (Stage->TraceThrough || MultipleHitCount > 0) + { + // Ray is saved for the next stage + IncomingRays[PreviousStageDataArrayIndex].Pos = PosRayGlob; + IncomingRays[PreviousStageDataArrayIndex].Cos = CosRayGlob; + IncomingRays[PreviousStageDataArrayIndex].Num = RayNumber; + + // Check if ray is last in stage + if (RayNumber == LastRayNumberInPreviousStage) + { + StageHasRays = false; break; } - // Increment MultipleHitCount - MultipleHitCount++; - - if (i == 0 && MultipleHitCount == 1) - { - auto r = System->RayData.Append(thread_id, - PosRayGlob, - CosRayGlob, - ELEMENT_NULL, - i + 1, - LastRayNumber, - RayEvent::CREATE); - if (r == nullptr) - { - std::stringstream ss; - ss << "Thread " << thread_id - << " failed to record ray data.\n"; - manager->error_log(ss.str()); - } - } - - // Get optics and check for absorption - const OpticalProperties *optics = 0; - RayEvent rev = RayEvent::VIRTUAL; - if (Stage->Virtual) - { - // If stage is virtual, there is no interaction - CopyVec3(PosRayOutElement, LastPosRaySurfElement); - CopyVec3(CosRayOutElement, LastCosRaySurfElement); - } - else - { - // trace through the interaction - telement_ptr optelm = Stage->ElementList[LastElementNumber - 1]; - - if (LastHitBackSide) - optics = &optelm->Optics.Back; - else - optics = &optelm->Optics.Front; - - double TestValue; - double UnitLastDFXYZ[3] = {0.0, 0.0, 0.0}; - double IncidentAngle = 0; - // switch (optelm->InteractionType) - switch (optics->my_type) - { - case InteractionType::REFRACTION: // refraction - // TODO: Implement transmissivity table? - // if (optics->UseTransmissivityTable) - // { - // int npoints = optics->TransmissivityTable.size(); - // int m = 0; - - // UnitLastDFXYZ[0] = -LastDFXYZ[0] / sqrt(DOT(LastDFXYZ, LastDFXYZ)); - // UnitLastDFXYZ[1] = -LastDFXYZ[1] / sqrt(DOT(LastDFXYZ, LastDFXYZ)); - // UnitLastDFXYZ[2] = -LastDFXYZ[2] / sqrt(DOT(LastDFXYZ, LastDFXYZ)); - // IncidentAngle = acos(DOT(LastCosRaySurfElement, UnitLastDFXYZ)) * 1000.; //[mrad] - // if (IncidentAngle >= optics->TransmissivityTable[npoints - 1].angle) - // { - // TestValue = optics->TransmissivityTable[npoints - 1].trans; - // } - // else - // { - // while (optics->TransmissivityTable[m].angle < IncidentAngle) - // m++; - - // if (m == 0) - // TestValue = optics->TransmissivityTable[m].trans; - // else - // TestValue = (optics->TransmissivityTable[m].trans + optics->TransmissivityTable[m - 1].trans) / 2.0; - // } - // } - // else - // TestValue = optics->Transmissivity; - TestValue = optics->transmitivity; - rev = RayEvent::TRANSMIT; - break; - case InteractionType::REFLECTION: // reflection - // TODO: Implement reflectivity table? - // if (optics->UseReflectivityTable) - // { - // int npoints = optics->ReflectivityTable.size(); - // int m = 0; - // UnitLastDFXYZ[0] = -LastDFXYZ[0] / sqrt(DOT(LastDFXYZ, LastDFXYZ)); - // UnitLastDFXYZ[1] = -LastDFXYZ[1] / sqrt(DOT(LastDFXYZ, LastDFXYZ)); - // UnitLastDFXYZ[2] = -LastDFXYZ[2] / sqrt(DOT(LastDFXYZ, LastDFXYZ)); - // IncidentAngle = acos(DOT(LastCosRaySurfElement, UnitLastDFXYZ)) * 1000.; //[mrad] - // if (IncidentAngle >= optics->ReflectivityTable[npoints - 1].angle) - // { - // TestValue = optics->ReflectivityTable[npoints - 1].refl; - // } - // else - // { - // while (optics->ReflectivityTable[m].angle < IncidentAngle) - // m++; - - // if (m == 0) - // TestValue = optics->ReflectivityTable[m].refl; - // else - // TestValue = (optics->ReflectivityTable[m].refl + optics->ReflectivityTable[m - 1].refl) / 2.0; - // } - // } - // else - // TestValue = optics->Reflectivity; - TestValue = optics->reflectivity; - rev = RayEvent::REFLECT; - break; - default: - std::stringstream ss; - ss << "Bad optical interaction." - << " Type: " << static_cast(optics->my_type) - << " Stage: " << i - << " Thread: " << thread_id - << "\n"; - manager->error_log(ss.str()); - return RunnerStatus::ERROR; - } - - if (rev == RayEvent::ABSORB) - { - RayIsAbsorbed = true; - break; - } + PreviousStageDataArrayIndex++; + PreviousStageHasRays = true; + + if (MultipleHitCount == 0) + { + FlagMiss = true; } - // Process Interaction - int_fast64_t k = LastElementNumber - 1; - ProcessInteraction(System, - myrng, - IncludeSunShape, - optics, - IncludeErrors, - i, - Stage, - MultipleHitCount, - LastDFXYZ, - LastCosRaySurfElement, - ErrorFlag, - CosRayOutElement, - LastPosRaySurfElement, - PosRayOutElement); - - // Transform ray back to stage coordinate system - Data::TransformToReference(PosRayOutElement, - CosRayOutElement, - Stage->ElementList[k]->Origin, - Stage->ElementList[k]->RLocToRef, - PosRayStage, - CosRayStage); - Data::TransformToReference(PosRayStage, - CosRayStage, - Stage->Origin, - Stage->RLocToRef, - PosRayGlob, - CosRayGlob); + // Go to next ray + continue; + } + // Ray missed stage entirely and is not traced + else + { + FlagMiss = true; + } + + // Handle FlagMiss condition ( + if (FlagMiss == true) + { + LastRayNumber = RayNumber; System->RayData.Append(thread_id, PosRayGlob, CosRayGlob, - LastElementNumber, + ELEMENT_NULL, i + 1, LastRayNumber, - rev); - - // Break out if multiple hits are not allowed - if (!Stage->MultiHitsPerRay) - { - StageHit = false; - break; - } - else - { - in_multi_hit_loop = true; - } - } + RayEvent::EXIT); - ++update_count; - if (update_count % update_rate == 0) - { - double progress = update_count / total_work; - manager->progress_update(thread_id, progress); - if (manager->terminate(thread_id)) - return RunnerStatus::CANCEL; + n_rays_active--; + + if (RayNumber == LastRayNumberInPreviousStage) + { + if (!Stage->TraceThrough) + { + PreviousStageHasRays = false; + if (PreviousStageDataArrayIndex > 0) + { + PreviousStageHasRays = true; + PreviousStageDataArrayIndex--; // last ray was previous one + } + } + + // Exit stage + StageHasRays = false; + break; + } + else + { + if (i == 0) + RayNumber++; // generate new sun ray + + // Start new ray + continue; + } } + } + } - // Handle if Ray was absorbed - if (RayIsAbsorbed) - { - Data::TransformToReference(LastPosRaySurfStage, - LastCosRaySurfStage, - Stage->Origin, - Stage->RLocToRef, - PosRayGlob, - CosRayGlob); + // EndStage section... - System->RayData.Append(thread_id, - PosRayGlob, - CosRayGlob, - LastElementNumber, - i + 1, - LastRayNumber, - RayEvent::ABSORB); - - n_rays_active--; - - // ray was fully absorbed - if (RayNumber == LastRayNumberInPreviousStage) - { - PreviousStageHasRays = false; - if (PreviousStageDataArrayIndex > 0) - { - PreviousStageDataArrayIndex--; - PreviousStageHasRays = true; - } - break; - } - else - { - if (i == 0) - { - if (RayNumber == NumberOfRays) - break; - else - RayNumber++; - } - - // Next ray in loop - continue; - } - } - - // Ray has left the stage - bool FlagMiss = false; - if (i == 0) - { - if (MultipleHitCount == 0) - { - // Ray in first stage missed stage entirely - // Generate new ray - continue; - } - else - { - // Ray hit an element, so save it for next stage - IncomingRays[PreviousStageDataArrayIndex].Pos = PosRayGlob; - IncomingRays[PreviousStageDataArrayIndex].Cos = CosRayGlob; - IncomingRays[PreviousStageDataArrayIndex].Num = RayNumber; - - // Is Ray the last in the stage? - if (RayNumber == NumberOfRays) - { - StageHasRays = false; - break; - } - - PreviousStageDataArrayIndex++; - PreviousStageHasRays = true; - - // Move on to next ray - RayNumber++; - continue; - } - } - else - { - // After the first stage - // Ray hit element OR is traced through stage - if (Stage->TraceThrough || MultipleHitCount > 0) - { - // Ray is saved for the next stage - IncomingRays[PreviousStageDataArrayIndex].Pos = PosRayGlob; - IncomingRays[PreviousStageDataArrayIndex].Cos = CosRayGlob; - IncomingRays[PreviousStageDataArrayIndex].Num = RayNumber; - - // Check if ray is last in stage - if (RayNumber == LastRayNumberInPreviousStage) - { - StageHasRays = false; - break; - } - - PreviousStageDataArrayIndex++; - PreviousStageHasRays = true; - - if (MultipleHitCount == 0) - { - FlagMiss = true; - } - - // Go to next ray - continue; - } - // Ray missed stage entirely and is not traced - else - { - FlagMiss = true; - } - - // Handle FlagMiss condition ( - if (FlagMiss == true) - { - LastRayNumber = RayNumber; - - System->RayData.Append(thread_id, - PosRayGlob, - CosRayGlob, - ELEMENT_NULL, - i + 1, - LastRayNumber, - RayEvent::EXIT); - - n_rays_active--; - - if (RayNumber == LastRayNumberInPreviousStage) - { - if (!Stage->TraceThrough) - { - PreviousStageHasRays = false; - if (PreviousStageDataArrayIndex > 0) - { - PreviousStageHasRays = true; - PreviousStageDataArrayIndex--; // last ray was previous one - } - } - - // Exit stage - StageHasRays = false; - break; - } - else - { - if (i == 0) - RayNumber++; // generate new sun ray - - // Start new ray - continue; - } - } - } - } - - // EndStage section... - - // skipping save_st_data logic - - if (!PreviousStageHasRays) - { - LastRayNumberInPreviousStage = 0; - continue; // No rays to carry forward - } - - if (PreviousStageDataArrayIndex < IncomingRays.size()) - { - LastRayNumberInPreviousStage = IncomingRays[PreviousStageDataArrayIndex].Num; - if (LastRayNumberInPreviousStage == 0) - { - return RunnerStatus::ERROR; - } - } - else - { - return RunnerStatus::ERROR; - } + // skipping save_st_data logic + + if (!PreviousStageHasRays) + { + LastRayNumberInPreviousStage = 0; + continue; // No rays to carry forward } - // Close out any remaining rays as misses - unsigned idx = System->StageList.size() - 1; - tstage_ptr Stage = System->StageList[idx]; - for (uint_fast64_t k = 0; k < n_rays_active; ++k) - { - GlobalRay_refactored ray = IncomingRays[k]; - System->RayData.Append(thread_id, - ray.Pos, - ray.Cos, - ELEMENT_NULL, - idx + 1, - ray.Num, - RayEvent::EXIT); - } - - // System->SunRayCount is atomic so this is thread safe - System->SunRayCount += sun_ray_count_local; - - return RunnerStatus::SUCCESS; - } + if (PreviousStageDataArrayIndex < IncomingRays.size()) + { + LastRayNumberInPreviousStage = IncomingRays[PreviousStageDataArrayIndex].Num; + if (LastRayNumberInPreviousStage == 0) + { + return RunnerStatus::ERROR; + } + } + else + { + return RunnerStatus::ERROR; + } + } + + // Close out any remaining rays as misses + unsigned idx = System->StageList.size() - 1; + tstage_ptr Stage = System->StageList[idx]; + for (uint_fast64_t k = 0; k < n_rays_active; ++k) + { + GlobalRay_refactored ray = IncomingRays[k]; + System->RayData.Append(thread_id, + ray.Pos, + ray.Cos, + ELEMENT_NULL, + idx + 1, + ray.Num, + RayEvent::EXIT); + } + + // System->SunRayCount is atomic so this is thread safe + System->SunRayCount += sun_ray_count_local; + + return RunnerStatus::SUCCESS; +} } // namespace SolTrace::NativeRunner diff --git a/google-tests/regression-tests/native_runner_validation_test.cpp b/google-tests/regression-tests/native_runner_validation_test.cpp index 34d109c1..2d03add6 100644 --- a/google-tests/regression-tests/native_runner_validation_test.cpp +++ b/google-tests/regression-tests/native_runner_validation_test.cpp @@ -509,9 +509,6 @@ TEST(NativeRunner, ValidationTest2) std::chrono::duration dur = t1 - t0; #ifdef NDEBUG EXPECT_TRUE(dur.count() < 75000.0); -#else - // Debug builds can go very slowly on some machines and compilers - EXPECT_TRUE(dur.count() < 300000.0); #endif std::cout << "Time: " << dur.count() << " ms" << std::endl; diff --git a/google-tests/unit-tests/simulation_data/cst-templates/CMakeLists.txt b/google-tests/unit-tests/simulation_data/cst-templates/CMakeLists.txt index fc3300c6..66549f30 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/CMakeLists.txt +++ b/google-tests/unit-tests/simulation_data/cst-templates/CMakeLists.txt @@ -40,9 +40,16 @@ target_link_libraries( native_runner testtools GTest::gtest_main - embree_runner ) +if (SOLTRACE_BUILD_EMBREE_SUPPORT) + target_link_libraries( + CSTUnitTests + embree_runner + ) +endif() + + if (ENABLE_COVERAGE AND CMAKE_BUILD_TYPE STREQUAL "Debug") target_link_options(CSTUnitTests PRIVATE --coverage) target_link_libraries(CSTUnitTests gcov) diff --git a/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp index a821c461..abe9a42b 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp @@ -7,8 +7,14 @@ #include -#include +// TODO: Replace with configuration define +#if __has_include() +#define USE_EMBREE #include +using SolTrace::EmbreeRunner::EmbreeRunner; +#endif + +#include #include #include #include @@ -25,9 +31,8 @@ using Heliostat = SolTrace::Data::Heliostat; -using SolTrace::Runner::RunnerStatus; using SolTrace::NativeRunner::NativeRunner; -using SolTrace::EmbreeRunner::EmbreeRunner; +using SolTrace::Runner::RunnerStatus; using SolTrace::NativeRunner::TRayData; using SolTrace::NativeRunner::TSystem; @@ -64,8 +69,12 @@ class HeliostatFieldSimulation : public ::testing::Test { protected: SimulationData simData; - //NativeRunner runner; + +#ifdef USE_EMBREE EmbreeRunner runner; +#else + NativeRunner runner; +#endif // Sun outputs double sun_width; @@ -90,7 +99,7 @@ class HeliostatFieldSimulation : public ::testing::Test { double PeakFlux, PeakFluxUncertainty; double AveFlux, AveFluxUncertainty; double MinFlux, SigmaFlux, Uniformity; - double Centroid[3]; + glm::dvec3 Centroid; double zScale; size_t NumberOfRays; @@ -231,7 +240,7 @@ class HeliostatFieldSimulation : public ::testing::Test { double distance = sqrt(pow(x_coords[i], 2) + pow(y_coords[i], 2)); glm::dvec3 aim_point = {rec_radius * (x_coords[i] / distance), rec_radius * (y_coords[i] / distance), - rec_origin[2]}; + rec_origin.z}; heliostat->set_target_position(aim_point); // At-slant focal length - to center of receiver glm::dvec3 slant = -rec_origin + heliostat_origin; //aim_point @@ -249,10 +258,10 @@ class HeliostatFieldSimulation : public ::testing::Test { int helio_idx = 0; for (const auto& heliostat : heliostat_field) { glm::dvec3 heliostat_origin = heliostat->get_origin_global(); - double distance = sqrt(pow(heliostat_origin[0], 2) + pow(heliostat_origin[1], 2)); - glm::dvec3 aim_point = {rec_radius * (heliostat_origin[0] / distance), - rec_radius * (heliostat_origin[1] / distance), - rec_origin[2] + scatter_aim_elevation[helio_idx]}; + double distance = sqrt(pow(heliostat_origin.x, 2) + pow(heliostat_origin.y, 2)); + glm::dvec3 aim_point = {rec_radius * (heliostat_origin.x / distance), + rec_radius * (heliostat_origin.y / distance), + rec_origin.z + scatter_aim_elevation[helio_idx]}; heliostat->set_target_position(aim_point); heliostat->create_geometry(); helio_idx++; @@ -262,7 +271,7 @@ class HeliostatFieldSimulation : public ::testing::Test { void assign_focal_lengths_banded() { for (const auto& heliostat : heliostat_field) { glm::dvec3 heliostat_origin = heliostat->get_origin_global(); - double distance = sqrt(pow(heliostat_origin[0], 2) + pow(heliostat_origin[1], 2)); + double distance = sqrt(pow(heliostat_origin.x, 2) + pow(heliostat_origin.y, 2)); double focal_length = 0.0; if (distance <= 502.5) focal_length = 353.8; @@ -284,7 +293,7 @@ class HeliostatFieldSimulation : public ::testing::Test { // NOTE: This was created for task 1b where the focal lengths were set to the canting distances. for (const auto& heliostat : heliostat_field) { glm::dvec3 heliostat_origin = heliostat->get_origin_global(); - double distance = sqrt(pow(heliostat_origin[0], 2) + pow(heliostat_origin[1], 2)); + double distance = sqrt(pow(heliostat_origin.x, 2) + pow(heliostat_origin.y, 2)); double focal_length = 0.0; if (distance <= 502.0) focal_length = 516; @@ -320,7 +329,7 @@ class HeliostatFieldSimulation : public ::testing::Test { // Modify heliostat canting to bands - to center of receiver for (const auto& heliostat : heliostat_field) { glm::dvec3 heliostat_origin = heliostat->get_origin_global(); - double distance = sqrt(pow(heliostat_origin[0], 2) + pow(heliostat_origin[1], 2)); + double distance = sqrt(pow(heliostat_origin.x, 2) + pow(heliostat_origin.y, 2)); double cant_distance = 0.0; if (distance <= 502.0) cant_distance = 516; @@ -493,10 +502,14 @@ class HeliostatFieldSimulation : public ::testing::Test { tokens.push_back(item); } // TODO: we could average values across the different models - if (line_number == 2) expected_power = std::stod(tokens[1]); - if (line_number == 3) expected_peak_flux = std::stod(tokens[1]); - if (line_number == 6) expected_flux_RMS = std::stod(tokens[1]); // TODO: Maybe not required - if (line_number == 8) expected_max_flux_RMS = std::stod(tokens[1]); + if (line_number == 2) + expected_power = std::stod(tokens[1]); + if (line_number == 3) + expected_peak_flux = std::stod(tokens[1]); + if (line_number == 6) + expected_flux_RMS = std::stod(tokens[1]); // TODO: Maybe not required + if (line_number == 8) + expected_max_flux_RMS = std::stod(tokens[1]); line_number++; } } @@ -520,7 +533,8 @@ class HeliostatFieldSimulation : public ::testing::Test { tokens.push_back(item); } if (line_number > 2) { - double avg_eff = (std::stod(tokens[2]) + std::stod(tokens[4]) + std::stod(tokens[6])) / 3.0; + double avg_eff = (std::stod(tokens[2]) + std::stod(tokens[4]) + std::stod(tokens[6])) + / 3.0; if (line_number == 3) expected_cosine_efficiency = avg_eff; if (line_number == 4) expected_absorption_efficiency = avg_eff; if (line_number == 5) expected_blocking_efficiency = avg_eff; @@ -579,7 +593,7 @@ class HeliostatFieldSimulation : public ::testing::Test { PeakFlux = PeakFluxUncertainty = 0.0; AveFlux = AveFluxUncertainty = 0.0; MinFlux = SigmaFlux = Uniformity = 0.0; - Centroid[0] = Centroid[1] = Centroid[2] = 0.0; + Centroid = glm::dvec3{0.0}; zScale = 0.0; NumberOfRays = 0; } @@ -587,16 +601,13 @@ class HeliostatFieldSimulation : public ::testing::Test { bool calculate_receiver_flux_map(const SimulationResult &result, int nbinsx, int nbinsy, bool is_cylinder) { reset_flux_map(); - double minx, maxx, miny, maxy; - minx = maxx = miny = maxy = 0.0; - glm::dvec3 rec_origin = receiver->get_origin_global(); - - minx = -rec_width / 2.0; - maxx = rec_width / 2.0; + double minx = -rec_width / 2.0; + double maxx = rec_width / 2.0; - maxy = rec_height / 2.0; - miny = -rec_height / 2.0; + double maxy = rec_height / 2.0; + double miny = -rec_height / 2.0; + glm::dvec3 rec_origin = receiver->get_origin_global(); // Autoscale if (false) { @@ -613,8 +624,8 @@ class HeliostatFieldSimulation : public ::testing::Test { rr->get_position(j, global_position); receiver->convert_global_to_local(local_position, global_position); - double x = local_position[0]; - double y = local_position[1]; + double x = local_position.x; + double y = local_position.y; if (x < minx) minx = x; if (x > maxx) maxx = x; @@ -654,7 +665,7 @@ class HeliostatFieldSimulation : public ::testing::Test { size_t RayCount = 0; size_t NotBinned = 0; size_t npoints = 0; - Centroid[0] = Centroid[1] = Centroid[2] = 0.0; + Centroid.x = Centroid.y = Centroid.z = 0.0; fluxGrid.fill(0.0); for (size_t i = 0; i < result.get_number_of_records(); i++) { @@ -669,13 +680,12 @@ class HeliostatFieldSimulation : public ::testing::Test { receiver->convert_global_to_local(local_position, global_position); - x = local_position[0]; - y = local_position[1]; - z = local_position[2]; + x = local_position.x; + y = local_position.y; + z = local_position.z; + + Centroid += local_position; - Centroid[0] += x; - Centroid[1] += y; - Centroid[2] += z; npoints++; if (is_cylinder) { @@ -725,9 +735,7 @@ class HeliostatFieldSimulation : public ::testing::Test { if (npoints > 0) { - Centroid[0] /= npoints; - Centroid[1] /= npoints; - Centroid[2] /= npoints; + Centroid /= npoints; } double SumFlux, SumFlux2; @@ -776,7 +784,8 @@ class HeliostatFieldSimulation : public ::testing::Test { std::cout << "Avg. flux: " << AveFlux << std::endl; std::cout << "Avg. flux uncertainty: +/- " << AveFluxUncertainty << " %" << std::endl; std::cout << "Uniformity: " << Uniformity << std::endl; - std::cout << "Centroid: (" << Centroid[0] << ", " << Centroid[1] << ", " << Centroid[2] << ")" << std::endl; + std::cout << "Centroid: (" << Centroid.x << ", " << Centroid.y << ", " << Centroid.z + << ")" << std::endl; } return true; diff --git a/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp index 9a44cf0b..2cb8c5f6 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp @@ -2,7 +2,13 @@ #include +// TODO: Replace with configuration define +#if __has_include() +#define USE_EMBREE #include +using SolTrace::EmbreeRunner::EmbreeRunner; +#endif + #include #include #include @@ -22,7 +28,6 @@ using Heliostat = SolTrace::Data::Heliostat; using SolTrace::Runner::RunnerStatus; using SolTrace::NativeRunner::NativeRunner; -using SolTrace::EmbreeRunner::EmbreeRunner; using SolTrace::NativeRunner::TRayData; using SolTrace::NativeRunner::TSystem; @@ -51,8 +56,12 @@ class SingleHeliostatSimulation : public ::testing::Test { protected: SimulationData simData; - //NativeRunner runner; + +#ifdef USE_EMBREE EmbreeRunner runner; +#else + NativeRunner runner; +#endif double sun_width; double sun_height; @@ -380,12 +389,10 @@ class SingleHeliostatSimulation : public ::testing::Test { bool calculate_receiver_flux_map(SimulationResult result, int nbinsx, int nbinsy, bool is_cylinder) { reset_flux_map(); - double minx, maxx, miny, maxy; - - minx = -rec_width / 2.0; - maxx = rec_width / 2.0; - miny = -rec_height / 2.0; - maxy = rec_height / 2.0; + double minx = -rec_width / 2.0; + double maxx = rec_width / 2.0; + double miny = -rec_height / 2.0; + double maxy = rec_height / 2.0; glm::dvec3 rec_origin = receiver->get_origin_global(); diff --git a/google-tests/unit-tests/simulation_data/utilities_test.cpp b/google-tests/unit-tests/simulation_data/utilities_test.cpp index d9cda209..944d5c75 100644 --- a/google-tests/unit-tests/simulation_data/utilities_test.cpp +++ b/google-tests/unit-tests/simulation_data/utilities_test.cpp @@ -1,8 +1,6 @@ #include #include - -#include #include #include "common.hpp" From 0edfd620262cbac2f2768856636e363d478ef347 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sun, 8 Feb 2026 14:52:09 -0700 Subject: [PATCH 14/23] Fix the helio tests to only run if embree is enabled Also, optimizations. --- coretrace/simulation_data/vector_utility.hpp | 27 ++-- .../embree_runner/bbox_calculator.cpp | 119 +++++++--------- .../embree_runner/bbox_calculator.hpp | 4 +- .../embree_runner/embree_helper.cpp | 81 ++++++----- .../embree_runner/embree_helper.hpp | 80 ++++++----- .../embree_runner/find_element_hit_embree.cpp | 134 +++++++++--------- .../embree_runner/find_element_hit_embree.hpp | 21 +-- .../embree_runner/trace_embree.cpp | 96 +++++++------ .../embree_runner/trace_embree.hpp | 2 +- .../native_runner/process_interaction.cpp | 27 ++-- .../native_runner/tracing_errors.cpp | 59 ++++---- .../embree_runner_validation_test.cpp | 34 ++--- .../cst-templates/CMakeLists.txt | 2 +- .../cst-templates/heliostat_field_test.cpp | 11 +- .../cst-templates/single_heliostat_test.cpp | 17 +-- .../embree_runner/embree_runner_test.cpp | 52 ++++--- 16 files changed, 373 insertions(+), 393 deletions(-) diff --git a/coretrace/simulation_data/vector_utility.hpp b/coretrace/simulation_data/vector_utility.hpp index 9fe784da..b6fe592a 100644 --- a/coretrace/simulation_data/vector_utility.hpp +++ b/coretrace/simulation_data/vector_utility.hpp @@ -11,22 +11,25 @@ namespace SolTrace::Data { inline double error(const glm::dvec3 &u, const glm::dvec3 &v) { - double err = 0.0; - double dx; - for (int i = 0; i < 3; ++i) { - dx = u[i] - v[i]; - err += dx * dx; - } - return sqrt(err); + //double err = 0.0; + //double dx; + // for (int i = 0; i < 3; ++i) { + // dx = u[i] - v[i]; + // err += dx * dx; + // } + return glm::distance(u,v); + //return sqrt(err); } inline double error_inf(const glm::dvec3 &u, const glm::dvec3 &v) { - double err = 0.0; - for (int i = 0; i < 3; ++i) { - err = std::max(err, fabs(u[i] - v[i])); - } - return err; + // double err = 0.0; + // for (int i = 0; i < 3; ++i) { + // err = std::max(err, fabs(u[i] - v[i])); + // } + // return err; + + return glm::compMax(glm::abs(u - v)); } inline void normalize_inplace(glm::dvec3 &v) diff --git a/coretrace/simulation_runner/embree_runner/bbox_calculator.cpp b/coretrace/simulation_runner/embree_runner/bbox_calculator.cpp index 450725e5..6a6b88d0 100644 --- a/coretrace/simulation_runner/embree_runner/bbox_calculator.cpp +++ b/coretrace/simulation_runner/embree_runner/bbox_calculator.cpp @@ -5,10 +5,10 @@ #include #include +#include + namespace SolTrace::EmbreeRunner { - using SolTrace::Data::MatrixVectorMult_generic; - using SolTrace::NativeRunner::TElement; using SolTrace::NativeRunner::telement_ptr; using SolTrace::NativeRunner::TStage; @@ -263,109 +263,86 @@ namespace SolTrace::EmbreeRunner // } // } - void transform_to_global(const float coord_element[3], - const tstage_ptr st_stage, + void transform_to_global(glm::vec3 coord_element, + const tstage_ptr& st_stage, const TElement *st_element, - float (&coord_global)[3]) + glm::vec3& coord_global) { - float PosDumStage[3]; - float coord_stage[3]; - MatrixVectorMult_generic(st_element->RLocToRef, coord_element, PosDumStage); - for (int i = 0; i < 3; i++) - coord_stage[i] = PosDumStage[i] + st_element->Origin[i]; + auto PosDumStage = st_element->RLocToRef * coord_element; + auto coord_stage = PosDumStage + st_element->Origin; - float PosDumGlob[3]; - MatrixVectorMult_generic(st_stage->RLocToRef, coord_stage, PosDumGlob); + auto PosDumGlob = st_stage->RLocToRef * coord_stage; + coord_global = PosDumGlob + st_stage->Origin; for (int i = 0; i < 3; i++) coord_global[i] = PosDumGlob[i] + st_stage->Origin[i]; return; } - void transform_bounds(const float min_coord_element[3], - const float max_coord_element[3], - const tstage_ptr st_stage, + void transform_bounds(glm::vec3 min_coord_element, + glm::vec3 max_coord_element, + const tstage_ptr& st_stage, const TElement *st_element, - float (&min_coord_global)[3], - float (&max_coord_global)[3]) + glm::vec3 &min_coord_global, + glm::vec3 &max_coord_global) { // Transform min and max bounding box from element coordinates to global - float corners_element[8][3] = + glm::vec3 corners_element[8] = { - {min_coord_element[0], min_coord_element[1], min_coord_element[2]}, - {min_coord_element[0], min_coord_element[1], max_coord_element[2]}, - {min_coord_element[0], max_coord_element[1], min_coord_element[2]}, - {min_coord_element[0], max_coord_element[1], max_coord_element[2]}, - {max_coord_element[0], min_coord_element[1], min_coord_element[2]}, - {max_coord_element[0], min_coord_element[1], max_coord_element[2]}, - {max_coord_element[0], max_coord_element[1], min_coord_element[2]}, - {max_coord_element[0], max_coord_element[1], max_coord_element[2]}}; + {min_coord_element.x, min_coord_element.y, min_coord_element.z}, + {min_coord_element.x, min_coord_element.y, max_coord_element.z}, + {min_coord_element.x, max_coord_element.y, min_coord_element.z}, + {min_coord_element.x, max_coord_element.y, max_coord_element.z}, + {max_coord_element.x, min_coord_element.y, min_coord_element.z}, + {max_coord_element.x, min_coord_element.y, max_coord_element.z}, + {max_coord_element.x, max_coord_element.y, min_coord_element.z}, + {max_coord_element.x, max_coord_element.y, max_coord_element.z}}; // Convert corners to global coordinates - float corners_global[8][3]; + glm::vec3 corners_global[8]; for (int i = 0; i < 8; i++) transform_to_global(corners_element[i], st_stage, st_element, corners_global[i]); // Find min and max xyz - min_coord_global[0] = corners_global[0][0]; - min_coord_global[1] = corners_global[0][1]; - min_coord_global[2] = corners_global[0][2]; - max_coord_global[0] = corners_global[0][0]; - max_coord_global[1] = corners_global[0][1]; - max_coord_global[2] = corners_global[0][2]; + min_coord_global = corners_global[0]; + max_coord_global = corners_global[0]; for (int i = 1; i < 8; i++) { - for (int j = 0; j < 3; j++) - { - float val = corners_global[i][j]; - if (val < min_coord_global[j]) - min_coord_global[j] = val; - if (val > max_coord_global[j]) - max_coord_global[j] = val; - } + min_coord_global = glm::min(corners_global[i], min_coord_global); + max_coord_global = glm::max(corners_global[i], max_coord_global); } } bool get_bounds(const TElement *st_element, - float (&min_coord_global)[3], - float (&max_coord_global)[3]) + glm::vec3 &min_coord_global, + glm::vec3 &max_coord_global) { // Get stage - tstage_ptr st_stage = st_element->parent_stage; + tstage_ptr const& st_stage = st_element->parent_stage; // Define element coord bounds - float min_coord_element[3] = {0.f, 0.f, 0.f}; - float max_coord_element[3] = {0.f, 0.f, 0.f}; - - double x_minmax[2] = {0.0, 0.0}; - double y_minmax[2] = {0.0, 0.0}; - double z_minmax[2] = {0.0, 0.0}; + glm::dvec2 x_minmax; + glm::dvec2 y_minmax; + glm::dvec2 z_minmax; - st_element->aperture->bounding_box(x_minmax[0], - x_minmax[1], - y_minmax[0], - y_minmax[1]); + st_element->aperture->bounding_box(x_minmax.x, + x_minmax.y, + y_minmax.x, + y_minmax.y); - st_element->surface->bounding_box(x_minmax, - y_minmax, - z_minmax[0], - z_minmax[1]); + st_element->surface->bounding_box(glm::value_ptr(x_minmax), + glm::value_ptr(y_minmax), + z_minmax.x, + z_minmax.y); // Expand bounding boxes slightly to account for float precision - const float expand = 1e-3f; - x_minmax[0] -= expand; - x_minmax[1] += expand; - y_minmax[0] -= expand; - y_minmax[1] += expand; - z_minmax[0] -= expand; - z_minmax[1] += expand; + glm::dvec2 expand = {1e-3f, -1e-3f}; + x_minmax += expand; + y_minmax += expand; + z_minmax += expand; // Assign points to min/max coordinate element arrays - min_coord_element[0] = x_minmax[0]; - min_coord_element[1] = y_minmax[0]; - min_coord_element[2] = z_minmax[0]; - max_coord_element[0] = x_minmax[1]; - max_coord_element[1] = y_minmax[1]; - max_coord_element[2] = z_minmax[1]; + glm::vec3 min_coord_element = {x_minmax.x, y_minmax.x, z_minmax.x}; + glm::vec3 max_coord_element = {x_minmax.y, y_minmax.y, z_minmax.y}; // Convert local element bounds, to global xyz transform_bounds(min_coord_element, max_coord_element, diff --git a/coretrace/simulation_runner/embree_runner/bbox_calculator.hpp b/coretrace/simulation_runner/embree_runner/bbox_calculator.hpp index 98e319a8..f7e91d28 100644 --- a/coretrace/simulation_runner/embree_runner/bbox_calculator.hpp +++ b/coretrace/simulation_runner/embree_runner/bbox_calculator.hpp @@ -8,8 +8,8 @@ namespace SolTrace::EmbreeRunner { bool get_bounds(const SolTrace::NativeRunner::TElement *st_element, - float (&min_coord_global)[3], - float (&max_coord_global)[3]); + glm::vec3& min_coord_global, + glm::vec3& max_coord_global); } // namespace SolTrace::EmbreeRunner diff --git a/coretrace/simulation_runner/embree_runner/embree_helper.cpp b/coretrace/simulation_runner/embree_runner/embree_helper.cpp index 643f175b..a71b92b6 100644 --- a/coretrace/simulation_runner/embree_runner/embree_helper.cpp +++ b/coretrace/simulation_runner/embree_runner/embree_helper.cpp @@ -29,14 +29,18 @@ namespace SolTrace::EmbreeRunner using SolTrace::NativeRunner::TStage; using SolTrace::NativeRunner::tstage_ptr; - template - bool compare_Vec3(T vec1[3], T vec2[3], double tol_diff) + bool compare_Vec3(const glm::dvec3 &v1, + const glm::dvec3 &v2, + double rel_tol, + double abs_tol = 1e-5) { - for (int i = 0; i < 3; i++) - { - if ((std::abs(vec1[i] / vec2[i] - 1) > tol_diff) && - (std::abs(vec1[i] - vec2[i]) > 1e-5)) - return false; + auto diff = v1 - v2; + auto scale = glm::max(glm::abs(v1), glm::abs(v2)); + + auto rel_tol_v = glm::max(glm::dvec3(abs_tol), rel_tol * scale); + + if (glm::any(glm::greaterThan(diff, rel_tol_v))) { + return false; } return true; } @@ -74,8 +78,8 @@ namespace SolTrace::EmbreeRunner TElement *st_element = (TElement *)args->geometryUserPtr; // Get bounds - float min_coord_global[3]; - float max_coord_global[3]; + glm::vec3 min_coord_global; + glm::vec3 max_coord_global; bool success = get_bounds(st_element, min_coord_global, max_coord_global); @@ -101,38 +105,36 @@ namespace SolTrace::EmbreeRunner // Get payload object RayIntersectPayload *payload = (RayIntersectPayload *)args->context; - double PosRayGlob[3], CosRayGlob[3]; - CopyVec3(PosRayGlob, payload->PosRayGlobIn); - CopyVec3(CosRayGlob, payload->CosRayGlobIn); + glm::dvec3 PosRayGlob, CosRayGlob; + PosRayGlob = payload->PosRayGlobIn; + CosRayGlob = payload->CosRayGlobIn; // Get Element data TElement *st_element = (TElement *)args->geometryUserPtr; - tstage_ptr st_stage = st_element->parent_stage; + tstage_ptr const& st_stage = st_element->parent_stage; // First, convert ray coordinates to element // Global -> stage -> element // transform the global incoming ray to local stage coordinates - double PosRayStage[3], CosRayStage[3]; + glm::dvec3 PosRayStage, CosRayStage; TransformToLocal(PosRayGlob, CosRayGlob, st_stage->Origin, st_stage->RRefToLoc, PosRayStage, CosRayStage); // {Transform ray to element[j] coord system of Stage[i]} - double PosRayElement[3], CosRayElement[3]; + glm::dvec3 PosRayElement, CosRayElement; TransformToLocal(PosRayStage, CosRayStage, st_element->Origin, st_element->RRefToLoc, PosRayElement, CosRayElement); // Increment position by tiny amount to get off the element if // tracing to the same element. - PosRayElement[0] = PosRayElement[0] + 1.0e-4 * CosRayElement[0]; - PosRayElement[1] = PosRayElement[1] + 1.0e-4 * CosRayElement[1]; - PosRayElement[2] = PosRayElement[2] + 1.0e-4 * CosRayElement[2]; + PosRayElement += 1.0e-4 * CosRayElement; // Call DeterminElementIntersectionNew - double PosRaySurfElement[3] = {0.0, 0.0, 0.0}; - double CosRaySurfElement[3] = {0.0, 0.0, 0.0}; - double DFXYZ[3] = {0.0, 0.0, 0.0}; + glm::dvec3 PosRaySurfElement = {0.0, 0.0, 0.0}; + glm::dvec3 CosRaySurfElement = {0.0, 0.0, 0.0}; + glm::dvec3 DFXYZ = {0.0, 0.0, 0.0}; double PathLength = 0; int InterceptFlag = 0; @@ -161,8 +163,8 @@ namespace SolTrace::EmbreeRunner { // Transform ray back to stage coordinate system - double PosRaySurfStage[3] = {0.0, 0.0, 0.0}; - double CosRaySurfStage[3] = {0.0, 0.0, 0.0}; + glm::dvec3 PosRaySurfStage = {0.0, 0.0, 0.0}; + glm::dvec3 CosRaySurfStage = {0.0, 0.0, 0.0}; TransformToReference(PosRaySurfElement, CosRaySurfElement, st_element->Origin, st_element->RLocToRef, PosRaySurfStage, CosRaySurfStage); @@ -178,13 +180,13 @@ namespace SolTrace::EmbreeRunner // Assign custom outputs payload->LastHitBackSide = HitBackSide; - CopyVec3(payload->LastDFXYZ, DFXYZ); + payload->LastDFXYZ = DFXYZ; // CopyVec3(payload->LastPosRaySurfGlob, PosRaySurfGlob); // CopyVec3(payload->LastCosRaySurfGlob, CosRaySurfGlob); - CopyVec3(payload->LastPosRaySurfStage, PosRaySurfStage); - CopyVec3(payload->LastCosRaySurfStage, CosRaySurfStage); - CopyVec3(payload->LastPosRaySurfElement, PosRaySurfElement); - CopyVec3(payload->LastCosRaySurfElement, CosRaySurfElement); + payload->LastPosRaySurfStage = PosRaySurfStage; + payload->LastCosRaySurfStage = CosRaySurfStage; + payload->LastPosRaySurfElement = PosRaySurfElement; + payload->LastCosRaySurfElement = CosRaySurfElement; payload->element_number = st_element->element_number; payload->LastPathLength = PathLength; } @@ -240,23 +242,24 @@ namespace SolTrace::EmbreeRunner return scene; } - bool validate_intersect(double (&LastPosRaySurfElement1)[3], - double (&LastCosRaySurfElement1)[3], - double (&LastDFXYZ1)[3], + bool validate_intersect(glm::dvec3 &LastPosRaySurfElement1, + glm::dvec3 &LastCosRaySurfElement1, + glm::dvec3 &LastDFXYZ1, uint_fast64_t &LastElementNumber1, uint_fast64_t &LastRayNumber1, - double (&LastPosRaySurfStage1)[3], - double (&LastCosRaySurfStage1)[3], + glm::dvec3 &LastPosRaySurfStage1, + glm::dvec3 &LastCosRaySurfStage1, int &ErrorFlag1, int &LastHitBackSide1, bool &StageHit1, - double (&LastPosRaySurfElement2)[3], - double (&LastCosRaySurfElement2)[3], - double (&LastDFXYZ2)[3], + + glm::dvec3 &LastPosRaySurfElement2, + glm::dvec3 &LastCosRaySurfElement2, + glm::dvec3 &LastDFXYZ2, uint_fast64_t &LastElementNumber2, uint_fast64_t &LastRayNumber2, - double (&LastPosRaySurfStage2)[3], - double (&LastCosRaySurfStage2)[3], + glm::dvec3 &LastPosRaySurfStage2, + glm::dvec3 &LastCosRaySurfStage2, int &ErrorFlag2, int &LastHitBackSide2, bool &StageHit2) @@ -285,4 +288,4 @@ namespace SolTrace::EmbreeRunner return true; } -} // namespace SolTrace::EmbreeRunner \ No newline at end of file +} // namespace SolTrace::EmbreeRunner diff --git a/coretrace/simulation_runner/embree_runner/embree_helper.hpp b/coretrace/simulation_runner/embree_runner/embree_helper.hpp index ceaad9a4..c7f87668 100644 --- a/coretrace/simulation_runner/embree_runner/embree_helper.hpp +++ b/coretrace/simulation_runner/embree_runner/embree_helper.hpp @@ -7,35 +7,35 @@ #include #include -#include namespace SolTrace::EmbreeRunner { - struct RayIntersectPayload - { - RTCRayQueryContext context; // Embree built-in context (MUST come first) + struct RayIntersectPayload + { + RTCRayQueryContext context; // Embree built-in context (MUST come first) + + int LastHitBackSide = -1; + glm::dvec3 LastDFXYZ{0.0}; - int LastHitBackSide = -1; - double LastDFXYZ[3] = {0.0, 0.0, 0.0}; + // glm::dvec3 LastPosRaySurfGlob{0.0}; + // glm::dvec3 LastCosRaySurfGlob{0.0}; - // double LastPosRaySurfGlob[3] = { 0.0, 0.0, 0.0 }; - // double LastCosRaySurfGlob[3] = { 0.0, 0.0, 0.0 }; + glm::dvec3 LastPosRaySurfStage{0.0}; + glm::dvec3 LastCosRaySurfStage{0.0}; - double LastPosRaySurfStage[3] = {0.0, 0.0, 0.0}; - double LastCosRaySurfStage[3] = {0.0, 0.0, 0.0}; + glm::dvec3 LastPosRaySurfElement{0.0}; + glm::dvec3 LastCosRaySurfElement{0.0}; - double LastPosRaySurfElement[3] = {0.0, 0.0, 0.0}; - double LastCosRaySurfElement[3] = {0.0, 0.0, 0.0}; + int_fast64_t element_number = -1; + int ErrorFlag = 0; - int_fast64_t element_number = -1; - int ErrorFlag = 0; + glm::dvec3 PosRayGlobIn{0.0}; + glm::dvec3 CosRayGlobIn{0.0}; - double PosRayGlobIn[3] = {0.0, 0.0, 0.0}; - double CosRayGlobIn[3] = {0.0, 0.0, 0.0}; + double LastPathLength = std::numeric_limits::infinity(); + }; - double LastPathLength = std::numeric_limits::infinity(); - }; inline unsigned int embree_mask(int_fast64_t stage_index) { @@ -49,26 +49,30 @@ namespace SolTrace::EmbreeRunner RTCScene make_scene(RTCDevice &device, SolTrace::NativeRunner::TSystem &system); - bool validate_intersect(double (&LastPosRaySurfElement1)[3], - double (&LastCosRaySurfElement1)[3], - double (&LastDFXYZ1)[3], - uint_fast64_t &LastElementNumber1, - uint_fast64_t &LastRayNumber1, - double (&LastPosRaySurfStage1)[3], - double (&LastCosRaySurfStage1)[3], - int &ErrorFlag1, - int &LastHitBackSide1, - bool &StageHit1, - double (&LastPosRaySurfElement2)[3], - double (&LastCosRaySurfElement2)[3], - double (&LastDFXYZ2)[3], - uint_fast64_t &LastElementNumber2, - uint_fast64_t &LastRayNumber2, - double (&LastPosRaySurfStage2)[3], - double (&LastCosRaySurfStage2)[3], - int &ErrorFlag2, - int &LastHitBackSide2, - bool &StageHit2); + bool validate_intersect( + glm::dvec3 &LastPosRaySurfElement1, + glm::dvec3 &LastCosRaySurfElement1, + glm::dvec3 &LastDFXYZ1, + uint_fast64_t &LastElementNumber1, + uint_fast64_t &LastRayNumber1, + glm::dvec3 &LastPosRaySurfStage1, + glm::dvec3 &LastCosRaySurfStage1, + int &ErrorFlag1, + int &LastHitBackSide1, + bool &StageHit1, + + glm::dvec3 &LastPosRaySurfElement2, + glm::dvec3 &LastCosRaySurfElement2, + glm::dvec3 &LastDFXYZ2, + uint_fast64_t &LastElementNumber2, + uint_fast64_t &LastRayNumber2, + glm::dvec3 &LastPosRaySurfStage2, + glm::dvec3 &LastCosRaySurfStage2, + int &ErrorFlag2, + int &LastHitBackSide2, + bool &StageHit2 + ); + } // namespace SolTrace::EmbreeRunner diff --git a/coretrace/simulation_runner/embree_runner/find_element_hit_embree.cpp b/coretrace/simulation_runner/embree_runner/find_element_hit_embree.cpp index 3f94fd66..3f72e673 100644 --- a/coretrace/simulation_runner/embree_runner/find_element_hit_embree.cpp +++ b/coretrace/simulation_runner/embree_runner/find_element_hit_embree.cpp @@ -11,80 +11,78 @@ namespace SolTrace::EmbreeRunner { - void FindElementHit_embree( - // Embree args - const RTCScene &scene, - // Ray info - const int i, - const uint_fast64_t RayNumber, - const double (&PosRayGlob)[3], - const double (&CosRayGlob)[3], - // outputs - double (&LastPosRaySurfElement)[3], - double (&LastCosRaySurfElement)[3], - double (&LastDFXYZ)[3], - uint_fast64_t &LastElementNumber, - uint_fast64_t &LastRayNumber, - double (&LastPosRaySurfStage)[3], - double (&LastCosRaySurfStage)[3], - int &ErrorFlag, - int &LastHitBackSide, - bool &StageHit) - { - // Initialize outputs - StageHit = false; +void FindElementHit_embree( + // Embree args + const RTCScene &scene, + // Ray info + const int i, + const uint_fast64_t RayNumber, + const glm::dvec3 &PosRayGlob, + const glm::dvec3 &CosRayGlob, + // outputs + glm::dvec3 &LastPosRaySurfElement, + glm::dvec3 &LastCosRaySurfElement, + glm::dvec3 &LastDFXYZ, + uint_fast64_t &LastElementNumber, + uint_fast64_t &LastRayNumber, + glm::dvec3 &LastPosRaySurfStage, + glm::dvec3 &LastCosRaySurfStage, + int &ErrorFlag, + int &LastHitBackSide, + bool &StageHit) +{ + // Initialize outputs + StageHit = false; - // Make payload object to store intersect outputs - RayIntersectPayload ray_payload; - CopyVec3(ray_payload.PosRayGlobIn, PosRayGlob); // Copy position (with full double precision) - CopyVec3(ray_payload.CosRayGlobIn, CosRayGlob); // Copy direction (with full double precision) - rtcInitRayQueryContext(&ray_payload.context); - RTCIntersectArguments args; - rtcInitIntersectArguments(&args); - args.context = &ray_payload.context; - ray_payload.LastPathLength = std::numeric_limits::infinity(); + // Make payload object to store intersect outputs + RayIntersectPayload ray_payload; + ray_payload.PosRayGlobIn = PosRayGlob; // Copy position (with full double precision) + ray_payload.CosRayGlobIn = CosRayGlob; // Copy direction (with full double precision) + rtcInitRayQueryContext(&ray_payload.context); + RTCIntersectArguments args; + rtcInitIntersectArguments(&args); + args.context = &ray_payload.context; + ray_payload.LastPathLength = std::numeric_limits::infinity(); - // Make rayhit object - RTCRayHit rayhit; - rayhit.ray.org_x = PosRayGlob[0]; - rayhit.ray.org_y = PosRayGlob[1]; - rayhit.ray.org_z = PosRayGlob[2]; - rayhit.ray.dir_x = CosRayGlob[0]; - rayhit.ray.dir_y = CosRayGlob[1]; - rayhit.ray.dir_z = CosRayGlob[2]; + // Make rayhit object + RTCRayHit rayhit; + rayhit.ray.org_x = PosRayGlob[0]; + rayhit.ray.org_y = PosRayGlob[1]; + rayhit.ray.org_z = PosRayGlob[2]; + rayhit.ray.dir_x = CosRayGlob[0]; + rayhit.ray.dir_y = CosRayGlob[1]; + rayhit.ray.dir_z = CosRayGlob[2]; - // Define rayhit outputs - rayhit.ray.tnear = 0; - rayhit.ray.tfar = std::numeric_limits::infinity(); - rayhit.ray.mask = 1u << (i + 1); - rayhit.ray.flags = 0; - rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID; - rayhit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID; + // Define rayhit outputs + rayhit.ray.tnear = 0; + rayhit.ray.tfar = std::numeric_limits::infinity(); + rayhit.ray.mask = 1u << (i + 1); + rayhit.ray.flags = 0; + rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID; + rayhit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID; - // Find intersection - rtcIntersect1(scene, &rayhit, &args); + // Find intersection + rtcIntersect1(scene, &rayhit, &args); - // Check if ray hit any elements - if (rayhit.hit.geomID != RTC_INVALID_GEOMETRY_ID) - { - // Collect intersection outputs - StageHit = true; - CopyVec3(LastPosRaySurfElement, ray_payload.LastPosRaySurfElement); - CopyVec3(LastCosRaySurfElement, ray_payload.LastCosRaySurfElement); - CopyVec3(LastDFXYZ, ray_payload.LastDFXYZ); - LastElementNumber = ray_payload.element_number; - LastRayNumber = RayNumber; - CopyVec3(LastPosRaySurfStage, ray_payload.LastPosRaySurfStage); - CopyVec3(LastCosRaySurfStage, ray_payload.LastCosRaySurfStage); - ErrorFlag = ray_payload.ErrorFlag; - LastHitBackSide = ray_payload.LastHitBackSide; - } + // Check if ray hit any elements + if (rayhit.hit.geomID != RTC_INVALID_GEOMETRY_ID) { + // Collect intersection outputs + StageHit = true; + LastPosRaySurfElement = ray_payload.LastPosRaySurfElement; + LastCosRaySurfElement = ray_payload.LastCosRaySurfElement; + LastDFXYZ = ray_payload.LastDFXYZ; + LastElementNumber = ray_payload.element_number; + LastRayNumber = RayNumber; + LastPosRaySurfStage = ray_payload.LastPosRaySurfStage; + LastCosRaySurfStage = ray_payload.LastCosRaySurfStage; + ErrorFlag = ray_payload.ErrorFlag; + LastHitBackSide = ray_payload.LastHitBackSide; + } - // No hit - else - { - StageHit = false; - } + // No hit + else { + StageHit = false; + } } } // namespace SolTrace::EmbreeRunner diff --git a/coretrace/simulation_runner/embree_runner/find_element_hit_embree.hpp b/coretrace/simulation_runner/embree_runner/find_element_hit_embree.hpp index 9f3842d3..7bd361aa 100644 --- a/coretrace/simulation_runner/embree_runner/find_element_hit_embree.hpp +++ b/coretrace/simulation_runner/embree_runner/find_element_hit_embree.hpp @@ -5,27 +5,32 @@ #include +#include + namespace SolTrace::EmbreeRunner { + void FindElementHit_embree( // Embree args const RTCScene &scene, // Ray info const int i, const uint_fast64_t RayNumber, - const double (&PosRayGlob)[3], - const double (&CosRayGlob)[3], + const glm::dvec3 &PosRayGlob, + const glm::dvec3 &CosRayGlob, // outputs - double (&LastPosRaySurfElement)[3], - double (&LastCosRaySurfElement)[3], - double (&LastDFXYZ)[3], + glm::dvec3 &LastPosRaySurfElement, + glm::dvec3 &LastCosRaySurfElement, + glm::dvec3 &LastDFXYZ, uint_fast64_t &LastElementNumber, uint_fast64_t &LastRayNumber, - double (&LastPosRaySurfStage)[3], - double (&LastCosRaySurfStage)[3], + glm::dvec3 &LastPosRaySurfStage, + glm::dvec3 &LastCosRaySurfStage, int &ErrorFlag, int &LastHitBackSide, - bool &StageHit); + bool &StageHit + ); + } // namespace SolTrace::EmbreeRunner #endif diff --git a/coretrace/simulation_runner/embree_runner/trace_embree.cpp b/coretrace/simulation_runner/embree_runner/trace_embree.cpp index c87bd23c..7835e3d2 100644 --- a/coretrace/simulation_runner/embree_runner/trace_embree.cpp +++ b/coretrace/simulation_runner/embree_runner/trace_embree.cpp @@ -102,10 +102,12 @@ namespace SolTrace::EmbreeRunner System->SunRayCount = 0; // Initialize Sun - Vector3d PosSunStage; - bool status = SolTrace::NativeRunner::SunToPrimaryStage( - logger, System, System->StageList[0].get(), - &System->Sun, PosSunStage.data); + glm::dvec3 PosSunStage; + bool status = SolTrace::NativeRunner::SunToPrimaryStage(logger, + System, + System->StageList[0].get(), + &System->Sun, + PosSunStage); if (!status) return RunnerStatus::ERROR; @@ -137,18 +139,17 @@ namespace SolTrace::EmbreeRunner return manager->monitor_until_completion(); } - RunnerStatus trace_embree_single_thread( - unsigned thread_id, - thread_manager_ptr manager, - trace_logger_ptr logger, - TSystem *System, - unsigned seed, - uint_fast64_t NumberOfRays, - uint_fast64_t MaxNumberOfRays, - bool IncludeSunShape, - bool IncludeErrors, - const SolTrace::Data::Vector3d &PosSunStage, - const RTCScene &embree_scene) + RunnerStatus trace_embree_single_thread(unsigned thread_id, + thread_manager_ptr manager, + trace_logger_ptr logger, + TSystem *System, + unsigned seed, + uint_fast64_t NumberOfRays, + uint_fast64_t MaxNumberOfRays, + bool IncludeSunShape, + bool IncludeErrors, + const glm::dvec3 &PosSunStage, + const RTCScene &embree_scene) { // std::cout << "Thread " << thread_id << " with seed " << seed // << std::endl; @@ -186,7 +187,7 @@ namespace SolTrace::EmbreeRunner } // Get Current Stage - tstage_ptr Stage = System->StageList[i]; + tstage_ptr const& Stage = System->StageList[i]; // Initialize stage variables StageDataArrayIndex = 0; @@ -196,30 +197,35 @@ namespace SolTrace::EmbreeRunner while (StageHasRays) { // Initialize Global Coordinates - double PosRayGlob[3] = {0.0, 0.0, 0.0}; - double CosRayGlob[3] = {0.0, 0.0, 0.0}; + glm::dvec3 PosRayGlob(0.0); + glm::dvec3 CosRayGlob(0.0); // Initialize Stage Coordinates - double PosRayStage[3] = {0.0, 0.0, 0.0}; - double CosRayStage[3] = {0.0, 0.0, 0.0}; + glm::dvec3 PosRayStage(0.0); + glm::dvec3 CosRayStage(0.0); + // Get Ray if (i == 0) { // Make ray (if first stage) - double PosRaySun[3]; - SolTrace::NativeRunner::GenerateRay( - myrng, PosSunStage.data, Stage->Origin, - Stage->RLocToRef, &System->Sun, - PosRayGlob, CosRayGlob, PosRaySun); + glm::dvec3 PosRaySun; + SolTrace::NativeRunner::GenerateRay(myrng, + PosSunStage, + Stage->Origin, + Stage->RLocToRef, + &System->Sun, + PosRayGlob, + CosRayGlob, + PosRaySun); System->SunRayCount++; } else { // Get ray from previous stage RayNumber = IncomingRays[StageDataArrayIndex].Num; - CopyVec3(PosRayGlob, IncomingRays[StageDataArrayIndex].Pos); - CopyVec3(CosRayGlob, IncomingRays[StageDataArrayIndex].Cos); + PosRayGlob = IncomingRays[StageDataArrayIndex].Pos; + CosRayGlob = IncomingRays[StageDataArrayIndex].Cos; StageDataArrayIndex++; } @@ -231,19 +237,23 @@ namespace SolTrace::EmbreeRunner // Initialize internal variables for ray intersection tracing bool RayInStage = true; bool in_multi_hit_loop = false; - double LastPosRaySurfElement[3] = {0.0, 0.0, 0.0}; - double LastCosRaySurfElement[3] = {0.0, 0.0, 0.0}; - double LastPosRaySurfStage[3] = {0.0, 0.0, 0.0}; - double LastCosRaySurfStage[3] = {0.0, 0.0, 0.0}; - double LastDFXYZ[3] = {0.0, 0.0, 0.0}; + + glm::dvec3 LastPosRaySurfElement(0.0); + glm::dvec3 LastCosRaySurfElement(0.0); + glm::dvec3 LastPosRaySurfStage(0.0); + glm::dvec3 LastCosRaySurfStage(0.0); + glm::dvec3 LastDFXYZ(0.0); + uint_fast64_t LastElementNumber = 0; uint_fast64_t LastRayNumber = 0; + int ErrorFlag; int LastHitBackSide; bool StageHit; int MultipleHitCount = 0; - double PosRayOutElement[3] = {0.0, 0.0, 0.0}; - double CosRayOutElement[3] = {0.0, 0.0, 0.0}; + + glm::dvec3 PosRayOutElement(0.0); + glm::dvec3 CosRayOutElement(0.0); // Start Loop to trace ray until it leaves stage bool RayIsAbsorbed = false; @@ -292,12 +302,12 @@ namespace SolTrace::EmbreeRunner if (Stage->Virtual) { // If stage is virtual, there is no interaction - CopyVec3(PosRayOutElement, LastPosRaySurfElement); - CopyVec3(CosRayOutElement, LastCosRaySurfElement); + PosRayOutElement = LastPosRaySurfElement; + CosRayOutElement = LastCosRaySurfElement; } else { - telement_ptr optelm = + telement_ptr const& optelm = Stage->ElementList[LastElementNumber - 1]; if (LastHitBackSide) optics = &optelm->Optics.Back; @@ -451,8 +461,8 @@ namespace SolTrace::EmbreeRunner else { // Ray hit an element, so save it for next stage - CopyVec3(IncomingRays[PreviousStageDataArrayIndex].Pos, PosRayGlob); - CopyVec3(IncomingRays[PreviousStageDataArrayIndex].Cos, CosRayGlob); + IncomingRays[PreviousStageDataArrayIndex].Pos = PosRayGlob; + IncomingRays[PreviousStageDataArrayIndex].Cos = CosRayGlob; IncomingRays[PreviousStageDataArrayIndex].Num = RayNumber; // Is Ray the last in the stage? @@ -477,8 +487,8 @@ namespace SolTrace::EmbreeRunner if (Stage->TraceThrough || MultipleHitCount > 0) { // Ray is saved for the next stage - CopyVec3(IncomingRays[PreviousStageDataArrayIndex].Pos, PosRayGlob); - CopyVec3(IncomingRays[PreviousStageDataArrayIndex].Cos, CosRayGlob); + IncomingRays[PreviousStageDataArrayIndex].Pos = PosRayGlob; + IncomingRays[PreviousStageDataArrayIndex].Cos = CosRayGlob; IncomingRays[PreviousStageDataArrayIndex].Num = RayNumber; // Check if ray is last in stage @@ -579,7 +589,7 @@ namespace SolTrace::EmbreeRunner // Close out any remaining rays as misses unsigned idx = System->StageList.size() - 1; - tstage_ptr Stage = System->StageList[idx]; + tstage_ptr const& Stage = System->StageList[idx]; for (uint_fast64_t k = 0; k < n_rays_active; ++k) { GlobalRay_refactored ray = IncomingRays[k]; diff --git a/coretrace/simulation_runner/embree_runner/trace_embree.hpp b/coretrace/simulation_runner/embree_runner/trace_embree.hpp index 568b1d33..5eacc9b5 100644 --- a/coretrace/simulation_runner/embree_runner/trace_embree.hpp +++ b/coretrace/simulation_runner/embree_runner/trace_embree.hpp @@ -42,7 +42,7 @@ namespace SolTrace::EmbreeRunner uint_fast64_t MaxNumberOfRays, bool IncludeSunShape, bool IncludeErrors, - const SolTrace::Data::Vector3d &PosSunStage, + const glm::dvec3 &PosSunStage, const RTCScene &embree_scene); } // namespace SolTrace::EmbreeRunner diff --git a/coretrace/simulation_runner/native_runner/process_interaction.cpp b/coretrace/simulation_runner/native_runner/process_interaction.cpp index aaf7e63d..bfd15ee6 100644 --- a/coretrace/simulation_runner/native_runner/process_interaction.cpp +++ b/coretrace/simulation_runner/native_runner/process_interaction.cpp @@ -182,8 +182,8 @@ void ProcessInteraction( Epsilon = 0.000005; *ErrorFlag = 0; - for (i = 0; i < 3; i++) - PosOut[i] = PosXYZ[i]; + + PosOut = PosXYZ; switch (Opticl->my_type) { @@ -211,9 +211,11 @@ void ProcessInteraction( } // fresnel equations - UnitDFXYZ[0] = -DFXYZ[0] / sqrt(glm::dot(DFXYZ, DFXYZ)); // unit surface normals - UnitDFXYZ[1] = -DFXYZ[1] / sqrt(glm::dot(DFXYZ, DFXYZ)); - UnitDFXYZ[2] = -DFXYZ[2] / sqrt(glm::dot(DFXYZ, DFXYZ)); + UnitDFXYZ = -glm::normalize(DFXYZ); + // UnitDFXYZ[0] = -DFXYZ[0] / sqrt(glm::dot(DFXYZ, DFXYZ)); // unit surface normals + // UnitDFXYZ[1] = -DFXYZ[1] / sqrt(glm::dot(DFXYZ, DFXYZ)); + // UnitDFXYZ[2] = -DFXYZ[2] / sqrt(glm::dot(DFXYZ, DFXYZ)); + IncidentAngle = acos(glm::dot(CosKLM, UnitDFXYZ)); Rs = sqr(((Refr1 * cos(IncidentAngle) - Refr2 * sqrt(1 - sqr(Refr1 * sin(IncidentAngle) / Refr2)))) / ((Refr1 * cos(IncidentAngle) + Refr2 * sqrt(1 - sqr(Refr1 * sin(IncidentAngle) / Refr2))))); @@ -246,14 +248,16 @@ void ProcessInteraction( // Have converged on Gamma, Compute direction cosines of refracted ray. // Label_Converge: - for (i = 0; i < 3; i++) - CosOut[i] = RMU * CosKLM[i] + Gamn1 * DFXYZ[i]; + CosOut = RMU * CosKLM + Gamn1 * DFXYZ; + // for (i = 0; i < 3; i++) + // CosOut[i] = RMU * CosKLM[i] + Gamn1 * DFXYZ[i]; } else // reflected from surface { A = glm::dot(CosKLM, DFXYZ) / glm::dot(DFXYZ, DFXYZ); - for (i = 0; i < 3; i++) - CosOut[i] = CosKLM[i] - 2.0 * A * DFXYZ[i]; + CosOut = CosKLM - 2.0 * A * DFXYZ; + // for (i = 0; i < 3; i++) + // CosOut[i] = CosKLM[i] - 2.0 * A * DFXYZ[i]; } return; break; @@ -265,8 +269,9 @@ void ProcessInteraction( { A = glm::dot(CosKLM, DFXYZ) / glm::dot(DFXYZ, DFXYZ); // Compute direction cosines for reflected ray - for (i = 0; i < 3; i++) - CosOut[i] = CosKLM[i] - 2.0 * A * DFXYZ[i]; + CosOut = CosKLM - 2.0 * A * DFXYZ; + // for (i = 0; i < 3; i++) + // CosOut[i] = CosKLM[i] - 2.0 * A * DFXYZ[i]; return; break; diff --git a/coretrace/simulation_runner/native_runner/tracing_errors.cpp b/coretrace/simulation_runner/native_runner/tracing_errors.cpp index 2bb28981..8f4c8a72 100644 --- a/coretrace/simulation_runner/native_runner/tracing_errors.cpp +++ b/coretrace/simulation_runner/native_runner/tracing_errors.cpp @@ -49,20 +49,20 @@ void SurfaceNormalErrors(MTRand &myrng, glm::dmat3 RRefToLoc(0.0); glm::dmat3 RLocToRef(0.0); - if (CosIn[2] == 0.0) { - if (CosIn[0] == 0.0) { - Euler[0] = 0.0; - Euler[1] = PI / 2.0; + if (CosIn.z == 0.0) { + if (CosIn.x == 0.0) { + Euler.x = 0.0; + Euler.y = PI / 2.0; } else { - Euler[0] = PI / 2.0; - Euler[1] = atan2(CosIn[1], sqrt(CosIn[0] * CosIn[0] + CosIn[2] * CosIn[2])); + Euler.x = PI / 2.0; + Euler.y = atan2(CosIn.y, sqrt(CosIn.x * CosIn.x + CosIn.z * CosIn.z)); } } else { - Euler[0] = atan2(CosIn[0], CosIn[2]); - Euler[1] = atan2(CosIn[1], sqrt(CosIn[0] * CosIn[0] + CosIn[2] * CosIn[2])); + Euler.x = atan2(CosIn.x, CosIn.z); + Euler.y = atan2(CosIn.y, sqrt(CosIn.x * CosIn.x + CosIn.z * CosIn.z)); } - Euler[2] = 0.0; + Euler.z = 0.0; Data::CalculateTransformMatrices(Euler, RRefToLoc, RLocToRef); @@ -106,15 +106,14 @@ void SurfaceNormalErrors(MTRand &myrng, phi = myrng() * 2.0 * PI; // Therefore have chosen to randomize phi rather than calculate from randomized theta components // obtained from the distribution. The two approaches are equivalent save for this issue with arctan2. wendelin 01-12-11 - CosOut[0] = sin(theta) * cos(phi); - CosOut[1] = sin(theta) * sin(phi); - CosOut[2] = cos(theta); + CosOut = { + sin(theta) * cos(phi), + sin(theta) * sin(phi), + cos(theta) + }; - for (i = 0; i < 3; i++) - { - PosIn[i] = PosOut[i]; - CosIn[i] = CosOut[i]; - } + PosIn = PosOut; + CosIn = CosOut; /*{Transform perturbed ray back to element system}*/ Data::TransformToReference(PosIn, CosIn, Origin, RLocToRef, PosOut, CosOut); @@ -161,26 +160,26 @@ void Errors( glm::dmat3 RRefToLoc(0.0); glm::dmat3 RLocToRef(0.0); - if (CosIn[2] == 0.0) + if (CosIn.z == 0.0) { - if (CosIn[0] == 0.0) + if (CosIn.x == 0.0) { - Euler[0] = 0.0; - Euler[1] = PI / 2.0; + Euler.x = 0.0; + Euler.y = PI / 2.0; } else { - Euler[0] = PI / 2.0; - Euler[1] = atan2(CosIn[1], sqrt(CosIn[0] * CosIn[0] + CosIn[2] * CosIn[2])); + Euler.x = PI / 2.0; + Euler.y = atan2(CosIn.y, sqrt(CosIn.x * CosIn.x + CosIn.z * CosIn.z)); } } else { - Euler[0] = atan2(CosIn[0], CosIn[2]); - Euler[1] = atan2(CosIn[1], sqrt(CosIn[0] * CosIn[0] + CosIn[2] * CosIn[2])); + Euler.x = atan2(CosIn.x, CosIn.z); + Euler.y = atan2(CosIn.y, sqrt(CosIn.x * CosIn.x + CosIn.z * CosIn.z)); } - Euler[2] = 0.0; + Euler.z = 0.0; Data::CalculateTransformMatrices(Euler, RRefToLoc, RLocToRef); @@ -249,7 +248,7 @@ void Errors( i++; if (i == 0) - stest = Sun->SunShapeIntensity[0]; + stest = Sun->SunShapeIntensity[0]; else // linear interpolation (switched from average) 12-20-11 wendelin stest = Sun->SunShapeIntensity[i - 1] + (Sun->SunShapeIntensity[i] - Sun->SunShapeIntensity[i - 1]) * (theta - Sun->SunShapeAngle[i - 1]) / (Sun->SunShapeAngle[i] - Sun->SunShapeAngle[i - 1]); @@ -307,9 +306,9 @@ void Errors( phi = myrng() * 2.0 * PI; // Therefore have chosen to randomize phi rather than calculate from randomized theta components // obtained from the distribution. The two approaches are equivalent save for this issue with arctan2. wendelin 01-12-11 - CosOut[0] = sin(theta) * cos(phi); - CosOut[1] = sin(theta) * sin(phi); - CosOut[2] = cos(theta); + CosOut.x = sin(theta) * cos(phi); + CosOut.y = sin(theta) * sin(phi); + CosOut.z = cos(theta); for (i = 0; i < 3; i++) { diff --git a/google-tests/regression-tests/embree_runner_validation_test.cpp b/google-tests/regression-tests/embree_runner_validation_test.cpp index a0000957..7ee16933 100644 --- a/google-tests/regression-tests/embree_runner_validation_test.cpp +++ b/google-tests/regression-tests/embree_runner_validation_test.cpp @@ -146,9 +146,9 @@ TEST(EmbreeRunner, ValidationTest1) EXPECT_EQ(sts, RunnerStatus::SUCCESS); EXPECT_EQ(result.get_number_of_records(), NRAYS); - Vector3d point, cosines; - Vector3d pos_stage, dir_stage; - Vector3d temp; + glm::dvec3 point, cosines; + glm::dvec3 pos_stage, dir_stage; + glm::dvec3 temp; int_fast64_t element; int_fast64_t stage; uint_fast64_t rayidx; @@ -277,17 +277,17 @@ TEST(EmbreeRunner, ValidationTest1) // if (fabs(pos_stage[0] - stod(ground_raydata[0][i]) > TOL)) // { - // Vector3d pos_csv(stod(ground_raydata[0][i]), + // glm::dvec3 pos_csv(stod(ground_raydata[0][i]), // stod(ground_raydata[1][i]), // stod(ground_raydata[2][i])); - // Vector3d dir_csv(stod(ground_raydata[3][i]), + // glm::dvec3 dir_csv(stod(ground_raydata[3][i]), // stod(ground_raydata[4][i]), // stod(ground_raydata[5][i])); - // Vector3d pos_loc; - // Vector3d dir_loc; + // glm::dvec3 pos_loc; + // glm::dvec3 dir_loc; - // Vector3d csv_glob; + // glm::dvec3 csv_glob; // el->convert_stage_to_local(temp, pos_csv); // el->convert_local_to_global(csv_glob, temp); @@ -468,9 +468,9 @@ TEST(EmbreeRunner, ValidationTest2) // result.write_csv_file("native_runner_result_dump.csv"); - Vector3d point, cosines; - Vector3d pos_stage, dir_stage; - Vector3d temp; + glm::dvec3 point, cosines; + glm::dvec3 pos_stage, dir_stage; + glm::dvec3 temp; int_fast64_t element; int_fast64_t stage; uint_fast64_t rayidx; @@ -610,7 +610,7 @@ TEST(EmbreeRunner, ValidationTest2) // See previous comment about coordinates el->convert_vector_global_to_reference(dir_stage, cosines); - RTOL = vector_norm(pos_stage) * TOL; + RTOL = glm::length(pos_stage) * TOL; EXPECT_NEAR(pos_stage[0], stod(ground_raydata[0][i]), RTOL); EXPECT_NEAR(pos_stage[1], stod(ground_raydata[1][i]), RTOL); EXPECT_NEAR(pos_stage[2], stod(ground_raydata[2][i]), RTOL); @@ -635,17 +635,17 @@ TEST(EmbreeRunner, ValidationTest2) // if (fabs(pos_stage[0] - stod(ground_raydata[0][i]) > TOL)) // { - // Vector3d pos_csv(stod(ground_raydata[0][i]), + // glm::dvec3 pos_csv(stod(ground_raydata[0][i]), // stod(ground_raydata[1][i]), // stod(ground_raydata[2][i])); - // Vector3d dir_csv(stod(ground_raydata[3][i]), + // glm::dvec3 dir_csv(stod(ground_raydata[3][i]), // stod(ground_raydata[4][i]), // stod(ground_raydata[5][i])); - // Vector3d pos_loc; - // Vector3d dir_loc; + // glm::dvec3 pos_loc; + // glm::dvec3 dir_loc; - // Vector3d csv_glob; + // glm::dvec3 csv_glob; // el->convert_stage_to_local(temp, pos_csv); // el->convert_local_to_global(csv_glob, temp); diff --git a/google-tests/unit-tests/simulation_data/cst-templates/CMakeLists.txt b/google-tests/unit-tests/simulation_data/cst-templates/CMakeLists.txt index 66549f30..7331e690 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/CMakeLists.txt +++ b/google-tests/unit-tests/simulation_data/cst-templates/CMakeLists.txt @@ -22,7 +22,7 @@ set(CST_TEST_SRC heliostat_test.cpp ) -if(CMAKE_BUILD_TYPE STREQUAL "Release" OR FULL_FIELD_VALIDATION_TEST) +if(SOLTRACE_BUILD_EMBREE_SUPPORT OR FULL_FIELD_VALIDATION_TEST) list(APPEND CST_TEST_SRC single_heliostat_test.cpp diff --git a/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp index abe9a42b..8d15ee02 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/heliostat_field_test.cpp @@ -7,13 +7,7 @@ #include -// TODO: Replace with configuration define -#if __has_include() -#define USE_EMBREE #include -using SolTrace::EmbreeRunner::EmbreeRunner; -#endif - #include #include #include @@ -31,6 +25,7 @@ using SolTrace::EmbreeRunner::EmbreeRunner; using Heliostat = SolTrace::Data::Heliostat; +using SolTrace::EmbreeRunner::EmbreeRunner; using SolTrace::NativeRunner::NativeRunner; using SolTrace::Runner::RunnerStatus; @@ -70,11 +65,7 @@ class HeliostatFieldSimulation : public ::testing::Test { protected: SimulationData simData; -#ifdef USE_EMBREE EmbreeRunner runner; -#else - NativeRunner runner; -#endif // Sun outputs double sun_width; diff --git a/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp b/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp index 2cb8c5f6..c0548bea 100644 --- a/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp +++ b/google-tests/unit-tests/simulation_data/cst-templates/single_heliostat_test.cpp @@ -2,13 +2,7 @@ #include -// TODO: Replace with configuration define -#if __has_include() -#define USE_EMBREE #include -using SolTrace::EmbreeRunner::EmbreeRunner; -#endif - #include #include #include @@ -26,12 +20,12 @@ using SolTrace::EmbreeRunner::EmbreeRunner; using Heliostat = SolTrace::Data::Heliostat; -using SolTrace::Runner::RunnerStatus; +using SolTrace::EmbreeRunner::EmbreeRunner; using SolTrace::NativeRunner::NativeRunner; - using SolTrace::NativeRunner::TRayData; -using SolTrace::NativeRunner::TSystem; using SolTrace::NativeRunner::TSun; +using SolTrace::NativeRunner::TSystem; +using SolTrace::Runner::RunnerStatus; class SingleHeliostatSimulation : public ::testing::Test { public: @@ -56,12 +50,7 @@ class SingleHeliostatSimulation : public ::testing::Test { protected: SimulationData simData; - -#ifdef USE_EMBREE EmbreeRunner runner; -#else - NativeRunner runner; -#endif double sun_width; double sun_height; diff --git a/google-tests/unit-tests/simulation_runner/embree_runner/embree_runner_test.cpp b/google-tests/unit-tests/simulation_runner/embree_runner/embree_runner_test.cpp index 8b1aaae2..cd03262f 100644 --- a/google-tests/unit-tests/simulation_runner/embree_runner/embree_runner_test.cpp +++ b/google-tests/unit-tests/simulation_runner/embree_runner/embree_runner_test.cpp @@ -29,12 +29,12 @@ TEST(EmbreeRunner, SingleRayValidationTest) double zref = R - sqrt(R * R - (x * x + y * y)); double z = z0 - zref; - Vector3d u(0.0, 0.0, -1.0); - Vector3d v(2.0 * x, 2.0 * y, -2.0 * (z0 - z - R)); - v.make_unit(); - Vector3d w; - double alpha = dot_product(u, v); - vector_add(1.0, u, -2.0 * alpha, v, w); + glm::dvec3 u(0.0, 0.0, -1.0); + glm::dvec3 v(2.0 * x, 2.0 * y, -2.0 * (z0 - z - R)); + v = glm::normalize(v); + + double alpha = glm::dot(u, v); + glm::dvec3 w = u - (2.0 * alpha * v); SimulationData sd; @@ -54,8 +54,8 @@ TEST(EmbreeRunner, SingleRayValidationTest) sd.add_ray_source(sun); auto sph = SolTrace::Data::make_element(); - Vector3d origin(0.0, 0.0, z0); - Vector3d aim(0.0, 0.0, -1.0); + glm::dvec3 origin(0.0, 0.0, z0); + glm::dvec3 aim(0.0, 0.0, -1.0); double zrot = 0.0; sph->set_reference_frame_geometry(origin, aim, zrot); sph->set_aperture(SolTrace::Data::make_aperture(20.0)); @@ -66,8 +66,8 @@ TEST(EmbreeRunner, SingleRayValidationTest) sd.add_element(sph); auto para = SolTrace::Data::make_element(); - origin.set_values(0.0, 0.0, -1.0); - aim.set_values(0.0, 0.0, 0.0); + origin = {0.0, 0.0, -1.0}; + aim = {0.0, 0.0, 0.0}; zrot = 0.0; para->set_reference_frame_geometry(origin, aim, zrot); para->set_aperture(SolTrace::Data::make_aperture(31.0, 31.0)); @@ -97,12 +97,11 @@ TEST(EmbreeRunner, SingleRayValidationTest) EXPECT_EQ(n, 3); - Vector3d ipoint, idir; + glm::dvec3 ipoint, idir; int element, stage; uint_fast64_t raynum; SolTrace::Result::RayEvent rev; - sys->RayData.Query(0, ipoint.data, idir.data, - &element, &stage, &raynum, &rev); + sys->RayData.Query(0, ipoint, idir, &element, &stage, &raynum, &rev); EXPECT_EQ(raynum, 1); EXPECT_EQ(rev, SolTrace::Result::RayEvent::CREATE); @@ -115,8 +114,7 @@ TEST(EmbreeRunner, SingleRayValidationTest) EXPECT_NEAR(idir[1], u[1], TOL); EXPECT_NEAR(idir[2], u[2], TOL); - sys->RayData.Query(1, ipoint.data, idir.data, - &element, &stage, &raynum, &rev); + sys->RayData.Query(1, ipoint, idir, &element, &stage, &raynum, &rev); EXPECT_EQ(raynum, 1); EXPECT_EQ(rev, SolTrace::Result::RayEvent::REFLECT); @@ -170,8 +168,8 @@ TEST(EmbreeRunner, PowerTowerSmokeTest) st0->set_origin(0.0, 0.0, 0.0); st0->set_aim_vector(0.0, 0.0, 1.0); - Vector3d rvec, svec, avec; - Vector3d aim, pos; + glm::dvec3 rvec, svec, avec; + glm::dvec3 aim, pos; const int NUM_ELEMENTS = 10; for (int k = 0; k < NUM_ELEMENTS; ++k) @@ -180,17 +178,15 @@ TEST(EmbreeRunner, PowerTowerSmokeTest) foptics = el->get_front_optical_properties(); foptics->reflectivity = 1.0; - pos.set_values(5 * sin(k * PI * 2.0 / NUM_ELEMENTS), - 5 * cos(k * PI * 2.0 / NUM_ELEMENTS), - 0.0); - vector_add(1.0, absorber->get_origin_global(), - -1.0, pos, - rvec); - make_unit_vector(rvec); - svec = sun->get_position(); - make_unit_vector(svec); - vector_add(0.5, rvec, 0.5, svec, avec); - vector_add(1.0, pos, 100.0, avec, aim); + pos = { + 5 * sin(k * PI * 2.0 / NUM_ELEMENTS), + 5 * cos(k * PI * 2.0 / NUM_ELEMENTS), + 0.0 + }; + rvec = glm::normalize(absorber->get_origin_global() - pos); + svec = glm::normalize(sun->get_position()); + avec = 0.5 * rvec + 0.5 * svec; + aim = pos + 100.0 * avec; el->set_reference_frame_geometry(pos, aim, 0.0); From 02bb568b3e9f26b810de0ce007734390cc39953b Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sun, 8 Feb 2026 14:57:19 -0700 Subject: [PATCH 15/23] Improve embree test This could still fail for very fast machines --- coretrace/simulation_runner/embree_runner/trace_embree.cpp | 3 +++ .../embree_runner/embree_runner_multithreading_test.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/coretrace/simulation_runner/embree_runner/trace_embree.cpp b/coretrace/simulation_runner/embree_runner/trace_embree.cpp index 7835e3d2..db529102 100644 --- a/coretrace/simulation_runner/embree_runner/trace_embree.cpp +++ b/coretrace/simulation_runner/embree_runner/trace_embree.cpp @@ -605,6 +605,9 @@ namespace SolTrace::EmbreeRunner // System->SunRayCount is atomic so this is thread safe System->SunRayCount += sun_ray_count_local; + if (manager->terminate(thread_id)) + return RunnerStatus::CANCEL; + return RunnerStatus::SUCCESS; } diff --git a/google-tests/unit-tests/simulation_runner/embree_runner/embree_runner_multithreading_test.cpp b/google-tests/unit-tests/simulation_runner/embree_runner/embree_runner_multithreading_test.cpp index 7d9eedb6..b735fae7 100644 --- a/google-tests/unit-tests/simulation_runner/embree_runner/embree_runner_multithreading_test.cpp +++ b/google-tests/unit-tests/simulation_runner/embree_runner/embree_runner_multithreading_test.cpp @@ -73,7 +73,7 @@ TEST(EmbreeRunner, CancelMultithread) auto fsts = std::async(&EmbreeRunner::run_simulation, &runner); // Give time to start processing - std::this_thread::sleep_for(std::chrono::milliseconds(500)); + std::this_thread::sleep_for(std::chrono::milliseconds(250)); sts = runner.status_simulation(); EXPECT_EQ(sts, RunnerStatus::RUNNING); From 7cfbb2bd035ffe4c496c71c2130ca012c70ea299 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sun, 8 Feb 2026 15:02:41 -0700 Subject: [PATCH 16/23] Header fixes GCC --- coretrace/simulation_data/utilities.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/coretrace/simulation_data/utilities.hpp b/coretrace/simulation_data/utilities.hpp index 968955b3..d142d44d 100644 --- a/coretrace/simulation_data/utilities.hpp +++ b/coretrace/simulation_data/utilities.hpp @@ -3,6 +3,7 @@ #define SOLTRACE_UTILITIES_H #include +#include #include #include From 2bedb97b1bb26fd10fca074f1e1d7a1282336210 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sun, 8 Feb 2026 15:50:51 -0700 Subject: [PATCH 17/23] Timing for coverage --- .../simulation_runner/native_runner/native_runner_test.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/google-tests/unit-tests/simulation_runner/native_runner/native_runner_test.cpp b/google-tests/unit-tests/simulation_runner/native_runner/native_runner_test.cpp index be02aec1..7bdbd40e 100644 --- a/google-tests/unit-tests/simulation_runner/native_runner/native_runner_test.cpp +++ b/google-tests/unit-tests/simulation_runner/native_runner/native_runner_test.cpp @@ -504,7 +504,13 @@ TEST(NativeRunner, StatusAndCancelSingleThread) std::chrono::duration dur = t1 - t0; EXPECT_EQ(fsts.get(), RunnerStatus::CANCEL); + + // succeeds in release, fails in some coverage tests +#ifndef NDEBUG + EXPECT_LT(dur.count(), 10000.0); +#else EXPECT_LT(dur.count(), 2000.0); +#endif std::cout << "Time for run: " << dur.count() << std::endl; std::cout << "Progress before cancel: " << prog << std::endl; From 68cdd49300f7b055ed11cff53c96affcca901546 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sun, 8 Feb 2026 16:08:53 -0700 Subject: [PATCH 18/23] Wider bands for CI --- .../native_runner/thread_manager_test.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/google-tests/unit-tests/simulation_runner/native_runner/thread_manager_test.cpp b/google-tests/unit-tests/simulation_runner/native_runner/thread_manager_test.cpp index 0e420c40..6fadbae9 100644 --- a/google-tests/unit-tests/simulation_runner/native_runner/thread_manager_test.cpp +++ b/google-tests/unit-tests/simulation_runner/native_runner/thread_manager_test.cpp @@ -14,6 +14,10 @@ using SolTrace::NativeRunner::thread_manager_ptr; using SolTrace::NativeRunner::ThreadManager; using SolTrace::NativeRunner::trace_logger_ptr; +//TODO: +// - Add thread launch barrier +// - Change test strat to not be on fixed wall times for CI + // "Runs" nsteps step where each step takes at least tlen milliseconds // checking the manager to see if it needs to terminate early after // each step @@ -55,8 +59,8 @@ ThreadManager::ThreadStatus error_task(thread_manager_ptr manager, TEST(ThreadManager, CleanExit) { const unsigned NTHREADS = 2; - const uint_fast64_t NSTEPS = 5; - const uint_fast64_t T_MS = 100; + const uint_fast64_t NSTEPS = 10; + const uint_fast64_t T_MS = 250; auto logger = make_trace_logger(); auto manager = make_thread_manager(logger); @@ -87,8 +91,8 @@ TEST(ThreadManager, CleanExit) TEST(ThreadManager, ErrorExit) { const unsigned NTHREADS = 2; - const uint_fast64_t NSTEPS = 5; - const uint_fast64_t T_MS = 100; + const uint_fast64_t NSTEPS = 10; + const uint_fast64_t T_MS = 250; auto logger = make_trace_logger(); auto manager = make_thread_manager(logger); @@ -127,8 +131,8 @@ TEST(ThreadManager, ErrorExit) TEST(ThreadManager, CancelExit) { const unsigned NTHREADS = 2; - const uint_fast64_t NSTEPS = 5; - const uint_fast64_t T_MS = 100; + const uint_fast64_t NSTEPS = 10; + const uint_fast64_t T_MS = 250; auto logger = make_trace_logger(); auto manager = make_thread_manager(logger); From fcf8b59110027d55017d3e82ca874107f1128829 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sun, 8 Feb 2026 16:37:21 -0700 Subject: [PATCH 19/23] Trying a fix for a weird coverage error --- .github/workflows/coverage.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index a818b3e0..98da663c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -42,6 +42,9 @@ jobs: -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DSOLTRACE_BUILD_CORETRACE=OFF -DSOLTRACE_BUILD_GUI=OFF + -DCMAKE_C_FLAGS="--coverage -O0 -g -fprofile-update=atomic" + -DCMAKE_CXX_FLAGS="--coverage -O0 -g -fprofile-update=atomic" + -DCMAKE_EXE_LINKER_FLAGS="--coverage" -DENABLE_COVERAGE=ON -DSOLTRACE_BUILD_EMBREE_SUPPORT=ON -S ${{ github.workspace }} From 4ebee8d39dbe1284a1064efe9878e365f5329d80 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Sun, 8 Feb 2026 18:00:52 -0700 Subject: [PATCH 20/23] Trying one more coverage fix --- .github/workflows/coverage.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 98da663c..20c10e80 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -42,9 +42,6 @@ jobs: -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DSOLTRACE_BUILD_CORETRACE=OFF -DSOLTRACE_BUILD_GUI=OFF - -DCMAKE_C_FLAGS="--coverage -O0 -g -fprofile-update=atomic" - -DCMAKE_CXX_FLAGS="--coverage -O0 -g -fprofile-update=atomic" - -DCMAKE_EXE_LINKER_FLAGS="--coverage" -DENABLE_COVERAGE=ON -DSOLTRACE_BUILD_EMBREE_SUPPORT=ON -S ${{ github.workspace }} @@ -60,7 +57,7 @@ jobs: working-directory: ${{ steps.strings.outputs.build-output-dir }} run: | # Capture coverage info; ignore mismatches to prevent geninfo line errors - lcov --capture --directory . --output-file coverage.info --ignore-errors unused + lcov --capture --directory . --output-file coverage.info --ignore-errors unused --rc geninfo_unexecuted_blocks=1 # Remove unwanted directories (3rd-party, deps) lcov --remove coverage.info '*/_deps/*' '*/nlohmann_json-src/*' '/usr/*' --output-file coverage.info --ignore-errors unused From ecf2a3f3eb467773d8c2878d635ecc4707025deb Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Mon, 9 Feb 2026 07:18:29 -0700 Subject: [PATCH 21/23] Another tweak. If this fails, we move to ignore negatives --- coretrace/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coretrace/CMakeLists.txt b/coretrace/CMakeLists.txt index eb1afb42..af7982ed 100644 --- a/coretrace/CMakeLists.txt +++ b/coretrace/CMakeLists.txt @@ -99,7 +99,7 @@ else(MSVC) add_compile_definitions(_DEBUG) if (NOT APPLE AND ENABLE_COVERAGE) # SET(CMAKE_CXX_FLAGS "-O0 -coverage -fkeep-inline-functions") - SET(CMAKE_CXX_FLAGS "-O0 --coverage") + SET(CMAKE_CXX_FLAGS "-O0 --coverage -fprofile-update=atomic") endif() else() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -DNDEBUG" ) From 10f0cfab4b65b253587591a41407aa127b5d8be8 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Mon, 9 Feb 2026 08:00:19 -0700 Subject: [PATCH 22/23] Ignore negatives for the moment --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 20c10e80..7b99b53d 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -57,7 +57,7 @@ jobs: working-directory: ${{ steps.strings.outputs.build-output-dir }} run: | # Capture coverage info; ignore mismatches to prevent geninfo line errors - lcov --capture --directory . --output-file coverage.info --ignore-errors unused --rc geninfo_unexecuted_blocks=1 + lcov --capture --directory . --output-file coverage.info --ignore-errors unused,negative --rc geninfo_unexecuted_blocks=1 # Remove unwanted directories (3rd-party, deps) lcov --remove coverage.info '*/_deps/*' '*/nlohmann_json-src/*' '/usr/*' --output-file coverage.info --ignore-errors unused From 6ec5c5a10864888d47288d90c0090bbcab86faa9 Mon Sep 17 00:00:00 2001 From: Nicholas Brunhart-Lupo Date: Wed, 11 Feb 2026 10:42:13 -0700 Subject: [PATCH 23/23] Address review comments --- .../embree_runner/bbox_calculator.cpp | 4 +--- .../native_runner/pt_optimizations.cpp | 16 ++++++++-------- .../optix_runner/gpu_tower_demo.cpp | 2 +- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/coretrace/simulation_runner/embree_runner/bbox_calculator.cpp b/coretrace/simulation_runner/embree_runner/bbox_calculator.cpp index 6a6b88d0..67270dca 100644 --- a/coretrace/simulation_runner/embree_runner/bbox_calculator.cpp +++ b/coretrace/simulation_runner/embree_runner/bbox_calculator.cpp @@ -273,8 +273,6 @@ namespace SolTrace::EmbreeRunner auto PosDumGlob = st_stage->RLocToRef * coord_stage; coord_global = PosDumGlob + st_stage->Origin; - for (int i = 0; i < 3; i++) - coord_global[i] = PosDumGlob[i] + st_stage->Origin[i]; return; } @@ -335,7 +333,7 @@ namespace SolTrace::EmbreeRunner z_minmax.y); // Expand bounding boxes slightly to account for float precision - glm::dvec2 expand = {1e-3f, -1e-3f}; + glm::dvec2 expand = {-1e-3f, 1e-3f}; x_minmax += expand; y_minmax += expand; z_minmax += expand; diff --git a/coretrace/simulation_runner/native_runner/pt_optimizations.cpp b/coretrace/simulation_runner/native_runner/pt_optimizations.cpp index f4ce69b7..dcdf9c89 100644 --- a/coretrace/simulation_runner/native_runner/pt_optimizations.cpp +++ b/coretrace/simulation_runner/native_runner/pt_optimizations.cpp @@ -233,15 +233,15 @@ namespace SolTrace::NativeRunner // Ray info const bool in_multi_hit_loop, - const glm::dvec3& PosRayStage, - const glm::dvec3& reccm_helio, - st_hash_tree* rec_hash, + const glm::dvec3 &PosRayStage, + const glm::dvec3 &reccm_helio, + st_hash_tree *rec_hash, - const std::vector& sunint_elements, + const std::vector &suntint_elements, // Outputs - std::vector& reflint_elements, - bool& has_elements) + std::vector &reflint_elements, + bool &has_elements) { uint_fast64_t nintelements = 0; @@ -276,8 +276,8 @@ namespace SolTrace::NativeRunner { // First time through - checking for sun ray intersections if (has_elements) - nintelements = sunint_elements.size(); - else + nintelements = suntint_elements.size(); + else nintelements = 0; } } diff --git a/google-tests/unit-tests/simulation_runner/optix_runner/gpu_tower_demo.cpp b/google-tests/unit-tests/simulation_runner/optix_runner/gpu_tower_demo.cpp index dc8af7a4..40ff88e3 100644 --- a/google-tests/unit-tests/simulation_runner/optix_runner/gpu_tower_demo.cpp +++ b/google-tests/unit-tests/simulation_runner/optix_runner/gpu_tower_demo.cpp @@ -81,7 +81,7 @@ TEST(GpuTowerDemo, OptixRunnerWithStages) 5 * cos(i * spacing), 0.0}; el->set_origin(pos); - rvec = glm::normalize(absorber->get_origin_global() - pos); + rvec = glm::normalize(absorber->get_origin_global() - pos); svec = glm::normalize(sun->get_position()); avec = 0.5 * rvec + 0.5 * svec;