Skip to content
Snippets Groups Projects
Commit 61a06de0 authored by Jonathan Lambrechts's avatar Jonathan Lambrechts
Browse files

dg : parallel implicit CG

parent 64898518
No related branches found
No related tags found
No related merge requests found
...@@ -7,6 +7,7 @@ set(SRC ...@@ -7,6 +7,7 @@ set(SRC
linearSystem.cpp linearSystem.cpp
linearSystemCSR.cpp linearSystemCSR.cpp
linearSystemPETSc.cpp linearSystemPETSc.cpp
dofManager.cpp
groupOfElements.cpp groupOfElements.cpp
elasticityTerm.cpp elasticityTerm.cpp
elasticitySolver.cpp elasticitySolver.cpp
......
#include <dofManager.h>
template<>
void dofManager<double>::scatterSolution()
{
#ifdef HAVE_MPI
if (!_parallelFinalized) {
_parallelFinalize();
}
MPI_Status status;
std::vector<std::vector<double> > sendBuf(Msg::GetCommSize()), recvBuf(Msg::GetCommSize());
std::vector<MPI_Request> reqRecv(Msg::GetCommSize()), reqSend(Msg::GetCommSize());
for (int i = 0; i<Msg::GetCommSize(); i++) {
reqRecv[i] = reqSend[i] = MPI_REQUEST_NULL;
if (!ghostByProc[i].empty()) {
recvBuf[i].resize(ghostByProc[i].size());
MPI_Irecv (&recvBuf[i][0], recvBuf[i].size(), MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &reqRecv[i]);
}
if (!parentByProc[i].empty()) {
getDofValue(parentByProc[i], sendBuf[i]);
MPI_Isend(&sendBuf[i][0], sendBuf[i].size(), MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &reqSend[i]);
}
}
int index;
while (MPI_Waitany (Msg::GetCommSize(), &reqRecv[0], &index, &status) == 0 && index != MPI_UNDEFINED) {
if (status.MPI_TAG == 0)
for (int j = 0; j < recvBuf[index].size(); j++) {
ghostValue[ghostByProc[index][j]] = recvBuf[index][j];
const Dof &dof = ghostByProc[index][j];
}
}
MPI_Waitall (Msg::GetCommSize(), &reqSend[0], MPI_STATUS_IGNORE);
#endif
}
...@@ -124,12 +124,15 @@ class dofManager{ ...@@ -124,12 +124,15 @@ class dofManager{
private : private :
// those dof are images of ghost located on another proc (id givent by the map). // those dof are images of ghost located on another proc (id givent by the map).
// this is a first try, maybe not the final implementation // this is a first try, maybe not the final implementation
std::map<Dof, int > ghosted; // dof => procId std::map<Dof, std::pair<int, int> > ghostByDof; // dof => procId, globalId
std::map<Dof, T> ghostValue;
std::vector<std::vector<Dof> > ghostByProc, parentByProc;
int _localSize; int _localSize;
bool _parallelFinalized; bool _parallelFinalized;
bool _isParallel; bool _isParallel;
public:
void _parallelFinalize(); void _parallelFinalize();
public:
void scatterSolution();
public: public:
dofManager(linearSystem<dataMat> *l, bool isParallel=false) dofManager(linearSystem<dataMat> *l, bool isParallel=false)
...@@ -175,14 +178,14 @@ class dofManager{ ...@@ -175,14 +178,14 @@ class dofManager{
inline void numberGhostDof (Dof key, int procId) { inline void numberGhostDof (Dof key, int procId) {
if (fixed.find(key) != fixed.end()) return; if (fixed.find(key) != fixed.end()) return;
if (constraints.find(key) != constraints.end()) return; if (constraints.find(key) != constraints.end()) return;
if (ghosted.find(key) != ghosted.end()) return; if (ghostByDof.find(key) != ghostByDof.end()) return;
ghosted[key] = procId; ghostByDof[key] = std::make_pair(procId, 0);
} }
inline void numberDof(Dof key) inline void numberDof(Dof key)
{ {
if (fixed.find(key) != fixed.end()) return; if (fixed.find(key) != fixed.end()) return;
if (constraints.find(key) != constraints.end()) return; if (constraints.find(key) != constraints.end()) return;
if (ghosted.find(key) != ghosted.end()) return; if (ghostByDof.find(key) != ghostByDof.end()) return;
std::map<Dof, int> :: iterator it = unknown.find(key); std::map<Dof, int> :: iterator it = unknown.find(key);
if (it == unknown.end()) { if (it == unknown.end()) {
...@@ -208,8 +211,8 @@ class dofManager{ ...@@ -208,8 +211,8 @@ class dofManager{
virtual inline void getDofValue(Dof key, dataVec &val) const virtual inline void getDofValue(Dof key, dataVec &val) const
{ {
{ {
typename std::map<Dof, dataVec>::const_iterator it = fixed.find(key); typename std::map<Dof, dataVec>::const_iterator it = ghostValue.find(key);
if (it != fixed.end()) { if (it != ghostValue.end()) {
val = it->second; val = it->second;
return; return;
} }
...@@ -221,6 +224,13 @@ class dofManager{ ...@@ -221,6 +224,13 @@ class dofManager{
return; return;
} }
} }
{
typename std::map<Dof, dataVec>::const_iterator it = fixed.find(key);
if (it != fixed.end()) {
val = it->second;
return;
}
}
{ {
typename std::map<Dof, DofAffineConstraint< dataVec > >::const_iterator it = typename std::map<Dof, DofAffineConstraint< dataVec > >::const_iterator it =
constraints.find(key); constraints.find(key);
...@@ -239,36 +249,7 @@ class dofManager{ ...@@ -239,36 +249,7 @@ class dofManager{
} }
inline void getDofValue(int ent, int type, dataVec &v) const inline void getDofValue(int ent, int type, dataVec &v) const
{ {
Dof key(ent, type); getDofValue(Dof(ent, type), v);
{
typename std::map<Dof, dataVec>::const_iterator it = fixed.find(key);
if (it != fixed.end()){
v = it->second;
return;
}
}
{
std::map<Dof, int>::const_iterator it = unknown.find(key);
if (it != unknown.end()){
_current->getFromSolution(it->second, v);
return;
}
}
{
typename std::map<Dof, DofAffineConstraint< dataVec > >::const_iterator it =
constraints.find(key);
if (it != constraints.end()){
v = it->second.shift;
dataVec tmp(v);
for (unsigned i = 0; i < (it->second).linear.size(); i++){
std::map<Dof, int>::const_iterator itu = unknown.find
(((it->second).linear[i]).first);
getDofValue(((it->second).linear[i]).first, tmp);
dofTraits<T>::gemm(v, ((it->second).linear[i]).second, tmp, 1, 1);
}
return;
}
}
} }
inline void getDofValue(MVertex *v, int iComp, int iField, dataVec &value) const inline void getDofValue(MVertex *v, int iComp, int iField, dataVec &value) const
{ {
...@@ -576,6 +557,8 @@ void dofManager<T>::_parallelFinalize() ...@@ -576,6 +557,8 @@ void dofManager<T>::_parallelFinalize()
int _numStart; int _numStart;
int _numTotal; int _numTotal;
MPI_Status status; MPI_Status status;
parentByProc.resize(Msg::GetCommSize());
ghostByProc.resize(Msg::GetCommSize());
if (Msg::GetCommRank() == 0){ if (Msg::GetCommRank() == 0){
_numStart = 0; _numStart = 0;
} }
...@@ -592,8 +575,10 @@ void dofManager<T>::_parallelFinalize() ...@@ -592,8 +575,10 @@ void dofManager<T>::_parallelFinalize()
int *nRequested = new int[Msg::GetCommSize()]; int *nRequested = new int[Msg::GetCommSize()];
for (int i = 0; i<Msg::GetCommSize(); i++) for (int i = 0; i<Msg::GetCommSize(); i++)
nRequest[i] = 0; nRequest[i] = 0;
for (std::map <Dof, int >::iterator it = ghosted.begin(); it != ghosted.end(); it++) for (std::map <Dof, std::pair<int, int> >::iterator it = ghostByDof.begin(); it != ghostByDof.end(); it++) {
nRequest[it->second] ++; int procId = it->second.first;
it->second.second = nRequest[procId]++;
}
MPI_Alltoall(nRequest, 1, MPI_INT, nRequested, 1, MPI_INT, MPI_COMM_WORLD); MPI_Alltoall(nRequest, 1, MPI_INT, nRequested, 1, MPI_INT, MPI_COMM_WORLD);
long int **recv0 = new long int*[Msg::GetCommSize()]; long int **recv0 = new long int*[Msg::GetCommSize()];
int **recv1 = new int*[Msg::GetCommSize()]; int **recv1 = new int*[Msg::GetCommSize()];
...@@ -609,13 +594,16 @@ void dofManager<T>::_parallelFinalize() ...@@ -609,13 +594,16 @@ void dofManager<T>::_parallelFinalize()
send1[i] = new int[nRequested[i]]; send1[i] = new int[nRequested[i]];
recv1[i] = new int[nRequest[i]]; recv1[i] = new int[nRequest[i]];
reqSend0[i] = reqSend1[i] = reqRecv0[i] = reqRecv1[i] = MPI_REQUEST_NULL; reqSend0[i] = reqSend1[i] = reqRecv0[i] = reqRecv1[i] = MPI_REQUEST_NULL;
parentByProc[i].resize(nRequested[i], Dof(0,0));
ghostByProc[i].resize(nRequest[i], Dof(0,0));
} }
for (int i = 0; i<Msg::GetCommSize(); i++) for (int i = 0; i<Msg::GetCommSize(); i++)
nRequest [i] = 0; nRequest [i] = 0;
for (std::map <Dof, int >::iterator it = ghosted.begin(); it != ghosted.end(); it++) { for (std::map <Dof, std::pair<int, int> >::iterator it = ghostByDof.begin(); it != ghostByDof.end(); it++) {
int proc = it->second; int proc = it->second.first;
send0 [proc] [nRequest[proc]*2] = it->first.getEntity(); send0 [proc] [nRequest[proc]*2] = it->first.getEntity();
send0 [proc] [nRequest[proc]*2+1] = it->first.getType(); send0 [proc] [nRequest[proc]*2+1] = it->first.getType();
ghostByProc[proc][nRequest[proc]] = it->first;
nRequest [proc] ++; nRequest [proc] ++;
} }
for (int i = 0; i<Msg::GetCommSize(); i++) { for (int i = 0; i<Msg::GetCommSize(); i++) {
...@@ -632,20 +620,22 @@ void dofManager<T>::_parallelFinalize() ...@@ -632,20 +620,22 @@ void dofManager<T>::_parallelFinalize()
index != MPI_UNDEFINED) { index != MPI_UNDEFINED) {
if (status.MPI_TAG == 0) { if (status.MPI_TAG == 0) {
for (int j = 0; j < nRequested[index]; j++) { for (int j = 0; j < nRequested[index]; j++) {
std::map<Dof, int>::iterator it = unknown.find Dof d(recv0[index][j*2], recv0[index][j*2+1]);
(Dof(recv0[index][j*2], recv0[index][j*2+1])); std::map<Dof, int>::iterator it = unknown.find(d);
if (it == unknown.end ()) if (it == unknown.end ())
Msg::Error ("ghost Dof does not exist on parent process"); Msg::Error ("ghost Dof does not exist on parent process");
send1[index][j] = it->second; send1[index][j] = it->second;
parentByProc[index][j] = d;
} }
MPI_Isend(send1[index], nRequested[index], MPI_INT, index, 1, MPI_Isend(send1[index], nRequested[index], MPI_INT, index, 1,
MPI_COMM_WORLD, &reqSend1[index]); MPI_COMM_WORLD, &reqSend1[index]);
} }
} }
for (int i = 0; i<Msg::GetCommSize(); i++)
for (int i = 0; i<Msg::GetCommSize(); i++) for (int i = 0; i<Msg::GetCommSize(); i++)
nRequest[i] = 0; nRequest[i] = 0;
for (std::map <Dof, int>::iterator it = ghosted.begin(); it != ghosted.end(); it++) { for (std::map <Dof, std::pair<int, int> >::iterator it = ghostByDof.begin(); it != ghostByDof.end(); it++) {
int proc = it->second; int proc = it->second.first;
unknown[it->first] = recv1 [proc][nRequest[proc] ++]; unknown[it->first] = recv1 [proc][nRequest[proc] ++];
} }
MPI_Waitall (Msg::GetCommSize(), reqSend0, MPI_STATUS_IGNORE); MPI_Waitall (Msg::GetCommSize(), reqSend0, MPI_STATUS_IGNORE);
......
...@@ -23,6 +23,7 @@ class linearSystemBase { ...@@ -23,6 +23,7 @@ class linearSystemBase {
virtual int systemSolve() = 0; virtual int systemSolve() = 0;
void setParameter (std::string key, std::string value); void setParameter (std::string key, std::string value);
virtual void insertInSparsityPattern(int _row, int _col){}; virtual void insertInSparsityPattern(int _row, int _col){};
virtual double normInfRightHandSide() const = 0;
}; };
template <class scalar> template <class scalar>
...@@ -35,7 +36,6 @@ class linearSystem : public linearSystemBase { ...@@ -35,7 +36,6 @@ class linearSystem : public linearSystemBase {
virtual void addToRightHandSide(int _row, const scalar &val) = 0; virtual void addToRightHandSide(int _row, const scalar &val) = 0;
virtual void getFromRightHandSide(int _row, scalar &val) const = 0; virtual void getFromRightHandSide(int _row, scalar &val) const = 0;
virtual void getFromSolution(int _row, scalar &val) const = 0; virtual void getFromSolution(int _row, scalar &val) const = 0;
virtual double normInfRightHandSide() const = 0;
}; };
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment