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

« back to all changes in this revision

Viewing changes to pkg/dem/FlowEngine.hpp

  • 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:
51
51
 
52
52
        public :
53
53
                int retriangulationLastIter;
54
 
                enum {wall_left=0, wall_right, wall_bottom, wall_top, wall_back, wall_front};
 
54
                enum {wall_xmin, wall_xmax, wall_ymin, wall_ymax, wall_zmin, wall_zmax};
55
55
                Vector3r normal [6];
56
56
                bool currentTes;
57
57
                int id_offset;
59
59
                int ReTrg;
60
60
                int ellapsedIter;
61
61
                TPL void initSolver (Solver& flow);
 
62
                #ifdef LINSOLV
 
63
                TPL void setForceMetis (Solver& flow, bool force);
 
64
                TPL bool getForceMetis (Solver& flow);
 
65
                #endif
62
66
                TPL void Triangulate (Solver& flow);
63
67
                TPL void AddBoundary (Solver& flow);
64
68
                TPL void Build_Triangulation (double P_zero, Solver& flow);
91
95
                        return (flow->viscousBodyStress.size()>id_sph)?flow->viscousBodyStress[id_sph]:Matrix3r::Zero();}
92
96
                TPL Matrix3r bodyNormalLubStress(unsigned int id_sph, Solver& flow) {
93
97
                        return (flow->lubBodyStress.size()>id_sph)?flow->lubBodyStress[id_sph]:Matrix3r::Zero();}
 
98
                TPL Vector3r shearVelocity(unsigned int interaction, Solver& flow) {
 
99
                        return (flow->deltaShearVel[interaction]);}
 
100
                TPL Vector3r normalVelocity(unsigned int interaction, Solver& flow) {
 
101
                        return (flow->deltaNormVel[interaction]);}
 
102
                TPL Matrix3r normalStressInteraction(unsigned int interaction, Solver& flow) {
 
103
                        return (flow->normalStressInteraction[interaction]);}
 
104
                TPL Matrix3r shearStressInteraction(unsigned int interaction, Solver& flow) {
 
105
                        return (flow->shearStressInteraction[interaction]);}
 
106
                TPL Vector3r normalVect(unsigned int interaction, Solver& flow) {
 
107
                        return (flow->normalV[interaction]);}
 
108
                TPL Real surfaceDistanceParticle(unsigned int interaction, Solver& flow) {
 
109
                        return (flow->surfaceDistance[interaction]);}
 
110
                TPL Real edgeSize(Solver& flow) {
 
111
                        return (flow->Edge_ids.size());}
 
112
                TPL Real OSI(Solver& flow) {
 
113
                        return (flow->onlySpheresInteractions.size());}
 
114
                TPL int onlySpheresInteractions(unsigned int interaction, Solver& flow) {
 
115
                        return (flow->onlySpheresInteractions[interaction]);}
94
116
                TPL python::list getConstrictions(bool all, Solver& flow) {
95
117
                        vector<Real> csd=flow->getConstrictions(); python::list pycsd;
96
118
                        for (unsigned int k=0;k<csd.size();k++) if ((all && csd[k]!=0) || csd[k]>0) pycsd.append(csd[k]); return pycsd;}
118
140
                void Oedometer_Boundary_Conditions();
119
141
                void Average_real_cell_velocity();
120
142
                void saveVtk() {solver->saveVtk();}
121
 
                vector<Real> AvFlVelOnSph(unsigned int id_sph) {return solver->Average_Fluid_Velocity_On_Sphere(id_sph);}
 
143
                vector<Real> avFlVelOnSph(unsigned int id_sph) {return solver->Average_Fluid_Velocity_On_Sphere(id_sph);}
122
144
 
123
 
                void setBoundaryVel(Vector3r vel) {topBoundaryVelocity=vel; Update_Triangulation=true;}
124
 
                void PressureProfile(double wallUpY, double wallDownY) {return solver->MeasurePressureProfile(wallUpY,wallDownY);}
125
 
                double MeasurePorePressure(Vector3r pos){return solver->MeasurePorePressure(pos[0], pos[1], pos[2]);}
 
145
//              void setBoundaryVel(Vector3r vel) {topBoundaryVelocity=vel; updateTriangulation=true;}
 
146
                void pressureProfile(double wallUpY, double wallDownY) {return solver->measurePressureProfile(wallUpY,wallDownY);}
 
147
                double getPorePressure(Vector3r pos){return solver->getPorePressure(pos[0], pos[1], pos[2]);}
126
148
                TPL int getCell(double posX, double posY, double posZ, Solver& flow){return flow->getCell(posX, posY, posZ);}
127
 
                double MeasureAveragedPressure(double posY){return solver->MeasureAveragedPressure(posY);}
128
 
                double MeasureTotalAveragedPressure(){return solver->MeasureTotalAveragedPressure();}
 
149
                double averageSlicePressure(double posY){return solver->averageSlicePressure(posY);}
 
150
                double averagePressure(){return solver->averagePressure();}
129
151
                #ifdef LINSOLV
130
152
                TPL void exportMatrix(string filename,Solver& flow) {if (useSolver==3) flow->exportMatrix(filename.c_str());
131
153
                        else cerr<<"available for Cholmod solver (useSolver==3)"<<endl;}
143
165
                Matrix3r        _bodyShearLubStress(unsigned int id_sph) {return bodyShearLubStress(id_sph,solver);}
