diff --git a/NonLinearSolver/Domain/partDomain.cpp b/NonLinearSolver/Domain/partDomain.cpp
index ddd748da26f3717450dba60ca2bda2a4889a0b3a..e7bdc57d478331232d62c80caf777fd023ea5cbb 100644
--- a/NonLinearSolver/Domain/partDomain.cpp
+++ b/NonLinearSolver/Domain/partDomain.cpp
@@ -1712,222 +1712,6 @@ void dgPartDomain::initMicroMeshId(){
   }
 };
 
-void dgPartDomain::prepareMPIExchange(AllIPState *aips, IPStateBase::whichState ws)
-{
-  MPI_Status status;
-  if (Msg::GetCommRank() == _rootRank){
-    // compute all IP strain on root rank
-    // this->computeAllIPStrain(aips,ufield,ws,false);
-    // send strain to other procs
-    // for bulk elements
-    for (std::set<int>::iterator it = _otherRanks.begin(); it!= _otherRanks.end(); it++){
-      int otherRank = *it;
-      std::set<int>& IPBulkonRank = _mapIPBulk[otherRank];
-      for (std::set<int>::iterator its = IPBulkonRank.begin(); its!= IPBulkonRank.end(); its++){
-        int num = *its;
-        int elnum,gnum;
-        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
-        IPStateBase* ips = (*vips)[gnum];
-        IPVariable* ipv = ips->getState(ws);
-        int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem(); // already known
-        double *buffer = new double[bufferSize];
-        ipv->getMacroDataSendToMicroProblem(buffer);
-        MPI_Send(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD);
-        delete[] buffer;
-      };
-
-      std::set<int>& IPInterfaceMinusonRank = _mapIPInterfaceMinus[otherRank];
-      for (std::set<int>::iterator its = IPInterfaceMinusonRank.begin(); its!= IPInterfaceMinusonRank.end(); its++){
-        int num = *its;
-        int elnum,gnum;
-        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
-        IPStateBase* ips = (*vips)[gnum];
-        IPVariable* ipv = ips->getState(ws);
-        int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem(); // already known
-        double *buffer = new double[bufferSize];
-        ipv->getMacroDataSendToMicroProblem(buffer);
-        MPI_Send(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD);
-        delete[] buffer;
-      };
-
-      std::set<int>& IPInterfacePlusonRank = _mapIPInterfacePlus[otherRank];
-      for (std::set<int>::iterator its = IPInterfacePlusonRank.begin(); its!= IPInterfacePlusonRank.end(); its++){
-        int num = *its;
-        int elnum,gnum;
-        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
-        IPStateBase* ips = (*vips)[gnum];
-        IPVariable* ipv = ips->getState(ws);
-        int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem(); // already known
-        double *buffer = new double[bufferSize];
-        ipv->getMacroDataSendToMicroProblem(buffer);
-        MPI_Send(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD);
-        delete[] buffer;
-      };
-    }
-  }
-  else if (_otherRanks.find(Msg::GetCommRank()) != _otherRanks.end()){
-    for (std::set<int>::iterator it = _domainIPBulk.begin(); it != _domainIPBulk.end(); it++){
-      int num = *it;
-      int elnum,gnum;
-      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
-      IPStateBase* ips = (*vips)[0];
-      IPVariable* ipv = ips->getState(ws);
-      int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem();
-      double *buffer = new double[bufferSize];
-      MPI_Recv(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD,&status);
-      ipv->setReceivedMacroDataToMicroProblem(buffer);
-      delete [] buffer;
-    };
-
-    for (std::set<int>::iterator it = _domainIPInterfaceMinus.begin(); it != _domainIPInterfaceMinus.end(); it++){
-      int num = *it;
-      int elnum, phys, gnum;
-      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
-      IPStateBase* ips = (*vips)[0];
-      IPVariable* ipv = ips->getState(ws);
-      int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem();
-      double *buffer = new double[bufferSize];
-      MPI_Recv(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD,&status);
-      ipv->setReceivedMacroDataToMicroProblem(buffer);
-      delete [] buffer;
-    };
-
-    for (std::set<int>::iterator it = _domainIPInterfacePlus.begin(); it != _domainIPInterfacePlus.end(); it++){
-      int num = *it;
-      int elnum,gnum;
-      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
-      IPStateBase* ips = (*vips)[0];
-      IPVariable* ipv =  ips->getState(ws);
-      int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem();
-      double *buffer = new double[bufferSize];
-      MPI_Recv(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD,&status);
-      ipv->setReceivedMacroDataToMicroProblem(buffer);
-      delete [] buffer;
-    };
-  };
-}
-void dgPartDomain::endMPIExchange(AllIPState *aips, IPStateBase::whichState ws)
-{
-  MPI_Status status;
-  IntPt *GP;
-  if (_otherRanks.find(Msg::GetCommRank()) != _otherRanks.end()){
-    for (std::set<int>::iterator it = _domainIPBulk.begin(); it != _domainIPBulk.end(); it++){
-      int num = *it;
-      int elnum,gnum;
-      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
-      IPStateBase* ips = (*vips)[0];
-      IPVariable* ipv = ips->getState(ws);
-      int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
-      double *buffer = new double[bufferSize];
-      ipv->getMicroDataToMacroProblem(buffer);
-      MPI_Send(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD);
-      delete [] buffer;
-    };
-    for (std::set<int>::iterator it = _domainIPInterfaceMinus.begin(); it != _domainIPInterfaceMinus.end(); it++){
-      int num = *it;
-      int elnum,gnum;
-      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
-      IPStateBase* ips = (*vips)[0];
-      IPVariable* ipv = ips->getState(ws);
-      int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
-      double *buffer = new double[bufferSize];
-      ipv->getMicroDataToMacroProblem(buffer);
-      MPI_Send(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD);
-      delete [] buffer;
-    };
-    for (std::set<int>::iterator it = _domainIPInterfacePlus.begin(); it != _domainIPInterfacePlus.end(); it++){
-      int num = *it;
-      int elnum,gnum;
-      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
-      IPStateBase* ips = (*vips)[0];
-      IPVariable* ipv = ips->getState(ws);
-      int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
-      double *buffer = new double[bufferSize];
-      ipv->getMicroDataToMacroProblem(buffer);
-      MPI_Send(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD);
-      delete [] buffer;
-    };
-  }
-  else if (Msg::GetCommRank() == _rootRank){
-
-    for (std::set<int>::iterator it = _otherRanks.begin(); it!= _otherRanks.end(); it++){
-      int otherRank = *it;
-      std::set<int>& IPBulkonRank = _mapIPBulk[otherRank];
-      for (std::set<int>::iterator its = IPBulkonRank.begin(); its!= IPBulkonRank.end(); its++){
-        int num = *its;
-        int elnum,gnum;
-        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
-        IPStateBase* ips = (*vips)[gnum];
-        IPVariable* ipv = ips->getState(ws);
-        int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
-        double *buffer = new double[bufferSize];
-        MPI_Recv(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD,&status);
-        ipv->setReceivedMicroDataToMacroProblem(buffer);
-        this->getMaterialLaw()->setElasticStiffness(ipv);
-        delete[] buffer;
-      };
-      std::set<int>& IPInterfaceMinusonRank = _mapIPInterfaceMinus[otherRank];
-      for (std::set<int>::iterator its = IPInterfaceMinusonRank.begin(); its!= IPInterfaceMinusonRank.end(); its++){
-        int num = *its;
-        int elnum,gnum;
-        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
-        IPStateBase* ips = (*vips)[gnum];
-        IPVariable* ipv = ips->getState(ws);
-        int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
-        double *buffer = new double[bufferSize];
-        MPI_Recv(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD,&status);
-        ipv->setReceivedMicroDataToMacroProblem(buffer);
-        this->getMaterialLawMinus()->setElasticStiffness(ipv);
-        delete[] buffer;
-      };
-
-      std::set<int>& IPInterfacePlusonRank = _mapIPInterfacePlus[otherRank];
-      for (std::set<int>::iterator its = IPInterfacePlusonRank.begin(); its!= IPInterfacePlusonRank.end(); its++){
-        int num = *its;
-        int elnum,gnum;
-        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
-        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
-        IPStateBase* ips = (*vips)[gnum];
-        IPVariable* ipv = ips->getState(ws);
-        int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
-        double *buffer = new double[bufferSize];
-        MPI_Recv(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD,&status);
-        ipv->setReceivedMicroDataToMacroProblem(buffer);
-        this->getMaterialLawPlus()->setElasticStiffness(ipv);
-        delete[] buffer;
-      };
-    }
-
-    if (_averageStrainBased and (this->getMaterialLawMinus()->getNum() == this->getMaterialLawPlus()->getNum())){
-      for (elementGroup::elementContainer::const_iterator ite = gi->begin(); ite!= gi->end(); ite++){
-        MElement* ele = ite->second;
-        int npts = this->getInterfaceGaussIntegrationRule()->getIntPoints(ele,&GP);
-        AllIPState::ipstateElementContainer *vips = aips->getIPstate(ele->getNum());
-        for(int j=0;j<npts;j++){
-          IPStateBase* ipsm = (*vips)[j];
-          IPStateBase* ipsp = (*vips)[j+npts];
-
-          IPVariable* ipvm = ipsm->getState(IPStateBase::current);
-          IPVariable* ipvp = ipsp->getState(IPStateBase::current);
-
-          ipvp->operator=(*ipvm);
-        }
-
-      }
-    }
-  }
-}
 
 void QuadratureFactory::createBulkGaussQuadrature(MElement* e, QuadratureBase*& integBulk)
 {
@@ -2448,5 +2232,3 @@ void QuadratureFactory::createGaussQuadratureForNeumannBCHierarchicalFE(int orde
     Msg::Error("interface gauss quadrature is not defined for this element type by default");
   }
 };
