BELFEM 0.9.0
Berkeley Lab Finite Element Framework
Loading...
Searching...
No Matches
fn_circle_from_points.hpp
Go to the documentation of this file.
1/*
2 * BELFEM -- The Berkeley Lab Finite Element Framework
3 * Copyright (c) 2026, The Regents of the University of California,
4 * through Lawrence Berkeley National Laboratory (subject to receipt of any required
5 * approvals from the U.S. Dept. of Energy). All rights reserved.
6 *
7 * Developers: Christian Messe, Gregory Giard
8 *
9 * See the top-level LICENSE file for the complete license and disclaimer.
10 */
11
12#ifndef BELFEM_FN_CIRCLE_FROM_POINTS_HPP
13#define BELFEM_FN_CIRCLE_FROM_POINTS_HPP
14
15#include "typedefs.hpp"
16#include "assert.hpp"
17#include "cl_Vector.hpp"
18#include "cl_Matrix.hpp"
19#include "fn_gesv.hpp"
20#include "fn_norm.hpp"
21namespace belfem
22{
23//------------------------------------------------------------------------------
24
25 // aCircle : { Xm, Ym, R }
26 inline void
28 const Vector< real > & aX,
29 const Vector< real > & aY,
30 Vector< real > & aCircle )
31 {
32 BELFEM_ASSERT( aX.length() == 3, "aX must have length 3 " );
33 BELFEM_ASSERT( aY.length() == 3, "aX must have length 3 " );
34 // initial solution by intersecting two lines
35 // calculated by creating lines between 0-1 and 1-2 and intersecting
36 // the normals
37 aCircle.set_size( 3 );
38
39
40 // initial guess for Xm
41 aCircle( 0 ) = aX(2)*aX(2)*(aY(0) - aY(1))
42 + (aX(0)*aX(0) + (aY(0) - aY(1))*(aY(0) - aY(2)))*(aY(1) - aY(2))
43 + aX(1)*aX(1)*(aY(2) + aY(0) );
44
45 // initial guess for Ym
46 aCircle( 1 ) = -(aX(1)*aX(1)*aX(2)) + aX(0)*aX(0)*(-aX(1) + aX(2))
47 + aX(2)*(aY(0) - aY(1))*(aY(0) + aY(1)) + aX(0)*(aX(1)*aX(1)
48 - aX(2)*aX(2) + aY(1)*aY(1) - aY(2)*aY(2)) + aX(1)
49 *(aX(2)*aX(2) - aY(0)*aY(0) + aY(2)*aY(2));
50
51 real tDiv = 2.0*(aX(2)*(aY(0) - aY(1)) + aX(0)*(aY(1)
52 - aY(2)) + aX(1)*(aY(2) + aY(0)));
53
54 aCircle( 0 ) /= tDiv;
55 aCircle( 1 ) /= tDiv;
56
57 // initial guess for radius
58 aCircle( 2 ) = ( std::sqrt(
59 std::pow( aX( 0 ) - aCircle( 0 ), 2 )
60 + std::pow( aY( 0 ) - aCircle( 1 ), 2 ) )
61 + std::sqrt(
62 std::pow( aX( 1 ) - aCircle( 0 ), 2 )
63 + std::pow( aY( 1 ) - aCircle( 1 ), 2 ) )
64 + std::sqrt(
65 std::pow( aX( 2 ) - aCircle( 0 ), 2 )
66 + std::pow( aY( 2 ) - aCircle( 1 ), 2 ) ) ) / 3.0;
67
68
69 real tResidual = BELFEM_REAL_MAX;
70
71 // initial counter
72 uint tCount = 0;
73
74 // Jacobian
75 Matrix< real > tJ( 3, 3 );
76
77 // right hand side
78 Vector< real > tF ( 3 );
79
80 // for gesv
81 Vector< int_t > tP( 3 );
82
83 const real tEpsilon = 1e-9;
84
85 while( tResidual > tEpsilon )
86 {
87 tJ( 0, 0 ) = aCircle( 0 ) - aX( 0 );
88 tJ( 1, 0 ) = aCircle( 0 ) - aX( 1 );
89 tJ( 2, 0 ) = aCircle( 0 ) - aX( 2 );
90 tJ( 0, 1 ) = aCircle( 1 ) - aY( 0 );
91 tJ( 1, 1 ) = aCircle( 1 ) - aY( 1 );
92 tJ( 2, 1 ) = aCircle( 1 ) - aY( 2 );
93 tJ( 0, 2 ) = -aCircle( 2 );
94 tJ( 1, 2 ) = -aCircle( 2 );
95 tJ( 2, 2 ) = -aCircle( 2 );
96
97 tJ *= 2.0;
98
99 tF( 0 ) = std::pow( aX( 0 ) - aCircle( 0 ), 2 )
100 + std::pow( aY( 0 ) - aCircle( 1 ), 2 )
101 - aCircle( 2 ) *aCircle( 2 );
102
103 tF( 1 ) = std::pow( aX( 1 ) - aCircle( 0 ), 2 )
104 + std::pow( aY( 1 ) - aCircle( 1 ), 2 )
105 - aCircle( 2 ) *aCircle( 2 );
106
107 tF( 2 ) = std::pow( aX( 2 ) - aCircle( 0 ), 2 )
108 + std::pow( aY( 2 ) - aCircle( 1 ), 2 )
109 - aCircle( 2 ) *aCircle( 2 );
110
111 tResidual = norm( tF );
112
113 if( tResidual > tEpsilon )
114 {
115
116 gesv( tJ, tF, tP );
117
118 aCircle -= 0.9 * tF;
119 }
120 else
121 {
122 break;
123 }
124
125 BELFEM_ERROR( tCount++ < 1000,
126 "Infinite loop while trying to find circle" );
127
128 }
129 }
130
131//------------------------------------------------------------------------------
132}
133#endif //BELFEM_FN_CIRCLE_FROM_POINTS_HPP
#define BELFEM_ERROR(aCheck,...)
Definition assert.hpp:264
#define BELFEM_ASSERT(aCheck,...)
Definition assert.hpp:244
void set_size(const size_t aNumRows)
change the size of the vector
Definition cl_AR_Vector.hpp:237
size_t length() const
get the length of the vector
Definition cl_AR_Vector.hpp:257
Solves a square linear system by LU factorization (LAPACK ?gesv).
Euclidean length of a vector.
auto norm(const Vector< T > &aA) -> decltype(norm(aA.vector_data()))
Euclidean (L2) norm of a vector.
Definition fn_norm.hpp:56
USER GUIDES:
Definition cl_Capacitor.cpp:16
unsigned int uint
Definition typedefs.hpp:30
int_t gesv(Matrix< T > &A, Vector< T > &B, Vector< int_t > &Pivot, const bool AbortOnError=true)
solve the square linear system A * x = b via LAPACK ?gesv ( LU factorization with partial pivoting )
Definition fn_gesv.hpp:222
double real
Definition typedefs.hpp:36
void circle_from_points(const Vector< real > &aX, const Vector< real > &aY, Vector< real > &aCircle)
Definition fn_circle_from_points.hpp:27
#define BELFEM_REAL_MAX
Definition typedefs.hpp:81