144
166
                Matrix3r        _bodyNormalLubStress(unsigned int id_sph) {return bodyNormalLubStress(id_sph,solver);}
145
167
                Vector3r        _fluidForce(unsigned int id_sph) {return fluidForce(id_sph,solver);}
 
168
                Vector3r        _shearVelocity(unsigned int interaction) {return shearVelocity(interaction,solver);}
 
169
                Vector3r        _normalVelocity(unsigned int interaction) {return normalVelocity(interaction,solver);}
 
170
                Matrix3r        _normalStressInteraction(unsigned int interaction) {return normalStressInteraction(interaction,solver);}
 
171
                Matrix3r        _shearStressInteraction(unsigned int interaction) {return shearStressInteraction(interaction,solver);}
 
172
                Vector3r        _normalVect(unsigned int interaction) {return normalVect(interaction,solver);}
 
173
                Real            _surfaceDistanceParticle(unsigned int interaction) {return surfaceDistanceParticle(interaction,solver);}
 
174
                int             _onlySpheresInteractions(unsigned int interaction) {return onlySpheresInteractions(interaction,solver);}
146
175
                void            _imposeFlux(Vector3r pos, Real flux) {return imposeFlux(pos,flux,*solver);}
147
176
                unsigned int    _imposePressure(Vector3r pos, Real p) {return imposePressure(pos,p,solver);}    
148
177
                void            _setImposedPressure(unsigned int cond, Real p) {setImposedPressure(cond,p,solver);}
155
184
                #ifdef LINSOLV
156
185
                void            _exportMatrix(string filename) {exportMatrix(filename,solver);}
157
186
                void            _exportTriplets(string filename) {exportTriplets(filename,solver);}
 
187
                void            _setForceMetis (bool force) {setForceMetis(solver,force);}
 
188
                bool            _getForceMetis () {return getForceMetis (solver);}
 
189
                void            cholmodStats() {
 
190
                                        cerr << cholmod_print_common("PFV Cholmod factorization",&(solver->eSolver.cholmod()))<<endl;
 
191
                                        cerr << "cholmod method:" << solver->eSolver.cholmod().selected<<endl;
 
192
                                        cerr << "METIS called:"<<solver->eSolver.cholmod().called_nd<<endl;}
 
193
                bool            metisUsed() {return bool(solver->eSolver.cholmod().called_nd);}
158
194
                #endif
159
195
                python::list    _getConstrictions(bool all) {return getConstrictions(all,solver);}
160
196
                python::list    _getConstrictionsFull(bool all) {return getConstrictionsFull(all,solver);}
164
200
                virtual void action();
165
201
                virtual void backgroundAction();
166
202
 
