00001 
00002 
00003 #ifndef MOTION_ELC_COUPLED_SOLVER_H
00004 #define MOTION_ELC_COUPLED_SOLVER_H
00005 
00012 #include "Point.h"
00013 #include "MotionCoupledSolver.h"
00014 #include "elc/LagrangianComm.h"
00015 
00016 template <class DataType,int dim>
00017 class MotionELCCoupledSolver : public MotionCoupledSolver<DataType,dim> {
00018   typedef MotionCoupledSolver<DataType,dim> base;
00019 public:
00020   typedef elc::LagrangianComm<dim,DataType> elc_lagcomm_type;
00021 
00022   MotionELCCoupledSolver() : base(), _olog(0), _elcLag(0) {}
00023 
00024   ~MotionELCCoupledSolver() {
00025     if (_elcLag) delete _elcLag;
00026   }
00027 
00028   void SetupInterComm(MPI_Comm solidComm, int numFluidNodes, int firstFluidNode) {
00029     MPI_Comm_rank(solidComm, &myRank);
00030 #ifdef DEBUG_PRINT
00031     std::ostringstream obuf;
00032     obuf << "S" << myRank << ".log" << static_cast<char>(0);
00033     oflog.open(obuf.str().c_str());
00034     _olog = new std::ostream(oflog.rdbuf());
00035     base::_bolog = _olog;
00036 #endif
00037     MKlog = _olog;
00038 
00039 #ifdef DEBUG_PRINT_ELC
00040     ( log() << "*** LagrangianComm: " << numFluidNodes << "  " << firstFluidNode ).flush();
00041 #endif
00042     
00043     _elcLag = new elc_lagcomm_type(MPI_COMM_WORLD, solidComm, numFluidNodes,
00044                                    firstFluidNode, elc::GlobalIdentifiers);
00045 #ifdef DEBUG_PRINT_ELC
00046     ( log() << " created.\n").flush();
00047 #endif
00048   }
00049 
00050   virtual void SendBoundaryData() {
00051     int elNumNodes = base::NumNodes();
00052     int elNumElements = base::NumElements();
00053     const int *elGlobalNodeIDs = base::NodeIDs();
00054     const int *elConnectivity = base::Connections();
00055     const DataType *elCoordinates = base::Coordinates();
00056     const DataType *elVelocities = base::Velocities();
00057  
00058 #ifdef DEBUG_PRINT_ELC_VALUES
00059     for (register int n=0; n<elNumNodes; n++)
00060       ( log() << "(" << elCoordinates[2*n] << ","
00061         << elCoordinates[2*n+1] << ")  " ).flush();
00062     ( log() << std::endl ).flush();
00063 #endif
00064 
00065 #ifdef DEBUG_PRINT_ELC
00066     ( log() << "*** MotionELCCoupledSolver::SendBoundaryData() " ).flush();
00067 #endif
00068         
00069     _elcLag->sendMesh(elNumNodes, reinterpret_cast<const void*>(elGlobalNodeIDs), 
00070                       reinterpret_cast<const void*>(elCoordinates), 
00071                       reinterpret_cast<const void*>(elVelocities), 
00072                       elNumElements, reinterpret_cast<const void*>(elConnectivity));
00073     _elcLag->waitForMesh();
00074 
00075 #ifdef DEBUG_PRINT_ELC
00076     ( log() << " done.\n" ).flush();
00077 #endif
00078   }
00079 
00080   virtual void PostReceiveBoundaryData() {
00081     DataType *elPressures = base::Pressures();
00082     int elNumNodes = base::NumNodes(); 
00083 
00084 #ifdef DEBUG_PRINT_ELC
00085     ( log() << "*** MotionELCCoupledSolver::PostReceiveBoundaryData()" ).flush();
00086 #endif
00087         
00088     _elcLag->receivePressure(elNumNodes, reinterpret_cast<void*>(elPressures));
00089 
00090 #ifdef DEBUG_PRINT_ELC
00091     ( log() << " done.\n" ).flush();
00092 #endif
00093   }
00094 
00095   virtual void WaitReceiveBoundaryData() {
00096     DataType *elPressures = base::Pressures();
00097     int elNumNodes = base::NumNodes();
00098 
00099 #ifdef DEBUG_PRINT_ELC
00100     ( log() << "*** MotionELCCoupledSolver::WaitReceiveBoundaryData()" ).flush();
00101 #endif
00102         
00103     _elcLag->waitForPressure();
00104 
00105     
00106     for (register int n=0; n<elNumNodes; n++) 
00107       if (elPressures[n] == std::numeric_limits<DataType>::max()) 
00108         elPressures[n] = 0.0;
00109 
00110 #ifdef DEBUG_PRINT_ELC_VALUES
00111     for (register int n=0; n<elNumNodes; n++)
00112       ( log() << elPressures[n] << "  " ).flush();
00113     ( log() << std::endl ).flush();
00114 #endif
00115 
00116 #ifdef DEBUG_PRINT_ELC
00117     ( log() << " done.\n" ).flush();
00118 #endif
00119   }
00120 
00121   virtual void sendBoundaryReceivePressure() {
00122     int elNumNodes = base::NumNodes();
00123     int elNumElements = base::NumElements();
00124     DataType *elPressures = base::Pressures();
00125     const int* elGlobalNodeIDs = base::NodeIDs();
00126     const int* elConnectivity = base::Connections();
00127     const DataType* elCoordinates = base::Coordinates();
00128     const DataType* elVelocities = base::Velocities();
00129 #ifdef DEBUG_PRINT_ELC_VALUES
00130     for (register int n=0; n<elNumNodes; n++)
00131       ( log() << "(" << elCoordinates[2*n] << ","
00132         << elCoordinates[2*n+1] << ")  " ).flush();
00133     ( log() << std::endl ).flush();
00134 #endif
00135 
00136 #ifdef DEBUG_PRINT_ELC
00137     ( log() << "*** MotionELCCoupledSolver::sendBoundaryReceivePressure" ).flush();
00138 #endif
00139 
00140     _elcLag->sendMesh(elNumNodes, reinterpret_cast<const void*>(elGlobalNodeIDs),
00141           reinterpret_cast<const void*>(elCoordinates),
00142           reinterpret_cast<const void*>(elVelocities),
00143           elNumElements, reinterpret_cast<const void*>(elConnectivity));
00144     _elcLag->waitForMesh();
00145     _elcLag->receivePressure(elNumNodes, reinterpret_cast<void*>(elPressures));
00146     _elcLag->waitForPressure();
00147 
00148     
00149     for (register int n=0; n<elNumNodes; n++)
00150       if (elPressures[n] == std::numeric_limits<DataType>::max())
00151         elPressures[n] = 0.0;
00152 #ifdef DEBUG_PRINT_ELC_VALUES
00153     for (register int n=0; n<elNumNodes; n++)
00154       ( log() << elPressures[n] << "  " ).flush();
00155     ( log() << std::endl ).flush();
00156 #endif
00157 
00158 #ifdef DEBUG_PRINT_ELC
00159     ( log() << " done.\n" ).flush();
00160 #endif
00161   }
00162 
00163   inline std::ostream& log() { return *_olog; }
00164 
00165 protected:
00166   std::ostream* _olog;
00167   std::ofstream oflog;
00168   int myRank;
00169   elc_lagcomm_type* _elcLag;
00170 };
00171 
00172 #endif