-
Christof Metzger-Kraus authoredChristof Metzger-Kraus authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
RingSectionTest.cpp 9.27 KiB
/*
* Copyright (c) 2014, Chris Rogers
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STFC nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <algorithm>
#include "gtest/gtest.h"
#include "opal_src/Utilities/MockComponent.h"
#include "Physics/Physics.h"
#include "Utilities/RingSection.h"
#include "opal_test_utilities/SilenceTest.h"
TEST(RingSectionTest, TestConstructDestruct) {
OpalTestUtilities::SilenceTest silencer;
RingSection ors;
MockComponent* compNull = NULL;
Vector_t vec0(0, 0, 0);
EXPECT_EQ(ors.getComponent(), compNull);
EXPECT_EQ(ors.getStartPosition(), vec0);
EXPECT_EQ(ors.getStartNormal(), vec0);
EXPECT_EQ(ors.getEndPosition(), vec0);
EXPECT_EQ(ors.getEndNormal(), vec0);
EXPECT_EQ(ors.getComponentPosition(), vec0);
EXPECT_EQ(ors.getComponentOrientation(), vec0);
EXPECT_EQ(ors.getVirtualBoundingBox(), std::vector<Vector_t>(4, vec0));
RingSection ors_comp;
MockComponent comp;
ors_comp.setComponent(&comp);
// and implicit destructors; should not double free comp;
}
TEST(RingSectionTest, TestIsOnOrPastStartPlane) {
OpalTestUtilities::SilenceTest silencer;
RingSection ors;
ors.setStartPosition(Vector_t(0., 1., 0.));
ors.setStartNormal(Vector_t(1., 0., 0.));
Vector_t vec1(1e-9, 1.e-9, 0.);
Vector_t vec2(-1e-9, 1.e-9, 0.);
Vector_t vec3(1e-9, -1.e-9, 0.); // other side of the ring
Vector_t vec4(-1e-9, -1.e-9, 0.); // other side of the ring
Vector_t vec5(1e-9, 1.e9, 0.); // large radius
Vector_t vec6(-1e-9, 1.e9, 0.); // large radius
EXPECT_TRUE(ors.isOnOrPastStartPlane(vec1));
EXPECT_FALSE(ors.isOnOrPastStartPlane(vec2));
EXPECT_FALSE(ors.isOnOrPastStartPlane(vec3));
EXPECT_FALSE(ors.isOnOrPastStartPlane(vec4));
EXPECT_TRUE(ors.isOnOrPastStartPlane(vec5));
EXPECT_FALSE(ors.isOnOrPastStartPlane(vec6));
ors.setStartNormal(Vector_t(-1., 0., 0.)); // rotate 180 degrees
EXPECT_FALSE(ors.isOnOrPastStartPlane(vec1));
EXPECT_TRUE(ors.isOnOrPastStartPlane(vec2));
EXPECT_FALSE(ors.isOnOrPastStartPlane(vec3));
EXPECT_FALSE(ors.isOnOrPastStartPlane(vec4));
EXPECT_FALSE(ors.isOnOrPastStartPlane(vec5));
EXPECT_TRUE(ors.isOnOrPastStartPlane(vec6));
ors.setStartPosition(Vector_t(-1., -1., 0.));
ors.setStartNormal(Vector_t(1., -0.5, 0.));
Vector_t vec7(-1.1e-9, 1.e-9, 0.); // this side of the ring
Vector_t vec8(-0.9e-9, 1.e-9, 0.); // other side of the ring
Vector_t vec9(-0.5-1e-9, 0., 0.); // behind normal
Vector_t vec10(-0.5+1e-9, 0., 0.); // in front of normal
EXPECT_TRUE(ors.isOnOrPastStartPlane(vec7));
EXPECT_FALSE(ors.isOnOrPastStartPlane(vec8));
EXPECT_FALSE(ors.isOnOrPastStartPlane(vec9));
EXPECT_TRUE(ors.isOnOrPastStartPlane(vec10));
}
TEST(RingSectionTest, TestIsPastEndPlane) {
OpalTestUtilities::SilenceTest silencer;
RingSection ors;
ors.setEndPosition(Vector_t(0., 1., 0.));
ors.setEndNormal(Vector_t(1., 0., 0.));
Vector_t vec1(1e-9, 1.e-9, 0.);
Vector_t vec2(-1e-9, 1.e-9, 0.);
Vector_t vec3(1e-9, -1.e-9, 0.); // other side of the ring
Vector_t vec4(-1e-9, -1.e-9, 0.); // other side of the ring
Vector_t vec5(1e-9, 1.e9, 0.); // large radius
Vector_t vec6(-1e-9, 1.e9, 0.); // large radius
EXPECT_TRUE(ors.isPastEndPlane(vec1));
EXPECT_FALSE(ors.isPastEndPlane(vec2));
EXPECT_FALSE(ors.isPastEndPlane(vec3));
EXPECT_FALSE(ors.isPastEndPlane(vec4));
EXPECT_TRUE(ors.isPastEndPlane(vec5));
EXPECT_FALSE(ors.isPastEndPlane(vec6));
ors.setEndNormal(Vector_t(-1., 0., 0.)); // rotate 180 degrees
EXPECT_FALSE(ors.isPastEndPlane(vec1));
EXPECT_TRUE(ors.isPastEndPlane(vec2));
EXPECT_FALSE(ors.isPastEndPlane(vec3));
EXPECT_FALSE(ors.isPastEndPlane(vec4));
EXPECT_FALSE(ors.isPastEndPlane(vec5));
EXPECT_TRUE(ors.isPastEndPlane(vec6));
ors.setEndPosition(Vector_t(-1., -1., 0.));
ors.setEndNormal(Vector_t(1., -0.5, 0.));
Vector_t vec7(-1.1e-9, 1.e-9, 0.); // this side of the ring
Vector_t vec8(-0.9e-9, 1.e-9, 0.); // other side of the ring
Vector_t vec9(-0.5-1e-9, 0., 0.); // behind normal
Vector_t vec10(-0.5+1e-9, 0., 0.); // in front of normal
EXPECT_TRUE(ors.isPastEndPlane(vec7));
EXPECT_FALSE(ors.isPastEndPlane(vec8));
EXPECT_FALSE(ors.isPastEndPlane(vec9));
EXPECT_TRUE(ors.isPastEndPlane(vec10));
}
TEST(RingSectionTest, TestGetFieldValue) {
OpalTestUtilities::SilenceTest silencer;
RingSection ors;
MockComponent comp;
ors.setComponent(&comp);
Vector_t centre(-1.33, +1.66, 0.);
for (double theta = -3.*Physics::pi; theta < 3.*Physics::pi; theta += Physics::pi/6.) {
Vector_t orientation(0., 0., theta);
ors.setComponentOrientation(orientation);
ors.setComponentPosition(centre);
double c = cos(orientation(2));
double s = -sin(orientation(2));
for (double x = 0.01; x < 1.; x += 0.1)
for (double y = 0.01; y < 1.; y += 0.1)
for (double z = -0.01; z > -1.; z -= 0.1) {
Vector_t offset(c*x+s*y, -s*x+c*y, z);
Vector_t pos = centre+offset;
Vector_t centroid, B, E;
double t = 0;
EXPECT_FALSE(ors.getFieldValue(pos, centroid, t, E, B));
Vector_t bfield(c*x+s*y, -s*x+c*y, z);
for (int l = 0; l < 3; ++l) {
EXPECT_NEAR(B(l), +bfield(l), 1e-6);
EXPECT_NEAR(E(l), -bfield(l), 1e-6);
}
}
}
}
bool sort_comparator(Vector_t v1, Vector_t v2) {
if (fabs(v1(0) - v2(0)) < 1e-6) {
if (fabs(v1(1) - v2(1)) < 1e-6) {
return v1(2) > v2(2);
}
return v1(1) > v2(1);
}
return v1(0) > v2(0);
}
TEST(RingSectionTest, TestGetVirtualBoundingBox) {
OpalTestUtilities::SilenceTest silencer;
RingSection ors;
ors.setStartPosition(Vector_t(3, -1, 99));
ors.setStartNormal(Vector_t(-4, -1, -1000));
ors.setEndPosition(Vector_t(2, 1, 77));
ors.setEndNormal(Vector_t(-1, 1, 655));
std::vector<Vector_t> bb = ors.getVirtualBoundingBox();
std::vector<Vector_t> bbRef;
bbRef.push_back(Vector_t(0.99*sqrt(10)/(-sqrt(17))+3.,
0.99*sqrt(10)*4./(+sqrt(17))-1., 99.));
bbRef.push_back(Vector_t(0.99*sqrt(10)/(+sqrt(17))+3.,
0.99*sqrt(10)*4./(-sqrt(17))-1., 99.));
bbRef.push_back(Vector_t(0.99*sqrt(5)/(+sqrt(2))+2.,
0.99*sqrt(5)/(+sqrt(2))+1., 77.));
bbRef.push_back(Vector_t(0.99*sqrt(5)/(-sqrt(2))+2.,
0.99*sqrt(5)/(-sqrt(2))+1., 77.));
std::sort(bb.begin(), bb.end(), sort_comparator);
std::sort(bbRef.begin(), bbRef.end(), sort_comparator);
EXPECT_EQ(bb.size(), bbRef.size());
for (size_t i = 0; i < bb.size(); ++i) {
for (size_t j = 0; j < 3; ++j)
EXPECT_NEAR(bb[i](j), bbRef[i](j), 1e-6);
}
}
RingSection buildORS(double r, double phi1, double phi2) {
RingSection ors;
ors.setStartPosition(Vector_t(sin(phi1)*r, cos(phi1)*r, 0.));
ors.setStartNormal(Vector_t(cos(phi1), -sin(phi1), 0.));
ors.setEndPosition(Vector_t(sin(phi2)*r, cos(phi2)*r, 0.));
ors.setEndNormal(Vector_t(cos(phi2), -sin(phi2), 0.));
return ors;
}
TEST(RingSectionTest, TestDoesOverlap) {
OpalTestUtilities::SilenceTest silencer;
double f1 = 1.0*Physics::pi/6.;
double f2 = 0.5*Physics::pi/6.;
double f3 = -0.5*Physics::pi/6.;
double f4 = -1.0*Physics::pi/6.;
double r = 3.;
RingSection ors1 = buildORS(r, f1, f3);
EXPECT_TRUE(ors1.doesOverlap(f2, f2));
EXPECT_FALSE(ors1.doesOverlap(f4, f4));
RingSection ors2 = buildORS(r, f1, f4);
EXPECT_TRUE(ors2.doesOverlap(f2, f3));
RingSection ors3 = buildORS(r, f2, f3);
EXPECT_TRUE(ors3.doesOverlap(f2, f3));
EXPECT_FALSE(ors3.doesOverlap(f1, f1));
EXPECT_FALSE(ors3.doesOverlap(f4, f4));
}