OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
tr1_2d_supg2.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 "tr1_2d_supg2.h"
36 #include "fluidmodel.h"
37 #include "node.h"
38 #include "material.h"
39 #include "gausspoint.h"
40 #include "gaussintegrationrule.h"
41 #include "floatmatrix.h"
42 #include "floatarray.h"
43 #include "intarray.h"
44 #include "domain.h"
45 #include "mathfem.h"
46 #include "engngm.h"
47 #include "fluiddynamicmaterial.h"
48 #include "fluidcrosssection.h"
49 #include "load.h"
50 #include "timestep.h"
51 #include "boundaryload.h"
52 #include "fei2dtrlin.h"
53 #include "fei2dquadlin.h"
54 #include "geotoolbox.h"
55 #include "contextioerr.h"
56 #include "crosssection.h"
57 #include "dynamicinputrecord.h"
58 #include "classfactory.h"
59 
60 #ifdef __OOFEG
61  #include "oofeggraphiccontext.h"
62  #include "connectivitytable.h"
63 #endif
64 
65 namespace oofem {
66 #define TRSUPG_ZERO_VOF 1.e-8
67 
68 REGISTER_Element(TR1_2D_SUPG2);
69 
70 //#define TR1_2D_SUPG2_DEBUG
71 
73  TR1_2D_SUPG(n, aDomain)
74 {
75  numberOfDofMans = 3;
76 }
77 
79 {
80 }
81 
82 
83 void
85 {
86  this->interp.evalN( answer, gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) );
87 }
88 
89 
90 int
92 {
93  return 9;
94 }
95 
96 void
98 {
99  answer = {V_u, V_v, P_f};
100 }
101 
104 {
105  IRResultType result; // Required by IR_GIVE_FIELD macro
106 
107  result = SUPGElement :: initializeFrom(ir);
108  if ( result != IRRT_OK ) {
109  return result;
110  }
111 
112 
113  this->vof = 0.0;
115  if ( vof > 0.0 ) {
117  this->temp_vof = this->vof;
118  } else {
119  this->vof = 0.0;
121  this->temp_vof = this->vof;
122  }
123 
124  this->mat [ 0 ] = this->mat [ 1 ] = this->material;
127  this->material = this->mat [ 0 ];
128 
129  return IRRT_OK;
130 }
131 
132 
133 void
135 {
137  if ( this->permanentVofFlag ) {
138  input.setField(this->vof, _IFT_Tr1SUPG_pvof);
139  } else {
140  input.setField(this->vof, _IFT_Tr1SUPG_vof);
141  }
142 
143  input.setField(this->mat [ 0 ], _IFT_Tr1SUPG2_mat0);
144  input.setField(this->mat [ 1 ], _IFT_Tr1SUPG2_mat1);
145 }
146 
147 
148 void
150 {
151  this->computeGaussPoints();
152  this->initGeometry();
153  this->updateIntegrationRules();
154 }
155 
156 
157 void
159 // Sets up the array containing the four Gauss points of the receiver.
160 {
161  if ( integrationRulesArray.size() == 0 ) {
162  integrationRulesArray.resize(2);
163  integrationRulesArray [ 0 ].reset( new GaussIntegrationRule(1, this, 1, 3, true) );
164  integrationRulesArray [ 1 ].reset( new GaussIntegrationRule(2, this, 1, 3, true) );
165  }
166  if ( !defaultIRule ) {
167  defaultIRule.reset( new GaussIntegrationRule(1, this, 1, 3, true) );
169  }
170 }
171 
172 
173 /*
174  * Integration template
175  * // loop over each fluid
176  * for (ifluid = 0; ifluid< 2; ifluid++) {
177  * for (ip=0 ; ip < sub_IPRule[ifluid]->giveNumberOfIntegrationPoints() ; ip++) {
178  * gp = sub_IPRule[ifluid]->getIntegrationPoint(ip) ;
179  * mapped_gp = sub_mapped_IPRule[ifluid]->getIntegrationPoint(ip) ;
180  * this->computeNVector (n, mapped_gp);
181  * dV = this->computeVolumeAroundID(gp,id[ifluid], vcoords[ifluid]) ;
182  * // compute integral here
183  * }
184  * }
185  */
186 
187 
188 
189 void
191 {
192  answer.resize(6, 6);
193  answer.zero();
194  FloatArray n, un;
195  double dV, val, rho;
196  double u1, u2;
197 
198  // consistent mass
199  // loop over each fluid
200  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
201  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
202  rho = this->_giveMaterial(ifluid)->give('d', gp);
203  this->computeNVector(n, gp);
204  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
205  // compute integral here
206  for ( int i = 1; i <= 3; i++ ) {
207  for ( int j = 1; j <= 3; j++ ) {
208  val = rho * n.at(i) * n.at(j) * dV;
209  answer.at(i * 2 - 1, j * 2 - 1) += val;
210  answer.at(i * 2, j * 2) += val;
211  }
212  }
213  }
214  }
215 
216  // SUPG stabilization term
217  // loop over each fluid
218  this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
219  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
220  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
221  rho = this->_giveMaterial(ifluid)->give('d', gp);
222  this->computeNVector(n, gp);
223  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
224  u1 = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
225  u2 = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
226  for ( int i = 1; i <= 3; i++ ) {
227  for ( int j = 1; j <= 3; j++ ) {
228  val = dV * rho * t_supg * ( u1 * b [ i - 1 ] + u2 * c [ i - 1 ] ) * n.at(j);
229  answer.at(i * 2, j * 2) += val;
230  answer.at(i * 2 - 1, j * 2 - 1) += val;
231  }
232  }
233  }
234  }
235 
236  /*
237  * // orginal version
238  * // consistent mass
239  * for (GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
240  * this->computeNVector (n, gp);
241  * dV = 2.0*area*gp->giveWeight();
242  * for (i=1;i<=3;i++) {
243  * for (j=1; j<=3; j++) {
244  * val = rho*n.at(i)*n.at(j)*dV;
245  * answer.at(i*2-1,j*2-1) += val;
246  * answer.at(i*2,j*2) += val;
247  * }
248  * }
249  * }
250  *
251  * // SUPG stabilization term
252  * this -> computeVectorOfVelocities(VM_Total,tStep->givePreviousStep(), un) ;
253  * for (GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
254  * this->computeNVector (n, gp);
255  * dV = 2.0*area*gp->giveWeight();
256  * u1=n.at(1)*un.at(1)+n.at(2)*un.at(3)+n.at(3)*un.at(5);
257  * u2=n.at(1)*un.at(2)+n.at(2)*un.at(4)+n.at(3)*un.at(6);
258  * for (i=1;i<=3;i++) {
259  * for (j=1; j<=3; j++) {
260  * val = dV*rho*t_supg*(u1*b[i-1]+u2*c[i-1])*n.at(j);
261  * answer.at(i*2,j*2) += val;
262  * answer.at(i*2-1, j*2-1) += val;
263  * }
264  * }
265  * }
266  */
267 #ifdef TR1_2D_SUPG2_DEBUG
268  /* test */
269  FloatMatrix test;
270  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
272  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
273  for ( i = 1; i <= 6; i++ ) {
274  for ( j = 1; j <= 6; j++ ) {
275  if ( fabs( ( answer.at(i, j) - test.at(i, j) ) / test.at(i, j) ) >= 1.e-10 ) {
276  OOFEM_ERROR("test failure");
277  }
278  }
279  }
280 
281 #endif
282 }
283 
284 
285 void
287 {
288  answer.resize(6);
289  answer.zero();
290 
291  FloatArray n, u, un;
292  double rho;
293  double dV, dudx, dudy, dvdx, dvdy, u1, u2;
294  this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
295  this->computeVectorOfVelocities(VM_Total, tStep, u);
296 
297 
298  dudx = b [ 0 ] * u.at(1) + b [ 1 ] * u.at(3) + b [ 2 ] * u.at(5);
299  dudy = c [ 0 ] * u.at(1) + c [ 1 ] * u.at(3) + c [ 2 ] * u.at(5);
300  dvdx = b [ 0 ] * u.at(2) + b [ 1 ] * u.at(4) + b [ 2 ] * u.at(6);
301  dvdy = c [ 0 ] * u.at(2) + c [ 1 ] * u.at(4) + c [ 2 ] * u.at(6);
302 
303  // standard galerkin term
304  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
305  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
306  rho = this->_giveMaterial(ifluid)->give('d', gp);
307  this->computeNVector(n, gp);
308  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
309 
310  u1 = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
311  u2 = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
312  for ( int i = 1; i <= 3; i++ ) {
313  answer.at(i * 2 - 1) += rho * dV * n.at(i) * ( u1 * dudx + u2 * dudy );
314  answer.at(i * 2) += rho * dV * n.at(i) * ( u1 * dvdx + u2 * dvdy );
315  }
316  }
317  }
318 
319  // supg stabilization term
320  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
321  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
322  rho = this->_giveMaterial(ifluid)->give('d', gp);
323  this->computeNVector(n, gp);
324  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
325 
326  u1 = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
327  u2 = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
328  for ( int i = 1; i <= 3; i++ ) {
329  answer.at(i * 2 - 1) += t_supg * rho * dV * ( u1 * b [ i - 1 ] + u2 * c [ i - 1 ] ) * ( u1 * dudx + u2 * dudy );
330  answer.at(i * 2) += t_supg * rho * dV * ( u1 * b [ i - 1 ] + u2 * c [ i - 1 ] ) * ( u1 * dvdx + u2 * dvdy );
331  }
332  }
333  }
334 
335 #if 0
336  // test of linearization
337  FloatMatrix _h;
338  FloatArray _t;
339  this->computeAdvectionDerivativeTerm_MB(_h, tStep);
340  _t.beProductOf(_h, u);
341  for ( int i = 1; i <= 6; i++ ) {
342  if ( ( fabs( answer.at(i) - _t.at(i) ) >= 1.e-6 ) ) {
343  OOFEM_ERROR("test failure (elem %d, error=%e)", this->number, fabs( answer.at(i) - _t.at(i) ));
344  }
345  }
346 
347 #endif
348 
349 
350 #ifdef TR1_2D_SUPG2_DEBUG
351  /* test */
352  FloatArray test;
353  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
355  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
356  for ( int i = 1; i <= 6; i++ ) {
357  if ( fabs( ( answer.at(i) - test.at(i) ) / test.at(i) ) >= 1.e-10 ) {
358  OOFEM_ERROR("test failure");
359  }
360  }
361 
362 #endif
363 }
364 
365 
366 void
368 {
369  answer.resize(6, 6);
370  answer.zero();
371 
372  FloatArray u, un, n;
373  double rho;
374  this->computeVectorOfVelocities(VM_Total, tStep, u);
375  this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
376 
377  double u1, u2, dV;
378  int w_dof_addr, u_dof_addr, dij;
379 
380 
381  // dN(v)/dv
382  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
383  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
384  rho = this->_giveMaterial(ifluid)->give('d', gp);
385  this->computeNVector(n, gp);
386  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
387 
388  u1 = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
389  u2 = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
390  for ( int i = 1; i <= 2; i++ ) { // test function index
391  for ( int k = 1; k <= 3; k++ ) { // nodal val of test function w
392  for ( int j = 1; j <= 2; j++ ) { // velocity vector component
393  for ( int m = 1; m <= 3; m++ ) { // nodal component
394  w_dof_addr = ( k - 1 ) * 2 + i;
395  u_dof_addr = ( m - 1 ) * 2 + j;
396  dij = ( i == j );
397  answer.at(w_dof_addr, u_dof_addr) += rho * dV * n.at(k) * ( u1 * dij * b [ m - 1 ] + u2 * dij * c [ m - 1 ] );
398  }
399  }
400  }
401  }
402  }
403  }
404 
405  // stabilization term dN_delta/du
406  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
407  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
408  rho = this->_giveMaterial(ifluid)->give('d', gp);
409  this->computeNVector(n, gp);
410  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
411 
412  u1 = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
413  u2 = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
414  for ( int i = 1; i <= 2; i++ ) { // test function index
415  for ( int k = 1; k <= 3; k++ ) { // nodal val of function w
416  for ( int j = 1; j <= 2; j++ ) { // velocity vector component
417  for ( int m = 1; m <= 3; m++ ) { // nodal components
418  w_dof_addr = ( k - 1 ) * 2 + i;
419  u_dof_addr = ( m - 1 ) * 2 + j;
420  dij = ( i == j );
421  answer.at(w_dof_addr, u_dof_addr) += t_supg * rho * dV * ( u1 * b [ k - 1 ] + u2 * c [ k - 1 ] ) * ( u1 * dij * b [ m - 1 ] + u2 * dij * c [ m - 1 ] );
422  }
423  }
424  }
425  }
426  }
427  }
428 
429 #ifdef TR1_2D_SUPG2_DEBUG
430  /* test */
431  FloatMatrix test;
432  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
434  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
435  for ( int i = 1; i <= 6; i++ ) {
436  for ( int j = 1; j <= 6; j++ ) {
437  if ( fabs( ( answer.at(i, j) - test.at(i, j) ) / test.at(i, j) ) >= 1.e-8 ) {
438  OOFEM_ERROR("test failure (err=%e)", ( answer.at(i, j) - test.at(i, j) ) / test.at(i, j));
439  }
440  }
441  }
442 
443 #endif
444 }
445 
446 
447 void
449 {
450  answer.resize(6);
451  answer.zero();
452  FloatArray u, eps(3), stress;
453  double dV, Re = static_cast< FluidModel * >( domain->giveEngngModel() )->giveReynoldsNumber();
454  //double dudx,dudy,dvdx,dvdy;
455 
456  this->computeVectorOfVelocities(VM_Total, tStep, u);
457 
458  eps.at(1) = ( b [ 0 ] * u.at(1) + b [ 1 ] * u.at(3) + b [ 2 ] * u.at(5) );
459  eps.at(2) = ( c [ 0 ] * u.at(2) + c [ 1 ] * u.at(4) + c [ 2 ] * u.at(6) );
460  eps.at(3) = ( b [ 0 ] * u.at(2) + b [ 1 ] * u.at(4) + b [ 2 ] * u.at(6) + c [ 0 ] * u.at(1) + c [ 1 ] * u.at(3) + c [ 2 ] * u.at(5) );
461 
462  /*
463  * this -> computeVectorOfVelocities(VM_Total,tStep->givePreviousStep(), un) ;
464  * dudx = b[0]*un.at(1)+b[1]*un.at(3)+b[2]*un.at(5);
465  * dudy = c[0]*un.at(1)+c[1]*un.at(3)+c[2]*un.at(5);
466  * dvdx = b[0]*un.at(2)+b[1]*un.at(4)+b[2]*un.at(6);
467  * dvdy = c[0]*un.at(2)+c[1]*un.at(4)+c[2]*un.at(6);
468  */
469 
470  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
471  FluidDynamicMaterial *mat = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(ifluid) );
472  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
473  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
474 
475  mat->computeDeviatoricStressVector(stress, gp, eps, tStep);
476  stress.times(1. / Re);
477 
478  // \int dNu/dxj \Tau_ij
479  for ( int i = 0; i < 3; i++ ) {
480  //rh1p(1,lok) = -geome(7,ia)*( sigxx(ia)*geome(lok,ia) + sigxy(ia)*geome(lok1,ia) )*0.5d+00;
481  //rh1p(2,lok) = -geome(7,ia)*( sigxy(ia)*geome(lok,ia) + sigyy(ia)*geome(lok1,ia) )*0.5d+00;
482  answer.at( ( i ) * 2 + 1 ) += dV * ( stress.at(1) * b [ i ] + stress.at(3) * c [ i ] );
483  answer.at( ( i + 1 ) * 2 ) += dV * ( stress.at(3) * b [ i ] + stress.at(2) * c [ i ] );
484 
485  /*
486  * // stabilization term k_delta
487  * answer.at((i)*2+1) += t_supg* dV * (stress.at(1)*(dudx*b[i]+dvdx*c[i]) + stress.at(3)*(dudy*b[i]+dvdy*c[i]));
488  * answer.at((i+1)*2) += t_supg* dV * (stress.at(3)*(dudx*b[i]+dvdx*c[i]) + stress.at(2)*(dudy*b[i]+dvdy*c[i]));
489  */
490  }
491  }
492  }
493 
494 #ifdef TR1_2D_SUPG2_DEBUG
495  /* test */
496  FloatArray test;
497  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
499  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
500  for ( int i = 1; i <= 6; i++ ) {
501  if ( fabs( ( answer.at(i) - test.at(i) ) / test.at(i) ) >= 1.e-10 ) {
502  OOFEM_ERROR("test failure");
503  }
504  }
505 
506 #endif
507 }
508 
509 
510 void
512 {
513  double dV;
514  //double dudx, dudy, dvdx, dvdy;
515  answer.resize(6, 6);
516  answer.zero();
517  FloatMatrix _db, _d, _b(3, 6);
518  //FloatArray un;
519  double Re = static_cast< FluidModel * >( domain->giveEngngModel() )->giveReynoldsNumber();
520 
521  _b.at(1, 1) = b [ 0 ];
522  _b.at(1, 2) = 0.;
523  _b.at(1, 3) = b [ 1 ];
524  _b.at(1, 4) = 0.;
525  _b.at(1, 5) = b [ 2 ];
526  _b.at(1, 6) = 0.;
527  _b.at(2, 1) = 0.;
528  _b.at(2, 2) = c [ 0 ];
529  _b.at(2, 3) = 0.;
530  _b.at(2, 4) = c [ 1 ];
531  _b.at(2, 5) = 0.;
532  _b.at(2, 6) = c [ 2 ];
533  _b.at(3, 1) = c [ 0 ];
534  _b.at(3, 2) = b [ 0 ];
535  _b.at(3, 3) = c [ 1 ];
536  _b.at(3, 4) = b [ 1 ];
537  _b.at(3, 5) = c [ 2 ];
538  _b.at(3, 6) = b [ 2 ];
539 
540  /*
541  * // stabilization terms
542  * this -> computeVectorOfVelocities(VM_Total,tStep->givePreviousStep(), un) ;
543  * dudx = b[0]*un.at(1)+b[1]*un.at(3)+b[2]*un.at(5);
544  * dudy = c[0]*un.at(1)+c[1]*un.at(3)+c[2]*un.at(5);
545  * dvdx = b[0]*un.at(2)+b[1]*un.at(4)+b[2]*un.at(6);
546  * dvdy = c[0]*un.at(2)+c[1]*un.at(4)+c[2]*un.at(6);
547  *
548  * _bs.at(1,1)=dudx*b[0]+dvdx*c[0]; _bs.at(1,2)=0.; _bs.at(1,3)=dudx*b[1]+dvdx*c[1]; _bs.at(1,4)=0.; _bs.at(1,5)=dudx*b[2]+dvdx*c[2]; _bs.at(1,6)=0.;
549  * _bs.at(2,1)=0.; _bs.at(2,2)=dudy*b[0]+dvdy*c[0]; _bs.at(2,3)=0.; _bs.at(2,4)=dudy*b[1]+dvdy*c[1]; _bs.at(2,5)=0.; _bs.at(2,6)=dudy*b[2]+dvdy*c[2];
550  * _bs.at(3,1)=dudy*b[0]+dvdy*c[0]; _bs.at(3,2)=dudx*b[0]+dvdx*c[0];
551  * _bs.at(3,3)=dudy*b[1]+dvdy*c[1]; _bs.at(3,4)=dudx*b[1]+dvdx*c[1];
552  * _bs.at(3,5)=dudy*b[2]+dvdy*c[2]; _bs.at(3,6)=dudx*b[2]+dvdx*c[2];
553  */
554 
555  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
556  FluidDynamicMaterial *mat = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(ifluid) );
557  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
558  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
559 
560 
561  mat->giveDeviatoricStiffnessMatrix(_d, mode, gp, tStep);
562  _db.beProductOf(_d, _b);
563  answer.plusProductSymmUpper(_b, _db, dV);
564  //answer.plusProductSymmUpper (_bs,_db,dV*t_supg);
565 
566  answer.symmetrized();
567  }
568  }
569 
570  answer.times(1. / Re);
571 
572 #ifdef TR1_2D_SUPG2_DEBUG
573  /* test */
574  FloatMatrix test;
575  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
577  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
578  for ( int i = 1; i <= 6; i++ ) {
579  for ( int j = 1; j <= 6; j++ ) {
580  if ( fabs( ( answer.at(i, j) - test.at(i, j) ) / test.at(i, j) ) >= 1.e-8 ) {
581  OOFEM_ERROR("test failure (err=%e)", ( answer.at(i, j) - test.at(i, j) ) / test.at(i, j));
582  }
583  }
584  }
585 
586 #endif
587 }
588 
589 
590 void
592 {
593  // TR1_2D_SUPG :: computePressureTerm_MB(answer, tStep);
594  answer.resize(6, 3);
595  answer.zero();
596  FloatArray p, un;
597  double usum, vsum;
598  double ar3 = area / 3.0, coeff;
599 
600  this->computeVectorOfPressures(VM_Total, tStep, p);
601 
602 
603  // G matrix
604  answer.at(1, 1) = answer.at(1, 2) = answer.at(1, 3) = -b [ 0 ] * ar3;
605  answer.at(3, 1) = answer.at(3, 2) = answer.at(3, 3) = -b [ 1 ] * ar3;
606  answer.at(5, 1) = answer.at(5, 2) = answer.at(5, 3) = -b [ 2 ] * ar3;
607 
608  answer.at(2, 1) = answer.at(2, 2) = answer.at(2, 3) = -c [ 0 ] * ar3;
609  answer.at(4, 1) = answer.at(4, 2) = answer.at(4, 3) = -c [ 1 ] * ar3;
610  answer.at(6, 1) = answer.at(6, 2) = answer.at(6, 3) = -c [ 2 ] * ar3;
611 
612  // stabilization term (G_\delta mtrx)
613  this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
614 
615  usum = un.at(1) + un.at(3) + un.at(5);
616  vsum = un.at(2) + un.at(4) + un.at(6);
617  coeff = ar3 * t_supg;
618 
619  answer.at(1, 1) += coeff * ( usum * b [ 0 ] * b [ 0 ] + vsum * c [ 0 ] * b [ 0 ] );
620  answer.at(1, 2) += coeff * ( usum * b [ 0 ] * b [ 1 ] + vsum * c [ 0 ] * b [ 1 ] );
621  answer.at(1, 3) += coeff * ( usum * b [ 0 ] * b [ 2 ] + vsum * c [ 0 ] * b [ 2 ] );
622 
623  answer.at(3, 1) += coeff * ( usum * b [ 1 ] * b [ 0 ] + vsum * c [ 1 ] * b [ 0 ] );
624  answer.at(3, 2) += coeff * ( usum * b [ 1 ] * b [ 1 ] + vsum * c [ 1 ] * b [ 1 ] );
625  answer.at(3, 3) += coeff * ( usum * b [ 1 ] * b [ 2 ] + vsum * c [ 1 ] * b [ 2 ] );
626 
627  answer.at(5, 1) += coeff * ( usum * b [ 2 ] * b [ 0 ] + vsum * c [ 2 ] * b [ 0 ] );
628  answer.at(5, 2) += coeff * ( usum * b [ 2 ] * b [ 1 ] + vsum * c [ 2 ] * b [ 1 ] );
629  answer.at(5, 3) += coeff * ( usum * b [ 2 ] * b [ 2 ] + vsum * c [ 2 ] * b [ 2 ] );
630 
631  answer.at(2, 1) += coeff * ( usum * b [ 0 ] * c [ 0 ] + vsum * c [ 0 ] * c [ 0 ] );
632  answer.at(2, 2) += coeff * ( usum * b [ 0 ] * c [ 1 ] + vsum * c [ 0 ] * c [ 1 ] );
633  answer.at(2, 3) += coeff * ( usum * b [ 0 ] * c [ 2 ] + vsum * c [ 0 ] * c [ 2 ] );
634 
635  answer.at(4, 1) += coeff * ( usum * b [ 1 ] * c [ 0 ] + vsum * c [ 1 ] * c [ 0 ] );
636  answer.at(4, 2) += coeff * ( usum * b [ 1 ] * c [ 1 ] + vsum * c [ 1 ] * c [ 1 ] );
637  answer.at(4, 3) += coeff * ( usum * b [ 1 ] * c [ 2 ] + vsum * c [ 1 ] * c [ 2 ] );
638 
639  answer.at(6, 1) += coeff * ( usum * b [ 2 ] * c [ 0 ] + vsum * c [ 2 ] * c [ 0 ] );
640  answer.at(6, 2) += coeff * ( usum * b [ 2 ] * c [ 1 ] + vsum * c [ 2 ] * c [ 1 ] );
641  answer.at(6, 3) += coeff * ( usum * b [ 2 ] * c [ 2 ] + vsum * c [ 2 ] * c [ 2 ] );
642 }
643 
644 
645 void
647 {
648  answer.resize(6, 6);
649  answer.zero();
650  double dV, rho;
651  //double coeff = area*t_lsic*rho;
652  double n[] = {
653  b [ 0 ], c [ 0 ], b [ 1 ], c [ 1 ], b [ 2 ], c [ 2 ]
654  };
655 
656  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
657  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
658  rho = this->_giveMaterial(ifluid)->give('d', gp);
659  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
660 
661 
662  for ( int i = 1; i <= 6; i++ ) {
663  for ( int j = 1; j <= 6; j++ ) {
664  answer.at(i, j) += dV * t_lsic * rho * n [ i - 1 ] * n [ j - 1 ];
665  }
666  }
667  }
668  }
669 
670 #ifdef TR1_2D_SUPG2_DEBUG
671  /* test */
672  FloatMatrix test;
673  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
675  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
676  for ( int i = 1; i <= 6; i++ ) {
677  for ( int j = 1; j <= 6; j++ ) {
678  if ( fabs( ( answer.at(i, j) - test.at(i, j) ) / test.at(i, j) ) >= 1.e-8 ) {
679  OOFEM_ERROR("test failure (err=%e)", ( answer.at(i, j) - test.at(i, j) ) / test.at(i, j));
680  }
681  }
682  }
683 
684 #endif
685 }
686 
687 
688 void
690 {
692 }
693 
694 void
696 {
697  // N_epsilon (due to PSPG stabilization)
698  double coeff = t_pspg * area / 3.0;
699  double dudx, dudy, dvdx, dvdy, usum, vsum;
700  FloatArray u, un;
701 
702  this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
703  this->computeVectorOfVelocities(VM_Total, tStep, u);
704 
705  dudx = b [ 0 ] * u.at(1) + b [ 1 ] * u.at(3) + b [ 2 ] * u.at(5);
706  dudy = c [ 0 ] * u.at(1) + c [ 1 ] * u.at(3) + c [ 2 ] * u.at(5);
707  dvdx = b [ 0 ] * u.at(2) + b [ 1 ] * u.at(4) + b [ 2 ] * u.at(6);
708  dvdy = c [ 0 ] * u.at(2) + c [ 1 ] * u.at(4) + c [ 2 ] * u.at(6);
709 
710  usum = un.at(1) + un.at(3) + un.at(5);
711  vsum = un.at(2) + un.at(4) + un.at(6);
712 
713  answer.resize(3);
714 
715  answer.at(1) = coeff * ( b [ 0 ] * ( dudx * usum + dudy * vsum ) + c [ 0 ] * ( dvdx * usum + dvdy * vsum ) );
716  answer.at(2) = coeff * ( b [ 1 ] * ( dudx * usum + dudy * vsum ) + c [ 1 ] * ( dvdx * usum + dvdy * vsum ) );
717  answer.at(3) = coeff * ( b [ 2 ] * ( dudx * usum + dudy * vsum ) + c [ 2 ] * ( dvdx * usum + dvdy * vsum ) );
718 }
719 
720 
721 void
723 {
724  answer.resize(3, 6);
725  answer.zero();
726  int w_dof_addr, u_dof_addr, d1j, d2j, km1, mm1;
727  FloatArray u, un;
728 
729  this->computeVectorOfVelocities(VM_Total, tStep, u);
730  this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
731 
732  double dudx [ 2 ] [ 2 ], usum [ 2 ];
733  double coeff;
734 
735  dudx [ 0 ] [ 0 ] = b [ 0 ] * u.at(1) + b [ 1 ] * u.at(3) + b [ 2 ] * u.at(5);
736  dudx [ 0 ] [ 1 ] = c [ 0 ] * u.at(1) + c [ 1 ] * u.at(3) + c [ 2 ] * u.at(5);
737  dudx [ 1 ] [ 0 ] = b [ 0 ] * u.at(2) + b [ 1 ] * u.at(4) + b [ 2 ] * u.at(6);
738  dudx [ 1 ] [ 1 ] = c [ 0 ] * u.at(2) + c [ 1 ] * u.at(4) + c [ 2 ] * u.at(6);
739  usum [ 0 ] = un.at(1) + un.at(3) + un.at(5);
740  usum [ 1 ] = un.at(2) + un.at(4) + un.at(6);
741 
742  // dN_epsilon(v)/dv
743  coeff = t_pspg * area / 3.;
744  for ( int k = 1; k <= 3; k++ ) { // nodal val of function w
745  km1 = k - 1;
746  for ( int j = 1; j <= 2; j++ ) { // velocity vector component
747  for ( int m = 1; m <= 3; m++ ) { // nodal components
748  w_dof_addr = k;
749  u_dof_addr = ( m - 1 ) * 2 + j;
750  mm1 = m - 1;
751  d1j = ( j == 1 );
752  d2j = ( j == 2 );
753  answer.at(w_dof_addr, u_dof_addr) = coeff * ( 0.0 * d1j * b [ km1 ] * dudx [ 0 ] [ 0 ] + d1j * b [ km1 ] * b [ mm1 ] * usum [ 0 ] +
754  0.0 * d2j * b [ km1 ] * dudx [ 0 ] [ 1 ] + d1j * b [ km1 ] * c [ mm1 ] * usum [ 1 ] +
755  0.0 * d1j * c [ km1 ] * dudx [ 1 ] [ 0 ] + d2j * c [ km1 ] * b [ mm1 ] * usum [ 0 ] +
756  0.0 * d2j * c [ km1 ] * dudx [ 1 ] [ 1 ] + d2j * c [ km1 ] * c [ mm1 ] * usum [ 1 ] );
757  }
758  }
759  }
760 }
761 
762 void
764 {
766 }
767 
768 void
770 {
771  double dV, rho;
772  //double coeff = t_pspg*area/rho;
773  answer.resize(3, 3);
774  answer.zero();
775 
776  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
777  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
778  rho = this->_giveMaterial(ifluid)->give('d', gp);
779  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
780 
781 
782  for ( int i = 1; i <= 3; i++ ) {
783  for ( int j = 1; j <= 3; j++ ) {
784  answer.at(i, j) += t_pspg * dV * ( b [ i - 1 ] * b [ j - 1 ] + c [ i - 1 ] * c [ j - 1 ] ) / rho;
785  }
786  }
787  }
788  }
789 
790 #ifdef TR1_2D_SUPG2_DEBUG
791  /* test */
792  FloatMatrix test;
793  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
795  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
796  for ( int i = 1; i <= 3; i++ ) {
797  for ( int j = 1; j <= 3; j++ ) {
798  if ( fabs( ( answer.at(i, j) - test.at(i, j) ) / test.at(i, j) ) >= 1.e-8 ) {
799  OOFEM_ERROR("test failure (err=%e)", ( answer.at(i, j) - test.at(i, j) ) / test.at(i, j));
800  }
801  }
802  }
803 
804 #endif
805 }
806 
808 void
810 {
811  answer.resize(6);
812  answer.zero();
813 
814  int nLoads;
815  Load *load;
816  bcGeomType ltype;
817  double rho;
818  FloatArray un, n, gVector;
819  double u1, u2, dV;
820 
821  // add body load (gravity) termms
822  this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
823 
824  nLoads = this->giveBodyLoadArray()->giveSize();
825  for ( int i = 1; i <= nLoads; i++ ) {
826  load = domain->giveLoad( this->bodyLoadArray.at(i) );
827  ltype = load->giveBCGeoType();
828  if ( ( ltype == BodyLoadBGT ) && ( load->giveBCValType() == ForceLoadBVT ) ) {
829  load->computeComponentArrayAt(gVector, tStep, VM_Total);
830  if ( gVector.giveSize() ) {
831  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
832  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
833  rho = this->_giveMaterial(ifluid)->give('d', gp);
834  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
835  this->computeNVector(n, gp);
836 
837  u1 = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
838  u2 = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
839 
840  for ( i = 1; i <= 3; i++ ) {
841  answer.at(i * 2 - 1) += rho * dV * gVector.at(1) * ( n.at(i) + t_supg * ( u1 * b [ i - 1 ] + u2 * c [ i - 1 ] ) );
842  answer.at(i * 2) += rho * dV * gVector.at(2) * ( n.at(i) + t_supg * ( u1 * b [ i - 1 ] + u2 * c [ i - 1 ] ) );
843  }
844  }
845  }
846  }
847  }
848  }
849 
850  // loop over sides
851  int n1, n2;
852  int lnum, id;
853  double tx, ty, length;
854  FloatArray t, coords(1);
855  BoundaryLoad *bload;
856 
857  // loop over boundary load array
858  nLoads = this->giveBoundaryLoadArray()->giveSize() / 2;
859  for ( int i = 1; i <= nLoads; i++ ) {
860  lnum = boundaryLoadArray.at(1 + ( i - 1 ) * 2);
861  id = boundaryLoadArray.at(i * 2);
862  load = domain->giveLoad(lnum);
863  if ( load->giveBCValType() == ForceLoadBVT ) {
864  // integrate tractions
865  n1 = id;
866  n2 = ( n1 == 3 ? 1 : n1 + 1 );
867 
868  tx = giveNode(n2)->giveCoordinate(1) - giveNode(n1)->giveCoordinate(1);
869  ty = giveNode(n2)->giveCoordinate(2) - giveNode(n1)->giveCoordinate(2);
870  length = sqrt(tx * tx + ty * ty);
871  //nx = ty / length;
872  //ny = -tx / length;
873 
874  bload = dynamic_cast< BoundaryLoad * >(load);
875  if ( bload ) {
876  bload->computeValueAt(t, tStep, coords, VM_Total);
877 
878  // here it is assumed constant traction, one point integration only
879  // n1 (u,v)
880  answer.at( ( n1 - 1 ) * 2 + 1 ) += t.at(1) * length / 2.;
881  answer.at(n1 * 2) += t.at(2) * length / 2.;
882  // n2 (u,v)
883  answer.at( ( n2 - 1 ) * 2 + 1 ) += t.at(1) * length / 2.;
884  answer.at(n2 * 2) += t.at(2) * length / 2.;
885 
886  //answer.at(n1)+= (t.at(1)*nx + t.at(2)*ny) * length/2.;
887  //answer.at(n2)+= (t.at(1)*nx + t.at(2)*ny) * length/2.;
888  }
889  }
890  }
891 
892 #ifdef TR1_2D_SUPG2_DEBUG
893  /* test */
894  FloatArray test;
895  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
897  std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
898  for ( int i = 1; i <= 6; i++ ) {
899  if ( fabs( ( answer.at(i) - test.at(i) ) / test.at(i) ) >= 1.e-10 ) {
900  OOFEM_ERROR("test failure");
901  }
902  }
903 
904 #endif
905 }
906 
907 void
909 {
910  TR1_2D_SUPG :: computeBCRhsTerm_MC(answer, tStep);
911 }
912 
913 
914 void
916 {
917  //TR1_2D_SUPG :: updateStabilizationCoeffs (tStep);
918 #if 0
919  int i, j, k, l, w_dof_addr, u_dof_addr, ip, ifluid;
920  double __g_norm, __gamma_norm, __gammav_norm, __beta_norm, __betav_norm, __c_norm, __e_norm, __k_norm, __Re;
921  double __t_p1, __t_p2, __t_p3, __t_pv1, __t_pv2, __t_pv3;
922  double nu, nu0, nu1, usum, vsum, rho, dV, u1, u2;
923  FloatArray u, un, a;
924 
925  // compute averaged viscosity based on rule of mixture
926  GaussPoint *gp;
927  if ( integrationRulesArray [ 0 ]->giveNumberOfIntegrationPoints() ) {
928  gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
929  } else {
930  gp = integrationRulesArray [ 1 ]->getIntegrationPoint(0);
931  }
932 
933  nu0 = this->_giveMaterial(0)->giveCharacteristicValue(MRM_Viscosity, gp, tStep);
934  nu1 = this->_giveMaterial(1)->giveCharacteristicValue(MRM_Viscosity, gp, tStep);
935  nu = vof * nu0 + ( 1. - vof ) * nu1;
936 
937  //this -> computeVectorOfVelocities(VM_Total,tStep->givePreviousStep(),un) ;
938  this->computeVectorOfVelocities(VM_Total, tStep, u);
939  this->computeVectorOfVelocities(VM_Acceleration, tStep, a);
940 
941  un = u;
942  usum = un.at(1) + un.at(3) + un.at(5);
943  vsum = un.at(2) + un.at(4) + un.at(6);
944 
945  FloatMatrix __tmp;
946  FloatArray __tmpvec, n;
947  // assemble g matrix
948  __tmp.resize(6, 3);
949  double ar3 = area / 3.0;
950 
951  __tmp.at(1, 1) = __tmp.at(1, 2) = __tmp.at(1, 3) = b [ 0 ] * ar3;
952  __tmp.at(3, 1) = __tmp.at(3, 2) = __tmp.at(3, 3) = b [ 1 ] * ar3;
953  __tmp.at(5, 1) = __tmp.at(5, 2) = __tmp.at(5, 3) = b [ 2 ] * ar3;
954 
955  __tmp.at(2, 1) = __tmp.at(2, 2) = __tmp.at(2, 3) = c [ 0 ] * ar3;
956  __tmp.at(4, 1) = __tmp.at(4, 2) = __tmp.at(4, 3) = c [ 1 ] * ar3;
957  __tmp.at(6, 1) = __tmp.at(6, 2) = __tmp.at(6, 3) = c [ 2 ] * ar3;
958 
959  __g_norm = __tmp.computeFrobeniusNorm();
960 
961  // assemble \gamma matrix (advectionTerm of mass conservation eq)
962  __tmp.resize(3, 6);
963  for ( k = 1; k <= 3; k++ ) {
964  for ( l = 1; l <= 3; l++ ) {
965  __tmp.at(k, l * 2 - 1) = ar3 * b [ k - 1 ] * ( usum * b [ l - 1 ] + vsum * c [ l - 1 ] );
966  __tmp.at(k, l * 2) = ar3 * c [ k - 1 ] * ( usum * b [ l - 1 ] + vsum * c [ l - 1 ] );
967  }
968  }
969 
970  __gamma_norm = __tmp.computeFrobeniusNorm();
971  __tmpvec.beProductOf(__tmp, u);
972  __gammav_norm = __tmpvec.computeNorm();
973  // compute beta mtrx (acceleration term of mass conservation eq)
974  __tmp.resize(3, 6);
975  __tmp.zero();
976  __tmp.at(1, 1) = __tmp.at(1, 3) = __tmp.at(1, 5) = ar3 * b [ 0 ];
977  __tmp.at(1, 2) = __tmp.at(1, 4) = __tmp.at(1, 6) = ar3 * c [ 0 ];
978  __tmp.at(2, 1) = __tmp.at(2, 3) = __tmp.at(2, 5) = ar3 * b [ 1 ];
979  __tmp.at(2, 2) = __tmp.at(2, 4) = __tmp.at(2, 6) = ar3 * c [ 1 ];
980  __tmp.at(3, 1) = __tmp.at(3, 3) = __tmp.at(3, 5) = ar3 * b [ 2 ];
981  __tmp.at(3, 2) = __tmp.at(3, 4) = __tmp.at(3, 6) = ar3 * c [ 2 ];
982  __beta_norm = __tmp.computeFrobeniusNorm();
983  __tmpvec.beProductOf(__tmp, a);
984  __betav_norm = __tmpvec.computeNorm();
985  // compute c mtrx (advection term of momentum balance)
986  // standard galerkin term
987  __tmp.resize(6, 6);
988  __tmp.zero();
989  for ( ifluid = 0; ifluid < 2; ifluid++ ) {
990  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
991  rho = this->_giveMaterial(ifluid)->give('d', gp);
992  this->computeNVector(n, gp);
993  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
994 
995  u1 = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
996  u2 = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
997  for ( i = 1; i <= 2; i++ ) {
998  for ( k = 1; k <= 3; k++ ) {
999  for ( l = 1; l <= 3; l++ ) {
1000  w_dof_addr = ( k - 1 ) * 2 + i;
1001  u_dof_addr = ( l - 1 ) * 2 + i;
1002  __tmp.at(w_dof_addr, u_dof_addr) += rho * dV * n.at(k) * ( u1 * b [ l - 1 ] + u2 * c [ l - 1 ] );
1003  }
1004  }
1005  }
1006  }
1007  }
1008 
1009  __c_norm = __tmp.computeFrobeniusNorm();
1010  // compute e mtrx (advection term of momentum balance)
1011  __tmp.resize(6, 6);
1012  __tmp.zero();
1013  double __n[] = {
1014  b [ 0 ], c [ 0 ], b [ 1 ], c [ 1 ], b [ 2 ], c [ 2 ]
1015  };
1016  for ( ifluid = 0; ifluid < 2; ifluid++ ) {
1017  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
1018  rho = this->_giveMaterial(ifluid)->give('d', gp);
1019  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
1020 
1021  for ( i = 1; i <= 6; i++ ) {
1022  for ( j = 1; j <= 6; j++ ) {
1023  __tmp.at(i, j) += dV * rho * __n [ i - 1 ] * __n [ j - 1 ];
1024  }
1025  }
1026  }
1027  }
1028 
1029  __e_norm = __tmp.computeFrobeniusNorm();
1030  // compute element level Reynolds number
1031  // compute k norm first
1032  __tmp.resize(6, 6);
1033  __tmp.zero();
1034  for ( ifluid = 0; ifluid < 2; ifluid++ ) {
1035  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
1036  rho = this->_giveMaterial(ifluid)->give('d', gp);
1037  this->computeNVector(n, gp);
1038  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
1039 
1040  u1 = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
1041  u2 = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
1042  for ( k = 1; k <= 3; k++ ) {
1043  for ( l = 1; l <= 3; l++ ) {
1044  __tmp.at(k * 2 - 1, l * 2 - 1) += rho * dV * ( u1 * b [ k - 1 ] + u2 * c [ k - 1 ] ) * ( u1 * b [ l - 1 ] + u2 * c [ l - 1 ] );
1045  __tmp.at(k * 2, l * 2) += rho * dV * ( u1 * b [ k - 1 ] + u2 * c [ k - 1 ] ) * ( u1 * b [ l - 1 ] + u2 * c [ l - 1 ] );
1046  }
1047  }
1048  }
1049  }
1050 
1051  __k_norm = __tmp.computeFrobeniusNorm();
1052  double u_1, u_2, vnorm = 0.;
1053  int im1;
1054  for ( i = 1; i <= 3; i++ ) {
1055  im1 = i - 1;
1056  u_1 = u.at( ( im1 ) * 2 + 1 );
1057  u_2 = u.at( ( im1 ) * 2 + 2 );
1058  vnorm = max( vnorm, sqrt(u_1 * u_1 + u_2 * u_2) );
1059  }
1060 
1061  if ( vnorm == 0.0 ) {
1062  //t_sugn1 = inf;
1063  double t_sugn2 = tStep->giveTimeIncrement() / 2.0;
1064  //t_sugn3 = inf;
1065  this->t_supg = 1. / sqrt( 1. / ( t_sugn2 * t_sugn2 ) );
1066  this->t_pspg = this->t_supg;
1067  this->t_lsic = 0.0;
1068  } else {
1069  __Re = vnorm * vnorm * __c_norm / __k_norm / nu;
1070 
1071  __t_p1 = __g_norm / __gamma_norm;
1072  __t_p2 = tStep->giveTimeIncrement() * __g_norm / 2.0 / __beta_norm;
1073  __t_p3 = __t_p1 * __Re;
1074  this->t_pspg = 1. / sqrt( 1. / ( __t_p1 * __t_p1 ) + 1. / ( __t_p2 * __t_p2 ) + 1. / ( __t_p3 * __t_p3 ) );
1075 
1076  __t_pv1 = __t_p1;
1077  __t_pv2 = __t_pv1 * __gammav_norm / __betav_norm;
1078  __t_pv3 = __t_pv1 * __Re;
1079  this->t_supg = 1. / sqrt( 1. / ( __t_pv1 * __t_pv1 ) + 1. / ( __t_pv2 * __t_pv2 ) + 1. / ( __t_pv3 * __t_pv3 ) );
1080 
1081  this->t_lsic = __c_norm / __e_norm;
1082  }
1083 
1084 #else
1085  /* UGN-Based Stabilization */
1086  double h_ugn, sum = 0.0, vnorm, t_sugn1, t_sugn2, t_sugn3, u_1, u_2, z, Re_ugn;
1087  double dscale, uscale, lscale, tscale, dt;
1088  //bool zeroFlag = false;
1089  int im1;
1090  FloatArray u;
1091 
1096 
1097  this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), u);
1098  u.times(uscale);
1099  double nu, nu0, nu1;
1100 
1101  // compute averaged viscosity based on rule of mixture
1102  GaussPoint *gp;
1103  if ( integrationRulesArray [ 0 ]->giveNumberOfIntegrationPoints() ) {
1104  gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
1105  } else {
1106  gp = integrationRulesArray [ 1 ]->getIntegrationPoint(0);
1107  }
1108 
1109  nu0 = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(0) )->giveEffectiveViscosity( gp, tStep->givePreviousStep() );
1110  nu1 = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(1) )->giveEffectiveViscosity( gp, tStep->givePreviousStep() );
1111  nu = vof * nu0 + ( 1. - vof ) * nu1;
1113 
1114  dt = tStep->giveTimeIncrement() * tscale;
1115 
1116  for ( int i = 1; i <= 3; i++ ) {
1117  im1 = i - 1;
1118  sum += fabs(u.at( ( im1 ) * 2 + 1 ) * b [ im1 ] / lscale + u.at(im1 * 2 + 2) * c [ im1 ] / lscale);
1119  }
1120 
1121  /*
1122  * u_1=(u.at(1)+u.at(3)+u.at(5))/3.0;
1123  * u_2=(u.at(2)+u.at(4)+u.at(6))/3.0;
1124  * vnorm=sqrt(u_1*u_1+u_2*u_2);
1125  */
1126  vnorm = 0.;
1127  for ( int i = 1; i <= 3; i++ ) {
1128  im1 = i - 1;
1129  u_1 = u.at( ( im1 ) * 2 + 1 );
1130  u_2 = u.at( ( im1 ) * 2 + 2 );
1131  vnorm = max( vnorm, sqrt(u_1 * u_1 + u_2 * u_2) );
1132  }
1133 
1134  if ( ( vnorm == 0.0 ) || ( sum == 0.0 ) ) {
1135  //t_sugn1 = inf;
1136  t_sugn2 = dt / 2.0;
1137  //t_sugn3 = inf;
1138  this->t_supg = 1. / sqrt( 1. / ( t_sugn2 * t_sugn2 ) );
1139  this->t_pspg = this->t_supg;
1140  this->t_lsic = 0.0;
1141  } else {
1142  h_ugn = 2.0 * vnorm / sum;
1143  t_sugn1 = 1. / sum;
1144  t_sugn2 = dt / 2.0;
1145  t_sugn3 = h_ugn * h_ugn / 4.0 / nu;
1146 
1147  this->t_supg = 1. / sqrt( 1. / ( t_sugn1 * t_sugn1 ) + 1. / ( t_sugn2 * t_sugn2 ) + 1. / ( t_sugn3 * t_sugn3 ) );
1148  this->t_pspg = this->t_supg;
1149 
1150  Re_ugn = vnorm * h_ugn / ( 2. * nu );
1151  z = ( Re_ugn <= 3. ) ? Re_ugn / 3. : 1.0;
1152  this->t_lsic = h_ugn * vnorm * z / 2.0;
1153  }
1154 
1155  // if (this->number == 1) {
1156  // printf ("t_supg %e t_pspg %e t_lsic %e\n", t_supg, t_pspg, t_lsic);
1157  // }
1158 
1159 
1160  this->t_supg *= uscale / lscale;
1161  this->t_pspg *= 1. / ( lscale * dscale );
1162  this->t_lsic *= ( dscale * uscale ) / ( lscale * lscale );
1163 
1164  this->t_lsic = 0.0;
1165 
1166 #endif
1167 
1168  //this->t_lsic=0.0;
1169  //this->t_pspg=0.0;
1170 }
1171 
1172 
1173 
1174 double
1176 {
1177  return 1.e3;
1178 }
1179 
1180 
1181 Interface *
1183 {
1184  if ( interface == ZZNodalRecoveryModelInterfaceType ) {
1185  return static_cast< ZZNodalRecoveryModelInterface * >(this);
1186  } else if ( interface == NodalAveragingRecoveryModelInterfaceType ) {
1187  return static_cast< NodalAveragingRecoveryModelInterface * >(this);
1188  } else if ( interface == SPRNodalRecoveryModelInterfaceType ) {
1189  return static_cast< SPRNodalRecoveryModelInterface * >(this);
1190  } else if ( interface == SpatialLocalizerInterfaceType ) {
1191  return static_cast< SpatialLocalizerInterface * >(this);
1192  } else if ( interface == EIPrimaryFieldInterfaceType ) {
1193  return static_cast< EIPrimaryFieldInterface * >(this);
1194  } else if ( interface == LEPlicElementInterfaceType ) {
1195  return static_cast< LEPlicElementInterface * >(this);
1196  }
1197 
1198  return NULL;
1199 }
1200 
1201 
1202 void
1204 {
1205  /* one computes here average deviatoric stress, based on rule of mixture (this is used only for postprocessing) */
1206  FloatArray eps, s0, s1;
1207  answer.resize(3);
1208 
1209  this->computeDeviatoricStrain(eps, gp, tStep);
1210 
1211  static_cast< FluidDynamicMaterial * >( this->_giveMaterial(0) )->computeDeviatoricStressVector(s0, gp, eps, tStep);
1212  static_cast< FluidDynamicMaterial * >( this->_giveMaterial(1) )->computeDeviatoricStressVector(s1, gp, eps, tStep);
1213 
1214  for ( int i = 1; i <= 3; i++ ) {
1215  answer.at(i) = ( temp_vof ) * s0.at(i) + ( 1. - temp_vof ) * s1.at(i);
1216  }
1217 }
1218 
1219 
1220 /*
1221  * double
1222  * TR1_2D_SUPG2 :: computeCriticalTimeStep (TimeStep* tStep)
1223  * {
1224  * FloatArray u;
1225  * double dt1, dt2, dt;
1226  * double Re = static_cast<FluidModel*>(domain->giveEngngModel())->giveReynoldsNumber();
1227  *
1228  * this -> computeVectorOfVelocities(VM_Total,tStep, u) ;
1229  *
1230  * double vn1 = sqrt(u.at(1)*u.at(1)+u.at(2)*u.at(2));
1231  * double vn2 = sqrt(u.at(3)*u.at(3)+u.at(4)*u.at(4));
1232  * double vn3 = sqrt(u.at(5)*u.at(5)+u.at(6)*u.at(6));
1233  * double veln = max (vn1, max(vn2,vn3));
1234  *
1235  * double l1 = 1.0/(sqrt(b[0]*b[0]+c[0]*c[0]));
1236  * double l2 = 1.0/(sqrt(b[1]*b[1]+c[1]*c[1]));
1237  * double l3 = 1.0/(sqrt(b[2]*b[2]+c[2]*c[2]));
1238  *
1239  * double ln = min (l1, min (l2,l3));
1240  *
1241  * // viscous limit
1242  * dt2 = 0.5*ln*ln*Re;
1243  * if (veln != 0.0) {
1244  * dt1 = ln/veln;
1245  * dt = dt1*dt2/(dt1+dt2);
1246  * } else {
1247  * dt = dt2;
1248  * }
1249  * return dt;
1250  * }
1251  */
1252 
1253 
1254 double
1255 TR1_2D_SUPG2 :: computeLEPLICVolumeFraction(const FloatArray &n, const double p, LEPlic *matInterface, bool updFlag)
1256 {
1257  Polygon pg;
1258  double answer, volume = computeMyVolume(matInterface, updFlag);
1259  this->formVolumeInterfacePoly(pg, matInterface, n, p, updFlag);
1260  answer = fabs(pg.computeVolume() / volume);
1261  if ( answer > 1.000000001 ) {
1262  OOFEM_WARNING("VOF fraction out of bounds, vof = %e\n", answer);
1263  return 1.0;
1264  } else {
1265  return answer;
1266  }
1267 }
1268 
1269 void
1271  const FloatArray &normal, const double p, bool updFlag)
1272 {
1273  double x, y;
1274  Vertex v;
1275 
1276  matvolpoly.clear();
1277 
1278  if ( this->vof <= TRSUPG_ZERO_VOF ) {
1279  return;
1280  } else if ( this->vof >= ( 1 - TRSUPG_ZERO_VOF ) ) {
1281  for ( int i = 1; i <= 3; i++ ) {
1282  if ( updFlag ) {
1283  x = matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() );
1284  y = matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() );
1285  } else {
1286  x = this->giveNode(i)->giveCoordinate(1);
1287  y = this->giveNode(i)->giveCoordinate(2);
1288  }
1289 
1290  v.setCoords(x, y);
1291  matvolpoly.addVertex(v);
1292  }
1293 
1294  return;
1295  }
1296 
1297  this->formVolumeInterfacePoly(matvolpoly, matInterface, normal, p, updFlag);
1298 }
1299 
1300 
1301 void
1303  const FloatArray &normal, const double p, bool updFlag)
1304 {
1305  int next;
1306  bool nodeIn [ 3 ];
1307  double nx = normal.at(1), ny = normal.at(2), x, y;
1308  double tx, ty;
1309  Vertex v;
1310 
1311  matvolpoly.clear();
1312 
1313  for ( int i = 1; i <= 3; i++ ) {
1314  if ( updFlag ) {
1315  x = matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() );
1316  y = matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() );
1317  } else {
1318  x = this->giveNode(i)->giveCoordinate(1);
1319  y = this->giveNode(i)->giveCoordinate(2);
1320  }
1321 
1322  if ( ( nx * x + ny * y + p ) >= 0. ) {
1323  nodeIn [ i - 1 ] = true;
1324  } else {
1325  nodeIn [ i - 1 ] = false;
1326  }
1327  }
1328 
1329  if ( nodeIn [ 0 ] && nodeIn [ 1 ] && nodeIn [ 2 ] ) { // all nodes inside
1330  for ( int i = 1; i <= 3; i++ ) {
1331  if ( updFlag ) {
1332  x = matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() );
1333  y = matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() );
1334  } else {
1335  x = this->giveNode(i)->giveCoordinate(1);
1336  y = this->giveNode(i)->giveCoordinate(2);
1337  }
1338 
1339  v.setCoords(x, y);
1340  matvolpoly.addVertex(v);
1341  }
1342 
1343  return;
1344  } else if ( !( nodeIn [ 0 ] || nodeIn [ 1 ] || nodeIn [ 2 ] ) ) { // all nodes outside
1345  return;
1346  } else {
1347  for ( int i = 1; i <= 3; i++ ) {
1348  next = i < 3 ? i + 1 : 1;
1349  if ( nodeIn [ i - 1 ] ) {
1350  if ( updFlag ) {
1351  v.setCoords( matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() ),
1352  matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() ) );
1353  } else {
1354  v.setCoords( this->giveNode(i)->giveCoordinate(1),
1355  this->giveNode(i)->giveCoordinate(2) );
1356  }
1357 
1358  matvolpoly.addVertex(v);
1359  }
1360 
1361  if ( nodeIn [ next - 1 ] ^ nodeIn [ i - 1 ] ) {
1362  // compute intersection with (i,next) edge
1363  if ( updFlag ) {
1364  x = matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() );
1365  y = matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() );
1366  tx = matInterface->giveUpdatedXCoordinate( this->giveNode(next)->giveNumber() ) - x;
1367  ty = matInterface->giveUpdatedYCoordinate( this->giveNode(next)->giveNumber() ) - y;
1368  } else {
1369  x = this->giveNode(i)->giveCoordinate(1);
1370  y = this->giveNode(i)->giveCoordinate(2);
1371  tx = this->giveNode(next)->giveCoordinate(1) - x;
1372  ty = this->giveNode(next)->giveCoordinate(2) - y;
1373  }
1374 
1375  double s, sd = nx * tx + ny * ty;
1376  if ( fabs(sd) > 1.e-10 ) {
1377  s = ( -p - ( nx * x + ny * y ) ) / sd;
1378  v.setCoords(x + tx * s, y + ty * s);
1379  matvolpoly.addVertex(v);
1380  } else {
1381  // pathological case - lines are parallel
1382  if ( nodeIn [ i - 1 ] ) {
1383  if ( updFlag ) {
1384  v.setCoords( matInterface->giveUpdatedXCoordinate( this->giveNode(next)->giveNumber() ),
1385  matInterface->giveUpdatedYCoordinate( this->giveNode(next)->giveNumber() ) );
1386  } else {
1387  v.setCoords( this->giveNode(next)->giveCoordinate(1), this->giveNode(next)->giveCoordinate(2) );
1388  }
1389 
1390  matvolpoly.addVertex(v);
1391  } else {
1392  v.setCoords(x, y);
1393  matvolpoly.addVertex(v);
1394  if ( updFlag ) {
1395  v.setCoords( matInterface->giveUpdatedXCoordinate( this->giveNode(next)->giveNumber() ),
1396  matInterface->giveUpdatedYCoordinate( this->giveNode(next)->giveNumber() ) );
1397  } else {
1398  v.setCoords( this->giveNode(next)->giveCoordinate(1), this->giveNode(next)->giveCoordinate(2) );
1399  }
1400 
1401  matvolpoly.addVertex(v);
1402  }
1403  }
1404  }
1405  } // end loop over elem nodes
1406  }
1407 }
1408 
1409 
1410 void
1411 TR1_2D_SUPG2 :: updateVolumePolygons(Polygon &referenceFluidPoly, Polygon &secondFluidPoly, int &rfPoints, int &sfPoints,
1412  const FloatArray &normal, const double p, bool updFlag)
1413 {
1414  /*
1415  * this method updates two polygons, one filled with reference fluid and second filled with
1416  * other fluid (air). These two polygons are used in integrating element contributions.
1417  */
1418  int next;
1419  bool nodeIn [ 3 ];
1420  double nx = normal.at(1), ny = normal.at(2), x, y;
1421  double tx, ty;
1422  Vertex v;
1423 
1424  rfPoints = sfPoints = 0;
1425  referenceFluidPoly.clear();
1426  secondFluidPoly.clear();
1427 
1428  for ( int i = 1; i <= 3; i++ ) {
1429  x = this->giveNode(i)->giveCoordinate(1);
1430  y = this->giveNode(i)->giveCoordinate(2);
1431 
1432  if ( ( nx * x + ny * y + p ) >= 0. ) {
1433  nodeIn [ i - 1 ] = true;
1434  } else {
1435  nodeIn [ i - 1 ] = false;
1436  }
1437  }
1438 
1439  if ( nodeIn [ 0 ] && nodeIn [ 1 ] && nodeIn [ 2 ] ) { // all nodes inside
1440  for ( int i = 1; i <= 3; i++ ) {
1441  x = this->giveNode(i)->giveCoordinate(1);
1442  y = this->giveNode(i)->giveCoordinate(2);
1443 
1444  v.setCoords(x, y);
1445  referenceFluidPoly.addVertex(v);
1446  rfPoints++;
1447  }
1448 
1449  return;
1450  } else if ( !( nodeIn [ 0 ] || nodeIn [ 1 ] || nodeIn [ 2 ] ) ) { // all nodes outside
1451  for ( int i = 1; i <= 3; i++ ) {
1452  x = this->giveNode(i)->giveCoordinate(1);
1453  y = this->giveNode(i)->giveCoordinate(2);
1454 
1455  v.setCoords(x, y);
1456  secondFluidPoly.addVertex(v);
1457  sfPoints++;
1458  }
1459 
1460  return;
1461  } else {
1462  for ( int i = 1; i <= 3; i++ ) {
1463  next = i < 3 ? i + 1 : 1;
1464  if ( nodeIn [ i - 1 ] ) {
1465  v.setCoords( this->giveNode(i)->giveCoordinate(1),
1466  this->giveNode(i)->giveCoordinate(2) );
1467 
1468  referenceFluidPoly.addVertex(v);
1469  rfPoints++;
1470  } else {
1471  v.setCoords( this->giveNode(i)->giveCoordinate(1),
1472  this->giveNode(i)->giveCoordinate(2) );
1473 
1474  secondFluidPoly.addVertex(v);
1475  sfPoints++;
1476  }
1477 
1478  if ( nodeIn [ next - 1 ] ^ nodeIn [ i - 1 ] ) {
1479  // compute intersection with (i,next) edge
1480  x = this->giveNode(i)->giveCoordinate(1);
1481  y = this->giveNode(i)->giveCoordinate(2);
1482  tx = this->giveNode(next)->giveCoordinate(1) - x;
1483  ty = this->giveNode(next)->giveCoordinate(2) - y;
1484 
1485  double s, sd = nx * tx + ny * ty;
1486  if ( fabs(sd) > 1.e-10 ) {
1487  s = ( -p - ( nx * x + ny * y ) ) / sd;
1488  v.setCoords(x + tx * s, y + ty * s);
1489  referenceFluidPoly.addVertex(v);
1490  secondFluidPoly.addVertex(v);
1491  rfPoints++;
1492  sfPoints++;
1493  } else {
1494  // pathological case - lines are parallel
1495  if ( nodeIn [ i - 1 ] ) {
1496  v.setCoords( this->giveNode(next)->giveCoordinate(1), this->giveNode(next)->giveCoordinate(2) );
1497 
1498  referenceFluidPoly.addVertex(v);
1499  secondFluidPoly.addVertex(v);
1500  rfPoints++;
1501  sfPoints++;
1502  } else {
1503  //v.setCoords(x, y);
1504  //referenceFluidPoly.addVertex(v);
1505  v.setCoords( this->giveNode(next)->giveCoordinate(1), this->giveNode(next)->giveCoordinate(2) );
1506 
1507  referenceFluidPoly.addVertex(v);
1508  secondFluidPoly.addVertex(v);
1509  rfPoints++;
1510  sfPoints++;
1511  }
1512  }
1513  }
1514  } // end loop over elem nodes
1515  }
1516 }
1517 
1518 double
1519 TR1_2D_SUPG2 :: truncateMatVolume(const Polygon &matvolpoly, double &volume)
1520 {
1521  Polygon me, clip;
1522  Graph g;
1523 
1524  this->formMyVolumePoly(me, NULL, false);
1525  g.clip(clip, me, matvolpoly);
1526 #ifdef __OOFEG
1527  EASValsSetColor( gc [ 0 ].getActiveCrackColor() );
1528  //GraphicObj *go = clip.draw(::gc[OOFEG_DEBUG_LAYER],true);
1529  clip.draw(gc [ OOFEG_DEBUG_LAYER ], true);
1530  //EVFastRedraw(myview);
1531 #endif
1532  volume = clip.computeVolume();
1533  return volume / area;
1534 }
1535 
1536 void
1537 TR1_2D_SUPG2 :: formMyVolumePoly(Polygon &me, LEPlic *matInterface, bool updFlag)
1538 {
1539  double x, y;
1540  Vertex v;
1541 
1542  me.clear();
1543 
1544  for ( int i = 1; i <= 3; i++ ) {
1545  if ( updFlag ) {
1546  x = matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() );
1547  y = matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() );
1548  } else {
1549  x = this->giveNode(i)->giveCoordinate(1);
1550  y = this->giveNode(i)->giveCoordinate(2);
1551  }
1552 
1553  v.setCoords(x, y);
1554  me.addVertex(v);
1555  }
1556 }
1557 
1558 
1559 double
1560 TR1_2D_SUPG2 :: computeMyVolume(LEPlic *matInterface, bool updFlag)
1561 {
1562  double x1, x2, x3, y1, y2, y3;
1563  if ( updFlag ) {
1564  x1 = matInterface->giveUpdatedXCoordinate( this->giveNode(1)->giveNumber() );
1565  x2 = matInterface->giveUpdatedXCoordinate( this->giveNode(2)->giveNumber() );
1566  x3 = matInterface->giveUpdatedXCoordinate( this->giveNode(3)->giveNumber() );
1567 
1568  y1 = matInterface->giveUpdatedYCoordinate( this->giveNode(1)->giveNumber() );
1569  y2 = matInterface->giveUpdatedYCoordinate( this->giveNode(2)->giveNumber() );
1570  y3 = matInterface->giveUpdatedYCoordinate( this->giveNode(3)->giveNumber() );
1571  return 0.5 * ( x2 * y3 + x1 * y2 + y1 * x3 - x2 * y1 - x3 * y2 - x1 * y3 );
1572  } else {
1573  return area;
1574  }
1575 }
1576 
1577 void
1578 TR1_2D_SUPG2 :: giveElementCenter(LEPlic *mat_interface, FloatArray &center, bool upd)
1579 {
1580  FloatArray coords;
1581 
1582  center.resize(2);
1583  center.zero();
1584  if ( upd ) {
1585  for ( int i = 1; i <= 3; i++ ) {
1586  mat_interface->giveUpdatedCoordinate( coords, giveNode(i)->giveNumber() );
1587  center.add(coords);
1588  }
1589  } else {
1590  for ( int i = 1; i <= 3; i++ ) {
1591  center.at(1) += this->giveNode(i)->giveCoordinate(1);
1592  center.at(2) += this->giveNode(i)->giveCoordinate(2);
1593  }
1594  }
1595 
1596  center.times(1. / 3.);
1597 }
1598 
1599 int
1601  const FloatArray &coords, IntArray &dofId, ValueModeType mode,
1602  TimeStep *tStep)
1603 {
1604  int indx, es;
1605  double sum;
1606  FloatArray elemvector, lc;
1607  //FloatMatrix n;
1608  IntArray elemdofs;
1609  // determine element dof ids
1610  this->giveElementDofIDMask(elemdofs);
1611  es = elemdofs.giveSize();
1612  // first evaluate element unknown vector
1613  this->computeVectorOf(pf, elemdofs, mode, tStep, elemvector);
1614 
1615  // determine corresponding local coordinates
1616  if ( this->computeLocalCoordinates(lc, coords) ) {
1617  // compute interpolation matrix
1618  // this->computeNmatrixAt(n, &lc);
1619  // compute answer
1620  answer.resize( dofId.giveSize() );
1621  for ( int i = 1; i <= dofId.giveSize(); i++ ) {
1622  if ( ( indx = elemdofs.findFirstIndexOf( dofId.at(i) ) ) ) {
1623  sum = 0.0;
1624  for ( int j = 1; j <= 3; j++ ) {
1625  sum += lc.at(j) * elemvector.at(es * ( j - 1 ) + indx);
1626  }
1627 
1628  answer.at(i) = sum;
1629  } else {
1630  //_error("EIPrimaryFieldI_evaluateFieldVectorAt: unknown dof id encountered");
1631  answer.at(i) = 0.0;
1632  }
1633  }
1634 
1635  return 0; // ok
1636  } else {
1637  OOFEM_ERROR("target point not in receiver volume");
1638  return 1; // fail
1639  }
1640 }
1641 
1642 void
1644 {
1647  //this->updateIntegrationRules ();
1648 }
1649 
1650 void
1652 {
1653  int c [ 2 ];
1654  double x, y;
1655  Vertex v;
1656 
1657  for ( int i = 0; i < 2; i++ ) {
1658  myPoly [ i ].clear();
1659  }
1660 
1661  if ( this->temp_vof <= TRSUPG_ZERO_VOF ) {
1662  for ( int i = 1; i <= 3; i++ ) {
1663  x = this->giveNode(i)->giveCoordinate(1);
1664  y = this->giveNode(i)->giveCoordinate(2);
1665  v.setCoords(x, y);
1666  myPoly [ 1 ].addVertex(v);
1667  c [ 1 ] = 3;
1668  c [ 0 ] = 0;
1669  }
1670  } else if ( this->temp_vof >= ( 1. - TRSUPG_ZERO_VOF ) ) {
1671  for ( int i = 1; i <= 3; i++ ) {
1672  x = this->giveNode(i)->giveCoordinate(1);
1673  y = this->giveNode(i)->giveCoordinate(2);
1674  v.setCoords(x, y);
1675  myPoly [ 0 ].addVertex(v);
1676  c [ 0 ] = 3;
1677  c [ 1 ] = 0;
1678  }
1679  } else {
1680  this->updateVolumePolygons(myPoly [ 0 ], myPoly [ 1 ], c [ 0 ], c [ 1 ], temp_normal, temp_p, false);
1681  }
1682 
1683  integrationRulesArray [ 0 ]->clear();
1684  integrationRulesArray [ 1 ]->clear();
1685 
1686  FloatArray gc, lc;
1687  const Vertex *p;
1688  FEI2dTrLin triaApprox(1, 2);
1689  FEI2dQuadLin quadApprox(1, 2);
1690  FEInterpolation *approx = NULL;
1691  // set up integration points
1692  for ( int i = 0; i < 2; i++ ) {
1693  if ( c [ i ] == 3 ) {
1694  id [ i ] = _Triangle;
1695  approx = & triaApprox;
1696  } else if ( c [ i ] == 4 ) {
1697  id [ i ] = _Square;
1698  approx = & quadApprox;
1699  } else if ( c [ i ] == 0 ) {
1700  continue;
1701  } else {
1702  OOFEM_ERROR("cannot set up integration domain for %d vertex polygon", c [ i ]);
1703  }
1704 
1705 #if 0
1706  if ( i == 0 ) {
1707  a = area * this->temp_vof;
1708  } else {
1709  a = area * ( 1. - this->temp_vof );
1710  }
1711 
1712 #endif
1713 
1714  vcoords [ i ].clear();
1715  vcoords [ i ].reserve(c [ i ]);
1716 
1717  // set up vertex coords
1719  while ( it.giveNext(& p) ) {
1720  vcoords [ i ].push_back( *p->getCoords() );
1721  }
1722 
1723  integrationRulesArray [ i ]->setUpIntegrationPoints(id [ i ], 4, _2dFlow);
1724 
1725  // remap ip coords into area coords of receiver
1726  for ( GaussPoint *gp: *integrationRulesArray [ i ] ) {
1727  approx->local2global( gc, gp->giveNaturalCoordinates(), FEIVertexListGeometryWrapper(vcoords [ i ]) );
1728  triaApprox.global2local( lc, gc, FEIElementGeometryWrapper(this) );
1729  // modify original ip coords to target ones
1730  gp->setSubPatchCoordinates( gp->giveNaturalCoordinates() );
1731  gp->setNaturalCoordinates(lc);
1732  //gp->setWeight (gp->giveWeight()*a/area);
1733  }
1734  }
1735 
1736  // internal test -> compute receiver area
1737  double dV, __area = 0.0;
1738  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
1739  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
1740  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
1741  // compute integral here
1742  __area += dV;
1743  }
1744  }
1745 
1746  double __err = fabs(__area - area) / area;
1747  if ( __err > 1.e-6 ) {
1748  OOFEM_ERROR("volume inconsistency (%5.2f)", __err * 100);
1749 
1750  __area = 0.0;
1751  for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
1752  for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
1753  dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
1754  // compute integral here
1755  __area += dV;
1756  }
1757  }
1758  }
1759 }
1760 
1761 
1762 double
1763 TR1_2D_SUPG2 :: computeVolumeAroundID(GaussPoint *gp, integrationDomain id, const std::vector< FloatArray > &idpoly)
1764 {
1765  double weight = gp->giveWeight();
1766 
1767  if ( id == _Triangle ) {
1768  FEI2dTrLin __interpolation(1, 2);
1769  return weight *fabs( __interpolation.giveTransformationJacobian ( gp->giveSubPatchCoordinates(), FEIVertexListGeometryWrapper(idpoly) ) );
1770  } else {
1771  FEI2dQuadLin __interpolation(1, 2);
1772  double det = fabs( __interpolation.giveTransformationJacobian( gp->giveSubPatchCoordinates(), FEIVertexListGeometryWrapper(idpoly) ) );
1773  return det * weight;
1774  }
1775 }
1776 
1777 
1778 /*
1779  * double
1780  * TR1_2D_SUPG2::computeVolumeAroundID(GaussPoint* gp, integrationDomain id, const Polygon& matvolpoly) {
1781  * }
1782  */
1783 
1784 int
1786 {
1787  if ( type == IST_VOFFraction ) {
1788  answer.resize(1);
1789  answer.at(1) = this->giveTempVolumeFraction();
1790  return 1;
1791  } else {
1792  return TR1_2D_SUPG :: giveIPValue(answer, gp, type, tStep);
1793  }
1794 }
1795 
1796 void
1798  InternalStateType type, TimeStep *tStep)
1799 {
1800  GaussPoint *gp;
1801  if ( integrationRulesArray [ 0 ]->giveNumberOfIntegrationPoints() ) {
1802  gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
1803  } else {
1804  gp = integrationRulesArray [ 1 ]->getIntegrationPoint(0);
1805  }
1806 
1807  this->giveIPValue(answer, gp, type, tStep);
1808 }
1809 
1810 void
1812 {
1813  pap.resize(3);
1814  pap.at(1) = this->giveNode(1)->giveNumber();
1815  pap.at(2) = this->giveNode(2)->giveNumber();
1816  pap.at(3) = this->giveNode(3)->giveNumber();
1817 }
1818 
1819 void
1821 {
1822  answer.resize(1);
1823  if ( ( pap == this->giveNode(1)->giveNumber() ) ||
1824  ( pap == this->giveNode(2)->giveNumber() ) ||
1825  ( pap == this->giveNode(3)->giveNumber() ) ) {
1826  answer.at(1) = pap;
1827  } else {
1828  OOFEM_ERROR("node unknown");
1829  }
1830 }
1831 
1832 int
1834 {
1835  return 1;
1836 }
1837 
1838 
1841 {
1842  return SPRPatchType_2dxy;
1843 }
1844 
1845 
1846 void
1848 // Performs end-of-step operations.
1849 {
1850  SUPGElement :: printOutputAt(file, tStep);
1851 
1852  GaussPoint *gp;
1853  if ( integrationRulesArray [ 0 ]->giveNumberOfIntegrationPoints() ) {
1854  gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
1855  } else {
1856  gp = integrationRulesArray [ 1 ]->getIntegrationPoint(0);
1857  }
1858 
1859  double rho0 = this->_giveMaterial(0)->give('d', gp);
1860  double rho1 = this->_giveMaterial(1)->give('d', gp);
1861  double vof = this->giveVolumeFraction();
1862 
1863  fprintf(file, "VOF %e, density %e\n\n", vof, rho0*vof + rho1*(1-vof));
1864 }
1865 
1866 
1868 //
1869 // saves full element context (saves state variables, that completely describe
1870 // current state)
1871 //
1872 {
1873  contextIOResultType iores;
1874 
1875  if ( ( iores = SUPGElement :: saveContext(stream, mode, obj) ) != CIO_OK ) {
1876  THROW_CIOERR(iores);
1877  }
1878 
1879  if ( ( iores = LEPlicElementInterface :: saveContext(stream, mode, obj) ) != CIO_OK ) {
1880  THROW_CIOERR(iores);
1881  }
1882 
1883  return CIO_OK;
1884 }
1885 
1886 
1887 
1889 //
1890 // restores full element context (saves state variables, that completely describe
1891 // current state)
1892 //
1893 {
1894  contextIOResultType iores;
1895 
1896  if ( ( iores = SUPGElement :: restoreContext(stream, mode, obj) ) != CIO_OK ) {
1897  THROW_CIOERR(iores);
1898  }
1899 
1900  if ( ( iores = LEPlicElementInterface :: restoreContext(stream, mode, obj) ) != CIO_OK ) {
1901  THROW_CIOERR(iores);
1902  }
1903 
1904 
1905  return CIO_OK;
1906 }
1907 
1908 
1909 
1910 
1911 #ifdef __OOFEG
1912 int
1914  int node, TimeStep *tStep)
1915 {
1916  /*
1917  * if (type == IST_VOFFraction) {
1918  * answer.resize(1);
1919  * answer.at(1) = this->giveTempVolumeFraction();
1920  * return 1;
1921  * } else if (type == IST_Density) {
1922  * answer.resize(1);
1923  * answer.at(1) = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveDensity( integrationRulesArray[0]-> getIntegrationPoint(0) );
1924  * return 1;
1925  *
1926  * } else
1927  */return SUPGElement :: giveInternalStateAtNode(answer, type, mode, node, tStep);
1928 }
1929 
1930 void
1932 {
1933  WCRec p [ 3 ];
1934  GraphicObj *go;
1935 
1936  if ( !gc.testElementGraphicActivity(this) ) {
1937  return;
1938  }
1939 
1940  EASValsSetLineWidth(OOFEG_RAW_GEOMETRY_WIDTH);
1941  EASValsSetColor( gc.getElementColor() );
1942  EASValsSetEdgeColor( gc.getElementEdgeColor() );
1943  EASValsSetEdgeFlag(true);
1944  EASValsSetLayer(OOFEG_RAW_GEOMETRY_LAYER);
1945  p [ 0 ].x = ( FPNum ) this->giveNode(1)->giveCoordinate(1);
1946  p [ 0 ].y = ( FPNum ) this->giveNode(1)->giveCoordinate(2);
1947  p [ 0 ].z = 0.;
1948  p [ 1 ].x = ( FPNum ) this->giveNode(2)->giveCoordinate(1);
1949  p [ 1 ].y = ( FPNum ) this->giveNode(2)->giveCoordinate(2);
1950  p [ 1 ].z = 0.;
1951  p [ 2 ].x = ( FPNum ) this->giveNode(3)->giveCoordinate(1);
1952  p [ 2 ].y = ( FPNum ) this->giveNode(3)->giveCoordinate(2);
1953  p [ 2 ].z = 0.;
1954 
1955  go = CreateTriangle3D(p);
1956  EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | EDGE_COLOR_MASK | EDGE_FLAG_MASK | LAYER_MASK, go);
1957  EGAttachObject(go, ( EObjectP ) this);
1958  EMAddGraphicsToModel(ESIModel(), go);
1959 }
1960 
1962 {
1963  int i, indx, result = 0;
1964  WCRec p [ 3 ];
1965  GraphicObj *tr;
1966  FloatArray v1, v2, v3;
1967  double s [ 3 ];
1968 
1969  if ( !gc.testElementGraphicActivity(this) ) {
1970  return;
1971  }
1972 
1973  EASValsSetLayer(OOFEG_VARPLOT_PATTERN_LAYER);
1974 
1975  // if ((gc.giveIntVarMode() == ISM_local) && (gc.giveIntVarType() == IST_VOFFraction)) {
1976  if ( ( gc.giveIntVarType() == IST_VOFFraction ) && ( gc.giveIntVarMode() == ISM_local ) ) {
1977  Polygon matvolpoly;
1978  this->formMaterialVolumePoly(matvolpoly, NULL, temp_normal, temp_p, false);
1979  EASValsSetColor( gc.getStandardSparseProfileColor() );
1980  //GraphicObj *go = matvolpoly.draw(gc,true,OOFEG_VARPLOT_PATTERN_LAYER);
1981  matvolpoly.draw(gc, true, OOFEG_VARPLOT_PATTERN_LAYER);
1982  return;
1983  }
1984 
1985  /*
1986  * if ((gc.giveIntVarMode() == ISM_local) && (gc.giveIntVarType() == IST_VOFFraction)) {
1987  * Polygon matvolpoly;
1988  * FloatArray _n;
1989  * double _p;
1990  * this->doCellDLS (_n, this->giveNumber());
1991  * this->findCellLineConstant (_p, _n, this->giveNumber());
1992  * this->formMaterialVolumePoly(matvolpoly, NULL, _n, _p, false);
1993  * GraphicObj *go = matvolpoly.draw(gc,true,OOFEG_VARPLOT_PATTERN_LAYER);
1994  * return;
1995  * }
1996  */
1997 
1998  if ( gc.giveIntVarMode() == ISM_recovered ) {
1999  result += this->giveInternalStateAtNode(v1, gc.giveIntVarType(), gc.giveIntVarMode(), 1, tStep);
2000  result += this->giveInternalStateAtNode(v2, gc.giveIntVarType(), gc.giveIntVarMode(), 2, tStep);
2001  result += this->giveInternalStateAtNode(v3, gc.giveIntVarType(), gc.giveIntVarMode(), 3, tStep);
2002  } else if ( gc.giveIntVarMode() == ISM_local ) {
2003  GaussPoint *gp;
2004  if ( integrationRulesArray [ 0 ]->giveNumberOfIntegrationPoints() ) {
2005  gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
2006  } else {
2007  gp = integrationRulesArray [ 1 ]->getIntegrationPoint(0);
2008  }
2009 
2010  result += giveIPValue(v1, gp, gc.giveIntVarType(), tStep);
2011  v2 = v1;
2012  v3 = v1;
2013  result *= 3;
2014  }
2015 
2016  if ( result != 3 ) {
2017  return;
2018  }
2019 
2020  indx = gc.giveIntVarIndx();
2021 
2022  s [ 0 ] = v1.at(indx);
2023  s [ 1 ] = v2.at(indx);
2024  s [ 2 ] = v3.at(indx);
2025 
2026  if ( gc.getScalarAlgo() == SA_ISO_SURF ) {
2027  for ( i = 0; i < 3; i++ ) {
2028  p [ i ].x = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(1);
2029  p [ i ].y = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(2);
2030  p [ i ].z = 0.;
2031  }
2032 
2033  //EASValsSetColor(gc.getYieldPlotColor(ratio));
2034  gc.updateFringeTableMinMax(s, 3);
2035  tr = CreateTriangleWD3D(p, s [ 0 ], s [ 1 ], s [ 2 ]);
2036  EGWithMaskChangeAttributes(LAYER_MASK, tr);
2037  EMAddGraphicsToModel(ESIModel(), tr);
2038  } else if ( ( gc.getScalarAlgo() == SA_ZPROFILE ) || ( gc.getScalarAlgo() == SA_COLORZPROFILE ) ) {
2039  double landScale = gc.getLandScale();
2040 
2041  for ( i = 0; i < 3; i++ ) {
2042  p [ i ].x = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(1);
2043  p [ i ].y = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(2);
2044  p [ i ].z = s [ i ] * landScale;
2045  }
2046 
2047  if ( gc.getScalarAlgo() == SA_ZPROFILE ) {
2048  EASValsSetColor( gc.getDeformedElementColor() );
2049  EASValsSetLineWidth(OOFEG_DEFORMED_GEOMETRY_WIDTH);
2050  EASValsSetFillStyle(FILL_SOLID);
2051  tr = CreateTriangle3D(p);
2052  EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | FILL_MASK | LAYER_MASK, tr);
2053  } else {
2054  gc.updateFringeTableMinMax(s, 3);
2055  EASValsSetFillStyle(FILL_SOLID);
2056  tr = CreateTriangleWD3D(p, s [ 0 ], s [ 1 ], s [ 2 ]);
2057  EGWithMaskChangeAttributes(FILL_MASK | LAYER_MASK, tr);
2058  }
2059 
2060  EMAddGraphicsToModel(ESIModel(), tr);
2061  }
2062 }
2063 
2064 
2065 
2066 #endif
2067 } // end namespace oofem
CrossSection * giveCrossSection()
Definition: element.C:495
virtual void giveElementCenter(LEPlic *mat_interface, FloatArray &center, bool updFlag)
Computes the receiver center (in updated Lagrangian configuration).
int testElementGraphicActivity(Element *)
Test if particular element passed fulfills various filtering criteria for its graphics output...
InternalStateType
Type representing the physical meaning of element or constitutive model internal variable.
The element interface required by NodalAvergagingRecoveryModel.
void setField(int item, InputFieldType id)
virtual void computeAccelerationTerm_MB(FloatMatrix &answer, TimeStep *tStep)
Computes acceleration terms (generalized mass matrix with stabilization terms) for momentum balance e...
Definition: tr1_2d_supg.C:147
virtual void computeDiffusionTerm_MB(FloatArray &answer, TimeStep *tStep)
Computes diffusion terms for momentum balance equations(s).
Definition: tr1_2d_supg.C:323
int number
Component number.
Definition: femcmpnn.h:80
integrationDomain
Used by integrator class to supply integration points for proper domain to be integrated (Area...
The element interface required by ZZNodalRecoveryModel.
contextIOResultType saveContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Stores context of receiver into given stream.
Definition: leplic.C:86
void giveUpdatedCoordinate(FloatArray &answer, int num)
Returns updated nodal positions.
Definition: leplic.h:183
virtual void computeAdvectionTerm_MB(FloatArray &answer, TimeStep *tStep)
Computes nonlinear advection terms for momentum balance equations(s).
Definition: tr1_2d_supg.C:205
IntArray * giveBoundaryLoadArray()
Returns array containing load numbers of boundary loads acting on element.
Definition: element.C:381
Element interface for LEPlic class representing Lagrangian-Eulerian (moving) material interface...
Definition: leplic.h:58
Class and object Domain.
Definition: domain.h:115
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the array of interpolation functions (shape functions) at given point.
Definition: fei2dtrlin.C:43
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Returns local vector of unknowns.
Definition: element.C:86
ScalarAlgorithmType getScalarAlgo()
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: tr1_2d_supg2.C:103
virtual void computeDiffusionDerivativeTerm_MB(FloatMatrix &answer, MatResponseMode mode, TimeStep *tStep)
Computes the derivative of diffusion terms for momentum balance equations(s) with respect to nodal ve...
Definition: tr1_2d_supg2.C:511
virtual void computeBCRhsTerm_MC(FloatArray &answer, TimeStep *tStep)
Computes Rhs terms due to boundary conditions.
Definition: tr1_2d_supg2.C:908
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the determinant of the transformation.
Definition: feinterpol.C:43
virtual void computeLinearAdvectionTerm_MC(FloatMatrix &answer, TimeStep *tStep)
Computes the linear advection term for mass conservation equation.
Definition: tr1_2d_supg.C:456
Abstract base class for all fluid materials.
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition: femcmpnn.h:82
Wrapper around cell with vertex coordinates stored in FloatArray**.
Definition: feinterpol.h:115
double computeVolume() const
Definition: geotoolbox.C:72
The element interface required by ZZNodalRecoveryModel.
Abstract class representing field of primary variables (those, which are unknown and are typically as...
Definition: primaryfield.h:104
const FloatArray & giveSubPatchCoordinates()
Returns local sub-patch coordinates of the receiver.
Definition: gausspoint.h:144
Material * _giveMaterial(int indx)
Definition: tr1_2d_supg2.h:182
The purpose of DataStream abstract class is to allow to store/restore context to different streams...
Definition: datastream.h:54
#define _IFT_Tr1SUPG_pvof
Definition: tr1_2d_supg.h:50
virtual void computeLSICStabilizationTerm_MB(FloatMatrix &answer, TimeStep *tStep)
Computes SLIC stabilization term for momentum balance equation(s).
Definition: tr1_2d_supg2.C:646
bcGeomType
Type representing the geometric character of loading.
Definition: bcgeomtype.h:40
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
int max(int i, int j)
Returns bigger value form two given decimals.
Definition: mathfem.h:71
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
virtual Interface * giveInterface(InterfaceType)
Interface requesting service.
virtual double computeLEPLICVolumeFraction(const FloatArray &n, const double p, LEPlic *matInterface, bool updFlag)
Computes corresponding volume fraction to given interface position.
#define OOFEG_RAW_GEOMETRY_LAYER
void setPermanentVolumeFraction(double v)
Definition: leplic.h:106
Base class for fluid problems.
Definition: fluidmodel.h:46
oofem::oofegGraphicContext gc[OOFEG_LAST_LAYER]
double giveUpdatedYCoordinate(int num)
Definition: leplic.h:190
EngngModel * giveEngngModel()
Returns engineering model to which receiver is associated.
Definition: domain.C:433
virtual void updateYourself(TimeStep *tStep)
Updates element state after equilibrium in time step has been reached.
Definition: element.C:779
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in full form.
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
Definition: supgelement.C:80
virtual void giveDofManDofIDMask(int inode, IntArray &answer) const
Returns dofmanager dof mask for node.
Definition: tr1_2d_supg2.C:97
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
Computes boundary condition value - its components values at given time.
Definition: load.C:82
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
MatResponseMode
Describes the character of characteristic material matrix.
virtual void computePressureTerm_MC(FloatMatrix &answer, TimeStep *tStep)
Computes pressure terms for mass conservation equation.
Definition: tr1_2d_supg.C:557
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
Definition: tr1_2d_supg2.C:134
virtual void drawScalar(oofegGraphicContext &gc, TimeStep *tStep)
#define THROW_CIOERR(e)
Definition: contextioerr.h:61
Distributed body load.
Definition: bcgeomtype.h:43
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Stores receiver state to output stream.
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Restores the receiver state previously written in stream.
Definition: element.C:970
int mat[2]
mat[0] reference fluid.
Definition: tr1_2d_supg2.h:80
const FloatArray * getCoords() const
Definition: geotoolbox.h:81
double giveTimeIncrement()
Returns solution step associated time increment.
Definition: timestep.h:150
void updateYourself(TimeStep *tStep)
Definition: leplic.h:122
Class representing a general abstraction for finite element interpolation class.
Definition: feinterpol.h:132
Element interface class.
Definition: primaryfield.h:58
virtual void computeVectorOfPressures(ValueModeType mode, TimeStep *tStep, FloatArray &pressures)
Definition: fmelement.C:55
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in full form.
Definition: tr1_2d_supg.C:1917
virtual double give(int aProperty, GaussPoint *gp)
Returns the value of material property &#39;aProperty&#39;.
Definition: material.C:52
InternalStateType giveIntVarType()
virtual void printOutputAt(FILE *file, TimeStep *tStep)
Prints output of receiver to stream, for given time step.
Definition: element.C:759
Class representing a 2d triangular linear interpolation based on area coordinates.
Definition: fei2dtrlin.h:44
virtual void computeBCRhsTerm_MB(FloatArray &answer, TimeStep *tStep)
Computes Rhs terms due to boundary conditions.
Definition: tr1_2d_supg.C:867
virtual void printOutputAt(FILE *file, TimeStep *tStep)
Prints output of receiver to stream, for given time step.
virtual ~TR1_2D_SUPG2()
Definition: tr1_2d_supg2.C:78
virtual void computeDeviatoricStressVector(FloatArray &stress_dev, double &epsp_vol, GaussPoint *gp, const FloatArray &eps, double pressure, TimeStep *tStep)
Computes the deviatoric stress vector and volumetric strain rate from given deviatoric strain and pre...
Abstract base class representing a boundary load (force, momentum, ...) that acts directly on a bound...
Definition: boundaryload.h:110
virtual void computeDiffusionTerm_MB(FloatArray &answer, TimeStep *tStep)
Computes diffusion terms for momentum balance equations(s).
Definition: tr1_2d_supg2.C:448
virtual void computeVectorOfVelocities(ValueModeType mode, TimeStep *tStep, FloatArray &velocities)
Definition: fmelement.C:48
virtual void computeAccelerationTerm_MC(FloatMatrix &answer, TimeStep *tStep)
Computes acceleration terms for mass conservation equation.
Definition: tr1_2d_supg.C:541
#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 computeLinearAdvectionTerm_MC(FloatMatrix &answer, TimeStep *tStep)
Computes the linear advection term for mass conservation equation.
Definition: tr1_2d_supg2.C:689
virtual void initGeometry()
Definition: tr1_2d_supg.C:1504
int material
Number of associated material.
Definition: element.h:153
virtual void computeGaussPoints()
Initializes the array of integration rules member variable.
Definition: tr1_2d_supg2.C:158
#define OOFEG_RAW_GEOMETRY_WIDTH
virtual double giveWeight()
Returns integration weight of receiver.
Definition: gausspoint.h:181
TR1_2D_SUPG2(int n, Domain *d)
Definition: tr1_2d_supg2.C:72
void clip(Polygon &result, const Polygon &a, const Polygon &b)
Definition: geotoolbox.C:575
void times(double f)
Multiplies receiver by factor f.
Definition: floatmatrix.C:1594
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 void formMyVolumePoly(Polygon &myPoly, LEPlic *mat_interface, bool updFlag)
Assembles receiver volume.
virtual double computeMyVolume(LEPlic *matInterface, bool updFlag)
Computes the volume of receiver.
IntArray * giveBodyLoadArray()
Returns array containing load numbers of loads acting on element.
Definition: element.C:372
virtual void computeAdvectionDerivativeTerm_MB(FloatMatrix &answer, TimeStep *tStep)
Computes the derivative of advection terms for momentum balance equations(s) with respect to nodal ve...
Definition: tr1_2d_supg2.C:367
int giveInternalStateAtNode(FloatArray &answer, InternalStateType type, InternalStateMode mode, int node, TimeStep *tStep)
Returns internal state variable (like stress,strain) at node of element in Reduced form...
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
IntArray bodyLoadArray
Array containing indexes of loads (body loads and boundary loads are kept separately), that apply on receiver.
Definition: element.h:160
void plusProductSymmUpper(const FloatMatrix &a, const FloatMatrix &b, double dV)
Adds to the receiver the product .
Definition: floatmatrix.C:698
Class representing the special graph constructed from two polygons that is used to perform boolean op...
Definition: geotoolbox.h:191
virtual int global2local(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Default implementation using Newton&#39;s method to find the local coordinates.
Definition: fei2dtrlin.C:103
virtual void giveElementDofIDMask(IntArray &answer) const
Returns element dof mask for node.
Definition: element.h:498
TimeStep * givePreviousStep()
Returns pointer to previous solution step.
Definition: timestep.C:114
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
virtual void computeAdvectionDerivativeTerm_MC(FloatMatrix &answer, TimeStep *tStep)
Computes the derivative of advection terms for mass conservation equation with respect to nodal veloc...
Definition: tr1_2d_supg2.C:722
virtual void computeAccelerationTerm_MB(FloatMatrix &answer, TimeStep *tStep)
Computes acceleration terms (generalized mass matrix with stabilization terms) for momentum balance e...
Definition: tr1_2d_supg2.C:190
virtual void formVolumeInterfacePoly(Polygon &matvolpoly, LEPlic *matInterface, const FloatArray &normal, const double p, bool updFlag)
Assembles receiver material polygon based solely on given interface line.
virtual void computeAccelerationTerm_MC(FloatMatrix &answer, TimeStep *tStep)
Computes acceleration terms for mass conservation equation.
Definition: tr1_2d_supg2.C:763
virtual void computeBCRhsTerm_MC(FloatArray &answer, TimeStep *tStep)
Computes Rhs terms due to boundary conditions.
Definition: tr1_2d_supg.C:966
double computeVolumeAroundID(GaussPoint *gp, integrationDomain id, const std::vector< FloatArray > &idpoly)
virtual int setupIntegrationPoints(IntegrationRule &irule, int npoints, Element *element)
Sets up integration rule for the given element.
Definition: crosssection.C:54
InternalStateMode giveIntVarMode()
Abstract base class representing Lagrangian-Eulerian (moving) material interfaces.
Definition: leplic.h:153
virtual void formMaterialVolumePoly(Polygon &matvolpoly, LEPlic *matInterface, const FloatArray &normal, const double p, bool updFlag)
Assembles the true element material polygon (takes receiver vof into accout).
integrationDomain id[2]
Definition: tr1_2d_supg2.h:75
Class representing vector of real numbers.
Definition: floatarray.h:82
virtual void computeDeviatoricStrain(FloatArray &answer, GaussPoint *gp, TimeStep *tStep)
Definition: tr1_2d_supg.C:1489
Class representing 2D polygon.
Definition: geotoolbox.h:91
virtual void computeDeviatoricStress(FloatArray &answer, GaussPoint *gp, TimeStep *)
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
double computeFrobeniusNorm() const
Computes the Frobenius norm of the receiver.
Definition: floatmatrix.C:1613
virtual void computeAdvectionDerivativeTerm_MB(FloatMatrix &answer, TimeStep *tStep)
Computes the derivative of advection terms for momentum balance equations(s) with respect to nodal ve...
Definition: tr1_2d_supg.C:249
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
#define _IFT_Tr1SUPG2_mat0
Definition: tr1_2d_supg.h:52
void setCoords(double x, double y)
Definition: geotoolbox.h:77
virtual void computePressureTerm_MC(FloatMatrix &answer, TimeStep *tStep)
Computes pressure terms for mass conservation equation.
Definition: tr1_2d_supg2.C:769
virtual double truncateMatVolume(const Polygon &matvolpoly, double &volume)
Truncates given material polygon to receiver.
static FEI2dTrLin interp
Definition: tr1_2d_supg.h:74
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the determinant of the transformation.
Definition: fei2dtrlin.C:147
virtual SPRPatchType SPRNodalRecoveryMI_givePatchType()
#define _IFT_Tr1SUPG2_mat1
Definition: tr1_2d_supg.h:53
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
virtual void drawRawGeometry(oofegGraphicContext &gc, TimeStep *tStep)
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Restores the receiver state previously written in stream.
Class representing the general Input Record.
Definition: inputrecord.h:101
double giveUpdatedXCoordinate(int num)
Definition: leplic.h:189
Class Interface.
Definition: interface.h:82
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
virtual bcGeomType giveBCGeoType() const
Returns geometry character of boundary condition.
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Stores receiver state to output stream.
Definition: element.C:885
Polygon myPoly[2]
myPoly[0] occupied by reference fluid.
Definition: tr1_2d_supg2.h:72
#define OOFEG_DEFORMED_GEOMETRY_WIDTH
Class representing the a dynamic Input Record.
void times(double s)
Multiplies receiver with scalar.
Definition: floatarray.C:818
The spatial localizer element interface associated to spatial localizer.
virtual bool computeLocalCoordinates(FloatArray &answer, const FloatArray &gcoords)
Computes the element local coordinates from given global coordinates.
Definition: element.C:1222
long ContextMode
Context mode (mask), defining the type of information written/read to/from context.
Definition: contextmode.h:43
virtual void computePressureTerm_MB(FloatMatrix &answer, TimeStep *tStep)
Computes pressure terms for momentum balance equations(s).
Definition: tr1_2d_supg2.C:591
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
contextIOResultType restoreContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Restores context of receiver from given stream.
Definition: leplic.C:107
Class representing vertex.
Definition: geotoolbox.h:60
std::vector< FloatArray > vcoords[2]
Definition: tr1_2d_supg2.h:73
double vof
Volume fraction of reference fluid in element.
Definition: leplic.h:63
virtual int EIPrimaryFieldI_evaluateFieldVectorAt(FloatArray &answer, PrimaryField &pf, const FloatArray &coords, IntArray &dofId, ValueModeType mode, TimeStep *tStep)
Evaluates the value of field at given point of interest (should be located inside receiver&#39;s volume) ...
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
virtual void computeDiffusionDerivativeTerm_MB(FloatMatrix &answer, MatResponseMode mode, TimeStep *tStep)
Computes the derivative of diffusion terms for momentum balance equations(s) with respect to nodal ve...
Definition: tr1_2d_supg.C:351
InterfaceType
Enumerative type, used to identify interface type.
Definition: interfacetype.h:43
virtual void NodalAveragingRecoveryMI_computeNodalValue(FloatArray &answer, int node, InternalStateType type, TimeStep *tStep)
Computes the element value in given node.
void updateFringeTableMinMax(double *s, int size)
Class representing 2d linear triangular element for solving incompressible fluid with SUPG solver...
Definition: tr1_2d_supg.h:68
virtual void computeLSICStabilizationTerm_MB(FloatMatrix &answer, TimeStep *tStep)
Computes SLIC stabilization term for momentum balance equation(s).
Definition: tr1_2d_supg.C:437
#define OOFEG_DEBUG_LAYER
Load is base abstract class for all loads.
Definition: load.h:61
virtual void updateYourself(TimeStep *tStep)
Updates element state after equilibrium in time step has been reached.
double p
Line constant of line segment representing interface.
Definition: leplic.h:65
virtual void postInitialize()
Performs post initialization steps.
Definition: tr1_2d_supg2.C:149
Class representing a 2d isoparametric linear interpolation based on natural coordinates for quadrilat...
Definition: fei2dquadlin.h:45
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:337
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: supgelement.C:65
GraphicObj * draw(oofegGraphicContext &, bool filled, int layer=OOFEG_DEBUG_LAYER)
Definition: geotoolbox.C:152
std::unique_ptr< IntegrationRule > defaultIRule
default integration rule over element volume.
Definition: tr1_2d_supg2.h:85
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
virtual int SPRNodalRecoveryMI_giveNumberOfIP()
the oofem namespace is to define a context or scope in which all oofem names are defined.
void addVertex(Vertex v)
Definition: geotoolbox.h:96
virtual bcValType giveBCValType() const
Returns receiver load type.
int giveNumber() const
Definition: femcmpnn.h:107
Node * giveNode(int i) const
Returns reference to the i-th node of element.
Definition: element.h:610
virtual void SPRNodalRecoveryMI_giveDofMansDeterminedByPatch(IntArray &answer, int pap)
virtual void computeValueAt(FloatArray &answer, TimeStep *tStep, const FloatArray &coords, ValueModeType mode)
Computes components values of load at given point - global coordinates (coordinates given)...
Definition: boundaryload.C:58
virtual void computeBCRhsTerm_MB(FloatArray &answer, TimeStep *tStep)
Computes Rhs terms due to boundary conditions.
Definition: tr1_2d_supg2.C:809
void computeNVector(FloatArray &answer, GaussPoint *gp)
Definition: tr1_2d_supg2.C:84
Load * giveLoad(int n)
Service for accessing particular domain load.
Definition: domain.C:222
void symmetrized()
Initializes the lower half of the receiver according to the upper half.
Definition: floatmatrix.C:1576
#define OOFEG_VARPLOT_PATTERN_LAYER
#define TRSUPG_ZERO_VOF
Definition: tr1_2d_supg2.C:66
virtual void updateStabilizationCoeffs(TimeStep *tStep)
Updates the stabilization coefficients used for CBS and SUPG algorithms.
Definition: tr1_2d_supg2.C:915
Class representing integration point in finite element program.
Definition: gausspoint.h:93
#define OOFEM_WARNING(...)
Definition: error.h:62
IntArray boundaryLoadArray
Definition: element.h:160
FloatArray normal
Interface segment normal.
Definition: leplic.h:67
int giveInternalStateAtNode(FloatArray &answer, InternalStateType type, InternalStateMode mode, int node, TimeStep *tStep)
Returns internal state variable (like stress,strain) at node of element in Reduced form...
Definition: supgelement.C:366
Class representing solution step.
Definition: timestep.h:80
int numberOfDofMans
Number of dofmanagers.
Definition: element.h:149
InternalStateMode
Determines the mode of internal variable.
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156
virtual int computeNumberOfDofs()
Computes or simply returns total number of element&#39;s local DOFs.
Definition: tr1_2d_supg2.C:91
virtual void local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates global coordinates from given local ones.
virtual double computeCriticalTimeStep(TimeStep *tStep)
Computes the critical time increment.
int findFirstIndexOf(int value) const
Finds index of first occurrence of given value in array.
Definition: intarray.C:331
const FloatArray & giveNaturalCoordinates()
Returns coordinate array of receiver.
Definition: gausspoint.h:138
#define _IFT_Tr1SUPG_vof
Definition: tr1_2d_supg.h:51
virtual void computeAdvectionTerm_MC(FloatArray &answer, TimeStep *tStep)
Computes advection terms for mass conservation equation.
Definition: tr1_2d_supg2.C:695
Class representing Gaussian-quadrature integration rule.
virtual void SPRNodalRecoveryMI_giveSPRAssemblyPoints(IntArray &pap)
virtual void updateVolumePolygons(Polygon &referenceFluidPoly, Polygon &secondFluidPoly, int &rfPoints, int &sfPoints, const FloatArray &normal, const double p, bool updFlag)
virtual void computeAdvectionTerm_MB(FloatArray &answer, TimeStep *tStep)
Computes nonlinear advection terms for momentum balance equations(s).
Definition: tr1_2d_supg2.C:286
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631
virtual void giveDeviatoricStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)=0
Computes the deviatoric stiffness; .

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:32 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011