OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
tet1_3d_supg.C
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
35 #include "tet1_3d_supg.h"
36 #include "fei3dtetlin.h"
37 #include "fluidmodel.h"
38 #include "node.h"
39 #include "material.h"
40 #include "gausspoint.h"
41 #include "gaussintegrationrule.h"
42 #include "fluiddynamicmaterial.h"
43 #include "fluidcrosssection.h"
44 #include "floatmatrix.h"
45 #include "floatarray.h"
46 #include "intarray.h"
47 #include "domain.h"
48 #include "mathfem.h"
49 #include "engngm.h"
50 #include "timestep.h"
51 #include "crosssection.h"
52 #include "classfactory.h"
53 
54 #ifdef __OOFEG
55  #include "oofeggraphiccontext.h"
56 #endif
57 
58 namespace oofem {
59 REGISTER_Element(Tet1_3D_SUPG);
60 
62 
64  SUPGElement2(n, aDomain)
65  // Constructor.
66 {
67  numberOfDofMans = 4;
68 }
69 
71 // Destructor
72 { }
73 
74 int
76 {
77  return 16;
78 }
79 
80 void
82 {
83  answer = {V_u, V_v, V_w, P_f};
84 }
85 
86 
87 void
89 // Sets up the array containing the integration points of the receiver.
90 {
91  if ( integrationRulesArray.size() == 0 ) {
92  integrationRulesArray.resize(3);
93  integrationRulesArray [ 0 ].reset( new GaussIntegrationRule(1, this, 1, 3) );
95 
96  integrationRulesArray [ 1 ].reset( new GaussIntegrationRule(2, this, 1, 3) );
98 
99  integrationRulesArray [ 2 ].reset( new GaussIntegrationRule(3, this, 1, 3) );
101  }
102 }
103 
104 
105 Interface *
107 {
108  if ( interface == LevelSetPCSElementInterfaceType ) {
109  return static_cast< LevelSetPCSElementInterface * >(this);
110  }
111 
112  return NULL;
113 }
114 
115 
116 void
118 {
119  FloatArray n;
121  answer.beNMatrixOf(n, 3);
122 }
123 
124 void
126 {
127  FloatMatrix n, dn;
128  FloatArray u, un;
130  this->computeNuMatrix(n, gp);
131  this->computeVectorOfVelocities(VM_Total, tStep, un);
132 
133  u.beProductOf(n, un);
134 
135  answer.resize(3, 12);
136  answer.zero();
137  for ( int i = 1; i <= 4; i++ ) {
138  answer.at(1, 3 * i - 2) = u.at(1) * dn.at(i, 1) + u.at(2) * dn.at(i, 2) + u.at(3) * dn.at(i, 3);
139  answer.at(2, 3 * i - 1) = u.at(1) * dn.at(i, 1) + u.at(2) * dn.at(i, 2) + u.at(3) * dn.at(i, 3);
140  answer.at(3, 3 * i - 0) = u.at(1) * dn.at(i, 1) + u.at(2) * dn.at(i, 2) + u.at(3) * dn.at(i, 3);
141  }
142 }
143 
144 void
146 {
147  answer.resize(3, 12);
148  answer.zero();
149 }
150 
151 
152 void
154 {
155  FloatArray u;
156  FloatMatrix dn, um(3, 4);
157 
158  this->computeVectorOfVelocities(VM_Total, tStep, u);
159 
161  for ( int i = 1; i <= 4; i++ ) {
162  um.at(1, i) = u.at(3 * i - 2);
163  um.at(2, i) = u.at(3 * i - 1);
164  um.at(3, i) = u.at(3 * i - 0);
165  }
166 
167  answer.beProductOf(um, dn);
168 }
169 
170 
171 void
173 {
174  FloatMatrix dn;
176 
177  answer.resize(6, 12);
178  answer.zero();
179 
180  for ( int i = 1; i <= 4; i++ ) {
181  answer.at(1, 3 * i - 2) = dn.at(i, 1);
182  answer.at(2, 3 * i - 1) = dn.at(i, 2);
183  answer.at(3, 3 * i - 0) = dn.at(i, 3);
184 
185  answer.at(4, 3 * i - 1) = dn.at(i, 3);
186  answer.at(4, 3 * i - 0) = dn.at(i, 2);
187 
188  answer.at(5, 3 * i - 2) = dn.at(i, 3);
189  answer.at(5, 3 * i - 0) = dn.at(i, 1);
190 
191  answer.at(6, 3 * i - 2) = dn.at(i, 2);
192  answer.at(6, 3 * i - 1) = dn.at(i, 1);
193  }
194 }
195 
196 void
198 {
199  FloatMatrix dn;
201 
202  answer.resize(1, 12);
203  answer.zero();
204 
205  for ( int i = 1; i <= 4; i++ ) {
206  answer.at(1, 3 * i - 2) = dn.at(i, 1);
207  answer.at(1, 3 * i - 1) = dn.at(i, 2);
208  answer.at(1, 3 * i - 0) = dn.at(i, 3);
209  }
210 }
211 
212 void
214 {
215  FloatArray n;
217 
218  answer.resize(1, 4);
219  answer.zero();
220 
221  answer.at(1, 1) = n.at(1);
222  answer.at(1, 2) = n.at(2);
223  answer.at(1, 3) = n.at(3);
224  answer.at(1, 4) = n.at(4);
225 }
226 
227 
228 void
230 {
231  FloatMatrix dn;
233 
234  answer.beTranspositionOf(dn);
235 }
236 
237 
238 
239 void
241 {
242  //TR1_2D_SUPG :: updateStabilizationCoeffs (tStep);
243  /* UGN-Based Stabilization */
244  double h_ugn, sum = 0.0, vnorm, t_sugn1, t_sugn2, t_sugn3, u_1, u_2, u_3, z, Re_ugn;
245  double dscale, uscale, lscale, tscale, dt;
246  //bool zeroFlag = false;
247  int im1;
248  FloatArray u, divu;
249  FloatMatrix du;
250 
255 
256  this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), u);
257 
258  u.times(uscale);
259  double nu;
260 
261  // compute averaged viscosity based on rule of mixture
262 
263  dt = tStep->giveTimeIncrement() * tscale;
264 
265  std :: unique_ptr< IntegrationRule > &iRule = this->integrationRulesArray [ 1 ];
266  GaussPoint *gp_first = iRule->getIntegrationPoint(0);
267  nu = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveFluidMaterial()->giveEffectiveViscosity(gp_first, tStep->givePreviousStep() );
269 
270  for ( auto *gp: *iRule ) {
271  this->computeDivUMatrix(du, gp);
272  divu.beProductOf(du, u);
273  sum += divu.at(1);
274  }
275 
276  sum *= ( 1. / lscale / iRule->giveNumberOfIntegrationPoints() );
277 
278  /*
279  * for (i=1; i<=3;i++) {
280  * im1=i-1;
281  * sum+= fabs(u.at((im1)*2+1)*b[im1]/lscale + u.at(im1*2+2)*c[im1]/lscale);
282  * }
283  */
284  vnorm = 0.;
285  int nsd = this->giveNumberOfSpatialDimensions();
286  for ( int i = 1; i <= numberOfDofMans; i++ ) {
287  im1 = i - 1;
288  u_1 = u.at( ( im1 ) * nsd + 1 );
289  u_2 = u.at( ( im1 ) * nsd + 2 );
290  if ( nsd > 2 ) {
291  u_3 = u.at( ( im1 ) * nsd + 3 );
292  } else {
293  u_3 = 0.;
294  }
295 
296  vnorm = max( vnorm, sqrt(u_1 * u_1 + u_2 * u_2 + u_3 * u_3) );
297  }
298 
299  if ( ( vnorm == 0.0 ) || ( sum < vnorm * 1e-10 ) ) {
300  //t_sugn1 = inf;
301  t_sugn2 = dt / 2.0;
302  //t_sugn3 = inf;
303  this->t_supg = 1. / sqrt( 1. / ( t_sugn2 * t_sugn2 ) );
304  this->t_pspg = this->t_supg;
305  this->t_lsic = 0.0;
306  } else {
307  h_ugn = 2.0 * vnorm / sum;
308  t_sugn1 = 1. / sum;
309  t_sugn2 = dt / 2.0;
310  t_sugn3 = h_ugn * h_ugn / 4.0 / nu;
311 
312  this->t_supg = 1. / sqrt( 1. / ( t_sugn1 * t_sugn1 ) + 1. / ( t_sugn2 * t_sugn2 ) + 1. / ( t_sugn3 * t_sugn3 ) );
313  this->t_pspg = this->t_supg;
314 
315  Re_ugn = vnorm * h_ugn / ( 2. * nu );
316  z = ( Re_ugn <= 3. ) ? Re_ugn / 3. : 1.0;
317  this->t_lsic = h_ugn * vnorm * z / 2.0;
318  }
319 
320  // if (this->number == 1) {
321  // printf ("t_supg %e t_pspg %e t_lsic %e\n", t_supg, t_pspg, t_lsic);
322  // }
323 
324 
325  this->t_supg *= uscale / lscale;
326  this->t_pspg *= 1. / ( lscale * dscale );
327  this->t_lsic *= ( dscale * uscale ) / ( lscale * lscale );
328 
329  this->t_lsic = 0.0;
330 
331  //this->t_lsic=0.0;
332  //this->t_pspg=0.0;
333 }
334 
335 int
337 {
338  return 3;
339 }
340 
341 double
343 {
344  FloatArray u;
345  double Re = static_cast< FluidModel * >( domain->giveEngngModel() )->giveReynoldsNumber();
346 
347  this->computeVectorOfVelocities(VM_Total, tStep, u);
348 
349  double vn1 = sqrt( u.at(1) * u.at(1) + u.at(2) * u.at(2) + u.at(3) * u.at(3) );
350  double vn2 = sqrt( u.at(4) * u.at(4) + u.at(5) * u.at(5) + u.at(6) * u.at(6) );
351  double vn3 = sqrt( u.at(7) * u.at(7) + u.at(8) * u.at(8) + u.at(9) * u.at(9) );
352  double vn4 = sqrt( u.at(10) * u.at(10) + u.at(11) * u.at(11) + u.at(12) * u.at(12) );
353  double veln = max( vn1, max( vn2, max(vn3, vn4) ) );
354 
355  double ln = 1.e6;
356  Node *inode, *jnode, *knode, *lnode;
357  FloatArray t1, t2, n3, n;
358  for ( int l = 1; l <= 4; l++ ) {
359  int i = ( l > 3 ) ? 1 : l + 1;
360  int j = ( i > 3 ) ? 1 : i + 1;
361  int k = ( j > 3 ) ? 1 : j + 1;
362 
363  inode = this->giveNode(i);
364  jnode = this->giveNode(j);
365  knode = this->giveNode(k);
366  lnode = this->giveNode(l);
367  t1.beDifferenceOf(*inode->giveCoordinates(), *jnode->giveCoordinates());
368 
369  t2.beDifferenceOf(*knode->giveCoordinates(), *jnode->giveCoordinates());
370 
371  n.beVectorProductOf(t1, t2);
372  n.normalize();
373 
374  n3.beDifferenceOf(*lnode->giveCoordinates(), *jnode->giveCoordinates());
375 
376  ln = min( ln, sqrt( fabs( n.dotProduct(n3) ) ) );
377  }
378 
379  if ( veln != 0.0 ) {
380  return ln / veln;
381  } else {
382  return 0.5 * ln * ln * Re;
383  }
384 }
385 
386 
387 double
389 // Returns the portion of the receiver which is attached to gp.
390 {
391  double determinant, weight, volume;
392  determinant = fabs( this->interpolation.giveTransformationJacobian( gp->giveNaturalCoordinates(),
393  FEIElementGeometryWrapper(this) ) );
394 
395  weight = gp->giveWeight();
396  volume = determinant * weight;
397 
398  return volume;
399 }
400 
401 
402 double
404 {
405  double answer = 0.0, norm, dV, vol = 0.0;
406  FloatMatrix n, dn;
407  FloatArray fi(4), u, un, gfi;
408 
409  this->computeVectorOfVelocities(VM_Total, tStep, un);
410 
411  for ( int i = 1; i <= 4; i++ ) {
412  fi.at(i) = ls->giveLevelSetDofManValue( dofManArray.at(i) );
413  }
414 
415  for ( GaussPoint *gp: *this->integrationRulesArray [ 0 ] ) {
416  dV = this->computeVolumeAround(gp);
417  interpolation.evaldNdx( dn, gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) );
418  this->computeNuMatrix(n, gp);
419  u.beProductOf(n, un);
420  gfi.beTProductOf(dn, fi);
421  norm = gfi.computeNorm();
422 
423  vol += dV;
424  answer += dV * u.dotProduct(gfi) / norm;
425  }
426 
427  return answer / vol;
428 }
429 
430 void
432 {
433  GaussPoint *gp = this->integrationRulesArray [ 0 ]->getIntegrationPoint(0);
435 }
436 
437 
438 double
440 {
441  double answer = 0.0;
442 
443  for ( GaussPoint *gp: *this->integrationRulesArray [ 0 ] ) {
444  answer += this->computeVolumeAround(gp);
445  }
446 
447  return answer;
448 }
449 
450 double
452 {
453  FloatArray voff(2), fi(4);
454  for ( int i = 1; i <= 4; i++ ) {
455  fi.at(i) = ls->giveLevelSetDofManValue( dofManArray.at(i) );
456  }
457 
458  this->LS_PCS_computeVOFFractions(voff, fi);
459  return ( voff.at(1) - voff.at(2) );
460 }
461 
462 
463 
464 
465 void
467 {
468  int neg = 0, pos = 0, zero = 0, si = 0;
469  double x1, y1, z1;
470  answer.resize(2);
471 
472  for ( double ifi: fi ) {
473  if ( ifi >= 0. ) {
474  pos++;
475  } else if ( ifi < 0. ) {
476  neg++;
477  } else {
478  zero++;
479  }
480  }
481 
482  if ( neg == 0 ) { // all level set values positive
483  answer.at(1) = 1.0;
484  answer.at(2) = 0.0;
485  return; //return area;
486  } else if ( pos == 0 ) { // all level set values negative
487  answer.at(1) = 0.0;
488  answer.at(2) = 1.0;
489  return; //return -area;
490  } else if ( zero == 4 ) {
491  // ???????
492  answer.at(1) = 1.0;
493  answer.at(2) = 0.0;
494  return;
495  } else {
496  // zero level set inside
497  // distinguish two poosible cases
498  if ( max(pos, neg) == 3 ) {
499  // find the vertex vith level set sign different from other three
500  for ( int i = 1; i <= 4; i++ ) {
501  if ( ( pos > neg ) && ( fi.at(i) < 0.0 ) ) {
502  si = i;
503  break;
504  }
505 
506  if ( ( pos < neg ) && ( fi.at(i) >= 0.0 ) ) {
507  si = i;
508  break;
509  }
510  }
511 
512  if ( si ) {
513  x1 = this->giveNode(si)->giveCoordinate(1);
514  y1 = this->giveNode(si)->giveCoordinate(2);
515  z1 = this->giveNode(si)->giveCoordinate(3);
516 
517 
518  int ii;
519  double t, xi [ 3 ], yi [ 3 ], zi [ 3 ];
520  // compute intersections with element sides originating from this vertex
521  for ( int i = 0; i < 3; i++ ) {
522  ii = ( si + i ) % 4 + 1;
523  t = fi.at(si) / ( fi.at(si) - fi.at(ii) );
524  xi [ i ] = x1 + t * ( this->giveNode(ii)->giveCoordinate(1) - x1 );
525  yi [ i ] = y1 + t * ( this->giveNode(ii)->giveCoordinate(2) - y1 );
526  zi [ i ] = z1 + t * ( this->giveNode(ii)->giveCoordinate(3) - z1 );
527  }
528 
529  // compute volume of this pyramid (si, xi[0], xi[1], xi[2])
530  double __vol = fabs( ( 1. / 6. ) * ( ( x1 - xi [ 0 ] ) * ( ( yi [ 1 ] - yi [ 0 ] ) * ( zi [ 2 ] - zi [ 0 ] ) - ( zi [ 1 ] - zi [ 0 ] ) * ( yi [ 2 ] - yi [ 0 ] ) ) +
531  ( y1 - yi [ 0 ] ) * ( ( zi [ 1 ] - zi [ 0 ] ) * ( xi [ 2 ] - xi [ 0 ] ) - ( xi [ 1 ] - xi [ 0 ] ) * ( zi [ 2 ] - zi [ 0 ] ) ) +
532  ( z1 - zi [ 0 ] ) * ( ( xi [ 1 ] - xi [ 0 ] ) * ( yi [ 2 ] - yi [ 0 ] ) - ( yi [ 1 ] - yi [ 0 ] ) * ( xi [ 2 ] - xi [ 0 ] ) ) ) );
533 
534 
535  double vol = LS_PCS_computeVolume();
536  if ( ( fabs(__vol) - vol ) < 0.0000001 ) {
537  __vol = sgn(__vol) * vol;
538  }
539 
540  if ( ( __vol < 0 ) || ( fabs(__vol) / vol > 1.0000001 ) ) {
541  OOFEM_ERROR("internal consistency error");
542  }
543 
544  if ( pos > neg ) {
545  // negative vol computed
546  answer.at(2) = min(fabs(__vol) / vol, 1.0);
547  answer.at(1) = 1.0 - answer.at(2);
548  } else {
549  // postive vol computed
550  answer.at(1) = min(fabs(__vol) / vol, 1.0);
551  answer.at(2) = 1.0 - answer.at(1);
552  }
553  } else {
554  OOFEM_ERROR("internal consistency error");
555  }
556  } else if ( max(pos, neg) == 2 ) {
557  // two vertices positive; two negative; compute positive volume
558  int p1 = 0, p2 = 0;
559  // find the vertex vith level set sign different from other three
560  for ( int i = 1; i <= 4; i++ ) {
561  if ( fi.at(i) >= 0.0 ) {
562  if ( p1 ) {
563  p2 = i;
564  break;
565  } else {
566  p1 = i;
567  }
568  }
569  }
570 
571  int _ind, ii;
572  double t;
573  double p1i_x [ 3 ], p1i_y [ 3 ], p1i_z [ 3 ];
574  double p2i_x [ 3 ], p2i_y [ 3 ], p2i_z [ 3 ];
575 
576  if ( p1 && p2 ) {
577  // find the two intersections sharing edge with p1 and p2
578  p1i_x [ 0 ] = this->giveNode(p1)->giveCoordinate(1);
579  p1i_y [ 0 ] = this->giveNode(p1)->giveCoordinate(2);
580  p1i_z [ 0 ] = this->giveNode(p1)->giveCoordinate(3);
581 
582  p2i_x [ 0 ] = this->giveNode(p2)->giveCoordinate(1);
583  p2i_y [ 0 ] = this->giveNode(p2)->giveCoordinate(2);
584  p2i_z [ 0 ] = this->giveNode(p2)->giveCoordinate(3);
585 
586  _ind = 1;
587  for ( int i = 0; i < 3; i++ ) {
588  ii = ( p1 + i ) % 4 + 1;
589  if ( ( ii == p2 ) || ( ii == p1 ) ) {
590  continue;
591  }
592 
593  t = fi.at(p1) / ( fi.at(p1) - fi.at(ii) );
594  p1i_x [ _ind ] = p1i_x [ 0 ] + t * ( this->giveNode(ii)->giveCoordinate(1) - p1i_x [ 0 ] );
595  p1i_y [ _ind ] = p1i_y [ 0 ] + t * ( this->giveNode(ii)->giveCoordinate(2) - p1i_y [ 0 ] );
596  p1i_z [ _ind ] = p1i_z [ 0 ] + t * ( this->giveNode(ii)->giveCoordinate(3) - p1i_z [ 0 ] );
597 
598  t = fi.at(p2) / ( fi.at(p2) - fi.at(ii) );
599  p2i_x [ _ind ] = p2i_x [ 0 ] + t * ( this->giveNode(ii)->giveCoordinate(1) - p2i_x [ 0 ] );
600  p2i_y [ _ind ] = p2i_y [ 0 ] + t * ( this->giveNode(ii)->giveCoordinate(2) - p2i_y [ 0 ] );
601  p2i_z [ _ind++ ] = p2i_z [ 0 ] + t * ( this->giveNode(ii)->giveCoordinate(3) - p2i_z [ 0 ] );
602  }
603 
604  // compute volume of this wedge as a sum of volumes of three
605  // pyramids
606  double __v1 = ( ( p2i_x [ 0 ] - p1i_x [ 0 ] ) * ( p1i_y [ 1 ] - p1i_y [ 0 ] ) * ( p1i_z [ 2 ] - p1i_z [ 0 ] ) -
607  ( p2i_x [ 0 ] - p1i_x [ 0 ] ) * ( p1i_y [ 2 ] - p1i_y [ 0 ] ) * ( p1i_z [ 1 ] - p1i_z [ 0 ] ) +
608  ( p1i_x [ 2 ] - p1i_x [ 0 ] ) * ( p2i_y [ 0 ] - p1i_y [ 0 ] ) * ( p1i_z [ 1 ] - p1i_z [ 0 ] ) -
609  ( p1i_x [ 1 ] - p1i_x [ 0 ] ) * ( p2i_y [ 0 ] - p1i_y [ 0 ] ) * ( p1i_z [ 2 ] - p1i_z [ 0 ] ) +
610  ( p1i_x [ 1 ] - p1i_x [ 0 ] ) * ( p1i_y [ 2 ] - p1i_y [ 0 ] ) * ( p2i_z [ 0 ] - p1i_z [ 0 ] ) -
611  ( p1i_x [ 2 ] - p1i_x [ 0 ] ) * ( p1i_y [ 1 ] - p1i_y [ 0 ] ) * ( p2i_z [ 0 ] - p1i_z [ 0 ] ) ) / 6.0;
612 
613  double __v2 = ( ( p2i_x [ 0 ] - p1i_x [ 1 ] ) * ( p1i_y [ 2 ] - p1i_y [ 1 ] ) * ( p2i_z [ 1 ] - p1i_z [ 1 ] ) -
614  ( p2i_x [ 0 ] - p1i_x [ 1 ] ) * ( p2i_y [ 1 ] - p1i_y [ 1 ] ) * ( p1i_z [ 2 ] - p1i_z [ 1 ] ) +
615  ( p2i_x [ 1 ] - p1i_x [ 1 ] ) * ( p2i_y [ 0 ] - p1i_y [ 1 ] ) * ( p1i_z [ 2 ] - p1i_z [ 1 ] ) -
616  ( p1i_x [ 2 ] - p1i_x [ 1 ] ) * ( p2i_y [ 0 ] - p1i_y [ 1 ] ) * ( p2i_z [ 1 ] - p1i_z [ 1 ] ) +
617  ( p1i_x [ 2 ] - p1i_x [ 1 ] ) * ( p2i_y [ 1 ] - p1i_y [ 1 ] ) * ( p2i_z [ 0 ] - p1i_z [ 1 ] ) -
618  ( p2i_x [ 1 ] - p1i_x [ 1 ] ) * ( p1i_y [ 2 ] - p1i_y [ 1 ] ) * ( p2i_z [ 0 ] - p1i_z [ 1 ] ) ) / 6.0;
619 
620  double __v3 = ( ( p1i_x [ 2 ] - p2i_x [ 0 ] ) * ( p2i_y [ 1 ] - p2i_y [ 0 ] ) * ( p2i_z [ 2 ] - p2i_z [ 0 ] ) -
621  ( p1i_x [ 2 ] - p2i_x [ 0 ] ) * ( p2i_y [ 2 ] - p2i_y [ 0 ] ) * ( p2i_z [ 1 ] - p2i_z [ 0 ] ) +
622  ( p2i_x [ 2 ] - p2i_x [ 0 ] ) * ( p1i_y [ 2 ] - p2i_y [ 0 ] ) * ( p2i_z [ 1 ] - p2i_z [ 0 ] ) -
623  ( p2i_x [ 1 ] - p2i_x [ 0 ] ) * ( p1i_y [ 2 ] - p2i_y [ 0 ] ) * ( p2i_z [ 2 ] - p2i_z [ 0 ] ) +
624  ( p2i_x [ 1 ] - p2i_x [ 0 ] ) * ( p2i_y [ 2 ] - p2i_y [ 0 ] ) * ( p1i_z [ 2 ] - p2i_z [ 0 ] ) -
625  ( p2i_x [ 2 ] - p2i_x [ 0 ] ) * ( p2i_y [ 1 ] - p2i_y [ 0 ] ) * ( p1i_z [ 2 ] - p2i_z [ 0 ] ) ) / 6.0;
626 
627  double __vol = fabs(__v1) + fabs(__v2) + fabs(__v3);
628  double vol = LS_PCS_computeVolume();
629 
630  if ( ( __vol < 0 ) || ( fabs(__vol) / vol > 1.0000001 ) ) {
631  OOFEM_ERROR("internal consistency error");
632  }
633 
634  answer.at(1) = min(fabs(__vol) / vol, 1.0);
635  answer.at(2) = 1.0 - answer.at(1);
636  } else {
637  OOFEM_ERROR("internal consistency error");
638  }
639  } else {
640  OOFEM_ERROR("internal consistency error");
641  }
642  }
643 }
644 
645 
646 #ifdef __OOFEG
647 
649 {
650  WCRec p [ 4 ];
651  GraphicObj *go;
652 
653  if ( !gc.testElementGraphicActivity(this) ) {
654  return;
655  }
656 
657  EASValsSetLineWidth(OOFEG_RAW_GEOMETRY_WIDTH);
658  EASValsSetColor( gc.getElementColor() );
659  EASValsSetEdgeColor( gc.getElementEdgeColor() );
660  EASValsSetEdgeFlag(true);
661  EASValsSetLayer(OOFEG_RAW_GEOMETRY_LAYER);
662  EASValsSetFillStyle(FILL_SOLID);
663  p [ 0 ].x = ( FPNum ) this->giveNode(1)->giveCoordinate(1);
664  p [ 0 ].y = ( FPNum ) this->giveNode(1)->giveCoordinate(2);
665  p [ 0 ].z = ( FPNum ) this->giveNode(1)->giveCoordinate(3);
666  p [ 1 ].x = ( FPNum ) this->giveNode(2)->giveCoordinate(1);
667  p [ 1 ].y = ( FPNum ) this->giveNode(2)->giveCoordinate(2);
668  p [ 1 ].z = ( FPNum ) this->giveNode(2)->giveCoordinate(3);
669  p [ 2 ].x = ( FPNum ) this->giveNode(3)->giveCoordinate(1);
670  p [ 2 ].y = ( FPNum ) this->giveNode(3)->giveCoordinate(2);
671  p [ 2 ].z = ( FPNum ) this->giveNode(3)->giveCoordinate(3);
672  p [ 3 ].x = ( FPNum ) this->giveNode(4)->giveCoordinate(1);
673  p [ 3 ].y = ( FPNum ) this->giveNode(4)->giveCoordinate(2);
674  p [ 3 ].z = ( FPNum ) this->giveNode(4)->giveCoordinate(3);
675 
676  go = CreateTetra(p);
677  EGWithMaskChangeAttributes(WIDTH_MASK | FILL_MASK | COLOR_MASK | EDGE_COLOR_MASK | EDGE_FLAG_MASK | LAYER_MASK, go);
678  EGAttachObject(go, ( EObjectP ) this);
679  EMAddGraphicsToModel(ESIModel(), go);
680 }
681 
682 #endif
683 } // end namespace oofem
CrossSection * giveCrossSection()
Definition: element.C:495
int testElementGraphicActivity(Element *)
Test if particular element passed fulfills various filtering criteria for its graphics output...
IntArray dofManArray
Array containing dofmanager numbers.
Definition: element.h:151
virtual double computeVolumeAround(GaussPoint *gp)
Returns volume related to given integration point.
Definition: tet1_3d_supg.C:388
void beVectorProductOf(const FloatArray &v1, const FloatArray &v2)
Computes vector product (or cross product) of vectors given as parameters, , and stores the result in...
Definition: floatarray.C:415
Class and object Domain.
Definition: domain.h:115
virtual double LS_PCS_computeVolume()
Returns receiver&#39;s volume.
Definition: tet1_3d_supg.C:439
Fluid cross-section.
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition: femcmpnn.h:82
virtual void computeUDotGradUMatrix(FloatMatrix &answer, GaussPoint *gp, TimeStep *tStep)
Definition: tet1_3d_supg.C:125
virtual ~Tet1_3D_SUPG()
Definition: tet1_3d_supg.C:70
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
double giveLevelSetDofManValue(int i)
Returns level set value in specific node.
Definition: levelsetpcs.h:168
int max(int i, int j)
Returns bigger value form two given decimals.
Definition: mathfem.h:71
double sgn(double i)
Returns the signum of given value (if value is < 0 returns -1, otherwise returns 1) ...
Definition: mathfem.h:91
#define OOFEG_RAW_GEOMETRY_LAYER
Element interface for LevelSetPCS class representing level-set like material interface.
Definition: levelsetpcs.h:68
static FEI3dTetLin interpolation
Definition: tet1_3d_supg.h:53
virtual int giveNumberOfSpatialDimensions()
Definition: tet1_3d_supg.C:336
Base class for fluid problems.
Definition: fluidmodel.h:46
oofem::oofegGraphicContext gc[OOFEG_LAST_LAYER]
virtual void computeDivUMatrix(FloatMatrix &answer, GaussPoint *gp)
Definition: tet1_3d_supg.C:197
EngngModel * giveEngngModel()
Returns engineering model to which receiver is associated.
Definition: domain.C:433
virtual void computeDivTauMatrix(FloatMatrix &answer, GaussPoint *gp, TimeStep *tStep)
Definition: tet1_3d_supg.C:145
virtual int computeNumberOfDofs()
Computes or simply returns total number of element&#39;s local DOFs.
Definition: tet1_3d_supg.C:75
Tet1_3D_SUPG(int n, Domain *d)
Definition: tet1_3d_supg.C:63
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the array of interpolation functions (shape functions) at given point.
Definition: fei3dtetlin.C:43
virtual void computeGaussPoints()
Initializes the array of integration rules member variable.
Definition: tet1_3d_supg.C:88
virtual void computeGradPMatrix(FloatMatrix &answer, GaussPoint *gp)
Definition: tet1_3d_supg.C:229
virtual double giveCoordinate(int i)
Definition: node.C:82
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the determinant of the transformation.
Definition: fei3dtetlin.C:178
This abstract class represent a general base element class for fluid dynamic problems.
Definition: supgelement2.h:57
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Sets receiver to be a - b.
Definition: floatarray.C:341
double giveTimeIncrement()
Returns solution step associated time increment.
Definition: timestep.h:150
virtual void computeGradUMatrix(FloatMatrix &answer, GaussPoint *gp, TimeStep *tStep)
Definition: tet1_3d_supg.C:153
virtual void giveDofManDofIDMask(int inode, IntArray &answer) const
Returns dofmanager dof mask for node.
Definition: tet1_3d_supg.C:81
virtual void LS_PCS_computeVOFFractions(FloatArray &answer, FloatArray &fi)
Returns VOF fractions for each material on element according to nodal values of level set function (p...
Definition: tet1_3d_supg.C:466
virtual void computeVectorOfVelocities(ValueModeType mode, TimeStep *tStep, FloatArray &velocities)
Definition: fmelement.C:48
double dotProduct(const FloatArray &x) const
Computes the dot product (or inner product) of receiver and argument.
Definition: floatarray.C:463
#define OOFEM_ERROR(...)
Definition: error.h:61
REGISTER_Element(LSpace)
virtual double giveVariableScale(VarScaleType varId)
Returns the scale factor for given variable type.
Definition: engngm.h:1087
virtual void computeNuMatrix(FloatMatrix &answer, GaussPoint *gp)
Definition: tet1_3d_supg.C:117
#define OOFEG_RAW_GEOMETRY_WIDTH
virtual double giveWeight()
Returns integration weight of receiver.
Definition: gausspoint.h:181
double t_supg
Stabilization coefficients, updated for each solution step in updateStabilizationCoeffs() ...
Definition: supgelement.h:70
Wrapper around element definition to provide FEICellGeometry interface.
Definition: feinterpol.h:95
virtual double computeCriticalTimeStep(TimeStep *tStep)
Computes the critical time increment.
Definition: tet1_3d_supg.C:342
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
virtual Interface * giveInterface(InterfaceType t)
Interface requesting service.
Definition: tet1_3d_supg.C:106
TimeStep * givePreviousStep()
Returns pointer to previous solution step.
Definition: timestep.C:114
virtual double evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the matrix of derivatives of interpolation functions (shape functions) at given point...
Definition: fei3dtetlin.C:54
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix^T and anArray.
Definition: floatarray.C:708
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
virtual void computeNpMatrix(FloatMatrix &answer, GaussPoint *gp)
Definition: tet1_3d_supg.C:213
virtual int setupIntegrationPoints(IntegrationRule &irule, int npoints, Element *element)
Sets up integration rule for the given element.
Definition: crosssection.C:54
void beNMatrixOf(const FloatArray &n, int nsd)
Assigns the receiver to be a repeated diagonal matrix.
Definition: floatmatrix.C:505
Class representing vector of real numbers.
Definition: floatarray.h:82
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
virtual void LS_PCS_computedN(FloatMatrix &answer)
Returns gradient of shape functions.
Definition: tet1_3d_supg.C:431
Abstract base class representing Level Set representation of material interfaces. ...
Definition: levelsetpcs.h:114
virtual void updateStabilizationCoeffs(TimeStep *tStep)
Updates the stabilization coefficients used for CBS and SUPG algorithms.
Definition: tet1_3d_supg.C:240
double norm(const FloatArray &x)
Definition: floatarray.C:985
virtual void computeBMatrix(FloatMatrix &anwer, GaussPoint *gp)
Definition: tet1_3d_supg.C:172
double computeNorm() const
Computes the norm (or length) of the vector.
Definition: floatarray.C:840
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
Class Interface.
Definition: interface.h:82
virtual double LS_PCS_computeF(LevelSetPCS *, TimeStep *)
Evaluates F in level set equation of the form where for interface position driven by flow with speed...
Definition: tet1_3d_supg.C:403
void times(double s)
Multiplies receiver with scalar.
Definition: floatarray.C:818
void beTranspositionOf(const FloatMatrix &src)
Assigns to the receiver the transposition of parameter.
Definition: floatmatrix.C:323
std::vector< std::unique_ptr< IntegrationRule > > integrationRulesArray
List of integration rules of receiver (each integration rule contains associated integration points a...
Definition: element.h:170
virtual FloatArray * giveCoordinates()
Definition: node.h:114
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
InterfaceType
Enumerative type, used to identify interface type.
Definition: interfacetype.h:43
int min(int i, int j)
Returns smaller value from two given decimals.
Definition: mathfem.h:59
virtual double LS_PCS_computeS(LevelSetPCS *, TimeStep *)
Evaluates S in level set equation of the form where .
Definition: tet1_3d_supg.C:451
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:337
the oofem namespace is to define a context or scope in which all oofem names are defined.
Class implementing node in finite element mesh.
Definition: node.h:87
double normalize()
Normalizes receiver.
Definition: floatarray.C:828
Node * giveNode(int i) const
Returns reference to the i-th node of element.
Definition: element.h:610
virtual void drawRawGeometry(oofegGraphicContext &gc, TimeStep *tStep)
Definition: tet1_3d_supg.C:648
Class representing integration point in finite element program.
Definition: gausspoint.h:93
Class representing solution step.
Definition: timestep.h:80
int numberOfDofMans
Number of dofmanagers.
Definition: element.h:149
const FloatArray & giveNaturalCoordinates()
Returns coordinate array of receiver.
Definition: gausspoint.h:138
Class representing Gaussian-quadrature integration rule.
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:31 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011