OOFEM 3.0
Loading...
Searching...
No Matches
tr1_2d_supg2_axi.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 - 2025 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_axi.h"
36#include "fluidmodel.h"
37#include "node.h"
38#include "material.h"
39#include "gausspoint.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"
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 "crosssection.h"
56#include "dynamicinputrecord.h"
57#include "classfactory.h"
58
59#ifdef __OOFEG
60 #include "oofeggraphiccontext.h"
61 #include "connectivitytable.h"
62#endif
63
64namespace oofem {
65#define TRSUPG_ZERO_VOF 1.e-8
66
68
69//#define TR1_2D_SUPG2_AXI_DEBUG
70
71TR1_2D_SUPG2_AXI :: TR1_2D_SUPG2_AXI(int n, Domain *aDomain) :
72 TR1_2D_SUPG(n, aDomain)
73{
75}
76
77
78void
79TR1_2D_SUPG2_AXI :: initializeFrom(InputRecord &ir, int priority)
80{
81 SUPGElement :: initializeFrom(ir, priority);
82
83 ParameterManager &ppm = this->giveDomain()->elementPPM;
84 bool flag;
85
86 PM_UPDATE_PARAMETER_AND_REPORT(vof, ppm, ir, this->number, IPK_TR1_2D_SUPG_pvof, priority, flag) ;
87 if (flag && (vof > 0.0)) {
89 this->temp_vof = vof;
90 } else {
91 this->vof = 0.0;
92 PM_UPDATE_PARAMETER_AND_REPORT(vof, ppm, ir, this->number, IPK_TR1_2D_SUPG_vof, priority, flag) ;
93 if (flag) {
94 this->temp_vof = this->vof;
95 }
96 }
97
98 this->mat [ 0 ] = this->mat [ 1 ] = this->material;
99 PM_UPDATE_PARAMETER_AND_REPORT(mat [ 0 ], ppm, ir, this->number, IPK_TR1_2D_SUPG_mat0, priority, flag) ;
100 if (flag) {
101 this->material = this->mat [ 0 ];
102 }
103 PM_UPDATE_PARAMETER(mat [ 1 ], ppm, ir, this->number, IPK_TR1_2D_SUPG_mat1, priority) ;
104
105 this->initGeometry();
106}
107
108
109void
110TR1_2D_SUPG2_AXI :: giveInputRecord(DynamicInputRecord &input)
111{
112 SUPGElement :: giveInputRecord(input);
113 if ( this->permanentVofFlag ) {
114 input.setField(this->vof, IPK_TR1_2D_SUPG_pvof.getNameCStr());
115 } else {
116 input.setField(this->vof, IPK_TR1_2D_SUPG_vof.getNameCStr());
117 }
118
119 input.setField(this->mat [ 0 ], IPK_TR1_2D_SUPG_mat0.getNameCStr());
120 input.setField(this->mat [ 1 ], IPK_TR1_2D_SUPG_mat1.getNameCStr());
121}
122
123void
124TR1_2D_SUPG2_AXI :: computeGaussPoints()
125// Sets up the array containing the four Gauss points of the receiver.
126{
127 if ( integrationRulesArray.size() == 0 ) {
128 integrationRulesArray.resize( 2 );
129 integrationRulesArray [ 0 ] = std::make_unique<GaussIntegrationRule>(1, this, 1, 3, true);
130 integrationRulesArray [ 1 ] = std::make_unique<GaussIntegrationRule>(2, this, 1, 3, true);
131 }
132}
133
134
135/*
136 * Integration template
137 * // loop over each fluid
138 * for (ifluid = 0; ifluid< 2; ifluid++) {
139 * for (GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
140 * mapped_gp = sub_mapped_IPRule[ifluid]->getIntegrationPoint(ip) ;
141 * this->computeNMtrx (n, mapped_gp);
142 * dV = this->computeVolumeAroundID(gp,id[ifluid], vcoords[ifluid]) ;
143 * // compute integral here
144 * }
145 * }
146 */
147
148
149
150void
151TR1_2D_SUPG2_AXI :: computeAccelerationTerm_MB(FloatMatrix &answer, TimeStep *tStep)
152{
153 answer.resize(6, 6);
154 answer.zero();
155 FloatArray n, un;
156
157 double _val, u, v;
158
159 this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
160
161 // consistent mass
162 // loop over each fluid
163 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
164 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
165 double rho = this->_giveMaterial(ifluid)->give('d', gp);
166 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
167 this->computeNMtrx(n, gp);
168
169 for ( int i = 1; i <= 3; i++ ) {
170 for ( int j = 1; j <= 3; j++ ) {
171 /* consistent mass */
172 _val = n.at(i) * n.at(j) * rho * dV;
173 answer.at(2 * i - 1, 2 * j - 1) += _val;
174 answer.at(2 * i, 2 * j) += _val;
175
176 /* SUPG stabilization term */
177 u = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
178 v = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
179 answer.at(2 * i - 1, 2 * j - 1) += ( u * b [ i - 1 ] + v * c [ j - 1 ] ) * n.at(j) * rho * t_supg * dV;
180 answer.at(2 * i, 2 * j) += ( u * b [ i - 1 ] + v * c [ j - 1 ] ) * n.at(j) * rho * t_supg * dV;
181 }
182 }
183 }
184 }
185}
186
187
188void
189TR1_2D_SUPG2_AXI :: computeAdvectionTerm_MB(FloatArray &answer, TimeStep *tStep)
190{
191 answer.resize(6);
192 answer.zero();
193
194 FloatArray n, u, un;
195 double dudx, dudy, dvdx, dvdy, _u, _v;
196 this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
197 this->computeVectorOfVelocities(VM_Total, tStep, u);
198
199
200 dudx = b [ 0 ] * u.at(1) + b [ 1 ] * u.at(3) + b [ 2 ] * u.at(5);
201 dudy = c [ 0 ] * u.at(1) + c [ 1 ] * u.at(3) + c [ 2 ] * u.at(5);
202 dvdx = b [ 0 ] * u.at(2) + b [ 1 ] * u.at(4) + b [ 2 ] * u.at(6);
203 dvdy = c [ 0 ] * u.at(2) + c [ 1 ] * u.at(4) + c [ 2 ] * u.at(6);
204
205 // standard galerkin term
206 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
207 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
208 double rho = this->_giveMaterial(ifluid)->give('d', gp);
209 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
210 this->computeNMtrx(n, gp);
211
212 _u = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
213 _v = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
214
215 // standard galerkin term
216 for ( int i = 1; i <= 3; i++ ) {
217 answer.at(2 * i - 1) += rho * n.at(i) * ( _u * dudx + _v * dudy ) * dV;
218 answer.at(2 * i) += rho * n.at(i) * ( _u * dvdx + _v * dvdy ) * dV;
219 }
220
221 // supg stabilization term
222 for ( int i = 1; i <= 3; i++ ) {
223 answer.at(2 * i - 1) += ( _u * b [ i - 1 ] + _v * c [ i - 1 ] ) * ( _u * dudx + _v * dudy ) * rho * t_supg * dV;
224 answer.at(2 * i) += ( _u * b [ i - 1 ] + _v * c [ i - 1 ] ) * ( _u * dvdx + _v * dvdy ) * rho * t_supg * dV;
225 }
226 }
227 }
228}
229
230
231void
232TR1_2D_SUPG2_AXI :: computeAdvectionDerivativeTerm_MB(FloatMatrix &answer, TimeStep *tStep)
233{
234 answer.resize(6, 6);
235 answer.zero();
236
237 FloatArray u, un, n;
238 this->computeVectorOfVelocities(VM_Total, tStep, u);
239 this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
240 double _u, _v;
241 int w_dof_addr, u_dof_addr, dij;
242
243 // dN(v)/dv
244 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
245 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
246 double rho = this->_giveMaterial(ifluid)->give('d', gp);
247 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
248 this->computeNMtrx(n, gp);
249
250 _u = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
251 _v = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
252
253 // dN(v)/dv
254 for ( int i = 1; i <= 2; i++ ) { // test function index
255 for ( int k = 1; k <= 3; k++ ) { // nodal val of function w
256 for ( int j = 1; j <= 2; j++ ) { // velocity vector component
257 for ( int m = 1; m <= 3; m++ ) { // nodal components
258 w_dof_addr = ( k - 1 ) * 2 + i;
259 u_dof_addr = ( m - 1 ) * 2 + j;
260 //d1j = (j==1); d2j=(j==2);
261 dij = ( i == j );
262 answer.at(w_dof_addr, u_dof_addr) += dV * rho * n.at(k) * ( dij * _u * b [ m - 1 ] + dij * _v * c [ m - 1 ] );
263 }
264 }
265 }
266 }
267
268 // stabilization term dN_delta/du
269 for ( int i = 1; i <= 2; i++ ) { // test function index
270 for ( int k = 1; k <= 3; k++ ) { // nodal val of function w
271 for ( int j = 1; j <= 2; j++ ) { // velocity vector component
272 for ( int m = 1; m <= 3; m++ ) { // nodal components
273 w_dof_addr = ( k - 1 ) * 2 + i;
274 u_dof_addr = ( m - 1 ) * 2 + j;
275 //d1j = (j==1); d2j=(j==2);
276 dij = ( i == j );
277 answer.at(w_dof_addr, u_dof_addr) += dV * t_supg * rho *
278 ( _u * b [ k - 1 ] + _v * c [ k - 1 ] ) * ( dij * _u * b [ m - 1 ] + dij * _v * c [ m - 1 ] );
279 }
280 }
281 }
282 }
283 }
284 }
285}
286
287
288void
289TR1_2D_SUPG2_AXI :: computeDiffusionTerm_MB(FloatArray &answer, TimeStep *tStep)
290{
291 answer.resize(6);
292 answer.zero();
293 FloatArray u, un, eps, stress;
294 double Re = static_cast< FluidModel * >( domain->giveEngngModel() )->giveReynoldsNumber();
295 //double dudx,dudy,dvdx,dvdy;
296
297 this->computeVectorOfVelocities(VM_Total, tStep, u);
298 FloatArray n;
299 this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
300 FloatMatrix _b(4, 6);
301
302 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
303 FluidDynamicMaterial *mat = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(ifluid) );
304 for ( auto &gp: *integrationRulesArray [ ifluid ] ) {
305 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
306
307 this->computeBMtrx(_b, gp);
308 eps.beProductOf(_b, u);
309 stress = mat->computeDeviatoricStressAxi(eps, gp, tStep);
310 answer.plusProduct(_b, stress, dV / Re);
311
312#if 1
313 // stabilization term k_delta
314 computeNVector(n, gp);
315 double _r = this->computeRadiusAt(gp);
316 double _u = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
317 double _v = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
318
319 for ( int i = 1; i <= 3; i++ ) {
320 answer.at(2 * i - 1) -= t_supg * ( _u * b [ i - 1 ] + _v * c [ i - 1 ] ) * ( stress.at(1) / _r ) * dV / Re;
321 answer.at(2 * i) -= t_supg * ( _u * b [ i - 1 ] + _v * c [ i - 1 ] ) * ( stress.at(4) / _r ) * dV / Re;
322 }
323
324#endif
325 }
326 }
327}
328
329
330void
331TR1_2D_SUPG2_AXI :: computeDiffusionDerivativeTerm_MB(FloatMatrix &answer, MatResponseMode mode, TimeStep *tStep)
332{
333 //double dudx, dudy, dvdx, dvdy;
334 answer.resize(6, 6);
335 answer.zero();
336 FloatMatrix _db, _d, _b;
337 //FloatArray un;
338 double Re = static_cast< FluidModel * >( domain->giveEngngModel() )->giveReynoldsNumber();
339 FloatArray un, u, n, eps, stress;
340
341 this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
342 this->computeVectorOfVelocities(VM_Total, tStep, u);
343
344 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
345 FluidDynamicMaterial *mat = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(ifluid) );
346 for ( auto gp: *integrationRulesArray [ ifluid ] ) {
347 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
348
349 this->computeBMtrx(_b, gp);
350 _d = mat->computeTangentAxi(mode, gp, tStep);
351 _db.beProductOf(_d, _b);
352 answer.plusProductUnsym(_b, _db, dV);
353 //answer.plusProductSymmUpper (_bs,_db,dV*t_supg);
354 // }
355
356#if 1
357 computeNVector(n, gp);
358 eps.beProductOf(_b, u);
359 stress = mat->computeDeviatoricStressAxi(eps, gp, tStep);
360 //_mu = mat->giveCharacteristicValue(MRM_Viscosity, gp, tStep);
361
362 double _r = this->computeRadiusAt(gp);
363 double _u = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
364 double _v = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
365
366 for ( int i = 1; i <= 3; i++ ) {
367 for ( int j = 1; j <= 6; j++ ) {
368 //answer.at(2*i-1,j) -= t_supg*(_u*b[i-1]+_v*c[i-1])*(_d.at(1,1)*_b.at(1,j)/_r - stress.at(1)/_r/_r)*dV;
369 //answer.at(2*i,j) -= t_supg*(_u*b[i-1]+_v*c[i-1])*(_d.at(4,4)*_b.at(4,j)/_r - stress.at(4)/_r/_r)*dV;
370
371 answer.at(2 * i - 1, j) -= t_supg * ( _u * b [ i - 1 ] + _v * c [ i - 1 ] ) * ( _db.at(1, j) / _r ) * dV;
372 answer.at(2 * i, j) -= t_supg * ( _u * b [ i - 1 ] + _v * c [ i - 1 ] ) * ( _db.at(4, j) / _r ) * dV;
373 }
374 }
375
376#endif
377 }
378 }
379
380 answer.times(1. / Re);
381}
382
383
384void
385TR1_2D_SUPG2_AXI :: computePressureTerm_MB(FloatMatrix &answer, TimeStep *tStep)
386{
387 answer.resize(6, 3);
388 answer.zero();
389 FloatArray un, n;
390 double _u, _v;
391
392 this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
393 double dV, _r;
394 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
395 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
396 dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
397 _r = this->computeRadiusAt(gp);
398 computeNVector(n, gp);
399 // G matrix
400 for ( int i = 1; i <= 3; i++ ) {
401 for ( int j = 1; j <= 3; j++ ) {
402 answer.at(2 * i - 1, j) -= b [ i - 1 ] * n.at(j) * dV;
403 answer.at(2 * i, j) -= c [ i - 1 ] * n.at(j) * dV;
404
405 answer.at(2 * i - 1, j) -= n.at(i) * n.at(j) * dV / _r;
406 }
407 }
408
409 // stabilization term (G_\delta mtrx)
410 _u = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
411 _v = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
412 for ( int i = 1; i <= 3; i++ ) {
413 for ( int j = 1; j <= 3; j++ ) {
414 answer.at(2 * i - 1, j) += ( _u * b [ i - 1 ] + _v * c [ i - 1 ] ) * b [ j - 1 ] * dV * t_supg;
415 answer.at(2 * i, j) += ( _u * b [ i - 1 ] + _v * c [ i - 1 ] ) * c [ j - 1 ] * dV * t_supg;
416 }
417 }
418 }
419 }
420}
421
422
423void
424TR1_2D_SUPG2_AXI :: computeLSICStabilizationTerm_MB(FloatMatrix &answer, TimeStep *tStep)
425{
426 answer.resize(6, 6);
427 answer.zero();
428 //double coeff = area*t_lsic*rho;
429 double n[] = {
430 b [ 0 ], c [ 0 ], b [ 1 ], c [ 1 ], b [ 2 ], c [ 2 ]
431 };
432
433 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
434 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
435 double rho = this->_giveMaterial(ifluid)->give('d', gp);
436 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
437
438 for ( int i = 1; i <= 6; i++ ) {
439 for ( int j = 1; j <= 6; j++ ) {
440 answer.at(i, j) += dV * t_lsic * rho * n [ i - 1 ] * n [ j - 1 ];
441 }
442 }
443 }
444 }
445}
446
447
448void
449TR1_2D_SUPG2_AXI :: computeLinearAdvectionTerm_MC(FloatMatrix &answer, TimeStep *tStep)
450{
451 answer.resize(3, 6);
452 answer.zero();
453
454 FloatArray n;
455
456 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
457 for ( auto &gp : *integrationRulesArray [ ifluid ] ) {
458 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
459 double _r = this->computeRadiusAt(gp);
460 computeNVector(n, gp);
461 for ( int i = 1; i <= 3; i++ ) {
462 for ( int j = 1; j <= 3; j++ ) {
463 answer.at(j, 2 * i - 1) += b [ i - 1 ] * n.at(j) * dV;
464 answer.at(j, 2 * i) += c [ i - 1 ] * n.at(j) * dV;
465
466 answer.at(i, 1 + ( j - 1 ) * 2) += n.at(i) * n.at(j) * dV / _r;
467 }
468 }
469 }
470 }
471}
472
473void
474TR1_2D_SUPG2_AXI :: computeAdvectionTerm_MC(FloatArray &answer, TimeStep *tStep)
475{
476 // N_epsilon (due to PSPG stabilization)
477 double dudx, dudy, dvdx, dvdy, _u, _v;
478 FloatArray u, un, n;
479
480 answer.resize(3);
481 answer.zero();
482
483 this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
484 this->computeVectorOfVelocities(VM_Total, tStep, u);
485 dudx = b [ 0 ] * u.at(1) + b [ 1 ] * u.at(3) + b [ 2 ] * u.at(5);
486 dudy = c [ 0 ] * u.at(1) + c [ 1 ] * u.at(3) + c [ 2 ] * u.at(5);
487 dvdx = b [ 0 ] * u.at(2) + b [ 1 ] * u.at(4) + b [ 2 ] * u.at(6);
488 dvdy = c [ 0 ] * u.at(2) + c [ 1 ] * u.at(4) + c [ 2 ] * u.at(6);
489
490 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
491 for ( auto &gp : *integrationRulesArray [ ifluid ] ) {
492 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
493 computeNVector(n, gp);
494
495 _u = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
496 _v = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
497
498 for ( int i = 1; i <= 3; i++ ) {
499 answer.at(i) += t_pspg * dV * ( b [ i - 1 ] * ( _u * dudx + _v * dudy ) + c [ i - 1 ] * ( _u * dvdx + _v * dvdy ) );
500 }
501 }
502 }
503}
504
505
506void
507TR1_2D_SUPG2_AXI :: computeAdvectionDerivativeTerm_MC(FloatMatrix &answer, TimeStep *tStep)
508{
509 answer.resize(3, 6);
510 answer.zero();
511 int w_dof_addr, u_dof_addr, d1j, d2j, km1, mm1;
512 FloatArray u, un, n;
513 double _u, _v;
514
515 this->computeVectorOfVelocities(VM_Total, tStep, u);
516 this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
517
518 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
519 for ( auto &gp : *integrationRulesArray [ ifluid ] ) {
520 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
521 computeNVector(n, gp);
522
523 _u = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
524 _v = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
525
526 for ( int k = 1; k <= 3; k++ ) { // nodal val of function w
527 km1 = k - 1;
528 for ( int j = 1; j <= 2; j++ ) { // velocity vector component
529 for ( int m = 1; m <= 3; m++ ) { // nodal components
530 w_dof_addr = k;
531 u_dof_addr = ( m - 1 ) * 2 + j;
532 mm1 = m - 1;
533 d1j = ( j == 1 );
534 d2j = ( j == 2 );
535 answer.at(w_dof_addr, u_dof_addr) += t_pspg * dV * ( b [ km1 ] * ( _u * d1j * b [ mm1 ] + _v * d1j * c [ mm1 ] ) + c [ km1 ] * ( _u * d2j * b [ mm1 ] + _v * d2j * c [ mm1 ] ) );
536 }
537 }
538 }
539 }
540 }
541}
542
543void TR1_2D_SUPG2_AXI :: computeDiffusionTerm_MC(FloatArray &answer, TimeStep *tStep)
544{
545 answer.resize(3);
546 answer.zero();
547
548#if 1
549 double Re = static_cast< FluidModel * >( domain->giveEngngModel() )->giveReynoldsNumber();
550 FloatArray eps, stress, u;
551 FloatMatrix _b;
552 FluidDynamicMaterial *mat = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveFluidMaterial();
553
554 // stabilization term K_eps
555 this->computeVectorOfVelocities(VM_Total, tStep, u);
556
557 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
558 for ( auto &gp : *integrationRulesArray [ ifluid ] ) {
559 double rho = this->_giveMaterial(ifluid)->give('d', gp);
560 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
561 double _r = this->computeRadiusAt(gp);
562 this->computeBMtrx(_b, gp);
563 eps.beProductOf(_b, u);
564 stress = (1. / Re) * mat->computeDeviatoricStressAxi(eps, gp, tStep);
565 for ( int i = 1; i <= 3; i++ ) {
566 answer.at(i) -= t_pspg * ( b [ i - 1 ] * stress.at(1) + c [ i - 1 ] * stress.at(4) ) * dV / rho / _r;
567 }
568 }
569 }
570
571#endif
572}
573
574void TR1_2D_SUPG2_AXI :: computeDiffusionDerivativeTerm_MC(FloatMatrix &answer, TimeStep *tStep)
575{
576 answer.resize(3, 6);
577 answer.zero();
578
579#if 1
580 double Re = static_cast< FluidModel * >( domain->giveEngngModel() )->giveReynoldsNumber();
581 FloatMatrix _d, _b, _db;
582 //FloatArray eps, stress,u;
583
584 // stabilization term K_eps
585 //this -> computeVectorOfVelocities(VM_Total,tStep, u) ;
586 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
587 FluidDynamicMaterial *mat = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(ifluid) );
588 for ( auto &gp: *integrationRulesArray [ ifluid ] ) {
589 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
590 double rho = mat->give('d', gp);
591 double _r = this->computeRadiusAt(gp);
592 this->computeBMtrx(_b, gp);
593 _d = mat->computeTangentAxi(TangentStiffness, gp, tStep);
594 _db.beProductOf(_d, _b);
595 //eps.beProductOf (_b, u);
596 //mat->computeDeviatoricStressVector (stress,gp,eps,tStep);
597
598 for ( int i = 1; i <= 3; i++ ) {
599 for ( int j = 1; j <= 6; j++ ) {
600 answer.at(i, j) -= t_pspg * ( b [ i - 1 ] * ( _db.at(1, j) / _r ) + c [ i - 1 ] * ( _db.at(4, j) / _r ) ) * dV / rho;
601 }
602 }
603 }
604 }
605
606 answer.times(1. / Re);
607
608#endif
609}
610
611
612
613
614void
615TR1_2D_SUPG2_AXI :: computeAccelerationTerm_MC(FloatMatrix &answer, TimeStep *tStep)
616{
617 answer.resize(3, 6);
618 answer.zero();
619 FloatArray n;
620 // M_\epsilon
621
622 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
623 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
624 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
625 computeNVector(n, gp);
626
627 for ( int i = 1; i <= 3; i++ ) {
628 for ( int j = 1; j <= 3; j++ ) {
629 answer.at(i, 2 * j - 1) += t_pspg * dV * b [ i - 1 ] * n.at(j);
630 answer.at(i, 2 * j) += t_pspg * dV * c [ i - 1 ] * n.at(j);
631 }
632 }
633 }
634 }
635}
636
637void
638TR1_2D_SUPG2_AXI :: computePressureTerm_MC(FloatMatrix &answer, TimeStep *tStep)
639{
640 answer.resize(3, 3);
641 answer.zero();
642
643 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
644 FluidDynamicMaterial *mat = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(ifluid) );
645 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
646 double rho = mat->give('d', gp);
647 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
648
649
650 for ( int i = 1; i <= 3; i++ ) {
651 for ( int j = 1; j <= 3; j++ ) {
652 answer.at(i, j) += t_pspg * dV * ( b [ i - 1 ] * b [ j - 1 ] + c [ i - 1 ] * c [ j - 1 ] ) / rho;
653 }
654 }
655 }
656 }
657
658#ifdef TR1_2D_SUPG2_DEBUG
659 /* test */
660 FloatMatrix test;
661 std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
662 TR1_2D_SUPG :: computePressureTerm_MC(test, tStep);
663 std :: swap(integrationRulesArray [ 0 ], integrationRulesArray [ 1 ]);
664 for ( int i = 1; i <= 3; i++ ) {
665 for ( int j = 1; j <= 3; j++ ) {
666 if ( fabs( ( answer.at(i, j) - test.at(i, j) ) / test.at(i, j) ) >= 1.e-8 ) {
667 OOFEM_ERROR("test failure (err=%e)", ( answer.at(i, j) - test.at(i, j) ) / test.at(i, j));
668 }
669 }
670 }
671
672#endif
673}
674
676void
677TR1_2D_SUPG2_AXI :: computeBCRhsTerm_MB(FloatArray &answer, TimeStep *tStep)
678{
679 answer.resize(6);
680 answer.zero();
681
682 int nLoads;
683 FloatArray un, nV, gVector;
684 double u, v;
685
686 // add body load (gravity) termms
687 this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), un);
688
689 nLoads = this->giveBodyLoadArray()->giveSize();
690 for ( int i = 1; i <= nLoads; i++ ) {
691 auto load = domain->giveLoad( bodyLoadArray.at(i) );
692 bcGeomType ltype = load->giveBCGeoType();
693 if ( ltype == BodyLoadBGT && load->giveBCValType() == ForceLoadBVT ) {
694 load->computeComponentArrayAt(gVector, tStep, VM_Total);
695 if ( gVector.giveSize() ) {
696 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
697 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
698 double rho = this->_giveMaterial(ifluid)->give('d', gp);
699 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
700 double coeff = rho * dV;
701 computeNVector(nV, gp);
702 u = nV.at(1) * un.at(1) + nV.at(2) * un.at(3) + nV.at(3) * un.at(5);
703 v = nV.at(1) * un.at(2) + nV.at(2) * un.at(4) + nV.at(3) * un.at(6);
704
705 answer.at(1) += coeff * ( gVector.at(1) * ( nV.at(1) + t_supg * ( b [ 0 ] * u + c [ 0 ] * v ) ) );
706 answer.at(2) += coeff * ( gVector.at(2) * ( nV.at(1) + t_supg * ( b [ 0 ] * u + c [ 0 ] * v ) ) );
707 answer.at(3) += coeff * ( gVector.at(1) * ( nV.at(2) + t_supg * ( b [ 1 ] * u + c [ 1 ] * v ) ) );
708 answer.at(4) += coeff * ( gVector.at(2) * ( nV.at(2) + t_supg * ( b [ 1 ] * u + c [ 1 ] * v ) ) );
709 answer.at(5) += coeff * ( gVector.at(1) * ( nV.at(3) + t_supg * ( b [ 2 ] * u + c [ 2 ] * v ) ) );
710 answer.at(6) += coeff * ( gVector.at(2) * ( nV.at(3) + t_supg * ( b [ 2 ] * u + c [ 2 ] * v ) ) );
711 }
712 }
713 }
714 }
715 }
716
717 // loop over sides
718 int n1, n2, code, sid;
719 double tx, ty, l, side_r;
720 //IntArray nodecounter (3);
721 for ( int j = 1; j <= boundarySides.giveSize(); j++ ) {
722 code = boundaryCodes.at(j);
723 sid = boundarySides.at(j);
724 if ( ( code & FMElement_PrescribedTractionBC ) ) {
725 FloatArray t, coords(1);
726 int n, id;
727 // integrate tractions
728 n1 = sid;
729 n2 = ( n1 == 3 ? 1 : n1 + 1 );
730
731 tx = giveNode(n2)->giveCoordinate(1) - giveNode(n1)->giveCoordinate(1);
732 ty = giveNode(n2)->giveCoordinate(2) - giveNode(n1)->giveCoordinate(2);
733 l = sqrt(tx * tx + ty * ty);
734 // radius at side center
735 side_r = 0.5 * ( giveNode(n2)->giveCoordinate(1) + giveNode(n1)->giveCoordinate(1) );
736
737 // if no traction bc applied but side marked as with traction load
738 // then zero traction is assumed !!!
739
740 // loop over boundary load array
741 int numLoads = this->giveBoundaryLoadArray()->giveSize() / 2;
742 for ( int i = 1; i <= numLoads; i++ ) {
743 n = boundaryLoadArray.at(1 + ( i - 1 ) * 2);
744 id = boundaryLoadArray.at(i * 2);
745 if ( id != sid ) {
746 continue;
747 }
748
749 auto bLoad = dynamic_cast< BoundaryLoad * >( domain->giveLoad(n) );
750 if ( bLoad ) {
751 bLoad->computeValueAt(t, tStep, coords, VM_Total);
752
753 // here it is assumed constant traction, one point integration only
754 // n1 (u,v)
755 answer.at( ( n1 - 1 ) * 2 + 1 ) += t.at(1) * side_r * l / 2.;
756 answer.at(n1 * 2) += t.at(2) * side_r * l / 2.;
757 // n2 (u,v)
758 answer.at( ( n2 - 1 ) * 2 + 1 ) += t.at(1) * side_r * l / 2.;
759 answer.at(n2 * 2) += t.at(2) * side_r * l / 2.;
760
761 //answer.at(n1)+= (t.at(1)*nx + t.at(2)*ny) * side_r * l/2.;
762 //answer.at(n2)+= (t.at(1)*nx + t.at(2)*ny) * side_r * l/2.;
763 }
764 }
765 }
766 }
767}
768
769void
770TR1_2D_SUPG2_AXI :: computeBCRhsTerm_MC(FloatArray &answer, TimeStep *tStep)
771{
772 int nLoads;
773 FloatArray gVector;
774
775 answer.resize(3);
776 answer.zero();
777 nLoads = this->giveBodyLoadArray()->giveSize();
778 for ( int i = 1; i <= nLoads; i++ ) {
779 Load *load = domain->giveLoad( bodyLoadArray.at(i) );
780 bcGeomType ltype = load->giveBCGeoType();
781 if ( ( ltype == BodyLoadBGT ) && ( load->giveBCValType() == ForceLoadBVT ) ) {
782 load->computeComponentArrayAt(gVector, tStep, VM_Total);
783 if ( gVector.giveSize() ) {
784 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
785 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
786 double dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
787 double coeff = t_pspg * dV;
788
789 answer.at(1) += coeff * ( b [ 0 ] * gVector.at(1) + c [ 0 ] * gVector.at(2) );
790 answer.at(2) += coeff * ( b [ 1 ] * gVector.at(1) + c [ 1 ] * gVector.at(2) );
791 answer.at(3) += coeff * ( b [ 2 ] * gVector.at(1) + c [ 2 ] * gVector.at(2) );
792 }
793 }
794 }
795 }
796 }
797}
798
799
800
801void
802TR1_2D_SUPG2_AXI :: updateStabilizationCoeffs(TimeStep *tStep)
803{
804 //TR1_2D_SUPG :: updateStabilizationCoeffs (tStep);
805#if 0
806 int i, j, k, l, w_dof_addr, u_dof_addr, ip, ifluid;
807 double __g_norm, __gamma_norm, __gammav_norm, __beta_norm, __betav_norm, __c_norm, __e_norm, __k_norm, __Re;
808 double __t_p1, __t_p2, __t_p3, __t_pv1, __t_pv2, __t_pv3;
809 double nu, nu0, nu1, usum, vsum, rho, dV, u1, u2;
810 FloatArray u, un, a;
811
812 // compute averaged viscosity based on rule of mixture
813 GaussPoint *gp;
814 if ( integrationRulesArray [ 0 ]->giveNumberOfIntegrationPoints() ) {
815 gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
816 } else {
817 gp = integrationRulesArray [ 1 ]->getIntegrationPoint(0);
818 }
819
820 nu0 = this->_giveMaterial(0)->giveCharacteristicValue( MRM_Viscosity, gp, tStep->givePreviousStep() );
821 nu1 = this->_giveMaterial(1)->giveCharacteristicValue( MRM_Viscosity, gp, tStep->givePreviousStep() );
822 nu = vof * nu0 + ( 1. - vof ) * nu1;
823
824 //this -> computeVectorOfVelocities(VM_Total,tStep->givePreviousStep(),un) ;
825 this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), u);
826 this->computeVectorOfVelocities(VM_Acceleration, tStep, a);
827 un = u;
828 usum = un.at(1) + un.at(3) + un.at(5);
829 vsum = un.at(2) + un.at(4) + un.at(6);
830
831 FloatMatrix __tmp;
832 FloatArray __tmpvec, n;
833 // assemble g matrix
834 __tmp.resize(6, 3);
835 double ar3 = area / 3.0;
836
837 __tmp.at(1, 1) = __tmp.at(1, 2) = __tmp.at(1, 3) = b [ 0 ] * ar3;
838 __tmp.at(3, 1) = __tmp.at(3, 2) = __tmp.at(3, 3) = b [ 1 ] * ar3;
839 __tmp.at(5, 1) = __tmp.at(5, 2) = __tmp.at(5, 3) = b [ 2 ] * ar3;
840
841 __tmp.at(2, 1) = __tmp.at(2, 2) = __tmp.at(2, 3) = c [ 0 ] * ar3;
842 __tmp.at(4, 1) = __tmp.at(4, 2) = __tmp.at(4, 3) = c [ 1 ] * ar3;
843 __tmp.at(6, 1) = __tmp.at(6, 2) = __tmp.at(6, 3) = c [ 2 ] * ar3;
844
845 __g_norm = __tmp.computeFrobeniusNorm();
846
847 // assemble \gamma matrix (advectionTerm of mass conservation eq)
848 __tmp.resize(3, 6);
849 for ( k = 1; k <= 3; k++ ) {
850 for ( l = 1; l <= 3; l++ ) {
851 __tmp.at(k, l * 2 - 1) = ar3 * b [ k - 1 ] * ( usum * b [ l - 1 ] + vsum * c [ l - 1 ] );
852 __tmp.at(k, l * 2) = ar3 * c [ k - 1 ] * ( usum * b [ l - 1 ] + vsum * c [ l - 1 ] );
853 }
854 }
855
856 __gamma_norm = __tmp.computeFrobeniusNorm();
857 __tmpvec.beProductOf(__tmp, u);
858 __gammav_norm = __tmpvec.computeNorm();
859 // compute beta mtrx (acceleration term of mass conservation eq)
860 __tmp.resize(3, 6);
861 __tmp.zero();
862 __tmp.at(1, 1) = __tmp.at(1, 3) = __tmp.at(1, 5) = ar3 * b [ 0 ];
863 __tmp.at(1, 2) = __tmp.at(1, 4) = __tmp.at(1, 6) = ar3 * c [ 0 ];
864 __tmp.at(2, 1) = __tmp.at(2, 3) = __tmp.at(2, 5) = ar3 * b [ 1 ];
865 __tmp.at(2, 2) = __tmp.at(2, 4) = __tmp.at(2, 6) = ar3 * c [ 1 ];
866 __tmp.at(3, 1) = __tmp.at(3, 3) = __tmp.at(3, 5) = ar3 * b [ 2 ];
867 __tmp.at(3, 2) = __tmp.at(3, 4) = __tmp.at(3, 6) = ar3 * c [ 2 ];
868 __beta_norm = __tmp.computeFrobeniusNorm();
869 __tmpvec.beProductOf(__tmp, a);
870 __betav_norm = __tmpvec.computeNorm();
871 // compute c mtrx (advection term of momentum balance)
872 // standard galerkin term
873 __tmp.resize(6, 6);
874 __tmp.zero();
875 for ( ifluid = 0; ifluid < 2; ifluid++ ) {
876 for ( GaussPoint *gp: integrationRulesArray [ ifluid ] ) {
877 rho = this->_giveMaterial(ifluid)->give('d', gp);
878 this->computeNMtrx(n, gp);
879 dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
880
881 u1 = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
882 u2 = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
883 for ( i = 1; i <= 2; i++ ) {
884 for ( k = 1; k <= 3; k++ ) {
885 for ( l = 1; l <= 3; l++ ) {
886 w_dof_addr = ( k - 1 ) * 2 + i;
887 u_dof_addr = ( l - 1 ) * 2 + i;
888 __tmp.at(w_dof_addr, u_dof_addr) += rho * dV * n.at(k) * ( u1 * b [ l - 1 ] + u2 * c [ l - 1 ] );
889 }
890 }
891 }
892 }
893 }
894
895 __c_norm = __tmp.computeFrobeniusNorm();
896 // compute e mtrx (advection term of momentum balance)
897 __tmp.resize(6, 6);
898 __tmp.zero();
899 double __n[] = {
900 b [ 0 ], c [ 0 ], b [ 1 ], c [ 1 ], b [ 2 ], c [ 2 ]
901 };
902 for ( ifluid = 0; ifluid < 2; ifluid++ ) {
903 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
904 rho = this->_giveMaterial(ifluid)->give('d', gp);
905 dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
906
907 for ( i = 1; i <= 6; i++ ) {
908 for ( j = 1; j <= 6; j++ ) {
909 __tmp.at(i, j) += dV * rho * __n [ i - 1 ] * __n [ j - 1 ];
910 }
911 }
912 }
913 }
914
915 __e_norm = __tmp.computeFrobeniusNorm();
916 // compute element level Reynolds number
917 // compute k norm first
918 __tmp.resize(6, 6);
919 __tmp.zero();
920 for ( ifluid = 0; ifluid < 2; ifluid++ ) {
921 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
922 rho = this->_giveMaterial(ifluid)->give('d', gp);
923 this->computeNMtrx(n, gp);
924 dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
925
926 u1 = n.at(1) * un.at(1) + n.at(2) * un.at(3) + n.at(3) * un.at(5);
927 u2 = n.at(1) * un.at(2) + n.at(2) * un.at(4) + n.at(3) * un.at(6);
928 for ( k = 1; k <= 3; k++ ) {
929 for ( l = 1; l <= 3; l++ ) {
930 __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 ] );
931 __tmp.at(k * 2, l * 2) += rho * dV * ( u1 * b [ k - 1 ] + u2 * c [ k - 1 ] ) * ( u1 * b [ l - 1 ] + u2 * c [ l - 1 ] );
932 }
933 }
934 }
935 }
936
937 __k_norm = __tmp.computeFrobeniusNorm();
938 double u_1, u_2, vnorm = 0.;
939 int im1;
940 for ( i = 1; i <= 3; i++ ) {
941 im1 = i - 1;
942 u_1 = u.at( ( im1 ) * 2 + 1 );
943 u_2 = u.at( ( im1 ) * 2 + 2 );
944 vnorm = max( vnorm, sqrt(u_1 * u_1 + u_2 * u_2) );
945 }
946
947 if ( vnorm == 0.0 ) {
948 //t_sugn1 = inf;
949 double t_sugn2 = tStep->giveTimeIncrement() / 2.0;
950 //t_sugn3 = inf;
951 this->t_supg = 1. / sqrt( 1. / ( t_sugn2 * t_sugn2 ) );
952 this->t_pspg = this->t_supg;
953 this->t_lsic = 0.0;
954 } else {
955 __Re = vnorm * vnorm * __c_norm / __k_norm / nu;
956
957 __t_p1 = __g_norm / __gamma_norm;
958 __t_p2 = tStep->giveTimeIncrement() * __g_norm / 2.0 / __beta_norm;
959 __t_p3 = __t_p1 * __Re;
960 this->t_pspg = 1. / sqrt( 1. / ( __t_p1 * __t_p1 ) + 1. / ( __t_p2 * __t_p2 ) + 1. / ( __t_p3 * __t_p3 ) );
961
962 __t_pv1 = __t_p1;
963 __t_pv2 = __t_pv1 * __gammav_norm / __betav_norm;
964 __t_pv3 = __t_pv1 * __Re;
965 this->t_supg = 1. / sqrt( 1. / ( __t_pv1 * __t_pv1 ) + 1. / ( __t_pv2 * __t_pv2 ) + 1. / ( __t_pv3 * __t_pv3 ) );
966
967 this->t_lsic = __c_norm / __e_norm;
968 }
969
970#else
971 /* UGN-Based Stabilization */
972 double h_ugn, sum = 0.0, vnorm, t_sugn1, t_sugn2, t_sugn3, u_1, u_2, z, Re_ugn;
973 double dscale, uscale, lscale, tscale, dt;
974 //bool zeroFlag = false;
975 int im1;
976 FloatArray u;
977
978 uscale = domain->giveEngngModel()->giveVariableScale(VST_Velocity);
979 lscale = domain->giveEngngModel()->giveVariableScale(VST_Length);
980 tscale = domain->giveEngngModel()->giveVariableScale(VST_Time);
981 dscale = domain->giveEngngModel()->giveVariableScale(VST_Density);
982
983 this->computeVectorOfVelocities(VM_Total, tStep->givePreviousStep(), u);
984 u.times(uscale);
985 double nu, nu0, nu1;
986
987 // compute averaged viscosity based on rule of mixture
988 GaussPoint *gp;
989 if ( integrationRulesArray [ 0 ]->giveNumberOfIntegrationPoints() ) {
990 gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
991 } else {
992 gp = integrationRulesArray [ 1 ]->getIntegrationPoint(0);
993 }
994
995 nu0 = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(0) )->giveEffectiveViscosity( gp, tStep->givePreviousStep() );
996 nu1 = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(1) )->giveEffectiveViscosity( gp, tStep->givePreviousStep() );
997 nu = vof * nu0 + ( 1. - vof ) * nu1;
998 nu *= domain->giveEngngModel()->giveVariableScale(VST_Viscosity);
999
1000 dt = tStep->giveTimeIncrement() * tscale;
1001
1002 for ( int i = 1; i <= 3; i++ ) {
1003 im1 = i - 1;
1004 sum += fabs(u.at( ( im1 ) * 2 + 1 ) * b [ im1 ] / lscale + u.at(im1 * 2 + 2) * c [ im1 ] / lscale);
1005 }
1006
1007 /*
1008 * u_1=(u.at(1)+u.at(3)+u.at(5))/3.0;
1009 * u_2=(u.at(2)+u.at(4)+u.at(6))/3.0;
1010 * vnorm=sqrt(u_1*u_1+u_2*u_2);
1011 */
1012 vnorm = 0.;
1013 for ( int i = 1; i <= 3; i++ ) {
1014 im1 = i - 1;
1015 u_1 = u.at( ( im1 ) * 2 + 1 );
1016 u_2 = u.at( ( im1 ) * 2 + 2 );
1017 vnorm = max( vnorm, sqrt(u_1 * u_1 + u_2 * u_2) );
1018 }
1019
1020 if ( ( vnorm == 0.0 ) || ( sum < vnorm * 1e-10 ) ) {
1021 //t_sugn1 = inf;
1022 t_sugn2 = dt / 2.0;
1023 //t_sugn3 = inf;
1024 this->t_supg = 1. / sqrt( 1. / ( t_sugn2 * t_sugn2 ) );
1025 this->t_pspg = this->t_supg;
1026 this->t_lsic = 0.0;
1027 } else {
1028 h_ugn = 2.0 * vnorm / sum;
1029 t_sugn1 = 1. / sum;
1030 t_sugn2 = dt / 2.0;
1031 t_sugn3 = h_ugn * h_ugn / 4.0 / nu;
1032
1033 this->t_supg = 1. / sqrt( 1. / ( t_sugn1 * t_sugn1 ) + 1. / ( t_sugn2 * t_sugn2 ) + 1. / ( t_sugn3 * t_sugn3 ) );
1034 this->t_pspg = this->t_supg;
1035
1036 Re_ugn = vnorm * h_ugn / ( 2. * nu );
1037 z = ( Re_ugn <= 3. ) ? Re_ugn / 3. : 1.0;
1038 this->t_lsic = h_ugn * vnorm * z / 2.0;
1039 }
1040
1041 // if (this->number == 1) {
1042 // printf ("t_supg %e t_pspg %e t_lsic %e\n", t_supg, t_pspg, t_lsic);
1043 // }
1044
1045
1046 this->t_supg *= uscale / lscale;
1047 this->t_pspg *= 1. / ( lscale * dscale );
1048 this->t_lsic *= ( dscale * uscale ) / ( lscale * lscale );
1049
1050 this->t_lsic = 0.0;
1051
1052#endif
1053
1054 //this->t_lsic=0.0;
1055 //this->t_pspg=0.0;
1056}
1057
1058
1059
1060double
1061TR1_2D_SUPG2_AXI :: computeCriticalTimeStep(TimeStep *tStep)
1062{
1063 return 1.e3;
1064}
1065
1066
1067void
1068TR1_2D_SUPG2_AXI :: computeDeviatoricStress(FloatArray &answer, const FloatArray &eps, GaussPoint *gp, TimeStep *tStep)
1069{
1070 /* one computes here average deviatoric stress, based on rule of mixture (this is used only for postprocessing) */
1071 auto s0 = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(0) )->computeDeviatoricStressAxi(eps, gp, tStep);
1072 auto s1 = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(1) )->computeDeviatoricStressAxi(eps, gp, tStep);
1073
1074 answer = temp_vof * s0 + ( 1. - temp_vof ) * s1;
1075}
1076
1077
1078void
1079TR1_2D_SUPG2_AXI :: computeTangent(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
1080{
1081 auto t0 = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(0) )->computeTangentAxi(mode, gp, tStep);
1082 auto t1 = static_cast< FluidDynamicMaterial * >( this->_giveMaterial(1) )->computeTangentAxi(mode, gp, tStep);
1083
1084 answer = temp_vof * t0 + ( 1. - temp_vof ) * t1;
1085}
1086
1087
1088/*
1089 * double
1090 * TR1_2D_SUPG2 :: computeCriticalTimeStep (TimeStep* tStep)
1091 * {
1092 * FloatArray u;
1093 * double dt1, dt2, dt;
1094 * double Re = static_cast<FluidModel*>(domain->giveEngngModel())->giveReynoldsNumber();
1095 *
1096 * this -> computeVectorOfVelocities(VM_Total,tStep, u) ;
1097 *
1098 * double vn1 = sqrt(u.at(1)*u.at(1)+u.at(2)*u.at(2));
1099 * double vn2 = sqrt(u.at(3)*u.at(3)+u.at(4)*u.at(4));
1100 * double vn3 = sqrt(u.at(5)*u.at(5)+u.at(6)*u.at(6));
1101 * double veln = max (vn1, max(vn2,vn3));
1102 *
1103 * double l1 = 1.0/(sqrt(b[0]*b[0]+c[0]*c[0]));
1104 * double l2 = 1.0/(sqrt(b[1]*b[1]+c[1]*c[1]));
1105 * double l3 = 1.0/(sqrt(b[2]*b[2]+c[2]*c[2]));
1106 *
1107 * double ln = min (l1, min (l2,l3));
1108 *
1109 * // viscous limit
1110 * dt2 = 0.5*ln*ln*Re;
1111 * if (veln != 0.0) {
1112 * dt1 = ln/veln;
1113 * dt = dt1*dt2/(dt1+dt2);
1114 * } else {
1115 * dt = dt2;
1116 * }
1117 * return dt;
1118 * }
1119 */
1120
1121
1122double
1123TR1_2D_SUPG2_AXI :: computeLEPLICVolumeFraction(const FloatArray &n, const double p, LEPlic *matInterface, bool updFlag)
1124{
1125 Polygon pg;
1126 double answer, volume = computeMyVolume(matInterface, updFlag);
1127 this->formVolumeInterfacePoly(pg, matInterface, n, p, updFlag);
1128 answer = fabs(pg.computeVolume() / volume);
1129 if ( answer > 1.000000001 ) {
1130 OOFEM_WARNING("VOF fraction out of bounds, vof = %e\n", answer);
1131 return 1.0;
1132 } else {
1133 return answer;
1134 }
1135}
1136
1137void
1138TR1_2D_SUPG2_AXI :: formMaterialVolumePoly(Polygon &matvolpoly, LEPlic *matInterface,
1139 const FloatArray &normal, const double p, bool updFlag)
1140{
1141 double x, y;
1142 Vertex v;
1143
1144 matvolpoly.clear();
1145
1146 if ( this->vof <= TRSUPG_ZERO_VOF ) {
1147 return;
1148 } else if ( this->vof >= ( 1 - TRSUPG_ZERO_VOF ) ) {
1149 for ( int i = 1; i <= 3; i++ ) {
1150 if ( updFlag ) {
1151 x = matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() );
1152 y = matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() );
1153 } else {
1154 x = this->giveNode(i)->giveCoordinate(1);
1155 y = this->giveNode(i)->giveCoordinate(2);
1156 }
1157
1158 v.setCoords(x, y);
1159 matvolpoly.addVertex(v);
1160 }
1161
1162 return;
1163 }
1164
1165 this->formVolumeInterfacePoly(matvolpoly, matInterface, normal, p, updFlag);
1166}
1167
1168
1169void
1170TR1_2D_SUPG2_AXI :: formVolumeInterfacePoly(Polygon &matvolpoly, LEPlic *matInterface,
1171 const FloatArray &normal, const double p, bool updFlag)
1172{
1173 int next;
1174 bool nodeIn [ 3 ];
1175 double nx = normal.at(1), ny = normal.at(2), x, y;
1176 double tx, ty;
1177 Vertex v;
1178
1179 matvolpoly.clear();
1180
1181 for ( int i = 1; i <= 3; i++ ) {
1182 if ( updFlag ) {
1183 x = matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() );
1184 y = matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() );
1185 } else {
1186 x = this->giveNode(i)->giveCoordinate(1);
1187 y = this->giveNode(i)->giveCoordinate(2);
1188 }
1189
1190 if ( ( nx * x + ny * y + p ) >= 0. ) {
1191 nodeIn [ i - 1 ] = true;
1192 } else {
1193 nodeIn [ i - 1 ] = false;
1194 }
1195 }
1196
1197 if ( nodeIn [ 0 ] && nodeIn [ 1 ] && nodeIn [ 2 ] ) { // all nodes inside
1198 for ( int i = 1; i <= 3; i++ ) {
1199 if ( updFlag ) {
1200 x = matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() );
1201 y = matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() );
1202 } else {
1203 x = this->giveNode(i)->giveCoordinate(1);
1204 y = this->giveNode(i)->giveCoordinate(2);
1205 }
1206
1207 v.setCoords(x, y);
1208 matvolpoly.addVertex(v);
1209 }
1210
1211 return;
1212 } else if ( !( nodeIn [ 0 ] || nodeIn [ 1 ] || nodeIn [ 2 ] ) ) { // all nodes outside
1213 return;
1214 } else {
1215 for ( int i = 1; i <= 3; i++ ) {
1216 next = i < 3 ? i + 1 : 1;
1217 if ( nodeIn [ i - 1 ] ) {
1218 if ( updFlag ) {
1219 v.setCoords( matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() ),
1220 matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() ) );
1221 } else {
1222 v.setCoords( this->giveNode(i)->giveCoordinate(1),
1223 this->giveNode(i)->giveCoordinate(2) );
1224 }
1225
1226 matvolpoly.addVertex(v);
1227 }
1228
1229 if ( nodeIn [ next - 1 ] ^ nodeIn [ i - 1 ] ) {
1230 // compute intersection with (i,next) edge
1231 if ( updFlag ) {
1232 x = matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() );
1233 y = matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() );
1234 tx = matInterface->giveUpdatedXCoordinate( this->giveNode(next)->giveNumber() ) - x;
1235 ty = matInterface->giveUpdatedYCoordinate( this->giveNode(next)->giveNumber() ) - y;
1236 } else {
1237 x = this->giveNode(i)->giveCoordinate(1);
1238 y = this->giveNode(i)->giveCoordinate(2);
1239 tx = this->giveNode(next)->giveCoordinate(1) - x;
1240 ty = this->giveNode(next)->giveCoordinate(2) - y;
1241 }
1242
1243 double s, sd = nx * tx + ny * ty;
1244 if ( fabs(sd) > 1.e-10 ) {
1245 s = ( -p - ( nx * x + ny * y ) ) / sd;
1246 v.setCoords(x + tx * s, y + ty * s);
1247 matvolpoly.addVertex(v);
1248 } else {
1249 // pathological case - lines are parallel
1250 if ( nodeIn [ i - 1 ] ) {
1251 if ( updFlag ) {
1252 v.setCoords( matInterface->giveUpdatedXCoordinate( this->giveNode(next)->giveNumber() ),
1253 matInterface->giveUpdatedYCoordinate( this->giveNode(next)->giveNumber() ) );
1254 } else {
1255 v.setCoords( this->giveNode(next)->giveCoordinate(1), this->giveNode(next)->giveCoordinate(2) );
1256 }
1257
1258 matvolpoly.addVertex(v);
1259 } else {
1260 v.setCoords(x, y);
1261 matvolpoly.addVertex(v);
1262 if ( updFlag ) {
1263 v.setCoords( matInterface->giveUpdatedXCoordinate( this->giveNode(next)->giveNumber() ),
1264 matInterface->giveUpdatedYCoordinate( this->giveNode(next)->giveNumber() ) );
1265 } else {
1266 v.setCoords( this->giveNode(next)->giveCoordinate(1), this->giveNode(next)->giveCoordinate(2) );
1267 }
1268
1269 matvolpoly.addVertex(v);
1270 }
1271 }
1272 }
1273 } // end loop over elem nodes
1274 }
1275}
1276
1277
1278void
1279TR1_2D_SUPG2_AXI :: updateVolumePolygons(Polygon &referenceFluidPoly, Polygon &secondFluidPoly, int &rfPoints, int &sfPoints,
1280 const FloatArray &normal, const double p, bool updFlag)
1281{
1282 /*
1283 * this method updates two polygons, one filled with reference fluid and second filled with
1284 * other fluid (air). These two polygons are used in integrating element contributions.
1285 */
1286 int next;
1287 bool nodeIn [ 3 ];
1288 double nx = normal.at(1), ny = normal.at(2), x, y;
1289 double tx, ty;
1290 Vertex v;
1291
1292 rfPoints = sfPoints = 0;
1293 referenceFluidPoly.clear();
1294 secondFluidPoly.clear();
1295
1296 for ( int i = 1; i <= 3; i++ ) {
1297 x = this->giveNode(i)->giveCoordinate(1);
1298 y = this->giveNode(i)->giveCoordinate(2);
1299
1300 if ( ( nx * x + ny * y + p ) >= 0. ) {
1301 nodeIn [ i - 1 ] = true;
1302 } else {
1303 nodeIn [ i - 1 ] = false;
1304 }
1305 }
1306
1307 if ( nodeIn [ 0 ] && nodeIn [ 1 ] && nodeIn [ 2 ] ) { // all nodes inside
1308 for ( int i = 1; i <= 3; i++ ) {
1309 x = this->giveNode(i)->giveCoordinate(1);
1310 y = this->giveNode(i)->giveCoordinate(2);
1311
1312 v.setCoords(x, y);
1313 referenceFluidPoly.addVertex(v);
1314 rfPoints++;
1315 }
1316
1317 return;
1318 } else if ( !( nodeIn [ 0 ] || nodeIn [ 1 ] || nodeIn [ 2 ] ) ) { // all nodes outside
1319 for ( int i = 1; i <= 3; i++ ) {
1320 x = this->giveNode(i)->giveCoordinate(1);
1321 y = this->giveNode(i)->giveCoordinate(2);
1322
1323 v.setCoords(x, y);
1324 secondFluidPoly.addVertex(v);
1325 sfPoints++;
1326 }
1327
1328 return;
1329 } else {
1330 for ( int i = 1; i <= 3; i++ ) {
1331 next = i < 3 ? i + 1 : 1;
1332 if ( nodeIn [ i - 1 ] ) {
1333 v.setCoords( this->giveNode(i)->giveCoordinate(1),
1334 this->giveNode(i)->giveCoordinate(2) );
1335
1336 referenceFluidPoly.addVertex(v);
1337 rfPoints++;
1338 } else {
1339 v.setCoords( this->giveNode(i)->giveCoordinate(1),
1340 this->giveNode(i)->giveCoordinate(2) );
1341
1342 secondFluidPoly.addVertex(v);
1343 sfPoints++;
1344 }
1345
1346 if ( nodeIn [ next - 1 ] ^ nodeIn [ i - 1 ] ) {
1347 // compute intersection with (i,next) edge
1348 x = this->giveNode(i)->giveCoordinate(1);
1349 y = this->giveNode(i)->giveCoordinate(2);
1350 tx = this->giveNode(next)->giveCoordinate(1) - x;
1351 ty = this->giveNode(next)->giveCoordinate(2) - y;
1352
1353 double s, sd = nx * tx + ny * ty;
1354 if ( fabs(sd) > 1.e-10 ) {
1355 s = ( -p - ( nx * x + ny * y ) ) / sd;
1356 v.setCoords(x + tx * s, y + ty * s);
1357 referenceFluidPoly.addVertex(v);
1358 secondFluidPoly.addVertex(v);
1359 rfPoints++;
1360 sfPoints++;
1361 } else {
1362 // pathological case - lines are parallel
1363 if ( nodeIn [ i - 1 ] ) {
1364 v.setCoords( this->giveNode(next)->giveCoordinate(1), this->giveNode(next)->giveCoordinate(2) );
1365
1366 referenceFluidPoly.addVertex(v);
1367 secondFluidPoly.addVertex(v);
1368 rfPoints++;
1369 sfPoints++;
1370 } else {
1371 //v.setCoords(x, y);
1372 //referenceFluidPoly.addVertex(v);
1373 v.setCoords( this->giveNode(next)->giveCoordinate(1), this->giveNode(next)->giveCoordinate(2) );
1374
1375 referenceFluidPoly.addVertex(v);
1376 secondFluidPoly.addVertex(v);
1377 rfPoints++;
1378 sfPoints++;
1379 }
1380 }
1381 }
1382 } // end loop over elem nodes
1383 }
1384}
1385
1386double
1387TR1_2D_SUPG2_AXI :: truncateMatVolume(const Polygon &matvolpoly, double &volume)
1388{
1389 Polygon me, clip;
1390 Graph g;
1391
1392 this->formMyVolumePoly(me, NULL, false);
1393 g.clip(clip, me, matvolpoly);
1394#ifdef __OOFEG
1395 EASValsSetColor( gc [ 0 ].getActiveCrackColor() );
1396 //GraphicObj *go = clip.draw(::gc[OOFEG_DEBUG_LAYER],true);
1397 clip.draw(gc [ OOFEG_DEBUG_LAYER ], true);
1398 //EVFastRedraw(myview);
1399#endif
1400 volume = clip.computeVolume();
1401 return volume / area;
1402}
1403
1404void
1405TR1_2D_SUPG2_AXI :: formMyVolumePoly(Polygon &me, LEPlic *matInterface, bool updFlag)
1406{
1407 double x, y;
1408 Vertex v;
1409
1410 me.clear();
1411
1412 for ( int i = 1; i <= 3; i++ ) {
1413 if ( updFlag ) {
1414 x = matInterface->giveUpdatedXCoordinate( this->giveNode(i)->giveNumber() );
1415 y = matInterface->giveUpdatedYCoordinate( this->giveNode(i)->giveNumber() );
1416 } else {
1417 x = this->giveNode(i)->giveCoordinate(1);
1418 y = this->giveNode(i)->giveCoordinate(2);
1419 }
1420
1421 v.setCoords(x, y);
1422 me.addVertex(v);
1423 }
1424}
1425
1426
1427double
1428TR1_2D_SUPG2_AXI :: computeMyVolume(LEPlic *matInterface, bool updFlag)
1429{
1430 double x1, x2, x3, y1, y2, y3;
1431 if ( updFlag ) {
1432 x1 = matInterface->giveUpdatedXCoordinate( this->giveNode(1)->giveNumber() );
1433 x2 = matInterface->giveUpdatedXCoordinate( this->giveNode(2)->giveNumber() );
1434 x3 = matInterface->giveUpdatedXCoordinate( this->giveNode(3)->giveNumber() );
1435
1436 y1 = matInterface->giveUpdatedYCoordinate( this->giveNode(1)->giveNumber() );
1437 y2 = matInterface->giveUpdatedYCoordinate( this->giveNode(2)->giveNumber() );
1438 y3 = matInterface->giveUpdatedYCoordinate( this->giveNode(3)->giveNumber() );
1439 return 0.5 * ( x2 * y3 + x1 * y2 + y1 * x3 - x2 * y1 - x3 * y2 - x1 * y3 );
1440 } else {
1441 return area;
1442 }
1443}
1444
1445void
1446TR1_2D_SUPG2_AXI :: giveElementCenter(LEPlic *mat_interface, FloatArray &center, bool upd)
1447{
1448 FloatArray coords;
1449
1450 center.resize(2);
1451 center.zero();
1452 if ( upd ) {
1453 for ( int i = 1; i <= 3; i++ ) {
1454 mat_interface->giveUpdatedCoordinate( coords, giveNode(i)->giveNumber() );
1455 center.add(coords);
1456 }
1457 } else {
1458 for ( int i = 1; i <= 3; i++ ) {
1459 center.at(1) += this->giveNode(i)->giveCoordinate(1);
1460 center.at(2) += this->giveNode(i)->giveCoordinate(2);
1461 }
1462 }
1463
1464 center.times(1. / 3.);
1465}
1466
1467void
1468TR1_2D_SUPG2_AXI :: updateIntegrationRules()
1469{
1470 int c [ 2 ];
1471 int nip;
1472 double x, y;
1473 Vertex v;
1474
1475 for ( int i = 0; i < 2; i++ ) {
1476 myPoly [ i ].clear();
1477 }
1478
1479 if ( this->temp_vof <= TRSUPG_ZERO_VOF ) {
1480 for ( int i = 1; i <= 3; i++ ) {
1481 x = this->giveNode(i)->giveCoordinate(1);
1482 y = this->giveNode(i)->giveCoordinate(2);
1483 v.setCoords(x, y);
1484 myPoly [ 1 ].addVertex(v);
1485 c [ 1 ] = 3;
1486 c [ 0 ] = 0;
1487 }
1488 } else if ( this->temp_vof >= ( 1. - TRSUPG_ZERO_VOF ) ) {
1489 for ( int i = 1; i <= 3; i++ ) {
1490 x = this->giveNode(i)->giveCoordinate(1);
1491 y = this->giveNode(i)->giveCoordinate(2);
1492 v.setCoords(x, y);
1493 myPoly [ 0 ].addVertex(v);
1494 c [ 0 ] = 3;
1495 c [ 1 ] = 0;
1496 }
1497 } else {
1498 this->updateVolumePolygons(myPoly [ 0 ], myPoly [ 1 ], c [ 0 ], c [ 1 ], temp_normal, temp_p, false);
1499 }
1500
1501 integrationRulesArray [ 0 ]->clear();
1502 integrationRulesArray [ 1 ]->clear();
1503
1504 FloatArray gc, lc;
1505 const Vertex *p;
1506 FEI2dTrLin triaApprox(1, 2);
1507 FEI2dQuadLin quadApprox(1, 2);
1508 FEInterpolation *approx = NULL;
1509 // set up integration points
1510 for ( int i = 0; i < 2; i++ ) {
1511 if ( c [ i ] == 3 ) {
1512 id [ i ] = _Triangle;
1513 approx = & triaApprox;
1514 } else if ( c [ i ] == 4 ) {
1515 id [ i ] = _Square;
1516 approx = & quadApprox;
1517 } else if ( c [ i ] == 0 ) {
1518 continue;
1519 } else {
1520 OOFEM_ERROR("cannot set up integration domain for %d vertex polygon", c [ i ]);
1521 }
1522
1523 vcoords [ i ].clear();
1524 vcoords [ i ].reserve( c [ i ] );
1525
1526 // set up vertex coords
1527 Polygon :: PolygonVertexIterator it(myPoly + i);
1528 while ( it.giveNext(& p) ) {
1529 vcoords [ i ].push_back( *p->getCoords() );
1530 }
1531
1532 if ( id [ i ] == _Triangle ) {
1533 nip = 4;
1534 } else {
1535 nip = 4;
1536 }
1537
1538 this->giveCrossSection()->setupIntegrationPoints(* integrationRulesArray [ i ], nip, this);
1539
1540 // remap ip coords into area coords of receiver
1541 for ( GaussPoint *gp: *integrationRulesArray [ i ] ) {
1542 approx->local2global( gc, gp->giveNaturalCoordinates(), FEIVertexListGeometryWrapper(vcoords [ i ], approx->giveGeometryType()) );
1543 triaApprox.global2local( lc, gc, FEIElementGeometryWrapper(this) );
1544 // modify original ip coords to target ones
1545 gp->setSubPatchCoordinates( gp->giveNaturalCoordinates() );
1546 gp->setNaturalCoordinates(lc);
1547 //gp->setWeight (gp->giveWeight()*a/area);
1548 }
1549 }
1550#if 0
1551 // internal test -> compute receiver area
1552 double dV, __area = 0.0;
1553 for ( int ifluid = 0; ifluid < 2; ifluid++ ) {
1554 for ( GaussPoint *gp: *integrationRulesArray [ ifluid ] ) {
1555 dV = this->computeVolumeAroundID(gp, id [ ifluid ], vcoords [ ifluid ]);
1556 // compute integral here
1557 __area += dV;
1558 }
1559 }
1560
1561
1562 double __err = fabs(__area-area)/area;
1563 if (__err > 1.e-6) {
1564 OOFEM_WARNING("volume inconsistency (%5.2f\%)", __err*100);
1565
1566 __area=0.0;
1567 for (ifluid = 0; ifluid< 2; ifluid++) {
1568 for (GaussPoint *gp: *integrationRulesArray[ifluid]) {
1569 dV = this->computeVolumeAroundID(gp,id[ifluid], vcoords[ifluid]) ;
1570 // compute integral here
1571 __area += dV;
1572 }
1573 }
1574 }
1575#endif
1576}
1577
1578
1579double
1580TR1_2D_SUPG2_AXI :: computeRadiusAt(GaussPoint *gp)
1581{
1582 double r1, r2, r3;
1583 double n1, n2, n3;
1584
1585 r1 = this->giveNode(1)->giveCoordinate(1);
1586 r2 = this->giveNode(2)->giveCoordinate(1);
1587 r3 = this->giveNode(3)->giveCoordinate(1);
1588
1589 n1 = gp->giveNaturalCoordinate(1);
1590 n2 = gp->giveNaturalCoordinate(2);
1591 n3 = 1. - n1 - n2;
1592
1593 return n1 * r1 + n2 * r2 + n3 * r3;
1594}
1595
1596
1597
1598double
1599TR1_2D_SUPG2_AXI :: computeVolumeAroundID(GaussPoint *gp, integrationDomain id, const std::vector< FloatArray > &idpoly)
1600{
1601 double weight = gp->giveWeight();
1602 double _r = computeRadiusAt(gp);
1603
1604 if ( id == _Triangle ) {
1605 FEI2dTrLin __interpolation(1, 2);
1606 return _r *weight *fabs( __interpolation.giveTransformationJacobian ( gp->giveSubPatchCoordinates(), FEIVertexListGeometryWrapper(idpoly, __interpolation.giveGeometryType()) ) );
1607 } else {
1608 FEI2dQuadLin __interpolation(1, 2);
1609 double det = fabs( __interpolation.giveTransformationJacobian( gp->giveSubPatchCoordinates(), FEIVertexListGeometryWrapper(idpoly, __interpolation.giveGeometryType()) ) );
1610 return _r * det * weight;
1611 }
1612}
1613
1614void TR1_2D_SUPG2_AXI :: computeBMtrx(FloatMatrix &_b, GaussPoint *gp)
1615{
1616 _b.resize(4, 6);
1617 double _r = this->computeRadiusAt(gp);
1618
1619
1620 _b.at(1, 1) = b [ 0 ];
1621 _b.at(1, 2) = 0.;
1622 _b.at(1, 3) = b [ 1 ];
1623 _b.at(1, 4) = 0.;
1624 _b.at(1, 5) = b [ 2 ];
1625 _b.at(1, 6) = 0.;
1626 _b.at(2, 1) = 1. / _r;
1627 _b.at(2, 2) = 0.;
1628 _b.at(2, 3) = 1. / _r;
1629 _b.at(2, 4) = 0.;
1630 _b.at(2, 5) = 1. / _r;
1631 _b.at(2, 6) = 0.;
1632 _b.at(3, 1) = 0.0;
1633 _b.at(3, 2) = c [ 0 ];
1634 _b.at(3, 3) = 0.0;
1635 _b.at(3, 4) = c [ 1 ];
1636 _b.at(3, 5) = 0.0;
1637 _b.at(3, 6) = c [ 2 ];
1638 _b.at(4, 1) = c [ 0 ];
1639 _b.at(4, 2) = b [ 0 ];
1640 _b.at(4, 3) = c [ 1 ];
1641 _b.at(4, 4) = b [ 1 ];
1642 _b.at(4, 5) = c [ 2 ];
1643 _b.at(4, 6) = b [ 2 ];
1644
1645 /*
1646 *
1647 * double _c = (1./3.);
1648 * double u1 = _c*(b[0]+1./_r), u2 = _c*(b[1]+1./_r), u3 = _c*(b[2]+1./_r);
1649 * double w1 = _c*c[0], w2 = _c*c[1], w3 = _c*c[2];
1650 *
1651 * //u1=u2=u3=w1=w2=w3=0.0;
1652 *
1653 * _b.at(1,1) = b[0]-u1; _b.at(1,2)=0.-w1; _b.at(1,3)= b[1]-u2; _b.at(1,4)=0.-w2; _b.at(1,5)=b[2]-u3; _b.at(1,6)=0.-w3;
1654 * _b.at(2,1) = 1./_r-u1;_b.at(2,2)=0.-w1; _b.at(2,3)= 1./_r-u2;_b.at(2,4)=0.-w2; _b.at(2,5)=1./_r-u3;_b.at(2,6)=0.-w3;
1655 * _b.at(3,1) = 0.0-u1; _b.at(3,2)=c[0]-w1; _b.at(3,3)= 0.0-u2; _b.at(3,4)=c[1]-w2; _b.at(3,5)=0.0-u3; _b.at(3,6)=c[2]-w3;
1656 * _b.at(4,1) = c[0]; _b.at(4,2)=b[0]; _b.at(4,3)= c[1]; _b.at(4,4)=b[1]; _b.at(4,5)=c[2]; _b.at(4,6)=b[2];
1657 */
1658}
1659
1660/*
1661 * double
1662 * TR1_2D_SUPG2::computeVolumeAroundID(GaussPoint* gp, integrationDomain id, const Polygon& matvolpoly) {
1663 * }
1664 */
1665void
1666TR1_2D_SUPG2_AXI :: computeNVector(FloatArray &n, GaussPoint *gp)
1667{
1668 this->interp.evalN( n, gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) );
1669}
1670
1671void
1672TR1_2D_SUPG2_AXI :: printOutputAt(FILE *file, TimeStep *tStep)
1673// Performs end-of-step operations.
1674{
1675 SUPGElement :: printOutputAt(file, tStep);
1676
1677 GaussPoint *gp;
1678 if ( integrationRulesArray [ 0 ]->giveNumberOfIntegrationPoints() ) {
1679 gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
1680 } else {
1681 gp = integrationRulesArray [ 1 ]->getIntegrationPoint(0);
1682 }
1683
1684 double rho = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveDensity(gp);
1685 fprintf(file, "VOF %e, density %e\n\n", this->giveVolumeFraction(), rho);
1686}
1687
1688
1689void
1690TR1_2D_SUPG2_AXI :: NodalAveragingRecoveryMI_computeNodalValue(FloatArray &answer, int node,
1691 InternalStateType type, TimeStep *tStep)
1692{
1693 GaussPoint *gp;
1694 if ( integrationRulesArray [ 0 ]->giveNumberOfIntegrationPoints() ) {
1695 gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
1696 } else {
1697 gp = integrationRulesArray [ 1 ]->getIntegrationPoint(0);
1698 }
1699
1700 this->giveIPValue(answer, gp, type, tStep);
1701}
1702
1703void
1704TR1_2D_SUPG2_AXI :: SPRNodalRecoveryMI_giveSPRAssemblyPoints(IntArray &pap)
1705{
1706 pap.resize(3);
1707 pap.at(1) = this->giveNode(1)->giveNumber();
1708 pap.at(2) = this->giveNode(2)->giveNumber();
1709 pap.at(3) = this->giveNode(3)->giveNumber();
1710}
1711
1712void
1713TR1_2D_SUPG2_AXI :: SPRNodalRecoveryMI_giveDofMansDeterminedByPatch(IntArray &answer, int pap)
1714{
1715 answer.resize(1);
1716 if ( ( pap == this->giveNode(1)->giveNumber() ) ||
1717 ( pap == this->giveNode(2)->giveNumber() ) ||
1718 ( pap == this->giveNode(3)->giveNumber() ) ) {
1719 answer.at(1) = pap;
1720 } else {
1721 OOFEM_ERROR("node unknown");
1722 }
1723}
1724
1725int
1726TR1_2D_SUPG2_AXI :: SPRNodalRecoveryMI_giveNumberOfIP()
1727{ return 1; }
1728
1729
1731TR1_2D_SUPG2_AXI :: SPRNodalRecoveryMI_givePatchType()
1732{
1733 return SPRPatchType_2dxy;
1734}
1735
1736
1737
1738#ifdef __OOFEG
1739int
1740TR1_2D_SUPG2_AXI :: giveInternalStateAtNode(FloatArray &answer, InternalStateType type, InternalStateMode mode,
1741 int node, TimeStep *tStep)
1742{
1743 /*
1744 * if (type == IST_VOFFraction) {
1745 * answer.resize(1);
1746 * answer.at(1) = this->giveTempVolumeFraction();
1747 * return 1;
1748 * } else if (type == IST_Density) {
1749 * answer.resize(1);
1750 * answer.at(1) = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveDensity(gp);
1751 * return 1;
1752 *
1753 * } else
1754 */return SUPGElement :: giveInternalStateAtNode(answer, type, mode, node, tStep);
1755}
1756
1757void
1758TR1_2D_SUPG2_AXI :: drawRawGeometry(oofegGraphicContext &gc, TimeStep *tStep)
1759{
1760 WCRec p [ 3 ];
1761 GraphicObj *go;
1762
1763 if ( !gc.testElementGraphicActivity(this) ) {
1764 return;
1765 }
1766
1767 EASValsSetLineWidth(OOFEG_RAW_GEOMETRY_WIDTH);
1768 EASValsSetColor( gc.getElementColor() );
1769 EASValsSetEdgeColor( gc.getElementEdgeColor() );
1770 EASValsSetEdgeFlag(true);
1771 EASValsSetLayer(OOFEG_RAW_GEOMETRY_LAYER);
1772 p [ 0 ].x = ( FPNum ) this->giveNode(1)->giveCoordinate(1);
1773 p [ 0 ].y = ( FPNum ) this->giveNode(1)->giveCoordinate(2);
1774 p [ 0 ].z = 0.;
1775 p [ 1 ].x = ( FPNum ) this->giveNode(2)->giveCoordinate(1);
1776 p [ 1 ].y = ( FPNum ) this->giveNode(2)->giveCoordinate(2);
1777 p [ 1 ].z = 0.;
1778 p [ 2 ].x = ( FPNum ) this->giveNode(3)->giveCoordinate(1);
1779 p [ 2 ].y = ( FPNum ) this->giveNode(3)->giveCoordinate(2);
1780 p [ 2 ].z = 0.;
1781
1782 go = CreateTriangle3D(p);
1783 EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | EDGE_COLOR_MASK | EDGE_FLAG_MASK | LAYER_MASK, go);
1784 EGAttachObject(go, ( EObjectP ) this);
1785 EMAddGraphicsToModel(ESIModel(), go);
1786}
1787
1788void TR1_2D_SUPG2_AXI :: drawScalar(oofegGraphicContext &gc, TimeStep *tStep)
1789{
1790 int i, indx, result = 0;
1791 WCRec p [ 3 ];
1792 GraphicObj *tr;
1793 FloatArray v1, v2, v3;
1794 double s [ 3 ];
1795
1796 if ( !gc.testElementGraphicActivity(this) ) {
1797 return;
1798 }
1799
1800 EASValsSetLayer(OOFEG_VARPLOT_PATTERN_LAYER);
1801
1802 // if ((gc.giveIntVarMode() == ISM_local) && (gc.giveIntVarType() == IST_VOFFraction)) {
1803 if ( ( gc.giveIntVarType() == IST_VOFFraction ) && ( gc.giveIntVarMode() == ISM_local ) ) {
1804 Polygon matvolpoly;
1805 this->formMaterialVolumePoly(matvolpoly, NULL, temp_normal, temp_p, false);
1806 EASValsSetColor( gc.getStandardSparseProfileColor() );
1807 //GraphicObj *go = matvolpoly.draw(gc,true,OOFEG_VARPLOT_PATTERN_LAYER);
1808 matvolpoly.draw(gc, true, OOFEG_VARPLOT_PATTERN_LAYER);
1809 return;
1810 }
1811
1812 /*
1813 * if ((gc.giveIntVarMode() == ISM_local) && (gc.giveIntVarType() == IST_VOFFraction)) {
1814 * Polygon matvolpoly;
1815 * FloatArray _n;
1816 * double _p;
1817 * this->doCellDLS (_n, this->giveNumber());
1818 * this->findCellLineConstant (_p, _n, this->giveNumber());
1819 * this->formMaterialVolumePoly(matvolpoly, NULL, _n, _p, false);
1820 * GraphicObj *go = matvolpoly.draw(gc,true,OOFEG_VARPLOT_PATTERN_LAYER);
1821 * return;
1822 * }
1823 */
1824
1825 if ( gc.giveIntVarMode() == ISM_recovered ) {
1826 result += this->giveInternalStateAtNode(v1, gc.giveIntVarType(), gc.giveIntVarMode(), 1, tStep);
1827 result += this->giveInternalStateAtNode(v2, gc.giveIntVarType(), gc.giveIntVarMode(), 2, tStep);
1828 result += this->giveInternalStateAtNode(v3, gc.giveIntVarType(), gc.giveIntVarMode(), 3, tStep);
1829 } else if ( gc.giveIntVarMode() == ISM_local ) {
1830 GaussPoint *gp;
1831 if ( integrationRulesArray [ 0 ]->giveNumberOfIntegrationPoints() ) {
1832 gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
1833 } else {
1834 gp = integrationRulesArray [ 1 ]->getIntegrationPoint(0);
1835 }
1836
1837 result += giveIPValue(v1, gp, gc.giveIntVarType(), tStep);
1838 v2 = v1;
1839 v3 = v1;
1840 result *= 3;
1841 }
1842
1843 if ( result != 3 ) {
1844 return;
1845 }
1846
1847 indx = gc.giveIntVarIndx();
1848
1849 s [ 0 ] = v1.at(indx);
1850 s [ 1 ] = v2.at(indx);
1851 s [ 2 ] = v3.at(indx);
1852
1853 if ( gc.getScalarAlgo() == SA_ISO_SURF ) {
1854 for ( i = 0; i < 3; i++ ) {
1855 p [ i ].x = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(1);
1856 p [ i ].y = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(2);
1857 p [ i ].z = 0.;
1858 }
1859
1860 //EASValsSetColor(gc.getYieldPlotColor(ratio));
1861 gc.updateFringeTableMinMax(s, 3);
1862 tr = CreateTriangleWD3D(p, s [ 0 ], s [ 1 ], s [ 2 ]);
1863 EGWithMaskChangeAttributes(LAYER_MASK, tr);
1864 EMAddGraphicsToModel(ESIModel(), tr);
1865 } else if ( ( gc.getScalarAlgo() == SA_ZPROFILE ) || ( gc.getScalarAlgo() == SA_COLORZPROFILE ) ) {
1866 double landScale = gc.getLandScale();
1867
1868 for ( i = 0; i < 3; i++ ) {
1869 p [ i ].x = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(1);
1870 p [ i ].y = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(2);
1871 p [ i ].z = s [ i ] * landScale;
1872 }
1873
1874 if ( gc.getScalarAlgo() == SA_ZPROFILE ) {
1875 EASValsSetColor( gc.getDeformedElementColor() );
1876 EASValsSetLineWidth(OOFEG_DEFORMED_GEOMETRY_WIDTH);
1877 EASValsSetFillStyle(FILL_SOLID);
1878 tr = CreateTriangle3D(p);
1879 EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | FILL_MASK | LAYER_MASK, tr);
1880 } else {
1881 gc.updateFringeTableMinMax(s, 3);
1882 EASValsSetFillStyle(FILL_SOLID);
1883 tr = CreateTriangleWD3D(p, s [ 0 ], s [ 1 ], s [ 2 ]);
1884 EGWithMaskChangeAttributes(FILL_MASK | LAYER_MASK, tr);
1885 }
1886
1887 EMAddGraphicsToModel(ESIModel(), tr);
1888 }
1889}
1890
1891
1892
1893#endif
1894} // end namespace oofem
#define REGISTER_Element(class)
void setField(int item, InputFieldType id)
Node * giveNode(int i) const
Definition element.h:629
IntArray boundaryLoadArray
Definition element.h:147
IntArray * giveBodyLoadArray()
Returns array containing load numbers of loads acting on element.
Definition element.C:411
int numberOfDofMans
Number of dofmanagers.
Definition element.h:136
IntArray * giveBoundaryLoadArray()
Returns array containing load numbers of boundary loads acting on element.
Definition element.C:420
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
Definition element.h:157
int material
Number of associated material.
Definition element.h:140
CrossSection * giveCrossSection()
Definition element.C:534
IntArray bodyLoadArray
Definition element.h:147
const Element_Geometry_Type giveGeometryType() const override
const Element_Geometry_Type giveGeometryType() const override
Definition fei2dtrlin.h:54
double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
Definition fei2dtrlin.C:172
int global2local(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
Definition fei2dtrlin.C:130
virtual const Element_Geometry_Type giveGeometryType() const =0
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
Definition feinterpol.C:81
virtual void local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
Domain * giveDomain() const
Definition femcmpnn.h:97
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
int number
Component number.
Definition femcmpnn.h:77
int giveNumber() const
Definition femcmpnn.h:104
void computeVectorOfVelocities(ValueModeType mode, TimeStep *tStep, FloatArray &velocities)
Definition fmelement.C:44
double computeNorm() const
Definition floatarray.C:861
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
void plusProduct(const FloatMatrix &b, const FloatArray &s, double dV)
Definition floatarray.C:288
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void add(const FloatArray &src)
Definition floatarray.C:218
void times(double s)
Definition floatarray.C:834
void times(double f)
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
void plusProductUnsym(const FloatMatrix &a, const FloatMatrix &b, double dV)
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
void zero()
Zeroes all coefficient of receiver.
double computeFrobeniusNorm() const
double at(std::size_t i, std::size_t j) const
virtual double giveReynoldsNumber()=0
double giveNaturalCoordinate(int i) const
Returns i-th natural element coordinate of receiver.
Definition gausspoint.h:136
const FloatArray & giveNaturalCoordinates() const
Returns coordinate array of receiver.
Definition gausspoint.h:138
const FloatArray & giveSubPatchCoordinates() const
Returns local sub-patch coordinates of the receiver.
Definition gausspoint.h:142
double giveWeight()
Returns integration weight of receiver.
Definition gausspoint.h:180
virtual bcGeomType giveBCGeoType() const
void clip(Polygon &result, const Polygon &a, const Polygon &b)
Definition geotoolbox.C:575
void resize(int n)
Definition intarray.C:73
int & at(std::size_t i)
Definition intarray.h:104
FloatArray normal
Interface segment normal.
Definition leplic.h:67
void setPermanentVolumeFraction(double v)
Definition leplic.h:106
double p
Line constant of line segment representing interface.
Definition leplic.h:65
double vof
Volume fraction of reference fluid in element.
Definition leplic.h:63
double giveUpdatedXCoordinate(int num)
Definition leplic.h:185
void giveUpdatedCoordinate(FloatArray &answer, int num)
Definition leplic.h:179
double giveUpdatedYCoordinate(int num)
Definition leplic.h:186
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
Definition load.C:84
void addVertex(Vertex v)
Definition geotoolbox.h:96
GraphicObj * draw(oofegGraphicContext &, bool filled, int layer=OOFEG_DEBUG_LAYER)
Definition geotoolbox.C:152
double computeVolume() const
Definition geotoolbox.C:72
IntArray boundaryCodes
Boundary sides codes.
Definition supgelement.h:59
IntArray boundarySides
Array of boundary sides.
Definition supgelement.h:57
integrationDomain id[2]
std::vector< FloatArray > vcoords[2]
double computeVolumeAroundID(GaussPoint *gp, integrationDomain id, const std::vector< FloatArray > &idpoly)
void formVolumeInterfacePoly(Polygon &matvolpoly, LEPlic *matInterface, const FloatArray &normal, const double p, bool updFlag) override
Assembles receiver material polygon based solely on given interface line.
Material * _giveMaterial(int indx)
void computeBMtrx(FloatMatrix &answer, GaussPoint *gp)
void formMyVolumePoly(Polygon &myPoly, LEPlic *mat_interface, bool updFlag) override
Assembles receiver volume.
int giveInternalStateAtNode(FloatArray &answer, InternalStateType type, InternalStateMode mode, int node, TimeStep *tStep) override
void updateVolumePolygons(Polygon &referenceFluidPoly, Polygon &secondFluidPoly, int &rfPoints, int &sfPoints, const FloatArray &normal, const double p, bool updFlag)
double computeRadiusAt(GaussPoint *gp)
void formMaterialVolumePoly(Polygon &matvolpoly, LEPlic *matInterface, const FloatArray &normal, const double p, bool updFlag) override
Assembles the true element material polygon (takes receiver vof into accout).
void computeNVector(FloatArray &answer, GaussPoint *gp)
double computeMyVolume(LEPlic *matInterface, bool updFlag) override
Computes the volume of receiver.
static ParamKey IPK_TR1_2D_SUPG_vof
Definition tr1_2d_supg.h:78
void computeNMtrx(FloatArray &answer, GaussPoint *gp)
static FEI2dTrLin interp
Definition tr1_2d_supg.h:71
TR1_2D_SUPG(int n, Domain *d)
Definition tr1_2d_supg.C:79
static ParamKey IPK_TR1_2D_SUPG_pvof
Definition tr1_2d_supg.h:79
virtual void initGeometry()
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
static ParamKey IPK_TR1_2D_SUPG_mat1
Definition tr1_2d_supg.h:81
static ParamKey IPK_TR1_2D_SUPG_mat0
Definition tr1_2d_supg.h:80
double giveTimeIncrement()
Returns solution step associated time increment.
Definition timestep.h:168
TimeStep * givePreviousStep()
Returns pointer to previous solution step.
Definition timestep.C:132
void setCoords(double x, double y)
Definition geotoolbox.h:77
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define FMElement_PrescribedTractionBC
Definition fmelement.h:44
@ VST_Length
@ VST_Viscosity
@ VST_Velocity
@ VST_Density
bcGeomType
Type representing the geometric character of loading.
Definition bcgeomtype.h:40
@ BodyLoadBGT
Distributed body load.
Definition bcgeomtype.h:43
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
InternalStateMode
Determines the mode of internal variable.
double det(const FloatMatrixF< 2, 2 > &mat)
Computes the determinant.
double sum(const FloatArray &x)
@ ForceLoadBVT
Definition bcvaltype.h:43
oofem::oofegGraphicContext gc[OOFEG_LAST_LAYER]
#define OOFEG_DEBUG_LAYER
#define OOFEG_VARPLOT_PATTERN_LAYER
#define OOFEG_DEFORMED_GEOMETRY_WIDTH
#define OOFEG_RAW_GEOMETRY_WIDTH
#define OOFEG_RAW_GEOMETRY_LAYER
#define PM_UPDATE_PARAMETER_AND_REPORT(_val, _pm, _ir, _componentnum, _paramkey, _prio, _flag)
#define PM_UPDATE_PARAMETER(_val, _pm, _ir, _componentnum, _paramkey, _prio)
#define TRSUPG_ZERO_VOF
Definition tr1_2d_cbs.C:66

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011