From 07f2e3b3b38d1ee8d6375f43e398c3676c0e1fa7 Mon Sep 17 00:00:00 2001 From: cfdem Date: Mon, 3 Dec 2012 09:41:15 +0100 Subject: [PATCH] release on 2012-12-03_09-41-15 --- README | 82 +++++ doc/CFDEMcoupling_Manual.pdf | Bin 515179 -> 515179 bytes doc/githubAccess_public.pdf | Bin 361862 -> 361862 bytes src/lagrangian/cfdemParticle/Make/files | 20 +- .../twoWayM2M/library/libcouple.a | Bin 4209202 -> 4209202 bytes .../dataExchangeModel/twoWayM2M/twoWayM2M.C | 312 ++++++++++-------- .../dataExchangeModel/twoWayM2M/twoWayM2M.H | 10 +- .../turboEngineSearchM2M.C | 24 +- .../CFD/constant/couplingProperties | 4 +- 9 files changed, 311 insertions(+), 141 deletions(-) create mode 100644 README diff --git a/README b/README new file mode 100644 index 00000000..a677e0a8 --- /dev/null +++ b/README @@ -0,0 +1,82 @@ +/*---------------------------------------------------------------------------*\ + CFDEMcoupling - Open Source CFD-DEM coupling + + CFDEMcoupling is part of the CFDEMproject + www.cfdem.com + Christoph Goniva, christoph.goniva@cfdem.com + Copyright 2009-2012 JKU Linz + Copyright 2012- DCS Computing GmbH, Linz +------------------------------------------------------------------------------- +License + This file is part of CFDEMcoupling. + + CFDEMcoupling is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with CFDEMcoupling; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Description + This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS + and OpenFOAM. Note: this code is not part of OpenFOAM (see DISCLAIMER). +\*---------------------------------------------------------------------------*/ + + +CFDEM coupling provides an open source parallel coupled CFD-DEM framework +combining the strengths of LIGGGHTS DEM code and the Open Source +CFD package OpenFOAM(R)(*). The CFDEMcoupling toolbox allows to expand +standard CFD solvers of OpenFOAM(R)(*) to include a coupling to the DEM +code LIGGGHTS. In this toolbox the particle representation within the +CFD solver is organized by "cloud" classes. Key functionalities are organised +in sub-models (e.g. force models, data exchange models, etc.) which can easily +be selected and combined by dictionary settings. + +The coupled solvers run fully parallel on distributed-memory clusters. + +Features are: + +- its modular approach allows users to easily implement new models +- its MPI parallelization enables to use it for large scale problems +- the "forum"_lws on CFD-DEM gives the possibility to exchange with other + users / developers +- the use of GIT allows to easily update to the latest version +- basic documentation is provided + +The file structure: + +- "src" directory including the source files of the coupling toolbox and models +- "applications" directory including the solver files for coupled CFD-DEM simulations +- "doc" directory including the documentation of CFDEMcoupling +- "tutorials" directory including basic tutorial cases showing the functionality + + + +Details on installation are given on the "www.cfdem.com" + +The functionality of this CFD-DEM framwork is described via "tutorial cases" showing +how to use different solvers and models. + +CFDEMcoupling stands for Computational Fluid Dynamics (CFD) - +Discrete Element Method (DEM) coupling. + +CFDEMcoupling is an open-source code, distributed freely under the terms of the +GNU Public License (GPL). + +Core development of CFDEMcoupling is done by +Christoph Goniva and Christoph Kloss, both at DCS Computing GmbH, 2012 + + +\*---------------------------------------------------------------------------*/ +(*) "OpenFOAM(R)"_of is a registered trade mark of Silicon Graphics +International Corp. This offering is not affiliated, approved or endorsed by +Silicon Graphics International Corp., the producer of the OpenFOAM(R) software +and owner of the OpenFOAM(R) trademark. +\*---------------------------------------------------------------------------*/ diff --git a/doc/CFDEMcoupling_Manual.pdf b/doc/CFDEMcoupling_Manual.pdf index 90a60e64fa9a3e959ca2353ac78d6086226334ca..6c8d547bcf1cd510803161632183cf08a2afdb92 100644 GIT binary patch delta 115 zcmaF8L;m#+`3dcuMh3XGIq$HarB>|D04IvfN{qL~L000bUCA0tl delta 115 zcmaF8L;m#+`3dcuhQlyCor~7U}~Mf+&Y1!bpmVa1h%ac*lTY)r5G5P qnWh=1nwh1fm>Z{>7$g}QB&Had7^RvSn46?p*x3+LG2Q5p(?Bm9h_izhJ*PO>>OlbVyjApeGe zm=NQRuO1kl;e2_&WsF!zPVGsK_z#)!gy`0XxjA}uRW1Qd=XE;Yj zc6%4qHx+v7Vn48jA7qikCGv1kKvDXE`{|4~{tq!jSD2xPD_o<58{A4Wyo*2o0!cfd A;Q#;t delta 401 zcmXxgJ5Rz;7=Yn`i1n_h6f0`2w|c`0EmXxz(jVc(X8ajN7f)gsob2YzOlnR7iSlnc z5EEkD@g>FK8P1n?IN#U$eN49Snok$4l54w9#)px()#8^ObR$z0buED;#*o4|(wLBS zO}V@OudR-fl|R1XR!0-T1e2J;G-fc1Icas~-v@E%1ca*SwHL6643@Br6=Y?vtq#89 zx-9z599E%W4SB3%1Dmqn)ctT24|m9kMr{iQwy}d<>|tLvYG&ajt}B8X2ROtLj&Xv5 z>_(>#Z=*2&vFBUD^UqL32{s&*QIVeSemSY(X@k$m)Px?oIL8GpQN0){ @@ -393,9 +394,6 @@ void Foam::twoWayM2M::syncIDs() const id_lammps_[0]=0; } - Pout << couplingStep_ << "st id_lammps_[0]=" << id_lammps_[0]<< endl; - - //delete [] id_lammps_vec_; Foam::dataExchangeModel::allocateArray(id_lammps_vec_,0,nlocal_lammps_*3); for (int i = 0; i < nlocal_lammps_; i++) @@ -470,6 +468,12 @@ void Foam::twoWayM2M::syncIDs() const //for (int i = 0; i < nlocal_lammps_; i++) // Pout << "getData3: " << "v" <<"=" << pos_lammps_[i][0]<<","<setup(nlocal_lammps_,id_lammpsComm_,nlocal_foam_,id_foam_); @@ -557,7 +563,8 @@ void Foam::twoWayM2M::locateParticle() const } } - // loop all lmp particles + // stage 1 - look on proc or send or prepare for all-to-all + particleCloud_.clockM().start(7,"locate_Stage1"); int iterate; if(firstRun_) iterate=nlocal_lammps_; else iterate=nlocal_foam_; @@ -566,39 +573,13 @@ void Foam::twoWayM2M::locateParticle() const nlocal_foam_lost_ = 0; vector pos; label cellID = 0; - label searchCellID; - - particleCloud_.clockM().start(7,"locate_Stage1"); - -/*//=============== - // move this to top level - const polyBoundaryMesh& pbm = particleCloud_.mesh().boundaryMesh(); - const globalMeshData& pData = particleCloud_.mesh().globalData(); // polyMesh??? - - // Which patches are processor patches - const labelList& procPatches = pData.processorPatches(); - - // Indexing of patches into the procPatches list - const labelList& procPatchIndices = pData.processorPatchIndices(); - - // Which processors this processor is connected to - const labelList& neighbourProcs = pData[Pstream::myProcNo()]; - - // Indexing from the processor number into the neighbourProcs list - labelList neighbourProcIndices(Pstream::nProcs(), -1); - - forAll(neighbourProcs, i) - { - neighbourProcIndices[neighbourProcs[i]] = i; - } - - List< DynamicList > particleTransferLists(neighbourProcs.size()); -//===============*/ + label searchCellID=-1; + List< DynamicList > particleTransferID(neighbourProcs_.size()); + List< DynamicList > particleTransferPos(neighbourProcs_.size()); for (int i = 0; i < iterate; i++) { pos = vector(pos_lammps_[i][0],pos_lammps_[i][1],pos_lammps_[i][2]); - searchCellID = -1; cellID = particleCloud_.locateM().findSingleCell(pos,searchCellID); point oldPos(pos_foam_[nlocal_foam_*3+0],pos_foam_[nlocal_foam_*3+1],pos_foam_[nlocal_foam_*3+2]); @@ -621,98 +602,183 @@ void Foam::twoWayM2M::locateParticle() const } else { - //----------------- - id_foam_lost_[nlocal_foam_lost_] = id_lammps_[i]; - - for (int j=0; j<3; j++) - lost_pos_[nlocal_foam_lost_*3+j] = pos[j]; - - nlocal_foam_lost_ += 1; - //Pout << couplingStep_ << "st cellID="<< cellID << " lost particle id="<< id_lammps_[i] <<" at pos=" << pos << endl; - //----------------- - /*// find out where particle has migrated (must have passed a CFD proc border) + // find out where particle has migrated (must have passed a CFD proc border) + bool commPart=false; point newPos=pos; label nearestFace = particleCloud_.locateM().intersection(oldPos,newPos); - Pout << "nearest face=" << nearestFace << endl; + //Pout << couplingStep_ << "st nearestFace="<< nearestFace << " oldPos="<< oldPos <<" at pos=" << pos << endl; - - // If we hit a boundary face if (nearestFace >= particleCloud_.mesh().nInternalFaces()) { - Pout << " face=" << nearestFace << " , is a boundary face!" << endl; - label patchI = pbm.whichPatch(nearestFace); + label patchI = pbm_.whichPatch(nearestFace); - // ... and the face is on a processor patch - // prepare it for transfer - if (procPatchIndices[patchI] != -1) + if (procPatchIndices_[patchI] != -1) { - Pout << " face=" << nearestFace << " , is a proc face!" << endl; - label n = neighbourProcIndices + label n = neighbourProcIndices_ [ refCast ( - pbm[patchI] + pbm_[patchI] ).neighbProcNo() ]; - Pout << " communicate to n=" << n << endl; - particleTransferLists[n].append(id_lammps_[i]); + particleTransferID[n].append(id_lammps_[i]); + particleTransferPos[n].append(pos); + commPart=true; } - }*/ - //----------------- + } + if (!commPart) + { + // prepare for all to all comm + id_foam_lost_[nlocal_foam_lost_] = id_lammps_[i]; + + for (int j=0; j<3; j++) + lost_pos_[nlocal_foam_lost_*3+j] = pos[j]; + nlocal_foam_lost_ += 1; + //Pout << couplingStep_ << "st cellID="<< cellID << " lost particle id="<< id_lammps_[i] <<" at pos=" << pos << endl; + } + } + } + particleCloud_.clockM().stop("locate_Stage1"); + + // stage 2 - recv particle, locate or all-to-all + particleCloud_.clockM().start(9,"locate_Stage2"); + + // Allocate transfer buffers + PstreamBuffers pBufs(Pstream::nonBlocking); + + // Stream into send buffers + forAll(particleTransferID, i) + { + if (particleTransferID[i].size()) + { + UOPstream particleStream + ( + neighbourProcs_[i], + pBufs + ); + particleStream << particleTransferID[i]<= 0) - { - // IDs for scalars - id_foam_[nlocal_foam_] = id_foam_lost_all[i]; - - // IDs for vectors - for (int j=0;j<3;j++) + if (allNTrans[i][j]) { - id_foam_vec_[nlocal_foam_*3+j] = id_foam_lost_all[i]*3+j; - pos_foam_[nlocal_foam_*3+j] = pos[j]; + break; } - cellID_foam_[nlocal_foam_] = cellID; + } + } - // mark that ID was finally found - id_foam_lost_all[i]=-1; + // Retrieve from receive buffers + label neighbProci; + label nRec; + forAll(neighbourProcs_, i) + { + neighbProci = neighbourProcs_[i]; + nRec = allNTrans[neighbProci][Pstream::myProcNo()]; - nlocal_foam_ += 1; - //Pout << "stage2 found particle at pos=" << pos << endl; + if (nRec) + { + UIPstream particleStream(neighbProci, pBufs); + + labelList recvParticleTransferID(particleStream); + List recvParticleTransferPos(particleStream); + + forAll(recvParticleTransferID,i) + { + //Pout << "received id="< 0) + { + //Info << "all-to-all necessary: nlocal_foam_lost_all=" << nlocal_foam_lost_all << endl; + int nlocal_foam_lost_all = LAMMPS_NS::MPI_Allgather_Vector(lost_pos_, nlocal_foam_lost_*3, lost_pos_all, MPI_COMM_WORLD)/3; + LAMMPS_NS::MPI_Allgather_Vector(id_foam_lost_, nlocal_foam_lost_, id_foam_lost_all, MPI_COMM_WORLD); + //Info << couplingStep_ << "st nlocal_foam_lost_all=" << nlocal_foam_lost_all << endl; + + // locate lost particles + for (int i = 0; i < nlocal_foam_lost_all; i++) + { + pos = vector(lost_pos_all[i*3+0],lost_pos_all[i*3+1],lost_pos_all[i*3+2]); + //Pout << "stage3 look for particle at pos=" << pos << endl; + cellID = particleCloud_.locateM().findSingleCell(pos,searchCellID); + + // found particle on cfd proc + if (cellID >= 0) + { + // IDs for scalars + id_foam_[nlocal_foam_] = id_foam_lost_all[i]; + + // IDs for vectors + for (int j=0;j<3;j++) + { + id_foam_vec_[nlocal_foam_*3+j] = id_foam_lost_all[i]*3+j; + pos_foam_[nlocal_foam_*3+j] = pos[j]; + } + cellID_foam_[nlocal_foam_] = cellID; + + // mark that ID was finally found + id_foam_lost_all[i]=-1; + + nlocal_foam_ += 1; + //Pout << "stage3 found particle at pos=" << pos << " ,id="<< id_foam_lost_all[i] << endl; + } + } + } + particleCloud_.clockM().stop("locate_Stage3"); + /* // check if really all particles were found particleCloud_.clockM().start(10,"locate_Stage3"); Foam::dataExchangeModel::allocateArray(id_foam_nowhere_all,1,nlocal_foam_lost_all); @@ -759,20 +825,6 @@ Info << "nlocal_lammps_ALL=" << gugu << endl;*/ //delete[] lost_pos_all; } -/*void Foam::twoWayM2M::exchange(double* demDat, double* cfdDat) const -{ - lmp2foam_->exchange(demDat,cfdDat);//(pos_lammps,pos_foam); -}*/ - -/*template -T*& Foam::twoWayM2M::extract_save(T *& a,char name) -{ - a = (T *) lammps_extract_atom(lmp,name); - if(!a) - a=new T[1]; - return a;//static_const(a); -}*/ - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/lagrangian/cfdemParticle/subModels/dataExchangeModel/twoWayM2M/twoWayM2M.H b/src/lagrangian/cfdemParticle/subModels/dataExchangeModel/twoWayM2M/twoWayM2M.H index e27f32a7..712f4237 100644 --- a/src/lagrangian/cfdemParticle/subModels/dataExchangeModel/twoWayM2M/twoWayM2M.H +++ b/src/lagrangian/cfdemParticle/subModels/dataExchangeModel/twoWayM2M/twoWayM2M.H @@ -111,6 +111,13 @@ private: mutable int *cellID_foam_; mutable double *pos_foam_; + const polyBoundaryMesh& pbm_; + const globalMeshData& pData_; + const labelList& procPatches_; + const labelList& procPatchIndices_; + const labelList& neighbourProcs_; + labelList neighbourProcIndices_; + // variables int me; @@ -191,9 +198,6 @@ public: void syncIDs() const; void locateParticle() const; - //void exchange(double*,double*) const; - //template - //T*& extract_save(T *& a,char name); }; diff --git a/src/lagrangian/cfdemParticle/subModels/locateModel/turboEngineSearchM2M/turboEngineSearchM2M.C b/src/lagrangian/cfdemParticle/subModels/locateModel/turboEngineSearchM2M/turboEngineSearchM2M.C index c7ebc550..c843ca1e 100755 --- a/src/lagrangian/cfdemParticle/subModels/locateModel/turboEngineSearchM2M/turboEngineSearchM2M.C +++ b/src/lagrangian/cfdemParticle/subModels/locateModel/turboEngineSearchM2M/turboEngineSearchM2M.C @@ -92,11 +92,25 @@ label turboEngineSearchM2M::intersection ) const { // find intersection with boundary - //pointIndexHit hit=searchEngine_.intersection(pStart,pEnd); - //Info << "hit.index()=" << hit.index()<< endl; - - //return searchEngine_.findNearestBoundaryFace(pStart); - return searchEngine_.intersection(pStart,pEnd).index(); + label face = searchEngine_.intersection(pStart,pEnd).index(); + + // try alternative + if (face==-1) + { + // try alternative + face = searchEngine_.findNearestBoundaryFace(pEnd); + //Pout << "found face=" << face << " with findNearestBoundaryFace" << endl; + + // might have been first search + if (face==-1 && mag(pStart-point(0,0,0))