vtf-logo

AdlibELCCoupledSolver.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2007 California Institute of Technology
00004 // Ralf Deiterding, ralf@amroc.net
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     // instantiate an elc object for data exchange
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     // update fluid/solid boundary
00055     adlib::AdlibBoundaryUpdate(&base::Boundary());
00056     
00057     int elNumNodes = base::Boundary().bNodes;
00058     int elNumElements = base::Boundary().bFacets;
00059     
00060     // list length = elNumNodes
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     // list length = dim*elNumNodes 
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     // list length = dim*elNumElements
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     // Necessary if solid domain larger than fluid domain
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     // apply pressure loading
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

Generated on Fri Aug 24 12:55:26 2007 for Adlib Finite Element Solver by  doxygen 1.4.7