-
-
diff --git a/NonLinearSolver/Domain/partDomain.h b/NonLinearSolver/Domain/partDomain.h
index de132077ab73b3bd6897ec07b9c6e73fbf0759d1..0ae5514b05b29d41e117873719be658dba5a38d0 100644
--- a/NonLinearSolver/Domain/partDomain.h
+++ b/NonLinearSolver/Domain/partDomain.h
@@ -216,9 +216,6 @@ class partDomain
     virtual void setValuesForBodyForce(AllIPState *aips, const IPStateBase::whichState ws)=0;
     virtual void computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichState ws,
                              materialLaw *mlaw,fullVector<double> &disp, bool stiff)=0;
-    virtual void prepareMPIExchange(AllIPState *aips, IPStateBase::whichState ws)=0;
-    virtual void endMPIExchange(AllIPState *aips, IPStateBase::whichState ws)=0;
-    
     virtual void setGaussIntegrationRule()=0;
     virtual bool getFormulation() const{return _fullDg;}
     virtual void setMaterialLaw(const std::map<int,materialLaw*> &maplaw)=0;
@@ -372,9 +369,7 @@ class dgPartDomain : public partDomain
                               const bool virt, bool stiff,const bool checkfrac=true)=0;
     virtual void computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichState ws,
                               materialLaw *mlaw,fullVector<double> &disp, bool stiff)=0;