167
 
                YADE_CLASS_BASE_DOC_ATTRS_DEPREC_INIT_CTOR_PY(FlowEngine,PartialEngine,"An engine to solve flow problem in saturated granular media.\n\n.. note::\n\t Multi-threading seems to work fine for Cholesky decomposition, but it fails for the solve phase in which -j1 is the fastest, here we specify thread numbers independently using :yref:`FlowEngine::numFactorizeThreads` and :yref:`FlowEngine::numSolveThreads`. These multhreading settings are only impacting the behaviour of openblas library and are relatively independant of :yref:`FlowEngine::multithread`. However, the settings have to be globally consistent. For instance, :yref:`FlowEngine::multithread`=True with  multithread :yref:`FlowEngine::numSolveThreads`=:yref:`FlowEngine::numFactorizeThreads`=4 means that openblas will mobilize 8 processors at some point, if the system doesn't have so many procs. it will hurt performance.",
 
203
                YADE_CLASS_BASE_DOC_ATTRS_DEPREC_INIT_CTOR_PY(FlowEngine,PartialEngine,"An engine to solve flow problem in saturated granular media. Model description can be found in [Chareyre2012a]_ and [Catalano2013a]_. See the example script FluidCouplingPFV/oedometer.py. More documentation to come.\n\n.. note::Multi-threading seems to work fine for Cholesky decomposition, but it fails for the solve phase in which -j1 is the fastest, here we specify thread numbers independently using :yref:`FlowEngine::numFactorizeThreads` and :yref:`FlowEngine::numSolveThreads`. These multhreading settings are only impacting the behaviour of openblas library and are relatively independant of :yref:`FlowEngine::multithread`. However, the settings have to be globally consistent. For instance, :yref:`multithread<FlowEngine::multithread>` =True with  yref:`numFactorizeThreads<FlowEngine::numFactorizeThreads>` = yref:`numSolveThreads<FlowEngine::numSolveThreads>` = 4 implies that openblas will mobilize 8 processors at some point. If the system does not have so many procs. it will hurt performance.",
168
204
                                        ((bool,isActivated,true,,"Activates Flow Engine"))
169
205
                                        ((bool,first,true,,"Controls the initialization/update phases"))
170
206
                                        ((double, fluidBulkModulus, 0.,,"Bulk modulus of fluid (inverse of compressibility) K=-dP*V/dV [Pa]. Flow is compressible if fluidBulkModulus > 0, else incompressible."))
171
207
                                        ((Real, dt, 0,,"timestep [s]"))
172
 
//                                      ((bool,save_vtk,false,,"Enable/disable vtk files creation for visualization"))
173
208
                                        ((bool,permeability_map,false,,"Enable/disable stocking of average permeability scalar in cell infos."))
174
 
                                        ((bool, save_mgpost, false,,"Enable/disable mgpost file creation"))
175
 
                                        ((bool, slice_pressures, false, ,"Enable/Disable slice pressure measurement"))
176
 
                                        ((bool, velocity_profile, false, ,"Enable/Disable slice velocity measurement"))
177
 
                                        ((bool, consolidation,false,,"Enable/Disable storing consolidation files"))
178
209
                                        ((bool, slip_boundary, true,, "Controls friction condition on lateral walls"))
179
210
                                        ((bool,WaveAction, false,, "Allow sinusoidal pressure condition to simulate ocean waves"))
180
 
                                        ((double, Sinus_Amplitude, 0,, "Pressure value (amplitude) when sinusoidal pressure is applied"))
181
 
                                        ((double, Sinus_Average, 0,,"Pressure value (average) when sinusoidal pressure is applied"))
182
 
                                        ((bool, CachedForces, true,,"Des/Activate the cached forces calculation"))
 
211
                                        ((double, sineMagnitude, 0,, "Pressure value (amplitude) when sinusoidal pressure is applied (p )"))
 
212
                                        ((double, sineAverage, 0,,"Pressure value (average) when sinusoidal pressure is applied"))
183
213
                                        ((bool, Debug, false,,"Activate debug messages"))
184
214
                                        ((double, wall_thickness,0.001,,"Walls thickness"))
185
 
                                        ((double,P_zero,0,,"Initial internal pressure for oedometer test"))
 
215
                                        ((double,P_zero,0,,"The value used for initializing pore pressure. It is useless for incompressible fluid, but important for compressible model."))
186
216
                                        ((double,Tolerance,1e-06,,"Gauss-Seidel Tolerance"))
187
217
                                        ((double,Relax,1.9,,"Gauss-Seidel relaxation"))
188
 
                                        ((bool, Update_Triangulation, 0,,"If true the medium is retriangulated. Can be switched on to force retriangulation after some events (else it will be true periodicaly based on :yref:`FlowEngine::EpsVolPercent_RTRG` and :yref:`FlowEngine::PermuteInterval`"))
189
 
                                        ((int,PermuteInterval,1000,,"Maximum number of timesteps between re-triangulation events. See also :yref:`FlowEngine::EpsVolPercent_RTRG`."))
190
 
                                        ((double, eps_vol_max, 0,,"Maximal absolute volumetric strain computed at each iteration"))
191
 
                                        ((double, EpsVolPercent_RTRG,0.01,,"Percentuage of cumulate eps_vol at which retriangulation of pore space is performed"))
192
 
                                        ((double, porosity, 0,,"Porosity computed at each retriangulation"))
193
 
                                        ((bool,compute_K,false,,"Activates permeability measure within a granular sample"))
194
 
                                        ((bool,meanKStat,false,,"Local permeabilities' correction through an optimized threshold"))
195
 
                                        ((bool,clampKValues,true,,"If true, clamp local permeabilities between min/max*globalK threshold. This clamping can avoid singular values in the permeability matrix and may reduce numerical errors in the solve phase. It will also hide junk values if they exist, or bias all values in very heterogeneous problems. So, use this with care."))
 
218
                                        ((bool, updateTriangulation, 0,,"If true the medium is retriangulated. Can be switched on to force retriangulation after some events (else it will be true periodicaly based on :yref:`FlowEngine::defTolerance` and :yref:`FlowEngine::meshUpdateInterval`. Of course, it costs CPU time."))
 
219
                                        ((int,meshUpdateInterval,1000,,"Maximum number of timesteps between re-triangulation events. See also :yref:`FlowEngine::defTolerance`."))
 
220
                                        ((double, eps_vol_max, 0,(Attr::readonly),"Maximal absolute volumetric strain computed at each iteration. |yupdate|"))
 
221
                                        ((double, defTolerance,0.05,,"Cumulated deformation threshold for which retriangulation of pore space is performed. If negative, the triangulation update will occure with a fixed frequency on the basis of :yref:`FlowEngine::meshUpdateInterval`"))
 
222
                                        ((double, porosity, 0,(Attr::readonly),"Porosity computed at each retriangulation |yupdate|"))
 
223
                                        ((bool,meanKStat,false,,"report the local permeabilities' correction"))
 
224
                                        ((bool,clampKValues,true,,"If true, clamp local permeabilities in [minKdivKmean,maxKdivKmean]*globalK. This clamping can avoid singular values in the permeability matrix and may reduce numerical errors in the solve phase. It will also hide junk values if they exist, or bias all values in very heterogeneous problems. So, use this with care."))
196
225
                                        ((Real,minKdivKmean,0.0001,,"define the min K value (see :yref:`FlowEngine::clampKValues`)"))
197
226
                                        ((Real,maxKdivKmean,100,,"define the max K value (see :yref:`FlowEngine::clampKValues`)"))
198
 
                                        ((double,permeability_factor,0.0,,"permability multiplier"))
199
 
                                        ((double,viscosity,1.0,,"viscosity of fluid"))
200
 
                                        ((double,stiffness, 10000,,"stiffness modulus"))
201
 
                                        ((Real,loadFactor,1.1,,"Load multiplicator for oedometer test"))
202
 
                                        ((double, K, 0,, "Permeability of the sample"))
 
227
                                        ((double,permeabilityFactor,1.0,,"permability multiplier"))
 
228
                                        ((double,viscosity,1.0,,"viscosity of the fluid"))
 
229
                                        ((double,stiffness, 10000,,"equivalent contact stiffness used in the lubrication model"))
203
230
                                        ((int, useSolver, 0,, "Solver to use 0=G-Seidel, 1=Taucs, 2-Pardiso, 3-CHOLMOD"))
204
 
//                                      ((std::string,key,"",,"A string appended at the output files, use it to name simulations."))
205
 
                                        ((double, V_d, 0,,"darcy velocity of fluid in sample"))
206
 
                                        ((bool, Flow_imposed_TOP_Boundary, true,, "if false involve pressure imposed condition"))
207
 
                                        ((bool, Flow_imposed_BOTTOM_Boundary, true,, "if false involve pressure imposed condition"))
208
 
                                        ((bool, Flow_imposed_FRONT_Boundary, true,, "if false involve pressure imposed condition"))
209
 
                                        ((bool, Flow_imposed_BACK_Boundary, true,, "if false involve pressure imposed condition"))
210
 
                                        ((bool, Flow_imposed_LEFT_Boundary, true,, "if false involve pressure imposed condition"))
211
 
                                        ((bool, Flow_imposed_RIGHT_Boundary, true,,"if false involve pressure imposed condition"))
212
 
                                        ((double, Pressure_TOP_Boundary, 0,, "Pressure imposed on top boundary"))
213
 
                                        ((double, Pressure_BOTTOM_Boundary,  0,, "Pressure imposed on bottom boundary"))
214
 
                                        ((double, Pressure_FRONT_Boundary,  0,, "Pressure imposed on front boundary"))
215
 
                                        ((double, Pressure_BACK_Boundary,  0,,"Pressure imposed on back boundary"))
216
 
                                        ((double, Pressure_LEFT_Boundary,  0,, "Pressure imposed on left boundary"))
217
 
                                        ((double, Pressure_RIGHT_Boundary,  0,, "Pressure imposed on right boundary"))
218
 
                                        ((Vector3r, topBoundaryVelocity, Vector3r::Zero(),, "velocity on top boundary, only change it using :yref:`FlowEngine::setBoundaryVel`"))
 
231
                                        ((int, xmin,0,(Attr::readonly),"Index of the boundary $x_{min}$. This index is not equal the the id of the corresponding body in general, it may be used to access the corresponding attributes (e.g. flow.bndCondValue[flow.xmin], flow.wallId[flow.xmin],...)."))
 
232
                                        ((int, xmax,1,(Attr::readonly),"See :yref:`FlowEngine::xmin`."))
 
233
                                        ((int, ymin,2,(Attr::readonly),"See :yref:`FlowEngine::xmin`."))
 
234
                                        ((int, ymax,3,(Attr::readonly),"See :yref:`FlowEngine::xmin`."))
 
235
                                        ((int, zmin,4,(Attr::readonly),"See :yref:`FlowEngine::xmin`."))
 
236
                                        ((int, zmax,5,(Attr::readonly),"See :yref:`FlowEngine::xmin`."))
 
237
 
 
238
                                        ((vector<bool>, bndCondIsPressure, vector<bool>(6,false),,"defines the type of boundary condition for each side. True if pressure is imposed, False for no-flux. Indexes can be retrieved with :yref:`FlowEngine::xmin` and friends."))
 
239
                                        ((vector<double>, bndCondValue, vector<double>(6,0),,"Imposed value of a boundary condition. Only applies if the boundary condition is imposed pressure, else the imposed flux is always zero presently (may be generalized to non-zero imposed fluxes in the future)."))
 
240
                                        //FIXME: to be implemented:
 
241
                                        ((vector<Vector3r>, boundaryVelocity, vector<Vector3r>(6,Vector3r::Zero()),, "velocity on top boundary, only change it using :yref:`FlowEngine::setBoundaryVel`"))
219
242
                                        ((int, ignoredBody,-1,,"Id of a sphere to exclude from the triangulation.)"))
220
 
                                        ((int, wallTopId,3,,"Id of top boundary (default value is ok if aabbWalls are appended BEFORE spheres.)"))
221
 
                                        ((int, wallBottomId,2,,"Id of bottom boundary (default value is ok if aabbWalls are appended BEFORE spheres.)"))
222
 
                                        ((int, wallFrontId,5,,"Id of front boundary (default value is ok if aabbWalls are appended BEFORE spheres.)"))
223
 
                                        ((int, wallBackId,4,,"Id of back boundary (default value is ok if aabbWalls are appended BEFORE spheres.)"))
224
 
                                        ((int, wallLeftId,0,,"Id of left boundary (default value is ok if aabbWalls are appended BEFORE spheres.)"))
225
 
                                        ((int, wallRightId,1,,"Id of right boundary (default value is ok if aabbWalls are appended BEFORE spheres.)"))
226
 
                                        ((bool, BOTTOM_Boundary_MaxMin, 1,,"If true (default value) bounding sphere is added as function of max/min sphere coord, if false as function of yade wall position"))
227
 
                                        ((bool, TOP_Boundary_MaxMin, 1,,"If true (default value) bounding sphere is added as function of max/min sphere coord, if false as function of yade wall position"))
228
 
                                        ((bool, RIGHT_Boundary_MaxMin, 1,,"If true (default value) bounding sphere is added as function of max/min sphere coord, if false as function of yade wall position"))
229
 
                                        ((bool, LEFT_Boundary_MaxMin, 1,,"If true (default value) bounding sphere is added as function of max/min sphere coord, if false as function of yade wall position"))
230
 
                                        ((bool, FRONT_Boundary_MaxMin, 1,,"If true (default value) bounding sphere is added as function of max/min sphere coord, if false as function of yade wall position"))
231
 
                                        ((bool, BACK_Boundary_MaxMin, 1,,"If true (default value) bounding sphere is added as function of max/min sphere coord, if false as function of yade wall position"))
232
 
                                        ((bool, areaR2Permeability, 1,,"Use corrected formula for permeabilities calculation in flowboundingsphere (areaR2permeability variable)"))
233
 
                                        ((bool, viscousShear, false,,"Compute viscous shear terms as developped by Donia Marzougui"))
234
 
                                        ((bool, shearLubrication, false,,"Compute shear lubrication force as developped by Brule"))
235
 
                                        ((double, eps, 0.00001,,"minimum distance between particles"))
 
243
                                        ((vector<int>, wallIds,vector<int>(6),,"body ids of the boundaries (default values are ok only if aabbWalls are appended before spheres, i.e. numbered 0,...,5)"))
 
244
                                        ((vector<bool>, boundaryUseMaxMin, vector<bool>(6,true),,"If true (default value) bounding sphere is added as function of max/min sphere coord, if false as function of yade wall position"))
 
245
                                        ((bool, display_force, false,,"display the lubrication force applied on particles"))
 
246
                                        ((bool, create_file, false,,"create file of velocities"))
 
247
                                        ((bool, viscousShear, false,,"Compute viscous shear terms as developped by Donia Marzougui (FIXME: ref.)"))
 
248
                                        ((bool, shearLubrication, false,,"Compute shear lubrication force as developped by Brule (FIXME: ref.) "))
 
249
                                        ((double, eps, 0.00001,,"roughness defined as a fraction of particles size, giving the minimum distance between particles in the lubrication model."))
236
250
                                        ((bool, pressureForce, true,,"Compute the pressure field and associated fluid forces. WARNING: turning off means fluid flow is not computed at all."))
237
 
 
238
251
                                        ((bool, normalLubrication, false,,"Compute normal lubrication force as developped by Brule"))
239
252
                                        ((bool, viscousNormalBodyStress, false,,"Compute normal viscous stress applied on each body"))
240
253
                                        ((bool, viscousShearBodyStress, false,,"Compute shear viscous stress applied on each body"))
242
255
                                        #ifdef EIGENSPARSE_LIB
243
256
                                        ((int, numSolveThreads, 1,,"number of openblas threads in the solve phase."))
244
257
                                        ((int, numFactorizeThreads, 1,,"number of openblas threads in the factorization phase"))
 
258
//                                      ((bool, forceMetis, 0,,"If true, METIS is used for matrix preconditioning, else Cholmod is free to choose the best method (which may be METIS to, depending on the matrix). See ``nmethods`` in Cholmod documentation"))
245
259
                                        #endif
246
 
                                        ((Real, allDeprecs, 0,,"transitory variable: point removed attributes to this so that older scripts won't crash."))
247
260
                                        ,
248
261
                                        /*deprec*/
249
262
                                        ((meanK_opt,clampKValues,"the name changed"))
250
 
                                        ((meanK_correction,allDeprecs,"the name changed"))
251
263
                                        ,,
252
264
                                        timingDeltas=shared_ptr<TimingDeltas>(new TimingDeltas);
253
 
                                        for (int i=0; i<6; ++i){normal[i]=Vector3r::Zero();}
254
 
                                        normal[wall_bottom].y()=normal[wall_left].x()=normal[wall_back].z()=1;
255
 
                                        normal[wall_top].y()=normal[wall_right].x()=normal[wall_front].z()=-1;                                  
 
265
                                        for (int i=0; i<6; ++i){normal[i]=Vector3r::Zero(); wallIds[i]=i;}
 
266
                                        normal[wall_ymin].y()=normal[wall_xmin].x()=normal[wall_zmin].z()=1;
 
267
                                        normal[wall_ymax].y()=normal[wall_xmax].x()=normal[wall_zmax].z()=-1;
256
268
                                        solver = shared_ptr<FlowSolver> (new FlowSolver);
257
269
                                        first=true;
258
 
                                        Update_Triangulation=false;
 
270
                                        updateTriangulation=false;
259
271
                                        eps_vol_max=Eps_Vol_Cumulative=retriangulationLastIter=0;
260
272
                                        ReTrg=1;
261
273
                                        backgroundCompleted=true;
267
279
                                        .def("clearImposedPressure",&FlowEngine::_clearImposedPressure,"Clear the list of points with pressure imposed.")
268
280
                                        .def("clearImposedFlux",&FlowEngine::_clearImposedFlux,"Clear the list of points with flux imposed.")
269
281
                                        .def("getCellFlux",&FlowEngine::_getCellFlux,(python::arg("cond")),"Get influx in cell associated to an imposed P (indexed using 'cond').")
270
 
                                        .def("getBoundaryFlux",&FlowEngine::_getBoundaryFlux,(python::arg("boundary")),"Get total flux through boundary defined by its body id.")
 
282
                                        .def("getBoundaryFlux",&FlowEngine::_getBoundaryFlux,(python::arg("boundary")),"Get total flux through boundary defined by its body id.\n\n.. note:: The flux may be not zero even for no-flow condition. This artifact comes from cells which are incident to two or more boundaries (along the edges of the sample, typically). Such flux evaluation on impermeable boundary is just irrelevant, it does not imply that the boundary condition is not applied properly.")
271
283
                                        .def("getConstrictions",&FlowEngine::_getConstrictions,(python::arg("all")=true),"Get the list of constriction radii (inscribed circle) for all finite facets (if all==True) or all facets not incident to a virtual bounding sphere (if all==False).  When all facets are returned, negative radii denote facet incident to one or more fictious spheres.")
272
284
                                        .def("getConstrictionsFull",&FlowEngine::_getConstrictionsFull,(python::arg("all")=true),"Get the list of constrictions (inscribed circle) for all finite facets (if all==True), or all facets not incident to a fictious bounding sphere (if all==False). When all facets are returned, negative radii denote facet incident to one or more fictious spheres. The constrictions are returned in the format {{cell1,cell2}{rad,nx,ny,nz}}")
273
285
                                        .def("saveVtk",&FlowEngine::saveVtk,"Save pressure field in vtk format.")
274
 
                                        .def("AvFlVelOnSph",&FlowEngine::AvFlVelOnSph,(python::arg("Id_sph")),"Compute a sphere-centered average fluid velocity")
 
286
                                        .def("avFlVelOnSph",&FlowEngine::avFlVelOnSph,(python::arg("Id_sph")),"Compute a sphere-centered average fluid velocity")
275
287
                                        .def("fluidForce",&FlowEngine::_fluidForce,(python::arg("Id_sph")),"Return the fluid force on sphere Id_sph.")
276
288
                                        .def("shearLubForce",&FlowEngine::_shearLubForce,(python::arg("Id_sph")),"Return the shear lubrication force on sphere Id_sph.")
277
289
                                        .def("shearLubTorque",&FlowEngine::_shearLubTorque,(python::arg("Id_sph")),"Return the shear lubrication torque on sphere Id_sph.")
278
290
                                        .def("normalLubForce",&FlowEngine::_normalLubForce,(python::arg("Id_sph")),"Return the normal lubrication force on sphere Id_sph.")
279
291
                                        .def("bodyShearLubStress",&FlowEngine::_bodyShearLubStress,(python::arg("Id_sph")),"Return the shear lubrication stress on sphere Id_sph.")
280
292
                                        .def("bodyNormalLubStress",&FlowEngine::_bodyNormalLubStress,(python::arg("Id_sph")),"Return the normal lubrication stress on sphere Id_sph.")
281
 
                                        .def("setBoundaryVel",&FlowEngine::setBoundaryVel,(python::arg("vel")),"Change velocity on top boundary.")
282
 
                                        .def("PressureProfile",&FlowEngine::PressureProfile,(python::arg("wallUpY"),python::arg("wallDownY")),"Measure pore pressure in 6 equally-spaced points along the height of the sample")
283
 
                                        .def("MeasurePorePressure",&FlowEngine::MeasurePorePressure,(python::arg("pos")),"Measure pore pressure in position pos[0],pos[1],pos[2]")
284
 
                                        .def("MeasureAveragedPressure",&FlowEngine::MeasureAveragedPressure,(python::arg("posY")),"Measure slice-averaged pore pressure at height posY")
285
 
                                        .def("MeasureTotalAveragedPressure",&FlowEngine::MeasureTotalAveragedPressure,"Measure averaged pore pressure in the entire volume")
286
 
 
 
293
                                        .def("shearVelocity",&FlowEngine::_shearVelocity,(python::arg("id_sph")),"Return the shear velocity of the interaction.")
 
294
                                        .def("normalVelocity",&FlowEngine::_normalVelocity,(python::arg("id_sph")),"Return the normal velocity of the interaction.")
 
295
                                        .def("normalVect",&FlowEngine::_normalVect,(python::arg("id_sph")),"Return the normal vector between particles.")
 
296
                                        .def("surfaceDistanceParticle",&FlowEngine::_surfaceDistanceParticle,(python::arg("interaction")),"Return the distance between particles.")
 
297
                                        .def("onlySpheresInteractions",&FlowEngine::_onlySpheresInteractions,(python::arg("interaction")),"Return the id of the interaction only between spheres.")
 
298
                                        
 
299
                                        
 
300
                                        .def("pressureProfile",&FlowEngine::pressureProfile,(python::arg("wallUpY"),python::arg("wallDownY")),"Measure pore pressure in 6 equally-spaced points along the height of the sample")
 
301
                                        .def("getPorePressure",&FlowEngine::getPorePressure,(python::arg("pos")),"Measure pore pressure in position pos[0],pos[1],pos[2]")
 
302
                                        .def("averageSlicePressure",&FlowEngine::averageSlicePressure,(python::arg("posY")),"Measure slice-averaged pore pressure at height posY")
 
303
                                        .def("averagePressure",&FlowEngine::averagePressure,"Measure averaged pore pressure in the entire volume")
287
304
                                        .def("updateBCs",&FlowEngine::_updateBCs,"tells the engine to update it's boundary conditions before running (especially useful when changing boundary pressure - should not be needed for point-wise imposed pressure)")
288
 
                                        .def("emulateAction",&FlowEngine::emulateAction,"get scene and run action (may be used to manipulate engine outside the main loop).")
 
305
                                        .def("emulateAction",&FlowEngine::emulateAction,"get scene and run action (may be used to manipulate an engine outside the timestepping loop).")
289
306
                                        .def("getCell",&FlowEngine::_getCell,(python::arg("pos")),"get id of the cell containing (X,Y,Z).")
290
307
                                        #ifdef LINSOLV
291
308
                                        .def("exportMatrix",&FlowEngine::_exportMatrix,(python::arg("filename")="matrix"),"Export system matrix to a file with all entries (even zeros will displayed).")
292
309
                                        .def("exportTriplets",&FlowEngine::_exportTriplets,(python::arg("filename")="triplets"),"Export system matrix to a file with only non-zero entries.")
 
310
                                        .def("cholmodStats",&FlowEngine::cholmodStats,"get statistics of cholmod solver activity")
 
311
                                        .def("metisUsed",&FlowEngine::metisUsed,"check wether metis lib is effectively used")
 
312
                                        .add_property("forceMetis",&FlowEngine::_getForceMetis,&FlowEngine::_setForceMetis,"If true, METIS is used for matrix preconditioning, else Cholmod is free to choose the best method (which may be METIS to, depending on the matrix). See ``nmethods`` in Cholmod documentation")
293
313
                                        #endif
294
314
                                        )
295
315
                DECLARE_LOGGER;
302
322
        if (!flow) LOG_ERROR("no flow defined yet, run at least one iter");
303
323
        flow->imposedP.push_back( pair<CGT::Point,Real>(CGT::Point(pos[0],pos[1],pos[2]),p) );
304
324
        //force immediate update of boundary conditions
305
 
        Update_Triangulation=true;
 
325
        updateTriangulation=true;
306
326
        return flow->imposedP.size()-1;
307
327
}
308
328
 
