00001
00002
00003
00004
00005
00006 #ifndef ADLIB_ELC_COUPLED_SOLVER_H
00007 #define ADLIB_ELC_COUPLED_SOLVER_H
00008
00016 template <int dim> class AdlibCoupledSolver;
00017
00018 #include "external_coupling/AdlibCoupledSolver3.h"
00019 #include "elc/LagrangianComm.h"
00020
00027 template <int dim>
00028 class AdlibELCCoupledSolver : public AdlibCoupledSolver<dim> {
00029 typedef AdlibCoupledSolver<dim> base;
00030 public:
00031 typedef elc::LagrangianComm<dim,double> elc_lagcomm_type;
00032
00033 AdlibELCCoupledSolver(MPI_Comm solidComm, int numFluidNodes, int firstFluidNode) : base(solidComm) {
00034
00035 #ifdef DEBUG_PRINT_ELC
00036 ( base::log() << "*** LagrangianComm: " << numFluidNodes << " " << firstFluidNode ).flush();
00037 #endif
00038
00039
00040 _elcLag = new elc_lagcomm_type(MPI_COMM_WORLD, solidComm, numFluidNodes,
00041 firstFluidNode, elc::GlobalIdentifiers);
00042
00043 #ifdef DEBUG_PRINT_ELC
00044 ( base::log() << " created.\n").flush();
00045 #endif
00046 }
00047
00048 ~AdlibELCCoupledSolver() {
00049 if (_elcLag) delete _elcLag;
00050 }
00051
00052 virtual void sendBoundaryReceivePressure() {
00053 ADLIB_START_WATCH
00054
00055 adlib::AdlibBoundaryUpdate(&base::Boundary());
00056
00057 int elNumNodes = base::Boundary().bNodes;
00058 int elNumElements = base::Boundary().bFacets;
00059
00060
00061 double *elPressures = base::Boundary().bPressure;
00062 int *elGlobalNodeIDs= new int[elNumNodes];
00063 for (int nod=0; nod<elNumNodes; ++nod) {
00064 int nodeNbInPart = base::Boundary().bNodeMap[nod];
00065 elGlobalNodeIDs[nod] =adlib::OTArray[nodeNbInPart-1]->GlobalId;
00066 }
00067
00068
00069 double *elCoordinates = new double[elNumNodes*dim]; ;
00070 computeBoundaryCoordinates(base::Boundary().bCoordinates, elCoordinates,
00071 base::Boundary().bNodeMap, elNumNodes);
00072
00073 double *elVelocities = base::Boundary().bVelocities;
00074
00075
00076 int *elConnectivity = new int[dim*elNumElements];
00077 int *bIds = base::Boundary().bConnectivities;
00078 int *bNodeMap = base::Boundary().bNodeMap;
00079 int *gIds = elConnectivity;
00080
00081 for (int elem=0; elem<elNumElements; ++elem, bIds+=dim, gIds+=dim)
00082 for (int a=0; a<dim; ++a) {
00083 int nodeNbInPart = bNodeMap[bIds[a]-1];
00084 gIds[a] = adlib::OTArray[nodeNbInPart-1]->GlobalId;
00085 }
00086 ADLIB_END_WATCH(CPL_SEND_OVERHEAD)
00087
00088 #ifdef DEBUG_PRINT_ELC
00089 ( base::log() << "*** AdlibCoupledSolver::sendBoundaryReceivePressure" ).flush();
00090 #endif
00091
00092 ModifyELCSendData(_elcLag);
00093
00094 ADLIB_START_WATCH
00095 _elcLag->sendMesh(elNumNodes, reinterpret_cast<void*>(elGlobalNodeIDs),
00096 reinterpret_cast<void*>(elCoordinates),
00097 reinterpret_cast<void*>(elVelocities),
00098 elNumElements, reinterpret_cast<void*>(elConnectivity));
00099 _elcLag->waitForMesh();
00100 _elcLag->receivePressure(elNumNodes, reinterpret_cast<void*>(elPressures));
00101 _elcLag->waitForPressure();
00102 ADLIB_END_WATCH(ELC_SNDBND_RCVPRS)
00103
00104 ModifyELCReceiveData(_elcLag);
00105
00106 ADLIB_START_WATCH
00107
00108 for (register int n=0; n<elNumNodes; n++)
00109 if (elPressures[n] == std::numeric_limits<double>::max())
00110 elPressures[n] = 0.0;
00111
00112 std::memset(adlib::forces, 0,
00113 sizeof(double)*(adlib::nodes)*(adlib::dof_node));
00114
00115
00116 adlib::AdlibBoundaryApplyPressure(&base::Boundary(),adlib::solidFluid);
00117
00118 delete [] elConnectivity;
00119 delete [] elGlobalNodeIDs;
00120 delete [] elCoordinates;
00121
00122 ADLIB_END_WATCH(CPL_RECEIVE_OVERHEAD)
00123
00124 #ifdef DEBUG_PRINT_ELC
00125 ( base::log() << " done.\n" ).flush();
00126 #endif
00127 }
00128
00129 virtual void computeBoundaryCoordinates(double *original, double *final,
00130 int *map, int size)
00131 {
00132 for(int i = 0; i < size; i++)
00133 {
00134 double x0 = adlib::coordinates[adlib::dof_node*(map[i]-1)];
00135 double y0 = adlib::coordinates[adlib::dof_node*(map[i]-1)+1];
00136 double z0 = adlib::coordinates[adlib::dof_node*(map[i]-1)+2];
00137 double x = original[dim*i+0];
00138 double y = original[dim*i+1];
00139 double z = original[dim*i+2];
00140
00141 double dx = x0 - base::xCenter;
00142 if(dx>0.)
00143 dx *= base::ratioXPos;
00144 else
00145 dx *= base::ratioXNeg;
00146 final[dim*i+0] = base::xCenter + dx + (x-x0);
00147
00148 double dy = y0 - base::yCenter;
00149 if(dy>0.)
00150 dy *= base::ratioYPos;
00151 else
00152 dy *= base::ratioYNeg;
00153 final[dim*i+1] = base::yCenter + dy + (y-y0);
00154
00155 double dz = z0 - base::zCenter;
00156 if(dz>0.)
00157 dz *= base::ratioZPos;
00158 else
00159 dz *= base::ratioZNeg;
00160 final[dim*i+2] = base::zCenter + dz + (z-z0);
00161 }
00162 }
00163
00164 virtual void ModifyELCReceiveData(elc_lagcomm_type* elcLag) {}
00165 virtual void ModifyELCSendData(elc_lagcomm_type* elcLag) {}
00166
00167 protected:
00168 elc_lagcomm_type* _elcLag;
00169 };
00170
00171 #endif