G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsApproxC1Utils.h
Go to the documentation of this file.
1 
13 #pragma once
14 
15 
16 #include <gsCore/gsFunctionSet.h>
17 
18 namespace gismo
19 {
20 
21 void createGluingDataSpace(const gsGeometry<real_t> & patch, const gsBasis<real_t> & basis, index_t dir,
22  gsBSplineBasis<real_t> & result, index_t p_tilde, index_t r_tilde);
23 
24 void createPlusSpace(const gsGeometry<real_t> & patch, gsBasis<real_t> & basis, index_t dir, gsBSplineBasis<real_t> & res_plus);
25 
26 void createMinusSpace(const gsGeometry<real_t> & patch, gsBasis<real_t> & basis, index_t dir, gsBSplineBasis<real_t> & res_minus);
27 
28 void createEdgeSpace(const gsGeometry<real_t> & patch, gsBasis<real_t> & basis, index_t dir, gsBSplineBasis<real_t> & basis_plus,
29  gsBSplineBasis<real_t> & basis_minus, gsBSplineBasis<real_t> & basis_gD, gsTensorBSplineBasis<2, real_t> & result);
30 
31 void createEdgeSpace(const gsGeometry<real_t> & patch, gsBasis<real_t> & basis, index_t dir, gsBSplineBasis<real_t> & basis_plus,
32  gsBSplineBasis<real_t> & basis_minus, gsTensorBSplineBasis<2, real_t> & result);
33 
34 void createVertexSpace(const gsGeometry<real_t> & patch, gsBasis<real_t> & basis, bool isInterface_1, bool isInterface_2,
35  gsTensorBSplineBasis<2, real_t> & result, index_t p_tilde, index_t r_tilde);
36 
37 // Input is parametric coordinates of 1-D \a mp
38 template <class T>
39 class gsAlpha : public gismo::gsFunction<T>
40 {
41 
42 protected:
43  gsGeometry<T> & _geo;
44  mutable gsMapData<T> _tmp;
45  index_t m_uv;
46 
47 
48 public:
50  typedef memory::shared_ptr< gsAlpha > Ptr;
51 
53  typedef memory::unique_ptr< gsAlpha > uPtr;
54 
55  gsAlpha(gsGeometry<T> & geo, index_t uv) :
56  _geo(geo), m_uv(uv), _alpha_piece(nullptr)
57  {
58  _tmp.flags = NEED_JACOBIAN;
59  }
60 
61  ~gsAlpha() { delete _alpha_piece; }
62 
63  GISMO_CLONE_FUNCTION(gsAlpha)
64 
65  short_t domainDim() const {return 1;}
66 
67  short_t targetDim() const {return 1;}
68 
69  mutable gsAlpha<T> * _alpha_piece; // why do we need this?
70 
71  const gsFunction<T> & piece(const index_t k) const
72  {
73  //delete _alpha_piece;
74  _alpha_piece = new gsAlpha(*this);
75  return *_alpha_piece;
76  }
77 
78  // Input is parametric coordinates of 1-D \a mp
79  void eval_into(const gsMatrix<T>& u, gsMatrix<T>& result) const
80  {
81  result.resize( targetDim() , u.cols() );
82 
83  if(_geo.parDim() == _geo.targetDim()) // Planar
84  {
85  gsMatrix<T> uv, ev, D0;
86  uv.setZero(2, u.cols());
87  uv.row(m_uv) = u; // u
88 
89  T gamma = 1.0;
90 
91  for (index_t i = 0; i < uv.cols(); i++) {
92  _geo.jacobian_into(uv.col(i), ev);
93  uv(0, i) = gamma * ev.determinant();
94  }
95  result = uv.row(0);
96  }
97  else if(_geo.parDim() + 1 == _geo.targetDim()) // Surface
98  {
99  gsMatrix<T> uv, ev, D0, N, Duv;
100  uv.setZero(2, u.cols());
101  uv.row(m_uv) = u; // u
102 
103  for (index_t i = 0; i < uv.cols(); i++) {
104  N.setZero(3,1);
105  _geo.deriv_into(uv.col(i), ev);
106  N.row(0) = ev.row(2) * ev.row(5) - ev.row(4) * ev.row(3);
107  N.row(1) = ev.row(4) * ev.row(1) - ev.row(0) * ev.row(5);
108  N.row(2) = ev.row(0) * ev.row(3) - ev.row(2) * ev.row(1);
109 
110  D0.setZero(3,3);
111  Duv.setZero(3,1);
112  if (m_uv == 0) // u
113  {
114  Duv.row(0) = ev.row(0);
115  Duv.row(1) = ev.row(2);
116  Duv.row(2) = ev.row(4);
117  D0.col(0) = Duv;
118  D0.col(2) = N;
119  D0(0,1) = ev(1,0);
120  D0(1,1) = ev(3,0);
121  D0(2,1) = ev(5,0);
122  }
123  else if (m_uv == 1) // v
124  {
125  Duv.row(0) = ev.row(1);
126  Duv.row(1) = ev.row(3);
127  Duv.row(2) = ev.row(5);
128  D0.col(1) = Duv;
129  D0.col(2) = N;
130  D0(0,0) = ev(0,0);
131  D0(1,0) = ev(2,0);
132  D0(2,0) = ev(4,0);
133  }
134  uv(0, i) = 1.0 / Duv.norm() * gsEigen::numext::sqrt(D0.determinant());
135  }
136  result = uv.row(0);
137  //gsDebugVar(result);
138  //gsDebugVar(m_uv);
139  }
140  }
141 };
142 
143 
144 template <class T>
145 class gsBeta : public gismo::gsFunction<T>
146 {
147 
148 protected:
149  gsGeometry<T> & _geo;
150  mutable gsMapData<T> _tmp;
151  index_t m_uv;
152 
153 
154 public:
156  typedef memory::shared_ptr< gsBeta > Ptr;
157 
159  typedef memory::unique_ptr< gsBeta > uPtr;
160 
161  gsBeta(gsGeometry<T> & geo, index_t uv) :
162  _geo(geo), m_uv(uv), _beta_piece(nullptr)
163  {
164  _tmp.flags = NEED_JACOBIAN;
165  }
166 
167  ~gsBeta() { delete _beta_piece; }
168 
169  GISMO_CLONE_FUNCTION(gsBeta)
170 
171  short_t domainDim() const {return 1;}
172 
173  short_t targetDim() const {return 1;}
174 
175  mutable gsBeta<T> * _beta_piece; // why do we need this?
176 
177  const gsFunction<T> & piece(const index_t k) const
178  {
179  //delete _beta_piece;
180  _beta_piece = new gsBeta(*this);
181  return *_beta_piece;
182  }
183 
184  // Input is parametric coordinates of 1-D \a mp
185  void eval_into(const gsMatrix<T>& u, gsMatrix<T>& result) const
186  {
187  result.resize( targetDim() , u.cols() );
188 
189  if(_geo.parDim() == _geo.targetDim()) // Planar
190  {
191  gsMatrix<T> uv, ev, D0;
192 
193  uv.setZero(2,u.cols());
194  uv.row(m_uv) = u; // u
195 
196  T gamma = 1.0;
197 
198  for(index_t i = 0; i < uv.cols(); i++)
199  {
200  _geo.jacobian_into(uv.col(i),ev);
201  D0 = ev.col(m_uv);
202  T D1 = T(1.0)/ D0.norm();
203  uv(0,i) = - gamma * D1 * D1 * ev.col(1).transpose() * ev.col(0);
204  }
205  result = uv.row(0);
206  }
207  else if(_geo.parDim() + 1 == _geo.targetDim()) // Surface
208  {
209  gsMatrix<T> uv, ev, D0;
210 
211  uv.setZero(2,u.cols());
212  uv.row(m_uv) = u; // u
213 
214  T gamma = 1.0;
215 
216  for(index_t i = 0; i < uv.cols(); i++)
217  {
218  _geo.jacobian_into(uv.col(i),ev);
219  D0 = ev.col(m_uv);
220  T D1 = T(1.0)/ D0.norm();
221  uv(0,i) = - gamma * D1 * D1 * ev.col(1).transpose() * ev.col(0);
222  }
223  result = uv.row(0);
224  //gsDebugVar(result);
225  //gsDebugVar(m_uv);
226  }
227  }
228 
229 };
230 
231 template <class T>
232 class gsTraceBasis : public gismo::gsFunction<T>
233 {
234 
235 protected:
236  gsGeometry<T> & _geo;
237 
238  gsBSpline<T> m_basis_beta;
239  gsBSplineBasis<T> m_basis_plus;
240 
241  gsBasis<T> & m_basis;
242 
243  mutable gsMapData<T> _tmp;
244 
245  bool m_isboundary;
246  const index_t m_bfID, m_uv;
247 
248 
249 public:
251  typedef memory::shared_ptr< gsTraceBasis > Ptr;
252 
254  typedef memory::unique_ptr< gsTraceBasis > uPtr;
255 
256  gsTraceBasis(gsGeometry<T> & geo,
257  gsBSpline<T> basis_beta,
258  gsBSplineBasis<T> basis_plus,
259  gsBasis<T> & basis,
260  bool isboundary,
261  const index_t bfID,
262  const index_t uv) :
263  _geo(geo), m_basis_beta(basis_beta), m_basis_plus(basis_plus), m_basis(basis),
264  m_isboundary(isboundary), m_bfID(bfID), m_uv(uv), _traceBasis_piece(nullptr)
265  {
266  //_tmp.flags = NEED_JACOBIAN;
267 
268  //createPlusSpace(geo, basis, m_uv, m_basis_plus); // Not efficient
269  }
270 
271  ~gsTraceBasis() { delete _traceBasis_piece; }
272 
273  GISMO_CLONE_FUNCTION(gsTraceBasis)
274 
275  short_t domainDim() const {return 2;}
276 
277  short_t targetDim() const {return 1;}
278 
279  mutable gsTraceBasis<T> * _traceBasis_piece; // why do we need this?
280 
281  const gsFunction<T> & piece(const index_t k) const
282  {
283  //delete _traceBasis_piece;
284  _traceBasis_piece = new gsTraceBasis(*this);
285  return *_traceBasis_piece;
286  }
287 
288  // Input is parametric coordinates of 2-D \a mp
289  void eval_into(const gsMatrix<T>& u, gsMatrix<T>& result) const
290  {
291  result.resize( targetDim() , u.cols() );
292 
293  // tau/p
294  gsBSplineBasis<T> bsp_temp = dynamic_cast<gsBSplineBasis<T> & >(m_basis.component(1-m_uv));
295 
296  T p = bsp_temp.degree();
297  T tau_1 = bsp_temp.knots().at(p + 1); // p + 2
298 
299  gsMatrix<T> beta, N_0, N_1, N_i_plus, der_N_i_plus;
300 
301  if (!m_isboundary)
302  m_basis_beta.eval_into(u.row(m_uv),beta); // 1-dir == PatchID
303  else
304  beta.setZero(1, u.cols());
305 
306  m_basis.component(1-m_uv).evalSingle_into(0,u.row(1-m_uv),N_0); // u
307  m_basis.component(1-m_uv).evalSingle_into(1,u.row(1-m_uv),N_1); // u
308 
309  m_basis_plus.evalSingle_into(m_bfID,u.row(m_uv),N_i_plus); // v
310  m_basis_plus.derivSingle_into(m_bfID,u.row(m_uv),der_N_i_plus);
311 
312  gsMatrix<T> temp = beta.cwiseProduct(der_N_i_plus);
313  result = N_i_plus.cwiseProduct(N_0 + N_1) - temp.cwiseProduct(N_1) * tau_1 / p;
314  }
315 
316 };
317 
318 
319 template <class T>
320 class gsNormalDerivBasis : public gismo::gsFunction<T>
321 {
322 
323 protected:
324  gsGeometry<T> & _geo;
325 
326  gsBSpline<T> m_basis_alpha;
327  gsBSplineBasis<T> m_basis_minus;
328 
329  gsBasis<T> & m_basis;
330 
331  mutable gsMapData<T> _tmp;
332 
333  bool m_isboundary;
334  const index_t m_bfID, m_uv;
335 
336 
337 public:
339  typedef memory::shared_ptr< gsNormalDerivBasis > Ptr;
340 
342  typedef memory::unique_ptr< gsNormalDerivBasis > uPtr;
343 
344  gsNormalDerivBasis(gsGeometry<T> & geo,
345  gsBSpline<T> basis_alpha,
346  gsBSplineBasis<T> basis_minus,
347  gsBasis<T> & basis,
348  bool isboundary,
349  const index_t bfID,
350  const index_t uv) :
351  _geo(geo), m_basis_alpha(basis_alpha), m_basis_minus(basis_minus), m_basis(basis),
352  m_isboundary(isboundary), m_bfID(bfID), m_uv(uv), _normalDerivBasis_piece(nullptr)
353  {
354  //_tmp.flags = NEED_JACOBIAN;
355  //createMinusSpace(geo, basis, m_uv, m_basis_minus);
356  }
357 
358  ~gsNormalDerivBasis() { delete _normalDerivBasis_piece; }
359 
360  GISMO_CLONE_FUNCTION(gsNormalDerivBasis)
361 
362  short_t domainDim() const {return 2;}
363 
364  short_t targetDim() const {return 1;}
365 
366  mutable gsNormalDerivBasis<T> * _normalDerivBasis_piece; // why do we need this?
367 
368  const gsFunction<T> & piece(const index_t k) const
369  {
370  //delete _normalDerivBasis_piece;
371  _normalDerivBasis_piece = new gsNormalDerivBasis(*this);
372  return *_normalDerivBasis_piece;
373  }
374 
375  // Input is parametric coordinates of 2-D \a mp
376  void eval_into(const gsMatrix<T>& u, gsMatrix<T>& result) const
377  {
378  result.resize( targetDim() , u.cols() );
379 
380  // tau/p
381  gsBSplineBasis<T> bsp_temp = dynamic_cast<gsBSplineBasis<T> & >(m_basis.component(1-m_uv));
382 
383  T p = bsp_temp.degree();
384  T tau_1 = bsp_temp.knots().at(p + 1); // p + 2
385 
386  gsMatrix<T> alpha, N_1, N_j_minus;
387 
388  if (!m_isboundary)
389  m_basis_alpha.eval_into(u.row(m_uv),alpha); // 1-dir == PatchID
390  else
391  alpha.setOnes(1, u.cols());
392 
393  m_basis.component(1-m_uv).evalSingle_into(1,u.row(1-m_uv),N_1); // u
394 
395  m_basis_minus.evalSingle_into(m_bfID,u.row(m_uv),N_j_minus); // v
396 
397  if (!m_isboundary)
398  result = (m_uv == 0 ? T(-1.0) : T(1.0)) * alpha.cwiseProduct(N_j_minus.cwiseProduct(N_1)) * tau_1 / p;
399  else
400  result = (m_uv == 0 ? T(-1.0) : T(1.0)) * alpha.cwiseProduct(N_j_minus.cwiseProduct(N_1));
401  }
402 
403 };
404 
405 
406 template <class T>
407 class gsVertexBasis : public gismo::gsFunction<T>
408 {
409 
410 protected:
411  const gsGeometry<T> & m_geo;
412  gsBasis<T> & m_basis;
413 
414  std::vector<gsBSpline<T>> m_alpha;
415  std::vector<gsBSpline<T>> m_beta;
416 
417  std::vector<gsBSplineBasis<T>> m_basis_plus;
418  std::vector<gsBSplineBasis<T>> m_basis_minus;
419 
420  const gsMatrix<T> m_Phi;
421  const std::vector<bool> m_kindOfEdge;
422 
423  const index_t m_bfID;
424 
425  mutable gsMapData<T> _tmp;
426 
427 public:
429  typedef memory::shared_ptr< gsVertexBasis > Ptr;
430 
432  typedef memory::unique_ptr< gsVertexBasis > uPtr;
433 
434  gsVertexBasis(const gsGeometry<T> & geo,
435  gsBasis<T> & basis,
436  std::vector<gsBSpline<T>> alpha,
437  std::vector<gsBSpline<T>> beta,
438  std::vector<gsBSplineBasis<T>> basis_plus,
439  std::vector<gsBSplineBasis<T>> basis_minus,
440  const gsMatrix<T> Phi,
441  const std::vector<bool> kindOfEdge,
442  const index_t bfID
443  ) : m_geo(geo), m_basis(basis), m_alpha(alpha), m_beta(beta), m_basis_plus(basis_plus), m_basis_minus(basis_minus),
444  m_Phi(Phi), m_kindOfEdge(kindOfEdge), m_bfID(bfID),
445  _vertexBasis_piece(nullptr)
446  {
447 
448  }
449 
450  ~gsVertexBasis() { delete _vertexBasis_piece; }
451 
452  GISMO_CLONE_FUNCTION(gsVertexBasis)
453 
454  short_t domainDim() const {return 2;}
455 
456  short_t targetDim() const {return 1;}
457 
458  mutable gsVertexBasis<T> * _vertexBasis_piece; // why do we need this?
459 
460  const gsFunction<T> & piece(const index_t k) const
461  {
462  //delete _vertexBasis_piece;
463  _vertexBasis_piece = new gsVertexBasis(*this);
464  return *_vertexBasis_piece;
465  }
466 
467  // Input is parametric coordinates of 2-D \a mp
468  // TODO IMPROVE THE FUNCTION
469  void eval_into(const gsMatrix<T>& u, gsMatrix<T>& result) const
470  {
471  result.resize( targetDim() , u.cols() );
472  result.setZero();
473 
474  // Computing c, c+ and c-
475  // Point zero
476  gsMatrix<T> zero;
477  zero.setZero(2,1);
478 
479  std::vector<gsMatrix<T>> c_0, c_1;
480  std::vector<gsMatrix <T>> c_0_plus, c_1_plus, c_2_plus;
481  std::vector<gsMatrix <T>> c_0_plus_deriv, c_1_plus_deriv, c_2_plus_deriv;
482  std::vector<gsMatrix <T>> c_0_minus, c_1_minus;
483  for (index_t i = 0; i < 2; i++) // i == 0 == u , i == 1 == v
484  {
485  gsMatrix<T> b_0, b_1;
486  gsMatrix<T> b_0_plus, b_1_plus, b_2_plus;
487  gsMatrix<T> b_0_plus_deriv, b_1_plus_deriv, b_2_plus_deriv;
488  gsMatrix<T> b_0_minus, b_1_minus;
489 
490  //gsBSplineBasis<T> bsp_temp = dynamic_cast<gsBSplineBasis<T> & >(m_basis.component(i));
491  //gsBSplineBasis<T> bsp_temp_2 = dynamic_cast<gsBSplineBasis<T> & >(m_basis.component(i));
492  //T p = bsp_temp.degree();
493  //T h_geo = bsp_temp.knots().at(p + 1);
494  //T h_geo_2 = bsp_temp_2.knots().at(p + 1);
495 
496  m_basis.component(i).evalSingle_into(0, u.row(i),b_0); // first
497  m_basis.component(i).evalSingle_into(1, u.row(i),b_1); // second
498 
499  m_basis_plus[i].evalSingle_into(0, u.row(i),b_0_plus);
500  m_basis_plus[i].evalSingle_into(1, u.row(i),b_1_plus);
501  m_basis_plus[i].evalSingle_into(2, u.row(i),b_2_plus);
502 
503  m_basis_plus[i].derivSingle_into(0, u.row(i),b_0_plus_deriv);
504  m_basis_plus[i].derivSingle_into(1, u.row(i),b_1_plus_deriv);
505  m_basis_plus[i].derivSingle_into(2, u.row(i),b_2_plus_deriv);
506 
507  m_basis_minus[i].evalSingle_into(0, u.row(i),b_0_minus);
508  m_basis_minus[i].evalSingle_into(1, u.row(i),b_1_minus);
509 
510  gsMatrix<T> b_1_0, b_1_minus_0;
511  m_basis.component(i).derivSingle_into(1, zero.row(i),b_1_0);
512  m_basis_minus[i].derivSingle_into(1, zero.row(i),b_1_minus_0);
513 
514  T factor_b_1 = 1.0/b_1_0(0,0);
515  c_0.push_back(b_0 + b_1);
516  c_1.push_back(factor_b_1 * b_1);
517 
518  T factor_b_1_minus = 1.0/b_1_minus_0(0,0);
519  c_0_minus.push_back(b_0_minus + b_1_minus);
520  c_1_minus.push_back(factor_b_1_minus * b_1_minus);
521 
522  gsMatrix<T> der_b_1_plus_0, der2_b_1_plus_0, der2_b_2_plus_0;
523  m_basis_plus[i].derivSingle_into(1, zero.row(i), der_b_1_plus_0);
524  m_basis_plus[i].deriv2Single_into(1, zero.row(i), der2_b_1_plus_0);
525  m_basis_plus[i].deriv2Single_into(2, zero.row(i), der2_b_2_plus_0);
526 
527  T factor_c_1_plus = 1.0/der_b_1_plus_0(0,0);
528  T factor2_c_1_plus = -der2_b_1_plus_0(0,0)/(der_b_1_plus_0(0,0)*der2_b_2_plus_0(0,0));
529  T factor_c_2_plus = 1.0/der2_b_2_plus_0(0,0);
530 
531  c_0_plus.push_back(b_0_plus + b_1_plus + b_2_plus);
532  c_1_plus.push_back(factor_c_1_plus * b_1_plus + factor2_c_1_plus * b_2_plus);
533  c_2_plus.push_back(factor_c_2_plus * b_2_plus );
534 
535  c_0_plus_deriv.push_back(b_0_plus_deriv + b_1_plus_deriv + b_2_plus_deriv);
536  c_1_plus_deriv.push_back(factor_c_1_plus * b_1_plus_deriv + factor2_c_1_plus * b_2_plus_deriv);
537  c_2_plus_deriv.push_back(factor_c_2_plus * b_2_plus_deriv);
538  }
539 
540  std::vector<gsMatrix<T>> alpha, beta, alpha_0, beta_0, alpha_deriv, beta_deriv;
541  gsMatrix < T > temp_mat;
542  if (m_kindOfEdge[0])
543  {
544  m_alpha[0].eval_into(u.row(0),temp_mat); // 1-dir == PatchID
545  alpha.push_back(temp_mat); // u
546 
547  m_alpha[0].eval_into(zero.row(0),temp_mat); // 1-dir == PatchID
548  alpha_0.push_back(temp_mat); // u
549 
550  m_alpha[0].deriv_into(zero.row(0),temp_mat); // 1-dir == PatchID
551  alpha_deriv.push_back(temp_mat); // u
552 
553  m_beta[0].eval_into(u.row(0),temp_mat); // 1-dir == PatchID
554  beta.push_back(temp_mat); // u
555 
556  m_beta[0].eval_into(zero.row(0),temp_mat); // 1-dir == PatchID
557  beta_0.push_back(temp_mat); // u
558 
559  m_beta[0].deriv_into(zero.row(0),temp_mat); // 1-dir == PatchID
560  beta_deriv.push_back(temp_mat); // u
561  }
562  else
563  {
564  temp_mat.setOnes(1, u.cols());
565  alpha.push_back(temp_mat); // u
566 
567  temp_mat.setOnes(1, zero.cols());
568  alpha_0.push_back(temp_mat); // u
569 
570  temp_mat.setZero(1, zero.cols());
571  alpha_deriv.push_back(temp_mat); // u
572 
573  temp_mat.setZero(1, u.cols());
574  beta.push_back(temp_mat); // u
575 
576  temp_mat.setZero(1, zero.cols());
577  beta_0.push_back(temp_mat); // u
578 
579  temp_mat.setZero(1, zero.cols());
580  beta_deriv.push_back(temp_mat); // u
581  }
582 
583  if (m_kindOfEdge[1]) {
584  m_alpha[1].eval_into(u.row(1), temp_mat); // 1-dir == PatchID
585  alpha.push_back(temp_mat); // v
586 
587  m_alpha[1].eval_into(zero.row(0), temp_mat); // 1-dir == PatchID
588  alpha_0.push_back(temp_mat); // v
589 
590  m_alpha[1].deriv_into(zero.row(0), temp_mat); // 1-dir == PatchID
591  alpha_deriv.push_back(temp_mat); // v
592 
593  m_beta[1].eval_into(u.row(1), temp_mat); // 1-dir == PatchID
594  beta.push_back(temp_mat); // v
595 
596  m_beta[1].eval_into(zero.row(0), temp_mat); // 1-dir == PatchID
597  beta_0.push_back(temp_mat); // v
598 
599  m_beta[1].deriv_into(zero.row(0), temp_mat); // 1-dir == PatchID
600  beta_deriv.push_back(temp_mat); // v
601  }
602  else
603  {
604  temp_mat.setOnes(1, u.cols());
605  alpha.push_back(temp_mat); // u
606 
607  temp_mat.setOnes(1, zero.cols());
608  alpha_0.push_back(temp_mat); // u
609 
610  temp_mat.setZero(1, zero.cols());
611  alpha_deriv.push_back(temp_mat); // u
612 
613  temp_mat.setZero(1, u.cols());
614  beta.push_back(temp_mat); // u
615 
616  temp_mat.setZero(1, zero.cols());
617  beta_0.push_back(temp_mat); // u
618 
619  temp_mat.setZero(1, zero.cols());
620  beta_deriv.push_back(temp_mat); // u
621  }
622 
623  // Geo data:
624  gsMatrix<T> geo_jac, geo_der2;
625  geo_jac = m_geo.jacobian(zero);
626  geo_der2 = m_geo.deriv2(zero);
627 
628 
629 
630  // Compute dd^^(i_k) and dd^^(i_k-1)
631  gsMatrix<T> dd_ik_plus, dd_ik_minus;
632  gsMatrix<T> dd_ik_minus_deriv, dd_ik_plus_deriv;
633  dd_ik_minus = -1.0/(alpha_0[0](0,0)) * (geo_jac.col(1) +
634  beta_0[0](0,0) * geo_jac.col(0));
635 
636  dd_ik_plus = 1.0/(alpha_0[1](0,0)) * (geo_jac.col(0) +
637  beta_0[1](0,0) * geo_jac.col(1));
638 
639  gsMatrix<T> geo_deriv2_12(m_geo.targetDim(),1), geo_deriv2_11(m_geo.targetDim(),1), geo_deriv2_22(m_geo.targetDim(),1);
640  geo_deriv2_12.row(0) = geo_der2.row(2);
641  geo_deriv2_12.row(1) = geo_der2.row(5);
642  geo_deriv2_11.row(0) = geo_der2.row(0);
643  geo_deriv2_11.row(1) = geo_der2.row(3);
644  geo_deriv2_22.row(0) = geo_der2.row(1);
645  geo_deriv2_22.row(1) = geo_der2.row(4);
646 
647  if(m_geo.parDim() + 1 == m_geo.targetDim()) // Surface
648  {
649  geo_deriv2_12.row(2) = m_geo.deriv2(zero).row(8);
650  geo_deriv2_11.row(2) = m_geo.deriv2(zero).row(6);
651  geo_deriv2_22.row(2) = m_geo.deriv2(zero).row(7);
652  }
653 
654  gsMatrix<T> alpha_squared_u = alpha_0[0]*alpha_0[0];
655  gsMatrix<T> alpha_squared_v = alpha_0[1]*alpha_0[1];
656 
657  dd_ik_minus_deriv = -1.0/(alpha_squared_u(0,0)) * // N^2
658  ((geo_deriv2_12 + (beta_deriv[0](0,0) * geo_jac.col(0) +
659  beta_0[0](0,0) * geo_deriv2_11))*alpha_0[0](0,0) -
660  (geo_jac.col(1) + beta_0[0](0,0) * geo_jac.col(0)) *
661  alpha_deriv[0](0,0));
662 
663  dd_ik_plus_deriv = 1.0/(alpha_squared_v(0,0)) *
664  ((geo_deriv2_12 + (beta_deriv[1](0,0) * geo_jac.col(1) +
665  beta_0[1](0,0) * geo_deriv2_22))*alpha_0[1](0,0) -
666  (geo_jac.col(0) + beta_0[1](0,0) * geo_jac.col(1)) *
667  alpha_deriv[1](0,0));
668 
669  // Comupute d_(0,0)^(i_k), d_(1,0)^(i_k), d_(0,1)^(i_k), d_(1,1)^(i_k) ; i_k == 2
670  std::vector<gsMatrix<T>> d_ik;
671  d_ik.push_back(m_Phi.col(0));
672  d_ik.push_back(m_Phi.block(1, 0, m_geo.targetDim(), 6).transpose() * geo_jac.col(0) ); // deriv into u
673  d_ik.push_back(m_Phi.block(1, 0, m_geo.targetDim(), 6).transpose() * geo_jac.col(1) ); // deriv into v
674 
675  if(m_geo.parDim() + 1 == m_geo.targetDim()) // In the surface case the dimension of the second derivative vector is 9x1
676  {
677  d_ik.push_back( (geo_jac(0,0) * m_Phi.row(4).transpose() + geo_jac(1,0) * m_Phi.row(7).transpose() + geo_jac(2,0) * m_Phi.row(10).transpose()) * geo_jac(0,1) +
678  (geo_jac(0,0) * m_Phi.row(5).transpose() + geo_jac(1,0) * m_Phi.row(8).transpose() + geo_jac(2,0) * m_Phi.row(11).transpose()) * geo_jac(1,1) +
679  (geo_jac(0,0) * m_Phi.row(6).transpose() + geo_jac(1,0) * m_Phi.row(9).transpose() + geo_jac(2,0) * m_Phi.row(12).transpose()) * geo_jac(2,1) +
680  m_Phi.block(1, 0, 1, 6).transpose() * geo_der2.row(2) +
681  m_Phi.block(2, 0, 1, 6).transpose() * geo_der2.row(5) +
682  m_Phi.block(3, 0, 1, 6).transpose() * geo_der2.row(8) );
683 
684  }
685  else
686  {
687  d_ik.push_back((geo_jac(0, 0) * m_Phi.col(3) + geo_jac(1, 0) * m_Phi.col(4)) * geo_jac(0, 1) +
688  (geo_jac(0, 0) * m_Phi.col(4) + geo_jac(1, 0) * m_Phi.col(5)) * geo_jac(1, 1) +
689  m_Phi.block(0, 1, 6, 1) * geo_der2.row(2) +
690  m_Phi.block(0, 2, 6, 1) * geo_der2.row(5)); // Hessian
691  }
692  // Compute d_(*,*)^(il,ik)
693  std::vector<gsMatrix<T>> d_ilik_minus, d_ilik_plus;
694  d_ilik_minus.push_back(m_Phi.col(0));
695  d_ilik_minus.push_back(m_Phi.block(1, 0, m_geo.targetDim(), 6).transpose() * geo_jac.col(0));
696 
697  if(m_geo.parDim() + 1 == m_geo.targetDim()) // In the surface case the dimension of the second derivative vector is 9x1
698  {
699  d_ilik_minus.push_back( (geo_jac(0,0) * m_Phi.row(4).transpose() + geo_jac(1,0) * m_Phi.row(7).transpose() + geo_jac(2,0) * m_Phi.row(10).transpose()) * geo_jac(0,0) +
700  (geo_jac(0,0) * m_Phi.row(5).transpose() + geo_jac(1,0) * m_Phi.row(8).transpose() + geo_jac(2,0) * m_Phi.row(11).transpose()) * geo_jac(1,0) +
701  (geo_jac(0,0) * m_Phi.row(6).transpose() + geo_jac(1,0) * m_Phi.row(9).transpose() + geo_jac(2,0) * m_Phi.row(12).transpose()) * geo_jac(2,0) +
702  m_Phi.block(1, 0, 1, 6).transpose() * geo_der2.row(0) +
703  m_Phi.block(2, 0, 1, 6).transpose() * geo_der2.row(3) +
704  m_Phi.block(3, 0, 1, 6).transpose() * geo_der2.row(6) );
705  }
706  else
707  {
708  d_ilik_minus.push_back((geo_jac(0, 0) * m_Phi.col(3) + geo_jac(1, 0) * m_Phi.col(4)) * geo_jac(0, 0) +
709  (geo_jac(0, 0) * m_Phi.col(4) + geo_jac(1, 0) * m_Phi.col(5)) * geo_jac(1, 0) +
710  m_Phi.block(0, 1, 6, 1) * geo_der2.row(0) +
711  m_Phi.block(0, 2, 6, 1) * geo_der2.row(3));
712  }
713 
714  d_ilik_minus.push_back(m_Phi.block(1, 0, m_geo.targetDim(), 6).transpose() * dd_ik_minus);
715 
716  if(m_geo.parDim() + 1 == m_geo.targetDim()) // In the surface case the dimension of the second derivative vector is 9x1
717  {
718  d_ilik_minus.push_back( (geo_jac(0,0) * m_Phi.row(4).transpose() + geo_jac(1,0) * m_Phi.row(7).transpose() + geo_jac(2,0) * m_Phi.row(10).transpose()) * dd_ik_minus(0,0) +
719  (geo_jac(0,0) * m_Phi.row(5).transpose() + geo_jac(1,0) * m_Phi.row(8).transpose() + geo_jac(2,0) * m_Phi.row(11).transpose()) * dd_ik_minus(1,0) +
720  (geo_jac(0,0) * m_Phi.row(6).transpose() + geo_jac(1,0) * m_Phi.row(9).transpose() + geo_jac(2,0) * m_Phi.row(12).transpose()) * dd_ik_minus(2,0) +
721  m_Phi.block(1, 0, 1, 6).transpose() * dd_ik_minus_deriv.row(0) +
722  m_Phi.block(2, 0, 1, 6).transpose() * dd_ik_minus_deriv.row(1) +
723  m_Phi.block(3, 0, 1, 6).transpose() * dd_ik_minus_deriv.row(2) );
724  }
725  else
726  {
727  d_ilik_minus.push_back((geo_jac(0, 0) * m_Phi.col(3) + geo_jac(1, 0) * m_Phi.col(4)) * dd_ik_minus(0, 0) +
728  (geo_jac(0, 0) * m_Phi.col(4) + geo_jac(1, 0) * m_Phi.col(5)) * dd_ik_minus(1, 0) +
729  m_Phi.block(0, 1, 6, 1) * dd_ik_minus_deriv.row(0) +
730  m_Phi.block(0, 2, 6, 1) * dd_ik_minus_deriv.row(1));
731  }
732 
733  d_ilik_plus.push_back(m_Phi.col(0));
734  d_ilik_plus.push_back(m_Phi.block(1, 0, m_geo.targetDim(), 6).transpose() * geo_jac.col(1));
735 
736  if(m_geo.parDim() + 1 == m_geo.targetDim()) // In the surface case the dimension of the second derivative vector is 9x1
737  {
738  d_ilik_plus.push_back( (geo_jac(0,1) * m_Phi.row(4).transpose() + geo_jac(1,1) * m_Phi.row(7).transpose() + geo_jac(2,1) * m_Phi.row(10).transpose()) * geo_jac(0,1) +
739  (geo_jac(0,1) * m_Phi.row(5).transpose() + geo_jac(1,1) * m_Phi.row(8).transpose() + geo_jac(2,1) * m_Phi.row(11).transpose()) * geo_jac(1,1) +
740  (geo_jac(0,1) * m_Phi.row(6).transpose() + geo_jac(1,1) * m_Phi.row(9).transpose() + geo_jac(2,1) * m_Phi.row(12).transpose()) * geo_jac(2,1) +
741  m_Phi.block(1, 0, 1, 6).transpose() * geo_der2.row(1) +
742  m_Phi.block(2, 0, 1, 6).transpose() * geo_der2.row(4) +
743  m_Phi.block(3, 0, 1, 6).transpose() * geo_der2.row(7) );
744  }
745  else
746  {
747  d_ilik_plus.push_back((geo_jac(0, 1) * m_Phi.col(3) + geo_jac(1, 1) * m_Phi.col(4)) * geo_jac(0, 1) +
748  (geo_jac(0, 1) * m_Phi.col(4) + geo_jac(1, 1) * m_Phi.col(5)) * geo_jac(1, 1) +
749  m_Phi.block(0, 1, 6, 1) * geo_der2.row(1) +
750  m_Phi.block(0, 2, 6, 1) * geo_der2.row(4));
751  }
752 
753  d_ilik_plus.push_back(m_Phi.block(1, 0, m_geo.targetDim(), 6).transpose() * dd_ik_plus);
754 
755  if(m_geo.parDim() + 1 == m_geo.targetDim()) // In the surface case the dimension of the second derivative vector is 9x1
756  {
757  d_ilik_plus.push_back( (geo_jac(0,1) * m_Phi.row(4).transpose() + geo_jac(1,1) * m_Phi.row(7).transpose() + geo_jac(2,1) * m_Phi.row(10).transpose()) * dd_ik_plus(0,0) +
758  (geo_jac(0,1) * m_Phi.row(5).transpose() + geo_jac(1,1) * m_Phi.row(8).transpose() + geo_jac(2,1) * m_Phi.row(11).transpose()) * dd_ik_plus(1,0) +
759  (geo_jac(0,1) * m_Phi.row(6).transpose() + geo_jac(1,1) * m_Phi.row(9).transpose() + geo_jac(2,1) * m_Phi.row(12).transpose()) * dd_ik_plus(2,0) +
760  m_Phi.block(1, 0, 1, 6).transpose() * dd_ik_plus_deriv.row(0) +
761  m_Phi.block(2, 0, 1, 6).transpose() * dd_ik_plus_deriv.row(1) +
762  m_Phi.block(3, 0, 1, 6).transpose() * dd_ik_plus_deriv.row(2) );
763  }
764  else
765  {
766  d_ilik_plus.push_back((geo_jac(0, 1) * m_Phi.col(3) + geo_jac(1, 1) * m_Phi.col(4)) * dd_ik_plus(0, 0) +
767  (geo_jac(0, 1) * m_Phi.col(4) + geo_jac(1, 1) * m_Phi.col(5)) * dd_ik_plus(1, 0) +
768  m_Phi.block(0, 1, 6, 1) * dd_ik_plus_deriv.row(0) +
769  m_Phi.block(0, 2, 6, 1) * dd_ik_plus_deriv.row(1));
770  }
771 
772 
773  result = d_ilik_minus.at(0)(m_bfID,0) * (c_0_plus.at(0).cwiseProduct(c_0.at(1)) -
774  beta[0].cwiseProduct(c_0_plus_deriv.at(0).cwiseProduct(c_1.at(1)))) +
775  d_ilik_minus.at(1)(m_bfID,0) * (c_1_plus.at(0).cwiseProduct(c_0.at(1)) -
776  beta[0].cwiseProduct(c_1_plus_deriv.at(0).cwiseProduct(c_1.at(1)))) +
777  d_ilik_minus.at(2)(m_bfID,0) * (c_2_plus.at(0).cwiseProduct(c_0.at(1)) -
778  beta[0].cwiseProduct(c_2_plus_deriv.at(0).cwiseProduct(c_1.at(1)))) -
779  d_ilik_minus.at(3)(m_bfID,0) * alpha[0].cwiseProduct(c_0_minus.at(0).cwiseProduct(c_1.at(1))) -
780  d_ilik_minus.at(4)(m_bfID,0) * alpha[0].cwiseProduct(c_1_minus.at(0).cwiseProduct(c_1.at(1))); // f*_(ik-1,ik)
781 
782  //if (kindOfEdge[0])
783  //rhsVals.at(i).setZero();
784 
785  //if (!kindOfEdge[1])
786  result += d_ilik_plus.at(0)(m_bfID,0) * (c_0_plus.at(1).cwiseProduct(c_0.at(0)) -
787  beta[1].cwiseProduct(c_0_plus_deriv.at(1).cwiseProduct(c_1.at(0)))) +
788  d_ilik_plus.at(1)(m_bfID,0) * (c_1_plus.at(1).cwiseProduct(c_0.at(0)) -
789  beta[1].cwiseProduct(c_1_plus_deriv.at(1).cwiseProduct(c_1.at(0)))) +
790  d_ilik_plus.at(2)(m_bfID,0) * (c_2_plus.at(1).cwiseProduct(c_0.at(0)) -
791  beta[1].cwiseProduct(c_2_plus_deriv.at(1).cwiseProduct(c_1.at(0)))) +
792  d_ilik_plus.at(3)(m_bfID,0) * alpha[1].cwiseProduct(c_0_minus.at(1).cwiseProduct(c_1.at(0))) +
793  d_ilik_plus.at(4)(m_bfID,0) * alpha[1].cwiseProduct(c_1_minus.at(1).cwiseProduct(c_1.at(0))); // f*_(ik+1,ik)
794 
795  result -= d_ik.at(0)(m_bfID,0) * c_0.at(0).cwiseProduct(c_0.at(1)) + d_ik.at(2)(m_bfID,0) * c_0.at(0).cwiseProduct(c_1.at(1)) +
796  d_ik.at(1)(m_bfID,0) * c_1.at(0).cwiseProduct(c_0.at(1)) + d_ik.at(3)(m_bfID,0) * c_1.at(0).cwiseProduct(c_1.at(1)); // f*_(ik)
797 
798 
799  }
800 
801 };
802 
803 }
#define short_t
Definition: gsConfig.h:35
#define index_t
Definition: gsConfig.h:32
A function from a n-dimensional domain to an m-dimensional image.
Definition: gsFunction.h:59
Jacobian of the object.
Definition: gsForwardDeclarations.h:75
This is the interface of all objects that computes functions on points like gsBasis, gsGeometry and gsFunctions.