~ubuntu-branches/ubuntu/trusty/yade/trusty

« back to all changes in this revision

Viewing changes to pkg/dem/FlowEngine.cpp

  • Committer: Package Import Robot
  • Author(s): Anton Gladky, cf3f8d9
  • Date: 2013-10-30 20:56:33 UTC
  • mfrom: (20.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20131030205633-1f01r7hjce17d723
Tags: 1.05.0-2
[cf3f8d9] Pass -ftrack-macro-expansion=0 only if gcc>=4.8. (Closes: #726009)

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include <boost/date_time.hpp>
22
22
#include <boost/date_time/posix_time/posix_time.hpp>
23
23
 
 
24
#ifdef LINSOLV
 
25
#include <cholmod.h>
 
26
#endif
 
27
 
24
28
#include "FlowEngine.hpp"
25
29
 
26
30
CREATE_LOGGER ( FlowEngine );
58
62
        timingDeltas->checkpoint ( "Update_Volumes" );
59
63
        
60
64
        Eps_Vol_Cumulative += eps_vol_max;
61
 
        if ( (EpsVolPercent_RTRG>0 && Eps_Vol_Cumulative > EpsVolPercent_RTRG) || retriangulationLastIter>PermuteInterval) {
62
 
                Update_Triangulation = true;
 
65
        if ( (defTolerance>0 && Eps_Vol_Cumulative > defTolerance) || retriangulationLastIter>meshUpdateInterval) {
 
66
                updateTriangulation = true;
63
67
                Eps_Vol_Cumulative=0;
64
68
                retriangulationLastIter=0;
65
69
                ReTrg++;
66
70
        } else  {
67
 
                Update_Triangulation = false;
 
71
                updateTriangulation = false;
68
72
                retriangulationLastIter++;}
69
73
 
70
74
 
83
87
        Finite_vertices_iterator vertices_end = solver->T[solver->currentTes].Triangulation().finite_vertices_end();
84
88
        for ( Finite_vertices_iterator V_it = solver->T[solver->currentTes].Triangulation().finite_vertices_begin(); V_it !=  vertices_end; V_it++ ) {
85
89
                force = pressureForce ? Vector3r ( V_it->info().forces[0],V_it->info().forces[1],V_it->info().forces[2] ): Vector3r(0,0,0);
86
 
                if (viscousShear || shearLubrication){
 
90
                if (shearLubrication || viscousShear){
87
91
                        force = force + solver->viscousShearForces[V_it->info().id()];
88
92
                        scene->forces.addTorque ( V_it->info().id(), solver->viscousShearTorques[V_it->info().id()]);
89
93
                }
95
99
        timingDeltas->checkpoint ( "Applying Forces" );
96
100
        int sleeping = 0;
97
101
        if (multithread && !first) {
98
 
                while (Update_Triangulation && !backgroundCompleted) { /*cout<<"sleeping..."<<sleeping++<<endl;*/ 
 
102
                while (updateTriangulation && !backgroundCompleted) { /*cout<<"sleeping..."<<sleeping++<<endl;*/
99
103
                  sleeping++;
100
104
                boost::this_thread::sleep(boost::posix_time::microseconds(1000));}
101
105
                if (Debug && sleeping) cerr<<"sleeping..."<<sleeping<<endl;
102
 
                if (Update_Triangulation || (ellapsedIter>(0.5*PermuteInterval) && backgroundCompleted)) {
 
106
                if (updateTriangulation || (ellapsedIter>(0.5*meshUpdateInterval) && backgroundCompleted)) {
103
107
                        if (Debug) cerr<<"switch flow solver"<<endl;
104
108
                        if (useSolver==0) LOG_ERROR("background calculations not available for Gauss-Seidel");
105
109
                        if (fluidBulkModulus>0) solver->Interpolate (solver->T[solver->currentTes], backgroundSolver->T[backgroundSolver->currentTes]);
112
116
                        setPositionsBuffer(false);//set "parallel" buffer for background calculation 
113
117
                        backgroundCompleted=false;
114
118
                        retriangulationLastIter=ellapsedIter;
115
 
                        Update_Triangulation=false;
 
119
                        updateTriangulation=false;
116
120
                        ellapsedIter=0;
117
121
                        boost::thread workerThread(&FlowEngine::backgroundAction,this);
118
122
                        workerThread.detach();
126
130
                        ellapsedIter++;
127
131
                }
128
132
        } else {
129
 
                if (Update_Triangulation && !first) {
 
133
                if (updateTriangulation && !first) {
130
134
                        Build_Triangulation (P_zero, solver);
131
135
                        Initialize_volumes(solver);
132
136
                        ComputeViscousForces(*solver);
133
 
                        Update_Triangulation = false;}
 
137
                        updateTriangulation = false;}
134
138
        }
135
 
        if ( velocity_profile ) /*flow->FluidVelocityProfile();*/solver->Average_Fluid_Velocity();
136
139
        first=false;
137
140
        timingDeltas->checkpoint ( "Triangulate + init volumes" );
138
141
}
153
156
 
154
157
void FlowEngine::BoundaryConditions ( Solver& flow )
155
158
{
156
 
        if ( flow->y_min_id>=0 ) {
157
 
                flow->boundary ( flow->y_min_id ).flowCondition=Flow_imposed_BOTTOM_Boundary;
158
 
                flow->boundary ( flow->y_min_id ).value=Pressure_BOTTOM_Boundary;
159
 
                flow->boundary ( flow->y_min_id ).velocity = Vector3r::Zero();
160
 
        }
161
 
        if ( flow->y_max_id>=0 ) {
162
 
                flow->boundary ( flow->y_max_id ).flowCondition=Flow_imposed_TOP_Boundary;
163
 
                flow->boundary ( flow->y_max_id ).value=Pressure_TOP_Boundary;
164
 
                flow->boundary ( flow->y_max_id ).velocity = topBoundaryVelocity;
165
 
        }
166
 
        if ( flow->x_max_id>=0 ) {
167
 
                flow->boundary ( flow->x_max_id ).flowCondition=Flow_imposed_RIGHT_Boundary;
168
 
                flow->boundary ( flow->x_max_id ).value=Pressure_RIGHT_Boundary;
169
 
                flow->boundary ( flow->x_max_id ).velocity = Vector3r::Zero();
170
 
        }
171
 
        if ( flow->x_min_id>=0 ) {
172
 
                flow->boundary ( flow->x_min_id ).flowCondition=Flow_imposed_LEFT_Boundary;
173
 
                flow->boundary ( flow->x_min_id ).value=Pressure_LEFT_Boundary;
174
 
                flow->boundary ( flow->x_min_id ).velocity = Vector3r::Zero();
175
 
        }
176
 
        if ( flow->z_max_id>=0 ) {
177
 
                flow->boundary ( flow->z_max_id ).flowCondition=Flow_imposed_FRONT_Boundary;
178
 
                flow->boundary ( flow->z_max_id ).value=Pressure_FRONT_Boundary;
179
 
                flow->boundary ( flow->z_max_id ).velocity = Vector3r::Zero();
180
 
        }
181
 
        if ( flow->z_min_id>=0 ) {
182
 
                flow->boundary ( flow->z_min_id ).flowCondition=Flow_imposed_BACK_Boundary;
183
 
                flow->boundary ( flow->z_min_id ).value=Pressure_BACK_Boundary;
184
 
                flow->boundary ( flow->z_min_id ).velocity = Vector3r::Zero();
185
 
        }
 
159
 
 
160
        for (int k=0;k<6;k++)   {
 
161
                flow->boundary (wallIds[k]).flowCondition=!bndCondIsPressure[k];
 
162
                flow->boundary (wallIds[k]).value=bndCondValue[k];
 
163
                flow->boundary (wallIds[k]).velocity = boundaryVelocity[k];//FIXME: needs correct implementation, maybe update the cached pos/vel?
 
164
        }
186
165
}
187
166
 
188
167
template<class Solver>
222
201
{
223
202
        flow->Vtotalissimo=0; flow->Vsolid_tot=0; flow->Vporale=0; flow->Ssolid_tot=0;
224
203
        flow->SLIP_ON_LATERALS=slip_boundary;
225
 
        flow->k_factor = permeability_factor;
 
204
        flow->k_factor = permeabilityFactor;
226
205
        flow->DEBUG_OUT = Debug;
227
206
        flow->useSolver = useSolver;
228
207
        #ifdef EIGENSPARSE_LIB
231
210
        #endif
232
211
        flow->meanKStat = meanKStat;
233
212
        flow->VISCOSITY = viscosity;
234
 
        flow->areaR2Permeability=areaR2Permeability;
235
213
        flow->TOLERANCE=Tolerance;
236
214
        flow->RELAX=Relax;
237
215
        flow->clampKValues = clampKValues;
245
223
        flow->x_min = 1000.0, flow->x_max = -10000.0, flow->y_min = 1000.0, flow->y_max = -10000.0, flow->z_min = 1000.0, flow->z_max = -10000.0;
246
224
}
247
225
 
 
226
#ifdef LINSOLV
 
227
template<class Solver>
 
228
void FlowEngine::setForceMetis ( Solver& flow, bool force )
 
229
{
 
230
        if (force) {
 
231
                flow->eSolver.cholmod().nmethods=1;
 
232
                flow->eSolver.cholmod().method[0].ordering=CHOLMOD_METIS;
 
233
        } else cholmod_defaults(&(flow->eSolver.cholmod()));
 
234
}
 
235
 
 
236
template<class Solver>
 
237
bool FlowEngine::getForceMetis ( Solver& flow ) {return (flow->eSolver.cholmod().nmethods==1);}
 
238
#endif
 
239
 
248
240
template<class Solver>
249
241
void FlowEngine::Build_Triangulation ( Solver& flow )
250
242
{
276
268
        for ( Finite_cells_iterator cell = flow->T[flow->currentTes].Triangulation().finite_cells_begin(); cell != cell_end; cell++ )
277
269
                flow->T[flow->currentTes].cellHandles.push_back(cell);
278
270
        flow->DisplayStatistics ();
279
 
        flow->Compute_Permeability ( );
280
 
 
 
271
        flow->Compute_Permeability();
281
272
        porosity = flow->V_porale_porosity/flow->V_totale_porosity;
282
273
 
283
 
        if ( compute_K ) {BoundaryConditions ( flow ); K = flow->Sample_Permeability ( flow->x_min, flow->x_max, flow->y_min, flow->y_max, flow->z_min, flow->z_max );}
284
 
 
285
274
        BoundaryConditions ( flow );
286
275
        flow->Initialize_pressures ( P_zero );
287
276
        
288
277
        if ( !first && !multithread && (useSolver==0 || fluidBulkModulus>0)) flow->Interpolate ( flow->T[!flow->currentTes], flow->T[flow->currentTes] );
289
 
        if ( WaveAction ) flow->ApplySinusoidalPressure ( flow->T[flow->currentTes].Triangulation(), Sinus_Amplitude, Sinus_Average, 30 );
290
 
 
291
 
        if ( viscousShear || normalLubrication || shearLubrication) flow->computeEdgesSurfaces();
 
278
        if ( WaveAction ) flow->ApplySinusoidalPressure ( flow->T[flow->currentTes].Triangulation(), sineMagnitude, sineAverage, 30 );
 
279
        if (normalLubrication || shearLubrication || viscousShear) flow->computeEdgesSurfaces();
292
280
}
293
281
 
294
282
void FlowEngine::setPositionsBuffer(bool current)
334
322
        flow->id_offset = id_offset;
335
323
        flow->SectionArea = ( flow->x_max - flow->x_min ) * ( flow->z_max-flow->z_min );
336
324
        flow->Vtotale = ( flow->x_max-flow->x_min ) * ( flow->y_max-flow->y_min ) * ( flow->z_max-flow->z_min );
337
 
        flow->y_min_id=wallBottomId;
338
 
        flow->y_max_id=wallTopId;
339
 
        flow->x_max_id=wallRightId;
340
 
        flow->x_min_id=wallLeftId;
341
 
        flow->z_min_id=wallBackId;
342
 
        flow->z_max_id=wallFrontId;
343
 
 
344
 
        if ( flow->y_min_id>=0 ) flow->boundary ( flow->y_min_id ).useMaxMin = BOTTOM_Boundary_MaxMin;
345
 
        if ( flow->y_max_id>=0 ) flow->boundary ( flow->y_max_id ).useMaxMin = TOP_Boundary_MaxMin;
346
 
        if ( flow->x_max_id>=0 ) flow->boundary ( flow->x_max_id ).useMaxMin = RIGHT_Boundary_MaxMin;
347
 
        if ( flow->x_min_id>=0 ) flow->boundary ( flow->x_min_id ).useMaxMin = LEFT_Boundary_MaxMin;
348
 
        if ( flow->z_max_id>=0 ) flow->boundary ( flow->z_max_id ).useMaxMin = FRONT_Boundary_MaxMin;
349
 
        if ( flow->z_min_id>=0 ) flow->boundary ( flow->z_min_id ).useMaxMin = BACK_Boundary_MaxMin;
 
325
        flow->y_min_id=wallIds[ymin];
 
326
        flow->y_max_id=wallIds[ymax];
 
327
        flow->x_max_id=wallIds[xmax];
 
328
        flow->x_min_id=wallIds[xmin];
 
329
        flow->z_min_id=wallIds[zmin];
 
330
        flow->z_max_id=wallIds[zmax];
350
331
 
351
332
        //FIXME: Id's order in boundsIds is done according to the enumeration of boundaries from TXStressController.hpp, line 31. DON'T CHANGE IT!
352
333
        flow->boundsIds[0]= &flow->x_min_id;
356
337
        flow->boundsIds[4]= &flow->z_min_id;
357
338
        flow->boundsIds[5]= &flow->z_max_id;
358
339
 
 
340
        for (int k=0;k<6;k++) flow->boundary ( *flow->boundsIds[k] ).useMaxMin = boundaryUseMaxMin[k];
 
341
 
 
342
//         if ( flow->y_min_id>=0 ) flow->boundary ( flow->y_min_id ).useMaxMin = boundaryUseMaxMin[ymin];
 
343
//         if ( flow->y_max_id>=0 ) flow->boundary ( flow->y_max_id ).useMaxMin = boundaryUseMaxMin[ymax];
 
344
//         if ( flow->x_max_id>=0 ) flow->boundary ( flow->x_max_id ).useMaxMin = boundaryUseMaxMin[xmax];
 
345
//         if ( flow->x_min_id>=0 ) flow->boundary ( flow->x_min_id ).useMaxMin = boundaryUseMaxMin[xmin];
 
346
//         if ( flow->z_max_id>=0 ) flow->boundary ( flow->z_max_id ).useMaxMin = boundaryUseMaxMin[zmax];
 
347
//         if ( flow->z_min_id>=0 ) flow->boundary ( flow->z_min_id ).useMaxMin = boundaryUseMaxMin[zmin];
 
348
 
359
349
        flow->Corner_min = CGT::Point ( flow->x_min, flow->y_min, flow->z_min );
360
350
        flow->Corner_max = CGT::Point ( flow->x_max, flow->y_max, flow->z_max );
361
 
 
362
 
        if ( Debug ) {
363
 
                cout << "Section area = " << flow->SectionArea << endl;
364
 
                cout << "Vtotale = " << flow->Vtotale << endl;
365
 
                cout << "x_min = " << flow->x_min << endl;
366
 
                cout << "x_max = " << flow->x_max << endl;
367
 
                cout << "y_max = " << flow->y_max << endl;
368
 
                cout << "y_min = " << flow->y_min << endl;
369
 
                cout << "z_min = " << flow->z_min << endl;
370
 
                cout << "z_max = " << flow->z_max << endl;
371
 
                cout << endl << "Adding Boundary------" << endl;
372
 
        }
 
351
 
373
352
        //assign BCs types and values
374
353
        BoundaryConditions ( flow );
375
354
 
377
356
        for ( int i=0; i<6; i++ ) {
378
357
                if ( *flow->boundsIds[i]<0 ) continue;
379
358
                CGT::Vecteur Normal ( normal[i].x(), normal[i].y(), normal[i].z() );
380
 
                if ( flow->boundary ( *flow->boundsIds[i] ).useMaxMin ) flow->AddBoundingPlane ( true, Normal, *flow->boundsIds[i] );
 
359
                if ( flow->boundary ( *flow->boundsIds[i] ).useMaxMin ) flow->AddBoundingPlane(Normal, *flow->boundsIds[i] );
381
360
                else {
382
361
                        for ( int h=0;h<3;h++ ) center[h] = buffer[*flow->boundsIds[i]].pos[h];
 
362
//                      cerr << "id="<<*flow->boundsIds[i] <<" center="<<center[0]<<","<<center[1]<<","<<center[2]<<endl;
383
363
                        flow->AddBoundingPlane ( center, wall_thickness, Normal,*flow->boundsIds[i] );
384
364
                }
385
365
        }
415
395
        typedef typename Solver::element_type Flow;
416
396
        typedef typename Flow::Finite_vertices_iterator Finite_vertices_iterator;
417
397
        typedef typename Solver::element_type Flow;
418
 
        typedef typename Flow::Finite_cells_iterator Finite_cells_iterator;
419
398
        
420
399
        Finite_vertices_iterator vertices_end = flow->T[flow->currentTes].Triangulation().finite_vertices_end();
421
400
        CGT::Vecteur Zero(0,0,0);
431
410
                        case ( 3 ) : cell->info().volume() = Volume_cell_triple_fictious ( cell ); break;
432
411
                        default: break; 
433
412
                }
434
 
 
435
413
                if (flow->fluidBulkModulus>0) { cell->info().invVoidVolume() = 1 / ( abs(cell->info().volume()) - flow->volumeSolidPore(cell) ); }
436
414
        }
437
415
        if (Debug) cout << "Volumes initialised." << endl;
493
471
                dVol=cell->info().volumeSign* ( newVol - cell->info().volume() );
494
472
                cell->info().dv() = dVol*invDeltaT;
495
473
                cell->info().volume() = newVol;
496
 
                if (EpsVolPercent_RTRG>0) { //if the criterion is not used, then we skip these updates a save a LOT of time when Nthreads > 1
 
474
                if (defTolerance>0) { //if the criterion is not used, then we skip these updates a save a LOT of time when Nthreads > 1
497
475
                        #pragma omp atomic
498
476
                        totVol+=newVol;
499
477
                        #pragma omp atomic
500
478
                        totDVol+=abs(dVol);}
501
479
        }
502
 
        if (EpsVolPercent_RTRG>0)  eps_vol_max = totDVol/totVol;
 
480
        if (defTolerance>0)  eps_vol_max = totDVol/totVol;
503
481
        for (unsigned int n=0; n<flow->imposedF.size();n++) {
504
482
                flow->IFCells[n]->info().dv()+=flow->imposedF[n].second;
505
483
                flow->IFCells[n]->info().Pcondition=false;}
508
486
template<class Cellhandle>
509
487
Real FlowEngine::Volume_cell_single_fictious ( Cellhandle cell )
510
488
{
511
 
        #if 0
512
 
        //Without buffer
513
 
        Vector3r V[3];
514
 
        int b=0;
515
 
        int w=0;
516
 
        cell->info().volumeSign=1;
517
 
        Real Wall_coordinate=0;
518
 
 
519
 
        for ( int y=0;y<4;y++ ) {
520
 
                if ( ! ( cell->vertex ( y )->info().isFictious ) ) {
521
 
                        const shared_ptr<Body>& sph = Body::byId ( cell->vertex ( y )->info().id(), scene );
522
 
                        V[w]=sph->state->pos;
523
 
                        w++;
524
 
                } else {
525
 
                        b = cell->vertex ( y )->info().id();
526
 
                        const shared_ptr<Body>& wll = Body::byId ( b , scene );
527
 
                        if ( !solver->boundary ( b ).useMaxMin ) Wall_coordinate = wll->state->pos[solver->boundary ( b ).coordinate]+ ( solver->boundary ( b ).normal[solver->boundary ( b ).coordinate] ) *wall_thickness/2;
528
 
                        else Wall_coordinate = solver->boundary ( b ).p[solver->boundary ( b ).coordinate];
529
 
                }
530
 
        }
531
 
        Real Volume = 0.5* ( ( V[0]-V[1] ).cross ( V[0]-V[2] ) ) [solver->boundary ( b ).coordinate] * ( 0.33333333333* ( V[0][solver->boundary ( b ).coordinate]+ V[1][solver->boundary ( b ).coordinate]+ V[2][solver->boundary ( b ).coordinate] ) - Wall_coordinate );
532
 
        #else
533
 
        //With buffer
534
 
        Vector3r V[3];
535
 
        int b=0;
536
 
        int w=0;
537
 
        cell->info().volumeSign=1;
538
 
        Real Wall_coordinate=0;
539
 
 
540
 
        for ( int y=0;y<4;y++ ) {
541
 
                if ( ! ( cell->vertex ( y )->info().isFictious ) ) {
542
 
//                         const shared_ptr<Body>& sph = Body::byId ( cell->vertex ( y )->info().id(), scene );
 
489
        Vector3r V[3];
 
490
        int b=0;
 
491
        int w=0;
 
492
        cell->info().volumeSign=1;
 
493
        Real Wall_coordinate=0;
 
494
 
 
495
        for ( int y=0;y<4;y++ ) {
 
496
                if ( ! ( cell->vertex ( y )->info().isFictious ) ) {
543
497
                        V[w]=positionBufferCurrent[cell->vertex ( y )->info().id()].pos;
544
498
                        w++;
545
499
                } else {
550
504
                }
551
505
        }
552
506
        Real Volume = 0.5* ( ( V[0]-V[1] ).cross ( V[0]-V[2] ) ) [solver->boundary ( b ).coordinate] * ( 0.33333333333* ( V[0][solver->boundary ( b ).coordinate]+ V[1][solver->boundary ( b ).coordinate]+ V[2][solver->boundary ( b ).coordinate] ) - Wall_coordinate );
553
 
        #endif
554
 
 
555
507
        return abs ( Volume );
556
508
}
557
509
template<class Cellhandle>
570
522
                if ( cell->vertex ( g )->info().isFictious ) {
571
523
                        b[j] = cell->vertex ( g )->info().id();
572
524
                        coord[j]=solver->boundary ( b[j] ).coordinate;
573
 
//                         const shared_ptr<Body>& wll = Body::byId ( b[j] , scene );
574
525
                        if ( !solver->boundary ( b[j] ).useMaxMin ) Wall_coordinate[j] = positionBufferCurrent[b[j]].pos[coord[j]] + ( solver->boundary ( b[j] ).normal[coord[j]] ) *wall_thickness/2;
575
526
                        else Wall_coordinate[j] = solver->boundary ( b[j] ).p[coord[j]];
576
527
                        j++;
577
528
                } else if ( first_sph ) {
578
 
//                         const shared_ptr<Body>& sph1 = Body::byId ( cell->vertex ( g )->info().id(), scene );
579
529
                        A=AS=/*AT=*/ positionBufferCurrent[cell->vertex(g)->info().id()].pos;
580
530
                        first_sph=false;
581
531
                } else {
582
 
//                         const shared_ptr<Body>& sph2 = Body::byId ( cell->vertex ( g )->info().id(), scene );
583
532
                        B=BS=/*BT=*/ positionBufferCurrent[cell->vertex(g)->info().id()].pos;;
584
533
                }
585
534
        }
622
571
Real FlowEngine::Volume_cell ( Cellhandle cell )
623
572
{
624
573
        static const Real inv6 = 1/6.;
625
 
        #if 0
626
 
        //Without buffer
627
 
        const Vector3r& p0 = Body::byId ( cell->vertex ( 0 )->info().id(), scene )->state->pos;
628
 
        const Vector3r& p1 = Body::byId ( cell->vertex ( 1 )->info().id(), scene )->state->pos;
629
 
        const Vector3r& p2 = Body::byId ( cell->vertex ( 2 )->info().id(), scene )->state->pos;
630
 
        const Vector3r& p3 = Body::byId ( cell->vertex ( 3 )->info().id(), scene )->state->pos;
631
 
        #else
632
574
        const Vector3r& p0 = positionBufferCurrent[cell->vertex ( 0 )->info().id()].pos;
633
575
        const Vector3r& p1 = positionBufferCurrent[cell->vertex ( 1 )->info().id()].pos;
634
576
        const Vector3r& p2 = positionBufferCurrent[cell->vertex ( 2 )->info().id()].pos;
635
577
        const Vector3r& p3 = positionBufferCurrent[cell->vertex ( 3 )->info().id()].pos;
636
 
        #endif
637
578
        Real volume = inv6 * ((p0-p1).cross(p0-p2)).dot(p0-p3);
638
579
        if ( ! ( cell->info().volumeSign ) ) cell->info().volumeSign= ( volume>0 ) ?1:-1;
639
580
        return volume;
641
582
template<class Solver>
642
583
void FlowEngine::ComputeViscousForces ( Solver& flow )
643
584
{
644
 
        if (viscousShear || normalLubrication || shearLubrication){
645
 
//   flow->ComputeEdgesSurfaces(); //only done in buildTriangulation
 
585
        if (normalLubrication || shearLubrication || viscousShear){
646
586
                if ( Debug ) cout << "Application of viscous forces" << endl;
647
587
                if ( Debug ) cout << "Number of edges = " << flow.Edge_ids.size() << endl;
648
588
                for ( unsigned int k=0; k<flow.viscousShearForces.size(); k++ ) flow.viscousShearForces[k]=Vector3r::Zero();
653
593
 
654
594
                typedef typename Solver::Tesselation Tesselation;
655
595
                const Tesselation& Tes = flow.T[flow.currentTes];
 
596
                flow.deltaShearVel.clear(); flow.normalV.clear(); flow.deltaNormVel.clear(); flow.surfaceDistance.clear(); flow.onlySpheresInteractions.clear(); flow.normalStressInteraction.clear(); flow.shearStressInteraction.clear();
 
597
 
656
598
 
657
599
                for ( int i=0; i< ( int ) flow.Edge_ids.size(); i++ ) {
658
600
                        const int& id1 = flow.Edge_ids[i].first;
659
601
                        const int& id2 = flow.Edge_ids[i].second;
660
602
                        
661
603
                        int hasFictious= Tes.vertex ( id1 )->info().isFictious +  Tes.vertex ( id2 )->info().isFictious;
662
 
//                      if (hasFictious==2) continue;
663
604
                        if (hasFictious>0 or id1==id2) continue;
664
605
                        const shared_ptr<Body>& sph1 = Body::byId ( id1, scene );
665
606
                        const shared_ptr<Body>& sph2 = Body::byId ( id2, scene );
709
650
                                }
710
651
                        }
711
652
                        deltaShearV = deltaV - ( normal.dot ( deltaV ) ) *normal;
712
 
                        
 
653
                        flow.deltaShearVel.push_back(deltaShearV);
 
654
                        flow.normalV.push_back(normal);
 
655
                        flow.surfaceDistance.push_back(max(surfaceDist, 0.) + eps*meanRad);
 
656
 
713
657
                        if (shearLubrication)
714
658
                                visc_f = flow.computeShearLubricationForce(deltaShearV,surfaceDist,i,eps,O1O2,meanRad);
715
659
                        else if (viscousShear) 
716
660
                                visc_f = flow.computeViscousShearForce ( deltaShearV, i , Rh);
717
 
                
718
 
                if ( Debug ) cout << "la force visqueuse entre " << id1 << " et " << id2 << "est " << visc_f << endl;
719
 
 
720
 
 
 
661
                                
721
662
                        if (viscousShear || shearLubrication){
 
663
 
722
664
                                flow.viscousShearForces[id1]+=visc_f;
723
665
                                flow.viscousShearForces[id2]+=(-visc_f);
724
666
                                flow.viscousShearTorques[id1]+=O1C_vect.cross(visc_f);
725
667
                                flow.viscousShearTorques[id2]+=O2C_vect.cross(-visc_f);
 
668
                        
726
669
                
727
670
                                /// Compute the viscous shear stress on each particle
728
671
                                if (viscousShearBodyStress){
729
672
                                        flow.viscousBodyStress[id1] += visc_f * O1C_vect.transpose()/ (4.0/3.0 *3.14* pow(r1,3));
730
 
                                        flow.viscousBodyStress[id2] += (-visc_f) * O2C_vect.transpose()/ (4.0/3.0 *3.14* pow(r2,3));}
 
673
                                        flow.viscousBodyStress[id2] += (-visc_f) * O2C_vect.transpose()/ (4.0/3.0 *3.14* pow(r2,3));
 
674
                                        flow.shearStressInteraction.push_back(visc_f * O1O2_vect.transpose()/(4.0/3.0 *3.14* pow(r1,3)));
 
675
                                }
731
676
                        }
732
 
                                        
733
 
                                        
734
 
                
 
677
 
735
678
                        /// Compute the normal lubrication force applied on each particle
736
679
                        if (normalLubrication){
737
680
                                deltaNormV = normal.dot(deltaV);
 
681
                                flow.deltaNormVel.push_back(deltaNormV * normal);
738
682
                                lub_f = flow.computeNormalLubricationForce (deltaNormV, surfaceDist, i,eps,stiffness,scene->dt,meanRad)*normal;
739
683
                                flow.normLubForce[id1]+=lub_f;
740
684
                                flow.normLubForce[id2]+=(-lub_f);
742
686
                        /// Compute the normal lubrication stress on each particle
743
687
                                if (viscousNormalBodyStress){
744
688
                                        flow.lubBodyStress[id1] += lub_f * O1C_vect.transpose()/ (4.0/3.0 *3.14* pow(r1,3));
745
 
                                        flow.lubBodyStress[id2] += (-lub_f) *O2C_vect.transpose() / (4.0/3.0 *3.14* pow(r2,3));}
746
 
                        if ( Debug ) cout << "la force normale entre " << id1 << " et " << id2 << "est " << lub_f << endl;
 
689
                                        flow.lubBodyStress[id2] += (-lub_f) *O2C_vect.transpose() / (4.0/3.0 *3.14* pow(r2,3));
 
690
                                        flow.normalStressInteraction.push_back(lub_f * O1O2_vect.transpose()/(4.0/3.0 *3.14* pow(r1,3)));
 
691
                                }
747
692
                        }
748
 
                
 
693
 
 
694
                        if (create_file){
 
695
                          std::ofstream velocity_file("result_velocity.txt",ios::app);
 
696
                          velocity_file << i << "\t" << deltaNormV * normal[0] << "\t" << deltaNormV * normal[1] << "\t" << deltaNormV * normal[2] << "\t" << deltaShearV[0] << "\t" << deltaShearV[1] << "\t" << deltaShearV[2] << "\t" << normal[0] << "\t" << normal[1] << "\t" << normal[2] << "\t" << max(surfaceDist, 0.) + eps*meanRad <<  endl;
 
697
                          velocity_file.close(); }
 
698
                          
 
699
                        if (display_force) cout<<"force tangentielle "<<visc_f<< " force normale "<< lub_f<<endl;
 
700
                        if (!hasFictious)
 
701
                                flow.onlySpheresInteractions.push_back(i);
 
702
                                
749
703
                }
750
 
        
751
 
                if(Debug) cout<<"number of viscousShearForce"<<flow.viscousShearForces.size()<<endl;
752
704
        }
753
705
}
754
706
 
773
725
                Build_Triangulation(P_zero,solver);
774
726
                if (solver->errorCode>0) {LOG_INFO("triangulation error, pausing"); Omega::instance().pause(); return;}
775
727
                Initialize_volumes(solver); backgroundSolver=solver; backgroundCompleted=true;}
776
 
//         if ( first ) {Build_Triangulation ( P_zero ); Update_Triangulation = false; Initialize_volumes();}
 
728
//         if ( first ) {Build_Triangulation ( P_zero ); updateTriangulation = false; Initialize_volumes();}
777
729
        
778
730
        timingDeltas->checkpoint("Triangulating");
779
731
        UpdateVolumes (solver);
780
732
        Eps_Vol_Cumulative += eps_vol_max;
781
 
        if ( (EpsVolPercent_RTRG>0 && Eps_Vol_Cumulative > EpsVolPercent_RTRG) || retriangulationLastIter>PermuteInterval ) {
782
 
                Update_Triangulation = true;
 
733
        if ( (defTolerance>0 && Eps_Vol_Cumulative > defTolerance) || retriangulationLastIter>meshUpdateInterval ) {
 
734
                updateTriangulation = true;
783
735
                Eps_Vol_Cumulative=0;
784
736
                retriangulationLastIter=0;
785
737
                ReTrg++;
786
738
         } else  {
787
 
                Update_Triangulation = false;
 
739
                updateTriangulation = false;
788
740
                retriangulationLastIter++;}
789
741
        timingDeltas->checkpoint("Update_Volumes");
790
742
 
805
757
                assert (Tes.vertexHandles[id] != NULL);
806
758
                const Tesselation::Vertex_Info& v_info = Tes.vertexHandles[id]->info();
807
759
                force =(pressureForce) ? Vector3r ( ( v_info.forces ) [0],v_info.forces[1],v_info.forces[2] ) : Vector3r(0,0,0);
808
 
                if (viscousShear){
 
760
                if (shearLubrication || viscousShear){
809
761
                        force = force +solver->viscousShearForces[v_info.id()];
810
762
                        scene->forces.addTorque ( v_info.id(), solver->viscousShearTorques[v_info.id()]);
811
763
                }
816
768
        ///End Compute flow and forces
817
769
        timingDeltas->checkpoint("Applying Forces");
818
770
        if (multithread && !first) {
819
 
                while (Update_Triangulation && !backgroundCompleted) { /*cout<<"sleeping..."<<sleeping++<<endl;*/       boost::this_thread::sleep(boost::posix_time::microseconds(1000));}
820
 
                if (Update_Triangulation || ellapsedIter>(0.5*PermuteInterval)) {
 
771
                while (updateTriangulation && !backgroundCompleted) { /*cout<<"sleeping..."<<sleeping++<<endl;*/        boost::this_thread::sleep(boost::posix_time::microseconds(1000));}
 
772
                if (updateTriangulation || ellapsedIter>(0.5*meshUpdateInterval)) {
821
773
                        if (useSolver==0) LOG_ERROR("background calculations not available for Gauss-Seidel");
822
774
                        if (fluidBulkModulus>0) solver->Interpolate (solver->T[solver->currentTes], backgroundSolver->T[backgroundSolver->currentTes]);
823
775
                        solver=backgroundSolver;
839
791
                        if (Debug && !backgroundCompleted) cerr<<"still computing solver in the background"<<endl;
840
792
                        ellapsedIter++;}
841
793
        } else {
842
 
                if (Update_Triangulation && !first) {
 
794
                if (updateTriangulation && !first) {
843
795
                        cachedCell= Cell(*(scene->cell));
844
796
                        Build_Triangulation (P_zero, solver);
845
797
                        Initialize_volumes(solver);
846
798
                        ComputeViscousForces(*solver);
847
 
                        Update_Triangulation = false;}
 
799
                        updateTriangulation = false;}
848
800
        }
849
801
        first=false;
850
802
        timingDeltas->checkpoint("Ending");
995
947
                //call recursively, since the returned cell could be also a ghost (especially if baseCell is a non-periodic type from the external contour
996
948
                locateCell ( ch,index,baseIndex,flow,++count );
997
949
                if ( ch==baseCell ) cerr<<"WTF!!"<<endl;
 
950
                //check consistency
 
951
                bool checkC=false;
 
952
                for (int kk=0; kk<4;kk++) if ((!baseCell->vertex(kk)->info().isGhost) && ((!baseCell->vertex(kk)->info().isFictious))) checkC = true;
 
953
                if (checkC) {
 
954
                        bool checkV=true;
 
955
                        for (int kk=0; kk<4;kk++) {
 
956
                                checkV=false;
 
957
                                for (int jj=0; jj<4;jj++)
 
958
                                        if (baseCell->vertex(kk)->info().id() == ch->vertex(jj)->info().id()) checkV = true;
 
959
                                if (!checkV) {cerr <<"periodicity is broken"<<endl;
 
960
                                for (int jj=0; jj<4;jj++) cerr<<baseCell->vertex(jj)->info().id()<<" ";
 
961
                                cerr<<" vs. ";
 
962
                                for (int jj=0; jj<4;jj++) cerr<<ch->vertex(jj)->info().id()<<" ";
 
963
                                cerr<<endl;}
 
964
                        }
 
965
                } else {
 
966
//                      bool checkV=true;
 
967
//                      for (int kk=0; kk<4;kk++) {
 
968
//                              checkV=false;
 
969
//                              for (int jj=0; jj<4;jj++)
 
970
//                                      if (baseCell->vertex(kk)->info().id() == ch->vertex(jj)->info().id()) checkV = true;
 
971
//                              if (!checkV) {cerr <<"periodicity is broken (that's ok probably)"<<endl;
 
972
//                              for (int jj=0; jj<4;jj++) cerr<<baseCell->vertex(jj)->info().id()<<" ";
 
973
//                              cerr<<" vs. ";
 
974
//                              for (int jj=0; jj<4;jj++) cerr<<ch->vertex(jj)->info().id()<<" ";
 
975
//                              cerr<<endl;}
 
976
//                      }
 
977
                }
 
978
 
998
979
                base_info.isGhost=true;
999
980
                base_info._pression=& ( ch->info().p() );
1000
981
                base_info.index=ch->info().index;
1129
1110
        if ( !first && !multithread && (useSolver==0 || fluidBulkModulus>0)) flow->Interpolate ( flow->T[!flow->currentTes], Tes );
1130
1111
//      if ( !first && (useSolver==0 || fluidBulkModulus>0)) flow->Interpolate ( flow->T[!flow->currentTes], flow->T[flow->currentTes] );
1131
1112
        
1132
 
        if ( WaveAction ) flow->ApplySinusoidalPressure ( Tes.Triangulation(), Sinus_Amplitude, Sinus_Average, 30 );
1133
 
        if ( viscousShear || normalLubrication || shearLubrication) flow->computeEdgesSurfaces();
 
1113
        if ( WaveAction ) flow->ApplySinusoidalPressure ( Tes.Triangulation(), sineMagnitude, sineAverage, 30 );
 
1114
 
 
1115
        if (normalLubrication || shearLubrication || viscousShear) flow->computeEdgesSurfaces();
1134
1116
        if ( Debug ) cout << endl << "end buildTri------" << endl << endl;
1135
1117
}
1136
1118