-    virtual void prepareMPIExchange(AllIPState *aips, IPStateBase::whichState ws);
-    virtual void endMPIExchange(AllIPState *aips, IPStateBase::whichState ws);
-
+    
     virtual void initiallyBreakAllInterfaceIP(AllIPState *aips) const;
     #if defined(HAVE_MPI)
     virtual void createIPMap();
diff --git a/NonLinearSolver/materialLaw/mlaw.h b/NonLinearSolver/materialLaw/mlaw.h
index dfddcd66dee33de8b83e33f07f318cae89c9d0a4..a9223f0cde82561b869b8d5e377d57fc1772362a 100644
--- a/NonLinearSolver/materialLaw/mlaw.h
+++ b/NonLinearSolver/materialLaw/mlaw.h
@@ -239,7 +239,6 @@ class materialLaw{
   virtual double SecantShearModulus(const IPVariable *q1) const {return 0.;};
   virtual double ResidualSecantShearModulus(const IPVariable *q_unloaded, const IPVariable *q1) const {return 0.;};
   virtual double ZeroResidualSecantShearModulus(const IPVariable *q_unloaded, const IPVariable *q1) const {return 0.;};
-  virtual void setElasticStiffness(IPVariable* ipv) {};
 
   virtual void ElasticStiffnessIsotropic(STensor43& ElasticStiffness) const
                             {
diff --git a/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
index 3c20dd8fd9a0c0ce14b9a23ae178289497434a0c..ba0539180347907b2f515ca446fd5366d1a31772 100644
--- a/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
+++ b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
@@ -13287,8 +13287,7 @@ void nonLinearMechSolver::extractAveragePropertiesPerturbation(homogenizedData*
     /*
     save all computed current data to tmp step
   */
- // estimation of stress matrix
-  
+
   _ipf->copy(IPStateBase::current,IPStateBase::temp);
   std::string Aname ="A";
   linearSystem<double>* lsys = pAssembler->getLinearSystem(Aname);
diff --git a/dG3D/src/dG3DDomain.cpp b/dG3D/src/dG3DDomain.cpp
index a34661b9f914c52e25e50455cfcbb4aece3add28..032c5941e097ca3e223155d19f7da74654545181 100644
--- a/dG3D/src/dG3DDomain.cpp
+++ b/dG3D/src/dG3DDomain.cpp
@@ -2112,6 +2112,226 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
   }
 }
 
+void dG3DDomain::prepareMPIExchange(AllIPState *aips, IPStateBase::whichState ws)
+{
+  MPI_Status status;
+  if (Msg::GetCommRank() == _rootRank){
+    // compute all IP strain on root rank
+    // this->computeAllIPStrain(aips,ufield,ws,false);
+    // send strain to other procs
+    // for bulk elements
+    for (std::set<int>::iterator it = _otherRanks.begin(); it!= _otherRanks.end(); it++){
+      int otherRank = *it;
+      std::set<int>& IPBulkonRank = _mapIPBulk[otherRank];
+      for (std::set<int>::iterator its = IPBulkonRank.begin(); its!= IPBulkonRank.end(); its++){
+        int num = *its;
+        int elnum,gnum;
+        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
+        IPStateBase* ips = (*vips)[gnum];
+        IPVariable* ipv = ips->getState(ws);
+        int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem(); // already known
+        double *buffer = new double[bufferSize];
+        ipv->getMacroDataSendToMicroProblem(buffer);
+        MPI_Send(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD);
+        delete[] buffer;
+      };
+
+      std::set<int>& IPInterfaceMinusonRank = _mapIPInterfaceMinus[otherRank];
+      for (std::set<int>::iterator its = IPInterfaceMinusonRank.begin(); its!= IPInterfaceMinusonRank.end(); its++){
+        int num = *its;
+        int elnum,gnum;
+        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
+        IPStateBase* ips = (*vips)[gnum];
+        IPVariable* ipv = ips->getState(ws);
+        int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem(); // already known
+        double *buffer = new double[bufferSize];
+        ipv->getMacroDataSendToMicroProblem(buffer);
+        MPI_Send(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD);
+        delete[] buffer;
+      };
+
+      std::set<int>& IPInterfacePlusonRank = _mapIPInterfacePlus[otherRank];
+      for (std::set<int>::iterator its = IPInterfacePlusonRank.begin(); its!= IPInterfacePlusonRank.end(); its++){
+        int num = *its;
+        int elnum,gnum;
+        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
+        IPStateBase* ips = (*vips)[gnum];
+        IPVariable* ipv = ips->getState(ws);
+        int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem(); // already known
+        double *buffer = new double[bufferSize];
+        ipv->getMacroDataSendToMicroProblem(buffer);
+        MPI_Send(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD);
+        delete[] buffer;
+      };
+    }
+  }
+  else if (_otherRanks.find(Msg::GetCommRank()) != _otherRanks.end()){
+    for (std::set<int>::iterator it = _domainIPBulk.begin(); it != _domainIPBulk.end(); it++){
+      int num = *it;
+      int elnum,gnum;
+      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
+      IPStateBase* ips = (*vips)[0];
+      IPVariable* ipv = ips->getState(ws);
+      int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem();
+      double *buffer = new double[bufferSize];
+      MPI_Recv(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD,&status);
+      ipv->setReceivedMacroDataToMicroProblem(buffer);
+      delete [] buffer;
+    };
+
+    for (std::set<int>::iterator it = _domainIPInterfaceMinus.begin(); it != _domainIPInterfaceMinus.end(); it++){
+      int num = *it;
+      int elnum, phys, gnum;
+      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
+      IPStateBase* ips = (*vips)[0];
+      IPVariable* ipv = ips->getState(ws);
+      int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem();
+      double *buffer = new double[bufferSize];
+      MPI_Recv(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD,&status);
+      ipv->setReceivedMacroDataToMicroProblem(buffer);
+      delete [] buffer;
+    };
+
+    for (std::set<int>::iterator it = _domainIPInterfacePlus.begin(); it != _domainIPInterfacePlus.end(); it++){
+      int num = *it;
+      int elnum,gnum;
+      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
+      IPStateBase* ips = (*vips)[0];
+      IPVariable* ipv =  ips->getState(ws);
+      int bufferSize = ipv->getMacroNumberElementDataSendToMicroProblem();
+      double *buffer = new double[bufferSize];
+      MPI_Recv(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD,&status);
+      ipv->setReceivedMacroDataToMicroProblem(buffer);
+      delete [] buffer;
+    };
+  };
+}
+void dG3DDomain::endMPIExchange(AllIPState *aips, IPStateBase::whichState ws)
+{
+  MPI_Status status;
+  IntPt *GP;
+  if (_otherRanks.find(Msg::GetCommRank()) != _otherRanks.end()){
+    for (std::set<int>::iterator it = _domainIPBulk.begin(); it != _domainIPBulk.end(); it++){
+      int num = *it;
+      int elnum,gnum;
+      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
+      IPStateBase* ips = (*vips)[0];
+      IPVariable* ipv = ips->getState(ws);
+      int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
+      double *buffer = new double[bufferSize];
+      ipv->getMicroDataToMacroProblem(buffer);
+      MPI_Send(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD);
+      delete [] buffer;
+    };
+    for (std::set<int>::iterator it = _domainIPInterfaceMinus.begin(); it != _domainIPInterfaceMinus.end(); it++){
+      int num = *it;
+      int elnum,gnum;
+      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
+      IPStateBase* ips = (*vips)[0];
+      IPVariable* ipv = ips->getState(ws);
+      int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
+      double *buffer = new double[bufferSize];
+      ipv->getMicroDataToMacroProblem(buffer);
+      MPI_Send(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD);
+      delete [] buffer;
+    };
+    for (std::set<int>::iterator it = _domainIPInterfacePlus.begin(); it != _domainIPInterfacePlus.end(); it++){
+      int num = *it;
+      int elnum,gnum;
+      numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+      AllIPState::ipstateElementContainer *vips = aips->getIPstate(num);
+      IPStateBase* ips = (*vips)[0];
+      IPVariable* ipv = ips->getState(ws);
+      int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
+      double *buffer = new double[bufferSize];
+      ipv->getMicroDataToMacroProblem(buffer);
+      MPI_Send(buffer,bufferSize,MPI_DOUBLE,_rootRank,num,MPI_COMM_WORLD);
+      delete [] buffer;
+    };
+  }
+  else if (Msg::GetCommRank() == _rootRank){
+
+    for (std::set<int>::iterator it = _otherRanks.begin(); it!= _otherRanks.end(); it++){
+      int otherRank = *it;
+      std::set<int>& IPBulkonRank = _mapIPBulk[otherRank];
+      for (std::set<int>::iterator its = IPBulkonRank.begin(); its!= IPBulkonRank.end(); its++){
+        int num = *its;
+        int elnum,gnum;
+        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
+        IPStateBase* ips = (*vips)[gnum];
+        IPVariable* ipv = ips->getState(ws);
+        int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
+        double *buffer = new double[bufferSize];
+        MPI_Recv(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD,&status);
+        ipv->setReceivedMicroDataToMacroProblem(buffer);
+        dG3DMaterialLaw* mlaw = dynamic_cast<dG3DMaterialLaw*>(this->getMaterialLaw());
+        mlaw->setElasticStiffness(ipv);
+        delete[] buffer;
+      };
+      std::set<int>& IPInterfaceMinusonRank = _mapIPInterfaceMinus[otherRank];
+      for (std::set<int>::iterator its = IPInterfaceMinusonRank.begin(); its!= IPInterfaceMinusonRank.end(); its++){
+        int num = *its;
+        int elnum,gnum;
+        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
+        IPStateBase* ips = (*vips)[gnum];
+        IPVariable* ipv = ips->getState(ws);
+        int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
+        double *buffer = new double[bufferSize];
+        MPI_Recv(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD,&status);
+        ipv->setReceivedMicroDataToMacroProblem(buffer);
+        dG3DMaterialLaw* mlawMinus = dynamic_cast<dG3DMaterialLaw*>(this->getMaterialLawMinus());
+        mlawMinus->setElasticStiffness(ipv);
+        delete[] buffer;
+      };
+
+      std::set<int>& IPInterfacePlusonRank = _mapIPInterfacePlus[otherRank];
+      for (std::set<int>::iterator its = IPInterfacePlusonRank.begin(); its!= IPInterfacePlusonRank.end(); its++){
+        int num = *its;
+        int elnum,gnum;
+        numericalMaterialBase::getTwoIntsFromType(num,elnum,gnum);
+        AllIPState::ipstateElementContainer *vips = aips->getIPstate(elnum);
+        IPStateBase* ips = (*vips)[gnum];
+        IPVariable* ipv = ips->getState(ws);
+        int bufferSize = ipv->getMicroNumberElementDataSendToMacroProblem();
+        double *buffer = new double[bufferSize];
+        MPI_Recv(buffer,bufferSize,MPI_DOUBLE,otherRank,num,MPI_COMM_WORLD,&status);
+        ipv->setReceivedMicroDataToMacroProblem(buffer);
+        dG3DMaterialLaw* mlawPlus = dynamic_cast<dG3DMaterialLaw*>(this->getMaterialLawPlus());
+        mlawPlus->setElasticStiffness(ipv);
+        delete[] buffer;
+      };
+    }
+
+    if (_averageStrainBased and (this->getMaterialLawMinus()->getNum() == this->getMaterialLawPlus()->getNum())){
+      for (elementGroup::elementContainer::const_iterator ite = gi->begin(); ite!= gi->end(); ite++){
+        MElement* ele = ite->second;
+        int npts = this->getInterfaceGaussIntegrationRule()->getIntPoints(ele,&GP);
+        AllIPState::ipstateElementContainer *vips = aips->getIPstate(ele->getNum());
+        for(int j=0;j<npts;j++){
+          IPStateBase* ipsm = (*vips)[j];
+          IPStateBase* ipsp = (*vips)[j+npts];
+
+          IPVariable* ipvm = ipsm->getState(IPStateBase::current);
+          IPVariable* ipvp = ipsp->getState(IPStateBase::current);
+
+          ipvp->operator=(*ipvm);
+        }
+
+      }
+    }
+  }
+}
+
 
 void dG3DDomain::computeIpvMPI(AllIPState *aips,MElement *e, IPStateBase::whichState ws,
                                         materialLaw *mlaw__,fullVector<double> &disp, bool stiff)
@@ -2129,13 +2349,13 @@ void dG3DDomain::computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichStat
   if (!getElementErosionFilter()(e)) return;
 
 
-/*#if defined(HAVE_MPI)
-  if (mlaw__->isNumeric() and this->_otherRanks.size()>0 and stiff==false)
-  {
-   this->computeIpvMPI(aips,e,ws,mlaw__,disp,stiff);
-  }
-  else
-#endif //HAVE_MPI*/
+  //#if defined(HAVE_MPI)
+  //if (mlaw__->isNumeric() and this->_otherRanks.size()>0 and stiff==false)
+  //{
+  // this->computeIpvMPI(aips,e,ws,mlaw__,disp,stiff);
+  //}
+  //else
+  //#endif //HAVE_MPI
   {
 
 
diff --git a/dG3D/src/dG3DDomain.h b/dG3D/src/dG3DDomain.h
index ac9755082662cf1abbd07c26bc7da8777620f8df..80bd80cc746ee15f51be70c68bdc18b2e9ba0652 100644
--- a/dG3D/src/dG3DDomain.h
+++ b/dG3D/src/dG3DDomain.h
@@ -280,6 +280,9 @@ class dG3DDomain : public dgPartDomain{
     }
   };
 
+  virtual void prepareMPIExchange(AllIPState *aips, IPStateBase::whichState ws);
+  virtual void endMPIExchange(AllIPState *aips, IPStateBase::whichState ws);
+
 #endif
 };