1 /**
2  * \file NETGeographicLib/SphericalHarmonic2.cpp
3  * \brief Implementation for NETGeographicLib::SphericalHarmonic2 class
4  *
5  * NETGeographicLib is copyright (c) Scott Heiman (2013)
6  * GeographicLib is Copyright (c) Charles Karney (2010-2012)
7  * <charles@karney.com> and licensed under the MIT/X11 License.
8  * For more information, see
9  * https://geographiclib.sourceforge.io/
10  **********************************************************************/
11 #include "stdafx.h"
12 #include "GeographicLib/SphericalHarmonic2.hpp"
13 #include "SphericalHarmonic2.h"
14 #include "CircularEngine.h"
15 #include "SphericalCoefficients.h"
16 #include "NETGeographicLib.h"
17 
18 using namespace NETGeographicLib;
19 
20 const char BADALLOC[] = "Failed to allocate memory for a GeographicLib::SphericalHarmonic2";
21 
22 //*****************************************************************************
23 SphericalHarmonic2::!SphericalHarmonic2(void)
24 {
25     if ( m_pSphericalHarmonic2 != NULL )
26     {
27         delete m_pSphericalHarmonic2;
28         m_pSphericalHarmonic2 = NULL;
29     }
30 
31     if ( m_C != NULL )
32     {
33         for ( int i = 0; i < m_numCoeffVectors; i++ )
34             if ( m_C[i] != NULL )
35                 delete m_C[i];
36         delete [] m_C;
37         m_C = NULL;
38     }
39 
40     if ( m_S != NULL )
41     {
42         for ( int i = 0; i < m_numCoeffVectors; i++ )
43             if ( m_S[i] != NULL )
44                 delete m_S[i];
45         delete [] m_S;
46         m_S = NULL;
47     }
48 }
49 
50 //*****************************************************************************
51 SphericalHarmonic2::SphericalHarmonic2(array<double>^ C,
52                                         array<double>^ S,
53                                         int N,
54                                         array<double>^ C1,
55                                         array<double>^ S1,
56                                         int N1,
57                                         array<double>^ C2,
58                                         array<double>^ S2,
59                                         int N2,
60                                         double a,
61                                         Normalization norm )
62 {
63     try
64     {
65         m_C = new std::vector<double>*[m_numCoeffVectors];
66         for ( int i = 0; i < m_numCoeffVectors; i++ ) m_C[i] = new std::vector<double>();
67         m_S = new std::vector<double>*[m_numCoeffVectors];
68         for ( int i = 0; i < m_numCoeffVectors; i++ ) m_S[i] = new std::vector<double>();
69         for each ( double x in C ) m_C[0]->push_back( x );
70         for each ( double x in S ) m_S[0]->push_back( x );
71         for each ( double x in C1 ) m_C[1]->push_back( x );
72         for each ( double x in S1 ) m_S[1]->push_back( x );
73         for each ( double x in C2 ) m_C[2]->push_back( x );
74         for each ( double x in S2 ) m_S[2]->push_back( x );
75         m_pSphericalHarmonic2 = new GeographicLib::SphericalHarmonic2( *m_C[0], *m_S[0], N,
76             *m_C[1], *m_S[1], N1, *m_C[2], *m_S[2], N2, a, (unsigned)norm);
77     }
78     catch ( std::bad_alloc )
79     {
80         throw gcnew GeographicErr( BADALLOC );
81     }
82     catch ( const std::exception& err )
83     {
84         throw gcnew GeographicErr( err.what() );
85     }
86     catch ( System::Exception^ sxpt )
87     {
88         throw gcnew GeographicErr( sxpt->Message );
89     }
90 }
91 
92 //*****************************************************************************
93 SphericalHarmonic2::SphericalHarmonic2(array<double>^ C,
94                                         array<double>^ S,
95                                         int N, int nmx, int mmx,
96                                         array<double>^ C1,
97                                         array<double>^ S1,
98                                         int N1, int nmx1, int mmx1,
99                                         array<double>^ C2,
100                                         array<double>^ S2,
101                                         int N2, int nmx2, int mmx2,
102                                         double a,
103                                         Normalization norm )
104 {
105     try
106     {
107         m_C = new std::vector<double>*[m_numCoeffVectors];
108         for ( int i = 0; i < m_numCoeffVectors; i++ ) m_C[i] = new std::vector<double>();
109         m_S = new std::vector<double>*[m_numCoeffVectors];
110         for ( int i = 0; i < m_numCoeffVectors; i++ ) m_S[i] = new std::vector<double>();
111         for each ( double x in C ) m_C[0]->push_back( x );
112         for each ( double x in S ) m_S[0]->push_back( x );
113         for each ( double x in C1 ) m_C[1]->push_back( x );
114         for each ( double x in S1 ) m_S[1]->push_back( x );
115         for each ( double x in C2 ) m_C[2]->push_back( x );
116         for each ( double x in S2 ) m_S[2]->push_back( x );
117         m_pSphericalHarmonic2 = new GeographicLib::SphericalHarmonic2( *m_C[0], *m_S[0], N,
118             nmx, mmx, *m_C[1], *m_S[1], N1, nmx1, mmx1, *m_C[2], *m_S[2], N2, nmx2, mmx2, a,
119             (unsigned)norm );
120     }
121     catch ( std::bad_alloc )
122     {
123         throw gcnew GeographicErr( BADALLOC );
124     }
125     catch ( const std::exception& err )
126     {
127         throw gcnew GeographicErr( err.what() );
128     }
129     catch ( System::Exception^ sxpt )
130     {
131         throw gcnew GeographicErr( sxpt->Message );
132     }
133 }
134 
135 //*****************************************************************************
HarmonicSum(double tau1,double tau2,double x,double y,double z)136 double SphericalHarmonic2::HarmonicSum(double tau1, double tau2, double x, double y, double z)
137 {
138     return m_pSphericalHarmonic2->operator()( tau1, tau2, x, y, z );
139 }
140 
141 //*****************************************************************************
142 double SphericalHarmonic2::HarmonicSum(double tau1, double tau2, double x, double y, double z,
143                         [System::Runtime::InteropServices::Out] double% gradx,
144                         [System::Runtime::InteropServices::Out] double% grady,
145                         [System::Runtime::InteropServices::Out] double% gradz)
146 {
147     double lgradx, lgrady, lgradz;
148     double out = m_pSphericalHarmonic2->operator()( tau1, tau2, x, y, z,
149         lgradx, lgrady, lgradz );
150     gradx = lgradx;
151     grady = lgrady;
152     gradz = lgradz;
153     return out;
154 }
155 
156 //*****************************************************************************
157 CircularEngine^ SphericalHarmonic2::Circle(double tau1, double tau2, double p,
158     double z, bool gradp)
159 {
160     try
161     {
162         return gcnew CircularEngine( m_pSphericalHarmonic2->Circle( tau1, tau2, p, z, gradp ) );
163     }
164     catch ( std::bad_alloc )
165     {
166         throw gcnew GeographicErr( "Memory allocation error in SphericalHarmonic2::Circle" );
167     }
168 }
169 
170 //*****************************************************************************
171 SphericalCoefficients^ SphericalHarmonic2::Coefficients()
172 {
173     return gcnew SphericalCoefficients( m_pSphericalHarmonic2->Coefficients() );
174 }
175 
176 //*****************************************************************************
177 SphericalCoefficients^ SphericalHarmonic2::Coefficients1()
178 {
179     return gcnew SphericalCoefficients( m_pSphericalHarmonic2->Coefficients1() );
180 }
181 
182 //*****************************************************************************
183 SphericalCoefficients^ SphericalHarmonic2::Coefficients2()
184 {
185     return gcnew SphericalCoefficients( m_pSphericalHarmonic2->Coefficients2() );
186 }
187