Phyth v0.1.0
A dimensional safe C++ header-only mechanics and electromagnetics simulation library.
Loading...
Searching...
No Matches
CurrentSegment.hpp
Go to the documentation of this file.
1#ifndef PHYTH_CURRENT_SEGMENT_HPP
2#define PHYTH_CURRENT_SEGMENT_HPP
3
4#include "MagneticSource.hpp"
6#include <cmath>
7#include <stdexcept>
8
33 public:
47 const auto delta = end_ - start_;
48 length_ = delta.Length();
49
51 throw std::invalid_argument("CurrentSegment: segment length must be non-zero");
52 }
53
55 }
56
70 if (IsPointOnWire(point)) {
71 throw std::runtime_error("CurrentSegment: point lies on the wire axis");
72 }
73
74 return AnalyticSolution(point);
75 }
76
79 return current_;
80 }
81
84 return length_;
85 }
86
89 return start_;
90 }
91
94 return end_;
95 }
96
97 private:
103
124 const auto r_vec = point - start_;
125 const auto proj = r_vec.Dot(direction_);
126
127 const auto perp_vec = r_vec - proj * direction_;
128 const auto rho = perp_vec.Length();
129
130 // If point is on the wire axis, field is undefined.
131 // Return zero instead of blowing up.
132 if (rho < Config::epsilon * length_) {
133 return Vector3<Quantity<Tesla> >{0_T, 0_T, 0_T};
134 }
135
136 const auto z1 = -proj;
137 const auto z2 = length_ - proj;
138
139 const auto rho2 = rho * rho;
140 const auto term1 = z2 / Utils::sqrt(rho2 + z2 * z2);
141 const auto term2 = z1 / Utils::sqrt(rho2 + z1 * z1);
142 const auto angular_factor = term1 - term2;
143
144 const auto B_mag = Consts::mu_0 * current_ / (4 * Consts::pi * rho) * angular_factor;
145
146 const auto perp_hat = perp_vec.Normalized();
147 const auto phi_hat = direction_.Cross(perp_hat);
148
149 return B_mag * phi_hat;
150 }
151
161 [[nodiscard]] bool
163 const auto r_vec = point - start_;
164 const auto proj = r_vec.Dot(direction_);
165
166 const auto tol = Quantity(
168 );
169
171 return false;
172 }
173
174 const auto perp_vec = r_vec - proj * direction_;
175 const auto rho = perp_vec.Length();
176
177 return rho < tol;
178 }
179
190 const auto v = point - start_;
191 const auto proj = v.Dot(direction_);
192
193 if (proj <= Quantity<Meter>(0)) {
194 return v.Length();
195 }
196
197 if (proj >= length_) {
198 return (point - end_).Length();
199 }
200
201 const auto closest = start_ + proj * direction_;
202 return (point - closest).Length();
203 }
204 };
205}
206
207#endif // PHYTH_CURRENT_SEGMENT_HPP
Magnetic field from a straight current-carrying wire segment.
Vector3< Quantity< Tesla > > GetMagneticFieldAt(const Vector3< Quantity< Meter > > &point) const override
Compute the magnetic field at a point.
CurrentSegment(const Vector3< Quantity< Meter > > &start, const Vector3< Quantity< Meter > > &end, const Quantity< Ampere > &current)
Construct a current segment from start to end.
Vector3< Quantity< Meter > > start_
bool IsPointOnWire(const Vector3< Quantity< Meter > > &point) const
Check if a point lies on the wire segment.
const Vector3< Quantity< Meter > > & GetStart() const
const Vector3< Quantity< Meter > > & GetEnd() const
Vector3< Quantity< Tesla > > AnalyticSolution(const Vector3< Quantity< Meter > > &point) const
Closed-form Biot-Savart solution for a finite straight wire.
Quantity< Meter > GetMinimumDistanceTo(const Vector3< Quantity< Meter > > &point) const
Compute the minimum distance from a point to the wire segment.
Vector3< Quantity< Meter > > end_
Quantity< Ampere > GetCurrent() const
Abstract base class for all magnetic field sources.
double epsilon
Definition Config.hpp:13
constexpr auto mu_0
constexpr double pi
Definition Constants.hpp:5
auto sqrt(Quantity< UnitT > q)
Square root of a quantity.
Quantity< UnitT > max(Quantity< UnitT > x, Quantity< UnitT > y)
Maximum of two quantities.
constexpr bool is_unit_v
Definition Unit.hpp:79
Physical quantity with a value and a compile-time unit.
Definition Quantity.hpp:27
3D vector with Quantity components
Definition Vector3.hpp:28