Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Generic_element_2.h
Go to the documentation of this file.
1 /* *******************************************************************
2  * Rocstar Simulation Suite *
3  * Copyright@2015, Illinois Rocstar LLC. All rights reserved. *
4  * *
5  * Illinois Rocstar LLC *
6  * Champaign, IL *
7  * www.illinoisrocstar.com *
8  * sales@illinoisrocstar.com *
9  * *
10  * License: See LICENSE file in top level of distribution package or *
11  * http://opensource.org/licenses/NCSA *
12  *********************************************************************/
13 /* *******************************************************************
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
16  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17  * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
21  * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
22  *********************************************************************/
23 // $Id: Generic_element_2.h,v 1.3 2008/12/06 08:43:23 mtcampbe Exp $
24 
28 /* Author: Xiangmin Jiao
29  * Date: Sept. 12, 2002
30  */
31 
32 #ifndef _GENERIC_ELEMENT_2_H_
33 #define _GENERIC_ELEMENT_2_H_
34 
57 #include "surfbasic.h"
58 #include <cassert>
59 
61 
66 template < class Field>
67 struct Field_traits {
68  typedef typename Field::Value Value;
69  typedef typename Field::Size Size;
70 };
71 
73 template < class _V>
74 struct Field_traits<_V*> {
75  typedef _V Value;
76  typedef unsigned int Size;
77 };
78 
80 template < class _V>
81 struct Field_traits<const _V*> {
82  typedef _V Value;
83  typedef unsigned int Size;
84 };
85 
95 public:
97  typedef double Real;
98  typedef unsigned int Size;
99  typedef SURF::Vector_2<Real> Vector_2;
100  typedef SURF::Vector_3<Real> Vector_3;
102 
103  enum { MAX_SIZE = 9}; // MAX_NV is maximum number of nodes per element.
104 
105 public:
110  Generic_element_2( Size ne, Size nn=0);
111 
113  Size size_of_edges() const { return _nedges; }
115  Size size_of_nodes() const { return _nnodes; }
117  Size order() const { return _order; }
118 
124  void shape_func( const Nat_coor &nc, Real N[]) const;
125 
127  void shape_func_deriv( const Nat_coor &nc, Vector_2 Np[]) const;
128 
130  template < class Field, class Value>
131  void interpolate( const Field &f,
132  const Nat_coor &nc, Value *v) const throw(int);
133 
135  template < class Field>
136  void interpolate( const Field &f,
137  const Nat_coor &nc, Real *v) const throw(int)
138  { interpolate_nopt( f, nc, v); }
139 
141  template < class Field, class Value>
142  void interpolate( const Field &f,
143  const Real xi, Value *v) const throw(int);
144 
146  template < class Field>
147  void interpolate( const Field &f,
148  const Real xi, Real *v) const throw(int)
149  { interpolate_nopt( f, xi, v); }
150 
152  template < class Field>
154  interpolate( const Field &f, const Nat_coor &nc) const throw(int) {
155  typename Field_traits<Field>::Value v;
156  this->interpolate( f, nc, &v); // Use this-> to get around a stupid bug in SGI C++ compiler
157  return v;
158  }
159 
161  template < class Field>
163  interpolate( const Field &f, const Real xi) const throw(int) {
164  typename Field_traits<Field>::Value v;
165  interpolate( f, xi, &v);
166  return v;
167  }
168 
170  template < class Field, class Value>
171  void interpolate_to_center( const Field &f, Value *v) const throw(int);
172 
174  template < class Field>
176  interpolate_to_center( const Field &f) const throw(int) {
177  typename Field_traits<Field>::Value v;
178  interpolate_to_center( f, &v);
179  return v;
180  }
181  //\}
182 
185  template < class Field>
187  void Jacobian( const Field &f, const Nat_coor &nc, Vector_3 J[2]) const;
188 
189  // This function evaluates the Jacobian at a given point on an edge.
190  template < class Field>
191  void Jacobian( const Field &f, const Real xi, Vector_3 &v) const;
192 
194  template < class Pnts>
195  void gradients( const Pnts &ps, const Nat_coor &nc, Vector_3 grads[3]) const;
196 
198  template < class Field>
199  Real Jacobian_det( const Field &f, const Nat_coor &nc) const;
200 
203  template < class Field>
204  Real Jacobian_det( const Field &f1, const Field &f2,
205  Real alpha, const Nat_coor &nc2) const;
206  //\}
207 
210  Size get_num_gp( const Size doa=0) const;
212 
214  Real get_gp_weight( const Size i, const Size doa=0) const;
215 
217  void get_gp_nat_coor( const Size i, Nat_coor &nc, const Size doa=0) const;
218  //\}
219 
220 protected:
221  // Solver M*x=b using pseudoinverse, where M is 2*3 matrix, b is 2 vector,
222  // and x is 3 vector.
223  void solve( const Vector_3 M[2], Vector_3 x[], const Vector_2 b[]) const;
224 
226  template < class Field, class Value>
227  void interpolate_nopt( const Field &f,
228  const Nat_coor &nc, Value *v) const throw(int);
229 
231  template < class Field, class Value>
232  void interpolate_nopt( const Field &f,
233  const Real xi, Value *v) const throw(int);
234 
235 private:
236  const Size _nedges;
237  const Size _nnodes; // Number of vertices.
238  const Size _order;
239 };
240 
241 template < class Field, class Value>
243  const Nat_coor &nc,
244  Value *v) const throw(int) {
245  const Real xi = nc[0], eta = nc[1];
246 
247  if ( eta == 0) // Interpolate on the edge.
248  { interpolate( f, xi, v); return; }
249 
250  *v = f[0];
251  switch ( _nnodes) {
252  case 3:
253  // *v = f[0] + xi*(f[1]-f[0]) + eta*(f[2]-f[0]);
254  *v += ((f[1]-f[0])*=xi) += ((f[2]-f[0])*=eta);
255  return;
256  case 4: {
257  // *v = f[0] + xi * (1.-eta) * (f[1]-f[0])
258  // + eta * ( f[3]-f[0] + xi *(f[2]-f[3]));
259  *v += ((f[1]-f[0]) *= (xi * (1.-eta)))
260  += ((f[3]-f[0]) *= eta)
261  += ((f[2]-f[3]) *= xi*eta);
262  return;
263  }
264  case 6: {
265  const Real zeta=1.-xi-eta;
266 
267  // *v = f[0] + xi*( (2.*xi-1.)*(f[1]-f[0]) + 4.*zeta*(f[3]-f[0])) +
268  // eta * ( (2.*eta-1.)*(f[2]-f[0]) + 4.*zeta*(f[5]-f[0])) +
269  // 4.*xi*eta*(f[4]-f[0]);
270  *v += ((f[1]-f[0]) *= xi * (2.*xi-1.))
271  += ((f[3]-f[0]) *= 4.* xi * zeta)
272  += ((f[2]-f[0]) *= eta * (2.*eta-1.))
273  += ((f[5]-f[0]) *= 4. * eta * zeta)
274  += ((f[4]-f[0]) *= 4.*xi*eta);
275  return;
276  }
277  case 8: {
278  const Real xi_minus = 1. - xi;
279  const Real eta_minus = 1. - eta;
280 
281  // *v = f[0] + xi * eta_minus * (f[1]-f[0]) +
282  // eta * ( f[3]-f[0] + xi *(f[2]-f[3])) -
283  // 2.*xi*xi_minus*eta_minus*( (f[0]-f[4])+(f[1]-f[4])) -
284  // 2.*xi*xi_minus*eta*( (f[2]-f[6])+(f[3]-f[6])) -
285  // 2.*xi*eta*eta_minus*( (f[1]-f[5])+(f[2]-f[5])) -
286  // 2.*xi_minus*eta*eta_minus*( (f[0]-f[7])+(f[3]-f[7]));
287 
288  *v += ((f[1]-f[0]) *= eta * (2.*eta-1.))
289  += ((f[3]-f[0]) *= eta)
290  += ((f[2]-f[3]) *= xi * eta)
291  -= ((((f[0]-f[4])+=(f[1]-f[4])) *= 2.*xi*xi_minus*eta_minus)
292  += (((f[2]-f[6])+=(f[3]-f[6])) *= 2.*xi*xi_minus*eta)
293  += (((f[1]-f[5])+=(f[2]-f[5])) *= 2.*xi*eta*eta_minus)
294  += (((f[0]-f[7])+=(f[3]-f[7])) *= 2.*xi_minus*eta*eta_minus));
295  return;
296  }
297  default:
298  throw(-1);
299  }
300 }
301 
302 template < class Field, class Value>
304  const Nat_coor &nc,
305  Value *v) const throw(int) {
306  const Real xi = nc[0], eta = nc[1];
307 
308  if ( eta == 0) // Interpolate on the edge.
309  { interpolate_nopt( f, xi, v); return; }
310 
311  *v = f[0];
312  switch ( _nnodes) {
313  case 3:
314  *v += ((f[1]-f[0])*xi) + ((f[2]-f[0])*eta);
315  return;
316  case 4: {
317  *v += ((f[1]-f[0]) * (xi * (1.-eta)))
318  + ((f[3]-f[0]) * eta)
319  + ((f[2]-f[3]) * xi*eta);
320  return;
321  }
322  case 6: {
323  const Real zeta=1.-xi-eta;
324 
325  *v += ((f[1]-f[0]) * xi * (2.*xi-1.))
326  + ((f[3]-f[0]) * 4.* xi * zeta)
327  + ((f[2]-f[0]) * eta * (2.*eta-1.))
328  + ((f[5]-f[0]) * 4. * eta * zeta)
329  + ((f[4]-f[0]) * 4.*xi*eta);
330  return;
331  }
332  case 8: {
333  const Real xi_minus = 1. - xi;
334  const Real eta_minus = 1. - eta;
335 
336  *v += ((f[1]-f[0]) * eta * (2.*eta-1.))
337  + ((f[3]-f[0]) * eta)
338  + ((f[2]-f[3]) * xi * eta)
339  - ((((f[0]-f[4])+(f[1]-f[4])) * 2.*xi*xi_minus*eta_minus)
340  + (((f[2]-f[6])+(f[3]-f[6])) * 2.*xi*xi_minus*eta)
341  + (((f[1]-f[5])+(f[2]-f[5])) * 2.*xi*eta*eta_minus)
342  + (((f[0]-f[7])+(f[3]-f[7])) * 2.*xi_minus*eta*eta_minus));
343  return;
344  }
345  default:
346  throw(-1);
347  }
348 }
349 
350 template < class Field, class Value>
352  const Real xi,
353  Value *v) const throw(int) {
354  *v = f[0];
355  switch ( _nnodes) {
356  case 3:
357  case 4:
358  // *v = f[0] + xi*(f[1]-f[0]);
359  *v += ((f[1]-f[0]) *= xi);
360  return;
361  case 6: {
362  // *v = f[0] + xi*( (2.*xi-1.)*(f[1]-f[0]) + 4.*(1.-xi)*(f[3]-f[0]));
363  *v += ((f[1]-f[0]) *= xi*(2.*xi-1.))
364  += ((f[3]-f[0]) *= 4.*xi*(1.-xi));
365  return;
366  }
367  case 8: {
368  // *v = f[0] + xi * (f[1]-f[0]) - 2.*xi*(1.-xi)*( (f[0]-f[4])+(f[1]-f[4]));
369  *v += ((f[1]-f[0]) *= xi)
370  -= (((f[0]-f[4])+=(f[1]-f[4])) *= 2.*xi*(1.-xi));
371  return;
372  }
373  default:
374  throw(-1);
375  }
376 }
377 
378 template < class Field, class Value>
380  const Real xi,
381  Value *v) const throw(int) {
382  *v = f[0];
383  switch ( _nnodes) {
384  case 3:
385  case 4:
386  *v += ((f[1]-f[0]) * xi);
387  return;
388  case 6: {
389  *v += ((f[1]-f[0]) * xi*(2.*xi-1.))
390  + ((f[3]-f[0]) * 4.*xi*(1.-xi));
391  return;
392  }
393  case 8: {
394  *v += ((f[1]-f[0]) * xi)
395  - (((f[0]-f[4])+(f[1]-f[4])) * 2.*xi*(1.-xi));
396  return;
397  }
398  default:
399  throw(-1);
400  }
401 }
402 
403 template < class Field, class Value>
405 interpolate_to_center( const Field &f, Value *v) const throw(int) {
406  if ( _order == 1) {
407  *v = f[0];
408  for ( Size i=1; i<_nnodes; ++i) *v += f[i];
409  *v /= _nnodes;
410  }
411  else {
412  Real x = size_of_edges()==3 ? 1./3. : 1./2.;
413  interpolate( f, Nat_coor(x, x), v);
414  }
415 }
416 
417 // This function evaluates the Jacobian at a given point.
418 template < class Field>
420  const Nat_coor &nc,
421  Vector_3 J[2]) const {
422  switch (_nnodes) {
423  case 3:
424  J[0] = f[1]-f[0]; J[1] = f[2]-f[0];
425  return;
426  case 4: {
427  const Real xi = nc[0], xi_minus = 1. - xi;
428  const Real eta = nc[1], eta_minus = 1. - eta;
429 
430  // J[0] = eta_minus * ( f[1] - f[0]) + eta * ( f[2] - f[3]);
431  J[0] = ((f[1]-f[0]) *= eta_minus) += (( f[2]-f[3]) *= eta );
432  // J[1] = xi_minus * ( f[3] - f[0]) + xi * ( f[2] - f[1]);
433  J[1] = ((f[3]-f[0]) *= xi_minus) += (( f[2]-f[1]) *= xi);
434  return;
435  }
436  case 6: {
437  const Real xi=nc[0], eta=nc[1], zeta=1.-xi-eta;
438 
439  // J[0] = (4.*xi -1.)*(f[1]-f[0]) +
440  // (4.*zeta-4.*xi)*(f[3]-f[0]) + 4.*eta*(f[4] -f[5]);
441  J[0] = ((f[1]-f[0]) *= 4.*xi -1.)
442  += ((f[3]-f[0]) *= 4.*zeta-4*xi)
443  += ((f[4]-f[5]) *= 4.*eta);
444  // J[1] = (4.*eta -1.)*(f[2]-f[0]) +
445  // (4.*zeta-4.*eta)*(f[5]-f[0]) + 4.*xi*(f[4] -f[3]);
446  J[1] = ((f[2]-f[0]) *= 4.*eta -1.)
447  += ((f[5]-f[0]) *= 4*zeta-4*eta)
448  += ((f[4]-f[3]) *= 4.*xi);
449  return;
450  }
451  case 8: {
452  const Real xi = nc[0], xi_minus = 1. - xi;
453  const Real eta = nc[1], eta_minus = 1. - eta;
454 
455  // J[0] = eta_minus * ( f[1] - f[0]) + eta * ( f[2] - f[3]) -
456  // 2.*eta_minus*(xi_minus-xi)*( (f[0]-f[4])+(f[1]-f[4])) -
457  // 2.*eta*(xi_minus-xi)*( (f[2]-f[6])+(f[3]-f[6])) -
458  // 2.*eta*eta_minus*( (f[1]-f[5])+(f[2]-f[5])-(f[0]-f[7])-(f[3]-f[7]));
459  J[0] = ((f[1]-f[0]) *= eta_minus) += ((f[2]-f[3]) *= eta)
460  -= ((((f[0]-f[4])+=(f[1]-f[4])) *= 2.*eta_minus*(xi_minus-xi))
461  += (((f[2]-f[6])+=(f[3]-f[6])) *= 2.*eta*(xi_minus-xi))
462  += (((f[1]-f[5])+=(f[2]-f[5])-=((f[0]-f[7])+=(f[3]-f[7])))
463  *= 2.*eta*eta_minus));
464 
465  // J[1] = xi_minus * ( f[3] - f[0]) + xi * ( f[2] - f[1]) -
466  // 2.*xi*(eta_minus-eta)*( (f[1]-f[5])+(f[2]-f[5]))-
467  // 2.*xi_minus*(eta_minus-eta)*( (f[0]-f[7])+(f[3]-f[7])) -
468  // 2.*xi*xi_minus*( (f[2]-f[6])-(f[3]-f[6])-(f[0]-f[4])+(f[1]-f[4]));
469  ((J[1] = f[3]-f[0]) *= xi_minus) += ((f[2]-f[1]) *= xi)
470  -= ((((f[1]-f[5])+=(f[2]-f[5])) *= 2.*xi*(eta_minus-eta))
471  += (((f[0]-f[7])+=(f[3]-f[7])) *= 2.*xi_minus*(eta_minus-eta))
472  += (((f[2]-f[6])+=(f[1]-f[4])-=((f[3]-f[6])+=(f[0]-f[4])))
473  *= 2.*xi*xi_minus));
474  return;
475  }
476  default:
477  abort(); // Should never reach here
478  }
479 }
480 
481 // This function evaluates the Jacobian at a given point.
482 template < class Field>
484  const Real xi,
485  Vector_3 &v) const {
486 
487  switch ( _nnodes) {
488  case 3:
489  case 4:
490  v = f[1] - f[0]; return;
491  case 6:
492  // return (4.*xi -1.)*(f[1]-f[0]) + (4.-8.*xi)*(f[3]-f[0]);
493  v = (((f[1]-f[0]) *= 4.*xi -1.) += ((f[3]-f[0]) *= 4.-8.*xi)); return;
494  case 8:
495  // return (f[1]-f[0]) - (2.-4.*xi)*( (f[0]-f[4])+(f[1]-f[4]));
496  v = ((f[1]-f[0]) -= (((f[0]-f[4])+=(f[1]-f[4])) *= 2.-4*xi)); return;
497  default:
498  assert( false);
499  v = Vector_3(0,0,0);
500  return;
501  }
502 }
503 
504 // This function evaluates the gradient of the shape functions.
505 template < class Pnts>
506 void Generic_element_2::gradients( const Pnts &pnts,
507  const Nat_coor &nc,
508  Vector_3 grads[3]) const {
509  Vector_3 J[2];
510  Jacobian( pnts, nc, J);
511 
512  Vector_2 deriv[9];
513  shape_func_deriv( nc, deriv);
514 
515  solve( J, grads, deriv);
516 }
517 
518 // This function evaluates the determinant of the Jacobian (dx/dxi,dx/deta).
519 template < class Field>
522  const Nat_coor &nc) const {
523  Vector_3 J[2];
524  Jacobian( f, nc, J);
525 
526  return std::sqrt( Vector_3::cross_product( J[0], J[1]).squared_norm());
527 }
528 
529 // Evaluates the determinant of the Jacobian (dx/dxi,dx/deta), where
530 // x is (1-alpha)*f1+alpha*f2. Used by Rocface.
531 template < class Field>
534  const Real alpha, const Nat_coor &nc) const {
535  Vector_3 J1[2],J2[2];
536  if ( alpha!=1.) {
537  Jacobian( f1, nc, J1);
538  }
539 
540  if ( alpha!=0.) {
541  Jacobian( f2, nc, J2);
542  if ( alpha!=1) {
543  J2[0] = (1-alpha)*J1[0]+alpha*J2[0];
544  J2[1] = (1-alpha)*J1[1]+alpha*J2[1];
545  }
546  }
547  else {
548  J2[0] = J1[0]; J2[1] = J1[1];
549  }
550 
551  return std::sqrt( Vector_3::cross_product( J2[0], J2[1]).squared_norm());
552 }
553 
555 
556 #endif /*_GENERIC_ELEMENT_2_H_ */
557 
558 
559 
560 
561 
562 
Generic_element_2 Self
SURF::Vector_2< Real > Vector_2
void shape_func_deriv(const Nat_coor &nc, Vector_2 Np[]) const
Evaluates the derivatives of the shape functions.
#define SURF_END_NAMESPACE
Definition: surfbasic.h:29
Adpator for element-wise data container.
Definition of Generic_element_2, which supports linear/quadratic triangle/quadrilateral elements...
void interpolate(const Field &f, const Nat_coor &nc, Real *v) const
Customized interpolation for primitive data types.
Size order() const
Degree of the element. 1 for linear and 2 for quadratic.
void get_gp_nat_coor(const Size i, Nat_coor &nc, const Size doa=0) const
Get the natrual coordinate associated with a Gauss point.
SURF::Vector_3< Real > Vector_3
Encapsulation of the element-wise computations for two-dimensional elements.
Real get_gp_weight(const Size i, const Size doa=0) const
Get the weight associated with a Gauss point.
double Real
Definition: mapbasic.h:322
Field_traits< Field >::Value interpolate(const Field &f, const Nat_coor &nc) const
Interpolates the field data at a given point and return the result.
double sqrt(double d)
Definition: double.h:73
void interpolate(const Field &f, const Nat_coor &nc, Value *v) const
Interpolates the field data at a given point.
unsigned int Size
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE v
Definition: roccomf90.h:20
Field::Value Value
#define SURF_BEGIN_NAMESPACE
Definition: surfbasic.h:28
void interpolate(const Field &f, const Real xi, Real *v) const
Customized interpolation for primitive data types.
Real Jacobian_det(const Field &f, const Nat_coor &nc) const
Evaluates the determinant of the Jacobian (dx/dxi,dx/deta).
Generic_element_2(Size ne, Size nn=0)
Constructor.
void solve(const Vector_3 M[2], Vector_3 x[], const Vector_2 b[]) const
_Cont::Value Value
Field::Size Size
void shape_func(const Nat_coor &nc, Real N[]) const
Evaluates the shape functions of the element and output the barycentric coordinates into the array N...
Field_traits< Field >::Value interpolate_to_center(const Field &f) const
Interpolates the field data to the center and return the value.
Size size_of_edges() const
Number of edges.
blockLoc i
Definition: read.cpp:79
void int int REAL * x
Definition: read.cpp:74
static Vector_3 cross_product(const Vector_3 &v, const Vector_3 &w)
Definition: mapbasic.h:104
Size size_of_nodes() const
Number of nodes.
Size get_num_gp(const Size doa=0) const
Get the number of Gauss points.
Field_traits< Field >::Value interpolate(const Field &f, const Real xi) const
Interpolates the field data at a given point on an edge and return the result.
void interpolate_nopt(const Field &f, const Nat_coor &nc, Value *v) const
Nonoptimized version of interpolation.
void gradients(const Pnts &ps, const Nat_coor &nc, Vector_3 grads[3]) const
Evaluates the gradient of the shape functions.
void Jacobian(const Field &f, const Nat_coor &nc, Vector_3 J[2]) const
Evaluates the Jacobian at a given point.
Some basic geometric data types.
Definition: mapbasic.h:54
void interpolate_to_center(const Field &f, Value *v) const
Interpolates the field data to the center of the element.