1 #include "moab/LocalDiscretization/SpectralQuad.hpp"
2 #include "moab/Forward.hpp"
3
4 namespace moab
5 {
6
7
8 int SpectralQuad::_n;
9 real* SpectralQuad::_z[2];
10 lagrange_data SpectralQuad::_ld[2];
11 opt_data_2 SpectralQuad::_data;
12 real* SpectralQuad::_odwork;
13 real* SpectralQuad::_glpoints;
14 bool SpectralQuad::_init = false;
15
16 SpectralQuad::SpectralQuad() : Map( 0 ) {}
17
18 SpectralQuad::SpectralQuad( int order, double* x, double* y, double* z ) : Map( 0 )
19 {
20 Init( order );
21 _xyz[0] = x;
22 _xyz[1] = y;
23 _xyz[2] = z;
24 }
25 SpectralQuad::SpectralQuad( int order ) : Map( 4 )
26 {
27 Init( order );
28 _xyz[0] = _xyz[1] = _xyz[2] = NULL;
29 }
30 SpectralQuad::~SpectralQuad()
31 {
32 if( _init ) freedata();
33 _init = false;
34 }
35 void SpectralQuad::Init( int order )
36 {
37 if( _init && _n == order ) return;
38 if( _init && _n != order )
39 {
40
41 freedata();
42 }
43
44 _init = true;
45 _n = order;
46
47 for( int d = 0; d < 2; d++ )
48 {
49 _z[d] = tmalloc( double, _n );
50 lobatto_nodes( _z[d], _n );
51 lagrange_setup( &_ld[d], _z[d], _n );
52 }
53 opt_alloc_2( &_data, _ld );
54
55 unsigned int nf = _n * _n, ne = _n, nw = 2 * _n * _n + 3 * _n;
56 _odwork = tmalloc( double, 6 * nf + 9 * ne + nw );
57 _glpoints = tmalloc( double, 3 * nf );
58 }
59
60 void SpectralQuad::freedata()
61 {
62 for( int d = 0; d < 2; d++ )
63 {
64 free( _z[d] );
65 lagrange_free( &_ld[d] );
66 }
67 opt_free_2( &_data );
68 free( _odwork );
69 free( _glpoints );
70 }
71
72 void SpectralQuad::set_gl_points( double* x, double* y, double* z )
73 {
74 _xyz[0] = x;
75 _xyz[1] = y;
76 _xyz[2] = z;
77 }
78 CartVect SpectralQuad::evalFcn( const double* params,
79 const double* field,
80 const int ndim,
81 const int num_tuples,
82 double* work,
83 double* result )
84 {
85
86 int d = 0;
87 for( d = 0; d < 2; d++ )
88 {
89 lagrange_0( &_ld[d], params[d] );
90 }
91 CartVect result;
92 for( d = 0; d < 3; d++ )
93 {
94 result[d] = tensor_i2( _ld[0].J, _ld[0].n, _ld[1].J, _ld[1].n, _xyz[d], _odwork );
95 }
96 return result;
97 }
98
99 bool SpectralQuad::reverseEvalFcn( const double* posn,
100 const double* verts,
101 const int nverts,
102 const int ndim,
103 const double iter_tol,
104 const double inside_tol,
105 double* work,
106 double* params,
107 int* is_inside )
108 {
109 params = init;
110
111
112 double x_star[3];
113 xyz.get( x_star );
114
115 double r[2] = { 0, 0 };
116 unsigned c = opt_no_constraints_3;
117 double dist = opt_findpt_2( &_data, (const double**)_xyz, x_star, r, &c );
118
119 if( dist > 0.9e+30 )
120 {
121 std::vector< CartVect > dummy;
122 throw Map::EvaluationError( CartVect( x_star ), dummy );
123 }
124
125
126
127 params = r;
128
129 return insideFcn( params, 2, inside_tol );
130 }
131
132 Matrix3 SpectralQuad::jacobian( const double* params,
133 const double* verts,
134 const int nverts,
135 const int ndim,
136 double* work,
137 double* result )
138 {
139
140 Matrix3 J( 0. );
141 return J;
142 }
143
144 void SpectralQuad::evaluate_vector( const CartVect& params, const double* field, int num_tuples, double* eval ) const
145 {
146
147 int d;
148 for( d = 0; d < 2; d++ )
149 {
150 lagrange_0( &_ld[d], params[d] );
151 }
152
153 *eval = tensor_i2( _ld[0].J, _ld[0].n, _ld[1].J, _ld[1].n, field, _odwork );
154 }
155 void SpectralQuad::integrate_vector( const double* field,
156 const double* verts,
157 const int nverts,
158 const int ndim,
159 const int num_tuples,
160 double* work,
161 double* result )
162 {
163
164 }
165
166 int SpectralQuad::insideFcn( const double* params, const int ndim, const double tol )
167 {
168 return EvalSet::inside( params, ndim, tol );
169 }
170
171
172
173 void SpectralQuad::compute_gl_positions()
174 {
175
176
177
178 assert( this->vertex.size() == 4 );
179 static double corner_params[4][2] = { { -1., -1. }, { 1., -1. }, { 1., 1. }, { -1., 1. } };
180
181 int indexGL = 0;
182 int n2 = _n * _n;
183 for( int i = 0; i < _n; i++ )
184 {
185 double csi = _z[0][i];
186 for( int j = 0; j < _n; j++ )
187 {
188 double eta = _z[1][j];
189 CartVect pos( 0.0 );
190 for( int k = 0; k < 4; k++ )
191 {
192 const double N_k = ( 1 + csi * corner_params[k][0] ) * ( 1 + eta * corner_params[k][1] );
193 pos += N_k * vertex[k];
194 }
195 pos *= 0.25;
196 _glpoints[indexGL] = pos[0];
197 _glpoints[indexGL + n2] = pos[1];
198 _glpoints[indexGL + 2 * n2] = pos[2];
199 indexGL++;
200 }
201 }
202
203 _xyz[0] = &( _glpoints[0] );
204 _xyz[1] = &( _glpoints[n2] );
205 _xyz[2] = &( _glpoints[2 * n2] );
206 }
207 void SpectralQuad::get_gl_points( double*& x, double*& y, double*& z, int& size )
208 {
209 x = (double*)_xyz[0];
210 y = (double*)_xyz[1];
211 z = (double*)_xyz[2];
212 size = _n * _n;
213 }
214
215 }