357
377
                Vector3r        _normalLubForce(unsigned int id_sph) {return normalLubForce(id_sph,solver);}
358
378
                Matrix3r        _bodyShearLubStress(unsigned int id_sph) {return bodyShearLubStress(id_sph,solver);}
359
379
                Matrix3r        _bodyNormalLubStress(unsigned int id_sph) {return bodyNormalLubStress(id_sph,solver);}
 
380
                Matrix3r        _normalStressInteraction(unsigned int interaction) {return normalStressInteraction(interaction,solver);}
 
381
                Matrix3r        _shearStressInteraction(unsigned int interaction) {return shearStressInteraction(interaction,solver);}
 
382
                Vector3r        _shearVelocity(unsigned int id_sph) {return shearVelocity(id_sph,solver);}
 
383
                Vector3r        _normalVelocity(unsigned int id_sph) {return normalVelocity(id_sph,solver);}
 
384
                Vector3r        _normalVect(unsigned int id_sph) {return normalVect(id_sph,solver);}
 
385
                Real            _surfaceDistanceParticle(unsigned int interaction) {return surfaceDistanceParticle(interaction,solver);}
 
386
                int             _onlySpheresInteractions(unsigned int interaction) {return onlySpheresInteractions(interaction,solver);}
 
387
                Real            _edgeSize() {return edgeSize(solver);}
 
