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