388
                Real            _OSI() {return OSI(solver);}
360
389
 
361
390
                Vector3r        _fluidForce(unsigned int id_sph) {return fluidForce(id_sph, solver);}
362
391
                void            _imposeFlux(Vector3r pos, Real flux) {return imposeFlux(pos,flux,*solver);}
364
393
                Real            _getBoundaryFlux(unsigned int boundary) {return getBoundaryFlux(boundary,solver);}
365
394
                        
366
395
                void            _updateBCs() {updateBCs(solver);}
367
 
                double          MeasurePorePressure(Vector3r pos){return solver->MeasurePorePressure(pos[0], pos[1], pos[2]);}
368
 
                double          MeasureTotalAveragedPressure(){return solver->MeasureTotalAveragedPressure();}
369
 
                void            PressureProfile(double wallUpY, double wallDownY) {return solver->MeasurePressureProfile(wallUpY,wallDownY);}
 
396
                double          getPorePressure(Vector3r pos){return solver->getPorePressure(pos[0], pos[1], pos[2]);}
 
397
                double          averagePressure(){return solver->averagePressure();}
 
398
                void            pressureProfile(double wallUpY, double wallDownY) {return solver->measurePressureProfile(wallUpY,wallDownY);}
370
399
 
371
400
                int             _getCell(Vector3r pos) {return getCell(pos[0],pos[1],pos[2],solver);}
372
401
                #ifdef LINSOLV
390
419
                        if (solver->T[solver->currentTes].Volume(id) == -1) {compTessVolumes(); LOG_WARN("Computing all volumes now, as you did not request it explicitely.");}
391
420
                        return (solver->T[solver->currentTes].Max_id() >= id) ? solver->T[solver->currentTes].Volume(id) : -1;}
392
421
 
393
 
                YADE_CLASS_BASE_DOC_ATTRS_INIT_CTOR_PY(PeriodicFlowEngine,FlowEngine,"An engine to solve flow problem in saturated granular media",
 
422
                YADE_CLASS_BASE_DOC_ATTRS_INIT_CTOR_PY(PeriodicFlowEngine,FlowEngine,"A variant of :yref:`FlowEngine` implementing periodic boundary conditions. The API is very similar.",
394
423
                        ((Real,duplicateThreshold, 0.06,,"distance from cell borders that will triger periodic duplication in the triangulation |yupdate|"))
395
424
                        ((Vector3r, gradP, Vector3r::Zero(),,"Macroscopic pressure gradient"))
396
425
                        ,,
397
 
                        wallTopId=wallBottomId=wallFrontId=wallBackId=wallLeftId=wallRightId=-1;
 
426
                        wallIds=vector<int>(6,-1);
 
427
//                      wallTopId=wallBottomId=wallFrontId=wallBackId=wallLeftId=wallRightId=-1;
398
428
                        solver = shared_ptr<FlowSolver> (new FlowSolver);
399
 
                        Update_Triangulation=false;
 
429
                        updateTriangulation=false;
400
430
                        eps_vol_max=Eps_Vol_Cumulative=retriangulationLastIter=0;
401
431
                        ReTrg=1;
402
432
                        first=true;
408
438
                        .def("normalLubForce",&PeriodicFlowEngine::_normalLubForce,(python::arg("Id_sph")),"Return the normal lubrication force on sphere Id_sph.")
409
439
                        .def("bodyShearLubStress",&PeriodicFlowEngine::_bodyShearLubStress,(python::arg("Id_sph")),"Return the shear lubrication stress on sphere Id_sph.")
410
440
                        .def("bodyNormalLubStress",&PeriodicFlowEngine::_bodyNormalLubStress,(python::arg("Id_sph")),"Return the normal lubrication stress on sphere Id_sph.")
 
441
                        .def("shearVelocity",&PeriodicFlowEngine::_shearVelocity,(python::arg("id_sph")),"Return the shear velocity of the interaction.")
 
442
                        .def("normalStressInteraction",&PeriodicFlowEngine::_normalStressInteraction,(python::arg("id_sph")),"Return the shear velocity of the interaction.")
 
443
                        .def("shearStressInteraction",&PeriodicFlowEngine::_shearStressInteraction,(python::arg("id_sph")),"Return the shear velocity of the interaction.")
 
444
                        .def("normalVelocity",&PeriodicFlowEngine::_normalVelocity,(python::arg("id_sph")),"Return the normal velocity of the interaction.")
 
445
                        .def("normalVect",&PeriodicFlowEngine::_normalVect,(python::arg("id_sph")),"Return the normal vector between particles.")
 
446
                        .def("surfaceDistanceParticle",&PeriodicFlowEngine::_surfaceDistanceParticle,(python::arg("interaction")),"Return the distance between particles.")
 
447
                        .def("onlySpheresInteractions",&PeriodicFlowEngine::_onlySpheresInteractions,(python::arg("interaction")),"Return the id of the interaction only between spheres.")
 
448
                        .def("edgeSize",&PeriodicFlowEngine::_edgeSize,"Return the number of interactions.")
 
449
                        .def("OSI",&PeriodicFlowEngine::_OSI,"Return the number of interactions only between spheres.")
411
450
 
412
451
//                      .def("imposeFlux",&FlowEngine::_imposeFlux,(python::arg("pos"),python::arg("p")),"Impose incoming flux in boundary cell of location 'pos'.")
413
452
                        .def("saveVtk",&PeriodicFlowEngine::saveVtk,"Save pressure field in vtk format.")
414
453
                        .def("imposePressure",&PeriodicFlowEngine::_imposePressure,(python::arg("pos"),python::arg("p")),"Impose pressure in cell of location 'pos'. The index of the condition is returned (for multiple imposed pressures at different points).")
415
454
                        .def("getBoundaryFlux",&PeriodicFlowEngine::_getBoundaryFlux,(python::arg("boundary")),"Get total flux through boundary defined by its body id.")
416
 
                        .def("MeasurePorePressure",&PeriodicFlowEngine::MeasurePorePressure,(python::arg("pos")),"Measure pore pressure in position pos[0],pos[1],pos[2]")
417
 
                        .def("MeasureTotalAveragedPressure",&PeriodicFlowEngine::MeasureTotalAveragedPressure,"Measure averaged pore pressure in the entire volume") 
418
 
                        .def("PressureProfile",&PeriodicFlowEngine::PressureProfile,(python::arg("wallUpY"),python::arg("wallDownY")),"Measure pore pressure in 6 equally-spaced points along the height of the sample")
 
455
                        .def("getPorePressure",&PeriodicFlowEngine::getPorePressure,(python::arg("pos")),"Measure pore pressure in position pos[0],pos[1],pos[2]")
 
456
                        .def("averagePressure",&PeriodicFlowEngine::averagePressure,"Measure averaged pore pressure in the entire volume")
 
457
                        .def("pressureProfile",&PeriodicFlowEngine::pressureProfile,(python::arg("wallUpY"),python::arg("wallDownY")),"Measure pore pressure in 6 equally-spaced points along the height of the sample")
419
458
 
420
459
                        .def("updateBCs",&PeriodicFlowEngine::_updateBCs,"tells the engine to update it's boundary conditions before running (especially useful when changing boundary pressure - should not be needed for point-wise imposed pressure)")
421
460