From 5236fab8f8b6986e7679b6f846be925c0dd6b091 Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Mon, 1 Jun 2020 09:08:48 +0200
Subject: [PATCH 01/19] done domain

---
 .../space/ThreeDLagrangeFunctionSpace.cpp     |  50 ++
 .../space/ThreeDLagrangeFunctionSpace.h       | 589 ++++++++-----
 NonLinearSolver/space/mixedFunctionSpace.h    |   5 +
 NonLinearSolver/space/nlsFunctionSpace.h      | 178 +++-
 dG3D/src/dG3DDomain.cpp                       | 775 +++++++++++-------
 dG3D/src/dG3DDomain.h                         |   6 +
 6 files changed, 1057 insertions(+), 546 deletions(-)

diff --git a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.cpp b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.cpp
index 7963bda23..4981ee672 100644
--- a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.cpp
+++ b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.cpp
@@ -11,7 +11,57 @@
 //
 
 #include "ThreeDLagrangeFunctionSpace.h"
+#include "MElement.h"
+#include "MPoint.h"
 
+std::map<int,MElement*> VertexBasedLagrangeFunctionSpace::primaryElementMap;
+MElement* VertexBasedLagrangeFunctionSpace::getPrimaryElement(MElement* ele)
+{
+  if (ele->getPolynomialOrder() == 1) return ele;
+  int type = ele->getType();
+  std::map<int,MElement*>::iterator itF = primaryElementMap.find(type);
+  if (itF == primaryElementMap.end())
+  {
+    return itF->second;
+  }
+  else
+  {
+    std::vector<MVertex*> vver;
+    for(int j=0;j<ele->getNumPrimaryVertices();j++)
+    {
+      vver.push_back(new MVertex(0.,0.,0.));
+    }
+    MElement *eletmp = NULL;
+    MElementFactory factory;
+    switch(ele->getType())
+    {
+      case TYPE_PNT:
+        eletmp = new MPoint(vver[0]); break;
+      case TYPE_LIN:
+        eletmp = factory.create(MSH_LIN_2,vver); break;
+      case TYPE_TRI:
+        eletmp = factory.create(MSH_TRI_3,vver); break;
+      case TYPE_QUA:
+        eletmp = factory.create(MSH_QUA_4,vver); break;
+      case TYPE_TET:
+        eletmp = factory.create(MSH_TET_4,vver); break;
+      case TYPE_PYR:
+        eletmp = factory.create(MSH_PYR_5,vver); break;
+      case TYPE_PRI:
+        eletmp = factory.create(MSH_PRI_6,vver); break;
+      case TYPE_HEX:
+        eletmp = factory.create(MSH_HEX_8,vver); break;
+      case TYPE_POLYG:
+        eletmp = factory.create(MSH_POLYG_,vver); break;
+      case TYPE_POLYH:
+        eletmp = factory.create(MSH_POLYH_,vver); break;
+      default:
+        Msg::Error("unknown element type %d",ele->getType());
+    }
+    primaryElementMap.insert(std::pair<int,MElement*>(ele->getType(),eletmp));
+    return eletmp;
+  }
+}
 
 ThreeDLagrangeFunctionSpace::ThreeDLagrangeFunctionSpace(int id, int ncomp,bool hesscompute, bool thirdcompute) : 
     VertexBasedLagrangeFunctionSpace(id,ncomp,hesscompute,thirdcompute)
diff --git a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
index eee2c91bb..a75d5814c 100644
--- a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
+++ b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
@@ -25,14 +25,19 @@ class VertexBasedLagrangeFunctionSpace : public nlsFunctionSpace<double>
     std::vector<int> ifield; // id field for each field
     // number of comp;
     int _ncomp;
+    std::set<int> _usePrimaryShapeFunctions;
+    
     
   protected:
     virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const=0;
 
+  public:
+    static std::map<int,MElement*> primaryElementMap; // to avoid reallocated
+    static MElement* getPrimaryElement(MElement* ele);
   
   public:
     VertexBasedLagrangeFunctionSpace(int id, int ncomp, bool hesscompute, bool thirdcompute) : 
-    _ncomp(ncomp),
+    _ncomp(ncomp), _usePrimaryShapeFunctions(),
     _hessianComputation(hesscompute), _thirdDevComputation(thirdcompute)
     {
       _iField = id;
@@ -44,6 +49,48 @@ class VertexBasedLagrangeFunctionSpace : public nlsFunctionSpace<double>
     }
     virtual ~VertexBasedLagrangeFunctionSpace(){};
     
+    virtual void usePrimaryShapeFunction(int c)
+    {
+      _usePrimaryShapeFunctions.insert(c);
+      Msg::Info("comp %d considers primary shape functions");
+    }
+    virtual bool withPrimaryShapeFunction(int c) const
+    {
+      return _usePrimaryShapeFunctions.find(c) != _usePrimaryShapeFunctions.end();
+    }
+    
+    virtual int getNumShapeFunctions(MElement* ele, int c) const
+    {
+      if (withPrimaryShapeFunction(c))
+      {
+        return ele->getNumPrimaryShapeFunctions();
+      }
+      else
+      {
+        return ele->getNumShapeFunctions();
+      }
+    };
+    
+    virtual int getNumShapeFunctions(MElement* ele, const std::vector<int>& cv) const
+    {
+      int num = 0;
+      for (int i=0; i< cv.size(); i++)
+      {
+        num += getNumShapeFunctions(ele,cv[i]);
+      }
+      return num;
+    }
+    
+    virtual int getTotalNumShapeFunctions(MElement* ele) const
+    {
+      int num = 0;
+      for (int i=0; i< comp.size(); i++)
+      {
+        num += getNumShapeFunctions(ele,comp[i]);
+      }
+      return num;
+    };
+
     virtual bool withHessianComputation() const {return _hessianComputation;};
     virtual bool withThirdDevComputation() const {return _thirdDevComputation;};
     virtual int getNumComp() const {return _ncomp;};
@@ -124,246 +171,357 @@ class VertexBasedLagrangeFunctionSpace : public nlsFunctionSpace<double>
           keys.push_back(elekeys[idx+numVer*vercomp[vc]]);
       }
     };
-};
-
-
-// Lagrange function space
-class ThreeDLagrangeFunctionSpace : public VertexBasedLagrangeFunctionSpace
-{
-  protected:
-    virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const=0;
     
-  public:
-    ThreeDLagrangeFunctionSpace(int id, int ncomp,bool hesscompute, bool thirdcompute);
-    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, bool hesscompute, bool thirdcompute);
-    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, int comp2_, const bool hessc, const bool thirdc);
-    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, int comp2_, int comp3_,
-                              const bool hessc, const bool thirdc) ;
-    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, int comp2_, int comp3_,
-                                int comp4_,const bool hessc, const bool thirdc);
-    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, int comp2_, int comp3_,
-                                int comp4_, int comp5_,const bool hessc, const bool thirdc);
-    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, int comp2_, int comp3_,
-                                int comp4_, int comp5_, int comp6_, const bool hessc, const bool thirdc);
-    virtual ~ThreeDLagrangeFunctionSpace(){}
-    
-    virtual FunctionSpaceBase* clone(const int id) const 
-    {
-      Msg::Error("define ThreeDLagrangeFunctionSpace::clone!!!");
-      return NULL;
-    }
-    
-
+    // shape function
     virtual void f(MElement *ele, double u, double v, double w, std::vector<ValType> &vals) const
     {
-      ele->getShapeFunctions(u,v,w,_ival);
-      int nbFF = ele->getNumShapeFunctions();
       int valssize = vals.size();
-      vals.resize(valssize + _ncomp*nbFF);
-      for(int i=0;i<nbFF;i++)
-        for(int l=0;l<_ncomp;l++)
-          vals[valssize + i+l*nbFF] = _ival[i];
+      int totalnbFF = getTotalNumShapeFunctions(ele);
+      vals.resize(valssize + totalnbFF);
+      int lastTotalnbFF = 0;
+      for(int l=0;l<_ncomp;l++)
+      {
+        int cc = comp[l];
+        int nbFF = getNumShapeFunctions(ele,cc);
+        if (withPrimaryShapeFunction(cc))
+        {
+          MElement* elePrimary = VertexBasedLagrangeFunctionSpace::getPrimaryElement(ele);
+          elePrimary->getShapeFunctions(u,v,w,_ival);
+        }
+        else
+        {
+          ele->getShapeFunctions(u,v,w,_ival);
+        }
+        for(int i=0;i<nbFF;i++)          
+        {
+          vals[valssize+i+lastTotalnbFF] = _ival[i];
+        }
+        lastTotalnbFF += nbFF;
+      }
     }
-
+    
     virtual void fuvw(MElement *ele, double u, double v, double w, std::vector<ValType> &vals) const
     {
-      ele->getShapeFunctions(u,v,w,_ival);
-      int nbFF = ele->getNumShapeFunctions();
       int valssize = vals.size();
-      vals.resize(valssize + _ncomp*nbFF);
-      for(int i=0;i<nbFF;i++)
-        for(int l=0;l<_ncomp;l++)
-          vals[valssize + i+l*nbFF] = _ival[i];
+      int totalnbFF = getTotalNumShapeFunctions(ele);
+      vals.resize(valssize + totalnbFF);
+      int lastTotalnbFF = 0;
+      for(int l=0;l<_ncomp;l++)
+      {
+        int cc = comp[l];
+        int nbFF = getNumShapeFunctions(ele,cc);
+        if (withPrimaryShapeFunction(cc))
+        {
+          MElement* elePrimary = VertexBasedLagrangeFunctionSpace::getPrimaryElement(ele);
+          elePrimary->getShapeFunctions(u,v,w,_ival);
+        }
+        else
+        {
+          ele->getShapeFunctions(u,v,w,_ival);
+        }
+        for(int i=0;i<nbFF;i++)          
+        {
+          vals[valssize+i+lastTotalnbFF] = _ival[i];
+        }
+        lastTotalnbFF += nbFF;
+      }
     }
-
+    
+    
     virtual void gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads) const
     {
-      ele->getGradShapeFunctions(u, v, w, _igrad);
-      int nbFF = ele->getNumShapeFunctions();
+      int gradssize = grads.size();
+      int totalnbFF = getTotalNumShapeFunctions(ele);
+      grads.resize(gradssize + totalnbFF);
+      int lastTotalnbFF = 0;
       double jac[3][3];
       double invjac[3][3];
-      const double detJ = ele->getJacobian(u, v, w, jac);
-      inv3x3(jac, invjac);
-      int gradssize = grads.size();
-      grads.resize(gradssize + _ncomp*nbFF);
-      for(int i = 0; i < nbFF; ++i)
+      for(int l=0;l<_ncomp; l++)
       {
-        gradt(0)=invjac[0][0] * _igrad[i][0] + invjac[0][1] * _igrad[i][1] + invjac[0][2] * _igrad[i][2];
-        gradt(1)=invjac[1][0] * _igrad[i][0] + invjac[1][1] * _igrad[i][1] + invjac[1][2] * _igrad[i][2];
-        gradt(2)=invjac[2][0] * _igrad[i][0] + invjac[2][1] * _igrad[i][1] + invjac[2][2] * _igrad[i][2];
-        for(int l=0;l<_ncomp;l++) // same values for all comp
-          grads[gradssize + i+l*nbFF]=gradt;
+        int cc = comp[l];
+        int nbFF = getNumShapeFunctions(ele,cc);
+        
+        if (withPrimaryShapeFunction(cc))
+        {
+          MElement* elePrimary = VertexBasedLagrangeFunctionSpace::getPrimaryElement(ele);
+          elePrimary->getGradShapeFunctions(u,v,w,_igrad);
+          double detJ = elePrimary->getJacobian(u, v, w, jac);
+        }
+        else
+        {
+          ele->getGradShapeFunctions(u,v,w,_igrad);
+          double detJ = ele->getJacobian(u, v, w, jac);
+        }
+        inv3x3(jac, invjac);
+      
+        for(int i=0;i<nbFF;i++)
+        {
+          gradt(0)=invjac[0][0] * _igrad[i][0] + invjac[0][1] * _igrad[i][1] + invjac[0][2] * _igrad[i][2];
+          gradt(1)=invjac[1][0] * _igrad[i][0] + invjac[1][1] * _igrad[i][1] + invjac[1][2] * _igrad[i][2];
+          gradt(2)=invjac[2][0] * _igrad[i][0] + invjac[2][1] * _igrad[i][1] + invjac[2][2] * _igrad[i][2];
+          grads[gradssize + i + lastTotalnbFF] = gradt;
+        }
+        lastTotalnbFF += nbFF;
       }
     }
     virtual void gradfuvw(MElement *ele, double u, double v, double w, std::vector<GradType> &grads) const
     {
-      ele->getGradShapeFunctions(u,v,w,_igrad);
-      int nbFF = ele->getNumShapeFunctions();
       int gradssize = grads.size();
-      grads.resize(gradssize + _ncomp*nbFF);
-      for(int i=0;i<nbFF;i++){
-        gradt(0) = _igrad[i][0];
-        gradt(1) = _igrad[i][1];
-        gradt(2) = _igrad[i][2];
-        for(int l=0;l<_ncomp; l++)
-          grads[gradssize + i + l*nbFF] = gradt;
+      int totalnbFF = getTotalNumShapeFunctions(ele);
+      grads.resize(gradssize + totalnbFF);
+      int lastTotalnbFF = 0;
+      for(int l=0;l<_ncomp; l++)
+      {
+        int cc = comp[l];
+        int nbFF = getNumShapeFunctions(ele,cc);
+        if (withPrimaryShapeFunction(cc))
+        {
+          MElement* elePrimary = VertexBasedLagrangeFunctionSpace::getPrimaryElement(ele);
+          elePrimary->getGradShapeFunctions(u,v,w,_igrad);
+        }
+        else
+        {
+          ele->getGradShapeFunctions(u,v,w,_igrad);
+        }
+      
+        for(int i=0;i<nbFF;i++)
+        {
+          gradt(0) = _igrad[i][0];
+          gradt(1) = _igrad[i][1];
+          gradt(2) = _igrad[i][2];
+          grads[gradssize + i + lastTotalnbFF] = gradt;
+        }
+        lastTotalnbFF += nbFF;
       }
     }
+    
     virtual void hessfuvw(MElement *ele, double u, double v, double w,std::vector<HessType> &hess) const
     {
-      ele->getHessShapeFunctions(u,v,w,_ihess);
-      int nbFF = ele->getNumShapeFunctions();
       int hesssize = hess.size();
-      hess.resize(hesssize + _ncomp*nbFF);
-      for(int i=0;i<nbFF;i++){
-        hesst(0,0) = _ihess[i][0][0]; hesst(0,1) = _ihess[i][0][1]; hesst(0,2) = _ihess[i][0][2];
-        hesst(1,0) = _ihess[i][1][0]; hesst(1,1) = _ihess[i][1][1]; hesst(1,2) = _ihess[i][1][2];
-        hesst(2,0) = _ihess[i][2][0]; hesst(2,1) = _ihess[i][2][1]; hesst(2,2) = _ihess[i][2][2];
-        for(int l=0;l<_ncomp; l++){
-          hess[hesssize + i+l*nbFF] = hesst;
+      int totalnbFF = getTotalNumShapeFunctions(ele);
+      hess.resize(hesssize + totalnbFF);
+      int lastTotalnbFF = 0;
+      for(int l=0;l<_ncomp; l++)
+      {
+        int cc = comp[l];
+        int nbFF = getNumShapeFunctions(ele,cc);
+        if (withPrimaryShapeFunction(cc))
+        {
+          MElement* elePrimary = VertexBasedLagrangeFunctionSpace::getPrimaryElement(ele);
+          elePrimary->getHessShapeFunctions(u,v,w,_ihess);
+        }
+        else
+        {
+          ele->getHessShapeFunctions(u,v,w,_ihess);
+        }
+        for(int i=0;i<nbFF;i++)
+        {
+          hesst(0,0) = _ihess[i][0][0]; hesst(0,1) = _ihess[i][0][1]; hesst(0,2) = _ihess[i][0][2];
+          hesst(1,0) = _ihess[i][1][0]; hesst(1,1) = _ihess[i][1][1]; hesst(1,2) = _ihess[i][1][2];
+          hesst(2,0) = _ihess[i][2][0]; hesst(2,1) = _ihess[i][2][1]; hesst(2,2) = _ihess[i][2][2];
+          hess[hesssize+i+lastTotalnbFF] = hesst;
         }
+        lastTotalnbFF += nbFF;
       }
     }
     virtual void hessf(MElement *ele, double u, double v, double w,std::vector<HessType> &hess) const
     {
-      ele->getGradShapeFunctions(u,v,w,_igrad);
-      ele->getHessShapeFunctions(u,v,w,_ihess);
-      int nbFF = ele->getNumShapeFunctions();
       int hesssize = hess.size();
-      hess.resize(hesssize + _ncomp*nbFF);
-
+      int totalnbFF = getTotalNumShapeFunctions(ele);
+      hess.resize(hesssize + totalnbFF);
+      int lastTotalnbFF = 0;
       double jac[3][3];
       double invjac[3][3];
-      const double detJ = ele->getJacobian(u, v, w, jac);
-      inv3x3(jac, invjac);
+      for(int l=0;l<_ncomp; l++)
+      {
+        int cc = comp[l];
+        int nbFF = getNumShapeFunctions(ele,cc);
+        int numver = 0;
+        if (withPrimaryShapeFunction(cc))
+        {
+          MElement* elePrimary = VertexBasedLagrangeFunctionSpace::getPrimaryElement(ele);
+          elePrimary->getGradShapeFunctions(u,v,w,_igrad);
+          elePrimary->getHessShapeFunctions(u,v,w,_ihess);
+          double detJ = elePrimary->getJacobian(u, v, w, jac);
+          numver = elePrimary->getNumVertices();
+        }
+        else
+        {
+          ele->getGradShapeFunctions(u,v,w,_igrad);
+          ele->getHessShapeFunctions(u,v,w,_ihess);
+          double detJ = ele->getJacobian(u, v, w, jac);
+          numver = ele->getNumVertices();
+        }
+        inv3x3(jac, invjac);
 
-      STensor33 graduvwJ(0.);
-      int numver = ele->getNumVertices();
-      for (int i=0; i<numver; i++){
-        MVertex* v = ele->getVertex(i);
-        SVector3 vec(v->x(),v->y(),v->z());
-        for (int m=0; m<3; m++){
-          for (int n=0; n<3; n++){
-            for (int q=0; q<3; q++){
-              graduvwJ(m,q,n) +=_ihess[i][m][n]*vec(q);
+        STensor33 graduvwJ(0.);
+        for (int i=0; i<numver; i++)
+        {
+          MVertex* v = ele->getVertex(i);
+          SVector3 vec(v->x(),v->y(),v->z());
+          for (int m=0; m<3; m++){
+            for (int n=0; n<3; n++){
+              for (int q=0; q<3; q++){
+                graduvwJ(m,q,n) +=_ihess[i][m][n]*vec(q);
+              };
             };
           };
         };
-      };
 
-      for(int i=0;i<nbFF;i++){
-        STensorOperation::zero(hesst);
-        for (int k=0; k<3; k++){
-          for (int l=0; l<3; l++){
-            for (int m=0; m<3; m++){
-              for (int n=0; n<3; n++){
-                hesst(k,l)+= invjac[k][m]*invjac[l][n]*_ihess[i][m][n];
-                for (int q=0; q<3; q++){
-                  for (int p=0; p<3; p++){
-                    hesst(k,l) -= invjac[k][m]*invjac[l][n]*graduvwJ(m,q,n)*invjac[q][p]*_igrad[i][p];
+        for(int i=0;i<nbFF;i++)
+        {
+          STensorOperation::zero(hesst);
+          for (int k=0; k<3; k++){
+            for (int l=0; l<3; l++){
+              for (int m=0; m<3; m++){
+                for (int n=0; n<3; n++){
+                  hesst(k,l)+= invjac[k][m]*invjac[l][n]*_ihess[i][m][n];
+                  for (int q=0; q<3; q++){
+                    for (int p=0; p<3; p++){
+                      hesst(k,l) -= invjac[k][m]*invjac[l][n]*graduvwJ(m,q,n)*invjac[q][p]*_igrad[i][p];
+                    };
                   };
                 };
               };
             };
           };
+          hess[hesssize + i+lastTotalnbFF] = hesst;
         };
-        for(int l=0;l<_ncomp; l++){
-          hess[hesssize + i+l*nbFF] = hesst;
-        };
+        lastTotalnbFF += nbFF;
       };
     };
-
-    virtual void thirdDevfuvw(MElement *ele, double u, double v, double w,std::vector<ThirdDevType> &third) const{
-      ele->getThirdDerivativeShapeFunctions(u,v,w,_ithird);
-      int nbFF = ele->getNumShapeFunctions();
+    virtual void thirdDevfuvw(MElement *ele, double u, double v, double w,std::vector<ThirdDevType> &third) const
+    {
       int thirdsize = third.size();
-      third.resize(thirdsize + _ncomp*nbFF);
-      for(int i=0;i<nbFF;i++){
-        for (int p=0; p<3; p++)
-          for (int q=0; q<3; q++)
-            for (int r=0; r<3; r++)
-              thirdt(p,q,r) = _ithird[i][p][q][r];
-        for(int l=0;l<_ncomp; l++){
-          third[thirdsize + i+l*nbFF] = thirdt;
+      int totalnbFF = getTotalNumShapeFunctions(ele);
+      third.resize(thirdsize + totalnbFF);
+      
+      int lastTotalnbFF = 0;
+      for(int l=0;l<_ncomp; l++)
+      {
+        int cc = comp[l];
+        int nbFF = getNumShapeFunctions(ele,cc);
+        if (withPrimaryShapeFunction(cc))
+        {
+          MElement* elePrimary = VertexBasedLagrangeFunctionSpace::getPrimaryElement(ele);
+          elePrimary->getThirdDerivativeShapeFunctions(u,v,w,_ithird);
+        }
+        else
+        {
+          ele->getThirdDerivativeShapeFunctions(u,v,w,_ithird);
+        }
+        
+        for(int i=0;i<nbFF;i++)
+        {
+          for (int p=0; p<3; p++)
+            for (int q=0; q<3; q++)
+              for (int r=0; r<3; r++)
+                thirdt(p,q,r) = _ithird[i][p][q][r];
+        
+          third[thirdsize + i+ lastTotalnbFF] = thirdt;
         }
+        lastTotalnbFF += nbFF;
       }
     }; //need to high order fem
-    virtual void thirdDevf(MElement *ele, double u, double v, double w,std::vector<ThirdDevType> &third) const{
-      ele->getGradShapeFunctions(u,v,w,_igrad);
-      ele->getHessShapeFunctions(u,v,w,_ihess);
-      ele->getThirdDerivativeShapeFunctions(u,v,w,_ithird);
-      int nbFF = ele->getNumShapeFunctions();
+    virtual void thirdDevf(MElement *ele, double u, double v, double w,std::vector<ThirdDevType> &third) const
+    {
+      
       int thirdsize = third.size();
-      third.resize(thirdsize + _ncomp*nbFF);
-
+      int totalnbFF = getTotalNumShapeFunctions(ele);
+      third.resize(thirdsize + totalnbFF);
+      
       double jac[3][3];
       double invjac[3][3];
-      const double detJ = ele->getJacobian(u, v, w, jac);
-      inv3x3(jac, invjac);
+      
+      int lastTotalnbFF = 0;
+      for(int l=0;l<_ncomp; l++)
+      {
+        int cc = comp[l];
+        int nbFF = getNumShapeFunctions(ele,cc);
+        int numver = 0;
+        if (withPrimaryShapeFunction(cc))
+        {
+          MElement* elePrimary = VertexBasedLagrangeFunctionSpace::getPrimaryElement(ele);
+          elePrimary->getGradShapeFunctions(u,v,w,_igrad);
+          elePrimary->getHessShapeFunctions(u,v,w,_ihess);
+          elePrimary->getThirdDerivativeShapeFunctions(u,v,w,_ithird);
+          double detJ = elePrimary->getJacobian(u, v, w, jac);
+          numver = elePrimary->getNumVertices();
+        }
+        else
+        {
+          ele->getGradShapeFunctions(u,v,w,_igrad);
+          ele->getHessShapeFunctions(u,v,w,_ihess);
+          ele->getThirdDerivativeShapeFunctions(u,v,w,_ithird);
+          double detJ = ele->getJacobian(u, v, w, jac);
+          numver = ele->getNumVertices();
+        }
+        inv3x3(jac, invjac);
 
-      STensor33 B(0.);
-      int numver = ele->getNumVertices();
-      for (int i=0; i<numver; i++){
-        MVertex* v = ele->getVertex(i);
-        SVector3 vec(v->x(),v->y(),v->z());
-        for (int m=0; m<3; m++){
-          for (int n=0; n<3; n++){
-            for (int q=0; q<3; q++){
-              B(m,q,n) +=_ihess[i][m][n]*vec(q);
+        STensor33 B(0.);
+      
+        for (int i=0; i<numver; i++){
+          MVertex* v = ele->getVertex(i);
+          SVector3 vec(v->x(),v->y(),v->z());
+          for (int m=0; m<3; m++){
+            for (int n=0; n<3; n++){
+              for (int q=0; q<3; q++){
+                B(m,q,n) +=_ihess[i][m][n]*vec(q);
+              };
             };
           };
         };
-      };
 
-      STensor43 C(0.);
-      for (int i=0; i<numver; i++){
-        MVertex* v = ele->getVertex(i);
-        SVector3 vec(v->x(),v->y(),v->z());
-        for (int m=0; m<3; m++){
-          for (int n=0; n<3; n++){
-            for (int q=0; q<3; q++){
-              for (int r=0; r<3; r++ ){
-                C(m,q,n,r) +=_ithird[i][m][n][r]*vec(q);
-              }
+        STensor43 C(0.);
+        for (int i=0; i<numver; i++){
+          MVertex* v = ele->getVertex(i);
+          SVector3 vec(v->x(),v->y(),v->z());
+          for (int m=0; m<3; m++){
+            for (int n=0; n<3; n++){
+              for (int q=0; q<3; q++){
+                for (int r=0; r<3; r++ ){
+                  C(m,q,n,r) +=_ithird[i][m][n][r]*vec(q);
+                }
+              };
             };
           };
         };
-      };
 
-      STensor33 A(0);
-      for (int i=0; i<3; i++)
-        for (int j=0; j<3; j++)
-          for (int k=0; k<3; k++)
-            for (int l=0; l<3; l++)
-              for (int m=0; m<3; m++)
-                A(i,j,k) -= B(l,m,k)*invjac[i][l]*invjac[m][j];
+        STensor33 A(0);
+        for (int i=0; i<3; i++)
+          for (int j=0; j<3; j++)
+            for (int k=0; k<3; k++)
+              for (int l=0; l<3; l++)
+                for (int m=0; m<3; m++)
+                  A(i,j,k) -= B(l,m,k)*invjac[i][l]*invjac[m][j];
 
-      for(int i=0;i<nbFF;i++){
-        STensorOperation::zero(thirdt);
-        for(int j=0; j<3; j++)
-          for (int k=0; k<3; k++)
-            for (int l=0; l<3; l++)
-              for (int m=0; m<3; m++){
-                for (int s=0; s<3; s++)
-                  for (int r=0; r<3; r++){
-                    double temp = invjac[l][s]*(A(j,m,s)*invjac[k][r]+ A(k,r,s)*invjac[j][m]);
-                    double temp2 = invjac[j][m]*invjac[k][r]*invjac[l][s];
-                    thirdt(j,k,l) += temp* _ihess[i][m][r]+
-                                     temp2* _ithird[i][m][r][s];
+        for(int i=0;i<nbFF;i++){
+          STensorOperation::zero(thirdt);
+          for(int j=0; j<3; j++)
+            for (int k=0; k<3; k++)
+              for (int l=0; l<3; l++)
+                for (int m=0; m<3; m++){
+                  for (int s=0; s<3; s++)
+                    for (int r=0; r<3; r++){
+                      double temp = invjac[l][s]*(A(j,m,s)*invjac[k][r]+ A(k,r,s)*invjac[j][m]);
+                      double temp2 = invjac[j][m]*invjac[k][r]*invjac[l][s];
+                      thirdt(j,k,l) += temp* _ihess[i][m][r]+
+                                       temp2* _ithird[i][m][r][s];
 
-                    for (int q=0; q<3; q++)
-                      for (int p=0; p<3; p++){
-                        thirdt(j,k,l) -= temp*B(m,q,r)*invjac[q][p]*_igrad[i][p]+
-                                         temp2*(C(m,q,r,s)*invjac[q][p]*_igrad[i][p]+
-                                                B(m,q,r)*A(q,p,s)*_igrad[i][p]+
-                                                B(m,q,r)*invjac[q][p]*_ihess[i][s][p]);
-                      }
-                  }
-              }
-        for(int l=0;l<_ncomp; l++){
-          third[thirdsize + i+l*nbFF] = thirdt;
+                      for (int q=0; q<3; q++)
+                        for (int p=0; p<3; p++){
+                          thirdt(j,k,l) -= temp*B(m,q,r)*invjac[q][p]*_igrad[i][p]+
+                                           temp2*(C(m,q,r,s)*invjac[q][p]*_igrad[i][p]+
+                                                  B(m,q,r)*A(q,p,s)*_igrad[i][p]+
+                                                  B(m,q,r)*invjac[q][p]*_ihess[i][s][p]);
+                        }
+                    }
+                }
+        
+          third[thirdsize + i+lastTotalnbFF] = thirdt;
         };
-      };
+        lastTotalnbFF += nbFF;
+      }
     }; //need to high order fem
     
   private: //cache to avoid constant reallocation
@@ -376,6 +534,34 @@ class ThreeDLagrangeFunctionSpace : public VertexBasedLagrangeFunctionSpace
      mutable ThirdDevType thirdt;
 };
 
+
+// Lagrange function space
+class ThreeDLagrangeFunctionSpace : public VertexBasedLagrangeFunctionSpace
+{
+  protected:
+    virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const=0;
+    
+  public:
+    ThreeDLagrangeFunctionSpace(int id, int ncomp,bool hesscompute, bool thirdcompute);
+    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, bool hesscompute, bool thirdcompute);
+    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, int comp2_, const bool hessc, const bool thirdc);
+    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, int comp2_, int comp3_,
+                              const bool hessc, const bool thirdc) ;
+    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, int comp2_, int comp3_,
+                                int comp4_,const bool hessc, const bool thirdc);
+    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, int comp2_, int comp3_,
+                                int comp4_, int comp5_,const bool hessc, const bool thirdc);
+    ThreeDLagrangeFunctionSpace(int id, int ncomp, int comp1_, int comp2_, int comp3_,
+                                int comp4_, int comp5_, int comp6_, const bool hessc, const bool thirdc);
+    virtual ~ThreeDLagrangeFunctionSpace(){}
+    
+    virtual FunctionSpaceBase* clone(const int id) const 
+    {
+      Msg::Error("define ThreeDLagrangeFunctionSpace::clone!!!");
+      return NULL;
+    }
+};
+
 // used by dgshell and by dG3D for interface
 class IsoparametricLagrangeFunctionSpace : public VertexBasedLagrangeFunctionSpace
 {  
@@ -395,58 +581,18 @@ class IsoparametricLagrangeFunctionSpace : public VertexBasedLagrangeFunctionSpa
       Msg::Error("define IsoparametricLagrangeFunctionSpace::clone");
       return NULL;
     };
-
-    virtual void fuvw(MElement *ele, double u, double v, double w,std::vector<ValType> &vals) const
-    {
-      ele->getShapeFunctions(u,v,w,_ival);
-      int nbFF = ele->getNumShapeFunctions();
-      int valssize = vals.size();
-      vals.resize(valssize + _ncomp*nbFF);
-      for(int i=0;i<nbFF;i++)
-        for(int l=0;l<_ncomp;l++)
-          vals[valssize + i+l*nbFF] = _ival[i];
-    }
+    
     // ==fuvw
     virtual void f(MElement *ele, double u, double v, double w, std::vector<ValType> &vals) const
     {
       this->fuvw(ele,u,v,w,vals);
     }
-
-    virtual void gradfuvw(MElement *ele, double u, double v, double w, std::vector<GradType> &grads) const
-    {
-      ele->getGradShapeFunctions(u,v,w,_igrad);
-      int nbFF = ele->getNumShapeFunctions();
-      int gradssize = grads.size();
-      grads.resize(gradssize + _ncomp*nbFF);
-      for(int i=0;i<nbFF;i++){
-        gradt(0) = _igrad[i][0];
-        gradt(1) = _igrad[i][1];
-        gradt(2) = _igrad[i][2];
-        for(int l=0;l<_ncomp; l++)
-          grads[gradssize + i + l*nbFF] = gradt;
-      }
-    }
     // == gradfuvw
     virtual void gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads) const
     {
       this->gradfuvw(ele,u,v,w,grads);
     }
 
-    virtual void hessfuvw(MElement *ele, double u, double v, double w,std::vector<HessType> &hess) const
-    {
-      ele->getHessShapeFunctions(u,v,w,_ihess);
-      int nbFF = ele->getNumShapeFunctions();
-      int hesssize = hess.size();
-      hess.resize(hesssize + _ncomp*nbFF);
-      for(int i=0;i<nbFF;i++){
-        hesst(0,0) = _ihess[i][0][0]; hesst(0,1) = _ihess[i][0][1]; hesst(0,2) = _ihess[i][0][2];
-        hesst(1,0) = _ihess[i][1][0]; hesst(1,1) = _ihess[i][1][1]; hesst(1,2) = _ihess[i][1][2];
-        hesst(2,0) = _ihess[i][2][0]; hesst(2,1) = _ihess[i][2][1]; hesst(2,2) = _ihess[i][2][2];
-        for(int l=0;l<_ncomp; l++){
-          hess[hesssize + i+l*nbFF] = hesst;
-        }
-      }
-    }
     // == hessfuvw
     virtual void hessf(MElement *ele, double u, double v, double w,std::vector<HessType> &hess) const
     {
@@ -461,13 +607,6 @@ class IsoparametricLagrangeFunctionSpace : public VertexBasedLagrangeFunctionSpa
     {
       this->thirdDevfuvw(ele,u,v,w,third);
     }
-    
-  private: // avoid constant reallocation
-    mutable double _ival[256];
-    mutable double _igrad[256][3];
-    mutable double _ihess [256][3][3];
-    mutable HessType hesst;
-    mutable GradType gradt;
 };
 
 
diff --git a/NonLinearSolver/space/mixedFunctionSpace.h b/NonLinearSolver/space/mixedFunctionSpace.h
index eecdbf1e2..d99d94326 100644
--- a/NonLinearSolver/space/mixedFunctionSpace.h
+++ b/NonLinearSolver/space/mixedFunctionSpace.h
@@ -65,6 +65,11 @@ class CurlMixedFunctionSpace : public mixedFunctionSpaceBase,  public nlsFunctio
     
     virtual int getId(void) const { return _space->getId();}
     
+    virtual int getNumShapeFunctions(MElement* ele, int c) const {Msg::Error("implement CurlMixedFunctionSpace::getNumShapeFunctions");};
+    virtual int getNumShapeFunctions(MElement* ele, const std::vector<int>& c) const  {Msg::Error("implement CurlMixedFunctionSpace::getNumShapeFunctions");};
+    virtual int getTotalNumShapeFunctions(MElement* ele) const {Msg::Error("implement CurlMixedFunctionSpace::getTotalNumShapeFunctions");};
+
+    
     virtual bool withHessianComputation() const {return _space->withHessianComputation();};
     virtual bool withThirdDevComputation() const {return _space->withThirdDevComputation();}
     
diff --git a/NonLinearSolver/space/nlsFunctionSpace.h b/NonLinearSolver/space/nlsFunctionSpace.h
index c08a324f7..929af947d 100644
--- a/NonLinearSolver/space/nlsFunctionSpace.h
+++ b/NonLinearSolver/space/nlsFunctionSpace.h
@@ -17,6 +17,7 @@
 #include "GaussIntegration.h"
 #include "STensorOperations.h"
 
+// Structure to store the value of a Gauss point
 template<class T> struct nlsContainerTraits
 {
   typedef T ContainerValType;
@@ -33,45 +34,145 @@ template<> struct nlsContainerTraits<double>
   typedef std::vector<TensorialTraits<double>::ThirdDevType> ContainerThirdDevType;
 };
 
-// Structure to store the value of a Gauss point
-template<class T> struct GaussPointSpaceValues
+
+template<class T>
+struct GaussPointSpaceValues
 {
- public:
-  typedef typename nlsContainerTraits<T>::ContainerValType ContainerValType;
-  typedef typename nlsContainerTraits<T>::ContainerGradType ContainerGradType;
-  typedef typename nlsContainerTraits<T>::ContainerHessType ContainerHessType;
-  typedef typename nlsContainerTraits<T>::ContainerThirdDevType ContainerThirdDevType;
-  ContainerValType _vvals;
-  ContainerGradType _vgrads;
-  ContainerHessType _vhess;
-  ContainerThirdDevType _vthird;
-  GaussPointSpaceValues(const FunctionSpace<T> *sp,MElement *ele,const double u, const double v, const double w,
-                        const bool hessian, const bool thirdDev)
-  {
-    // compute the value
-    sp->fuvw(ele,u,v,w,_vvals);
-    sp->gradfuvw(ele,u,v,w,_vgrads);
-    if(hessian)
-      sp->hessfuvw(ele,u,v,w,_vhess);
-    if(thirdDev)
-      sp->thirdDevfuvw(ele,u,v,w,_vthird);
-  }
-  GaussPointSpaceValues(const GaussPointSpaceValues &source)
-  {
-    _vvals.assign(source._vals.begin(),source._vals.end());
-    _vgrads.assign(source._vgrads.begin(),source._vgrads.end());
-    _vhess.assign(source._vhess.begin(),source._vhess.end());
-    _vthird.assign(source._vthird.begin(),source._vthird.end());
-  }
-  virtual ~GaussPointSpaceValues()
-  {
-    _vvals.clear();
-    _vgrads.clear();
-    _vhess.clear();
-    _vthird.clear();
-  }
+  public:
+    typedef typename nlsContainerTraits<T>::ContainerValType ContainerValType;
+    typedef typename nlsContainerTraits<T>::ContainerGradType ContainerGradType;
+    typedef typename nlsContainerTraits<T>::ContainerHessType ContainerHessType;
+    typedef typename nlsContainerTraits<T>::ContainerThirdDevType ContainerThirdDevType;
+
+    ContainerValType _vvals;
+    ContainerGradType _vgrads;
+    ContainerHessType _vhess;
+    ContainerThirdDevType _vthird;
+    GaussPointSpaceValues(const FunctionSpace<T> *sp, MElement *ele,const double u, const double v, const double w,
+                          const bool hessian, const bool thirdDev)
+    {
+      // compute the value
+      sp->fuvw(ele,u,v,w,_vvals);
+      sp->gradfuvw(ele,u,v,w,_vgrads);
+      if(hessian)
+        sp->hessfuvw(ele,u,v,w,_vhess);
+      if(thirdDev)
+        sp->thirdDevfuvw(ele,u,v,w,_vthird);
+    }
+    GaussPointSpaceValues(const GaussPointSpaceValues &source)
+    {
+      _vvals.assign(source._vvals.begin(),source._vvals.end());
+      _vgrads.assign(source._vgrads.begin(),source._vgrads.end());
+      _vhess.assign(source._vhess.begin(),source._vhess.end());
+      _vthird.assign(source._vthird.begin(),source._vthird.end());
+    }
+    virtual ~GaussPointSpaceValues()
+    {
+      _vvals.clear();
+      _vgrads.clear();
+      _vhess.clear();
+      _vthird.clear();
+    }
 };
 
+
+template<> struct GaussPointSpaceValues <double>
+{
+  public:
+    typedef typename nlsContainerTraits<double>::ContainerValType ContainerValType;
+    typedef typename nlsContainerTraits<double>::ContainerGradType ContainerGradType;
+    typedef typename nlsContainerTraits<double>::ContainerHessType ContainerHessType;
+    typedef typename nlsContainerTraits<double>::ContainerThirdDevType ContainerThirdDevType;
+    ContainerValType _vvals;
+    ContainerGradType _vgrads;
+    ContainerHessType _vhess;
+    ContainerThirdDevType _vthird;
+    GaussPointSpaceValues(const FunctionSpace<double> *sp, MElement *ele,const double u, const double v, const double w,
+                          const bool hessian, const bool thirdDev)
+    {
+      int nbFF = ele->getNumShapeFunctions();
+      //
+      _vvals.resize(3*nbFF);
+      _vgrads.resize(3*nbFF);
+      if (hessian)
+      {
+        _vhess.resize(3*nbFF);
+      }
+      if (thirdDev)
+      {
+        _vthird.resize(3*nbFF);
+      }
+      // val
+      double _ival[256];
+      ele->getShapeFunctions(u,v,w,_ival);
+      for(int i=0;i<nbFF;i++)
+      {
+        _vvals[i] = _ival[i];
+        _vvals[i+nbFF] = _ival[i];
+        _vvals[i+2*+nbFF] = _ival[i];
+      }
+      // grad
+      double _igrad[256][3];
+      ele->getGradShapeFunctions(u,v,w,_igrad);
+      for(int i=0;i<nbFF;i++)
+      {
+        _vgrads[i](0) = _igrad[i][0];
+        _vgrads[i](1) = _igrad[i][1];
+        _vgrads[i](2) = _igrad[i][2];
+        _vgrads[i+nbFF] = _vgrads[i];
+        _vgrads[i+2*nbFF] = _vgrads[i];
+      }
+      
+      // hess
+      if (hessian)
+      {
+        double _ihess [256][3][3];
+        ele->getHessShapeFunctions(u,v,w,_ihess);
+        for(int i=0;i<nbFF;i++)
+        {
+          _vhess[i](0,0) = _ihess[i][0][0]; _vhess[i](0,1) = _ihess[i][0][1]; _vhess[i](0,2) = _ihess[i][0][2];
+          _vhess[i](1,0) = _ihess[i][1][0]; _vhess[i](1,1) = _ihess[i][1][1]; _vhess[i](1,2) = _ihess[i][1][2];
+          _vhess[i](2,0) = _ihess[i][2][0]; _vhess[i](2,1) = _ihess[i][2][1]; _vhess[i](2,2) = _ihess[i][2][2];
+          
+          _vhess[i+nbFF] = _vhess[i];
+          _vhess[i+2*nbFF] = _vhess[i];
+        }
+      }
+      
+      // third
+      if(thirdDev)
+      {
+        double _ithird[256][3][3][3];
+        ele->getThirdDerivativeShapeFunctions(u,v,w,_ithird);
+        for(int i=0;i<nbFF;i++)
+        {
+          for (int p=0; p<3; p++)
+            for (int q=0; q<3; q++)
+              for (int r=0; r<3; r++)
+                _vthird[i](p,q,r) = _ithird[i][p][q][r];
+                
+          _vthird[i+nbFF] = _vthird[i];
+          _vthird[i+2*nbFF] = _vthird[i];
+        }
+      }
+    }
+    GaussPointSpaceValues(const GaussPointSpaceValues &source)
+    {
+      _vvals.assign(source._vvals.begin(),source._vvals.end());
+      _vgrads.assign(source._vgrads.begin(),source._vgrads.end());
+      _vhess.assign(source._vhess.begin(),source._vhess.end());
+      _vthird.assign(source._vthird.begin(),source._vthird.end());
+    }
+    virtual ~GaussPointSpaceValues()
+    {
+      _vvals.clear();
+      _vgrads.clear();
+      _vhess.clear();
+      _vthird.clear();
+    }
+};
+
+
 template<class T> 
 class  nlsFunctionSpace : public FunctionSpace<T>
 {
@@ -92,6 +193,9 @@ class  nlsFunctionSpace : public FunctionSpace<T>
       }
       _mapGaussValues.clear();
     }
+    virtual int getNumShapeFunctions(MElement* ele, int c) const = 0;
+    virtual int getNumShapeFunctions(MElement* ele, const std::vector<int>& c) const = 0;
+    virtual int getTotalNumShapeFunctions(MElement* ele) const = 0;
     //some new function
     virtual bool withHessianComputation() const = 0;
     virtual bool withThirdDevComputation() const =0;
@@ -116,7 +220,7 @@ class  nlsFunctionSpace : public FunctionSpace<T>
     virtual void thirdDevf(MElement *ele, double u, double v, double w, std::vector<ThirdDevType> &third) const  = 0;
     
     
-  protected:
+   protected:
     mutable std::map<IntPt*,std::vector<GaussPointSpaceValues<T>*> > _mapGaussValues; // cache in order to assess everywhere
     // function to allocate the map
     typename std::map<IntPt*,std::vector<GaussPointSpaceValues<T>*> >::iterator allocatePoints(MElement *ele,int npts, IntPt *GP) const
diff --git a/dG3D/src/dG3DDomain.cpp b/dG3D/src/dG3DDomain.cpp
index 637a93f72..6b150efee 100644
--- a/dG3D/src/dG3DDomain.cpp
+++ b/dG3D/src/dG3DDomain.cpp
@@ -1005,8 +1005,8 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
                                fullVector<double> &disp, bool useBarF, bool useAverageNonlocal) const
 {
   if (!getElementErosionFilter()(e)) return;
-
-  int nbFF = e->getNumShapeFunctions();
+  const nlsFunctionSpace<double>* nlspace  = static_cast<nlsFunctionSpace<double>*>(_space);
+  std::vector<int> comp;
   //Msg::Info("nb bulk gp %d",npts_bulk);
   for(int j=0;j<npts_bulk;j++)
   {
@@ -1018,22 +1018,27 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
     //x y z
     STensor3 &F = ipv->getRefToDeformationGradient();
     STensorOperation::unity(F);
-    for (int i = 0; i < nbFF; i++)
-    {
-      //x y z: take compoenent x arbitrarily
-      // xx yy zz xy xz yz
-      F(0,0) += Grads[i+0*nbFF][0]*disp(i);
-      F(0,1) += Grads[i+0*nbFF][1]*disp(i);
-      F(0,2) += Grads[i+0*nbFF][2]*disp(i);
-      F(1,0) += Grads[i+0*nbFF][0]*disp(i+nbFF);
-      F(1,1) += Grads[i+0*nbFF][1]*disp(i+nbFF);
-      F(1,2) += Grads[i+0*nbFF][2]*disp(i+nbFF);
-      F(2,0) += Grads[i+0*nbFF][0]*disp(i+2*nbFF);
-      F(2,1) += Grads[i+0*nbFF][1]*disp(i+2*nbFF);
-      F(2,2) += Grads[i+0*nbFF][2]*disp(i+2*nbFF);
+    
+    int nbFFTotalLast = 0; 
+    for (int k=0; k<3; k++)
+    {    
+      int nbFF = nlspace->getNumShapeFunctions(e,k);
+      for (int i = 0; i < nbFF; i++)
+      {
+        //x y z: take compoenent x arbitrarily
+        // xx yy zz xy xz yz
+        F(k,0) += Grads[i+nbFFTotalLast][0]*disp(i+nbFFTotalLast);
+        F(k,1) += Grads[i+nbFFTotalLast][1]*disp(i+nbFFTotalLast);
+        F(k,2) += Grads[i+nbFFTotalLast][2]*disp(i+nbFFTotalLast);
+      }
+      nbFFTotalLast += nbFF;
     }
     if(STensorOperation::determinantSTensor3(F) < 1.e-15) Msg::Error("Negative Jacobian in ele %d",e->getNum());
   }
+  // three displacemnt components
+  comp.push_back(0);
+  comp.push_back(1);
+  comp.push_back(2);
 
   if(useBarF)
   {
@@ -1076,8 +1081,11 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
 
       if( ipv->getNumberNonLocalVariable()>getNumNonLocalVariable() )
         Msg::Error("Your material law uses more non local variables than your domain dG3DDomain::computeStrain bulk");
+      
+      int nbFFTotalLast = nlspace->getNumShapeFunctions(e,comp);
       for (int nl = 0; nl < ipv->getNumberNonLocalVariable(); nl++)
       {
+        int nbFF = nlspace->getNumShapeFunctions(e,3+nl);
         double& nonlocalVar = ipv->getRefToNonLocalVariable(nl);
         SVector3& gradNonlocalVar = ipv->getRefToGradNonLocalVariable()[nl];
 
@@ -1085,13 +1093,19 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
         STensorOperation::zero(gradNonlocalVar);
         for (int i = 0; i < nbFF; i++)
         {
-          nonlocalVar += Vals[i+3*nbFF+nl*nbFF]*disp(i+3*nbFF+nl*nbFF);
-          gradNonlocalVar(0) += Grads[i+3*nbFF+nl*nbFF][0]*disp(i+3*nbFF+nl*nbFF);
-          gradNonlocalVar(1) += Grads[i+3*nbFF+nl*nbFF][1]*disp(i+3*nbFF+nl*nbFF);
-          gradNonlocalVar(2) += Grads[i+3*nbFF+nl*nbFF][2]*disp(i+3*nbFF+nl*nbFF);
+          nonlocalVar += Vals[i+nbFFTotalLast]*disp(i+nbFFTotalLast);
+          gradNonlocalVar(0) += Grads[i+nbFFTotalLast][0]*disp(i+nbFFTotalLast);
+          gradNonlocalVar(1) += Grads[i+nbFFTotalLast][1]*disp(i+nbFFTotalLast);
+          gradNonlocalVar(2) += Grads[i+nbFFTotalLast][2]*disp(i+nbFFTotalLast);
         }
+        nbFFTotalLast += nbFF;
       }
     }
+    // add comp to vector for next computation
+    for (int nl = 0; nl < getNumNonLocalVariable(); nl++)
+    {
+      comp.push_back(3+nl);
+    }
     
     // compute nonlocal var for law
     if (useAverageNonlocal)
@@ -1140,6 +1154,7 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
    * */
   if (getNumConstitutiveExtraDofDiffusionVariable() > 0)
   {
+    // porition from last
     for(int j=0;j<npts_bulk;j++)
     {
       IPStateBase* ips = (*vips)[j];
@@ -1151,37 +1166,37 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
       if( ipv->getNumConstitutiveExtraDofDiffusionVariable()>getNumConstitutiveExtraDofDiffusionVariable() )
         Msg::Error("Your material law uses more constitutive extra dof diffusion variables than your domain dG3DDomain::computeStrain bulk");
         
-      if((getNumConstitutiveExtraDofDiffusionVariable() == 1)&&(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()))
-      {
-         // thermomechanics with conjugate fields fT = 1/T
-      }
-      else if((getNumConstitutiveExtraDofDiffusionVariable() == 2)&&(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()))
+      if((getNumConstitutiveExtraDofDiffusionVariable() == 2)&&(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()))
       {
+        // eletro-thermomec, if fV, fT are used
+        int nbFFTotalLast = nlspace->getNumShapeFunctions(e,comp);
         // if two fields (T, V) are considered using fT= 1/T, fV = -V/T as unknowns
         for (int extraDOFField = 0; extraDOFField < ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
         {
-          // field and grad field must be estimated from unknowns
-          double& T = ipv->getRefToField(extraDOFField);
-          SVector3& gradT = ipv->getRefToGradField()[extraDOFField];
-          T = 0.;
-          STensorOperation::zero(gradT);
-          
           // unknown
           double& energyConjugatedField = ipv->getRefToEnergyConjugatedField(extraDOFField);
           SVector3& gradEnergyConjugatedField = ipv->getRefToGradEnergyConjugatedField()[extraDOFField];
           energyConjugatedField = 0.;
           STensorOperation::zero(gradEnergyConjugatedField);
-
-          int extraDOFField_aux=0;
-          if (extraDOFField == 0)
-          {
-            extraDOFField_aux = 1;
-          }
-          else 
+          
+          int indexFieldfT=3+getNumNonLocalVariable()+extraDOFField;
+          int nbFF = nlspace->getNumShapeFunctions(e,indexFieldfT);
+          for (int i = 0; i < nbFF; i++)
           {
-            extraDOFField_aux = 0;
-          }
+            const double& ftemp = disp(i+nbFFTotalLast);
+            energyConjugatedField += Vals[i+nbFFTotalLast]*ftemp;
+            gradEnergyConjugatedField(0) += Grads[i+nbFFTotalLast][0]*ftemp;
+            gradEnergyConjugatedField(1) += Grads[i+nbFFTotalLast][1]*ftemp;
+            gradEnergyConjugatedField(2) += Grads[i+nbFFTotalLast][2]*ftemp;
+          }         
+          nbFFTotalLast += nbFF;
+          
+          // field and grad field must be estimated from unknowns
+          double& T = ipv->getRefToField(extraDOFField);
+          SVector3& gradT = ipv->getRefToGradField()[extraDOFField];
           
+          int extraDOFField_aux = (extraDOFField == 0)? 1 : 0;
+          // derivatives of field and grad with with respect to conjugate fields and their gradients
           double& dFielddEnergyConjugatedField = ipv->getRefTodFielddEnergyConjugatedField()[extraDOFField][extraDOFField];
           double& dFielddEnergyConjugatedField2 = ipv->getRefTodFielddEnergyConjugatedField()[extraDOFField][extraDOFField_aux];
           SVector3& dGradFielddEnergyConjugatedField = ipv->getRefTodGradFielddEnergyConjugatedField()[extraDOFField][extraDOFField];
@@ -1189,21 +1204,9 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
           STensor3& dGradFielddGradEnergyConjugatedField = ipv->getRefTodGradFielddGradEnergyConjugatedField()[extraDOFField][extraDOFField];
           STensor3& dGradFielddGradEnergyConjugatedField2 = ipv->getRefTodGradFielddGradEnergyConjugatedField()[extraDOFField][extraDOFField_aux];
 
-          STensorOperation::zero(dGradFielddGradEnergyConjugatedField); 
-          STensorOperation::zero(dGradFielddGradEnergyConjugatedField2);
-
-          int indexFieldfT=3+getNumNonLocalVariable()+extraDOFField;
-          for (int i = 0; i < nbFF; i++)
-          {
-            const double& ftemp = disp(i+indexFieldfT*nbFF);
-            energyConjugatedField += Vals[i+indexFieldfT*nbFF]*ftemp;
-            gradEnergyConjugatedField(0) += Grads[i+indexFieldfT*nbFF][0]*ftemp;
-            gradEnergyConjugatedField(1) += Grads[i+indexFieldfT*nbFF][1]*ftemp;
-            gradEnergyConjugatedField(2) += Grads[i+indexFieldfT*nbFF][2]*ftemp;
-          }
-
           if(extraDOFField == 0)
           {
+            // temperature field
             T = 1/(energyConjugatedField);
             gradT(0)=-1/(pow(energyConjugatedField,2))*(gradEnergyConjugatedField(0));
             gradT(1)=-1/(pow(energyConjugatedField,2))*(gradEnergyConjugatedField(1));
@@ -1221,10 +1224,11 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
             dGradFielddEnergyConjugatedField2(2)=0.;
 
             STensorOperation::diag(dGradFielddGradEnergyConjugatedField,-1./(energyConjugatedField)/(energyConjugatedField));
-
+            STensorOperation::zero(dGradFielddGradEnergyConjugatedField2);
           }
           else
           {
+            // volteage field
             double fT = ipv->getConstRefToEnergyConjugatedField(0);
             SVector3 gradfT = ipv->getConstRefToGradEnergyConjugatedField()[0];
 
@@ -1247,10 +1251,14 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
             STensorOperation::diag(dGradFielddGradEnergyConjugatedField,-1./(fT));
             STensorOperation::diag(dGradFielddGradEnergyConjugatedField2,(energyConjugatedField)/(fT)/(fT));
           }
+          
+          
         }
       }
       else
       {
+        // field are unknowns
+        int nbFFTotalLast = nlspace->getNumShapeFunctions(e,comp);
         for (int extraDOFField = 0; extraDOFField < ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
         {
           double& T = ipv->getRefToField(extraDOFField);
@@ -1258,17 +1266,27 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
           T = 0.;
           STensorOperation::zero(gradT);
           
+          int indexFieldfT=3+getNumNonLocalVariable()+extraDOFField;
+          int nbFF = nlspace->getNumShapeFunctions(e,indexFieldfT);
+          
           for (int i = 0; i < nbFF; i++)
           {
-            int indexField=3+getNumNonLocalVariable()+extraDOFField;
-            T += Vals[i+indexField*nbFF]*disp(i+indexField*nbFF);
-            gradT(0) += Grads[i+indexField*nbFF][0]*disp(i+indexField*nbFF);
-            gradT(1) += Grads[i+indexField*nbFF][1]*disp(i+indexField*nbFF);
-            gradT(2) += Grads[i+indexField*nbFF][2]*disp(i+indexField*nbFF);
+            T += Vals[i+nbFFTotalLast]*disp(i+nbFFTotalLast);
+            gradT(0) += Grads[i+nbFFTotalLast][0]*disp(i+nbFFTotalLast);
+            gradT(1) += Grads[i+nbFFTotalLast][1]*disp(i+nbFFTotalLast);
+            gradT(2) += Grads[i+nbFFTotalLast][2]*disp(i+nbFFTotalLast);
           }
+          // update previous field
+          nbFFTotalLast += nbFF;
         }
       }
     }
+    
+    //update comp for next fields
+    for (int extraDOFField = 0; extraDOFField < getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
+    {
+      comp.push_back(3+getNumNonLocalVariable()+extraDOFField);
+    }
   }
 }
 void dG3DDomain::computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichState ws,
@@ -1383,57 +1401,21 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
 
   if(!virt)
   {
-    FunctionSpaceBase* _spaceminus = efMinus->getFunctionSpace();
-    FunctionSpaceBase* _spaceplus = efPlus->getFunctionSpace();
-
+    nlsFunctionSpace<double>* _spaceminus = dynamic_cast<nlsFunctionSpace<double>*>(efMinus->getFunctionSpace());
+    nlsFunctionSpace<double>* _spaceplus = dynamic_cast<nlsFunctionSpace<double>*>(efPlus->getFunctionSpace());
+    std::vector<int> comp;
+    
     int npts=integBound->getIntPoints(ele,&GP);
-
     MElement *em = ie->getElem(0);
     MElement *ep = ie->getElem(1);
 
-     // gauss point
-    int nbFFm = em->getNumVertices();
-    int nbFFp = ep->getNumVertices();
     // Get Gauss points values on minus and plus elements
     IntPt *GPm; IntPt *GPp;
     _interQuad->getIntPoints(ie,GP,&GPm,&GPp);
-
-    // the current outward normal is computed at the mean surface
-    // which defined as the reference coordinates plus mean displacement of positive and negative part
-    // displacement at the mean face
-    fullVector<double> dispinter, jumpinter;
-    int nbdofinter = _space->getNumKeys(ele);
-    int nbvertexInter = ele->getNumVertices();
-    std::vector<int> vn;
-
-    vn.resize(nbvertexInter);
-    ie->getLocalVertexNum(0,vn);
-    dispinter.resize(nbdofinter);
-    jumpinter.resize(nbdofinter);
-    for(int i=0;i<nbvertexInter;i++){
-      dispinter(i) = 0.5*dispm(vn[i]);
-      dispinter(i+nbvertexInter) = 0.5*dispm(vn[i]+nbFFm);
-      dispinter(i+2*nbvertexInter) = 0.5*dispm(vn[i]+2*nbFFm);
-      jumpinter(i) = -dispm(vn[i]);
-      jumpinter(i+nbvertexInter) = -dispm(vn[i]+nbFFm);
-      jumpinter(i+2*nbvertexInter) = -dispm(vn[i]+2*nbFFm);
-    }
-
-    std::vector<int> vp;
-    vp.resize(nbvertexInter);
-    ie->getLocalVertexNum(1,vp);
-    for(int i=0;i<nbvertexInter;i++){
-      dispinter(i) += 0.5*dispp(vp[i]);
-      dispinter(i+nbvertexInter) += 0.5*dispp(vp[i]+nbFFp);
-      dispinter(i+2*nbvertexInter) += 0.5*dispp(vp[i]+2*nbFFp);
-      jumpinter(i) += dispp(vp[i]);
-      jumpinter(i+nbvertexInter) += dispp(vp[i]+nbFFp);
-      jumpinter(i+2*nbvertexInter) += dispp(vp[i]+2*nbFFp);
-    }
-    
     
+    // based on elements,
     std::vector<GaussPointSpaceValues<double>*> vgps;
-    static_cast<nlsFunctionSpace<double>*>(_space)->get(ele,npts,GP,vgps);
+    _spaceminus->get(ele,npts,GP,vgps);
 
     AllIPState::ipstateElementContainer *vips = aips->getIPstate(ele->getNum());
     /**
@@ -1441,6 +1423,48 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
      * CURRENT AND REFERENCE NORMAL
      * 
      * **/
+     
+    // compute current interface based on the average displaceemnt of the node at interface    
+    int nbvertexInter = ele->getNumVertices();
+    std::vector<int> vnlist, vplist;
+    vnlist.resize(nbvertexInter);
+    ie->getLocalVertexNum(0,vnlist);
+    vplist.resize(nbvertexInter);
+    ie->getLocalVertexNum(1,vplist);
+     
+    fullVector<double> dispinter(3*nbvertexInter);
+    dispinter.setAll(0.);
+    for (int iv=0; iv < nbvertexInter; iv++)
+    {
+      double um, vm, wm;
+      double up, vp, wp;
+      em->getNode(vnlist[iv],um,vm,wm);
+      ep->getNode(vplist[iv],up,vp,wp);
+      
+      std::vector<TensorialTraits<double>::ValType> Valm, Valp;
+      _spaceminus->f(em,um,vm,wm,Valm);
+      _spaceplus->f(ep,up,vp,wp,Valp);
+      
+      int nbFFmLastTotal = 0;
+      int nbFFpLastTotal = 0;
+      for (int i=0; i<3; i++)
+      {
+        int nbFFm = _spaceminus->getNumShapeFunctions(em,i);
+        for (int k=0; k< nbFFm; k++)
+        {
+          dispinter(iv+i*nbvertexInter) += 0.5*Valm[k+nbFFmLastTotal]*dispm(k+nbFFmLastTotal);
+        }
+        
+        int nbFFp = _spaceplus->getNumShapeFunctions(ep,i);
+        for (int k=0; k< nbFFp; k++)
+        {
+          dispinter(iv+i*nbvertexInter) += 0.5*Valp[k+nbFFpLastTotal]*dispp(k+nbFFpLastTotal);
+        }
+        nbFFmLastTotal += nbFFm;
+        nbFFpLastTotal += nbFFp;
+      }
+    }
+   
     for(int j=0;j<npts;j++)
     {
       IPStateBase* ipsm = (*vips)[j];
@@ -1449,7 +1473,6 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
       dG3DIPVariableBase* ipvm = static_cast<dG3DIPVariableBase*>(ipsm->getState(ws));
       dG3DIPVariableBase* ipvp = static_cast<dG3DIPVariableBase*>(ipsp->getState(ws));
 
-
       const std::vector<TensorialTraits<double>::GradType> &Grads = vgps[j]->_vgrads;
       // minus outward normal
       static SVector3 referencePhi0[2];
@@ -1502,10 +1525,10 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
         STensorOperation::zero(phi0Cur[0]);
         STensorOperation::zero(phi0Cur[1]);
 
-        FunctionSpace<double>* spaceMinus = dynamic_cast<FunctionSpace<double>*> (_spaceminus);
 
         std::vector<TensorialTraits<double>::GradType> gradmUVW;
-        spaceMinus->gradfuvw(em,GPm[j].pt[0],GPm[j].pt[1],GPm[j].pt[2],gradmUVW);
+        _spaceminus->gradfuvw(em,GPm[j].pt[0],GPm[j].pt[1],GPm[j].pt[2],gradmUVW);
+        int nbFFm = em->getNumVertices();
         for(int k=0;k<nbFFm;k++)
         {
           double x = em->getVertex(k)->x();
@@ -1517,9 +1540,9 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
            phi0[i](0) += gradmUVW[k](i)*x;
            phi0[i](1) += gradmUVW[k+nbFFm](i)*y;
            phi0[i](2) += gradmUVW[k+nbFFm+nbFFm](i)*z;
-           phi0Cur[i](0) += gradmUVW[k](i)*(x+dispm(k));
-           phi0Cur[i](1) += gradmUVW[k+nbFFm](i)*(y+dispm(k+nbFFm));
-           phi0Cur[i](2) += gradmUVW[k+nbFFm+nbFFm](i)*(z+dispm(k+2*nbFFm));
+           phi0Cur[i](0) += gradmUVW[k](i)*x;
+           phi0Cur[i](1) += gradmUVW[k+nbFFm](i)*y;
+           phi0Cur[i](2) += gradmUVW[k+2*nbFFm](i)*z;
           }
         }
 
@@ -1605,45 +1628,55 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
 
       STensor3& Fm = ipvm->getRefToDeformationGradient();
       STensorOperation::unity(Fm);
-      for (int i = 0; i < nbFFm; i++)
+      int nbFFmTotalLast = 0; 
+      for (int cc=0; cc <3; cc++)
       {
-        //x y z: take compoenent x arbitrarily
-        // xx yy zz xy xz yz
-        Fm(0,0) += Gradm[i+0*nbFFm][0]*dispm(i);
-        Fm(0,1) += Gradm[i+0*nbFFm][1]*dispm(i);
-        Fm(0,2) += Gradm[i+0*nbFFm][2]*dispm(i);
-        Fm(1,0) += Gradm[i+0*nbFFm][0]*dispm(i+nbFFm);
-        Fm(1,1) += Gradm[i+0*nbFFm][1]*dispm(i+nbFFm);
-        Fm(1,2) += Gradm[i+0*nbFFm][2]*dispm(i+nbFFm);
-        Fm(2,0) += Gradm[i+0*nbFFm][0]*dispm(i+2*nbFFm);
-        Fm(2,1) += Gradm[i+0*nbFFm][1]*dispm(i+2*nbFFm);
-        Fm(2,2) += Gradm[i+0*nbFFm][2]*dispm(i+2*nbFFm);
+        int nbFFm = _spaceminus->getNumShapeFunctions(em,cc);
+        for (int i = 0; i < nbFFm; i++)
+        {
+          Fm(cc,0) += Gradm[i+nbFFmTotalLast][0]*dispm(i+nbFFmTotalLast);
+          Fm(cc,1) += Gradm[i+nbFFmTotalLast][1]*dispm(i+nbFFmTotalLast);
+          Fm(cc,2) += Gradm[i+nbFFmTotalLast][2]*dispm(i+nbFFmTotalLast);
+        }
+        nbFFmTotalLast += nbFFm;
       }
       if(STensorOperation::determinantSTensor3(Fm) < 1.e-15) Msg::Error("Negative Jacobian Fm, em = %d, ele=%d",em->getNum(),ele->getNum());
 
       STensor3& Fp = ipvp->getRefToDeformationGradient();
       STensorOperation::unity(Fp);
-      for (int i = 0; i < nbFFp; i++)
+      int nbFFpTotalLast = 0; 
+      for (int cc=0; cc <3; cc++)
       {
-        //x y z: take compoenent x arbitrarily
-        // xx yy zz xy xz yz
-        Fp(0,0) += Gradp[i+0*nbFFp][0]*dispp(i);
-        Fp(0,1) += Gradp[i+0*nbFFp][1]*dispp(i);
-        Fp(0,2) += Gradp[i+0*nbFFp][2]*dispp(i);
-        Fp(1,0) += Gradp[i+0*nbFFp][0]*dispp(i+nbFFp);
-        Fp(1,1) += Gradp[i+0*nbFFp][1]*dispp(i+nbFFp);
-        Fp(1,2) += Gradp[i+0*nbFFp][2]*dispp(i+nbFFp);
-        Fp(2,0) += Gradp[i+0*nbFFp][0]*dispp(i+2*nbFFp);
-        Fp(2,1) += Gradp[i+0*nbFFp][1]*dispp(i+2*nbFFp);
-        Fp(2,2) += Gradp[i+0*nbFFp][2]*dispp(i+2*nbFFp);
+        int nbFFp = _spaceplus->getNumShapeFunctions(ep,cc); 
+        for (int i = 0; i < nbFFp; i++)
+        {
+          Fp(cc,0) += Gradp[i+nbFFpTotalLast][0]*dispp(i+nbFFpTotalLast);
+          Fp(cc,1) += Gradp[i+nbFFpTotalLast][1]*dispp(i+nbFFpTotalLast);
+          Fp(cc,2) += Gradp[i+nbFFpTotalLast][2]*dispp(i+nbFFpTotalLast);
+        }
+        nbFFpTotalLast += nbFFp;
       }
       if(STensorOperation::determinantSTensor3(Fp) < 1.e-15) Msg::Error("Negative Jacobian Fp, ep =%d ele = %d",ep->getNum(),ele->getNum());
       
       // displacement jump
       SVector3& ujump = ipvm->getRefToJump();
-      computeJump(Valm,nbFFm,Valp,nbFFp,dispm,dispp,ujump);
+      int nbFFmx = _spaceminus->getNumShapeFunctions(em,0);
+      int nbFFmy = _spaceminus->getNumShapeFunctions(em,1);
+      int nbFFmz = _spaceminus->getNumShapeFunctions(em,2);
+      int nbFFpx = _spaceplus->getNumShapeFunctions(ep,0);
+      int nbFFpy = _spaceplus->getNumShapeFunctions(ep,1);
+      int nbFFpz = _spaceplus->getNumShapeFunctions(ep,2);
+      
+      ujump[0] = computeJumpField(Valm,0,nbFFmx,Valp,0,nbFFpx,dispm,dispp);
+      ujump[1] = computeJumpField(Valm,nbFFmx,nbFFmy,Valp,nbFFpx,nbFFpy,dispm,dispp);
+      ujump[2] = computeJumpField(Valm,nbFFmx+nbFFmy,nbFFmz,Valp,nbFFpx+nbFFpy,nbFFpz,dispm,dispp);
       ipvp->getRefToJump() = ujump;
-    }
+    };
+    
+    // add computed component
+    comp.push_back(0);
+    comp.push_back(1);
+    comp.push_back(2);
     
     if(useBarF)
     {
@@ -1728,6 +1761,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
        
         // non-local for minus part
         if( ipvm->getNumberNonLocalVariable()>getNumNonLocalVariable()) Msg::Error("Your material law uses more non local variables than your domain dG3DDomain::computeStrain negative interface");
+        int nbFFmTotalLast = _spaceminus->getNumShapeFunctions(em,comp);
         for (int nlm = 0; nlm < ipvm->getNumberNonLocalVariable(); nlm++)
         {
           double& nonlocalVarm = ipvm->getRefToNonLocalVariable(nlm);
@@ -1735,43 +1769,60 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
           
           SVector3& gradNonlocalVarm = ipvm->getRefToGradNonLocalVariable()[nlm];
           STensorOperation::zero(gradNonlocalVarm);
-
+          int nbFFm = _spaceminus->getNumShapeFunctions(em,3+nlm);
           for (int i = 0; i < nbFFm; i++)
           {
              //epsbar: take compoenent epsbar
-            nonlocalVarm += Valm[i+3*nbFFm+nlm*nbFFm]*dispm(i+3*nbFFm+nlm*nbFFm);
-            gradNonlocalVarm(0) += Gradm[i+3*nbFFm+nlm*nbFFm][0]*dispm(i+3*nbFFm+nlm*nbFFm);
-            gradNonlocalVarm(1) += Gradm[i+3*nbFFm+nlm*nbFFm][1]*dispm(i+3*nbFFm+nlm*nbFFm);
-            gradNonlocalVarm(2) += Gradm[i+3*nbFFm+nlm*nbFFm][2]*dispm(i+3*nbFFm+nlm*nbFFm);
+            nonlocalVarm += Valm[i+nbFFmTotalLast]*dispm(i+nbFFmTotalLast);
+            gradNonlocalVarm(0) += Gradm[i+nbFFmTotalLast][0]*dispm(i+nbFFmTotalLast);
+            gradNonlocalVarm(1) += Gradm[i+nbFFmTotalLast][1]*dispm(i+nbFFmTotalLast);
+            gradNonlocalVarm(2) += Gradm[i+nbFFmTotalLast][2]*dispm(i+nbFFmTotalLast);
           }
+          nbFFmTotalLast += nbFFm;
         }
 
         // for plus part
         if( ipvp->getNumberNonLocalVariable()>getNumNonLocalVariable() ) Msg::Error("Your material law uses more non local variables than your domain dG3DDomain::computeStrain positive interface");
+        int nbFFpTotalLast = _spaceplus->getNumShapeFunctions(ep,comp);
         for (int nlp = 0; nlp < ipvp->getNumberNonLocalVariable(); nlp++)
         {
           double& nonlocalVarp = ipvp->getRefToNonLocalVariable(nlp);
           nonlocalVarp = 0.;
           SVector3& gradNonlocalVarp = ipvp->getRefToGradNonLocalVariable()[nlp];
           STensorOperation::zero(gradNonlocalVarp);
-
+          int nbFFp = _spaceminus->getNumShapeFunctions(ep,3+nlp);
           for (int i = 0; i < nbFFp; i++)
           {
              //epsbar: take compoenent epsbar
-            nonlocalVarp += Valp[i+3*nbFFp+nlp*nbFFp]*dispp(i+3*nbFFp+nlp*nbFFp);
-            gradNonlocalVarp(0) += Gradp[i+3*nbFFp+nlp*nbFFp][0]*dispp(i+3*nbFFp+nlp*nbFFp);
-            gradNonlocalVarp(1) += Gradp[i+3*nbFFp+nlp*nbFFp][1]*dispp(i+3*nbFFp+nlp*nbFFp);
-            gradNonlocalVarp(2) += Gradp[i+3*nbFFp+nlp*nbFFp][2]*dispp(i+3*nbFFp+nlp*nbFFp);
+            nonlocalVarp += Valp[i+nbFFpTotalLast]*dispp(i+nbFFpTotalLast);
+            gradNonlocalVarp(0) += Gradp[i+nbFFpTotalLast][0]*dispp(i+nbFFpTotalLast);
+            gradNonlocalVarp(1) += Gradp[i+nbFFpTotalLast][1]*dispp(i+nbFFpTotalLast);
+            gradNonlocalVarp(2) += Gradp[i+nbFFpTotalLast][2]*dispp(i+nbFFpTotalLast);
           }
+          nbFFpTotalLast += nbFFp;
         }
 
         // compute the jump
-        for (int nl = 0; nl < ipvp->getNumberNonLocalVariable(); nl++){
+        // reset the number
+        nbFFmTotalLast = _spaceminus->getNumShapeFunctions(em,comp);
+        nbFFpTotalLast = _spaceplus->getNumShapeFunctions(ep,comp);
+        for (int nl = 0; nl < ipvp->getNumberNonLocalVariable(); nl++)
+        {
+          int nbFFm = _spaceminus->getNumShapeFunctions(em,3+nl);
+          int nbFFp = _spaceminus->getNumShapeFunctions(ep,3+nl);
           double& epsjump= ipvm->getRefToNonLocalJump()(nl);
-          computeNonLocalJump(Valm,nbFFm,Valp,nbFFp,dispm,dispp,epsjump,nl);
+          epsjump = computeJumpField(Valm,nbFFmTotalLast,nbFFm,Valp,nbFFmTotalLast,nbFFp,dispm,dispp);
           ipvp->getRefToNonLocalJump()(nl) = epsjump;
+          nbFFmTotalLast += nbFFm;
+          nbFFpTotalLast += nbFFp;
         }
       }
+      
+      // update nonlocal component
+      for (int nl = 0; nl < getNumNonLocalVariable(); nl++)
+      {
+        comp.push_back(3+nl);
+      }
 
       if (useAverageNonlocal)
       {
@@ -1853,6 +1904,70 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
      * COHESIVE AND FRACTURE 
      * 
      * **/
+     
+     // comupute jump at each interfce nodes
+    fullVector<double> jumpinter;
+    bool willComputeJumpinter = false;
+    for(int j=0;j<npts;j++)
+    {
+      IPStateBase* ipsm = (*vips)[j];
+      IPStateBase* ipsp = (*vips)[j+npts];
+      FractureCohesive3DIPVariable *ipvfm = dynamic_cast<FractureCohesive3DIPVariable*>(ipsm->getState(ws));
+      FractureCohesive3DIPVariable *ipvfp = dynamic_cast<FractureCohesive3DIPVariable*>(ipsp->getState(ws));
+      if((ipvfm!=NULL) and (ipvfp!= NULL) )
+      {
+        Cohesive3DIPVariableBase* cohipvfm = ipvfm->getIPvFrac();
+        Cohesive3DIPVariableBase* cohipvfp = ipvfp->getIPvFrac();
+        // Compute spatial gradient of jump on interface at interface IP
+        if (cohipvfm->withJumpGradient() and cohipvfp->withJumpGradient())
+        {
+          willComputeJumpinter = true;
+          break;
+        }
+      }
+      else
+      {
+        // all ip in one state has same type
+        break;
+      }
+    }
+    
+    if (willComputeJumpinter)
+    {
+      jumpinter.resize(3*nbvertexInter);
+      jumpinter.setAll(0.);
+      for (int iv=0; iv < nbvertexInter; iv++)
+      {
+        double um, vm, wm;
+        double up, vp, wp;
+        em->getNode(vnlist[iv],um,vm,wm);
+        ep->getNode(vplist[iv],up,vp,wp);
+        
+        std::vector<TensorialTraits<double>::ValType> Valm, Valp;
+        _spaceminus->f(em,um,vm,wm,Valm);
+        _spaceplus->f(ep,up,vp,wp,Valp);
+        
+        int nbFFmLastTotal = 0;
+        int nbFFpLastTotal = 0;
+        for (int i=0; i<3; i++)
+        {
+          int nbFFm = _spaceminus->getNumShapeFunctions(em,i);
+          for (int k=0; k< nbFFm; k++)
+          {
+            jumpinter(iv+i*nbvertexInter) -= Valm[k+nbFFmLastTotal]*dispm(k+nbFFmLastTotal);
+          }
+          nbFFmLastTotal += nbFFm;
+          
+          int nbFFp = _spaceplus->getNumShapeFunctions(ep,i);
+          for (int k=0; k< nbFFp; k++)
+          {
+            jumpinter(iv+i*nbvertexInter) += Valp[k+nbFFpLastTotal]*dispp(k+nbFFpLastTotal);
+          }
+          nbFFpLastTotal += nbFFp;
+        }
+      }
+    }
+     
     for(int j=0;j<npts;j++)
     {
     
@@ -1882,7 +1997,8 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
         }
 
         // Compute spatial gradient of jump on interface at interface IP
-        if (cohipvfm->withJumpGradient() and cohipvfp->withJumpGradient()){
+        if (cohipvfm->withJumpGradient() and cohipvfp->withJumpGradient())
+        {
           const std::vector<TensorialTraits<double>::GradType>& gradVal = ipvm->gradf(_extraSpace,ie,GP[j]);
           STensor3& Gradjumpm =  cohipvfm->getRefToJumpGradient();
           STensorOperation::zero(Gradjumpm);
@@ -1968,31 +2084,32 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
         // constitutive extra dofs
         if( ipvm->getNumConstitutiveExtraDofDiffusionVariable()>getNumConstitutiveExtraDofDiffusionVariable() )
           Msg::Error("Your material law uses more constitutive extra dof diffusion variables than your domain dG3DDomain::computeStrain bulk");
+          
+        int nbFFmTotalLast = _spaceminus->getNumShapeFunctions(em,comp);
         for (int extraDOFFieldm = 0; extraDOFFieldm < ipvm->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFFieldm++)
         {
-          double& Tm = ipvm->getRefToField(extraDOFFieldm);
-          Tm = 0.;
-          SVector3& gradTm = ipvm->getRefToGradField()[extraDOFFieldm];
-          STensorOperation::zero(gradTm);
-          for (int i = 0; i < nbFFm; i++)
-          {
-            int indexField=3+getNumNonLocalVariable()+extraDOFFieldm;
-            Tm += Valm[i+indexField*nbFFm]*dispm(i+indexField*nbFFm);
-            gradTm(0) += Gradm[i+indexField*nbFFm][0]*dispm(i+indexField*nbFFm);
-            gradTm(1) += Gradm[i+indexField*nbFFm][1]*dispm(i+indexField*nbFFm);
-            gradTm(2) += Gradm[i+indexField*nbFFm][2]*dispm(i+indexField*nbFFm);
-          }
-
           if((ipvm->getNumConstitutiveExtraDofDiffusionVariable() == 2)&&(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()))
           {
             double& energyConjugatedFieldm = ipvm->getRefToEnergyConjugatedField(extraDOFFieldm);
             SVector3& gradEnergyConjugatedFieldm = ipvm->getRefToGradEnergyConjugatedField()[extraDOFFieldm];
             energyConjugatedFieldm = 0.;
             STensorOperation::zero(gradEnergyConjugatedFieldm);
+            
+            int nbFFm = _spaceminus->getNumShapeFunctions(em,3+getNumNonLocalVariable()+extraDOFFieldm);
+            for (int i = 0; i < nbFFm; i++)
+            {
+              const double& ftemp = dispm(i+nbFFmTotalLast);
+              energyConjugatedFieldm += Valm[i+nbFFmTotalLast]*ftemp;
+              gradEnergyConjugatedFieldm(0) += Gradm[i+nbFFmTotalLast][0]*ftemp;
+              gradEnergyConjugatedFieldm(1) += Gradm[i+nbFFmTotalLast][1]*ftemp;
+              gradEnergyConjugatedFieldm(2) += Gradm[i+nbFFmTotalLast][2]*ftemp;
+            }
+            nbFFmTotalLast += nbFFm;
 
-            int extraDOFField_aux=0;
-            if((extraDOFFieldm+1)< ipvm->getNumConstitutiveExtraDofDiffusionVariable()) extraDOFField_aux=extraDOFFieldm+1;
-            else extraDOFField_aux=extraDOFFieldm-1;
+            double& Tm = ipvm->getRefToField(extraDOFFieldm);
+            SVector3& gradTm = ipvm->getRefToGradField()[extraDOFFieldm];
+            
+            int extraDOFField_aux= (extraDOFFieldm == 0)? 1 : 0;
 
             double& dFielddEnergyConjugatedFieldm = ipvm->getRefTodFielddEnergyConjugatedField()[extraDOFFieldm][extraDOFFieldm];
             double& dFielddEnergyConjugatedField2m = ipvm->getRefTodFielddEnergyConjugatedField()[extraDOFFieldm][extraDOFField_aux];
@@ -2001,40 +2118,27 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
             STensor3& dGradFielddGradEnergyConjugatedFieldm = ipvm->getRefTodGradFielddGradEnergyConjugatedField()[extraDOFFieldm][extraDOFFieldm];
             STensor3& dGradFielddGradEnergyConjugatedField2m = ipvm->getRefTodGradFielddGradEnergyConjugatedField()[extraDOFFieldm][extraDOFField_aux];
 
-            STensorOperation::zero(dGradFielddGradEnergyConjugatedFieldm); STensorOperation::zero(dGradFielddGradEnergyConjugatedField2m);
-
-            int indexFieldfT=3+getNumNonLocalVariable()+extraDOFFieldm;
-
-            for (int i = 0; i < nbFFm; i++)
-            {
-              const double& ftemp = dispm(i+indexFieldfT*nbFFm);
-              energyConjugatedFieldm += Valm[i+indexFieldfT*nbFFm]*ftemp;
-              gradEnergyConjugatedFieldm(0) += Gradm[i+indexFieldfT*nbFFm][0]*ftemp;
-              gradEnergyConjugatedFieldm(1) += Gradm[i+indexFieldfT*nbFFm][1]*ftemp;
-              gradEnergyConjugatedFieldm(2) += Gradm[i+indexFieldfT*nbFFm][2]*ftemp;
-            }
-
             if(extraDOFFieldm == 0)
             {
-             Tm = 1/(energyConjugatedFieldm);
-
-             gradTm(0)=-1/(pow(energyConjugatedFieldm,2))*(gradEnergyConjugatedFieldm(0));
-             gradTm(1)=-1/(pow(energyConjugatedFieldm,2))*(gradEnergyConjugatedFieldm(1));
-             gradTm(2)=-1/(pow(energyConjugatedFieldm,2))*(gradEnergyConjugatedFieldm(2));
+              Tm = 1/(energyConjugatedFieldm);
 
-             dFielddEnergyConjugatedFieldm  = -1./(energyConjugatedFieldm)/(energyConjugatedFieldm);
-             dFielddEnergyConjugatedField2m = 0.;
+              gradTm(0)=-1/(pow(energyConjugatedFieldm,2))*(gradEnergyConjugatedFieldm(0));
+              gradTm(1)=-1/(pow(energyConjugatedFieldm,2))*(gradEnergyConjugatedFieldm(1));
+              gradTm(2)=-1/(pow(energyConjugatedFieldm,2))*(gradEnergyConjugatedFieldm(2));
 
-             dGradFielddEnergyConjugatedFieldm(0)=2/(energyConjugatedFieldm)/(energyConjugatedFieldm)/(energyConjugatedFieldm)*(gradEnergyConjugatedFieldm(0));
-             dGradFielddEnergyConjugatedFieldm(1)=2/(energyConjugatedFieldm)/(energyConjugatedFieldm)/(energyConjugatedFieldm)*(gradEnergyConjugatedFieldm(1));
-             dGradFielddEnergyConjugatedFieldm(2)=2/(energyConjugatedFieldm)/(energyConjugatedFieldm)/(energyConjugatedFieldm)*(gradEnergyConjugatedFieldm(2));
+              dFielddEnergyConjugatedFieldm  = -1./(energyConjugatedFieldm)/(energyConjugatedFieldm);
+              dFielddEnergyConjugatedField2m = 0.;
 
-             dGradFielddEnergyConjugatedField2m(0)=0.;
-             dGradFielddEnergyConjugatedField2m(1)=0.;
-             dGradFielddEnergyConjugatedField2m(2)=0.;
+              dGradFielddEnergyConjugatedFieldm(0)=2/(energyConjugatedFieldm)/(energyConjugatedFieldm)/(energyConjugatedFieldm)*(gradEnergyConjugatedFieldm(0));
+              dGradFielddEnergyConjugatedFieldm(1)=2/(energyConjugatedFieldm)/(energyConjugatedFieldm)/(energyConjugatedFieldm)*(gradEnergyConjugatedFieldm(1));
+              dGradFielddEnergyConjugatedFieldm(2)=2/(energyConjugatedFieldm)/(energyConjugatedFieldm)/(energyConjugatedFieldm)*(gradEnergyConjugatedFieldm(2));
 
-             STensorOperation::diag(dGradFielddGradEnergyConjugatedFieldm,-1./(energyConjugatedFieldm)/(energyConjugatedFieldm));
+              dGradFielddEnergyConjugatedField2m(0)=0.;
+              dGradFielddEnergyConjugatedField2m(1)=0.;
+              dGradFielddEnergyConjugatedField2m(2)=0.;
 
+              STensorOperation::diag(dGradFielddGradEnergyConjugatedFieldm,-1./(energyConjugatedFieldm)/(energyConjugatedFieldm));
+              STensorOperation::zero(dGradFielddGradEnergyConjugatedField2m);
             }
             else
             {
@@ -2062,35 +2166,52 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
                STensorOperation::diag(dGradFielddGradEnergyConjugatedField2m,(energyConjugatedFieldm)/(fTm)/(fTm));
             }
           }
+          else
+          {
+            double& Tm = ipvm->getRefToField(extraDOFFieldm);
+            Tm = 0.;
+            SVector3& gradTm = ipvm->getRefToGradField()[extraDOFFieldm];
+            STensorOperation::zero(gradTm);
+            
+            int nbFFm = _spaceminus->getNumShapeFunctions(em,3+getNumNonLocalVariable()+extraDOFFieldm);
+            for (int i = 0; i < nbFFm; i++)
+            {
+              Tm += Valm[i+nbFFmTotalLast]*dispm(i+nbFFmTotalLast);
+              gradTm(0) += Gradm[i+nbFFmTotalLast][0]*dispm(i+nbFFmTotalLast);
+              gradTm(1) += Gradm[i+nbFFmTotalLast][1]*dispm(i+nbFFmTotalLast);
+              gradTm(2) += Gradm[i+nbFFmTotalLast][2]*dispm(i+nbFFmTotalLast);
+            }
+            nbFFmTotalLast  += nbFFm;
+          }
         }
         if( ipvp->getNumConstitutiveExtraDofDiffusionVariable()>getNumConstitutiveExtraDofDiffusionVariable() )
           Msg::Error("Your material law uses more constitutive extra dof diffusion variables than your domain dG3DDomain::computeStrain bulk");
+          
+        int nbFFpTotalLast = _spaceplus->getNumShapeFunctions(ep,comp);
         for (int extraDOFFieldp = 0; extraDOFFieldp < ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFFieldp++)
         {
-          double&  Tp = ipvp->getRefToField(extraDOFFieldp);
-          Tp = 0.;
-          SVector3& gradTp = ipvp->getRefToGradField()[extraDOFFieldp];
-          STensorOperation::zero(gradTp);
-          
-          for (int i = 0; i < nbFFp; i++)
-          {
-            int indexField=3+getNumNonLocalVariable()+extraDOFFieldp;
-            Tp += Valp[i+indexField*nbFFp]*dispp(i+indexField*nbFFp);
-            gradTp(0) += Gradp[i+indexField*nbFFp][0]*dispp(i+indexField*nbFFp);
-            gradTp(1) += Gradp[i+indexField*nbFFp][1]*dispp(i+indexField*nbFFp);
-            gradTp(2) += Gradp[i+indexField*nbFFp][2]*dispp(i+indexField*nbFFp);
-          }
-
           if((ipvp->getNumConstitutiveExtraDofDiffusionVariable() == 2)&&(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()))
           {
             double& energyConjugatedFieldp = ipvp->getRefToEnergyConjugatedField(extraDOFFieldp);
             SVector3& gradEnergyConjugatedFieldp = ipvp->getRefToGradEnergyConjugatedField()[extraDOFFieldp];
             energyConjugatedFieldp = 0.;
             STensorOperation::zero(gradEnergyConjugatedFieldp);
+            
+            int nbFFp = _spaceplus->getNumShapeFunctions(ep,3+getNumNonLocalVariable()+extraDOFFieldp);
+            for (int i = 0; i < nbFFp; i++)
+            {
+              const double& ftemp = dispp(i+nbFFpTotalLast);
+              energyConjugatedFieldp += Valp[i+nbFFpTotalLast]*ftemp;
+              gradEnergyConjugatedFieldp(0) += Gradp[i+nbFFpTotalLast][0]*ftemp;
+              gradEnergyConjugatedFieldp(1) += Gradp[i+nbFFpTotalLast][1]*ftemp;
+              gradEnergyConjugatedFieldp(2) += Gradp[i+nbFFpTotalLast][2]*ftemp;
+            }
+            nbFFpTotalLast += nbFFp;
+            
+            double&  Tp = ipvp->getRefToField(extraDOFFieldp);
+            SVector3& gradTp = ipvp->getRefToGradField()[extraDOFFieldp];
 
-            int extraDOFField_aux=0;
-            if((extraDOFFieldp+1)< ipvp->getNumConstitutiveExtraDofDiffusionVariable()) extraDOFField_aux=extraDOFFieldp+1;
-            else extraDOFField_aux=extraDOFFieldp-1;
+            int extraDOFField_aux= (extraDOFFieldp == 0)? 1 : 0;
 
             double& dFielddEnergyConjugatedFieldp = ipvp->getRefTodFielddEnergyConjugatedField()[extraDOFFieldp][extraDOFFieldp];
             double& dFielddEnergyConjugatedField2p = ipvp->getRefTodFielddEnergyConjugatedField()[extraDOFFieldp][extraDOFField_aux];
@@ -2099,19 +2220,6 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
             STensor3& dGradFielddGradEnergyConjugatedFieldp = ipvp->getRefTodGradFielddGradEnergyConjugatedField()[extraDOFFieldp][extraDOFFieldp];
             STensor3& dGradFielddGradEnergyConjugatedField2p = ipvp->getRefTodGradFielddGradEnergyConjugatedField()[extraDOFFieldp][extraDOFField_aux];
 
-            STensorOperation::zero(dGradFielddGradEnergyConjugatedFieldp); STensorOperation::zero(dGradFielddGradEnergyConjugatedField2p);
-
-            int indexFieldfT=3+getNumNonLocalVariable()+extraDOFFieldp;
-
-            for (int i = 0; i < nbFFp; i++)
-            {
-              const double& ftemp = dispp(i+indexFieldfT*nbFFp);
-              energyConjugatedFieldp += Valp[i+indexFieldfT*nbFFp]*ftemp;
-              gradEnergyConjugatedFieldp(0) += Gradp[i+indexFieldfT*nbFFp][0]*ftemp;
-              gradEnergyConjugatedFieldp(1) += Gradp[i+indexFieldfT*nbFFp][1]*ftemp;
-              gradEnergyConjugatedFieldp(2) += Gradp[i+indexFieldfT*nbFFp][2]*ftemp;
-            }
-
             if(extraDOFFieldp == 0)
             {
               Tp = 1/(energyConjugatedFieldp);
@@ -2132,6 +2240,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
               dGradFielddEnergyConjugatedField2p(2)=0.;
 
               STensorOperation::diag(dGradFielddGradEnergyConjugatedFieldp,-1./(energyConjugatedFieldp)/(energyConjugatedFieldp));
+              STensorOperation::zero(dGradFielddGradEnergyConjugatedField2p);
             }
             else
             {
@@ -2159,25 +2268,57 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
               STensorOperation::diag(dGradFielddGradEnergyConjugatedField2p,(energyConjugatedFieldp)/(fTp)/(fTp));
             }
           }
+          else
+          {
+            double&  Tp = ipvp->getRefToField(extraDOFFieldp);
+            Tp = 0.;
+            SVector3& gradTp = ipvp->getRefToGradField()[extraDOFFieldp];
+            STensorOperation::zero(gradTp);
+            
+            int nbFFp = _spaceplus->getNumShapeFunctions(ep,3+getNumNonLocalVariable()+extraDOFFieldp);
+            for (int i = 0; i < nbFFp; i++)
+            {
+              Tp += Valp[i+nbFFpTotalLast]*dispp(i+nbFFpTotalLast);
+              gradTp(0) += Gradp[i+nbFFpTotalLast][0]*dispp(i+nbFFpTotalLast);
+              gradTp(1) += Gradp[i+nbFFpTotalLast][1]*dispp(i+nbFFpTotalLast);
+              gradTp(2) += Gradp[i+nbFFpTotalLast][2]*dispp(i+nbFFpTotalLast);
+            }
+            nbFFpTotalLast += nbFFp;
+          }
         }
         // compute the jump
+        // reset counter
+        nbFFmTotalLast = _spaceminus->getNumShapeFunctions(em,comp);
+        nbFFpTotalLast = _spaceplus->getNumShapeFunctions(ep,comp);
+        
+        std::vector<double> Tminus, Tplus;
+        Tminus.resize(getNumConstitutiveExtraDofDiffusionVariable());
+        Tplus.resize(getNumConstitutiveExtraDofDiffusionVariable());
+        
         for (int extraDOFField = 0; extraDOFField < ipvm->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
         {
-          int indexField=3+getNumNonLocalVariable()+extraDOFField;
+          int nbFFm = _spaceminus->getNumShapeFunctions(em,3+getNumNonLocalVariable()+extraDOFField);
+          int nbFFp = _spaceplus->getNumShapeFunctions(ep,3+getNumNonLocalVariable()+extraDOFField);
 
           if(ipvm->getNumConstitutiveExtraDofDiffusionVariable()==1) //thermomec
           {
-            double& tempjump= ipvm->getRefToFieldJump()(extraDOFField);
-            computeExtraFieldJump(indexField,Valm,nbFFm,Valp,nbFFp,dispm,dispp,tempjump);
-            double tpj=tempjump;
-            ipvp->getRefToFieldJump()(extraDOFField) = tpj;
+            Tminus[extraDOFField] = computFieldValue(Valm,nbFFmTotalLast,nbFFm,dispm);
+            Tplus[extraDOFField] = computFieldValue(Valp,nbFFpTotalLast,nbFFp,dispp);
+            
+            ipvm->getRefToFieldJump()(extraDOFField) = Tplus[extraDOFField] - Tminus[extraDOFField];
+            ipvp->getRefToFieldJump()(extraDOFField) = Tplus[extraDOFField] - Tminus[extraDOFField];
+            
             // compute 1/T jump to be energetically consistent
             if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
             {
               double& ftjump = ipvm->getRefToEnergyConjugatedFieldJump()(extraDOFField);
               double& dftjumpdTp = ipvp->getRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][extraDOFField];
               double& dftjumpdTm = ipvm->getRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][extraDOFField];
-              computeftjump(3+getNumNonLocalVariable(),Valm,nbFFm,Valp,nbFFp,dispm,dispp,ftjump,dftjumpdTp,dftjumpdTm);
+              
+              ftjump = 1./Tplus[extraDOFField]-1./Tminus[extraDOFField];
+              dftjumpdTp = -1./(Tplus[extraDOFField]*Tplus[extraDOFField]);
+              dftjumpdTm = 1./(Tminus[extraDOFField]*Tminus[extraDOFField]);
+              
               ipvp->getRefToEnergyConjugatedFieldJump()(extraDOFField) = ftjump;
               ipvm->getRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][extraDOFField] = dftjumpdTm;
               ipvp->getRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][extraDOFField] = dftjumpdTp;
@@ -2187,46 +2328,64 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
           {
             if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
             {
-             double& ftjump = ipvm->getRefToEnergyConjugatedFieldJump()(extraDOFField);
-             computeExtraFieldJump(indexField,Valm,nbFFm,Valp,nbFFp,dispm,dispp,ftjump);
-             double tpj=ftjump;
-             ipvp->getRefToEnergyConjugatedFieldJump()(extraDOFField) = tpj;
+              double& ftjump = ipvm->getRefToEnergyConjugatedFieldJump()(extraDOFField);
+              ftjump = computeJumpField(Valm,nbFFmTotalLast,nbFFm,Valp,nbFFpTotalLast,nbFFp,dispm,dispp);
+              ipvp->getRefToEnergyConjugatedFieldJump()(extraDOFField) = ftjump;
             }
             else
             {
-              double& tempjump= ipvm->getRefToFieldJump()(extraDOFField);
-              computeExtraFieldJump(indexField,Valm,nbFFm,Valp,nbFFp,dispm,dispp,tempjump);
-              double tpj =tempjump;
-              ipvp->getRefToFieldJump()(extraDOFField) = tpj;
-
-              double& ftjump = ipvm->getRefToEnergyConjugatedFieldJump()(extraDOFField);
-              double& dftjumpdTp = ipvp->getRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][extraDOFField];
-              double& dftjumpdTm = ipvm->getRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][extraDOFField];
-
+              Tminus[extraDOFField] = computFieldValue(Valm,nbFFmTotalLast,nbFFm,dispm);
+              Tplus[extraDOFField] = computFieldValue(Valp,nbFFpTotalLast,nbFFp,dispp);
+              ipvm->getRefToFieldJump()(extraDOFField) = Tplus[extraDOFField] - Tminus[extraDOFField];
+              ipvp->getRefToFieldJump()(extraDOFField) = Tplus[extraDOFField] - Tminus[extraDOFField];
+              
               if(extraDOFField==0)
               {
-                computeftjump(indexField,Valm,nbFFm,Valp,nbFFp,dispm,dispp,ftjump,dftjumpdTp,dftjumpdTm);
+                double& ftjump = ipvm->getRefToEnergyConjugatedFieldJump()(extraDOFField);
+                double& dftjumpdTp = ipvp->getRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][extraDOFField];
+                double& dftjumpdTm = ipvm->getRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][extraDOFField]; 
+          
+                ftjump = 1./Tplus[extraDOFField]-1./Tminus[extraDOFField];
+                dftjumpdTp = -1./(Tplus[extraDOFField]*Tplus[extraDOFField]);
+                dftjumpdTm = 1./(Tminus[extraDOFField]*Tminus[extraDOFField]);
+                
                 ipvp->getRefToEnergyConjugatedFieldJump()(extraDOFField) = ftjump;
-                ipvm->getRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][extraDOFField] = dftjumpdTm;
-                ipvp->getRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][extraDOFField] = dftjumpdTp;
               }
               else
               {
-               double& dftjumpdT2p = ipvp->getRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][0];
-               double& dftjumpdT2m = ipvm->getRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][0];
-               computefvjump(indexField-1,indexField,Valm,nbFFm,Valp,nbFFp,dispm,dispp,ftjump,dftjumpdT2p,dftjumpdT2m,dftjumpdTp,dftjumpdTm);
-               ipvp->getRefToEnergyConjugatedFieldJump()(extraDOFField) = ftjump;
-               ipvm->getRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][extraDOFField] = dftjumpdTm;
-               ipvp->getRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][extraDOFField] = dftjumpdTp;
-               ipvm->getRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][0] = dftjumpdT2m;
-               ipvp->getRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][0] = dftjumpdT2p;
+                double& fvjump = ipvm->getRefToEnergyConjugatedFieldJump()(extraDOFField);
+                double& dfvjumpdvp = ipvp->getRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][extraDOFField];
+                double& dfvjumpdvm = ipvm->getRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][extraDOFField]; 
+                double& dfvjumpdTp = ipvp->getRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][0];
+                double& dfvjumpdTm = ipvm->getRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][0];
+                
+                double vm = Tminus[1];
+                double vp = Tplus[1];
+                double tm = Tminus[0];
+                double tp = Tplus[0];
+                fvjump = vm/tm -vp/tp;
+                
+                dfvjumpdvp=-1./tp;
+                dfvjumpdvm= 1./tm;
+                dfvjumpdTp= vp/(tp*tp);
+                dfvjumpdTm=-vm/(tm*tm);
+                
+                ipvp->getRefToEnergyConjugatedFieldJump()(extraDOFField) = fvjump;
               }
             }
           }
           else Msg::Error("UseEnergyConjugatedField with more than 2 extra dofs not implemented");
+          
+          nbFFmTotalLast += nbFFm;
+          nbFFpTotalLast += nbFFp;
         }
         //
       }
+      
+      for (int extraDOFField = 0; extraDOFField < getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
+      {
+        comp.push_back(3+getNumNonLocalVariable()+extraDOFField);
+      }
     }
   }
   else
@@ -2986,46 +3145,69 @@ void dG3DDomain::initialIPVariable(AllIPState *aips,const unknownField *ufield,
   IntPt *GP;
   IntPt *GPm; IntPt *GPp;
   // loop on interface
-  for(elementGroup::elementContainer::const_iterator it=gi->begin(); it!=gi->end(); ++it){
+  
+  nlsFunctionSpace<double>* _spaceminus = dynamic_cast<nlsFunctionSpace<double>*>(getMinusDomain()->getFunctionSpace());
+  nlsFunctionSpace<double>* _spaceplus = dynamic_cast<nlsFunctionSpace<double>*>(getPlusDomain()->getFunctionSpace());
+    
+  for(elementGroup::elementContainer::const_iterator it=gi->begin(); it!=gi->end(); ++it)
+  {
     MInterfaceElement *ie = dynamic_cast<MInterfaceElement*>(it->second);
     MElement *ele = it->second; //dynamic_cast<MElement*>(ie);
     MElement *em = ie->getElem(0);
     MElement *ep = ie->getElem(1);
+    
+    
     // get displacement
     R.clear();
-    this->getFunctionSpaceMinus()->getKeys(em,R);
+    _spaceminus->getKeys(em,R);
     unknowns_m.resize(R.size());
     ufield->get(R,unknowns_m);
     R.clear();
-    this->getFunctionSpacePlus()->getKeys(ep,R);
+    _spaceplus->getKeys(ep,R);
     unknowns_p.resize(R.size());
     ufield->get(R,unknowns_p);
-
-    int nbdofinter = _space->getNumKeys(ele);
+  
+    // compute current interface based on the average displaceemnt of the node at interface    
     int nbvertexInter = ele->getNumVertices();
-    int nbFFm = ie->getElem(0)->getNumVertices();
-    int nbFFp = ie->getElem(1)->getNumVertices();
-
-    unknowns_inter.resize(nbdofinter);
-    unknowns_inter.setAll(0.);
-
-    std::vector<int> vn;
-    vn.resize(nbvertexInter);
-    ie->getLocalVertexNum(0,vn);
-    for(int i=0;i<nbvertexInter;i++){
-      unknowns_inter(i) += 0.5*unknowns_m(vn[i]);
-      unknowns_inter(i+nbvertexInter) += 0.5*unknowns_m(vn[i]+nbFFm);
-      unknowns_inter(i+2*nbvertexInter) += 0.5*unknowns_m(vn[i]+2*nbFFm);
-    }
-    std::vector<int> vp;
-    vp.resize(nbvertexInter);
-    ie->getLocalVertexNum(1,vp);
-    for(int i=0;i<nbvertexInter;i++){
-      unknowns_inter(i) += 0.5*unknowns_p(vp[i]);
-      unknowns_inter(i+nbvertexInter) += 0.5*unknowns_p(vp[i]+nbFFp);
-      unknowns_inter(i+2*nbvertexInter) +=0.5* unknowns_p(vp[i]+2*nbFFp);
+    std::vector<int> vnlist, vplist;
+    vnlist.resize(nbvertexInter);
+    ie->getLocalVertexNum(0,vnlist);
+    vplist.resize(nbvertexInter);
+    ie->getLocalVertexNum(1,vplist);
+     
+    fullVector<double> dispinter(3*nbvertexInter);
+    dispinter.setAll(0.);
+    for (int iv=0; iv < nbvertexInter; iv++)
+    {
+      double um, vm, wm;
+      double up, vp, wp;
+      em->getNode(vnlist[iv],um,vm,wm);
+      ep->getNode(vplist[iv],up,vp,wp);
+      
+      std::vector<TensorialTraits<double>::ValType> Valm, Valp;
+      _spaceminus->f(em,um,vm,wm,Valm);
+      _spaceplus->f(ep,up,vp,wp,Valp);
+      
+      int nbFFmLastTotal = 0;
+      int nbFFpLastTotal = 0;
+      for (int i=0; i<3; i++)
+      {
+        int nbFFm = _spaceminus->getNumShapeFunctions(em,i);
+        for (int k=0; k< nbFFm; k++)
+        {
+          dispinter(iv+i*nbvertexInter) += 0.5*Valm[k+nbFFmLastTotal]*unknowns_m(k+nbFFmLastTotal);
+        }
+        
+        int nbFFp = _spaceplus->getNumShapeFunctions(ep,i);
+        for (int k=0; k< nbFFp; k++)
+        {
+          dispinter(iv+i*nbvertexInter) += 0.5*Valp[k+nbFFpLastTotal]*unknowns_p(k+nbFFpLastTotal);
+        }
+        nbFFmLastTotal += nbFFm;
+        nbFFpLastTotal += nbFFp;
+      }
     }
-
+    
     AllIPState::ipstateElementContainer *vips = aips->getIPstate(ele->getNum());
     int npts=integBound->getIntPoints(ele,&GP);
     _interQuad->getIntPoints(ie,GP,&GPm,&GPp);
@@ -3066,9 +3248,9 @@ void dG3DDomain::initialIPVariable(AllIPState *aips,const unknownField *ufield,
             referencePhi0[i](0) += Grads[k](i)*x;
             referencePhi0[i](1) += Grads[k+nbvertexInter](i)*y;
             referencePhi0[i](2) += Grads[k+nbvertexInter+nbvertexInter](i)*z;
-            currentPhi0[i](0) += Grads[k](i)*(x+unknowns_inter(k));
-            currentPhi0[i](1) += Grads[k+nbvertexInter](i)*(y+unknowns_inter(k+nbvertexInter));
-            currentPhi0[i](2) += Grads[k+nbvertexInter+nbvertexInter](i)*(z+unknowns_inter(k+2*nbvertexInter));
+            currentPhi0[i](0) += Grads[k](i)*(x+dispinter(k));
+            currentPhi0[i](1) += Grads[k+nbvertexInter](i)*(y+dispinter(k+nbvertexInter));
+            currentPhi0[i](2) += Grads[k+nbvertexInter+nbvertexInter](i)*(z+dispinter(k+2*nbvertexInter));
           }
         }
       }
@@ -3081,9 +3263,9 @@ void dG3DDomain::initialIPVariable(AllIPState *aips,const unknownField *ufield,
            referencePhi0[0](0) += Grads[k](0)*x;
            referencePhi0[0](1) += Grads[k+nbvertexInter](0)*y;
            referencePhi0[0](2) += Grads[k+nbvertexInter+nbvertexInter](0)*z;
-           currentPhi0[0](0) += Grads[k](0)*(x+unknowns_inter(k));
-           currentPhi0[0](1) += Grads[k+nbvertexInter](0)*(y+unknowns_inter(k+nbvertexInter));
-           currentPhi0[0](2) += Grads[k+nbvertexInter+nbvertexInter](0)*(z+unknowns_inter(k+2*nbvertexInter));
+           currentPhi0[0](0) += Grads[k](0)*(x+dispinter(k));
+           currentPhi0[0](1) += Grads[k+nbvertexInter](0)*(y+dispinter(k+nbvertexInter));
+           currentPhi0[0](2) += Grads[k+nbvertexInter+nbvertexInter](0)*(z+dispinter(k+2*nbvertexInter));
         }
 
         static SVector3 phi0[2];
@@ -3095,10 +3277,9 @@ void dG3DDomain::initialIPVariable(AllIPState *aips,const unknownField *ufield,
         STensorOperation::zero(phi0Cur[0]);
         STensorOperation::zero(phi0Cur[1]);
 
-        FunctionSpace<double>* spaceMinus = dynamic_cast<FunctionSpace<double>*> (this->getMinusDomain()->getFunctionSpace());
-
         std::vector<TensorialTraits<double>::GradType> gradmUVW;
-        spaceMinus->gradfuvw(em,GPm[j].pt[0],GPm[j].pt[1],GPm[j].pt[2],gradmUVW);
+        _spaceminus->gradfuvw(em,GPm[j].pt[0],GPm[j].pt[1],GPm[j].pt[2],gradmUVW);
+        int nbFFm = em->getNumVertices();
         for(int k=0;k<nbFFm;k++)
         {
           double x = em->getVertex(k)->x();
@@ -5127,6 +5308,32 @@ void interDomainBetween3D::setMaterialLaw(const std::map<int,materialLaw*> &mapl
   }
 }
 
+double computFieldValue(const std::vector<TensorialTraits<double>::ValType> &Val, int pos, int n,
+                      const fullVector<double> & disp)
+{
+  double val = 0;
+  for (int j=0; j< n; j++)
+  {
+    val += Val[pos+j]*disp(pos+j);
+  }
+  return val;
+}
+
+double computeJumpField(const std::vector<TensorialTraits<double>::ValType> &Val_m, int pos_m, int n_m,
+                      const std::vector<TensorialTraits<double>::ValType> &Val_p, int pos_p, const int n_p,
+                      const fullVector<double> & dispm,const fullVector<double> & dispp)
+{
+  double jump = 0.;
+  for (int j=0; j< n_m; j++)
+  {
+    jump -= Val_m[pos_m+j]*dispm(pos_m+j);
+  }
+  for (int j=0; j< n_p; j++)
+  {
+    jump += Val_p[pos_p+j]*dispp(pos_p+j);
+  }
+  return jump;
+}
 
 void computeJump(const std::vector<TensorialTraits<double>::ValType> &Val_m,const int n_m,
                       const std::vector<TensorialTraits<double>::ValType> &Val_p,
diff --git a/dG3D/src/dG3DDomain.h b/dG3D/src/dG3DDomain.h
index 02e6e2c57..e38f50263 100644
--- a/dG3D/src/dG3DDomain.h
+++ b/dG3D/src/dG3DDomain.h
@@ -556,6 +556,12 @@ class ElecMagTherMechInterDomainBetween3D : public interDomainBase, public ElecM
 
   };
 
+double computFieldValue(const std::vector<TensorialTraits<double>::ValType> &Val, int pos, int n,
+                      const fullVector<double> & disp);
+double computeJumpField(const std::vector<TensorialTraits<double>::ValType> &Val_m, int pos_m, int n_m,
+                      const std::vector<TensorialTraits<double>::ValType> &Val_p, int pos_p, const int n_p,
+                      const fullVector<double> & dispm,const fullVector<double> & dispp);
+                      
 void computeJump(const std::vector<TensorialTraits<double>::ValType> &Val_m,const int n_m,
                       const std::vector<TensorialTraits<double>::ValType> &Val_p,
                       const int n_p,const fullVector<double> & dispm,const fullVector<double> & dispp,SVector3 &ujump);
-- 
GitLab


From 159de43cf43d36bfda84de8ddb6b30c0c8962de4 Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Mon, 1 Jun 2020 12:26:41 +0200
Subject: [PATCH 02/19] done pressure terms and force terms

---
 .../space/ThreeDLagrangeFunctionSpace.h       |  22 +-
 NonLinearSolver/space/mixedFunctionSpace.h    |   2 +-
 NonLinearSolver/space/nlsFunctionSpace.h      |   2 +-
 dG3D/src/dG3DDomain.cpp                       | 116 ++---
 dG3D/src/dG3DTerms.cpp                        | 434 ++++++++++--------
 dG3D/src/dG3DTerms.h                          |  50 +-
 6 files changed, 314 insertions(+), 312 deletions(-)

diff --git a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
index a75d5814c..6f2398f0b 100644
--- a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
+++ b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
@@ -25,7 +25,7 @@ class VertexBasedLagrangeFunctionSpace : public nlsFunctionSpace<double>
     std::vector<int> ifield; // id field for each field
     // number of comp;
     int _ncomp;
-    std::set<int> _usePrimaryShapeFunctions;
+    std::set<int> _usePrimaryShapeFunctions; // set of all comps using primary shape functions
     
     
   protected:
@@ -71,15 +71,27 @@ class VertexBasedLagrangeFunctionSpace : public nlsFunctionSpace<double>
       }
     };
     
-    virtual int getNumShapeFunctions(MElement* ele, const std::vector<int>& cv) const
+    virtual int getShapeFunctionsIndex(MElement* ele, int c) const
     {
       int num = 0;
-      for (int i=0; i< cv.size(); i++)
+      bool found = false;
+      for (int i=0; i< comp.size(); i++)
       {
-        num += getNumShapeFunctions(ele,cv[i]);
+        if (c == comp[i])
+        {
+          found = true;
+          break;
+        }
+        num += getNumShapeFunctions(ele,comp[i]);
       }
+      
+      if (!found)
+      {
+        Msg::Error("field index %d does not exist",c);
+      };
+      
       return num;
-    }
+    };
     
     virtual int getTotalNumShapeFunctions(MElement* ele) const
     {
diff --git a/NonLinearSolver/space/mixedFunctionSpace.h b/NonLinearSolver/space/mixedFunctionSpace.h
index d99d94326..cedbd27c4 100644
--- a/NonLinearSolver/space/mixedFunctionSpace.h
+++ b/NonLinearSolver/space/mixedFunctionSpace.h
@@ -66,7 +66,7 @@ class CurlMixedFunctionSpace : public mixedFunctionSpaceBase,  public nlsFunctio
     virtual int getId(void) const { return _space->getId();}
     
     virtual int getNumShapeFunctions(MElement* ele, int c) const {Msg::Error("implement CurlMixedFunctionSpace::getNumShapeFunctions");};
-    virtual int getNumShapeFunctions(MElement* ele, const std::vector<int>& c) const  {Msg::Error("implement CurlMixedFunctionSpace::getNumShapeFunctions");};
+    virtual int getShapeFunctionsIndex(MElement* ele, int c) const { Msg::Error("implement CurlMixedFunctionSpace::getShapeFunctionsIndex");}; // location of comp c
     virtual int getTotalNumShapeFunctions(MElement* ele) const {Msg::Error("implement CurlMixedFunctionSpace::getTotalNumShapeFunctions");};
 
     
diff --git a/NonLinearSolver/space/nlsFunctionSpace.h b/NonLinearSolver/space/nlsFunctionSpace.h
index 929af947d..927ef4aa7 100644
--- a/NonLinearSolver/space/nlsFunctionSpace.h
+++ b/NonLinearSolver/space/nlsFunctionSpace.h
@@ -194,7 +194,7 @@ class  nlsFunctionSpace : public FunctionSpace<T>
       _mapGaussValues.clear();
     }
     virtual int getNumShapeFunctions(MElement* ele, int c) const = 0;
-    virtual int getNumShapeFunctions(MElement* ele, const std::vector<int>& c) const = 0;
+    virtual int getShapeFunctionsIndex(MElement* ele, int c) const = 0; // location for comp c
     virtual int getTotalNumShapeFunctions(MElement* ele) const = 0;
     //some new function
     virtual bool withHessianComputation() const = 0;
diff --git a/dG3D/src/dG3DDomain.cpp b/dG3D/src/dG3DDomain.cpp
index 6b150efee..7e73a8f9f 100644
--- a/dG3D/src/dG3DDomain.cpp
+++ b/dG3D/src/dG3DDomain.cpp
@@ -769,7 +769,7 @@ dG3DDomain::createNeumannTerm(FunctionSpace<double> *spneu,  const elementGroup*
   }
   else if(neumann_type == nonLinearNeumannBC::SCALAR_FLUX)
   {
-    term = new g3DFiniteStrainsScalarFluxLinearTerm(this,*spneu,uf,std::vector<int>(1,comp),f);
+    term = new g3DFiniteStrainsScalarFluxLinearTerm(this,*spneu,uf,comp,f);
   }
   else if (neumann_type == nonLinearNeumannBC::FORCE)
   {
@@ -814,7 +814,7 @@ BilinearTermBase* dG3DDomain::createNeumannMatrixTerm(FunctionSpace<double> *spn
     bneuterm = new g3DFiniteStrainsPressureBilinearTerm(this,*spneu,uf,f);
   }
   else if (neumann_type == nonLinearNeumannBC::SCALAR_FLUX){
-    bneuterm =  new g3DFiniteStrainsScalarFluxBiLinearTerm(this,*spneu,*spneu,uf,std::vector<int>(1,comp),f);
+    bneuterm =  new g3DFiniteStrainsScalarFluxBiLinearTerm(this,*spneu,*spneu,uf,comp,f);
   }
   else if (neumann_type == nonLinearNeumannBC::FORCE){
     bneuterm = new BiNonLinearTermVoid();
@@ -1006,7 +1006,6 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
 {
   if (!getElementErosionFilter()(e)) return;
   const nlsFunctionSpace<double>* nlspace  = static_cast<nlsFunctionSpace<double>*>(_space);
-  std::vector<int> comp;
   //Msg::Info("nb bulk gp %d",npts_bulk);
   for(int j=0;j<npts_bulk;j++)
   {
@@ -1019,10 +1018,10 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
     STensor3 &F = ipv->getRefToDeformationGradient();
     STensorOperation::unity(F);
     
-    int nbFFTotalLast = 0; 
     for (int k=0; k<3; k++)
     {    
       int nbFF = nlspace->getNumShapeFunctions(e,k);
+      int nbFFTotalLast = nlspace->getShapeFunctionsIndex(e,k);
       for (int i = 0; i < nbFF; i++)
       {
         //x y z: take compoenent x arbitrarily
@@ -1031,14 +1030,9 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
         F(k,1) += Grads[i+nbFFTotalLast][1]*disp(i+nbFFTotalLast);
         F(k,2) += Grads[i+nbFFTotalLast][2]*disp(i+nbFFTotalLast);
       }
-      nbFFTotalLast += nbFF;
     }
     if(STensorOperation::determinantSTensor3(F) < 1.e-15) Msg::Error("Negative Jacobian in ele %d",e->getNum());
   }
-  // three displacemnt components
-  comp.push_back(0);
-  comp.push_back(1);
-  comp.push_back(2);
 
   if(useBarF)
   {
@@ -1082,10 +1076,11 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
       if( ipv->getNumberNonLocalVariable()>getNumNonLocalVariable() )
         Msg::Error("Your material law uses more non local variables than your domain dG3DDomain::computeStrain bulk");
       
-      int nbFFTotalLast = nlspace->getNumShapeFunctions(e,comp);
       for (int nl = 0; nl < ipv->getNumberNonLocalVariable(); nl++)
       {
         int nbFF = nlspace->getNumShapeFunctions(e,3+nl);
+        int nbFFTotalLast = nlspace->getShapeFunctionsIndex(e,3+nl);
+        
         double& nonlocalVar = ipv->getRefToNonLocalVariable(nl);
         SVector3& gradNonlocalVar = ipv->getRefToGradNonLocalVariable()[nl];
 
@@ -1098,14 +1093,8 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
           gradNonlocalVar(1) += Grads[i+nbFFTotalLast][1]*disp(i+nbFFTotalLast);
           gradNonlocalVar(2) += Grads[i+nbFFTotalLast][2]*disp(i+nbFFTotalLast);
         }
-        nbFFTotalLast += nbFF;
       }
     }
-    // add comp to vector for next computation
-    for (int nl = 0; nl < getNumNonLocalVariable(); nl++)
-    {
-      comp.push_back(3+nl);
-    }
     
     // compute nonlocal var for law
     if (useAverageNonlocal)
@@ -1169,7 +1158,6 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
       if((getNumConstitutiveExtraDofDiffusionVariable() == 2)&&(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()))
       {
         // eletro-thermomec, if fV, fT are used
-        int nbFFTotalLast = nlspace->getNumShapeFunctions(e,comp);
         // if two fields (T, V) are considered using fT= 1/T, fV = -V/T as unknowns
         for (int extraDOFField = 0; extraDOFField < ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
         {
@@ -1181,6 +1169,7 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
           
           int indexFieldfT=3+getNumNonLocalVariable()+extraDOFField;
           int nbFF = nlspace->getNumShapeFunctions(e,indexFieldfT);
+          int nbFFTotalLast = nlspace->getShapeFunctionsIndex(e,indexFieldfT);
           for (int i = 0; i < nbFF; i++)
           {
             const double& ftemp = disp(i+nbFFTotalLast);
@@ -1189,7 +1178,6 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
             gradEnergyConjugatedField(1) += Grads[i+nbFFTotalLast][1]*ftemp;
             gradEnergyConjugatedField(2) += Grads[i+nbFFTotalLast][2]*ftemp;
           }         
-          nbFFTotalLast += nbFF;
           
           // field and grad field must be estimated from unknowns
           double& T = ipv->getRefToField(extraDOFField);
@@ -1258,7 +1246,6 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
       else
       {
         // field are unknowns
-        int nbFFTotalLast = nlspace->getNumShapeFunctions(e,comp);
         for (int extraDOFField = 0; extraDOFField < ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
         {
           double& T = ipv->getRefToField(extraDOFField);
@@ -1268,7 +1255,7 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
           
           int indexFieldfT=3+getNumNonLocalVariable()+extraDOFField;
           int nbFF = nlspace->getNumShapeFunctions(e,indexFieldfT);
-          
+          int nbFFTotalLast = nlspace->getShapeFunctionsIndex(e,indexFieldfT);
           for (int i = 0; i < nbFF; i++)
           {
             T += Vals[i+nbFFTotalLast]*disp(i+nbFFTotalLast);
@@ -1276,17 +1263,9 @@ void dG3DDomain::computeStrain(MElement *e, const int npts_bulk, IntPt *GP,
             gradT(1) += Grads[i+nbFFTotalLast][1]*disp(i+nbFFTotalLast);
             gradT(2) += Grads[i+nbFFTotalLast][2]*disp(i+nbFFTotalLast);
           }
-          // update previous field
-          nbFFTotalLast += nbFF;
         }
       }
     }
-    
-    //update comp for next fields
-    for (int extraDOFField = 0; extraDOFField < getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
-    {
-      comp.push_back(3+getNumNonLocalVariable()+extraDOFField);
-    }
   }
 }
 void dG3DDomain::computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichState ws,
@@ -1403,7 +1382,6 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
   {
     nlsFunctionSpace<double>* _spaceminus = dynamic_cast<nlsFunctionSpace<double>*>(efMinus->getFunctionSpace());
     nlsFunctionSpace<double>* _spaceplus = dynamic_cast<nlsFunctionSpace<double>*>(efPlus->getFunctionSpace());
-    std::vector<int> comp;
     
     int npts=integBound->getIntPoints(ele,&GP);
     MElement *em = ie->getElem(0);
@@ -1445,23 +1423,21 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
       _spaceminus->f(em,um,vm,wm,Valm);
       _spaceplus->f(ep,up,vp,wp,Valp);
       
-      int nbFFmLastTotal = 0;
-      int nbFFpLastTotal = 0;
       for (int i=0; i<3; i++)
       {
         int nbFFm = _spaceminus->getNumShapeFunctions(em,i);
+        int nbFFmLastTotal = _spaceminus->getShapeFunctionsIndex(em,i);
         for (int k=0; k< nbFFm; k++)
         {
           dispinter(iv+i*nbvertexInter) += 0.5*Valm[k+nbFFmLastTotal]*dispm(k+nbFFmLastTotal);
         }
         
         int nbFFp = _spaceplus->getNumShapeFunctions(ep,i);
+        int nbFFpLastTotal = _spaceplus->getShapeFunctionsIndex(ep,i);
         for (int k=0; k< nbFFp; k++)
         {
           dispinter(iv+i*nbvertexInter) += 0.5*Valp[k+nbFFpLastTotal]*dispp(k+nbFFpLastTotal);
         }
-        nbFFmLastTotal += nbFFm;
-        nbFFpLastTotal += nbFFp;
       }
     }
    
@@ -1628,33 +1604,33 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
 
       STensor3& Fm = ipvm->getRefToDeformationGradient();
       STensorOperation::unity(Fm);
-      int nbFFmTotalLast = 0; 
+      
       for (int cc=0; cc <3; cc++)
       {
         int nbFFm = _spaceminus->getNumShapeFunctions(em,cc);
+        int nbFFmTotalLast = _spaceminus->getShapeFunctionsIndex(em,cc);
         for (int i = 0; i < nbFFm; i++)
         {
           Fm(cc,0) += Gradm[i+nbFFmTotalLast][0]*dispm(i+nbFFmTotalLast);
           Fm(cc,1) += Gradm[i+nbFFmTotalLast][1]*dispm(i+nbFFmTotalLast);
           Fm(cc,2) += Gradm[i+nbFFmTotalLast][2]*dispm(i+nbFFmTotalLast);
         }
-        nbFFmTotalLast += nbFFm;
       }
       if(STensorOperation::determinantSTensor3(Fm) < 1.e-15) Msg::Error("Negative Jacobian Fm, em = %d, ele=%d",em->getNum(),ele->getNum());
 
       STensor3& Fp = ipvp->getRefToDeformationGradient();
       STensorOperation::unity(Fp);
-      int nbFFpTotalLast = 0; 
+       
       for (int cc=0; cc <3; cc++)
       {
         int nbFFp = _spaceplus->getNumShapeFunctions(ep,cc); 
+        int nbFFpTotalLast = _spaceplus->getShapeFunctionsIndex(ep,cc);
         for (int i = 0; i < nbFFp; i++)
         {
           Fp(cc,0) += Gradp[i+nbFFpTotalLast][0]*dispp(i+nbFFpTotalLast);
           Fp(cc,1) += Gradp[i+nbFFpTotalLast][1]*dispp(i+nbFFpTotalLast);
           Fp(cc,2) += Gradp[i+nbFFpTotalLast][2]*dispp(i+nbFFpTotalLast);
         }
-        nbFFpTotalLast += nbFFp;
       }
       if(STensorOperation::determinantSTensor3(Fp) < 1.e-15) Msg::Error("Negative Jacobian Fp, ep =%d ele = %d",ep->getNum(),ele->getNum());
       
@@ -1672,12 +1648,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
       ujump[2] = computeJumpField(Valm,nbFFmx+nbFFmy,nbFFmz,Valp,nbFFpx+nbFFpy,nbFFpz,dispm,dispp);
       ipvp->getRefToJump() = ujump;
     };
-    
-    // add computed component
-    comp.push_back(0);
-    comp.push_back(1);
-    comp.push_back(2);
-    
+        
     if(useBarF)
     {
       double barJm=0.;
@@ -1761,7 +1732,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
        
         // non-local for minus part
         if( ipvm->getNumberNonLocalVariable()>getNumNonLocalVariable()) Msg::Error("Your material law uses more non local variables than your domain dG3DDomain::computeStrain negative interface");
-        int nbFFmTotalLast = _spaceminus->getNumShapeFunctions(em,comp);
+        
         for (int nlm = 0; nlm < ipvm->getNumberNonLocalVariable(); nlm++)
         {
           double& nonlocalVarm = ipvm->getRefToNonLocalVariable(nlm);
@@ -1770,6 +1741,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
           SVector3& gradNonlocalVarm = ipvm->getRefToGradNonLocalVariable()[nlm];
           STensorOperation::zero(gradNonlocalVarm);
           int nbFFm = _spaceminus->getNumShapeFunctions(em,3+nlm);
+          int nbFFmTotalLast = _spaceminus->getShapeFunctionsIndex(em,3+nlm);
           for (int i = 0; i < nbFFm; i++)
           {
              //epsbar: take compoenent epsbar
@@ -1778,12 +1750,10 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
             gradNonlocalVarm(1) += Gradm[i+nbFFmTotalLast][1]*dispm(i+nbFFmTotalLast);
             gradNonlocalVarm(2) += Gradm[i+nbFFmTotalLast][2]*dispm(i+nbFFmTotalLast);
           }
-          nbFFmTotalLast += nbFFm;
         }
 
         // for plus part
         if( ipvp->getNumberNonLocalVariable()>getNumNonLocalVariable() ) Msg::Error("Your material law uses more non local variables than your domain dG3DDomain::computeStrain positive interface");
-        int nbFFpTotalLast = _spaceplus->getNumShapeFunctions(ep,comp);
         for (int nlp = 0; nlp < ipvp->getNumberNonLocalVariable(); nlp++)
         {
           double& nonlocalVarp = ipvp->getRefToNonLocalVariable(nlp);
@@ -1791,6 +1761,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
           SVector3& gradNonlocalVarp = ipvp->getRefToGradNonLocalVariable()[nlp];
           STensorOperation::zero(gradNonlocalVarp);
           int nbFFp = _spaceminus->getNumShapeFunctions(ep,3+nlp);
+          int nbFFpTotalLast = _spaceplus->getShapeFunctionsIndex(ep,3+nlp);
           for (int i = 0; i < nbFFp; i++)
           {
              //epsbar: take compoenent epsbar
@@ -1799,17 +1770,16 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
             gradNonlocalVarp(1) += Gradp[i+nbFFpTotalLast][1]*dispp(i+nbFFpTotalLast);
             gradNonlocalVarp(2) += Gradp[i+nbFFpTotalLast][2]*dispp(i+nbFFpTotalLast);
           }
-          nbFFpTotalLast += nbFFp;
         }
 
         // compute the jump
         // reset the number
-        nbFFmTotalLast = _spaceminus->getNumShapeFunctions(em,comp);
-        nbFFpTotalLast = _spaceplus->getNumShapeFunctions(ep,comp);
         for (int nl = 0; nl < ipvp->getNumberNonLocalVariable(); nl++)
         {
           int nbFFm = _spaceminus->getNumShapeFunctions(em,3+nl);
+          int nbFFmTotalLast = _spaceminus->getShapeFunctionsIndex(em,3+nl);
           int nbFFp = _spaceminus->getNumShapeFunctions(ep,3+nl);
+          int nbFFpTotalLast = _spaceplus->getShapeFunctionsIndex(ep,3+nl);
           double& epsjump= ipvm->getRefToNonLocalJump()(nl);
           epsjump = computeJumpField(Valm,nbFFmTotalLast,nbFFm,Valp,nbFFmTotalLast,nbFFp,dispm,dispp);
           ipvp->getRefToNonLocalJump()(nl) = epsjump;
@@ -1818,12 +1788,6 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
         }
       }
       
-      // update nonlocal component
-      for (int nl = 0; nl < getNumNonLocalVariable(); nl++)
-      {
-        comp.push_back(3+nl);
-      }
-
       if (useAverageNonlocal)
       {
         // make average
@@ -1947,23 +1911,22 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
         _spaceminus->f(em,um,vm,wm,Valm);
         _spaceplus->f(ep,up,vp,wp,Valp);
         
-        int nbFFmLastTotal = 0;
-        int nbFFpLastTotal = 0;
+        
         for (int i=0; i<3; i++)
         {
           int nbFFm = _spaceminus->getNumShapeFunctions(em,i);
+          int nbFFmLastTotal = _spaceminus->getShapeFunctionsIndex(em,i);
           for (int k=0; k< nbFFm; k++)
           {
             jumpinter(iv+i*nbvertexInter) -= Valm[k+nbFFmLastTotal]*dispm(k+nbFFmLastTotal);
           }
-          nbFFmLastTotal += nbFFm;
           
           int nbFFp = _spaceplus->getNumShapeFunctions(ep,i);
+          int nbFFpLastTotal = _spaceplus->getShapeFunctionsIndex(ep,i);
           for (int k=0; k< nbFFp; k++)
           {
             jumpinter(iv+i*nbvertexInter) += Valp[k+nbFFpLastTotal]*dispp(k+nbFFpLastTotal);
           }
-          nbFFpLastTotal += nbFFp;
         }
       }
     }
@@ -2085,7 +2048,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
         if( ipvm->getNumConstitutiveExtraDofDiffusionVariable()>getNumConstitutiveExtraDofDiffusionVariable() )
           Msg::Error("Your material law uses more constitutive extra dof diffusion variables than your domain dG3DDomain::computeStrain bulk");
           
-        int nbFFmTotalLast = _spaceminus->getNumShapeFunctions(em,comp);
+        
         for (int extraDOFFieldm = 0; extraDOFFieldm < ipvm->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFFieldm++)
         {
           if((ipvm->getNumConstitutiveExtraDofDiffusionVariable() == 2)&&(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()))
@@ -2096,6 +2059,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
             STensorOperation::zero(gradEnergyConjugatedFieldm);
             
             int nbFFm = _spaceminus->getNumShapeFunctions(em,3+getNumNonLocalVariable()+extraDOFFieldm);
+            int nbFFmTotalLast = _spaceminus->getShapeFunctionsIndex(em,3+getNumNonLocalVariable()+extraDOFFieldm);
             for (int i = 0; i < nbFFm; i++)
             {
               const double& ftemp = dispm(i+nbFFmTotalLast);
@@ -2104,7 +2068,6 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
               gradEnergyConjugatedFieldm(1) += Gradm[i+nbFFmTotalLast][1]*ftemp;
               gradEnergyConjugatedFieldm(2) += Gradm[i+nbFFmTotalLast][2]*ftemp;
             }
-            nbFFmTotalLast += nbFFm;
 
             double& Tm = ipvm->getRefToField(extraDOFFieldm);
             SVector3& gradTm = ipvm->getRefToGradField()[extraDOFFieldm];
@@ -2174,6 +2137,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
             STensorOperation::zero(gradTm);
             
             int nbFFm = _spaceminus->getNumShapeFunctions(em,3+getNumNonLocalVariable()+extraDOFFieldm);
+            int nbFFmTotalLast =_spaceminus->getShapeFunctionsIndex(em,3+getNumNonLocalVariable()+extraDOFFieldm);
             for (int i = 0; i < nbFFm; i++)
             {
               Tm += Valm[i+nbFFmTotalLast]*dispm(i+nbFFmTotalLast);
@@ -2181,13 +2145,11 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
               gradTm(1) += Gradm[i+nbFFmTotalLast][1]*dispm(i+nbFFmTotalLast);
               gradTm(2) += Gradm[i+nbFFmTotalLast][2]*dispm(i+nbFFmTotalLast);
             }
-            nbFFmTotalLast  += nbFFm;
           }
         }
         if( ipvp->getNumConstitutiveExtraDofDiffusionVariable()>getNumConstitutiveExtraDofDiffusionVariable() )
           Msg::Error("Your material law uses more constitutive extra dof diffusion variables than your domain dG3DDomain::computeStrain bulk");
           
-        int nbFFpTotalLast = _spaceplus->getNumShapeFunctions(ep,comp);
         for (int extraDOFFieldp = 0; extraDOFFieldp < ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFFieldp++)
         {
           if((ipvp->getNumConstitutiveExtraDofDiffusionVariable() == 2)&&(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()))
@@ -2198,6 +2160,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
             STensorOperation::zero(gradEnergyConjugatedFieldp);
             
             int nbFFp = _spaceplus->getNumShapeFunctions(ep,3+getNumNonLocalVariable()+extraDOFFieldp);
+            int nbFFpTotalLast = _spaceplus->getShapeFunctionsIndex(ep,3+getNumNonLocalVariable()+extraDOFFieldp);
             for (int i = 0; i < nbFFp; i++)
             {
               const double& ftemp = dispp(i+nbFFpTotalLast);
@@ -2206,7 +2169,6 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
               gradEnergyConjugatedFieldp(1) += Gradp[i+nbFFpTotalLast][1]*ftemp;
               gradEnergyConjugatedFieldp(2) += Gradp[i+nbFFpTotalLast][2]*ftemp;
             }
-            nbFFpTotalLast += nbFFp;
             
             double&  Tp = ipvp->getRefToField(extraDOFFieldp);
             SVector3& gradTp = ipvp->getRefToGradField()[extraDOFFieldp];
@@ -2276,6 +2238,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
             STensorOperation::zero(gradTp);
             
             int nbFFp = _spaceplus->getNumShapeFunctions(ep,3+getNumNonLocalVariable()+extraDOFFieldp);
+            int nbFFpTotalLast = _spaceplus->getShapeFunctionsIndex(ep,3+getNumNonLocalVariable()+extraDOFFieldp);
             for (int i = 0; i < nbFFp; i++)
             {
               Tp += Valp[i+nbFFpTotalLast]*dispp(i+nbFFpTotalLast);
@@ -2283,14 +2246,9 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
               gradTp(1) += Gradp[i+nbFFpTotalLast][1]*dispp(i+nbFFpTotalLast);
               gradTp(2) += Gradp[i+nbFFpTotalLast][2]*dispp(i+nbFFpTotalLast);
             }
-            nbFFpTotalLast += nbFFp;
           }
         }
         // compute the jump
-        // reset counter
-        nbFFmTotalLast = _spaceminus->getNumShapeFunctions(em,comp);
-        nbFFpTotalLast = _spaceplus->getNumShapeFunctions(ep,comp);
-        
         std::vector<double> Tminus, Tplus;
         Tminus.resize(getNumConstitutiveExtraDofDiffusionVariable());
         Tplus.resize(getNumConstitutiveExtraDofDiffusionVariable());
@@ -2298,7 +2256,11 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
         for (int extraDOFField = 0; extraDOFField < ipvm->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
         {
           int nbFFm = _spaceminus->getNumShapeFunctions(em,3+getNumNonLocalVariable()+extraDOFField);
+          int nbFFmTotalLast = _spaceminus->getShapeFunctionsIndex(em,3+getNumNonLocalVariable()+extraDOFField);
+          
           int nbFFp = _spaceplus->getNumShapeFunctions(ep,3+getNumNonLocalVariable()+extraDOFField);
+          int nbFFpTotalLast = _spaceplus->getShapeFunctionsIndex(ep,3+getNumNonLocalVariable()+extraDOFField);
+           // reset counter
 
           if(ipvm->getNumConstitutiveExtraDofDiffusionVariable()==1) //thermomec
           {
@@ -2375,17 +2337,9 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
             }
           }
           else Msg::Error("UseEnergyConjugatedField with more than 2 extra dofs not implemented");
-          
-          nbFFmTotalLast += nbFFm;
-          nbFFpTotalLast += nbFFp;
         }
         //
       }
-      
-      for (int extraDOFField = 0; extraDOFField < getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
-      {
-        comp.push_back(3+getNumNonLocalVariable()+extraDOFField);
-      }
     }
   }
   else
@@ -3188,23 +3142,23 @@ void dG3DDomain::initialIPVariable(AllIPState *aips,const unknownField *ufield,
       _spaceminus->f(em,um,vm,wm,Valm);
       _spaceplus->f(ep,up,vp,wp,Valp);
       
-      int nbFFmLastTotal = 0;
-      int nbFFpLastTotal = 0;
+      
+      
       for (int i=0; i<3; i++)
       {
         int nbFFm = _spaceminus->getNumShapeFunctions(em,i);
+        int nbFFmLastTotal = _spaceminus->getShapeFunctionsIndex(em,i);
         for (int k=0; k< nbFFm; k++)
         {
           dispinter(iv+i*nbvertexInter) += 0.5*Valm[k+nbFFmLastTotal]*unknowns_m(k+nbFFmLastTotal);
         }
         
         int nbFFp = _spaceplus->getNumShapeFunctions(ep,i);
+        int nbFFpLastTotal = _spaceplus->getShapeFunctionsIndex(ep,i);
         for (int k=0; k< nbFFp; k++)
         {
           dispinter(iv+i*nbvertexInter) += 0.5*Valp[k+nbFFpLastTotal]*unknowns_p(k+nbFFpLastTotal);
         }
-        nbFFmLastTotal += nbFFm;
-        nbFFpLastTotal += nbFFp;
       }
     }
     
diff --git a/dG3D/src/dG3DTerms.cpp b/dG3D/src/dG3DTerms.cpp
index 5cfffec1c..3a07f3e77 100644
--- a/dG3D/src/dG3DTerms.cpp
+++ b/dG3D/src/dG3DTerms.cpp
@@ -20,23 +20,19 @@ void g3DLoadTerm::get(MElement *ele,int npts,IntPt *GP,fullVector<double> &m) co
   const int nbdof=this->space1.getNumKeys(ele);
   m.resize(nbdof);
   m.setAll(0.);
-  // Get shape functions values and gradients at all Gauss points
-  nlsFunctionSpace<double>* sp1 = static_cast<nlsFunctionSpace<double>*>(&(this->space1));
-  std::vector<GaussPointSpaceValues<double>*> vgps;
-  sp1->get(ele,npts,GP,vgps);
 
   SPoint3 p;
   double scaleEq = 1.;
   if (comp < 3){
     scaleEq = 1.; // disp
   }
-  else if (comp > 2 and comp < 3+getNumNonLocalVariable()){
+  else if (3<=comp  and comp < 3+getNumNonLocalVariable()){
     scaleEq = getNonLocalEqRatio(); // nonlocal Dof
   }
-  else if (comp > 2+getNumNonLocalVariable() and comp < 3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable()){
+  else if (3+getNumNonLocalVariable()<=comp and comp < 3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable()){
     scaleEq = getConstitutiveExtraDofDiffusionEqRatio(); // extraDof
   }
-  else if (comp > 2+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable() && 
+  else if (3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable() <=comp  && 
            comp < 3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable()+getNumConstitutiveCurlVariable())
   {
     scaleEq = getConstitutiveCurlEqRatio(); // curlData
@@ -44,15 +40,23 @@ void g3DLoadTerm::get(MElement *ele,int npts,IntPt *GP,fullVector<double> &m) co
   else{
     Msg::Error("comp = %d has not been wrongly introduced in g3DLoadTerm::get",comp);
   }
+    // Get shape functions values and gradients at all Gauss points
+  nlsFunctionSpace<double>* sp1 = static_cast<nlsFunctionSpace<double>*>(&(this->space1));
   for (int i = 0; i < npts; i++)
   {
     const double weight = GP[i].weight;
-    std::vector<double> &Vals = vgps[i]->_vvals;
-    double detJ = ele->getJacobianDeterminant(GP[i].pt[0],GP[i].pt[1],GP[i].pt[2]);
+    const double u = GP[i].pt[0];
+    const double v = GP[i].pt[1];
+    const double w = GP[i].pt[2];
+    std::vector<double> Vals;
+    // space->f must be used as dof depends on context of space
+    sp1->f(ele,u,v,w,Vals);
+    double detJ = ele->getJacobianDeterminant(u,v,w);
     ele->pnt(Vals,p);
     double load=Load->operator()(p.x(),p.y(),p.z());
     double loadvalue = load*weight*detJ;
-    for (int j = 0; j < nbdof ; ++j){
+    for (int j = 0; j < nbdof ; ++j)
+    {
       m(j)+=Vals[j]*loadvalue*scaleEq;
     }
   }
@@ -62,12 +66,11 @@ void g3DFiniteStrainsPressureTerm::get(MElement *ele,int npts,IntPt *GP,fullVect
 {
   // resize the force vector
   const int nbdof=this->space1.getNumKeys(ele);
-  const int nbFF = ele->getNumShapeFunctions();
   m.resize(nbdof);
   m.setAll(0.);
 
   // get the displacements of the element
-  std::vector<Dof> keys;
+  std::vector<Dof> keys; // must be all dofs or al least ux, uy, uz dofs
   this->space1.getKeys(ele,keys);
   fullVector<double> disp(keys.size());
   _ufield->get(keys,disp);
@@ -76,34 +79,35 @@ void g3DFiniteStrainsPressureTerm::get(MElement *ele,int npts,IntPt *GP,fullVect
   nlsFunctionSpace<double>* sp1 = static_cast<nlsFunctionSpace<double>*>(&(this->space1));
   std::vector<GaussPointSpaceValues<double>*> vgps;
   sp1->get(ele,npts,GP,vgps);
-  
+  //
   SPoint3 p;
-
   for (int i = 0; i < npts; i++)
   {
     const double weight = GP[i].weight;
-    double u = GP[i].pt[0];
-    double v = GP[i].pt[1];
-    double w = GP[i].pt[2];
-    std::vector<TensorialTraits<double>::ValType> &Vals = vgps[i]->_vvals;
+    const double u = GP[i].pt[0];
+    const double v = GP[i].pt[1];
+    const double w = GP[i].pt[2];
+    // vals and grads must be evaluated by space, not element basis
+    std::vector<TensorialTraits<double>::ValType> Vals;
     std::vector<TensorialTraits<double>::GradType> Grads;
+    sp1->f(ele,u,v,w,Vals);
     sp1->gradf(ele,u,v,w,Grads);
 
     static STensor3 defo_grad;
     STensorOperation::unity(defo_grad);
-    for (int j = 0; j < nbFF; j++)
+    
+    for (int cc=0; cc<3; cc++)
     {
-      //x y z: take compoenent x arbitrarily
-      // xx yy zz xy xz yz
-      defo_grad(0,0) += Grads[j+0*nbFF][0]*disp(j);
-      defo_grad(0,1) += Grads[j+0*nbFF][1]*disp(j);
-      defo_grad(0,2) += Grads[j+0*nbFF][2]*disp(j);
-      defo_grad(1,0) += Grads[j+nbFF][0]*disp(j+nbFF);
-      defo_grad(1,1) += Grads[j+nbFF][1]*disp(j+nbFF);
-      defo_grad(1,2) += Grads[j+nbFF][2]*disp(j+nbFF);
-      defo_grad(2,0) += Grads[j+2*nbFF][0]*disp(j+2*nbFF);
-      defo_grad(2,1) += Grads[j+2*nbFF][1]*disp(j+2*nbFF);
-      defo_grad(2,2) += Grads[j+2*nbFF][2]*disp(j+2*nbFF);
+      int nbFF = sp1->getNumShapeFunctions(ele,cc);
+      int nbFFTotalLast = sp1->getShapeFunctionsIndex(ele,cc);
+      for (int j = 0; j < nbFF; j++)
+      {
+        //x y z: take compoenent x arbitrarily
+        // xx yy zz xy xz yz
+        defo_grad(cc,0) += Grads[j+nbFFTotalLast][0]*disp(j+nbFFTotalLast);
+        defo_grad(cc,1) += Grads[j+nbFFTotalLast][1]*disp(j+nbFFTotalLast);
+        defo_grad(cc,2) += Grads[j+nbFFTotalLast][2]*disp(j+nbFFTotalLast);
+      }
     }
     if(STensorOperation::determinantSTensor3(defo_grad) < 1.e-15) Msg::Error("Negative Jacobian g3DFiniteStrainsPressureTerm::get");
     
@@ -112,10 +116,11 @@ void g3DFiniteStrainsPressureTerm::get(MElement *ele,int npts,IntPt *GP,fullVect
     double jdefo = STensorOperation::determinantSTensor3(defo_grad);
     static STensor3 invF;
     STensorOperation::inverseSTensor3(defo_grad,invF);
-    
-    std::vector<TensorialTraits<double>::GradType> &graduv = vgps[i]->_vgrads;
+    //
+    std::vector<TensorialTraits<double>::GradType> &graduv = vgps[i]->_vgrads; // must be taken from element basis
     SVector3 ref_normal(0.,0.,0.);
-    if (dom->getDim() == 3){
+    if (dom->getDim() == 3)
+    {
       // initial normal de l'élément (compute and store it once at the beginning)
       SVector3 phi1(0.), phi2(0.);
       for(int j=0;j<ele->getNumVertices();++j)
@@ -126,7 +131,8 @@ void g3DFiniteStrainsPressureTerm::get(MElement *ele,int npts,IntPt *GP,fullVect
       }
       ref_normal = crossprod(phi1,phi2);        
     }
-    else if (dom->getDim() == 2){
+    else if (dom->getDim() == 2)
+    {
       // initial normal de l'élément (compute and store it once at the beginning)
       SVector3 phi1(0.);
       for(int j=0;j<ele->getNumVertices();++j)
@@ -149,9 +155,15 @@ void g3DFiniteStrainsPressureTerm::get(MElement *ele,int npts,IntPt *GP,fullVect
     double load=Load->operator()(p.x(),p.y(),p.z());
 
     double loadvalue = -load*weight*detJ; /// minus as cur_normal == outward normal
-    for (int j = 0; j < nbFF ; j++){
-      for (int k=0; k< 3; k++){
-        m(j+k*nbFF)+=Vals[j+k*nbFF]*loadvalue*jdefo*cur_normal[k];
+    //
+    
+    for (int k=0; k< 3; k++)
+    {
+      int nbFF = sp1->getNumShapeFunctions(ele,k);
+      int nbFFTotalLast = sp1->getShapeFunctionsIndex(ele,k);
+      for (int j = 0; j < nbFF ; j++)
+      {
+        m(j+nbFFTotalLast)+=Vals[j+nbFFTotalLast]*loadvalue*jdefo*cur_normal[k];
       }
     }
   }
@@ -162,7 +174,6 @@ void g3DFiniteStrainsPressureBilinearTerm::get(MElement *ele,int npts,IntPt *GP,
 {
   // resize the force vector
   const int nbdof=this->space1.getNumKeys(ele);
-  const int nbFF = ele->getNumShapeFunctions();
   m.resize(nbdof,nbdof);
   m.setAll(0.);
 
@@ -182,30 +193,32 @@ void g3DFiniteStrainsPressureBilinearTerm::get(MElement *ele,int npts,IntPt *GP,
   for (int i = 0; i < npts; i++)
   {
     const double weight = GP[i].weight;
-    double u = GP[i].pt[0];
-    double v = GP[i].pt[1];
-    double w = GP[i].pt[2];
-    std::vector<TensorialTraits<double>::ValType> &Vals = vgps[i]->_vvals;
+    const double u = GP[i].pt[0];
+    const double v = GP[i].pt[1];
+    const double w = GP[i].pt[2];
+    // vals and grads must be evaluated by space, not element basis
+    std::vector<TensorialTraits<double>::ValType> Vals;
     std::vector<TensorialTraits<double>::GradType> Grads;
+    sp1->f(ele,u,v,w,Vals);
     sp1->gradf(ele,u,v,w,Grads);
-
+    
     static STensor3 defo_grad;
     STensorOperation::unity(defo_grad);
-    for (int j = 0; j < nbFF; j++)
+    
+    for (int cc=0; cc<3; cc++)
     {
-      //x y z: take compoenent x arbitrarily
-      // xx yy zz xy xz yz
-      defo_grad(0,0) += Grads[j+0*nbFF][0]*disp(j);
-      defo_grad(0,1) += Grads[j+0*nbFF][1]*disp(j);
-      defo_grad(0,2) += Grads[j+0*nbFF][2]*disp(j);
-      defo_grad(1,0) += Grads[j+nbFF][0]*disp(j+nbFF);
-      defo_grad(1,1) += Grads[j+nbFF][1]*disp(j+nbFF);
-      defo_grad(1,2) += Grads[j+nbFF][2]*disp(j+nbFF);
-      defo_grad(2,0) += Grads[j+2*nbFF][0]*disp(j+2*nbFF);
-      defo_grad(2,1) += Grads[j+2*nbFF][1]*disp(j+2*nbFF);
-      defo_grad(2,2) += Grads[j+2*nbFF][2]*disp(j+2*nbFF);
+      int nbFF = sp1->getNumShapeFunctions(ele,cc);
+      int nbFFTotalLast = sp1->getShapeFunctionsIndex(ele,cc);
+      for (int j = 0; j < nbFF; j++)
+      {
+        //x y z: take compoenent x arbitrarily
+        // xx yy zz xy xz yz
+        defo_grad(cc,0) += Grads[j+nbFFTotalLast][0]*disp(j+nbFFTotalLast);
+        defo_grad(cc,1) += Grads[j+nbFFTotalLast][1]*disp(j+nbFFTotalLast);
+        defo_grad(cc,2) += Grads[j+nbFFTotalLast][2]*disp(j+nbFFTotalLast);
+      }
     }
-    if(STensorOperation::determinantSTensor3(defo_grad) < 1.e-15) Msg::Error("Negative Jacobian g3DFiniteStrainsPressureBilinearTerm::");
+    if(STensorOperation::determinantSTensor3(defo_grad) < 1.e-15) Msg::Error("Negative Jacobian g3DFiniteStrainsPressureBilinearTerm::get");
     
 
     // defo gradient and jac
@@ -215,7 +228,8 @@ void g3DFiniteStrainsPressureBilinearTerm::get(MElement *ele,int npts,IntPt *GP,
 
     SVector3 ref_normal(0.,0.,0.);
     std::vector<TensorialTraits<double>::GradType> &graduv = vgps[i]->_vgrads;
-    if (dom->getDim() == 3){
+    if (dom->getDim() == 3)
+    {
       // initial normal de l'élément (compute and store it once at the beginning)
       SVector3 phi1(0.), phi2(0.);
       for(int j=0;j<ele->getNumVertices();++j)
@@ -226,7 +240,8 @@ void g3DFiniteStrainsPressureBilinearTerm::get(MElement *ele,int npts,IntPt *GP,
       }
       ref_normal = crossprod(phi1,phi2);        
     }
-    else if (dom->getDim() == 2){
+    else if (dom->getDim() == 2)
+    {
       // initial normal de l'élément (compute and store it once at the beginning)
       SVector3 phi1(0.);
       for(int j=0;j<ele->getNumVertices();++j)
@@ -259,12 +274,22 @@ void g3DFiniteStrainsPressureBilinearTerm::get(MElement *ele,int npts,IntPt *GP,
     double load=Load->operator()(p.x(),p.y(),p.z());
 
     double loadvalue = -load*weight*detJ; /// minus as cur_normal == outward normal
-    for (int j = 0; j < nbFF; j++){
-      for (int k=0; k<3; k++){
-        for (int p=0; p< nbFF; p++){
-          for (int q=0; q<3; q++){
-            for (int r=0; r<3; r++){
-              m(j+k*nbFF,p+q*nbFF) -=Vals[j+k*nbFF]*loadvalue*DJcur_normalDF(k,q,r)*Grads[p+q*nbFF](r); // negative as it is the derivative of Fext
+    
+    for (int k=0; k<3; k++)
+    {
+      int nbFFRow = sp1->getNumShapeFunctions(ele,k);
+      int nbFFTotalLastRow  = sp1->getShapeFunctionsIndex(ele,k);
+      for (int j = 0; j < nbFFRow; j++)
+      {
+        for (int q=0; q<3; q++)
+        {
+          int nbFFCol = sp1->getNumShapeFunctions(ele,q);
+          int nbFFTotalLastCol = sp1->getShapeFunctionsIndex(ele,q);
+          for (int p=0; p< nbFFCol; p++)
+          {
+            for (int r=0; r<3; r++)
+            {
+              m(j+nbFFTotalLastRow,p+nbFFTotalLastCol) -=Vals[j+nbFFTotalLastRow]*loadvalue*DJcur_normalDF(k,q,r)*Grads[p+nbFFTotalLastCol](r); // negative as it is the derivative of Fext
             }
           }
         }
@@ -277,7 +302,6 @@ void g3DFiniteStrainsScalarFluxLinearTerm::get(MElement *ele,int npts,IntPt *GP,
 {
   // resize the force vector
   const int nbdof=this->space1.getNumKeys(ele);
-  const int nbFF = ele->getNumShapeFunctions();
   m.resize(nbdof);
   m.setAll(0.);
 
@@ -297,28 +321,31 @@ void g3DFiniteStrainsScalarFluxLinearTerm::get(MElement *ele,int npts,IntPt *GP,
   for (int i = 0; i < npts; i++)
   {
     const double weight = GP[i].weight;
-    double u = GP[i].pt[0];
-    double v = GP[i].pt[1];
-    double w = GP[i].pt[2];
-    std::vector<TensorialTraits<double>::ValType> &Vals = vgps[i]->_vvals;
+    const double u = GP[i].pt[0];
+    const double v = GP[i].pt[1];
+    const double w = GP[i].pt[2];
+    // vals and grads must be evaluated by space, not element basis
+    std::vector<TensorialTraits<double>::ValType> Vals;
     std::vector<TensorialTraits<double>::GradType> Grads;
+    sp1->f(ele,u,v,w,Vals);
     sp1->gradf(ele,u,v,w,Grads);
 
+    // deformation gradient
     static STensor3 defo_grad;
     STensorOperation::unity(defo_grad);
-    for (int j = 0; j < nbFF; j++)
+    
+    for (int cc=0; cc<3; cc++)
     {
-      //x y z: take compoenent x arbitrarily
-      // xx yy zz xy xz yz
-      defo_grad(0,0) += Grads[j+0*nbFF][0]*disp(j);
-      defo_grad(0,1) += Grads[j+0*nbFF][1]*disp(j);
-      defo_grad(0,2) += Grads[j+0*nbFF][2]*disp(j);
-      defo_grad(1,0) += Grads[j+nbFF][0]*disp(j+nbFF);
-      defo_grad(1,1) += Grads[j+nbFF][1]*disp(j+nbFF);
-      defo_grad(1,2) += Grads[j+nbFF][2]*disp(j+nbFF);
-      defo_grad(2,0) += Grads[j+2*nbFF][0]*disp(j+2*nbFF);
-      defo_grad(2,1) += Grads[j+2*nbFF][1]*disp(j+2*nbFF);
-      defo_grad(2,2) += Grads[j+2*nbFF][2]*disp(j+2*nbFF);
+      int nbFF = sp1->getNumShapeFunctions(ele,cc);
+      int nbFFTotalLast = sp1->getShapeFunctionsIndex(ele,cc);
+      for (int j = 0; j < nbFF; j++)
+      {
+        //x y z: take compoenent x arbitrarily
+        // xx yy zz xy xz yz
+        defo_grad(cc,0) += Grads[j+nbFFTotalLast][0]*disp(j+nbFFTotalLast);
+        defo_grad(cc,1) += Grads[j+nbFFTotalLast][1]*disp(j+nbFFTotalLast);
+        defo_grad(cc,2) += Grads[j+nbFFTotalLast][2]*disp(j+nbFFTotalLast);
+      }
     }
     if(STensorOperation::determinantSTensor3(defo_grad) < 1.e-15) Msg::Error("Negative Jacobian g3DFiniteStrainsScalarFluxLinearTerm::get");
     
@@ -329,7 +356,8 @@ void g3DFiniteStrainsScalarFluxLinearTerm::get(MElement *ele,int npts,IntPt *GP,
     
     SVector3 ref_normal(0.,0.,0.);
     std::vector<TensorialTraits<double>::GradType> &graduv = vgps[i]->_vgrads;
-    if (_dom->getDim() == 3){
+    if (_dom->getDim() == 3)
+    {
       // initial normal de l'élément (compute and store it once at the beginning)
       SVector3 phi1(0.), phi2(0.);
       for(int j=0;j<ele->getNumVertices();++j)
@@ -340,7 +368,8 @@ void g3DFiniteStrainsScalarFluxLinearTerm::get(MElement *ele,int npts,IntPt *GP,
       }
       ref_normal = crossprod(phi1,phi2);        
     }
-    else if (_dom->getDim() == 2){
+    else if (_dom->getDim() == 2)
+    {
       // initial normal de l'élément (compute and store it once at the beginning)
       SVector3 phi1(0.);
       for(int j=0;j<ele->getNumVertices();++j)
@@ -362,46 +391,51 @@ void g3DFiniteStrainsScalarFluxLinearTerm::get(MElement *ele,int npts,IntPt *GP,
     // value of the force at the given Gauss points
     ele->pnt(Vals,p);
     // loop on the different components
-    for(size_t k=0;k<vload.size();++k)
+    double load=_load->operator()(p.x(),p.y(),p.z());
+    double loadvalue = - load*weight*detJ;
+    double depenValue = 1.;
+    // get field value
+    if (_load->withUnknownDependency())
     {
-      double load=vload[k]->operator()(p.x(),p.y(),p.z());
-      double loadvalue = - load*weight*detJ;
-      double depenValue = 1.;
-      // get field value
-      if (vload[k]->withUnknownDependency()){
-        const std::vector<int>& depenComps = vload[k]->getDependenceComponents();
-        const scalarFunction* depenFunc = vload[k]->getDependenceFunction();
-        std::vector<double> fieldValue(depenComps.size());
-        for (int ic = 0; ic < depenComps.size(); ic++){
-          fieldValue[ic] = 0.;
-          for (int jc = 0; jc < nbFF; jc++){
-            fieldValue[ic] += Vals[jc+depenComps[ic]*nbFF]*disp(jc+depenComps[ic]*nbFF); 
-          }
-        }
-        depenValue = depenFunc->getVal(fieldValue); 
-        //Msg::Info("depenValue = %e fieldValue = %e",depenValue,fieldValue[0]);
-      }
-      double scaleEq = 1.;
-      if (_vcomp[k] < 3){
-        scaleEq = 1.; // disp
-      }
-      else if (_vcomp[k] > 2 and _vcomp[k] < 3+getNumNonLocalVariable()){
-        scaleEq = getNonLocalEqRatio(); // nonlocal Dof
-      }
-      else if (_vcomp[k] > 2+getNumNonLocalVariable() and _vcomp[k] < 3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable()){
-        scaleEq = getConstitutiveExtraDofDiffusionEqRatio(); // extraDof
-      }
-      else if (_vcomp[k] > 2+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable() &&
-               _vcomp[k] < 3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable()+getNumConstitutiveCurlVariable())
+      const std::vector<int>& depenComps = _load->getDependenceComponents();
+      const scalarFunction* depenFunc = _load->getDependenceFunction();
+      std::vector<double> fieldValue(depenComps.size());
+      for (int ic = 0; ic < depenComps.size(); ic++)
       {
-        scaleEq = getConstitutiveCurlEqRatio(); // curlData
-      }
-      else{
-        Msg::Error("comp = %d has not been wrongly introduced in g3DFiniteStrainsScalarFluxLinearTerm::get",_vcomp[k]);
-      }
-      for (int j = 0; j < nbFF ; ++j){
-        m(j+_vcomp[k]*nbFF)+=Vals[j]*loadvalue*depenValue*normJcur_normal*scaleEq;
+        fieldValue[ic] = 0.;
+        int nbFF = sp1->getNumShapeFunctions(ele,depenComps[ic]);
+        int nbFFTotalLast = sp1->getShapeFunctionsIndex(ele,depenComps[ic]);
+        for (int jc = 0; jc < nbFF; jc++)
+        {
+          fieldValue[ic] += Vals[jc+nbFFTotalLast]*disp(jc+nbFFTotalLast); 
+        }
       }
+      depenValue = depenFunc->getVal(fieldValue); 
+      //Msg::Info("depenValue = %e fieldValue = %e",depenValue,fieldValue[0]);
+    }
+    double scaleEq = 1.;
+    if (_comp < 3){
+      scaleEq = 1.; // disp
+    }
+    else if (3<=_comp and _comp < 3+getNumNonLocalVariable()){
+      scaleEq = getNonLocalEqRatio(); // nonlocal Dof
+    }
+    else if (3+getNumNonLocalVariable()<=_comp and _comp < 3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable()){
+      scaleEq = getConstitutiveExtraDofDiffusionEqRatio(); // extraDof
+    }
+    else if (3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable() <=_comp &&
+             _comp < 3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable()+getNumConstitutiveCurlVariable())
+    {
+      scaleEq = getConstitutiveCurlEqRatio(); // curlData
+    }
+    else{
+      Msg::Error("comp = %d has not been wrongly introduced in g3DFiniteStrainsScalarFluxLinearTerm::get",_comp);
+    }
+    int nbFF = sp1->getNumShapeFunctions(ele,_comp);
+    int nbFFTotalLast = sp1->getShapeFunctionsIndex(ele,_comp);
+    for (int j = 0; j < nbFF ; ++j)
+    {
+      m(j+nbFFTotalLast)+=Vals[j+nbFFTotalLast]*loadvalue*depenValue*normJcur_normal*scaleEq;
     }
   }
 };
@@ -410,7 +444,6 @@ void g3DFiniteStrainsScalarFluxBiLinearTerm::get(MElement *ele, int npts, IntPt
 {
   // resize the force vector
   const int nbdof=this->space2.getNumKeys(ele);
-  const int nbFF = ele->getNumShapeFunctions();
   m.resize(nbdof,nbdof);
   m.setAll(0.);
 
@@ -431,30 +464,33 @@ void g3DFiniteStrainsScalarFluxBiLinearTerm::get(MElement *ele, int npts, IntPt
   for (int i = 0; i < npts; i++)
   {
     const double weight = GP[i].weight;
-    double u = GP[i].pt[0];
-    double v = GP[i].pt[1];
-    double w = GP[i].pt[2];
-    std::vector<TensorialTraits<double>::ValType> &Vals = vgps[i]->_vvals;
+    const double u = GP[i].pt[0];
+    const double v = GP[i].pt[1];
+    const double w = GP[i].pt[2];
+    // vals and grads must be evaluated by space, not element basis
+    std::vector<TensorialTraits<double>::ValType> Vals;
     std::vector<TensorialTraits<double>::GradType> Grads;
+    sp1->f(ele,u,v,w,Vals);
     sp1->gradf(ele,u,v,w,Grads);
 
+    // deformation gradient
     static STensor3 defo_grad;
     STensorOperation::unity(defo_grad);
-    for (int j = 0; j < nbFF; j++)
+    
+    for (int cc=0; cc<3; cc++)
     {
-      //x y z: take compoenent x arbitrarily
-      // xx yy zz xy xz yz
-      defo_grad(0,0) += Grads[j+0*nbFF][0]*disp(j);
-      defo_grad(0,1) += Grads[j+0*nbFF][1]*disp(j);
-      defo_grad(0,2) += Grads[j+0*nbFF][2]*disp(j);
-      defo_grad(1,0) += Grads[j+nbFF][0]*disp(j+nbFF);
-      defo_grad(1,1) += Grads[j+nbFF][1]*disp(j+nbFF);
-      defo_grad(1,2) += Grads[j+nbFF][2]*disp(j+nbFF);
-      defo_grad(2,0) += Grads[j+2*nbFF][0]*disp(j+2*nbFF);
-      defo_grad(2,1) += Grads[j+2*nbFF][1]*disp(j+2*nbFF);
-      defo_grad(2,2) += Grads[j+2*nbFF][2]*disp(j+2*nbFF);
+      int nbFF = sp1->getNumShapeFunctions(ele,cc);
+      int nbFFTotalLast = sp1->getShapeFunctionsIndex(ele,cc);
+      for (int j = 0; j < nbFF; j++)
+      {
+        //x y z: take compoenent x arbitrarily
+        // xx yy zz xy xz yz
+        defo_grad(cc,0) += Grads[j+nbFFTotalLast][0]*disp(j+nbFFTotalLast);
+        defo_grad(cc,1) += Grads[j+nbFFTotalLast][1]*disp(j+nbFFTotalLast);
+        defo_grad(cc,2) += Grads[j+nbFFTotalLast][2]*disp(j+nbFFTotalLast);
+      }
     }
-    if(STensorOperation::determinantSTensor3(defo_grad) < 1.e-15) Msg::Error("Negative Jacobian");
+    if(STensorOperation::determinantSTensor3(defo_grad) < 1.e-15) Msg::Error("Negative Jacobian g3DFiniteStrainsScalarFluxBiLinearTerm::get");
     
     // defo gradient and jac
     double jdefo = STensorOperation::determinantSTensor3(defo_grad);
@@ -463,7 +499,8 @@ void g3DFiniteStrainsScalarFluxBiLinearTerm::get(MElement *ele, int npts, IntPt
     
     SVector3 ref_normal(0.,0.,0.);
     std::vector<TensorialTraits<double>::GradType> &graduv = vgps[i]->_vgrads;
-    if (_dom->getDim() == 3){
+    if (_dom->getDim() == 3)
+    {
       // initial normal de l'élément (compute and store it once at the beginning)
       SVector3 phi1(0.), phi2(0.);
       for(int j=0;j<ele->getNumVertices();++j)
@@ -474,7 +511,8 @@ void g3DFiniteStrainsScalarFluxBiLinearTerm::get(MElement *ele, int npts, IntPt
       }
       ref_normal = crossprod(phi1,phi2);        
     }
-    else if (_dom->getDim() == 2){
+    else if (_dom->getDim() == 2)
+    {
       // initial normal de l'élément (compute and store it once at the beginning)
       SVector3 phi1(0.);
       for(int j=0;j<ele->getNumVertices();++j)
@@ -518,66 +556,80 @@ void g3DFiniteStrainsScalarFluxBiLinearTerm::get(MElement *ele, int npts, IntPt
 
     // value of the force at the given Gauss points. Change this by a evaluation only at the barycenter?
     ele->pnt(Vals,p);
-    for(size_t k=0;k<vload.size();++k)
+    double loadvalue= - _load->operator()(p.x(),p.y(),p.z())*weight*detJ;
+    double depenValue = 1.;
+    std::vector<double> DdepenValue;
+    std::vector<int> depenComps;
+    const scalarFunction* depenFunc = NULL;
+    // get field value
+    if (_load->withUnknownDependency())
     {
-      double loadvalue= - vload[k]->operator()(p.x(),p.y(),p.z())*weight*detJ;
-      double depenValue = 1.;
-      std::vector<double> DdepenValue;
-      std::vector<int> depenComps;
-      const scalarFunction* depenFunc = NULL;
-      // get field value
-      if (vload[k]->withUnknownDependency()){
-        depenComps = vload[k]->getDependenceComponents();
-        depenFunc =  vload[k]->getDependenceFunction();
-        std::vector<double> fieldValue(depenComps.size());
-        for (int ic = 0; ic < depenComps.size(); ic++){
-          fieldValue[ic] = 0.;
-          for (int jc = 0; jc < nbFF; jc++){
-            fieldValue[ic] += Vals[jc+depenComps[ic]*nbFF]*disp(jc+depenComps[ic]*nbFF); 
-          }
+      depenComps = _load->getDependenceComponents();
+      depenFunc =  _load->getDependenceFunction();
+      std::vector<double> fieldValue(depenComps.size());
+      for (int ic = 0; ic < depenComps.size(); ic++){
+        fieldValue[ic] = 0.;
+        int nbFF = sp1->getNumShapeFunctions(ele,depenComps[ic]);
+        int nbFFTotalLast = sp1->getShapeFunctionsIndex(ele,depenComps[ic]);
+        for (int jc = 0; jc < nbFF; jc++)
+        {
+          fieldValue[ic] += Vals[jc+nbFFTotalLast]*disp(jc+nbFFTotalLast); 
         }
-        depenValue *= depenFunc->getVal(fieldValue); 
-        depenFunc->getDiff(fieldValue,DdepenValue);
-      }
-      
-      double scaleEq = 1.;
-      if (_vcomp[k] < 3){
-        scaleEq = 1.; // disp
       }
-      else if (_vcomp[k] > 2 and _vcomp[k] < 3+getNumNonLocalVariable()){
-        scaleEq = getNonLocalEqRatio(); // nonlocal Dof
-      }
-      else if (_vcomp[k] > 2+getNumNonLocalVariable() and _vcomp[k] < 3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable()){
-        scaleEq = getConstitutiveExtraDofDiffusionEqRatio(); // extraDof
-      }
-      else if (_vcomp[k] > 2+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable() &&
-               _vcomp[k] < 3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable()+getNumConstitutiveCurlVariable())
+      depenValue *= depenFunc->getVal(fieldValue); 
+      depenFunc->getDiff(fieldValue,DdepenValue);
+    }
+    
+    double scaleEq = 1.;
+    if (_comp < 3){
+      scaleEq = 1.; // disp
+    }
+    else if (3<=_comp and _comp < 3+getNumNonLocalVariable()){
+      scaleEq = getNonLocalEqRatio(); // nonlocal Dof
+    }
+    else if (3+getNumNonLocalVariable()<=_comp and _comp < 3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable()){
+      scaleEq = getConstitutiveExtraDofDiffusionEqRatio(); // extraDof
+    }
+    else if (3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable() <=_comp &&
+             _comp < 3+getNumNonLocalVariable()+getNumConstitutiveExtraDofDiffusionVariable()+getNumConstitutiveCurlVariable())
+    {
+      scaleEq = getConstitutiveCurlEqRatio(); // curlData
+    }
+    else{
+      Msg::Error("comp = %d has not been wrongly introduced in g3DFiniteStrainsScalarFluxLinearTerm::get",_comp);
+    }
+    
+    // loop on the different components
+    int nbFFRow = sp1->getNumShapeFunctions(ele,_comp);
+    int nbFFTotalLastRow = sp1->getShapeFunctionsIndex(ele,_comp);
+    
+    for (int j = 0; j < nbFFRow ; ++j)
+    {
+      for (int q=0; q<3; q++)
       {
-        scaleEq = getConstitutiveCurlEqRatio(); // curlData
-      }
-      else{
-        Msg::Error("comp = %d has not been wrongly introduced in g3DFiniteStrainsScalarFluxLinearTerm::get",_vcomp[k]);
-      }
-      
-      // loop on the different components
-      for (int j = 0; j < nbFF ; ++j){
-        for (int p=0; p< nbFF; p++){
-          for (int q=0; q<3; q++){
-            for (int r=0; r<3; r++){
-              m(j+_vcomp[k]*nbFF,p+q*nbFF) -=Vals[j]*loadvalue*depenValue*DnormJcur_normalDF(q,r)*Grads[p](r)*scaleEq; // negative as it is the derivative of Fext
-            }
+        int nbFFColF = sp1->getNumShapeFunctions(ele,q);
+        int nbFFTotalLastColF = sp1->getShapeFunctionsIndex(ele,q);
+        for (int p=0; p< nbFFColF; p++)
+        {
+          for (int r=0; r<3; r++)
+          {
+            m(j+nbFFTotalLastRow,p+nbFFTotalLastColF) -=Vals[j+nbFFTotalLastRow]*loadvalue*depenValue*DnormJcur_normalDF(q,r)*Grads[p+nbFFTotalLastColF](r)*scaleEq; // negative as it is the derivative of Fext
           }
-          
-          if (vload[k]->withUnknownDependency()){
-            for (int ic = 0; ic < depenComps.size(); ic++){
-              m(j+_vcomp[k]*nbFF,p+depenComps[ic]*nbFF) -= Vals[j]* loadvalue*normJcur_normal*DdepenValue[ic]*Vals[p]*scaleEq; // negative as it is the derivative of Fext
-            }
+        }
+      }
+      if (_load->withUnknownDependency())
+      {
+        for (int ic = 0; ic < depenComps.size(); ic++)
+        {
+          int nbFFColOther = sp1->getNumShapeFunctions(ele,depenComps[ic]);
+          int nbFFTotalLastColOther = sp1->getShapeFunctionsIndex(ele,depenComps[ic]);
+          for (int p=0; p< nbFFColOther; p++)
+          {
+            m(j+nbFFTotalLastRow,p+nbFFTotalLastColOther) -= Vals[j+j+nbFFTotalLastRow]* loadvalue*normJcur_normal*DdepenValue[ic]*Vals[p+nbFFTotalLastColOther]*scaleEq; // negative as it is the derivative of Fext
           }
         }
-        
       }
     }
-    
   }
 }
 
diff --git a/dG3D/src/dG3DTerms.h b/dG3D/src/dG3DTerms.h
index 447f3b1a1..0c63e77ef 100644
--- a/dG3D/src/dG3DTerms.h
+++ b/dG3D/src/dG3DTerms.h
@@ -371,36 +371,28 @@ class g3DFiniteStrainsScalarFluxLinearTerm : public g3DLinearTerm<double>
     // needed to compute the deformation gradient
     const unknownField* _ufield;
     // component on which the scalar flux is applied
-    std::vector<int> _vcomp;
+    int _comp;
     // load function for each scalar flux
-    std::vector< const simpleFunctionTime<double>*> vload; // one load function per component
+    const simpleFunctionTime<double>* _load; // one load function per component
     SVector3 normalToDomain;
     
   public:
     // one function has to be given per components
     g3DFiniteStrainsScalarFluxLinearTerm(const partDomain* d, FunctionSpace<double>& space1_,
                                     const unknownField* ufield,
-                                    const std::vector<int> &vcomp,...) : g3DLinearTerm<double>(space1_), _dom(d), _ufield(ufield),
-                                                                      _vcomp(vcomp)
-    {
-      va_list ap;
-      va_start(ap, vcomp);
-      vload.resize(vcomp.size(),NULL);
-      for(size_t i=0; i<vload.size();++i)
-      {
-        vload[i] = va_arg(ap,const simpleFunctionTime<double>*);
-      }
-      
+                                    int comp, const simpleFunctionTime<double>* f) : g3DLinearTerm<double>(space1_), _dom(d), _ufield(ufield),
+                                                                      _comp(comp), _load(f)
+    {      
       if (_dom->getDim() == 2){
         computeNormalOfElement(_dom,_dom->element_begin()->second,normalToDomain);
       }
     }
   // internal copy constructor for the clone method
   protected:
-    g3DFiniteStrainsScalarFluxLinearTerm(const partDomain* d, FunctionSpace<double>& space1_, const unknownField* ufield, const std::vector<int> &vcomp_,
-                                    const std::vector< const simpleFunctionTime<double>*>& vload_, const SVector3& normal) : g3DLinearTerm<double>(space1_), _dom(d),
+    g3DFiniteStrainsScalarFluxLinearTerm(const partDomain* d, FunctionSpace<double>& space1_, const unknownField* ufield, int comp_,
+                                     const simpleFunctionTime<double>* load_, const SVector3& normal) : g3DLinearTerm<double>(space1_), _dom(d),
                                                                                     _ufield(ufield),
-                                                                                     _vcomp(vcomp_),vload(vload_), 
+                                                                                     _comp(comp_),_load(load_), 
                                                                                      normalToDomain(normal){}
   public:
     virtual ~g3DFiniteStrainsScalarFluxLinearTerm(){}
@@ -414,7 +406,7 @@ class g3DFiniteStrainsScalarFluxLinearTerm : public g3DLinearTerm<double>
     virtual void get(MElement *ele,int npts,IntPt *GP,fullVector<double> &m) const;
     virtual LinearTermBase<double>* clone () const
     {
-      g3DFiniteStrainsScalarFluxLinearTerm* flux =  new g3DFiniteStrainsScalarFluxLinearTerm(_dom,this->space1,_ufield,_vcomp,vload,normalToDomain);
+      g3DFiniteStrainsScalarFluxLinearTerm* flux =  new g3DFiniteStrainsScalarFluxLinearTerm(_dom,this->space1,_ufield,_comp,_load,normalToDomain);
       flux->setNonLocalEqRatio(this->getNonLocalEqRatio());
       flux->setNumNonLocalVariable(this->getNumNonLocalVariable());
       flux->setNumConstitutiveExtraDofDiffusionVariable(this->getNumConstitutiveExtraDofDiffusionVariable());
@@ -437,25 +429,17 @@ class g3DFiniteStrainsScalarFluxBiLinearTerm : public g3DBilinearTerm<double,dou
     // needed to compute the deformation gradient
     const partDomain* _dom;
     const unknownField* _ufield;
-    std::vector<int> _vcomp;
-    std::vector< const simpleFunctionTime<double>*> vload; // one load function per component
+    int _comp;
+    const simpleFunctionTime<double>* _load; // one load function per component
     SVector3 normalToDomain;
 
   public:
     // space1 only flux dofs, space2 all dof i.e. with displacement too
     g3DFiniteStrainsScalarFluxBiLinearTerm(const partDomain* d, FunctionSpace<double> &space1_, FunctionSpace<double> & space2_,
                                             const unknownField* ufield,
-                                            const std::vector<int> &vcomp,...) : g3DBilinearTerm<double,double>(space1_,space2_),  _dom(d),
-                                                                              _ufield(ufield), _vcomp(vcomp)
+                                            int comp, const simpleFunctionTime<double>* f) : g3DBilinearTerm<double,double>(space1_,space2_),  _dom(d),
+                                                                              _ufield(ufield), _comp(comp), _load(f)
     {
-      va_list ap;
-      va_start(ap, vcomp);
-      vload.resize(vcomp.size(),NULL);
-      for(size_t i=0; i<vload.size();++i)
-      {
-        vload[i] = va_arg(ap,const simpleFunctionTime<double>*);
-      }
-
       if (_dom->getDim() == 2){
         computeNormalOfElement(_dom,_dom->element_begin()->second,normalToDomain);
       }
@@ -466,9 +450,9 @@ class g3DFiniteStrainsScalarFluxBiLinearTerm : public g3DBilinearTerm<double,dou
    // protected constructor for the copy
     g3DFiniteStrainsScalarFluxBiLinearTerm(const partDomain* d, FunctionSpace<double> &space1_, FunctionSpace<double> & space2_,
                                           const unknownField* ufield,
-                                          const std::vector<int> &vcomp,
-                                          const std::vector< const simpleFunctionTime<double>*> &vload_,
-                                          const SVector3& normal): g3DBilinearTerm<double,double>(space1_,space2_),  _ufield(ufield), _vcomp(vcomp), vload(vload_),
+                                          int comp,
+                                          const simpleFunctionTime<double>* load_,
+                                          const SVector3& normal): g3DBilinearTerm<double,double>(space1_,space2_),  _ufield(ufield), _comp(comp), _load(load_),
                                                     _dom(d),normalToDomain(normal){}
     virtual ~g3DFiniteStrainsScalarFluxBiLinearTerm()
     {
@@ -484,7 +468,7 @@ class g3DFiniteStrainsScalarFluxBiLinearTerm : public g3DBilinearTerm<double,dou
 
     virtual BilinearTermBase* clone () const
     {
-      g3DFiniteStrainsScalarFluxBiLinearTerm* fluxbiterm =  new g3DFiniteStrainsScalarFluxBiLinearTerm(_dom,this->space1,this->space2,_ufield,_vcomp,vload,normalToDomain);
+      g3DFiniteStrainsScalarFluxBiLinearTerm* fluxbiterm =  new g3DFiniteStrainsScalarFluxBiLinearTerm(_dom,this->space1,this->space2,_ufield,_comp,_load,normalToDomain);
       fluxbiterm->setNonLocalEqRatio(this->getNonLocalEqRatio());
       fluxbiterm->setNumNonLocalVariable(this->getNumNonLocalVariable());
       fluxbiterm->setNumConstitutiveExtraDofDiffusionVariable(this->getNumConstitutiveExtraDofDiffusionVariable());
-- 
GitLab


From 0167b1f9ef02e30d67f7cd14cee609bcf3719f52 Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Mon, 1 Jun 2020 14:13:11 +0200
Subject: [PATCH 03/19] oups

---
 dG3D/src/dG3DTerms.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dG3D/src/dG3DTerms.cpp b/dG3D/src/dG3DTerms.cpp
index 3a07f3e77..873fd92f6 100644
--- a/dG3D/src/dG3DTerms.cpp
+++ b/dG3D/src/dG3DTerms.cpp
@@ -625,7 +625,7 @@ void g3DFiniteStrainsScalarFluxBiLinearTerm::get(MElement *ele, int npts, IntPt
           int nbFFTotalLastColOther = sp1->getShapeFunctionsIndex(ele,depenComps[ic]);
           for (int p=0; p< nbFFColOther; p++)
           {
-            m(j+nbFFTotalLastRow,p+nbFFTotalLastColOther) -= Vals[j+j+nbFFTotalLastRow]* loadvalue*normJcur_normal*DdepenValue[ic]*Vals[p+nbFFTotalLastColOther]*scaleEq; // negative as it is the derivative of Fext
+            m(j+nbFFTotalLastRow,p+nbFFTotalLastColOther) -= Vals[j+nbFFTotalLastRow]* loadvalue*normJcur_normal*DdepenValue[ic]*Vals[p+nbFFTotalLastColOther]*scaleEq; // negative as it is the derivative of Fext
           }
         }
       }
-- 
GitLab


From 4415d33b341c44977f73cb54825af766fbe5fa06 Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Mon, 1 Jun 2020 15:20:36 +0200
Subject: [PATCH 04/19] done bulk terms

---
 dG3D/src/dG3DTerms.cpp | 352 ++++++++++++++++++++++++-----------------
 1 file changed, 205 insertions(+), 147 deletions(-)

diff --git a/dG3D/src/dG3DTerms.cpp b/dG3D/src/dG3DTerms.cpp
index 873fd92f6..1aa7c1dce 100644
--- a/dG3D/src/dG3DTerms.cpp
+++ b/dG3D/src/dG3DTerms.cpp
@@ -637,10 +637,11 @@ void dG3DForceBulk::get(MElement *ele,int npts,IntPt *GP,fullVector<double> &vFo
 {
   // Initialization of some data
   int nbdof = this->space1.getNumKeys(ele);
-  int nbFF = ele->getNumShapeFunctions();
   vFor.resize(nbdof);
   vFor.setAll(0.);
   
+  nlsFunctionSpace<double>* nlspace = dynamic_cast<nlsFunctionSpace<double>*>(&space1);
+  
   // IP FIELD
   const AllIPState::ipstateElementContainer *vips = _ipf->getAips()->getIPstate(ele->getNum());
   /***
@@ -660,17 +661,20 @@ void dG3DForceBulk::get(MElement *ele,int npts,IntPt *GP,fullVector<double> &vFo
     const STensor3 *PK1 = &(ipv->getConstRefToFirstPiolaKirchhoffStress());
     static SVector3 BT;
     
-    for(int j=0;j<nbFF; j++)
+    // x y z
+    for(int kk=0;kk<3;kk++)
     {
-      BT(0) = Grads[j+0*nbFF][0];
-      BT(1) = Grads[j+0*nbFF][1];
-      BT(2) = Grads[j+0*nbFF][2];
-      // x y z
-      for(int kk=0;kk<3;kk++)
+      int nbFFRow = nlspace->getNumShapeFunctions(ele,kk);
+      int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,kk);
+      for(int j=0;j<nbFFRow; j++)
       {
+        BT(0) = Grads[j+nbFFTotalLastRow][0];
+        BT(1) = Grads[j+nbFFTotalLastRow][1];
+        BT(2) = Grads[j+nbFFTotalLastRow][2];
+      
         for(int m=0; m<3; m++)
         {
-          vFor(j+kk*nbFF) += ratio*(BT(m)*PK1->operator()(kk,m));
+          vFor(j+nbFFTotalLastRow) += ratio*(BT(m)*PK1->operator()(kk,m));
         }
       }
     }
@@ -712,18 +716,20 @@ void dG3DForceBulk::get(MElement *ele,int npts,IntPt *GP,fullVector<double> &vFo
           localVar -= ipvprev->getConstRefToLocalVariable(nl);
         }
                 
-        const int threeTimesNbFF = 3*nbFF;
-        for(int j=0;j<nbFF; j++)
+        int nbFFRow = nlspace->getNumShapeFunctions(ele,3+nl);
+        int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,3+nl);
+        
+        for(int j=0;j<nbFFRow; j++)
         {
-          vFor(j+nl*nbFF+threeTimesNbFF) +=  getNonLocalEqRatio()*ratio*(Vals[j+nl*nbFF+threeTimesNbFF]*nonlocalVar);
+          vFor(j+nbFFTotalLastRow) +=  getNonLocalEqRatio()*ratio*(Vals[j+nbFFTotalLastRow]*nonlocalVar);
           for(int m=0; m<3; m++)
           {
             for(int n=0; n<3; n++)
             {
-              vFor(j+nl*nbFF+threeTimesNbFF) +=  getNonLocalEqRatio()*ratio*(Grads[j+nl*nbFF+threeTimesNbFF](m)*cg->operator()(m,n)*gradNonlocalVar(n));
+              vFor(j+nbFFTotalLastRow) +=  getNonLocalEqRatio()*ratio*(Grads[j+nbFFTotalLastRow](m)*cg->operator()(m,n)*gradNonlocalVar(n));
             }
           }
-          vFor(j+nl*nbFF+threeTimesNbFF) -=  getNonLocalEqRatio()*ratio*(Vals[j+nl*nbFF+threeTimesNbFF]*localVar);
+          vFor(j+nbFFTotalLastRow) -=  getNonLocalEqRatio()*ratio*(Vals[j+nbFFTotalLastRow]*localVar);
         }
       }
     }
@@ -763,16 +769,17 @@ void dG3DForceBulk::get(MElement *ele,int npts,IntPt *GP,fullVector<double> &vFo
            w += ipv->getConstRefToMechanicalSource()(extraDOFField);
         }
         int indexField=3+getNumNonLocalVariable()+extraDOFField;
-
-        for(int j=0;j<nbFF; j++)
+        int nbFFRow = nlspace->getNumShapeFunctions(ele,indexField);
+        int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,indexField);
+        for(int j=0;j<nbFFRow; j++)
         {
           for(int m=0; m<3; m++)
           {
-            vFor(j+indexField*nbFF) += getConstitutiveExtraDofDiffusionEqRatio()*ratio*(Grads[j+indexField*nbFF][m]*flux(m));
+            vFor(j+nbFFTotalLastRow) += getConstitutiveExtraDofDiffusionEqRatio()*ratio*(Grads[j+nbFFTotalLastRow][m]*flux(m));
           }
           if(extraDOFField==0)
           { // corresponds to temperature, but when considering electro-mechanics, ???
-            vFor(j+indexField*nbFF) += getConstitutiveExtraDofDiffusionEqRatio()*ratio*(w*Vals[j+indexField*nbFF]);// related to cp
+            vFor(j+nbFFTotalLastRow) += getConstitutiveExtraDofDiffusionEqRatio()*ratio*(w*Vals[j+nbFFTotalLastRow]);// related to cp
           }
         }
       }
@@ -843,7 +850,6 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
   {
     // Initialization of some data
     int nbdof = g3DBilinearTerm<double,double>::space1.getNumKeys(ele);
-    int nbFF = ele->getNumShapeFunctions();
     const dG3DMaterialLaw *mlawbulk;
     if(_mlaw->getType() == materialLaw::fracture)
       mlawbulk = static_cast<const dG3DMaterialLaw* >((static_cast<const FractureByCohesive3DLaw* > (_mlaw) )->getBulkLaw());
@@ -853,6 +859,8 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
     bool useAverageNonlocal = mlawbulk->getUseAverageNonlocal();
     
     mStiff.resize(nbdof, nbdof,true); // true --> setAll(0.)
+    
+    nlsFunctionSpace<double>* nlspace = dynamic_cast<nlsFunctionSpace<double>*>(&space1);
 
     // get ipvariables
     const AllIPState::ipstateElementContainer *vips = _ipf->getAips()->getIPstate(ele->getNum());
@@ -863,6 +871,7 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
     static std::vector< std::vector< STensor33 > > dBarFdu; //for each GP and for each node
     if(useBarF)
     {
+      int nbFF = nlspace->getNumShapeFunctions(ele,0); // same for ux, uy, uz components
       dBarJdu.resize(nbFF);
       dBarFdu.resize(npts);
       for (int k=0;k<nbFF;k++)
@@ -962,22 +971,27 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
       //
       static SVector3 B;
       static SVector3 BT;
-      for(int j=0;j<nbFF; j++)
+      for(int kk=0;kk<3;kk++)
       {
-        BT(0) = Grads[j][0];
-        BT(1) = Grads[j][1];
-        BT(2) = Grads[j][2];
-        for(int k=0;k<nbFF;k++)
+        int nbFFRow = nlspace->getNumShapeFunctions(ele,kk);
+        int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,kk);
+        for(int ll=0; ll<3; ll++)
         {
-          // x y z
-          B(0) = Grads[k][0];
-          B(1) = Grads[k][1];
-          B(2) = Grads[k][2];
-
-          for(int kk=0;kk<3;kk++)
+          int nbFFCol = nlspace->getNumShapeFunctions(ele,ll);
+          int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,ll);
+        
+          for(int j=0;j<nbFFRow; j++)
           {
-            for(int ll=0; ll<3; ll++)
+            BT(0) = Grads[j+nbFFTotalLastRow][0];
+            BT(1) = Grads[j+nbFFTotalLastRow][1];
+            BT(2) = Grads[j+nbFFTotalLastRow][2];
+            for(int k=0;k<nbFFCol;k++)
             {
+              // x y z
+              B(0) = Grads[k+nbFFTotalLastCol][0];
+              B(1) = Grads[k+nbFFTotalLastCol][1];
+              B(2) = Grads[k+nbFFTotalLastCol][2];
+
               if(useBarF)
               {
                 for(int m=0; m<3; m++)
@@ -986,7 +1000,7 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                   {
                     for(int p=0; p<3; p++)
                     {
-                      mStiff(j+kk*nbFF,k+ll*nbFF) += ratio*(BT(m)*H->operator()(kk,m,ii,p)*dBarFdu[i][k](ii,p,ll));
+                      mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol) += ratio*(BT(m)*H->operator()(kk,m,ii,p)*dBarFdu[i][k](ii,p,ll));
                     }                                
                   }
                 }
@@ -997,7 +1011,7 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 {
                   for(int n=0; n<3; n++)
                   {
-                    mStiff(j+kk*nbFF,k+ll*nbFF) += ratio*(BT(m)*H->operator()(kk,m,ll,n)*B(n));
+                    mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol) += ratio*(BT(m)*H->operator()(kk,m,ll,n)*B(n));
                   }
                 }
               }
@@ -1014,19 +1028,23 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           Msg::Error("Your material law uses more non local variables than your domain dG3DStiffnessBulk::get");
         }
         
-        const int threeTimesNbFF = 3*nbFF;
         for (int nlk = 0; nlk < ipv->getNumberNonLocalVariable(); nlk++)
         {
           const STensor3  *dsdp    = &ipv->getConstRefToDStressDNonLocalVariable()[nlk];
-          for(int j=0;j<nbFF; j++)
+          int nbFFCol = nlspace->getNumShapeFunctions(ele,3+nlk);
+          int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,3+nlk);
+          for(int kk=0;kk<3;kk++)
           {
-            for(int k=0;k<nbFF;k++)
+            int nbFFRow = nlspace->getNumShapeFunctions(ele,kk);
+            int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,kk);
+            for(int j=0;j<nbFFRow; j++)
             {
-              for(int kk=0;kk<3;kk++)
+              for(int k=0;k<nbFFCol;k++)
               {
+                
                 for(int m=0; m<3; m++)
                 {
-                  mStiff(j+kk*nbFF,k+nlk*nbFF+threeTimesNbFF) += ratio*(Grads[j+kk*nbFF](m)*dsdp->operator()(kk,m)*Vals[k+nlk*nbFF+threeTimesNbFF]);
+                  mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol) += ratio*(Grads[j+nbFFTotalLastRow](m)*dsdp->operator()(kk,m)*Vals[k+nbFFTotalLastCol]);
                 }
               }
             }
@@ -1046,26 +1064,28 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           for (int extraDOFField = 0; extraDOFField< ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
             const STensor3  &dPdField1 = ipv->getConstRefTodPdField()[extraDOFField];
-            int extraDOFField_aux=0;
-            if (extraDOFField == 0)
-              extraDOFField_aux=1;
-            else 
-              extraDOFField_aux=0;
+            int extraDOFField_aux= (extraDOFField == 0) ? 1: 0;
             
             const STensor3  &dPdField2 = ipv->getConstRefTodPdField()[extraDOFField_aux];
             double dFielddEnergyConjugatedField1 = ipv->getConstRefTodFielddEnergyConjugatedField()[extraDOFField][extraDOFField];
             double dFielddEnergyConjugatedField2 = ipv->getConstRefTodFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField];
-            for(int j=0;j<nbFF; j++)
+            //
+            int indexField=3+getNumNonLocalVariable()+extraDOFField;
+            int nbFFCol = nlspace->getNumShapeFunctions(ele,indexField);
+            int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,indexField);
+            
+            for(int kk=0;kk<3;kk++)
             {
-              for(int k=0;k<nbFF;k++)
+              int nbFFRow = nlspace->getNumShapeFunctions(ele,kk);
+              int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,kk);    
+              for(int j=0;j<nbFFRow; j++)
               {
-                int indexField=3+getNumNonLocalVariable()+extraDOFField;
-                for(int kk=0;kk<3;kk++)
+                for(int k=0;k<nbFFCol;k++)
                 {
                   for(int m=0; m<3; m++)
                   {
-                    mStiff(j+kk*nbFF,k+indexField*nbFF) += ratio*(Grads[j+kk*nbFF][m]*(dPdField1.operator()(kk,m)*dFielddEnergyConjugatedField1+
-                                                 dPdField2.operator()(kk,m)*dFielddEnergyConjugatedField2)*Vals[k+indexField*nbFF]);
+                    mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol) += ratio*(Grads[j+nbFFTotalLastRow][m]*(dPdField1.operator()(kk,m)*dFielddEnergyConjugatedField1+
+                                                 dPdField2.operator()(kk,m)*dFielddEnergyConjugatedField2)*Vals[k+nbFFTotalLastCol]);
                   }
                 }
               }
@@ -1078,16 +1098,22 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           for (int extraDOFField = 0; extraDOFField< ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
             const STensor3  &dPdField = ipv->getConstRefTodPdField()[extraDOFField];
-            for(int j=0;j<nbFF; j++)
+            int indexField=3+getNumNonLocalVariable()+extraDOFField;
+            int nbFFCol = nlspace->getNumShapeFunctions(ele,indexField);
+            int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,indexField);
+            
+            for(int kk=0;kk<3;kk++)
             {
-              for(int k=0;k<nbFF;k++)
+              int nbFFRow = nlspace->getNumShapeFunctions(ele,kk);
+              int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,kk);  
+              
+              for(int j=0;j<nbFFRow; j++)
               {
-                int indexField=3+getNumNonLocalVariable()+extraDOFField;
-                for(int kk=0;kk<3;kk++)
+                for(int k=0;k<nbFFCol;k++)
                 {
                   for(int m=0; m<3; m++)
                   {
-                    mStiff(j+kk*nbFF,k+indexField*nbFF) += ratio*(Grads[j+kk*nbFF][m]*dPdField.operator()(kk,m)*Vals[k+indexField*nbFF]);
+                    mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol) += ratio*(Grads[j+nbFFTotalLastRow][m]*dPdField.operator()(kk,m)*Vals[k+nbFFTotalLastCol]);
                   }
                 }
               }
@@ -1120,15 +1146,16 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
         const std::vector<TensorialTraits<double>::GradType> &Grads = ipv->gradf(&space1,ele,GP[i]);
         const std::vector<TensorialTraits<double>::ValType> &Vals = ipv->f(&space1,ele,GP[i]);
         //
-        const int threeTimesNbFF = 3*nbFF;        
         for (int nlk = 0; nlk < ipv->getNumberNonLocalVariable(); nlk++)
         {
           const STensor3    *cg    = &ipv->getConstRefToCharacteristicLengthMatrix(nlk); 
+          int nbFFRow = nlspace->getNumShapeFunctions(ele,3+nlk);
+          int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,3+nlk);
           
-          // nonlocal-nonlocal
-          for(int j=0;j<nbFF; j++)
+          // nonlocal-nonlocal, no couling hear
+          for(int j=0;j<nbFFRow; j++)
           {
-            for(int k=0;k<nbFF;k++)
+            for(int k=0;k<nbFFRow;k++)
             {
               // principal term
               double BtB = 0.;
@@ -1136,21 +1163,24 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               {
                 for(int n=0; n<3; n++)
                 {
-                  BtB += Grads[j+nlk*nbFF+threeTimesNbFF](m)*(cg->operator()(m,n))*Grads[k+nlk*nbFF+threeTimesNbFF](n);
+                  BtB += Grads[j+nbFFTotalLastRow](m)*(cg->operator()(m,n))*Grads[k+nbFFTotalLastRow](n);
                 }
               }
-              mStiff(j+nlk*nbFF+threeTimesNbFF,k+nlk*nbFF+threeTimesNbFF)  += getNonLocalEqRatio()*ratio*(Vals[j+nlk*nbFF+threeTimesNbFF]*Vals[k+nlk*nbFF+threeTimesNbFF]+ BtB);
+              mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastRow)  += getNonLocalEqRatio()*ratio*(Vals[j+nbFFTotalLastRow]*Vals[k+nbFFTotalLastRow]+ BtB);
             }
           }
           // cross nonlocal terms due to local variable
           for (int mlk = 0; mlk < ipv->getNumberNonLocalVariable(); mlk++)
           {
+            int nbFFCol = nlspace->getNumShapeFunctions(ele,3+mlk);
+            int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,3+mlk);
+          
             double  SpBar = ipv->getConstRefToDLocalVariableDNonLocalVariable()(nlk,mlk);
-            for(int j=0;j<nbFF; j++)
+            for(int j=0;j<nbFFRow; j++)
             {
-              for(int k=0;k<nbFF;k++)
+              for(int k=0;k<nbFFCol;k++)
               {
-                mStiff(j+nlk*nbFF+threeTimesNbFF,k+mlk*nbFF+threeTimesNbFF) -= getNonLocalEqRatio()*ratio*(Vals[j+nlk*nbFF+threeTimesNbFF]*SpBar*Vals[k+mlk*nbFF+threeTimesNbFF]);
+                mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol) -= getNonLocalEqRatio()*ratio*(Vals[j+nbFFTotalLastRow]*SpBar*Vals[k+nbFFTotalLastCol]);
               }
             }
           }
@@ -1159,19 +1189,22 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           if(considerNonElasticOnes)
           {
             const STensor3  *dpds    = &ipv->getConstRefToDLocalVariableDStrain()[nlk];
-            for(int j=0;j<nbFF; j++)
+            for(int kk=0;kk<3;kk++)
             {
-              for(int k=0;k<nbFF;k++)
-              {              
-                for(int kk=0;kk<3;kk++)
-                {
+              int nbFFCol = nlspace->getNumShapeFunctions(ele,kk);
+              int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,kk);   
+              for(int j=0;j<nbFFRow; j++)
+              {
+                for(int k=0;k<nbFFCol;k++)
+                {              
+                  
                   if(useBarF)
                   {
                     for(int ii=0; ii<3; ii++)
                     {
                       for(int p=0; p<3; p++)
                       {
-                        mStiff(j+nlk*nbFF+threeTimesNbFF,k+kk*nbFF) -= getNonLocalEqRatio()*ratio*(Vals[j+nlk*nbFF+threeTimesNbFF]*
+                        mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol) -= getNonLocalEqRatio()*ratio*(Vals[j+nbFFTotalLastRow]*
                                                dpds->operator()(ii,p)*dBarFdu[i][k](ii,p,kk));
                       }                                
                     }
@@ -1180,8 +1213,8 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                   {
                     for(int m=0; m<3; m++)
                     {
-                      mStiff(j+nlk*nbFF+threeTimesNbFF,k+kk*nbFF) -= getNonLocalEqRatio()*ratio*(Vals[j+nlk*nbFF+threeTimesNbFF]*
-                                               dpds->operator()(kk,m)*Grads[k+kk*nbFF](m));
+                      mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol) -= getNonLocalEqRatio()*ratio*(Vals[j+nbFFTotalLastRow]*
+                                               dpds->operator()(kk,m)*Grads[k+nbFFTotalLastCol](m));
                     }
                   }
                 }
@@ -1205,11 +1238,7 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               {
                 //Msg::Error("Check non-local / extra dof coupling in dG3DStiffnessBulk::get");
                               
-                int extraDOFField_aux=0;
-                if(extraDOFField == 0) 
-                  extraDOFField_aux=1;
-                else 
-                  extraDOFField_aux=0;
+                int extraDOFField_aux= (extraDOFField == 0) ? 1: 0;
    
                 const STensor3  &dPdField2 = ipv->getConstRefTodPdField()[extraDOFField_aux];
                 double dFielddEnergyConjugatedField1 = ipv->getConstRefTodFielddEnergyConjugatedField()[extraDOFField][extraDOFField];
@@ -1218,13 +1247,17 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 double  dLocalVariableDExtraDof1 = ipv->getConstRefTodLocalVariableDExtraDofDiffusionField()(nlk,extraDOFField);
                 double  dLocalVariableDExtraDof2 = ipv->getConstRefTodLocalVariableDExtraDofDiffusionField()(nlk,extraDOFField_aux);
                 
-                for(int j=0;j<nbFF; j++)
+                int indexField=3+getNumNonLocalVariable()+extraDOFField;
+                int nbFFCol = nlspace->getNumShapeFunctions(ele,indexField);
+                int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,indexField); 
+              
+                for(int j=0;j<nbFFRow; j++)
                 {
-                  for(int k=0;k<nbFF;k++)
+                  for(int k=0;k<nbFFCol;k++)
                   {
-                    int indexField=3+getNumNonLocalVariable()+extraDOFField;
-                    mStiff(j+nlk*nbFF+threeTimesNbFF,k+indexField*nbFF)
-                          += getNonLocalEqRatio()*ratio*Vals[j+nlk*nbFF+threeTimesNbFF]*Vals[k+indexField*nbFF]*(dLocalVariableDExtraDof1*dFielddEnergyConjugatedField1+dLocalVariableDExtraDof2*dLocalVariableDExtraDof2);
+                    
+                    mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)
+                          += getNonLocalEqRatio()*ratio*Vals[j+nbFFTotalLastRow]*Vals[k+nbFFTotalLastCol]*(dLocalVariableDExtraDof1*dFielddEnergyConjugatedField1+dLocalVariableDExtraDof2*dLocalVariableDExtraDof2);
                   }
                 }
               }
@@ -1235,14 +1268,17 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               {
                 //Msg::Error("Check non-local / extra dof coupling in dG3DStiffnessBulk::get");
                 double  dLocalVariableDExtraDof = ipv->getConstRefTodLocalVariableDExtraDofDiffusionField()(nlk,extraDOFField);
-                for(int j=0;j<nbFF; j++)
+                int indexField=3+getNumNonLocalVariable()+extraDOFField;
+                int nbFFCol = nlspace->getNumShapeFunctions(ele,indexField);
+                int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,indexField); 
+                
+                for(int j=0;j<nbFFRow; j++)
                 {
-                  for(int k=0;k<nbFF;k++)
+                  for(int k=0;k<nbFFCol;k++)
                   {
-                    int indexField=3+getNumNonLocalVariable()+extraDOFField;
                     // principal term
-                    mStiff(j+nlk*nbFF+threeTimesNbFF,k+indexField*nbFF)
-                          += getNonLocalEqRatio()*ratio*(Vals[j+nlk*nbFF+threeTimesNbFF]*Vals[k+indexField*nbFF]*dLocalVariableDExtraDof);
+                    mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)
+                          += getNonLocalEqRatio()*ratio*(Vals[j+nbFFTotalLastRow]*Vals[k+nbFFTotalLastCol]*dLocalVariableDExtraDof);
                   }
                 }
               }
@@ -1274,8 +1310,6 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
         // shape function
         const std::vector<TensorialTraits<double>::GradType> &Grads = ipv->gradf(&space1,ele,GP[i]);
         const std::vector<TensorialTraits<double>::ValType> &Vals = ipv->f(&space1,ele,GP[i]);
-        //
-        const int threeTimesNbFF = 3*nbFF;  
         
         // extraDof - extraDof
         if ((getNumConstitutiveExtraDofDiffusionVariable() == 2)&&(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()))
@@ -1283,17 +1317,21 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           //if two fields (T, V) are considered using fT= 1/T, fV = -V/T as unknowns
           for (int extraDOFField = 0; extraDOFField< ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
+            int indexField=3+getNumNonLocalVariable()+extraDOFField;
+            int nbFFRow = nlspace->getNumShapeFunctions(ele,indexField);
+            int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,indexField);
+            
             for (int extraDOFField2 = 0; extraDOFField2< ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField2++)
             {
+              int indexField2=3+getNumNonLocalVariable()+extraDOFField2;
+              int nbFFCol = nlspace->getNumShapeFunctions(ele,indexField2);
+              int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,indexField2);
+              
               //int extraDOFField2=extraDOFField;
-              const STensor3  &dFluxdGradField1                         = ipv->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField2]; //in reference conf
-              const SVector3  &dFluxdField1                             = ipv->getConstRefTodFluxdField()[extraDOFField][extraDOFField2]; //in reference conf
+              const STensor3  &dFluxdGradField1   = ipv->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField2]; //in reference conf
+              const SVector3  &dFluxdField1  = ipv->getConstRefTodFluxdField()[extraDOFField][extraDOFField2]; //in reference conf
 
-              int extraDOFField_aux=0;
-              if((extraDOFField2+1)< ipv->getNumConstitutiveExtraDofDiffusionVariable()) 
-                extraDOFField_aux=extraDOFField2+1;
-              else 
-                extraDOFField_aux=extraDOFField2-1;        
+              int extraDOFField_aux= (extraDOFField2==0) ? 1: 0;
 
               const STensor3  &dFluxdGradField2 = ipv->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField_aux]; //in reference conf
               const SVector3  &dFluxdField2     = ipv->getConstRefTodFluxdField()[extraDOFField][extraDOFField_aux]; //in reference conf
@@ -1307,45 +1345,46 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               double          dFielddEnergyConjugatedField2 = ipv->getConstRefTodFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField2];
 
               double dwdt = 0.;
-              if (getConstitutiveExtraDofDiffusionAccountFieldSource()){
+              if (getConstitutiveExtraDofDiffusionAccountFieldSource())
+              {
                 if(extraDOFField==0 && extraDOFField2==0){
                   dwdt += ipv->getConstRefTodFieldSourcedField()(extraDOFField,extraDOFField2);
                 }
               }
-              if (getConstitutiveExtraDofDiffusionAccountMecaSource()){
+              if (getConstitutiveExtraDofDiffusionAccountMecaSource())
+              {
                 if(extraDOFField==0 && extraDOFField2==0){
                   dwdt += ipv->getConstRefTodMechanicalSourcedField()(extraDOFField,extraDOFField2);
                 }
               }
-              for(int j=0;j<nbFF; j++){
-                for(int k=0;k<nbFF;k++){
-                  int indexField=3+getNumNonLocalVariable()+extraDOFField;
-                  int indexField2=3+getNumNonLocalVariable()+extraDOFField2;
-
+              for(int j=0;j<nbFFRow; j++)
+              {
+                for(int k=0;k<nbFFCol;k++)
+                {
                   // Pure & Cross Terms
                   for(int m=0; m<3; m++)
                   {
-                    mStiff(j+indexField*nbFF,k+indexField2*nbFF)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
-                                  (Grads[j+indexField*nbFF][m]*(dFluxdField1.operator()(m)*dFielddEnergyConjugatedField1+
-                                   dFluxdField2.operator()(m)*dFielddEnergyConjugatedField2)*Vals[k+indexField2*nbFF]);
+                    mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
+                                  (Grads[j+nbFFTotalLastRow][m]*(dFluxdField1.operator()(m)*dFielddEnergyConjugatedField1+
+                                   dFluxdField2.operator()(m)*dFielddEnergyConjugatedField2)*Vals[k+nbFFTotalLastCol]);
 
-                     for(int n=0; n<3; n++)
+                    for(int n=0; n<3; n++)
                     {
-                      mStiff(j+indexField*nbFF,k+indexField2*nbFF)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
-                                 (Grads[j+indexField*nbFF][m]*(dFluxdGradField1.operator()(m,n)*dGradFielddEnergyConjugatedField1.operator()(n)+
-                                 dFluxdGradField2.operator()(m,n)*dGradFielddEnergyConjugatedField2.operator()(n))*Vals[k+indexField2*nbFF]);
+                      mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
+                                 (Grads[j+nbFFTotalLastRow][m]*(dFluxdGradField1.operator()(m,n)*dGradFielddEnergyConjugatedField1.operator()(n)+
+                                 dFluxdGradField2.operator()(m,n)*dGradFielddEnergyConjugatedField2.operator()(n))*Vals[k+nbFFTotalLastCol]);
                  
                       for(int p=0; p<3; p++)
                       {
-                        mStiff(j+indexField*nbFF,k+indexField2*nbFF)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
-                                 (Grads[j+indexField*nbFF][m]*(dFluxdGradField1.operator()(m,p)*dGradFielddGradEnergyConjugatedField1.operator()(p,n)+
-                                 dFluxdGradField2.operator()(m,p)*dGradFielddGradEnergyConjugatedField2.operator()(p,n))*Grads[k+indexField2*nbFF][n]);
-                    }
+                        mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
+                                 (Grads[j+nbFFTotalLastRow][m]*(dFluxdGradField1.operator()(m,p)*dGradFielddGradEnergyConjugatedField1.operator()(p,n)+
+                                 dFluxdGradField2.operator()(m,p)*dGradFielddGradEnergyConjugatedField2.operator()(p,n))*Grads[k+nbFFTotalLastCol][n]);
+                      }
                     }
                   }
-                  if(extraDOFField==0 && extraDOFField2==0) mStiff(j+indexField*nbFF,k+indexField*nbFF)+=
-                                getConstitutiveExtraDofDiffusionEqRatio()*ratio*dwdt*dFielddEnergyConjugatedField1*
-                                Vals[j+indexField*nbFF]*Vals[k+indexField*nbFF];// related to cp
+                  if(extraDOFField==0 && extraDOFField2==0) 
+                    mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)+= getConstitutiveExtraDofDiffusionEqRatio()*ratio*dwdt*dFielddEnergyConjugatedField1*
+                                Vals[j+nbFFTotalLastRow]*Vals[k+nbFFTotalLastCol];// related to cp
                 }
               }
             }
@@ -1354,10 +1393,17 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
         else
         {
           for (int extraDOFField = 0; extraDOFField< ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
-          {            
+          {
+            int indexField=3+getNumNonLocalVariable()+extraDOFField;
+            int nbFFRow = nlspace->getNumShapeFunctions(ele,indexField);
+            int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,indexField);
+            
             for (int extraDOFField2 = 0; extraDOFField2< ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField2++)
             {
-              //int extraDOFField2=extraDOFField;
+              int indexField2=3+getNumNonLocalVariable()+extraDOFField2;
+              int nbFFCol = nlspace->getNumShapeFunctions(ele,indexField2);
+              int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,indexField2);
+              
               const STensor3  &dFluxdGradField = ipv->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField2]; //in reference conf
               const SVector3  &dFluxdField     = ipv->getConstRefTodFluxdField()[extraDOFField][extraDOFField2]; //in reference conf
 
@@ -1376,24 +1422,22 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                   dwdt += ipv->getConstRefTodMechanicalSourcedField()(extraDOFField,extraDOFField2);
                 }
               }
-              for(int j=0;j<nbFF; j++)
+              for(int j=0;j<nbFFRow; j++)
               {
-                for(int k=0;k<nbFF;k++)
+                for(int k=0;k<nbFFCol;k++)
                 {
-                  int indexField=3+getNumNonLocalVariable()+extraDOFField;
-                  int indexField2=3+getNumNonLocalVariable()+extraDOFField2;
-
                   // Pure & Cross Terms
                   for(int m=0; m<3; m++)
                   {
-                    mStiff(j+indexField*nbFF,k+indexField2*nbFF)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*(Grads[j+indexField*nbFF][m]*dFluxdField.operator()(m)*Vals[k+indexField2*nbFF]);
+                    mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*(Grads[j+nbFFTotalLastRow][m]*dFluxdField.operator()(m)*Vals[k+nbFFTotalLastCol]);
                     for(int n=0; n<3; n++)
                     {
-                      mStiff(j+indexField*nbFF,k+indexField2*nbFF)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*(Grads[j+indexField*nbFF][m]*dFluxdGradField.operator()(m,n)*Grads[k+indexField2*nbFF][n]);
+                      mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*(Grads[j+nbFFTotalLastRow][m]*dFluxdGradField.operator()(m,n)*Grads[k+nbFFTotalLastCol][n]);
                     }
                   }
                
-                  if(extraDOFField==0 && extraDOFField2==0) mStiff(j+indexField*nbFF,k+indexField*nbFF)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*dwdt*Vals[j+indexField*nbFF]*Vals[k+indexField*nbFF];// related to cp
+                  if(extraDOFField==0 && extraDOFField2==0) 
+                    mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*dwdt*Vals[j+nbFFTotalLastRow]*Vals[k+nbFFTotalLastCol];// related to cp
                 }
               }
             }
@@ -1404,7 +1448,11 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
         // extraDof-mecanics
         for (int extraDOFField = 0; extraDOFField< ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
         {
-          const STensor33 &dFluxdF         = ipv->getConstRefTodFluxdF()[extraDOFField]; //in reference conf
+          int indexField=3+getNumNonLocalVariable()+extraDOFField;
+          int nbFFRow = nlspace->getNumShapeFunctions(ele,indexField);
+          int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,indexField);
+          //
+          const STensor33 &dFluxdF = ipv->getConstRefTodFluxdF()[extraDOFField]; //in reference conf
           static STensor3 dwdf;
           STensorOperation::zero(dwdf);
 
@@ -1422,12 +1470,15 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               dwdf += ipv->getConstRefTodMechanicalSourcedF()[extraDOFField];
             }
           }
-          for(int j=0;j<nbFF; j++)
-          {
-            for(int k=0;k<nbFF;k++)
+          
+          for(int kk=0;kk<3;kk++)
+          {  
+            int nbFFCol = nlspace->getNumShapeFunctions(ele,kk);
+            int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,kk);
+              
+            for(int j=0;j<nbFFRow; j++)
             {
-              int indexField=3+getNumNonLocalVariable()+extraDOFField;
-              for(int kk=0;kk<3;kk++)
+              for(int k=0;k<nbFFCol;k++)
               {
                 if(useBarF)
                 {
@@ -1437,12 +1488,12 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     {
                       for(int p=0; p<3; p++)
                       {
-                        mStiff(j+indexField*nbFF,k+kk*nbFF) += getConstitutiveExtraDofDiffusionEqRatio()*ratio*
-                             (Grads[j+indexField*nbFF][m]*dFluxdF.operator()(m,ii,p)*dBarFdu[i][k](ii,p,kk));
+                        mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol) += getConstitutiveExtraDofDiffusionEqRatio()*ratio*
+                             (Grads[j+nbFFTotalLastRow][m]*dFluxdF.operator()(m,ii,p)*dBarFdu[i][k](ii,p,kk));
                       }
                       if(extraDOFField==0) 
-                        mStiff(j+indexField*nbFF,k+kk*nbFF)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
-                                              (Vals[j+indexField*nbFF]*dwdf.operator()(ii,m)*dBarFdu[i][k](ii,m,kk)); // related to cp
+                        mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
+                                              (Vals[j+nbFFTotalLastRow]*dwdf.operator()(ii,m)*dBarFdu[i][k](ii,m,kk)); // related to cp
                     }
                   }
                 }
@@ -1452,12 +1503,12 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                   {
                     for(int n=0; n<3; n++)
                     {
-                      mStiff(j+indexField*nbFF,k+kk*nbFF) += getConstitutiveExtraDofDiffusionEqRatio()*ratio*
-                                       (Grads[j+indexField*nbFF][m]*dFluxdF.operator()(m,kk,n)*Grads[k][n]);
+                      mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol) += getConstitutiveExtraDofDiffusionEqRatio()*ratio*
+                                       (Grads[j+nbFFTotalLastRow][m]*dFluxdF.operator()(m,kk,n)*Grads[k+nbFFTotalLastCol][n]);
                     }
                     if(extraDOFField==0) 
-                       mStiff(j+indexField*nbFF,k+kk*nbFF)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
-                                              (Vals[j+indexField*nbFF]*dwdf.operator()(kk,m)*Grads[k][m]); // related to cp
+                       mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
+                                              (Vals[j+nbFFTotalLastRow]*dwdf.operator()(kk,m)*Grads[k+nbFFTotalLastCol][m]); // related to cp
                   }
                 }
               }
@@ -1470,8 +1521,15 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
         {
           for (int extraDOFField = 0; extraDOFField< ipv->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
+            int indexField=3+getNumNonLocalVariable()+extraDOFField;
+            int nbFFRow = nlspace->getNumShapeFunctions(ele,indexField);
+            int nbFFTotalLastRow = nlspace->getShapeFunctionsIndex(ele,indexField);
+            
             for (int nlk = 0; nlk < ipv->getNumberNonLocalVariable(); nlk++)
             {
+              int nbFFCol = nlspace->getNumShapeFunctions(ele,3+nlk);
+              int nbFFTotalLastCol = nlspace->getShapeFunctionsIndex(ele,3+nlk);
+            
               //Msg::Error("Check extra dof / non-local coupling in dG3DStiffnessBulk::get");
               const SVector3 &dFluxdNonLocalVariable = ipv->getConstRefTodFluxdNonLocalVariable()[extraDOFField][nlk];
               double dwdNonLocalVariable   = 0.;  
@@ -1483,17 +1541,17 @@ void dG3DStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               }
               if(considerNonElasticOnes)
               {
-                for(int j=0;j<nbFF; j++){
-                  for(int k=0;k<nbFF;k++){
-                    int indexField=3+getNumNonLocalVariable()+extraDOFField;
-                    int indexNL=3+nlk;
+                for(int j=0;j<nbFFRow; j++)
+                {
+                  for(int k=0;k<nbFFCol;k++)
+                  {
                     for(int m=0; m<3; m++)
                     {
-                      mStiff(j+indexField*nbFF,k+indexNL*nbFF)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
-                                          (Grads[j+indexField*nbFF][m]*dFluxdNonLocalVariable.operator()(m)*Vals[k+indexNL*nbFF]);
+                      mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
+                                          (Grads[j+nbFFTotalLastRow][m]*dFluxdNonLocalVariable.operator()(m)*Vals[k+nbFFTotalLastCol]);
                     }
-                    mStiff(j+indexField*nbFF,k+indexNL*nbFF)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
-                                                  dwdNonLocalVariable*Vals[j+indexField*nbFF]*Vals[k+indexNL*nbFF];
+                    mStiff(j+nbFFTotalLastRow,k+nbFFTotalLastCol)+=getConstitutiveExtraDofDiffusionEqRatio()*ratio*
+                                                  dwdNonLocalVariable*Vals[j+nbFFTotalLastRow]*Vals[k+nbFFTotalLastCol];
                   }
                 }
               }
-- 
GitLab


From 13ef617967e2fca78437527ee6eb572cc9dc74ac Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Mon, 1 Jun 2020 15:58:11 +0200
Subject: [PATCH 05/19] done interface DG linear terms

---
 dG3D/src/dG3DTerms.cpp | 189 +++++++++++++++++++++++++----------------
 1 file changed, 115 insertions(+), 74 deletions(-)

diff --git a/dG3D/src/dG3DTerms.cpp b/dG3D/src/dG3DTerms.cpp
index 1aa7c1dce..2938c37ea 100644
--- a/dG3D/src/dG3DTerms.cpp
+++ b/dG3D/src/dG3DTerms.cpp
@@ -1591,8 +1591,6 @@ void dG3DElasticStiffnessBulk::get(MElement *ele,int npts,IntPt *GP,fullMatrix<d
 void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double> &m)const
 {
   MInterfaceElement *ie = dynamic_cast<MInterfaceElement*>(ele);
-  const int nbFFm = ie->getElem(0)->getNumVertices();
-  const int nbFFp = ie->getElem(1)->getNumVertices();
   const int nbdofm = _minusSpace->getNumKeys(ie->getElem(0));
   const int nbdofp = _plusSpace->getNumKeys(ie->getElem(1));
   m.resize(nbdofm+nbdofp);
@@ -1601,6 +1599,9 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
   {
     // characteristic size
     const double hs = ie->getCharacteristicSize();
+    
+    MElement* em = ie->getElem(0);
+    MElement* ep = ie->getElem(1);
 
     // get value at gauss's point
     const AllIPState::ipstateElementContainer *vips = _ipf->getAips()->getIPstate(ele->getNum());
@@ -1686,17 +1687,7 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
             }
           }
         }
-        // Assembly consistency + stability (if not broken)
-        for(int j=0;j<nbFFm;j++){
-          for(int k=0;k<3;k++){
-            m(j+k*nbFFm) -= (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsm[j+0*nbFFm]*wJ);
-          }
-        }
-        for(int j=0;j<nbFFp;j++){
-          for(int k=0;k<3;k++){
-            m(j+k*nbFFp+nbdofm) += (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsp[j+0*nbFFp]*wJ);
-          }
-        }
+        
         // compatibility membrane (4 terms to assembly)
         static STensor3 HmJumpN;
         static STensor3 HpJumpN;
@@ -1717,24 +1708,39 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
             }
           }
         }
-        // Assembly (loop on shape function)
-        for(int j=0;j<nbFFm;j++)
+        
+        // Assembly consistency + stability (if not broken)
+        for(int k=0;k<3;k++)
         {
-          for(int k=0;k<3;k++)
+          // Assembly consistency + stability (if not broken)
+          int nbFFmRow = _minusSpace->getNumShapeFunctions(em,k);
+          int nbFFmTotalLastRow = _minusSpace->getShapeFunctionsIndex(em,k);
+          //
+          int nbFFpRow = _plusSpace->getNumShapeFunctions(ep,k);
+          int nbFFpTotalLastRow = _plusSpace->getShapeFunctionsIndex(ep,k);
+          //
+          for(int j=0;j<nbFFmRow;j++)
+          {
+            m(j+nbFFmTotalLastRow) -= (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsm[j+nbFFmTotalLastRow]*wJ);
+          }
+          for(int j=0;j<nbFFpRow;j++)
+          {
+            m(j+nbFFpTotalLastRow+nbdofm) += (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsp[j+nbFFpTotalLastRow]*wJ);
+          }
+        
+          // Assembly symetrical term
+          for(int j=0;j<nbFFmRow;j++)
           {
             for(int l=0;l<3;l++)
             {
-              m(j+k*nbFFm) += (HmJumpN(k,l)*Gradsm[j+0*nbFFm][l])*(wJ/2.);
+              m(j+nbFFmTotalLastRow) += (HmJumpN(k,l)*Gradsm[j+nbFFmTotalLastRow][l])*(wJ/2.);
             }
           }
-        }
-        for(int j=0;j<nbFFm;j++)
-        {
-          for(int k=0;k<3;k++)
+          for(int j=0;j<nbFFpRow;j++)
           {
             for(int l=0;l<3;l++)
             {
-              m(j+k*nbFFp+nbdofm) += (HpJumpN(k,l)*Gradsp[j+0*nbFFp][l])*(wJ/2.);
+              m(j+nbFFpTotalLastRow+nbdofm) += (HpJumpN(k,l)*Gradsp[j+nbFFpTotalLastRow][l])*(wJ/2.);
             }
           }
         }
@@ -1752,15 +1758,22 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
         const std::vector<TensorialTraits<double>::ValType> &Valsm = ipvm->f(_minusSpace,ie->getElem(0),GPm[i]);
         const std::vector<TensorialTraits<double>::ValType> &Valsp = ipvp->f(_plusSpace,ie->getElem(1),GPp[i]);
 
-        // Assembly consistency + stability (if not broken)
-        for(int j=0;j<nbFFm;j++){
-          for(int k=0;k<3;k++){
-            m(j+k*nbFFm) -= interfaceForce[k]*(Valsm[j+0*nbFFm]*wJ);
+        // Assembly consistency (broken)
+        for(int k=0;k<3;k++)
+        {
+          int nbFFmRow = _minusSpace->getNumShapeFunctions(em,k);
+          int nbFFmTotalLastRow = _minusSpace->getShapeFunctionsIndex(em,k);
+          //
+          int nbFFpRow = _plusSpace->getNumShapeFunctions(ep,k);
+          int nbFFpTotalLastRow = _plusSpace->getShapeFunctionsIndex(ep,k);
+          
+          for(int j=0;j<nbFFmRow;j++)
+          {
+            m(j+nbFFmTotalLastRow) -= interfaceForce[k]*(Valsm[j+nbFFmTotalLastRow]*wJ);
           }
-        }
-        for(int j=0;j<nbFFp;j++){
-          for(int k=0;k<3;k++){
-            m(j+k*nbFFp+nbdofm) += interfaceForce[k]*(Valsp[j+0*nbFFp]*wJ);
+          for(int j=0;j<nbFFpRow;j++)
+          {
+            m(j+nbFFpTotalLastRow+nbdofm) += interfaceForce[k]*(Valsp[j+nbFFpTotalLastRow]*wJ);
           }
         }
       }
@@ -1822,13 +1835,15 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
           // characteristic size
           const double nbetahs = getNonLocalStabilityParameter()/hs;
  
-          for (int nlk = 0; nlk< ipvp->getNumberNonLocalVariable(); nlk++){
+          for (int nlk = 0; nlk< ipvp->getNumberNonLocalVariable(); nlk++)
+          {
             double epljump = ipvp->getConstRefToNonLocalJump()(nlk);
-            if (_incrementNonlocalBased){
+            if (_incrementNonlocalBased)
+            {
               epljump -= ipvpprev->getConstRefToNonLocalJump()(nlk);
             }
-            const STensor3  *cgm = &(ipvm->getConstRefToCharacteristicLengthMatrix(nlk));           // by Wu Ling
-            const STensor3  *cgp = &(ipvp->getConstRefToCharacteristicLengthMatrix(nlk));           // by Wu Ling
+            const STensor3  *cgm = &(ipvm->getConstRefToCharacteristicLengthMatrix(nlk));        
+            const STensor3  *cgp = &(ipvp->getConstRefToCharacteristicLengthMatrix(nlk));    
             
             static SVector3 gradm, gradp;
             gradm = ipvm->getConstRefToGradNonLocalVariable()[nlk];
@@ -1871,15 +1886,24 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
               {
                 NMeanCgJumpNBetasc += meanCg(l,n)*epljump*nu(n)*nbetahs*nu(l);
               }
-            }
+            };
+            
+            //
+            int nbFFmRow = _minusSpace->getNumShapeFunctions(em,3+nlk);
+            int nbFFmTotalLastRow = _minusSpace->getShapeFunctionsIndex(em,3+nlk);
+            //
+            int nbFFpRow = _plusSpace->getNumShapeFunctions(ep,3+nlk);
+            int nbFFpTotalLastRow = _plusSpace->getShapeFunctionsIndex(ep,3+nlk);
+            //
+            
             // Assembly consistency + stability (if not broken)
-            for(int j=0;j<nbFFm;j++)
+            for(int j=0;j<nbFFmRow;j++)
             {
-              m(j+nlk*nbFFm+3*nbFFm) -= (meanCgGradN+NMeanCgJumpNBetasc)*(Valsm[j+nlk*nbFFm+3*nbFFm]*wJ*getNonLocalEqRatio());
+              m(j+nbFFmTotalLastRow) -= (meanCgGradN+NMeanCgJumpNBetasc)*(Valsm[j+nbFFmTotalLastRow]*wJ*getNonLocalEqRatio());
             }
-            for(int j=0;j<nbFFp;j++)
+            for(int j=0;j<nbFFpRow;j++)
             {
-              m(j+nlk*nbFFp+3*nbFFp+nbdofm) += (meanCgGradN+NMeanCgJumpNBetasc)*(Valsp[j+nlk*nbFFp+3*nbFFp]*wJ*getNonLocalEqRatio());
+              m(j+nbFFpTotalLastRow+nbdofm) += (meanCgGradN+NMeanCgJumpNBetasc)*(Valsp[j+nbFFpTotalLastRow]*wJ*getNonLocalEqRatio());
             }
             // compatibility membrane (4 terms to assembly)
             SVector3 CgmJumpN;
@@ -1896,18 +1920,18 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
               }
             }
             // Assembly (loop on shape function)
-            for(int j=0;j<nbFFm;j++)
+            for(int j=0;j<nbFFmRow;j++)
             {
               for(int l=0;l<3;l++)
               {
-                m(j+nlk*nbFFm+3*nbFFm) += (CgmJumpN(l)*Gradsm[j+nlk*nbFFm+3*nbFFm][l])*(wJ*getNonLocalEqRatio()/2.);
+                m(j+nbFFmTotalLastRow) += (CgmJumpN(l)*Gradsm[j+nbFFmTotalLastRow][l])*(wJ*getNonLocalEqRatio()/2.);
               }
             }
-            for(int j=0;j<nbFFp;j++)
+            for(int j=0;j<nbFFpRow;j++)
             {
               for(int l=0;l<3;l++)
               {
-                m(j+nlk*nbFFp+3*nbFFp+nbdofm) += (CgpJumpN(l)*Gradsp[j+nlk*nbFFp+3*nbFFp][l])*(wJ*getNonLocalEqRatio()/2.);
+                m(j+nbFFpTotalLastRow+nbdofm) += (CgpJumpN(l)*Gradsp[j+nbFFpTotalLastRow][l])*(wJ*getNonLocalEqRatio()/2.);
               }
             }
           }
@@ -1978,24 +2002,34 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
               Msg::Error("Your plus and minus material laws do not use the same number of constitutive extra dof variables dG3DForceInter::get");
           for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
+            const double nbetahs = getConstitutiveExtraDofDiffusionStabilityParameter()/hs;
+            //
+            int indexField=3+getNumNonLocalVariable()+extraDOFField;
+            //
+            int nbFFmRow = _minusSpace->getNumShapeFunctions(em,indexField);
+            int nbFFmTotalLastRow = _minusSpace->getShapeFunctionsIndex(em,indexField);
+            //
+            int nbFFpRow = _plusSpace->getNumShapeFunctions(ep,indexField);
+            int nbFFpTotalLastRow = _plusSpace->getShapeFunctionsIndex(ep,indexField);
+            //
             for (int extraDOFField2 = 0; extraDOFField2< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField2++)
             {
-              const double nbetahs = getConstitutiveExtraDofDiffusionStabilityParameter()/hs;
+              
               double fieldJump;
               double fieldp=0.;
               double fieldm=0.;
 
               if(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==1)
               {
-               fieldJump = ipvp->getConstRefToFieldJump()(extraDOFField);
-               fieldp = ipvp->getConstRefToField(extraDOFField);
-               fieldm = ipvm->getConstRefToField(extraDOFField);
+                fieldJump = ipvp->getConstRefToFieldJump()(extraDOFField);
+                fieldp = ipvp->getConstRefToField(extraDOFField);
+                fieldm = ipvm->getConstRefToField(extraDOFField);
               }
               else
               {
-               fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField2);
-               fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
-               fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
+                fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField2);
+                fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
+                fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
               }
 
               static STensor3  k0m;
@@ -2035,28 +2069,26 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
                 }
               }
 
-              int indexField=3+getNumNonLocalVariable()+extraDOFField;
-              
               if(extraDOFField==extraDOFField2)
               {
-                for(int j=0;j<nbFFm;j++)
+                for(int j=0;j<nbFFmRow;j++)
                 {
-                  m(j+indexField*nbFFm) -= (meantflux+NMeank0JumpNBetasc)*(Valsm[j+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  m(j+nbFFmTotalLastRow) -= (meantflux+NMeank0JumpNBetasc)*(Valsm[j+nbFFmTotalLastRow]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 }
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpRow;j++)
                 {
-                  m(j+indexField*nbFFp+nbdofm) += ( meantflux+NMeank0JumpNBetasc)*(Valsp[j+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  m(j+nbFFpTotalLastRow+nbdofm) += ( meantflux+NMeank0JumpNBetasc)*(Valsp[j+nbFFpTotalLastRow]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 }
               }
               else
               {
-                for(int j=0;j<nbFFm;j++)
+                for(int j=0;j<nbFFmRow;j++)
                 {
-                  m(j+indexField*nbFFm) -= (NMeank0JumpNBetasc)*(Valsm[j+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  m(j+nbFFmTotalLastRow) -= (NMeank0JumpNBetasc)*(Valsm[j+nbFFmTotalLastRow]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 }
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpRow;j++)
                 {
-                  m(j+indexField*nbFFp+nbdofm) += (NMeank0JumpNBetasc)*(Valsp[j+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  m(j+nbFFpTotalLastRow+nbdofm) += (NMeank0JumpNBetasc)*(Valsp[j+nbFFpTotalLastRow]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 }
               }
       
@@ -2073,18 +2105,18 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
                 }
               }
               // Assembly (loop on shape function)
-              for(int j=0;j<nbFFm;j++)
+              for(int j=0;j<nbFFmRow;j++)
               {
                 for(int l=0;l<3;l++)
                 {
-                  m(j+indexField*nbFFm) += ( k0mJumpN(l)*Gradsm[j+indexField*nbFFm][l])*(wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.);
+                  m(j+nbFFmTotalLastRow) += ( k0mJumpN(l)*Gradsm[j+nbFFmTotalLastRow][l])*(wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.);
                 }
               }
-              for(int j=0;j<nbFFp;j++)
+              for(int j=0;j<nbFFpRow;j++)
               {
                 for(int l=0;l<3;l++)
                 {
-                  m(j+indexField*nbFFp+nbdofm) += ( k0pJumpN(l)*Gradsp[j+indexField*nbFFp][l])*(wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.);
+                  m(j+nbFFpTotalLastRow+nbdofm) += ( k0pJumpN(l)*Gradsp[j+nbFFpTotalLastRow][l])*(wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.);
                 }
               }
             }
@@ -2099,6 +2131,13 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
            * */
           for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
+            int indexField=3+getNumNonLocalVariable()+extraDOFField;
+            //
+            int nbFFmRow = _minusSpace->getNumShapeFunctions(em,indexField);
+            int nbFFmTotalLastRow = _minusSpace->getShapeFunctionsIndex(em,indexField);
+            //
+            int nbFFpRow = _plusSpace->getNumShapeFunctions(ep,indexField);
+            int nbFFpTotalLastRow = _plusSpace->getShapeFunctionsIndex(ep,indexField);
             
             if(extraDOFField==0)
             {
@@ -2108,15 +2147,15 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
 
               if(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==1)
               {
-               fieldJump = ipvp->getConstRefToFieldJump()(extraDOFField);
-               fieldp = ipvp->getConstRefToField(extraDOFField);
-               fieldm = ipvm->getConstRefToField(extraDOFField);
+                fieldJump = ipvp->getConstRefToFieldJump()(extraDOFField);
+                fieldp = ipvp->getConstRefToField(extraDOFField);
+                fieldm = ipvm->getConstRefToField(extraDOFField);
               }
               else
               {
-               fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField);
-               fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
-               fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
+                fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField);
+                fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
+                fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
               }
 
               static STensor3  Stiff_alphadialitationm;
@@ -2153,11 +2192,13 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
               //new
             
               double gamma=0.;
-              for(int j=0;j<nbFFm;j++){
-                m(j+indexField*nbFFm) += gamma*( Stiff_alphadialitationm_JumpN*Valsm[j+indexField*nbFFm])*(wJ/2.)*(-1.);
+              for(int j=0;j<nbFFmRow;j++)
+              {
+                m(j+nbFFmTotalLastRow) += gamma*( Stiff_alphadialitationm_JumpN*Valsm[j+nbFFmTotalLastRow])*(wJ/2.)*(-1.);
               }
-              for(int j=0;j<nbFFp;j++){
-                m(j+indexField*nbFFp+nbdofm) += gamma*( Stiff_alphadialitationp_JumpN*Valsp[j+indexField*nbFFp])*(wJ/2.)*(-1.);
+              for(int j=0;j<nbFFpRow;j++)
+              {
+                m(j+nbFFpTotalLastRow+nbdofm) += gamma*( Stiff_alphadialitationp_JumpN*Valsp[j+nbFFpTotalLastRow])*(wJ/2.)*(-1.);
               }
             }
           }
-- 
GitLab


From c92f10d54abe207d75721f3874d0d310e31d4148 Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Mon, 1 Jun 2020 17:42:33 +0200
Subject: [PATCH 06/19] done interface terms without extraDof

---
 dG3D/src/dG3DTerms.cpp | 190 +++++++++++++++++++++++------------------
 1 file changed, 107 insertions(+), 83 deletions(-)

diff --git a/dG3D/src/dG3DTerms.cpp b/dG3D/src/dG3DTerms.cpp
index 2938c37ea..331c5585e 100644
--- a/dG3D/src/dG3DTerms.cpp
+++ b/dG3D/src/dG3DTerms.cpp
@@ -2213,13 +2213,10 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
 void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double> &stiff) const
 {
   MInterfaceElement *ie = dynamic_cast<MInterfaceElement*>(ele);
-  const int nbFFm = ie->getElem(0)->getNumVertices();
-  const int nbFFp = ie->getElem(1)->getNumVertices();
   const int nbdofm = _minusSpace->getNumKeys(ie->getElem(0));
   const int nbdofp = _plusSpace->getNumKeys(ie->getElem(1));
   stiff.resize(nbdofm+nbdofp,nbdofm+nbdofp);
   stiff.setAll(0.);
-  double jac[3][3];
   if(_fullDg)
   {
     // characteristic size
@@ -2230,8 +2227,10 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
     // Values on minus and plus elements
     IntPt *GPm; IntPt *GPp;
     _interQuad->getIntPoints(ie,GP,&GPm,&GPp);
-    // loop on Gauss Point
-  
+    
+    MElement* em = ie->getElem(0);
+    MElement* ep = ie->getElem(1);
+    
     /****
      * DISPLACEMENT FIELD
      * */
@@ -2253,6 +2252,8 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
     bool useBarF=mlawbulkm->getUseBarF();
     if(useBarF)
     {
+      int nbFFm = _minusSpace->getNumShapeFunctions(em,0); // same for component 0, 1, 2
+      int nbFFp = _plusSpace->getNumShapeFunctions(ep,0);
       dBarJdum.resize(nbFFm);
       dBarFdum.resize(npts);
       dBarJdup.resize(nbFFp);
@@ -2472,6 +2473,9 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
         DInterfaceForceDjump = ipvmf->getConstRefToDInterfaceForceDjump();
         DInterfaceForceDjump += ipvpf->getConstRefToDInterfaceForceDjump();
         DInterfaceForceDjump *= 0.5;
+        
+        int nbFFm = _minusSpace->getNumShapeFunctions(em,0); // same for component 0, 1, 2
+        int nbFFp = _plusSpace->getNumShapeFunctions(ep,0); // same for component 0, 1, 2
 
         // Assembly (if broken)
         for(int j=0;j<nbFFm;j++)
@@ -2693,6 +2697,10 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
         const STensor43 &Hm = ipvm->getConstRefToTangentModuli();
         const STensor43 &eHp = ipvp->getConstRefToDGElasticTangentModuli();
         const STensor43 &eHm = ipvm->getConstRefToDGElasticTangentModuli();
+        
+        int nbFFm = _minusSpace->getNumShapeFunctions(em,0); // same for component 0, 1, 2
+        int nbFFp = _plusSpace->getNumShapeFunctions(ep,0); // same for component 0, 1, 2
+        
         // Assembly consistency
         for(int j=0;j<nbFFm;j++)
         {
@@ -2966,24 +2974,29 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
             
             const STensor3  *dsdpp = &(ipvp->getConstRefToDStressDNonLocalVariable()[nlk]);
             const STensor3  *dsdpm = &(ipvm->getConstRefToDStressDNonLocalVariable()[nlk]);
-
+            
+            int nbFFmNonlocal = _minusSpace->getNumShapeFunctions(em,3+nlk); 
+            int nbFFmTotalLastNonlocal = _minusSpace->getShapeFunctionsIndex(em,3+nlk); 
+            int nbFFpNonlocal = _plusSpace->getNumShapeFunctions(ep,3+nlk); 
+            int nbFFpTotalLastNonlocal = _plusSpace->getShapeFunctionsIndex(ep,3+nlk);
+            
             // Assembly consistency (from derivative of sigma with tilde{p}
             for(int j=0;j<nbFFm;j++)
             {
               for(int k=0;k<3;k++)
               {
-                for(int l=0;l<nbFFm;l++)
+                for(int l=0;l<nbFFmNonlocal;l++)
                 {
                   for(int q = 0; q< 3; q++)
                   {
-                    stiff(j+k*nbFFm,l+nlk*nbFFm+3*nbFFm) -= dsdpm->operator()(k,q)*(Valsm[l+nlk*nbFFm+3*nbFFm]*Valsm[j+k*nbFFm]*wJ/2.*nu(q));
+                    stiff(j+k*nbFFm,l+nbFFmTotalLastNonlocal) -= dsdpm->operator()(k,q)*(Valsm[l+nbFFmTotalLastNonlocal]*Valsm[j+k*nbFFm]*wJ/2.*nu(q));
                   }
                 }
-                for(int l=0;l<nbFFp;l++)
+                for(int l=0;l<nbFFpNonlocal;l++)
                 {
                   for(int q = 0; q< 3; q++)
                   {
-                    stiff(j+k*nbFFm,l+nlk*nbFFp+3*nbFFp+nbdofm) -= dsdpp->operator()(k,q)*(Valsp[l+nlk*nbFFp+3*nbFFp]*Valsm[j+k*nbFFm]*wJ/2.*nu(q));
+                    stiff(j+k*nbFFm,l+nbFFpTotalLastNonlocal+nbdofm) -= dsdpp->operator()(k,q)*(Valsp[l+nbFFpTotalLastNonlocal]*Valsm[j+k*nbFFm]*wJ/2.*nu(q));
                   }
                 }
               }
@@ -2992,19 +3005,19 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
             {
               for(int k=0;k<3;k++)
               {
-                for(int l=0;l<nbFFm;l++)
+                for(int l=0;l<nbFFmNonlocal;l++)
                 {
                   for(int q = 0; q< 3; q++)
                   {
-                    stiff(j+k*nbFFp+nbdofm,l+nlk*nbFFm+3*nbFFm) += dsdpm->operator()(k,q)*(Valsm[l+nlk*nbFFm+3*nbFFm]*
+                    stiff(j+k*nbFFp+nbdofm,l+nbFFmTotalLastNonlocal) += dsdpm->operator()(k,q)*(Valsm[l+nbFFmTotalLastNonlocal]*
                                                                            Valsp[j+k*nbFFp]*wJ/2.*nu(q));
                   }
                 }
-                for(int l=0;l<nbFFp;l++)
+                for(int l=0;l<nbFFpNonlocal;l++)
                 {
                   for(int q = 0; q< 3; q++)
                   {
-                    stiff(j+k*nbFFp+nbdofm,l+nlk*nbFFp+3*nbFFp+nbdofm) += dsdpp->operator()(k,q)*(Valsp[l+nlk*nbFFp+3*nbFFp]* 
+                    stiff(j+k*nbFFp+nbdofm,l+nbFFpTotalLastNonlocal+nbdofm) += dsdpp->operator()(k,q)*(Valsp[l+nbFFpTotalLastNonlocal]* 
                                                                             Valsp[j+k*nbFFp]*wJ/2.*nu(q));
                   }
                 }
@@ -3033,12 +3046,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               const STensor3  *dPdFieldm = &(ipvm->getConstRefTodPdField()[extraDOFField]);
               const STensor3  *dPdFieldp = &(ipvp->getConstRefTodPdField()[extraDOFField]);
               
-              int extraDOFField_aux=0;
-              if(extraDOFField == 0) 
-                extraDOFField_aux=1;
-              else 
-                extraDOFField_aux=0;  
-
+              int extraDOFField_aux = (extraDOFField == 0)? 1: 0;
               double dFielddEnergyConjugatedFieldp = ipvp->getConstRefTodFielddEnergyConjugatedField()[extraDOFField][extraDOFField];
               double dFielddEnergyConjugatedFieldm = ipvm->getConstRefTodFielddEnergyConjugatedField()[extraDOFField][extraDOFField]; 
               double dFielddEnergyConjugatedField2p = ipvp->getConstRefTodFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField];
@@ -3047,26 +3055,30 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               const STensor3& dPdField2m = ipvm->getConstRefTodPdField()[extraDOFField_aux]; 
 
               int indexField=3+getNumNonLocalVariable()+extraDOFField;
+              int nbFFmExtraDof = _minusSpace->getNumShapeFunctions(em,indexField); 
+              int nbFFmTotalLastExtraDof = _minusSpace->getShapeFunctionsIndex(em,indexField); 
+              int nbFFpExtraDof = _plusSpace->getNumShapeFunctions(ep,indexField); 
+              int nbFFpTotalLastExtraDof = _plusSpace->getShapeFunctionsIndex(ep,indexField);
 
               // Assembly consistency (from derivative of sigma with extra field)
               for(int j=0;j<nbFFm;j++)
               {
                 for(int k=0;k<3;k++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDof;l++)
                   {
                     for(int q = 0; q< 3; q++)
                     {
-                      stiff(j+k*nbFFm,l+indexField*nbFFm) -= (dPdFieldm->operator()(k,q)*dFielddEnergyConjugatedFieldm+dPdField2m(k,q)*
-                                                                   dFielddEnergyConjugatedField2m)*(Valsm[l+indexField*nbFFm]*Valsm[j+0*nbFFm]*wJ/2.*nu(q));
+                      stiff(j+k*nbFFm,l+nbFFmTotalLastExtraDof) -= (dPdFieldm->operator()(k,q)*dFielddEnergyConjugatedFieldm+dPdField2m(k,q)*
+                                                                   dFielddEnergyConjugatedField2m)*(Valsm[l+nbFFmTotalLastExtraDof]*Valsm[j+k*nbFFm]*wJ/2.*nu(q));
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDof;l++)
                   {
                     for(int q = 0; q< 3; q++)
                     {
-                      stiff(j+k*nbFFm,l+indexField*nbFFp+nbdofm) -= (dPdFieldp->operator()(k,q)*dFielddEnergyConjugatedFieldp+
-                                                    dPdField2p(k,q)*dFielddEnergyConjugatedField2p)*(Valsp[l+indexField*nbFFp]*Valsm[j+0*nbFFm]*wJ/2.*nu(q));
+                      stiff(j+k*nbFFm,l+nbFFpTotalLastExtraDof+nbdofm) -= (dPdFieldp->operator()(k,q)*dFielddEnergyConjugatedFieldp+
+                                                    dPdField2p(k,q)*dFielddEnergyConjugatedField2p)*(Valsp[l+nbFFpTotalLastExtraDof]*Valsm[j+k*nbFFm]*wJ/2.*nu(q));
                     }
                   }
                 }
@@ -3075,20 +3087,20 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               {
                 for(int k=0;k<3;k++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDof;l++)
                   {
                     for(int q = 0; q< 3; q++)
                     {
-                      stiff(j+k*nbFFp+nbdofm,l+indexField*nbFFm) += (dPdFieldm->operator()(k,q)*dFielddEnergyConjugatedFieldm+dPdField2m(k,q)*
-                                                                  dFielddEnergyConjugatedField2m)*(Valsm[l+indexField*nbFFm]*Valsp[j+0*nbFFp]*wJ/2.*nu(q));
+                      stiff(j+k*nbFFp+nbdofm,l+nbFFmTotalLastExtraDof) += (dPdFieldm->operator()(k,q)*dFielddEnergyConjugatedFieldm+dPdField2m(k,q)*
+                                                                  dFielddEnergyConjugatedField2m)*(Valsm[l+nbFFmTotalLastExtraDof]*Valsp[j+k*nbFFp]*wJ/2.*nu(q));
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDof;l++)
                   {
                     for(int q = 0; q< 3; q++)
                     {
-                        stiff(j+k*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += (dPdFieldp->operator()(k,q)*dFielddEnergyConjugatedFieldp+dPdField2p(k,q)*
-                                                                     dFielddEnergyConjugatedField2p)*(Valsp[l+indexField*nbFFp]*Valsp[j+0*nbFFp]*wJ/2.*nu(q));
+                        stiff(j+k*nbFFp+nbdofm,l+nbFFpTotalLastExtraDof+nbdofm) += (dPdFieldp->operator()(k,q)*dFielddEnergyConjugatedFieldp+dPdField2p(k,q)*
+                                                                     dFielddEnergyConjugatedField2p)*(Valsp[l+nbFFpTotalLastExtraDof]*Valsp[j+k*nbFFp]*wJ/2.*nu(q));
                     }
                   }
                 }
@@ -3104,24 +3116,28 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               const STensor3  *dPdFieldp = &(ipvp->getConstRefTodPdField()[extraDOFField]);
               
               int indexField=3+getNumNonLocalVariable()+extraDOFField;
+              int nbFFmExtraDof = _minusSpace->getNumShapeFunctions(em,indexField); 
+              int nbFFmTotalLastExtraDof = _minusSpace->getShapeFunctionsIndex(em,indexField); 
+              int nbFFpExtraDof = _plusSpace->getNumShapeFunctions(ep,indexField); 
+              int nbFFpTotalLastExtraDof = _plusSpace->getShapeFunctionsIndex(ep,indexField);
 
               // Assembly consistency (from derivative of sigma with extra field)
               for(int j=0;j<nbFFm;j++)
               {
                 for(int k=0;k<3;k++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDof;l++)
                   {
                     for(int q = 0; q< 3; q++)
                     {
-                      stiff(j+k*nbFFm,l+indexField*nbFFm) -= dPdFieldm->operator()(k,q)*(Valsm[l+indexField*nbFFm]*Valsm[j+0*nbFFm]*wJ/2.*nu(q));
+                      stiff(j+k*nbFFm,l+nbFFmTotalLastExtraDof) -= dPdFieldm->operator()(k,q)*(Valsm[l+nbFFmTotalLastExtraDof]*Valsm[j+k*nbFFm]*wJ/2.*nu(q));
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDof;l++)
                   {
                     for(int q = 0; q< 3; q++)
                     {
-                      stiff(j+k*nbFFm,l+indexField*nbFFp+nbdofm) -= dPdFieldp->operator()(k,q)*(Valsp[l+indexField*nbFFp]*Valsm[j+0*nbFFm]*wJ/2.*nu(q));
+                      stiff(j+k*nbFFm,l+nbFFpTotalLastExtraDof+nbdofm) -= dPdFieldp->operator()(k,q)*(Valsp[l+nbFFpTotalLastExtraDof]*Valsm[j+k*nbFFm]*wJ/2.*nu(q));
                     }
                   }
                 }
@@ -3130,18 +3146,18 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               {
                 for(int k=0;k<3;k++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDof;l++)
                   {
                     for(int q = 0; q< 3; q++)
                     {
-                      stiff(j+k*nbFFp+nbdofm,l+indexField*nbFFm) += dPdFieldm->operator()(k,q)*(Valsm[l+indexField*nbFFm]*Valsp[j+0*nbFFp]*wJ/2.*nu(q));
+                      stiff(j+k*nbFFp+nbdofm,l+nbFFmTotalLastExtraDof) += dPdFieldm->operator()(k,q)*(Valsm[l+nbFFmTotalLastExtraDof]*Valsp[j+k*nbFFp]*wJ/2.*nu(q));
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDof;l++)
                   {
                     for(int q = 0; q< 3; q++)
                     {
-                      stiff(j+k*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += dPdFieldp->operator()(k,q)*(Valsp[l+indexField*nbFFp]*Valsp[j+0*nbFFp]*wJ/2.*nu(q));
+                      stiff(j+k*nbFFp+nbdofm,l+nbFFpTotalLastExtraDof+nbdofm) += dPdFieldp->operator()(k,q)*(Valsp[l+nbFFpTotalLastExtraDof]*Valsp[j+k*nbFFp]*wJ/2.*nu(q));
                     }
                   }
                 }
@@ -3221,57 +3237,63 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
             }
               
             const STensor3  *cgm = &(ipvm->getConstRefToCharacteristicLengthMatrix(nlk));           
-            const STensor3  *cgp = &(ipvp->getConstRefToCharacteristicLengthMatrix(nlk));        
+            const STensor3  *cgp = &(ipvp->getConstRefToCharacteristicLengthMatrix(nlk));    
+
+            //
+            int nbFFmNonlocal = _minusSpace->getNumShapeFunctions(em,3+nlk); 
+            int nbFFmTotalLastNonlocal = _minusSpace->getShapeFunctionsIndex(em,3+nlk); 
+            int nbFFpNonlocal = _plusSpace->getNumShapeFunctions(ep,3+nlk); 
+            int nbFFpTotalLastNonlocal = _plusSpace->getShapeFunctionsIndex(ep,3+nlk);    
                           
       
             // consistency D\mean{cG grad epl} Depl
             // Assembly consistency
-            for(int j=0;j<nbFFm;j++)
+            for(int j=0;j<nbFFmNonlocal;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmNonlocal;l++)
               {
                 for(int p = 0; p< 3; p++)
                 {
                   for(int q = 0; q< 3; q++)
                   {
-                    stiff(j+nlk*nbFFm+3*nbFFm,l+nlk*nbFFm+3*nbFFm) -= cgm->operator()(p,q)*
-                                      (Gradsm[l+nlk*nbFFm+3*nbFFm][p]*Valsm[j+nlk*nbFFm+3*nbFFm]*wJ*getNonLocalEqRatio()/2.*nu(q));
+                    stiff(j+nbFFmTotalLastNonlocal,l+nbFFmTotalLastNonlocal) -= cgm->operator()(p,q)*
+                                      (Gradsm[l+nbFFmTotalLastNonlocal][p]*Valsm[j+nbFFmTotalLastNonlocal]*wJ*getNonLocalEqRatio()/2.*nu(q));
                   }
                 }
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpNonlocal;l++)
               {
                 for(int p = 0; p< 3; p++)
                 {
                   for(int q = 0; q< 3; q++)
                   {
-                    stiff(j+nlk*nbFFm+3*nbFFm,l+nlk*nbFFp+3*nbFFp+nbdofm) -= cgp->operator()(p,q)*
-                                       (Gradsp[l+nlk*nbFFp+3*nbFFp][p]*Valsm[j+nlk*nbFFm+3*nbFFm]*wJ*getNonLocalEqRatio()/2.*nu(q));
+                    stiff(j+nbFFmTotalLastNonlocal,l+nbFFpTotalLastNonlocal+nbdofm) -= cgp->operator()(p,q)*
+                                       (Gradsp[l+nbFFpTotalLastNonlocal][p]*Valsm[j+nbFFmTotalLastNonlocal]*wJ*getNonLocalEqRatio()/2.*nu(q));
                   }
                 }
               }
             }
-            for(int j=0;j<nbFFp;j++)
+            for(int j=0;j<nbFFpNonlocal;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmNonlocal;l++)
               {
                 for(int p = 0; p< 3; p++)
                 {
                   for(int q = 0; q< 3; q++)
                   {
-                    stiff(j+nlk*nbFFp+3*nbFFp+nbdofm,l+nlk*nbFFm+3*nbFFm) += cgm->operator()(p,q)*
-                                       (Gradsm[l+nlk*nbFFm+3*nbFFm][p]*Valsp[j+nlk*nbFFp+3*nbFFp]*wJ*getNonLocalEqRatio()/2.*nu(q));
+                    stiff(j+nbFFpTotalLastNonlocal+nbdofm,l+nbFFmTotalLastNonlocal) += cgm->operator()(p,q)*
+                                       (Gradsm[l+nbFFmTotalLastNonlocal][p]*Valsp[j+nbFFpTotalLastNonlocal]*wJ*getNonLocalEqRatio()/2.*nu(q));
                   }
                 }
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpNonlocal;l++)
               {
                 for(int p = 0; p< 3; p++)
                 {
                   for(int q = 0; q< 3; q++)
                   {
-                    stiff(j+nlk*nbFFp+3*nbFFp+nbdofm,l+nlk*nbFFp+3*nbFFp+nbdofm) += cgp->operator()(p,q)*
-                                       (Gradsp[l+nlk*nbFFp+3*nbFFp][p]*Valsp[j+nlk*nbFFp+3*nbFFp]*wJ*getNonLocalEqRatio()/2.*nu(q));
+                    stiff(j+nbFFpTotalLastNonlocal+nbdofm,l+nbFFpTotalLastNonlocal+nbdofm) += cgp->operator()(p,q)*
+                                       (Gradsp[l+nbFFpTotalLastNonlocal][p]*Valsp[j+nbFFpTotalLastNonlocal]*wJ*getNonLocalEqRatio()/2.*nu(q));
                   }
                 }
               }
@@ -3287,79 +3309,79 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               }
             }
             // Assembly stability (if not broken)
-            for(int j=0;j<nbFFm;j++)
+            for(int j=0;j<nbFFmNonlocal;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmNonlocal;l++)
               {
-                stiff(j+nlk*nbFFm+3*nbFFm,l+nlk*nbFFm+3*nbFFm) += NMeanCgNBetasc*
-                                     (Valsm[j+nlk*nbFFm+3*nbFFm]*Valsm[l+nlk*nbFFm+3*nbFFm]*wJ*getNonLocalEqRatio());
+                stiff(j+nbFFmTotalLastNonlocal,l+nbFFmTotalLastNonlocal) += NMeanCgNBetasc*
+                                     (Valsm[j+nbFFmTotalLastNonlocal]*Valsm[l+nbFFmTotalLastNonlocal]*wJ*getNonLocalEqRatio());
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpNonlocal;l++)
               {
-                stiff(j+nlk*nbFFm+3*nbFFm,l+nlk*nbFFp+3*nbFFp+nbdofm) -= NMeanCgNBetasc*
-                                     (Valsm[j+nlk*nbFFm+3*nbFFm]*Valsp[l+nlk*nbFFp+3*nbFFp]*wJ*getNonLocalEqRatio());
+                stiff(j+nbFFmTotalLastNonlocal,l+nbFFpTotalLastNonlocal+nbdofm) -= NMeanCgNBetasc*
+                                     (Valsm[j+nbFFmTotalLastNonlocal]*Valsp[l+nbFFpTotalLastNonlocal]*wJ*getNonLocalEqRatio());
               }
             }
-            for(int j=0;j<nbFFp;j++)
+            for(int j=0;j<nbFFpNonlocal;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmNonlocal;l++)
               {
-                stiff(j+nlk*nbFFp+3*nbFFp+nbdofm,l+nlk*nbFFm+3*nbFFm) -= NMeanCgNBetasc*
-                                     (Valsp[j+nlk*nbFFp+3*nbFFp]*Valsm[l+nlk*nbFFm+3*nbFFm]*wJ*getNonLocalEqRatio());
+                stiff(j+nbFFpTotalLastNonlocal+nbdofm,l+nbFFmTotalLastNonlocal) -= NMeanCgNBetasc*
+                                     (Valsp[j+nbFFpTotalLastNonlocal]*Valsm[l+nbFFmTotalLastNonlocal]*wJ*getNonLocalEqRatio());
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpNonlocal;l++)
               {
-                stiff(j+nlk*nbFFp+3*nbFFp+nbdofm,l+nlk*nbFFp+3*nbFFp+nbdofm) += NMeanCgNBetasc*
-                                    (Valsp[j+nlk*nbFFp+3*nbFFp]*Valsp[l+nlk*nbFFp+3*nbFFp]*wJ*getNonLocalEqRatio());
+                stiff(j+nbFFpTotalLastNonlocal+nbdofm,l+nbFFpTotalLastNonlocal+nbdofm) += NMeanCgNBetasc*
+                                    (Valsp[j+nbFFpTotalLastNonlocal]*Valsp[l+nbFFpTotalLastNonlocal]*wJ*getNonLocalEqRatio());
               }
             }
             // Assembly (loop on shape function)
-            for(int j=0;j<nbFFm;j++)
+            for(int j=0;j<nbFFmNonlocal;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmNonlocal;l++)
               {
                 for(int p =0; p < 3; p++)
                 {
                   for(int q =0; q < 3; q++)
                   {
-                    stiff(j+nlk*nbFFm+3*nbFFm,l+nlk*nbFFm+3*nbFFm) -= (cgm->operator()(p,q)*
-                                Gradsm[j+nlk*nbFFm+3*nbFFm][q])*(nu(p)*wJ*getNonLocalEqRatio()/2.*Valsm[l+nlk*nbFFm+3*nbFFm]);
+                    stiff(j+nbFFmTotalLastNonlocal,l+nbFFmTotalLastNonlocal) -= (cgm->operator()(p,q)*
+                                Gradsm[j+nbFFmTotalLastNonlocal][q])*(nu(p)*wJ*getNonLocalEqRatio()/2.*Valsm[l+nbFFmTotalLastNonlocal]);
                   }
                 }
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpNonlocal;l++)
               {
                 for(int p =0; p < 3; p++)
                 {
                   for(int q =0; q < 3; q++)
                   {
-                    stiff(j+nlk*nbFFm+3*nbFFm,l+nlk*nbFFp+3*nbFFp+nbdofm) += (cgm->operator()(p,q)*
-                                Gradsm[j+nlk*nbFFm+3*nbFFm][q])*(nu(p)*wJ*getNonLocalEqRatio()/2.*Valsp[l+nlk*nbFFp+3*nbFFp]);
+                    stiff(j+nbFFmTotalLastNonlocal,l+nbFFpTotalLastNonlocal+nbdofm) += (cgm->operator()(p,q)*
+                                Gradsm[j+nbFFmTotalLastNonlocal][q])*(nu(p)*wJ*getNonLocalEqRatio()/2.*Valsp[l+nbFFpTotalLastNonlocal]);
                   }
                 }
               }
             }
-            for(int j=0;j<nbFFp;j++)
+            for(int j=0;j<nbFFpNonlocal;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmNonlocal;l++)
               {
                 for(int p =0; p < 3; p++)
                 {
                   for(int q =0; q < 3; q++)
                   {
-                    stiff(j+nlk*nbFFp+3*nbFFp+nbdofm,l+nlk*nbFFm+3*nbFFm) -= (cgp->operator()(p,q)*
-                                Gradsp[j+nlk*nbFFp+3*nbFFp][q])*(nu(p)*wJ*getNonLocalEqRatio()/2.*Valsm[l+nlk*nbFFm+3*nbFFm]);
+                    stiff(j+nbFFpTotalLastNonlocal+nbdofm,l+nbFFmTotalLastNonlocal) -= (cgp->operator()(p,q)*
+                                Gradsp[j+nbFFpTotalLastNonlocal][q])*(nu(p)*wJ*getNonLocalEqRatio()/2.*Valsm[l+nbFFmTotalLastNonlocal]);
                   }
                 }
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpNonlocal;l++)
               {
                 for(int p =0; p < 3; p++)
                 {
                   for(int q =0; q < 3; q++)
                   {
-                    stiff(j+nlk*nbFFp+3*nbFFp+nbdofm,l+nlk*nbFFp+3*nbFFp+nbdofm) += (cgp->operator()(p,q)*
-                                Gradsp[j+nlk*nbFFp+3*nbFFp][q])*(nu(p)*wJ*getNonLocalEqRatio()/2.*Valsp[l+nlk*nbFFp+3*nbFFp]);
+                    stiff(j+nbFFpTotalLastNonlocal+nbdofm,l+nbFFpTotalLastNonlocal+nbdofm) += (cgp->operator()(p,q)*
+                                Gradsp[j+nbFFpTotalLastNonlocal][q])*(nu(p)*wJ*getNonLocalEqRatio()/2.*Valsp[l+nbFFpTotalLastNonlocal]);
                   }
                 }
               }
@@ -3375,6 +3397,8 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
     
     if ((getNumConstitutiveExtraDofDiffusionVariable() > 0) && getConstitutiveExtraDofDiffusionContinuity())
     {
+      int nbFFm = em->getNumShapeFunctions();
+      int nbFFp = ep->getNumShapeFunctions();
     
       for(int i=0;i<npts; i++)
       {
-- 
GitLab


From 1ab055e2de9b91d6ec062cc4d0dbb08cf4ac8a1c Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Mon, 1 Jun 2020 18:22:33 +0200
Subject: [PATCH 07/19] make mixed interpolation works

---
 .../space/ThreeDLagrangeFunctionSpace.cpp     | 10 ++++----
 .../space/ThreeDLagrangeFunctionSpace.h       |  1 -
 dG3D/src/dG3DDomain.cpp                       | 24 +++++++++++++++++++
 dG3D/src/dG3DDomain.h                         |  2 ++
 4 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.cpp b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.cpp
index 4981ee672..0f926cfd8 100644
--- a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.cpp
+++ b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.cpp
@@ -18,18 +18,18 @@ std::map<int,MElement*> VertexBasedLagrangeFunctionSpace::primaryElementMap;
 MElement* VertexBasedLagrangeFunctionSpace::getPrimaryElement(MElement* ele)
 {
   if (ele->getPolynomialOrder() == 1) return ele;
-  int type = ele->getType();
-  std::map<int,MElement*>::iterator itF = primaryElementMap.find(type);
-  if (itF == primaryElementMap.end())
+  std::map<int,MElement*>::iterator itF = primaryElementMap.find(ele->getNum());
+  if (itF != primaryElementMap.end())
   {
     return itF->second;
   }
   else
   {
+    int type = ele->getType();
     std::vector<MVertex*> vver;
     for(int j=0;j<ele->getNumPrimaryVertices();j++)
     {
-      vver.push_back(new MVertex(0.,0.,0.));
+      vver.push_back(ele->getVertex(j));
     }
     MElement *eletmp = NULL;
     MElementFactory factory;
@@ -58,7 +58,7 @@ MElement* VertexBasedLagrangeFunctionSpace::getPrimaryElement(MElement* ele)
       default:
         Msg::Error("unknown element type %d",ele->getType());
     }
-    primaryElementMap.insert(std::pair<int,MElement*>(ele->getType(),eletmp));
+    primaryElementMap.insert(std::pair<int,MElement*>(ele->getNum(),eletmp));
     return eletmp;
   }
 }
diff --git a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
index 6f2398f0b..b1604720a 100644
--- a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
+++ b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
@@ -52,7 +52,6 @@ class VertexBasedLagrangeFunctionSpace : public nlsFunctionSpace<double>
     virtual void usePrimaryShapeFunction(int c)
     {
       _usePrimaryShapeFunctions.insert(c);
-      Msg::Info("comp %d considers primary shape functions");
     }
     virtual bool withPrimaryShapeFunction(int c) const
     {
diff --git a/dG3D/src/dG3DDomain.cpp b/dG3D/src/dG3DDomain.cpp
index 7e73a8f9f..af7c18442 100644
--- a/dG3D/src/dG3DDomain.cpp
+++ b/dG3D/src/dG3DDomain.cpp
@@ -204,6 +204,30 @@ void dG3DDomain::setMaterialLawNumber(const int num)
     _lnum =num;
     this->setmaterial= false;
   }
+};
+
+void dG3DDomain::usePrimaryShapeFunction(const int comp)
+{
+  VertexBasedLagrangeFunctionSpace* sp = dynamic_cast<VertexBasedLagrangeFunctionSpace*>(this->getFunctionSpace());
+  if (sp != NULL)
+  {
+    if (comp == 0 || comp==1 || comp ==2)
+    {
+      Msg::Info("use primary FE approximation for displacement field !!!");
+      sp->usePrimaryShapeFunction(0);
+      sp->usePrimaryShapeFunction(1);
+      sp->usePrimaryShapeFunction(2);
+    }
+    else
+    {
+      sp->usePrimaryShapeFunction(comp);
+      Msg::Info("use primary FE approximation for comp %d !!!",comp);      
+    }
+  }
+  else
+  {
+    Msg::Error("VertexBasedLagrangeFunctionSpace must be used in dG3DDomain::usePrimaryShapeFunction !!!");
+  }
 }
 
 void dG3DDomain::setPlaneStressState(const bool fl){
diff --git a/dG3D/src/dG3DDomain.h b/dG3D/src/dG3DDomain.h
index e38f50263..9f4f86c82 100644
--- a/dG3D/src/dG3DDomain.h
+++ b/dG3D/src/dG3DDomain.h
@@ -151,6 +151,8 @@ class dG3DDomain : public dgPartDomain{
   
   virtual void setMaterialLawNumber(const int num);
   
+  virtual void usePrimaryShapeFunction(const int comp);
+  
 #ifndef SWIG
   dG3DDomain(const dG3DDomain &source);
   virtual ~dG3DDomain();
-- 
GitLab


From b6542f1e2cb5d3b6a6cb18bf26e69a2a936baca2 Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Mon, 1 Jun 2020 20:21:33 +0200
Subject: [PATCH 08/19] work with mixed fe

---
 .../nlsolver/nonLinearMechSolver.cpp          |   1 +
 dG3D/src/dG3DFunctionSpace.h                  | 142 ++++++++++--
 dG3D/src/dG3DTerms.cpp                        | 205 ++++++++----------
 3 files changed, 211 insertions(+), 137 deletions(-)

diff --git a/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
index b343c5823..c0eb54205 100644
--- a/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
+++ b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
@@ -2887,6 +2887,7 @@ void nonLinearMechSolver::init2()
 
   Msg::Info("Fix and number Dofs");
   this->numberDofs();
+  printf("total number of Dofs = %d\n",pAssembler->sizeOfR());
   Msg::Info("Dofs are fixed and numbered");
 
   /* MPI init */
diff --git a/dG3D/src/dG3DFunctionSpace.h b/dG3D/src/dG3DFunctionSpace.h
index 6d2d76747..a6c2a9a08 100644
--- a/dG3D/src/dG3DFunctionSpace.h
+++ b/dG3D/src/dG3DFunctionSpace.h
@@ -40,12 +40,17 @@ class g3DLagrangeFunctionSpace : public ThreeDLagrangeFunctionSpace{
  protected :
   virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const
   {
-    int nk=ele->getNumVertices(); // return the number of vertices
     // negative type in mpi if the Dof are not located on this partition
     #if defined(HAVE_MPI) // small duplication to avoid multiple if in a loop
     if( (ele->getPartition() != 0) and (ele->getPartition() != Msg::GetCommRank() +1))
     {
-      for (int j=0;j<_ncomp;++j){
+      for (int j=0;j<_ncomp;++j)
+      {
+        int nk=ele->getNumVertices(); // return the number of vertices
+        if (withPrimaryShapeFunction(comp[j]))
+        {
+          nk = ele->getNumPrimaryVertices();
+        }
         for (int i=0;i<nk;++i){
           keys.push_back(Dof(ele->getVertex(i)->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],ele->getPartition())));
         }          
@@ -54,7 +59,13 @@ class g3DLagrangeFunctionSpace : public ThreeDLagrangeFunctionSpace{
     else
     #endif // HAVE_MPI
     {
-      for (int j=0;j<_ncomp;++j){
+      for (int j=0;j<_ncomp;++j)
+      {
+        int nk=ele->getNumVertices(); // return the number of vertices
+        if (withPrimaryShapeFunction(comp[j]))
+        {
+          nk = ele->getNumPrimaryVertices();
+        }
         for (int i=0;i<nk;++i){
           keys.push_back(Dof(ele->getVertex(i)->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],ele->getPartition())));
         }
@@ -84,20 +95,35 @@ class g3DLagrangeFunctionSpace : public ThreeDLagrangeFunctionSpace{
 class dG3DLagrangeFunctionSpace : public ThreeDLagrangeFunctionSpace{
  protected:
   virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const{
-    int nk=ele->getNumVertices(); // return the number of vertices
     #if defined(HAVE_MPI) // small duplication to avoid multiple if in a loop
     if( (ele->getPartition() != 0)and (ele->getPartition() != Msg::GetCommRank() +1))
     {
       for (int j=0;j<_ncomp;++j)
+      {
+        int nk=ele->getNumVertices(); // return the number of vertices
+        if (withPrimaryShapeFunction(comp[j]))
+        {
+          nk = ele->getNumPrimaryVertices();
+        }
         for (int i=0;i<nk;i++)
           keys.push_back(Dof(ele->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],i)));
+          
+      }
     }
     else
     #endif // HAVE_MPI
     {
       for (int j=0;j<_ncomp;++j)
+      {
+        int nk=ele->getNumVertices(); // return the number of vertices
+        if (withPrimaryShapeFunction(comp[j]))
+        {
+          nk = ele->getNumPrimaryVertices();
+        }
         for (int i=0;i<nk;i++)
           keys.push_back(Dof(ele->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],i)));
+          
+      }
     }
   }
  public :
@@ -164,21 +190,34 @@ class g3DhoDGFunctionSpace : public ThreeDLagrangeFunctionSpace{
  protected :
   virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const
   {
-    int nk=ele->getNumVertices(); // return the number of vertices
     // negative type in mpi if the Dof are not located on this partition
     #if defined(HAVE_MPI) // small duplication to avoid multiple if in a loop
     if( (ele->getPartition() != 0) and (ele->getPartition() != Msg::GetCommRank() +1))
     {
       for (int j=0;j<_ncomp;++j)
+      {
+        int nk=ele->getNumVertices(); // return the number of vertices
+        if (withPrimaryShapeFunction(comp[j]))
+        {
+          nk = ele->getNumPrimaryVertices();
+        }
         for (int i=0;i<nk;++i)
           keys.push_back(Dof(ele->getVertex(i)->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],ele->getPartition())));
+      }
     }
     else
     #endif // HAVE_MPI
     {
       for (int j=0;j<comp.size();++j)
+      {
+        int nk=ele->getNumVertices(); // return the number of vertices
+        if (withPrimaryShapeFunction(comp[j]))
+        {
+          nk = ele->getNumPrimaryVertices();
+        }
         for (int i=0;i<nk;++i)
           keys.push_back(Dof(ele->getVertex(i)->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],ele->getPartition())));
+      }
     }
   }
  public:
@@ -211,20 +250,33 @@ class dG3DhoDGFunctionSpace : public ThreeDLagrangeFunctionSpace{
 
  protected: // avoid duplication of the following functions with dG3DLagrangeFunctionSpace HOW ??
   virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const{
-    int nk=ele->getNumVertices(); // return the number of vertices
     #if defined(HAVE_MPI) // small duplication to avoid multiple if in a loop
     if( (ele->getPartition() != 0)and (ele->getPartition() != Msg::GetCommRank() +1))
     {
       for (int j=0;j<_ncomp;++j)
+      {
+        int nk=ele->getNumVertices(); // return the number of vertices
+        if (withPrimaryShapeFunction(comp[j]))
+        {
+          nk = ele->getNumPrimaryVertices();
+        }
         for (int i=0;i<nk;i++)
           keys.push_back(Dof(ele->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],i)));
+      }
     }
     else
     #endif // HAVE_MPI
     {
       for (int j=0;j<_ncomp;++j)
+      {
+        int nk=ele->getNumVertices(); // return the number of vertices
+        if (withPrimaryShapeFunction(comp[j]))
+        {
+          nk = ele->getNumPrimaryVertices();
+        }
         for (int i=0;i<nk;i++)
           keys.push_back(Dof(ele->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],i)));
+      }
     }
   }
 	
@@ -277,7 +329,6 @@ class g3DDirichletBoundaryConditionLagrangeFunctionSpace : public g3DLagrangeFun
 
   virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const
   {
-    int nk=ele->getNumVertices();
     // negative type in mpi if the Dof are not located on this partition
     // For BC on edge in the case of CG in // ele->getPartition() is equal to 0.
     // Therefore generate more keys to be sure to fix the dofs (There will be extra fixed dof but normally it doesn't matter)
@@ -286,14 +337,28 @@ class g3DDirichletBoundaryConditionLagrangeFunctionSpace : public g3DLagrangeFun
     {
       if(ele->getPartition()!=0){ // Sure than it will match
         for (int j=0;j<_ncomp;++j)
+        {
+          int nk=ele->getNumVertices(); // return the number of vertices
+          if (withPrimaryShapeFunction(comp[j]))
+          {
+            nk = ele->getNumPrimaryVertices();
+          }
           for (int i=0;i<nk;++i)
             keys.push_back(Dof(ele->getVertex(i)->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],ele->getPartition())));
+        }
       }
       else{ // match is not ensured --> generate keys for each partitions
         for(int p=0;p<=Msg::GetCommSize();p++){
           for (int j=0;j<_ncomp;++j)
+          {
+            int nk=ele->getNumVertices(); // return the number of vertices
+            if (withPrimaryShapeFunction(comp[j]))
+            {
+              nk = ele->getNumPrimaryVertices();
+            }
             for (int i=0;i<nk;++i)
               keys.push_back(Dof(ele->getVertex(i)->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],p)));
+          }
          }
       }
     }
@@ -302,19 +367,28 @@ class g3DDirichletBoundaryConditionLagrangeFunctionSpace : public g3DLagrangeFun
     {
 
       for (int j=0;j<_ncomp;++j)
+      {
+        int nk=ele->getNumVertices(); // return the number of vertices
+        if (withPrimaryShapeFunction(comp[j]))
+        {
+          nk = ele->getNumPrimaryVertices();
+        }
+        
         for (int i=0;i<nk;++i)
           keys.push_back(Dof(ele->getVertex(i)->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],ele->getPartition())));
 /*      if(ele->getPartition()==0) // Add the keys corresponding to this partition
-      {
-        for (int j=0;j<_ncomp;++j)
-          for (int i=0;i<nk;++i)
-            keys.push_back(Dof(ele->getVertex(i)->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],Msg::GetCommRank()+1)));
-        // and fix all the other partitions
-        for(int p=0;p<=Msg::GetCommSize();p++)
+        {
           for (int j=0;j<_ncomp;++j)
             for (int i=0;i<nk;++i)
-              keys.push_back(Dof(ele->getVertex(i)->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],p)));
-      }*/
+              keys.push_back(Dof(ele->getVertex(i)->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],Msg::GetCommRank()+1)));
+          // and fix all the other partitions
+          for(int p=0;p<=Msg::GetCommSize();p++)
+            for (int j=0;j<_ncomp;++j)
+              for (int i=0;i<nk;++i)
+                keys.push_back(Dof(ele->getVertex(i)->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],p)));
+        }*/
+        
+      }
     }
   }
 };
@@ -364,13 +438,19 @@ class g3DNeumannBoundaryConditionLagrangeFunctionSpace : public g3DLagrangeFunct
 
   virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const
   {
-     // For Neumann BC we sure that the BC is applied on element that are on this partition.
-     // Indeed Neumann BC are never applied on ghost element
-     int p = (_parallelMesh) ? Msg::GetCommRank()+1 : 0;
-     int nk=ele->getNumVertices();
-     for (int j=0;j<_ncomp;++j)
-       for (int i=0;i<nk;++i)
-         keys.push_back(Dof(ele->getVertex(i)->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],p)));
+    // For Neumann BC we sure that the BC is applied on element that are on this partition.
+    // Indeed Neumann BC are never applied on ghost element
+    int p = (_parallelMesh) ? Msg::GetCommRank()+1 : 0;
+    for (int j=0;j<_ncomp;++j)
+    {
+      int nk=ele->getNumVertices(); // return the number of vertices
+      if (withPrimaryShapeFunction(comp[j]))
+      {
+        nk = ele->getNumPrimaryVertices();
+      }
+      for (int i=0;i<nk;++i)
+        keys.push_back(Dof(ele->getVertex(i)->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],p)));
+    }
   }
 };
 
@@ -402,18 +482,32 @@ class g3DDirichletBoundaryConditionLagrangeFunctionSpaceGhost : public g3DDirich
 
   // be sure that the type is negative !!
   virtual void getKeys(MElement *ele, std::vector<Dof> &keys) const{
-    int nk=ele->getNumVertices();
     if(ele->getPartition()!=0){ // Sure than it will match
       for (int j=0;j<_ncomp;++j)
+      {
+        int nk=ele->getNumVertices(); // return the number of vertices
+        if (withPrimaryShapeFunction(comp[j]))
+        {
+          nk = ele->getNumPrimaryVertices();
+        }
         for (int i=0;i<nk;++i)
           keys.push_back(Dof(ele->getVertex(i)->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],ele->getPartition())));
+      }
     }
     else{ // match is not ensured --> generate keys for each partitions
-      for(int p=0;p<=Msg::GetCommSize();p++){
+      for(int p=0;p<=Msg::GetCommSize();p++)
+      {
         for (int j=0;j<_ncomp;++j)
+        {
+          int nk=ele->getNumVertices(); // return the number of vertices
+          if (withPrimaryShapeFunction(this->comp[j]))
+          {
+            nk = ele->getNumPrimaryVertices();
+          }
           for (int i=0;i<nk;++i)
             keys.push_back(Dof(ele->getVertex(i)->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],p)));
         }
+      }
     }
   }
 };
diff --git a/dG3D/src/dG3DTerms.cpp b/dG3D/src/dG3DTerms.cpp
index 331c5585e..e4588aedb 100644
--- a/dG3D/src/dG3DTerms.cpp
+++ b/dG3D/src/dG3DTerms.cpp
@@ -1599,9 +1599,6 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
   {
     // characteristic size
     const double hs = ie->getCharacteristicSize();
-    
-    MElement* em = ie->getElem(0);
-    MElement* ep = ie->getElem(1);
 
     // get value at gauss's point
     const AllIPState::ipstateElementContainer *vips = _ipf->getAips()->getIPstate(ele->getNum());
@@ -1609,6 +1606,9 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
     IntPt *GPm; IntPt *GPp;
     _interQuad->getIntPoints(ie,GP,&GPm,&GPp);
     
+    MElement* em = ie->getElem(0);
+    MElement* ep = ie->getElem(1);
+    
     /*
      * DISPLACEMENT FIELD
      * */
@@ -1647,6 +1647,10 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
         const FractureCohesive3DIPVariable *ipvwf = static_cast<const FractureCohesive3DIPVariable*>(ipvm); // broken via minus (OK broken on both sides)
         broken = ipvwf->isbroken();
       }
+      
+      int nbFFm = _minusSpace->getNumShapeFunctions(em,0);
+      int nbFFp = _plusSpace->getNumShapeFunctions(ep,0); // same for 0, 1, 2
+
 
       if(!broken)
       {
@@ -1687,7 +1691,17 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
             }
           }
         }
-        
+        // Assembly consistency + stability (if not broken)
+        for(int j=0;j<nbFFm;j++){
+          for(int k=0;k<3;k++){
+            m(j+k*nbFFm) -= (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsm[j+0*nbFFm]*wJ);
+          }
+        }
+        for(int j=0;j<nbFFp;j++){
+          for(int k=0;k<3;k++){
+            m(j+k*nbFFp+nbdofm) += (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsp[j+0*nbFFp]*wJ);
+          }
+        }
         // compatibility membrane (4 terms to assembly)
         static STensor3 HmJumpN;
         static STensor3 HpJumpN;
@@ -1708,39 +1722,24 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
             }
           }
         }
-        
-        // Assembly consistency + stability (if not broken)
-        for(int k=0;k<3;k++)
+        // Assembly (loop on shape function)
+        for(int j=0;j<nbFFm;j++)
         {
-          // Assembly consistency + stability (if not broken)
-          int nbFFmRow = _minusSpace->getNumShapeFunctions(em,k);
-          int nbFFmTotalLastRow = _minusSpace->getShapeFunctionsIndex(em,k);
-          //
-          int nbFFpRow = _plusSpace->getNumShapeFunctions(ep,k);
-          int nbFFpTotalLastRow = _plusSpace->getShapeFunctionsIndex(ep,k);
-          //
-          for(int j=0;j<nbFFmRow;j++)
-          {
-            m(j+nbFFmTotalLastRow) -= (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsm[j+nbFFmTotalLastRow]*wJ);
-          }
-          for(int j=0;j<nbFFpRow;j++)
-          {
-            m(j+nbFFpTotalLastRow+nbdofm) += (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsp[j+nbFFpTotalLastRow]*wJ);
-          }
-        
-          // Assembly symetrical term
-          for(int j=0;j<nbFFmRow;j++)
+          for(int k=0;k<3;k++)
           {
             for(int l=0;l<3;l++)
             {
-              m(j+nbFFmTotalLastRow) += (HmJumpN(k,l)*Gradsm[j+nbFFmTotalLastRow][l])*(wJ/2.);
+              m(j+k*nbFFm) += (HmJumpN(k,l)*Gradsm[j+0*nbFFm][l])*(wJ/2.);
             }
           }
-          for(int j=0;j<nbFFpRow;j++)
+        }
+        for(int j=0;j<nbFFm;j++)
+        {
+          for(int k=0;k<3;k++)
           {
             for(int l=0;l<3;l++)
             {
-              m(j+nbFFpTotalLastRow+nbdofm) += (HpJumpN(k,l)*Gradsp[j+nbFFpTotalLastRow][l])*(wJ/2.);
+              m(j+k*nbFFp+nbdofm) += (HpJumpN(k,l)*Gradsp[j+0*nbFFp][l])*(wJ/2.);
             }
           }
         }
@@ -1758,22 +1757,15 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
         const std::vector<TensorialTraits<double>::ValType> &Valsm = ipvm->f(_minusSpace,ie->getElem(0),GPm[i]);
         const std::vector<TensorialTraits<double>::ValType> &Valsp = ipvp->f(_plusSpace,ie->getElem(1),GPp[i]);
 
-        // Assembly consistency (broken)
-        for(int k=0;k<3;k++)
-        {
-          int nbFFmRow = _minusSpace->getNumShapeFunctions(em,k);
-          int nbFFmTotalLastRow = _minusSpace->getShapeFunctionsIndex(em,k);
-          //
-          int nbFFpRow = _plusSpace->getNumShapeFunctions(ep,k);
-          int nbFFpTotalLastRow = _plusSpace->getShapeFunctionsIndex(ep,k);
-          
-          for(int j=0;j<nbFFmRow;j++)
-          {
-            m(j+nbFFmTotalLastRow) -= interfaceForce[k]*(Valsm[j+nbFFmTotalLastRow]*wJ);
+        // Assembly consistency + stability (if not broken)
+        for(int j=0;j<nbFFm;j++){
+          for(int k=0;k<3;k++){
+            m(j+k*nbFFm) -= interfaceForce[k]*(Valsm[j+0*nbFFm]*wJ);
           }
-          for(int j=0;j<nbFFpRow;j++)
-          {
-            m(j+nbFFpTotalLastRow+nbdofm) += interfaceForce[k]*(Valsp[j+nbFFpTotalLastRow]*wJ);
+        }
+        for(int j=0;j<nbFFp;j++){
+          for(int k=0;k<3;k++){
+            m(j+k*nbFFp+nbdofm) += interfaceForce[k]*(Valsp[j+0*nbFFp]*wJ);
           }
         }
       }
@@ -1837,13 +1829,17 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
  
           for (int nlk = 0; nlk< ipvp->getNumberNonLocalVariable(); nlk++)
           {
+            int nbFFmNonlocal = _minusSpace->getNumShapeFunctions(em,3+nlk);
+            int nbFFmTotalLastNonlocal = _minusSpace->getShapeFunctionsIndex(em,3+nlk);
+            int nbFFpNonlocal = _plusSpace->getNumShapeFunctions(ep,3+nlk); 
+            int nbFFpTotalLastNonlocal = _plusSpace->getShapeFunctionsIndex(ep,3+nlk);
+            
             double epljump = ipvp->getConstRefToNonLocalJump()(nlk);
-            if (_incrementNonlocalBased)
-            {
+            if (_incrementNonlocalBased){
               epljump -= ipvpprev->getConstRefToNonLocalJump()(nlk);
             }
-            const STensor3  *cgm = &(ipvm->getConstRefToCharacteristicLengthMatrix(nlk));        
-            const STensor3  *cgp = &(ipvp->getConstRefToCharacteristicLengthMatrix(nlk));    
+            const STensor3  *cgm = &(ipvm->getConstRefToCharacteristicLengthMatrix(nlk));           // by Wu Ling
+            const STensor3  *cgp = &(ipvp->getConstRefToCharacteristicLengthMatrix(nlk));           // by Wu Ling
             
             static SVector3 gradm, gradp;
             gradm = ipvm->getConstRefToGradNonLocalVariable()[nlk];
@@ -1886,24 +1882,15 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
               {
                 NMeanCgJumpNBetasc += meanCg(l,n)*epljump*nu(n)*nbetahs*nu(l);
               }
-            };
-            
-            //
-            int nbFFmRow = _minusSpace->getNumShapeFunctions(em,3+nlk);
-            int nbFFmTotalLastRow = _minusSpace->getShapeFunctionsIndex(em,3+nlk);
-            //
-            int nbFFpRow = _plusSpace->getNumShapeFunctions(ep,3+nlk);
-            int nbFFpTotalLastRow = _plusSpace->getShapeFunctionsIndex(ep,3+nlk);
-            //
-            
+            }
             // Assembly consistency + stability (if not broken)
-            for(int j=0;j<nbFFmRow;j++)
+            for(int j=0;j<nbFFmNonlocal;j++)
             {
-              m(j+nbFFmTotalLastRow) -= (meanCgGradN+NMeanCgJumpNBetasc)*(Valsm[j+nbFFmTotalLastRow]*wJ*getNonLocalEqRatio());
+              m(j+nbFFmTotalLastNonlocal) -= (meanCgGradN+NMeanCgJumpNBetasc)*(Valsm[j+nbFFmTotalLastNonlocal]*wJ*getNonLocalEqRatio());
             }
-            for(int j=0;j<nbFFpRow;j++)
+            for(int j=0;j<nbFFpNonlocal;j++)
             {
-              m(j+nbFFpTotalLastRow+nbdofm) += (meanCgGradN+NMeanCgJumpNBetasc)*(Valsp[j+nbFFpTotalLastRow]*wJ*getNonLocalEqRatio());
+              m(j+nbFFpTotalLastNonlocal+nbdofm) += (meanCgGradN+NMeanCgJumpNBetasc)*(Valsp[j+nbFFpTotalLastNonlocal]*wJ*getNonLocalEqRatio());
             }
             // compatibility membrane (4 terms to assembly)
             SVector3 CgmJumpN;
@@ -1920,18 +1907,18 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
               }
             }
             // Assembly (loop on shape function)
-            for(int j=0;j<nbFFmRow;j++)
+            for(int j=0;j<nbFFmNonlocal;j++)
             {
               for(int l=0;l<3;l++)
               {
-                m(j+nbFFmTotalLastRow) += (CgmJumpN(l)*Gradsm[j+nbFFmTotalLastRow][l])*(wJ*getNonLocalEqRatio()/2.);
+                m(j+nbFFmTotalLastNonlocal) += (CgmJumpN(l)*Gradsm[j+nbFFmTotalLastNonlocal][l])*(wJ*getNonLocalEqRatio()/2.);
               }
             }
-            for(int j=0;j<nbFFpRow;j++)
+            for(int j=0;j<nbFFpNonlocal;j++)
             {
               for(int l=0;l<3;l++)
               {
-                m(j+nbFFpTotalLastRow+nbdofm) += (CgpJumpN(l)*Gradsp[j+nbFFpTotalLastRow][l])*(wJ*getNonLocalEqRatio()/2.);
+                m(j+nbFFpTotalLastNonlocal+nbdofm) += (CgpJumpN(l)*Gradsp[j+nbFFpTotalLastNonlocal][l])*(wJ*getNonLocalEqRatio()/2.);
               }
             }
           }
@@ -2002,34 +1989,30 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
               Msg::Error("Your plus and minus material laws do not use the same number of constitutive extra dof variables dG3DForceInter::get");
           for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
-            const double nbetahs = getConstitutiveExtraDofDiffusionStabilityParameter()/hs;
-            //
             int indexField=3+getNumNonLocalVariable()+extraDOFField;
-            //
-            int nbFFmRow = _minusSpace->getNumShapeFunctions(em,indexField);
-            int nbFFmTotalLastRow = _minusSpace->getShapeFunctionsIndex(em,indexField);
-            //
-            int nbFFpRow = _plusSpace->getNumShapeFunctions(ep,indexField);
-            int nbFFpTotalLastRow = _plusSpace->getShapeFunctionsIndex(ep,indexField);
-            //
+            int nbFFmExtraDof = _minusSpace->getNumShapeFunctions(em,indexField);
+            int nbFFmTotalLastExtraDof = _minusSpace->getShapeFunctionsIndex(em,indexField);
+            int nbFFpExtraDof = _plusSpace->getNumShapeFunctions(ep,indexField); 
+            int nbFFpTotalLastExtraDof = _plusSpace->getShapeFunctionsIndex(ep,indexField);
+            
             for (int extraDOFField2 = 0; extraDOFField2< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField2++)
             {
-              
+              const double nbetahs = getConstitutiveExtraDofDiffusionStabilityParameter()/hs;
               double fieldJump;
               double fieldp=0.;
               double fieldm=0.;
 
               if(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==1)
               {
-                fieldJump = ipvp->getConstRefToFieldJump()(extraDOFField);
-                fieldp = ipvp->getConstRefToField(extraDOFField);
-                fieldm = ipvm->getConstRefToField(extraDOFField);
+               fieldJump = ipvp->getConstRefToFieldJump()(extraDOFField);
+               fieldp = ipvp->getConstRefToField(extraDOFField);
+               fieldm = ipvm->getConstRefToField(extraDOFField);
               }
               else
               {
-                fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField2);
-                fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
-                fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
+               fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField2);
+               fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
+               fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
               }
 
               static STensor3  k0m;
@@ -2068,27 +2051,27 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
                   NMeank0JumpNBetasc += meank(l,n)*fieldJump*nu(n)*nbetahs*nu(l);
                 }
               }
-
+              
               if(extraDOFField==extraDOFField2)
               {
-                for(int j=0;j<nbFFmRow;j++)
+                for(int j=0;j<nbFFmExtraDof;j++)
                 {
-                  m(j+nbFFmTotalLastRow) -= (meantflux+NMeank0JumpNBetasc)*(Valsm[j+nbFFmTotalLastRow]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  m(j+nbFFmTotalLastExtraDof) -= (meantflux+NMeank0JumpNBetasc)*(Valsm[j+nbFFmTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 }
-                for(int j=0;j<nbFFpRow;j++)
+                for(int j=0;j<nbFFpExtraDof;j++)
                 {
-                  m(j+nbFFpTotalLastRow+nbdofm) += ( meantflux+NMeank0JumpNBetasc)*(Valsp[j+nbFFpTotalLastRow]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  m(j+nbFFpTotalLastExtraDof+nbdofm) += ( meantflux+NMeank0JumpNBetasc)*(Valsp[j+nbFFpTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 }
               }
               else
               {
-                for(int j=0;j<nbFFmRow;j++)
+                for(int j=0;j<nbFFmExtraDof;j++)
                 {
-                  m(j+nbFFmTotalLastRow) -= (NMeank0JumpNBetasc)*(Valsm[j+nbFFmTotalLastRow]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  m(j+nbFFmTotalLastExtraDof) -= (NMeank0JumpNBetasc)*(Valsm[j+nbFFmTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 }
-                for(int j=0;j<nbFFpRow;j++)
+                for(int j=0;j<nbFFpExtraDof;j++)
                 {
-                  m(j+nbFFpTotalLastRow+nbdofm) += (NMeank0JumpNBetasc)*(Valsp[j+nbFFpTotalLastRow]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  m(j+nbFFpTotalLastExtraDof+nbdofm) += (NMeank0JumpNBetasc)*(Valsp[j+nbFFpTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 }
               }
       
@@ -2105,18 +2088,18 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
                 }
               }
               // Assembly (loop on shape function)
-              for(int j=0;j<nbFFmRow;j++)
+              for(int j=0;j<nbFFmExtraDof;j++)
               {
                 for(int l=0;l<3;l++)
                 {
-                  m(j+nbFFmTotalLastRow) += ( k0mJumpN(l)*Gradsm[j+nbFFmTotalLastRow][l])*(wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.);
+                  m(j+nbFFmTotalLastExtraDof) += ( k0mJumpN(l)*Gradsm[j+nbFFmTotalLastExtraDof][l])*(wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.);
                 }
               }
-              for(int j=0;j<nbFFpRow;j++)
+              for(int j=0;j<nbFFpExtraDof;j++)
               {
                 for(int l=0;l<3;l++)
                 {
-                  m(j+nbFFpTotalLastRow+nbdofm) += ( k0pJumpN(l)*Gradsp[j+nbFFpTotalLastRow][l])*(wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.);
+                  m(j+nbFFpTotalLastExtraDof+nbdofm) += ( k0pJumpN(l)*Gradsp[j+nbFFpTotalLastExtraDof][l])*(wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.);
                 }
               }
             }
@@ -2132,12 +2115,10 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
           for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
             int indexField=3+getNumNonLocalVariable()+extraDOFField;
-            //
-            int nbFFmRow = _minusSpace->getNumShapeFunctions(em,indexField);
-            int nbFFmTotalLastRow = _minusSpace->getShapeFunctionsIndex(em,indexField);
-            //
-            int nbFFpRow = _plusSpace->getNumShapeFunctions(ep,indexField);
-            int nbFFpTotalLastRow = _plusSpace->getShapeFunctionsIndex(ep,indexField);
+            int nbFFmExtraDof = _minusSpace->getNumShapeFunctions(em,indexField);
+            int nbFFmTotalLastExtraDof = _minusSpace->getShapeFunctionsIndex(em,indexField);
+            int nbFFpExtraDof = _plusSpace->getNumShapeFunctions(ep,indexField); 
+            int nbFFpTotalLastExtraDof = _plusSpace->getShapeFunctionsIndex(ep,indexField);
             
             if(extraDOFField==0)
             {
@@ -2147,15 +2128,15 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
 
               if(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==1)
               {
-                fieldJump = ipvp->getConstRefToFieldJump()(extraDOFField);
-                fieldp = ipvp->getConstRefToField(extraDOFField);
-                fieldm = ipvm->getConstRefToField(extraDOFField);
+               fieldJump = ipvp->getConstRefToFieldJump()(extraDOFField);
+               fieldp = ipvp->getConstRefToField(extraDOFField);
+               fieldm = ipvm->getConstRefToField(extraDOFField);
               }
               else
               {
-                fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField);
-                fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
-                fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
+               fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField);
+               fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
+               fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
               }
 
               static STensor3  Stiff_alphadialitationm;
@@ -2192,13 +2173,11 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
               //new
             
               double gamma=0.;
-              for(int j=0;j<nbFFmRow;j++)
-              {
-                m(j+nbFFmTotalLastRow) += gamma*( Stiff_alphadialitationm_JumpN*Valsm[j+nbFFmTotalLastRow])*(wJ/2.)*(-1.);
+              for(int j=0;j<nbFFmExtraDof;j++){
+                m(j+nbFFmTotalLastExtraDof) += gamma*( Stiff_alphadialitationm_JumpN*Valsm[j+nbFFmTotalLastExtraDof])*(wJ/2.)*(-1.);
               }
-              for(int j=0;j<nbFFpRow;j++)
-              {
-                m(j+nbFFpTotalLastRow+nbdofm) += gamma*( Stiff_alphadialitationp_JumpN*Valsp[j+nbFFpTotalLastRow])*(wJ/2.)*(-1.);
+              for(int j=0;j<nbFFpExtraDof;j++){
+                m(j+nbFFpTotalLastExtraDof) += gamma*( Stiff_alphadialitationp_JumpN*Valsp[j+nbFFpTotalLastExtraDof])*(wJ/2.)*(-1.);
               }
             }
           }
@@ -2208,7 +2187,7 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
     }
   }
 //m.print("Force inter");
-}
+};
 
 void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double> &stiff) const
 {
-- 
GitLab


From 08d2330fb6584134ac33d0aafcc23aa843a2e5ae Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Mon, 1 Jun 2020 21:28:34 +0200
Subject: [PATCH 09/19] bug

---
 dG3D/src/dG3DDomain.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/dG3D/src/dG3DDomain.cpp b/dG3D/src/dG3DDomain.cpp
index af7c18442..6fc926f59 100644
--- a/dG3D/src/dG3DDomain.cpp
+++ b/dG3D/src/dG3DDomain.cpp
@@ -1784,7 +1784,7 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
           nonlocalVarp = 0.;
           SVector3& gradNonlocalVarp = ipvp->getRefToGradNonLocalVariable()[nlp];
           STensorOperation::zero(gradNonlocalVarp);
-          int nbFFp = _spaceminus->getNumShapeFunctions(ep,3+nlp);
+          int nbFFp = _spaceplus->getNumShapeFunctions(ep,3+nlp);
           int nbFFpTotalLast = _spaceplus->getShapeFunctionsIndex(ep,3+nlp);
           for (int i = 0; i < nbFFp; i++)
           {
@@ -1807,8 +1807,6 @@ void dG3DDomain::computeStrain(AllIPState *aips,MInterfaceElement *ie, IntPt *GP
           double& epsjump= ipvm->getRefToNonLocalJump()(nl);
           epsjump = computeJumpField(Valm,nbFFmTotalLast,nbFFm,Valp,nbFFmTotalLast,nbFFp,dispm,dispp);
           ipvp->getRefToNonLocalJump()(nl) = epsjump;
-          nbFFmTotalLast += nbFFm;
-          nbFFpTotalLast += nbFFp;
         }
       }
       
-- 
GitLab


From 4fb6d1c2db1541dcf8ff5185b6a5b190377917bd Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Mon, 1 Jun 2020 22:41:47 +0200
Subject: [PATCH 10/19] correct number of shape functions

---
 NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
index b1604720a..53ee05c1c 100644
--- a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
+++ b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
@@ -125,7 +125,7 @@ class VertexBasedLagrangeFunctionSpace : public nlsFunctionSpace<double>
     virtual int getNumKeys(MElement *ele)  const 
     {
       if (ele->getParent()) ele = ele->getParent();
-      return getNumComp()*ele->getNumVertices();
+      return getTotalNumShapeFunctions(ele);
     };
     virtual void getKeys(MElement *ele, std::vector<Dof> &keys) const
     {
-- 
GitLab


From 9eae98219ea3ecfff8ebca59de1b9d064eb0add1 Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Mon, 1 Jun 2020 23:27:24 +0200
Subject: [PATCH 11/19] missing

---
 dG3D/src/dG3DTerms.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/dG3D/src/dG3DTerms.cpp b/dG3D/src/dG3DTerms.cpp
index e4588aedb..832ab8db9 100644
--- a/dG3D/src/dG3DTerms.cpp
+++ b/dG3D/src/dG3DTerms.cpp
@@ -1694,12 +1694,12 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
         // Assembly consistency + stability (if not broken)
         for(int j=0;j<nbFFm;j++){
           for(int k=0;k<3;k++){
-            m(j+k*nbFFm) -= (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsm[j+0*nbFFm]*wJ);
+            m(j+k*nbFFm) -= (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsm[j+k*nbFFm]*wJ);
           }
         }
         for(int j=0;j<nbFFp;j++){
           for(int k=0;k<3;k++){
-            m(j+k*nbFFp+nbdofm) += (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsp[j+0*nbFFp]*wJ);
+            m(j+k*nbFFp+nbdofm) += (meanPN[k]+NMeanHJumpNBetasc[k])*(Valsp[j+k*nbFFp]*wJ);
           }
         }
         // compatibility membrane (4 terms to assembly)
@@ -1729,7 +1729,7 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
           {
             for(int l=0;l<3;l++)
             {
-              m(j+k*nbFFm) += (HmJumpN(k,l)*Gradsm[j+0*nbFFm][l])*(wJ/2.);
+              m(j+k*nbFFm) += (HmJumpN(k,l)*Gradsm[j+k*nbFFm][l])*(wJ/2.);
             }
           }
         }
@@ -1739,7 +1739,7 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
           {
             for(int l=0;l<3;l++)
             {
-              m(j+k*nbFFp+nbdofm) += (HpJumpN(k,l)*Gradsp[j+0*nbFFp][l])*(wJ/2.);
+              m(j+k*nbFFp+nbdofm) += (HpJumpN(k,l)*Gradsp[j+k*nbFFp][l])*(wJ/2.);
             }
           }
         }
@@ -1760,12 +1760,12 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
         // Assembly consistency + stability (if not broken)
         for(int j=0;j<nbFFm;j++){
           for(int k=0;k<3;k++){
-            m(j+k*nbFFm) -= interfaceForce[k]*(Valsm[j+0*nbFFm]*wJ);
+            m(j+k*nbFFm) -= interfaceForce[k]*(Valsm[j+k*nbFFm]*wJ);
           }
         }
         for(int j=0;j<nbFFp;j++){
           for(int k=0;k<3;k++){
-            m(j+k*nbFFp+nbdofm) += interfaceForce[k]*(Valsp[j+0*nbFFp]*wJ);
+            m(j+k*nbFFp+nbdofm) += interfaceForce[k]*(Valsp[j+k*nbFFp]*wJ);
           }
         }
       }
@@ -2177,7 +2177,7 @@ void dG3DForceInter::get(MElement *ele, int npts, IntPt *GP, fullVector<double>
                 m(j+nbFFmTotalLastExtraDof) += gamma*( Stiff_alphadialitationm_JumpN*Valsm[j+nbFFmTotalLastExtraDof])*(wJ/2.)*(-1.);
               }
               for(int j=0;j<nbFFpExtraDof;j++){
-                m(j+nbFFpTotalLastExtraDof) += gamma*( Stiff_alphadialitationp_JumpN*Valsp[j+nbFFpTotalLastExtraDof])*(wJ/2.)*(-1.);
+                m(j+nbFFpTotalLastExtraDof+nbdofm) += gamma*( Stiff_alphadialitationp_JumpN*Valsp[j+nbFFpTotalLastExtraDof])*(wJ/2.)*(-1.);
               }
             }
           }
-- 
GitLab


From 692e75de1ef98b1ce0c97ae5dc3696e81c699031 Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Tue, 2 Jun 2020 09:22:02 +0200
Subject: [PATCH 12/19] well code structure

---
 dG3D/src/dG3DTerms.cpp | 1193 ++++++++++++++++++++++++++--------------
 1 file changed, 775 insertions(+), 418 deletions(-)

diff --git a/dG3D/src/dG3DTerms.cpp b/dG3D/src/dG3DTerms.cpp
index 832ab8db9..6cbaa0ea2 100644
--- a/dG3D/src/dG3DTerms.cpp
+++ b/dG3D/src/dG3DTerms.cpp
@@ -3425,383 +3425,808 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               Msg::Error("Your plus and minus material laws do not use the same number of constitutive extra dof variables dG3DStiffnessInter::get");
           
           // EXTRADOF- ExtraDof
-          for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
+          const double nbetahs = getConstitutiveExtraDofDiffusionStabilityParameter()/hs;
+          if (getNumConstitutiveExtraDofDiffusionVariable() == 1)// thermomec
           {
-            const double nbetahs = getConstitutiveExtraDofDiffusionStabilityParameter()/hs;
-            double fieldJump=0.; double fieldJump2=0.;
-            double fieldp=0.;double fieldm=0.; double dfieldJumpdFieldp=0.; double dfieldJumpdFieldm=0.;
-            double dfieldJumpdField2p=0.; double dfieldJumpdField2m=0.; double oneOverFieldJump=0.;
-            double dFielddEnergyConjugatedFieldp=0.; double dFielddEnergyConjugatedFieldm=0.; 
-            double dFielddEnergyConjugatedField2p=0.; double dFielddEnergyConjugatedField2m=0.;
-            static SVector3 dGradFielddEnergyConjugatedFieldp, dGradFielddEnergyConjugatedFieldm, dGradFielddEnergyConjugatedField2p, dGradFielddEnergyConjugatedField2m;
-            static STensor3 dGradFielddGradEnergyConjugatedFieldp, dGradFielddGradEnergyConjugatedFieldm, dGradFielddGradEnergyConjugatedField2p, dGradFielddGradEnergyConjugatedField2m;
-            static STensor3 dk0mdFieldm, dk0pdFieldp, dk0mdField2m, dk0pdField2p, dk0mdField_auxm, dk0pdField_auxp, dk0mdField_aux2m, dk0pdField_aux2p;
+            double fieldJump = ipvp->getConstRefToFieldJump()(0);
+            double fieldp = ipvp->getConstRefToField(0);
+            double fieldm = ipvm->getConstRefToField(0);
+            double dfieldJumpdFieldp = 1.;
+            double dfieldJumpdFieldm = -1.;
+            double oneOverFieldJump = ipvp->getConstRefToOneOverFieldJump()(0);
+            static STensor3 dk0mdFieldm, dk0pdFieldp;
+            STensorOperation::zero(dk0mdFieldm);
+            STensorOperation::zero(dk0pdFieldp);
+            if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
+            {
+              fieldJump=ipvp->getConstRefToOneOverFieldJump()(0);
+            }
+            
+           
             
-            if(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==1)
+            const STensor3  *dqdGradFieldm = &(ipvm->getConstRefTodFluxdGradField()[0][0]);
+            const STensor3  *dqdGradFieldp = &(ipvp->getConstRefTodFluxdGradField()[0][0]);
+            const SVector3  *dqdFieldm = &(ipvm->getConstRefTodFluxdField()[0][0]);
+            const SVector3  *dqdFieldp = &(ipvp->getConstRefTodFluxdField()[0][0]);
+            
+            static STensor3  k0m, k0p;
+            k0m = *(ipvm->getConstRefToLinearK()[0][0]);
+            k0p = *(ipvp->getConstRefToLinearK()[0][0]);
+            if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
             {
-              fieldJump = ipvp->getConstRefToFieldJump()(extraDOFField);
-              fieldp = ipvp->getConstRefToField(extraDOFField);
-              fieldm = ipvm->getConstRefToField(extraDOFField);
-              dfieldJumpdFieldp = 1.;
-              dfieldJumpdFieldm = -1.;
-              oneOverFieldJump = ipvp->getConstRefToOneOverFieldJump()(extraDOFField);
-              STensorOperation::zero(dk0mdFieldm);
-              STensorOperation::zero(dk0pdFieldp);
-              if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
+              k0m*=(-1.)*fieldm*fieldm;
+              k0p*=(-1.)*fieldp*fieldp;
+              dk0mdFieldm=k0m;
+              dk0mdFieldm*=(1.)*2./fieldm;//the - is removed
+              dk0pdFieldp=k0p;
+              dk0pdFieldp*=(1.)*2./fieldp;//the - is removed
+            }
+            
+            int indexField= 3+getNumNonLocalVariable();
+            int indexField2 = 3+getNumNonLocalVariable();
+            for(int j=0;j<nbFFm;j++)
+            {
+              for(int l=0;l<nbFFm;l++)
+              {
+                for(int p = 0; p< 3; p++)
+                {
+                  stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= dqdFieldm->operator()(p)*(Valsm[l+indexField2*nbFFm]*
+                                                        Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                  for(int q = 0; q< 3; q++)
+                  {
+                    stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= dqdGradFieldm->operator()(q,p)*
+                                     (Gradsm[l+indexField2*nbFFm][p]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                  }
+                }
+              }
+              for(int l=0;l<nbFFp;l++)
               {
-                fieldJump=ipvp->getConstRefToOneOverFieldJump()(extraDOFField);
+                for(int p = 0; p< 3; p++)
+                {
+                  stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= dqdFieldp->operator()(p)*
+                               (Valsp[l+indexField2*nbFFp]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+
+                  for(int q = 0; q< 3; q++)
+                  {
+                    stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= dqdGradFieldp->operator()(q,p)*
+                                                 (Gradsp[l+indexField2*nbFFp][p]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+
+                  }
+                }
               }
             }
-            else
+            for(int j=0;j<nbFFp;j++)
             {
-              fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
-              fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
-             
-              if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
+              for(int l=0;l<nbFFm;l++)
               {
-                int extraDOFField_aux=0;
-                if((extraDOFField+1)< ipvp->getNumConstitutiveExtraDofDiffusionVariable()) extraDOFField_aux=extraDOFField+1;
-                else extraDOFField_aux=extraDOFField-1;  
-
-                dFielddEnergyConjugatedFieldp = ipvp->getConstRefTodFielddEnergyConjugatedField()[extraDOFField][extraDOFField];
-                dFielddEnergyConjugatedFieldm = ipvm->getConstRefTodFielddEnergyConjugatedField()[extraDOFField][extraDOFField]; 
-                dFielddEnergyConjugatedField2p = ipvp->getConstRefTodFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField];
-                dFielddEnergyConjugatedField2m = ipvm->getConstRefTodFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField];  
+                for(int p = 0; p< 3; p++)
+                {
+                  stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += dqdFieldm->operator()(p)*(Valsm[l+indexField2*nbFFm]*
+                                Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                  for(int q = 0; q< 3; q++)
+                  {
+
+                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += dqdGradFieldm->operator()(q,p)*
+                                    (Gradsm[l+indexField2*nbFFm][p]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                  }
+                }
+              }
+              for(int l=0;l<nbFFp;l++)
+              {
+                for(int p = 0; p< 3; p++)
+                {
+                  stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += dqdFieldp->operator()(p)*
+                              (Valsp[l+indexField2*nbFFp]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                  for(int q = 0; q< 3; q++)
+                  {
+
+                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += dqdGradFieldp->operator()(q,p)*(Gradsp[l+indexField2*nbFFp][p]*
+                                Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                  }
+                }
               }
             }
             
-            int indexField=3+getNumNonLocalVariable()+extraDOFField;
-            for (int extraDOFField2 = 0; extraDOFField2< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField2++)
-            {
-              const STensor3  *dqdGradFieldm = &(ipvm->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField2]);
-              const STensor3  *dqdGradFieldp = &(ipvp->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField2]);
-              const SVector3  *dqdFieldm = &(ipvm->getConstRefTodFluxdField()[extraDOFField][extraDOFField2]);
-              const SVector3  *dqdFieldp = &(ipvp->getConstRefTodFluxdField()[extraDOFField][extraDOFField2]);
+            //
+            // Stability  N \mean{k0} (N)
+            double NMeankNBetasc=0.;
+            double dNMeankNBetascdFieldp=0.;
+            double dNMeankNBetascdFieldm=0.;
 
-              static STensor3  k0m, k0p, k02m, k02p, dqdGradField2m, dqdGradField2p;
-              static SVector3 dqdField2m, dqdField2p;
-              static STensor43 dk0mdFm, dk0pdFp;
-              STensorOperation::zero(dk0mdFm);STensorOperation::zero(dk0pdFp);
+            for(int l = 0; l <3; l++)
+            {
+              for(int n = 0; n <3; n++)
+              {
+                NMeankNBetasc += (k0p(l,n)+k0m(l,n))*nu(n)*nbetahs*nu(l)/2.;
+                dNMeankNBetascdFieldp+=dk0pdFieldp(l,n)*nu(n)*nbetahs*nu(l)/2.;
+                dNMeankNBetascdFieldm+=dk0mdFieldm(l,n)*nu(n)*nbetahs*nu(l)/2.;
+              }
+            }
 
-              k0m = *(ipvm->getConstRefToLinearK()[extraDOFField][extraDOFField2]);
-              k0p = *(ipvp->getConstRefToLinearK()[extraDOFField][extraDOFField2]);
-              if(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==1) //thermomec
+            // Assembly stability (if not broken)
+            for(int j=0;j<nbFFm;j++)
+            {
+              for(int l=0;l<nbFFm;l++)
+              {
+                stiff(j+indexField*nbFFm,l+indexField*nbFFm) -= dfieldJumpdFieldm*NMeankNBetasc*
+                                      (Valsm[j+indexField*nbFFm]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
+                  stiff(j+indexField*nbFFm,l+indexField*nbFFm) -= oneOverFieldJump*dNMeankNBetascdFieldm*
+                                      (Valsm[j+indexField*nbFFm]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+              }
+              for(int l=0;l<nbFFp;l++)
+              {
+                stiff(j+indexField*nbFFm,l+indexField*nbFFp+nbdofm) -= dfieldJumpdFieldp*NMeankNBetasc*
+                                      (Valsm[j+indexField*nbFFm]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
+                  stiff(j+indexField*nbFFm,l+indexField*nbFFp+nbdofm) -= oneOverFieldJump*dNMeankNBetascdFieldp*
+                                                  (Valsm[j+indexField*nbFFm]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+              }
+            }
+            for(int j=0;j<nbFFp;j++)
+            {
+              for(int l=0;l<nbFFm;l++)
               {
+                stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFm) += dfieldJumpdFieldm*NMeankNBetasc*
+                                                  (Valsp[j+indexField*nbFFp]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
+                  stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFm) += oneOverFieldJump*dNMeankNBetascdFieldm*
+                                                  (Valsp[j+indexField*nbFFp]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+              }
+              for(int l=0;l<nbFFp;l++)
+              {
+                stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += dfieldJumpdFieldp*NMeankNBetasc*
+                                                  (Valsp[j+indexField*nbFFp]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
+                  stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += oneOverFieldJump*dNMeankNBetascdFieldp*
+                                                  (Valsp[j+indexField*nbFFp]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+              }
+            }
+            // compatibility
+            // Assembly (loop on shape function)
+            for(int j=0;j<nbFFm;j++)
+            {
+              for(int l=0;l<nbFFm;l++)
+              {
+                for(int p =0; p < 3; p++)
                 {
-                  k0m*=(-1.)*fieldm*fieldm;
-                  k0p*=(-1.)*fieldp*fieldp;
-                  dk0mdFieldm=k0m;
-                  dk0mdFieldm*=(1.)*2./fieldm;//the - is removed
-                  dk0pdFieldp=k0p;
-                  dk0pdFieldp*=(1.)*2./fieldp;//the - is removed
+                  for(int q =0; q < 3; q++)
+                  {
+                    stiff(j+indexField*nbFFm,l+indexField*nbFFm) += dfieldJumpdFieldm*(k0m(p,q)*
+                                                  Gradsm[j+indexField*nbFFm][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+indexField*nbFFm]);
+                    if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
+                      stiff(j+indexField*nbFFm,l+indexField*nbFFm) += oneOverFieldJump*(dk0mdFieldm(p,q)*
+                                                  Gradsm[j+indexField*nbFFm][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+indexField*nbFFm]);
+                  }
                 }
               }
-              else
+              for(int l=0;l<nbFFp;l++)
               {
-                int extraDOFField_aux=0;
-                if((extraDOFField2+1)< ipvp->getNumConstitutiveExtraDofDiffusionVariable()) extraDOFField_aux=extraDOFField2+1;
-                else extraDOFField_aux=extraDOFField2-1; 
-
-                fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField2);
-                fieldJump2 = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField_aux);
-
-                dk0mdFieldm  = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField2];
-                dk0pdFieldp  = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField2];
-                dk0mdField2m = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField2];
-                dk0pdField2p = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField2];
-
-                dk0mdFm  = ipvm->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
-                dk0pdFp  = ipvp->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
-
-                if(!getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
+                for(int p =0; p < 3; p++)
                 {
-                  if(extraDOFField==extraDOFField2)
+                  for(int q =0; q < 3; q++)
                   {
-                    dfieldJumpdFieldp=ipvp->getConstRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][extraDOFField2];
-                    dfieldJumpdFieldm=ipvm->getConstRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][extraDOFField2];
-                    dfieldJumpdField2p=ipvp->getConstRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField_aux][extraDOFField];
-                    dfieldJumpdField2m=ipvm->getConstRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField_aux][extraDOFField];
-
-                    k02m = *(ipvm->getConstRefToLinearK()[extraDOFField][extraDOFField_aux]);
-                    k02p = *(ipvp->getConstRefToLinearK()[extraDOFField][extraDOFField_aux]);
+                    stiff(j+indexField*nbFFm,l+indexField*nbFFp+nbdofm) += dfieldJumpdFieldp*(k0m(p,q)*
+                                                Gradsm[j+indexField*nbFFm][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+indexField*nbFFp]);
                   }
-                  else 
+                }
+              }
+            }
+            for(int j=0;j<nbFFp;j++)
+            {
+              for(int l=0;l<nbFFm;l++)
+              {
+                for(int p =0; p < 3; p++)
+                {
+                  for(int q =0; q < 3; q++)
                   {
-                    dfieldJumpdFieldp=ipvp->getConstRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][extraDOFField2];
-                    dfieldJumpdFieldm=ipvm->getConstRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][extraDOFField2];
-                    dfieldJumpdField2p=ipvp->getConstRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField2][extraDOFField2];
-                    dfieldJumpdField2m=ipvm->getConstRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField2][extraDOFField2];
-
-                    k0m  = *(ipvm->getConstRefToLinearK()[extraDOFField][extraDOFField]);
-                    k0p  = *(ipvp->getConstRefToLinearK()[extraDOFField][extraDOFField]);
-                    k02m = *(ipvm->getConstRefToLinearK()[extraDOFField][extraDOFField2]);
-                    k02p = *(ipvp->getConstRefToLinearK()[extraDOFField][extraDOFField2]);
+                    stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFm) += dfieldJumpdFieldm*(k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*
+                                               (nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+indexField*nbFFm]);
                   }
                 }
-                if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
+              }
+              for(int l=0;l<nbFFp;l++)
+              {
+                for(int p =0; p < 3; p++)
                 {
-                  dk0mdField_auxm = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField_aux];
-                  dk0pdField_auxp = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField_aux];
-                  dk0mdField_aux2m = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField_aux];
-                  dk0pdField_aux2p = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField_aux];
-                   
-                  dFielddEnergyConjugatedFieldp = ipvp->getConstRefTodFielddEnergyConjugatedField()[extraDOFField2][extraDOFField2];
-                  dFielddEnergyConjugatedFieldm = ipvm->getConstRefTodFielddEnergyConjugatedField()[extraDOFField2][extraDOFField2]; 
-                  dFielddEnergyConjugatedField2p = ipvp->getConstRefTodFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField2];
-                  dFielddEnergyConjugatedField2m = ipvm->getConstRefTodFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField2]; 
-
-                  dGradFielddEnergyConjugatedFieldp = ipvp->getConstRefTodGradFielddEnergyConjugatedField()[extraDOFField2][extraDOFField2]; 
-                  dGradFielddEnergyConjugatedFieldm = ipvm->getConstRefTodGradFielddEnergyConjugatedField()[extraDOFField2][extraDOFField2];
-                  dGradFielddGradEnergyConjugatedFieldp = ipvp->getConstRefTodGradFielddGradEnergyConjugatedField()[extraDOFField2][extraDOFField2];
-                  dGradFielddGradEnergyConjugatedFieldm = ipvm->getConstRefTodGradFielddGradEnergyConjugatedField()[extraDOFField2][extraDOFField2]; 
-
-                  dGradFielddEnergyConjugatedField2p = ipvp->getConstRefTodGradFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField2]; 
-                  dGradFielddEnergyConjugatedField2m = ipvm->getConstRefTodGradFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField2];
-                  dGradFielddGradEnergyConjugatedField2p = ipvp->getConstRefTodGradFielddGradEnergyConjugatedField()[extraDOFField_aux][extraDOFField2];
-                  dGradFielddGradEnergyConjugatedField2m = ipvm->getConstRefTodGradFielddGradEnergyConjugatedField()[extraDOFField_aux][extraDOFField2]; 
-
-                  dqdField2m = ipvm->getConstRefTodFluxdField()[extraDOFField][extraDOFField_aux];
-                  dqdField2p = ipvp->getConstRefTodFluxdField()[extraDOFField][extraDOFField_aux];
-                  dqdGradField2m = ipvm->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField_aux];
-                  dqdGradField2p = ipvp->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField_aux];
+                  for(int q =0; q < 3; q++)
+                  {
+                    stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += dfieldJumpdFieldp*(k0p(p,q)*
+                                      Gradsp[j+indexField*nbFFp][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+indexField*nbFFp]);
+                    if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
+                      stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += oneOverFieldJump*
+                                 (dk0pdFieldp(p,q)*Gradsp[j+indexField*nbFFp][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+indexField*nbFFp]);
+                  }
                 }
               }
-              //
-              int indexField2=3+getNumNonLocalVariable()+extraDOFField2;
-              for(int j=0;j<nbFFm;j++)
+            }
+            
+          }
+          else if (getNumConstitutiveExtraDofDiffusionVariable() == 2 && getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) // electro-thermomec
+          {
+            for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
+            {
+              const double fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
+              const double fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
+                        
+              int indexField=3+getNumNonLocalVariable()+extraDOFField;
+              for (int extraDOFField2 = 0; extraDOFField2< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField2++)
               {
-                for(int l=0;l<nbFFm;l++)
+                const STensor3  *dqdGradFieldm = &(ipvm->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField2]);
+                const STensor3  *dqdGradFieldp = &(ipvp->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField2]);
+                const SVector3  *dqdFieldm = &(ipvm->getConstRefTodFluxdField()[extraDOFField][extraDOFField2]);
+                const SVector3  *dqdFieldp = &(ipvp->getConstRefTodFluxdField()[extraDOFField][extraDOFField2]);
+                
+                static STensor3  k0m, k0p;
+                k0m = *(ipvm->getConstRefToLinearK()[extraDOFField][extraDOFField2]);
+                k0p = *(ipvp->getConstRefToLinearK()[extraDOFField][extraDOFField2]);
+                
+                int extraDOFField_aux= (extraDOFField2==0)?1:0;
+                
+                double fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField2);
+                double fieldJump2 = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField_aux);
+
+                const STensor3& dk0mdFieldm  = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField2];
+                const STensor3& dk0pdFieldp  = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField2];
+                const STensor3& dk0mdField2m = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField2];
+                const STensor3& dk0pdField2p = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField2];
+
+                const STensor43& dk0mdFm  = ipvm->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
+                const STensor43& dk0pdFp  = ipvp->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
+
+                const STensor3& dk0mdField_auxm = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField_aux];
+                const STensor3& dk0pdField_auxp = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField_aux];
+                const STensor3& dk0mdField_aux2m= ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField_aux];
+                const STensor3& dk0pdField_aux2p = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField_aux];
+                 
+                const double& dFielddEnergyConjugatedFieldp = ipvp->getConstRefTodFielddEnergyConjugatedField()[extraDOFField2][extraDOFField2];
+                const double& dFielddEnergyConjugatedFieldm = ipvm->getConstRefTodFielddEnergyConjugatedField()[extraDOFField2][extraDOFField2]; 
+                const double& dFielddEnergyConjugatedField2p = ipvp->getConstRefTodFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField2];
+                const double& dFielddEnergyConjugatedField2m = ipvm->getConstRefTodFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField2]; 
+
+                const SVector3& dGradFielddEnergyConjugatedFieldp = ipvp->getConstRefTodGradFielddEnergyConjugatedField()[extraDOFField2][extraDOFField2]; 
+                const SVector3& dGradFielddEnergyConjugatedFieldm = ipvm->getConstRefTodGradFielddEnergyConjugatedField()[extraDOFField2][extraDOFField2];
+                const STensor3& dGradFielddGradEnergyConjugatedFieldp = ipvp->getConstRefTodGradFielddGradEnergyConjugatedField()[extraDOFField2][extraDOFField2];
+                const STensor3& dGradFielddGradEnergyConjugatedFieldm = ipvm->getConstRefTodGradFielddGradEnergyConjugatedField()[extraDOFField2][extraDOFField2]; 
+
+                const SVector3& dGradFielddEnergyConjugatedField2p = ipvp->getConstRefTodGradFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField2]; 
+                const SVector3& dGradFielddEnergyConjugatedField2m = ipvm->getConstRefTodGradFielddEnergyConjugatedField()[extraDOFField_aux][extraDOFField2];
+                const STensor3& dGradFielddGradEnergyConjugatedField2p = ipvp->getConstRefTodGradFielddGradEnergyConjugatedField()[extraDOFField_aux][extraDOFField2];
+                const STensor3& dGradFielddGradEnergyConjugatedField2m = ipvm->getConstRefTodGradFielddGradEnergyConjugatedField()[extraDOFField_aux][extraDOFField2]; 
+
+                const SVector3& dqdField2m = ipvm->getConstRefTodFluxdField()[extraDOFField][extraDOFField_aux];
+                const SVector3& dqdField2p = ipvp->getConstRefTodFluxdField()[extraDOFField][extraDOFField_aux];
+                const STensor3& dqdGradField2m = ipvm->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField_aux];
+                const STensor3& dqdGradField2p = ipvp->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField_aux];
+                
+                //
+                int indexField2=3+getNumNonLocalVariable()+extraDOFField2;
+                for(int j=0;j<nbFFm;j++)
                 {
-                  for(int p = 0; p< 3; p++)
+                  for(int l=0;l<nbFFm;l++)
                   {
-
-                    if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2)) 
-                      stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (dqdFieldm->operator()(p)*dFielddEnergyConjugatedFieldm+dqdField2m(p)*
-                                                         dFielddEnergyConjugatedField2m)*(Valsm[l+indexField2*nbFFm]*Valsm[j+indexField*nbFFm]*
-                                                         getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                    else 
-                      stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= dqdFieldm->operator()(p)*(Valsm[l+indexField2*nbFFm]*
-                                                          Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                    for(int q = 0; q< 3; q++)
+                    for(int p = 0; p< 3; p++)
                     {
+                      stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (dqdFieldm->operator()(p)*dFielddEnergyConjugatedFieldm+dqdField2m(p)*
+                                                           dFielddEnergyConjugatedField2m)*(Valsm[l+indexField2*nbFFm]*Valsm[j+indexField*nbFFm]*
+                                                           getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                   
+                      for(int q = 0; q< 3; q++)
+                      {
 
-                      if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2)) 
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -=(dqdGradFieldm->operator()(p,q)*dGradFielddEnergyConjugatedFieldm(q)+dqdGradField2m(p,q)*
-                                                      dGradFielddEnergyConjugatedField2m(q))*(Valsm[j+indexField*nbFFm]*
-                                                      Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                      else 
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= dqdGradFieldm->operator()(q,p)*
-                                       (Gradsm[l+indexField2*nbFFm][p]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                          stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -=(dqdGradFieldm->operator()(p,q)*dGradFielddEnergyConjugatedFieldm(q)+dqdGradField2m(p,q)*
+                                                        dGradFielddEnergyConjugatedField2m(q))*(Valsm[j+indexField*nbFFm]*
+                                                        Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                   
 
-                      if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2))
-                       {
-                         for(int o = 0; o< 3; o++)
+                          for(int o = 0; o< 3; o++)
                           {
 
                             stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -=(dqdGradFieldm->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldm(o,q)+dqdGradField2m(p,o)*
                                                        dGradFielddGradEnergyConjugatedField2m(o,q))*Valsm[j+indexField*nbFFm]*
                                                        (Gradsm[l+indexField2*nbFFm][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                           }
-                       }
+                         
+                      }
+                    }
+                  }
+                  for(int l=0;l<nbFFp;l++)
+                  {
+                    for(int p = 0; p< 3; p++)
+                    {
+                      
+                      stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (dqdFieldp->operator()(p)*dFielddEnergyConjugatedFieldp+dqdField2p(p)*
+                                    dFielddEnergyConjugatedField2p)*(Valsp[l+indexField2*nbFFp]*
+                                    Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+
+                      for(int q = 0; q< 3; q++)
+                      {
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (dqdGradFieldp->operator()(p,q)*
+                                                     dGradFielddEnergyConjugatedFieldp(q)+dqdGradField2p(p,q)*dGradFielddEnergyConjugatedField2p(q))*
+                                                     Valsm[j+indexField*nbFFm]*(Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+
+    
+                        for(int o = 0; o< 3; o++)
+                        {
+
+                          stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -=(dqdGradFieldp->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldp(o,q)+
+                                                      dqdGradField2p(p,o)*dGradFielddGradEnergyConjugatedField2p(o,q))*Valsm[j+indexField*nbFFm]*
+                                                      (Gradsp[l+indexField2*nbFFp][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                        
+                        }
+                      }
+                    }
+                  }
+                }
+                for(int j=0;j<nbFFp;j++)
+                {
+                  for(int l=0;l<nbFFm;l++)
+                  {
+                    for(int p = 0; p< 3; p++)
+                    {
+                       stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += (dqdFieldm->operator()(p)*dFielddEnergyConjugatedFieldm+dqdField2m(p)*
+                                   dFielddEnergyConjugatedField2m)*
+                                   (Valsm[l+indexField2*nbFFm]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                      for(int q = 0; q< 3; q++)
+                      {
+
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) +=(dqdGradFieldm->operator()(p,q)*dGradFielddEnergyConjugatedFieldm(q)+
+                                        dqdGradField2m(p,q)*dGradFielddEnergyConjugatedField2m(q))*Valsp[j+indexField*nbFFp]*
+                                        (Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                        for(int o = 0; o< 3; o++)
+                        {
+
+                          stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) +=(dqdGradFieldm->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldm(o,q)+
+                                               dqdGradField2m(p,o)*dGradFielddGradEnergyConjugatedField2m(o,q))*Valsp[j+indexField*nbFFp]*
+                                               (Gradsm[l+indexField2*nbFFm][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                        }
+                        
+                      }
+                    }
+                  }
+                  for(int l=0;l<nbFFp;l++)
+                  {
+                    for(int p = 0; p< 3; p++)
+                    {
+
+                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dqdFieldp->operator()(p)*dFielddEnergyConjugatedFieldp+
+                                                              dqdField2p(p)*dFielddEnergyConjugatedField2p)*
+                                  (Valsp[l+indexField2*nbFFp]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                      for(int q = 0; q< 3; q++)
+                      {
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dqdGradFieldp->operator()(p,q)*dGradFielddEnergyConjugatedFieldp(q)+
+                                    dqdGradField2p(p,q)*dGradFielddEnergyConjugatedField2p(q))*(Valsp[j+indexField*nbFFp]*
+                                    Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+
+                        for(int o = 0; o< 3; o++)
+                        {
+
+                          stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dqdGradFieldp->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldp(o,q)+
+                                   dqdGradField2p(p,o)*dGradFielddGradEnergyConjugatedField2p(o,q))*Valsp[j+indexField*nbFFp]*
+                                   (Gradsp[l+indexField2*nbFFp][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                        }
+                        
+                      }
+                    }
+                  }
+                }
+                
+                //
+                // Stability  N \mean{k0} (N)
+                double NMeankNBetasc=0.;
+                double NMeank2NBetasc=0.;
+                double dNMeankNBetascdFieldp=0.;
+                double dNMeankNBetascdFieldm=0.;
+                double dNMeankNBetascdField2p=0.;
+                double dNMeankNBetascdField2m=0.;
+                double dNMeankNBetascdField_auxp=0.;
+                double dNMeankNBetascdField_auxm=0.;
+                double dNMeankNBetascdField_aux2p=0.;
+                double dNMeankNBetascdField_aux2m=0.;          
+                static STensor3 dNMeankNBetascdFm, dNMeankNBetascdFp;
+
+                STensorOperation::zero(dNMeankNBetascdFm); STensorOperation::zero(dNMeankNBetascdFp);
+
+                for(int l = 0; l <3; l++)
+                {
+                  for(int n = 0; n <3; n++)
+                  {
+                    NMeankNBetasc  += (k0p(l,n)+k0m(l,n))*nu(n)*nbetahs*nu(l)/2.;
+
+                    dNMeankNBetascdFieldp  += dk0pdFieldp(l,n)*nu(n)*nbetahs*nu(l)/2.;
+                    dNMeankNBetascdFieldm  += dk0mdFieldm(l,n)*nu(n)*nbetahs*nu(l)/2.;
+                    dNMeankNBetascdField2p += dk0pdField2p(l,n)*nu(n)*nbetahs*nu(l)/2.;
+                    dNMeankNBetascdField2m += dk0mdField2m(l,n)*nu(n)*nbetahs*nu(l)/2.; 
+                    
+                    dNMeankNBetascdField_auxp += dk0pdField_auxp(l,n)*nu(n)*nbetahs*nu(l)/2.;         
+                    dNMeankNBetascdField_auxm += dk0mdField_auxm(l,n)*nu(n)*nbetahs*nu(l)/2.; 
+                    dNMeankNBetascdField_aux2p += dk0pdField_aux2p(l,n)*nu(n)*nbetahs*nu(l)/2.;         
+                    dNMeankNBetascdField_aux2m += dk0mdField_aux2m(l,n)*nu(n)*nbetahs*nu(l)/2.;                 
+                  
+                    for(int j = 0; j<3; j++)
+                      {
+                       for(int p = 0; p<3; p++)
+                        {
+                          dNMeankNBetascdFm(j,p)+=dk0mdFm(l,n,j,p)*nu(j)*nbetahs*nu(p)/2.;
+                          dNMeankNBetascdFp(j,p)+=dk0pdFp(l,n,j,p)*nu(j)*nbetahs*nu(p)/2.;
+                       }                
+                     }
+                  }
+                }
+
+                dNMeankNBetascdFieldp *= dFielddEnergyConjugatedFieldp;
+                dNMeankNBetascdFieldp += (dNMeankNBetascdField_auxp*dFielddEnergyConjugatedField2p);
+                dNMeankNBetascdFieldm *= dFielddEnergyConjugatedFieldm;
+                dNMeankNBetascdFieldm += (dNMeankNBetascdField_auxp*dFielddEnergyConjugatedField2m);
+                dNMeankNBetascdField2p *= dFielddEnergyConjugatedFieldp;
+                dNMeankNBetascdField2p += (dNMeankNBetascdField_aux2p*dFielddEnergyConjugatedField2p);
+                dNMeankNBetascdField2m *= dFielddEnergyConjugatedFieldm;
+                dNMeankNBetascdField2m += (dNMeankNBetascdField_aux2p*dFielddEnergyConjugatedField2m);
+
+                // Assembly stability (if not broken)
+                for(int j=0;j<nbFFm;j++)
+                {
+                  for(int l=0;l<nbFFm;l++)
+                  {
+                    stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += NMeankNBetasc*(Valsm[j+indexField*nbFFm]*Valsm[l+indexField2*nbFFm]*
+                                                                        wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
+                                          (Valsm[j+indexField*nbFFm]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  }
+                  for(int l=0;l<nbFFp;l++)
+                  {
+                    stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= NMeankNBetasc*(Valsm[j+indexField*nbFFm]*
+                                          Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
+                                          (Valsm[j+indexField*nbFFm]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  }
+                }
+                for(int j=0;j<nbFFp;j++)
+                {
+                  for(int l=0;l<nbFFm;l++)
+                  {
+                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) -= NMeankNBetasc*
+                                                         (Valsp[j+indexField*nbFFp]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
+                                                          (Valsp[j+indexField*nbFFp]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  }
+                  for(int l=0;l<nbFFp;l++)
+                  {
+                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += NMeankNBetasc*
+                                             (Valsp[j+indexField*nbFFp]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+
+                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
+                                             (Valsp[j+indexField*nbFFp]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  }
+                }
+     
+
+                for(int j=0;j<nbFFm;j++)
+                {
+                  for(int k=0;k<3;k++)
+                  {
+                    for(int l=0;l<nbFFm;l++)
+                    {
+                      if(useBarF)
+                      {
+                        for(int ii=0; ii<3; ii++)
+                        {
+                          for(int p=0; p<3; p++)
+                          {
+                            stiff(j+indexField*nbFFm,l+k*nbFFm) -= fieldJump*dNMeankNBetascdFm(ii,p)*dBarFdum[i][l](ii,p,k)*Valsm[j+indexField*nbFFm]*
+                                                               wJ*getConstitutiveExtraDofDiffusionEqRatio();
+                          }
+                        }
+                      }
+                      else
+                      {
+                        for(int p=0;p<3;p++)
+                        {
+                          stiff(j+indexField*nbFFm,l+k*nbFFm) -= fieldJump*dNMeankNBetascdFm(k,p)*Gradsm[l+0*nbFFm][p]*Valsm[j+indexField*nbFFm]*
+                                                               wJ*getConstitutiveExtraDofDiffusionEqRatio();
+                        }
+                      }
+                    }
+                    for(int l=0;l<nbFFp;l++)
+                    {
+                      if(useBarF)
+                      {
+                        for(int ii=0; ii<3; ii++)
+                        {
+                          for(int p=0; p<3; p++)
+                          {
+                           stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= fieldJump*dNMeankNBetascdFp(ii,p)*dBarFdup[i][l](ii,p,k)*Valsm[j+indexField*nbFFm]*
+                                                                  wJ*getConstitutiveExtraDofDiffusionEqRatio();
+                          }
+                        }
+                      }
+                      else
+                      {
+                        for(int p=0;p<3;p++)
+                        {
+                          stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= fieldJump*dNMeankNBetascdFp(k,p)*Gradsp[l+0*nbFFp][p]*Valsm[j+indexField*nbFFm]*
+                                                                 wJ*getConstitutiveExtraDofDiffusionEqRatio();
+                        }
+                      }
+                    }
+                  } 
+                }
+
+                for(int j=0;j<nbFFp;j++)
+                {
+                  for(int k=0;k<3;k++)
+                  {
+                    for(int l=0;l<nbFFm;l++)
+                    {
+                      if(useBarF)
+                      {
+                        for(int ii=0; ii<3; ii++)
+                        {
+                          for(int p=0; p<3; p++)
+                          {
+                            stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFm) += fieldJump*dNMeankNBetascdFm(ii,p)*dBarFdum[i][l](ii,p,k)*Valsp[j+indexField*nbFFp]*
+                                                                        wJ*getConstitutiveExtraDofDiffusionEqRatio();
+                          }
+                        }
+                      }
+                      else
+                      {
+                        for(int p=0;p<3;p++)
+                        {
+                          stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFm) += fieldJump*dNMeankNBetascdFm(k,p)*Gradsm[l+0*nbFFm][p]*Valsp[j+indexField*nbFFp]*
+                                                                        wJ*getConstitutiveExtraDofDiffusionEqRatio();
+                        }
+                      }
+                    }
+
+                    for(int l=0;l<nbFFp;l++)
+                    {
+                      if(useBarF)
+                      {
+                        for(int ii=0; ii<3; ii++)
+                        {
+                          for(int p=0; p<3; p++)
+                          {
+                            stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFp+nbdofm) +=fieldJump*dNMeankNBetascdFp(ii,p)*dBarFdup[i][l](ii,p,k)*Valsp[j+indexField*nbFFp]*
+                                                                         wJ*getConstitutiveExtraDofDiffusionEqRatio();
+                          }
+                        }
+                      }
+                      else
+                      {
+                        for(int p=0;p<3;p++)
+                        {
+                          stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFp+nbdofm) +=fieldJump*dNMeankNBetascdFp(k,p)*Gradsp[l+0*nbFFp][p]*Valsp[j+indexField*nbFFp]*
+                                                                         wJ*getConstitutiveExtraDofDiffusionEqRatio();
+                        }
+                      }
+                    }
+                  }
+                }
+                // compatibility
+                // Assembly (loop on shape function)
+
+                for(int j=0;j<nbFFm;j++)
+                {
+                  for(int l=0;l<nbFFm;l++)
+                  {
+                    for(int p =0; p < 3; p++)
+                    {
+                      for(int q =0; q < 3; q++)
+                      {
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
+                                                       Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += (fieldJump*(dk0mdFieldm(p,q)*dFielddEnergyConjugatedFieldm+dk0mdField_auxm(p,q)*
+                                          dFielddEnergyConjugatedField2m)+fieldJump2*(dk0mdField2m(p,q)*dFielddEnergyConjugatedFieldm+dk0mdField_aux2m(p,q)*
+                                          dFielddEnergyConjugatedField2m))*Gradsm[j+indexField*nbFFm][q]*nu(p)*Valsm[l+indexField2*nbFFm]*
+                                          getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
+                      }
+                    }
+                  }
+                  for(int l=0;l<nbFFp;l++)
+                  {
+                    for(int p =0; p < 3; p++)
+                    {
+                      for(int q =0; q < 3; q++)
+                      {
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) += (k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
+                                              Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
+                      }
+                    }
+                  }
+                }
+
+                for(int j=0;j<nbFFp;j++)
+                {
+                  for(int l=0;l<nbFFm;l++)
+                  {
+                    for(int p =0; p < 3; p++)
+                    {
+                      for(int q =0; q < 3; q++)
+                      {
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) -= (k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*
+                                               (nu(p)*Valsm[l+indexField2*nbFFm])*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
+                      }
                     }
                   }
-                }
-                for(int l=0;l<nbFFp;l++)
-                {
-                  for(int p = 0; p< 3; p++)
+                  for(int l=0;l<nbFFp;l++)
                   {
-                    
-                    if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2)) 
-                      stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (dqdFieldp->operator()(p)*dFielddEnergyConjugatedFieldp+dqdField2p(p)*
-                                  dFielddEnergyConjugatedField2p)*(Valsp[l+indexField2*nbFFp]*
-                                  Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                    else 
-                      stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= dqdFieldp->operator()(p)*
-                                 (Valsp[l+indexField2*nbFFp]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-
-                    for(int q = 0; q< 3; q++)
+                    for(int p =0; p < 3; p++)
                     {
-                      if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2)) 
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (dqdGradFieldp->operator()(p,q)*
-                                                   dGradFielddEnergyConjugatedFieldp(q)+dqdGradField2p(p,q)*dGradFielddEnergyConjugatedField2p(q))*
-                                                   Valsm[j+indexField*nbFFm]*(Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                      else 
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= dqdGradFieldp->operator()(q,p)*
-                                                   (Gradsp[l+indexField2*nbFFp][p]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
-
-                      if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2))
+                      for(int q =0; q < 3; q++)
                       {
-                        for(int o = 0; o< 3; o++)
-                        {
-
-                            stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -=(dqdGradFieldp->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldp(o,q)+
-                                                      dqdGradField2p(p,o)*dGradFielddGradEnergyConjugatedField2p(o,q))*Valsm[j+indexField*nbFFm]*
-                                                      (Gradsp[l+indexField2*nbFFp][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                        }
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
+                                                      Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*(dk0pdFieldp(p,q)*
+                                                      dFielddEnergyConjugatedFieldp+dk0pdField_auxp(p,q)*dFielddEnergyConjugatedField2p)+
+                                                      fieldJump2*(dk0pdField2p(p,q)*dFielddEnergyConjugatedFieldp+
+                                                      dk0pdField_aux2p(p,q)*dFielddEnergyConjugatedField2p))*Gradsp[j+indexField*nbFFp][q]*
+                                                      (nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*(wJ/2.)*Valsp[l+indexField2*nbFFp]);
                       }
                     }
                   }
                 }
-              }
-              for(int j=0;j<nbFFp;j++)
-              {
-                for(int l=0;l<nbFFm;l++)
+               
+                for(int j=0;j<nbFFm;j++)
                 {
-                  for(int p = 0; p< 3; p++)
+                  for(int l=0;l<nbFFm;l++)
                   {
-
-                    if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2)) 
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += (dqdFieldm->operator()(p)*dFielddEnergyConjugatedFieldm+dqdField2m(p)*
-                                 dFielddEnergyConjugatedField2m)*
-                                 (Valsm[l+indexField2*nbFFm]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                    else 
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += dqdFieldm->operator()(p)*(Valsm[l+indexField2*nbFFm]*
-                                  Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                    for(int q = 0; q< 3; q++)
+                    for(int m =0; m < 3; m++)
                     {
-
-                      if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2)) 
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) +=(dqdGradFieldm->operator()(p,q)*dGradFielddEnergyConjugatedFieldm(q)+
-                                      dqdGradField2m(p,q)*dGradFielddEnergyConjugatedField2m(q))*Valsp[j+indexField*nbFFp]*
-                                      (Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                      else 
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += dqdGradFieldm->operator()(q,p)*
-                                      (Gradsm[l+indexField2*nbFFm][p]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
-                      if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2))
+                      for(int p =0; p < 3; p++)
                       {
-                        for(int o = 0; o< 3; o++)
+                        for(int q =0; q < 3; q++)
                         {
-
-                          stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) +=(dqdGradFieldm->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldm(o,q)+
-                                               dqdGradField2m(p,o)*dGradFielddGradEnergyConjugatedField2m(o,q))*Valsp[j+indexField*nbFFp]*
-                                               (Gradsm[l+indexField2*nbFFm][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                          if(useBarF)
+                          {
+                            for(int ii=0; ii<3; ii++)
+                            {
+                              for(int n=0; n<3; n++)
+                              {
+                                stiff(j+indexField*nbFFm,l+m*nbFFm) += fieldJump*(dk0mdFm(p,q,ii,n)*
+                                          Gradsm[j+indexField*nbFFm][q]*dBarFdum[i][l](ii,n,m))*(nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                              }
+                            }
+                          }
+                          else
+                          {
+                            for(int n =0; n< 3; n++)
+                            {
+                              stiff(j+indexField*nbFFm,l+m*nbFFm) += fieldJump*(dk0mdFm(p,q,m,n)*
+                                          Gradsm[j+indexField*nbFFm][q]*Gradsm[l+0*nbFFm][n])*(nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                            }
+                          }
                         }
                       }
                     }
                   }
                 }
-                for(int l=0;l<nbFFp;l++)
+
+                for(int j=0;j<nbFFp;j++)
                 {
-                  for(int p = 0; p< 3; p++)
+                  for(int l=0;l<nbFFp;l++)
                   {
-
-                    if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2)) 
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dqdFieldp->operator()(p)*dFielddEnergyConjugatedFieldp+
-                                                            dqdField2p(p)*dFielddEnergyConjugatedField2p)*
-                                (Valsp[l+indexField2*nbFFp]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                    else 
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += dqdFieldp->operator()(p)*
-                                (Valsp[l+indexField2*nbFFp]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                    for(int q = 0; q< 3; q++)
+                    for(int m =0; m < 3; m++)
                     {
-
-                      if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2))
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dqdGradFieldp->operator()(p,q)*dGradFielddEnergyConjugatedFieldp(q)+
-                                  dqdGradField2p(p,q)*dGradFielddEnergyConjugatedField2p(q))*(Valsp[j+indexField*nbFFp]*
-                                  Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
-                      else 
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += dqdGradFieldp->operator()(q,p)*(Gradsp[l+indexField2*nbFFp][p]*
-                                  Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
-
-                      if((getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())&&(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2))
+                      for(int q =0; q< 3; q++)
                       {
-                        for(int o = 0; o< 3; o++)
+                        for(int p =0; p < 3; p++)
                         {
-
-                          stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dqdGradFieldp->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldp(o,q)+
-                                   dqdGradField2p(p,o)*dGradFielddGradEnergyConjugatedField2p(o,q))*Valsp[j+indexField*nbFFp]*
-                                   (Gradsp[l+indexField2*nbFFp][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                          if(useBarF)
+                          {
+                            for(int ii=0; ii<3; ii++)
+                            {
+                              for(int n=0; n<3; n++)
+                              {
+                                stiff(j+indexField*nbFFp+nbdofm,l+m*nbFFp+nbdofm) += fieldJump*(dk0pdFp(p,q,ii,n)*
+                                          Gradsp[j+indexField*nbFFp][q]*dBarFdup[i][l](ii,n,m))*
+                                          (nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                              }
+                            }
+                          }
+                          else
+                          {
+                            for(int n =0; n < 3; n++)
+                            {
+                              stiff(j+indexField*nbFFp+nbdofm,l+m*nbFFp+nbdofm) += fieldJump*(dk0pdFp(p,q,m,n)*
+                                          Gradsp[j+indexField*nbFFp][q]*Gradsp[l+0*nbFFp][n])*
+                                          (nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                            }
+                          }
                         }
                       }
                     }
                   }
                 }
               }
+            }
+          }
+          else if (getNumConstitutiveExtraDofDiffusionVariable() == 2 && !getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) // electro-thermomec
+          {
+            for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
+            {
+              const double fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
+              const double fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
               
-              //
-              if(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==1)
+              int indexField=3+getNumNonLocalVariable()+extraDOFField;
+              for (int extraDOFField2 = 0; extraDOFField2< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField2++)
               {
-                // Stability  N \mean{k0} (N)
-                double NMeankNBetasc=0.;
-                double dNMeankNBetascdFieldp=0.;
-                double dNMeankNBetascdFieldm=0.;
+                const STensor3  *dqdGradFieldm = &(ipvm->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField2]);
+                const STensor3  *dqdGradFieldp = &(ipvp->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField2]);
+                const SVector3  *dqdFieldm = &(ipvm->getConstRefTodFluxdField()[extraDOFField][extraDOFField2]);
+                const SVector3  *dqdFieldp = &(ipvp->getConstRefTodFluxdField()[extraDOFField][extraDOFField2]);
+                
+                static STensor3  k0m, k0p;
+                k0m = *(ipvm->getConstRefToLinearK()[extraDOFField][extraDOFField2]);
+                k0p = *(ipvp->getConstRefToLinearK()[extraDOFField][extraDOFField2]);
+                
+                int extraDOFField_aux= (extraDOFField2==0)? 1:0;
+                
+                const double fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField2);
+                const double fieldJump2 = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField_aux);
 
-                for(int l = 0; l <3; l++)
-                {
-                  for(int n = 0; n <3; n++)
-                  {
-                    NMeankNBetasc += (k0p(l,n)+k0m(l,n))*nu(n)*nbetahs*nu(l)/2.;
-                    dNMeankNBetascdFieldp+=dk0pdFieldp(l,n)*nu(n)*nbetahs*nu(l)/2.;
-                    dNMeankNBetascdFieldm+=dk0mdFieldm(l,n)*nu(n)*nbetahs*nu(l)/2.;
-                  }
-                }
+                const STensor3& dk0mdFieldm  = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField2];
+                const STensor3& dk0pdFieldp  = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField2];
+                const STensor3& dk0mdField2m = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField2];
+                const STensor3& dk0pdField2p = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField2];
 
-                // Assembly stability (if not broken)
-                for(int j=0;j<nbFFm;j++)
+                const STensor43& dk0mdFm  = ipvm->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
+                const STensor43& dk0pdFp  = ipvp->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
+                
+                double dfieldJumpdFieldp, dfieldJumpdFieldm, dfieldJumpdField2p, dfieldJumpdField2m;
+                static STensor3 k02m, k02p;
+                if(extraDOFField==extraDOFField2)
                 {
-                  for(int l=0;l<nbFFm;l++)
-                  {
-                    stiff(j+indexField*nbFFm,l+indexField*nbFFm) -= dfieldJumpdFieldm*NMeankNBetasc*
-                                          (Valsm[j+indexField*nbFFm]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                      stiff(j+indexField*nbFFm,l+indexField*nbFFm) -= oneOverFieldJump*dNMeankNBetascdFieldm*
-                                          (Valsm[j+indexField*nbFFm]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                  }
-                  for(int l=0;l<nbFFp;l++)
-                  {
-                    stiff(j+indexField*nbFFm,l+indexField*nbFFp+nbdofm) -= dfieldJumpdFieldp*NMeankNBetasc*
-                                          (Valsm[j+indexField*nbFFm]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                      stiff(j+indexField*nbFFm,l+indexField*nbFFp+nbdofm) -= oneOverFieldJump*dNMeankNBetascdFieldp*
-                                                      (Valsm[j+indexField*nbFFm]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                  }
+                  dfieldJumpdFieldp=ipvp->getConstRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][extraDOFField2];
+                  dfieldJumpdFieldm=ipvm->getConstRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][extraDOFField2];
+                  dfieldJumpdField2p=ipvp->getConstRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField_aux][extraDOFField];
+                  dfieldJumpdField2m=ipvm->getConstRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField_aux][extraDOFField];
+
+                  k02m = *(ipvm->getConstRefToLinearK()[extraDOFField][extraDOFField_aux]);
+                  k02p = *(ipvp->getConstRefToLinearK()[extraDOFField][extraDOFField_aux]);
                 }
-                for(int j=0;j<nbFFp;j++)
+                else 
                 {
-                  for(int l=0;l<nbFFm;l++)
-                  {
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFm) += dfieldJumpdFieldm*NMeankNBetasc*
-                                                      (Valsp[j+indexField*nbFFp]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFm) += oneOverFieldJump*dNMeankNBetascdFieldm*
-                                                      (Valsp[j+indexField*nbFFp]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                  }
-                  for(int l=0;l<nbFFp;l++)
-                  {
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += dfieldJumpdFieldp*NMeankNBetasc*
-                                                      (Valsp[j+indexField*nbFFp]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += oneOverFieldJump*dNMeankNBetascdFieldp*
-                                                      (Valsp[j+indexField*nbFFp]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                  }
+                  dfieldJumpdFieldp=ipvp->getConstRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField][extraDOFField2];
+                  dfieldJumpdFieldm=ipvm->getConstRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField][extraDOFField2];
+                  dfieldJumpdField2p=ipvp->getConstRefTodEnergyConjugatedFieldJumpdFieldp()[extraDOFField2][extraDOFField2];
+                  dfieldJumpdField2m=ipvm->getConstRefTodEnergyConjugatedFieldJumpdFieldm()[extraDOFField2][extraDOFField2];
+
+                  k0m  = *(ipvm->getConstRefToLinearK()[extraDOFField][extraDOFField]);
+                  k0p  = *(ipvp->getConstRefToLinearK()[extraDOFField][extraDOFField]);
+                  k02m = *(ipvm->getConstRefToLinearK()[extraDOFField][extraDOFField2]);
+                  k02p = *(ipvp->getConstRefToLinearK()[extraDOFField][extraDOFField2]);
                 }
-                // compatibility
-                // Assembly (loop on shape function)
+                //
+                int indexField2=3+getNumNonLocalVariable()+extraDOFField2;
                 for(int j=0;j<nbFFm;j++)
                 {
                   for(int l=0;l<nbFFm;l++)
                   {
-                    for(int p =0; p < 3; p++)
+                    for(int p = 0; p< 3; p++)
                     {
-                      for(int q =0; q < 3; q++)
+
+                      stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= dqdFieldm->operator()(p)*(Valsm[l+indexField2*nbFFm]*
+                                                            Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                      for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFm,l+indexField*nbFFm) += dfieldJumpdFieldm*(k0m(p,q)*
-                                                      Gradsm[j+indexField*nbFFm][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+indexField*nbFFm]);
-                        if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                          stiff(j+indexField*nbFFm,l+indexField*nbFFm) += oneOverFieldJump*(dk0mdFieldm(p,q)*
-                                                      Gradsm[j+indexField*nbFFm][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+indexField*nbFFm]);
+
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= dqdGradFieldm->operator()(q,p)*
+                                         (Gradsm[l+indexField2*nbFFm][p]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
                       }
                     }
                   }
                   for(int l=0;l<nbFFp;l++)
                   {
-                    for(int p =0; p < 3; p++)
+                    for(int p = 0; p< 3; p++)
                     {
-                      for(int q =0; q < 3; q++)
+                      stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= dqdFieldp->operator()(p)*
+                                   (Valsp[l+indexField2*nbFFp]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+
+                      for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFm,l+indexField*nbFFp+nbdofm) += dfieldJumpdFieldp*(k0m(p,q)*
-                                                    Gradsm[j+indexField*nbFFm][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+indexField*nbFFp]);
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= dqdGradFieldp->operator()(q,p)*
+                                                     (Gradsp[l+indexField2*nbFFp][p]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
                       }
                     }
                   }
@@ -3810,33 +4235,32 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 {
                   for(int l=0;l<nbFFm;l++)
                   {
-                    for(int p =0; p < 3; p++)
+                    for(int p = 0; p< 3; p++)
                     {
-                      for(int q =0; q < 3; q++)
+                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += dqdFieldm->operator()(p)*(Valsm[l+indexField2*nbFFm]*
+                                    Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                      for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFm) += dfieldJumpdFieldm*(k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*
-                                                   (nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+indexField*nbFFm]);
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += dqdGradFieldm->operator()(q,p)*
+                                        (Gradsm[l+indexField2*nbFFm][p]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
                       }
                     }
                   }
                   for(int l=0;l<nbFFp;l++)
                   {
-                    for(int p =0; p < 3; p++)
+                    for(int p = 0; p< 3; p++)
                     {
-                      for(int q =0; q < 3; q++)
+                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += dqdFieldp->operator()(p)*
+                                  (Valsp[l+indexField2*nbFFp]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                      for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += dfieldJumpdFieldp*(k0p(p,q)*
-                                          Gradsp[j+indexField*nbFFp][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+indexField*nbFFp]);
-                        if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                          stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += oneOverFieldJump*
-                                     (dk0pdFieldp(p,q)*Gradsp[j+indexField*nbFFp][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+indexField*nbFFp]);
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += dqdGradFieldp->operator()(q,p)*(Gradsp[l+indexField2*nbFFp][p]*
+                                    Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
                       }
                     }
                   }
                 }
-              }
-              else
-              {
+                //
                 // Stability  N \mean{k0} (N)
                 double NMeankNBetasc=0.;
                 double NMeank2NBetasc=0.;
@@ -3850,7 +4274,8 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 double dNMeankNBetascdField_aux2m=0.;          
                 static STensor3 dNMeankNBetascdFm, dNMeankNBetascdFp;
 
-                STensorOperation::zero(dNMeankNBetascdFm); STensorOperation::zero(dNMeankNBetascdFp);
+                STensorOperation::zero(dNMeankNBetascdFm); 
+                STensorOperation::zero(dNMeankNBetascdFp);
 
                 for(int l = 0; l <3; l++)
                 {
@@ -3864,13 +4289,6 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     dNMeankNBetascdField2p += dk0pdField2p(l,n)*nu(n)*nbetahs*nu(l)/2.;
                     dNMeankNBetascdField2m += dk0mdField2m(l,n)*nu(n)*nbetahs*nu(l)/2.; 
                     
-                    if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                    {
-                      dNMeankNBetascdField_auxp += dk0pdField_auxp(l,n)*nu(n)*nbetahs*nu(l)/2.;         
-                      dNMeankNBetascdField_auxm += dk0mdField_auxm(l,n)*nu(n)*nbetahs*nu(l)/2.; 
-                      dNMeankNBetascdField_aux2p += dk0pdField_aux2p(l,n)*nu(n)*nbetahs*nu(l)/2.;         
-                      dNMeankNBetascdField_aux2m += dk0mdField_aux2m(l,n)*nu(n)*nbetahs*nu(l)/2.;                 
-                    }
                     for(int j = 0; j<3; j++)
                       {
                        for(int p = 0; p<3; p++)
@@ -3881,40 +4299,19 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                      }
                   }
                 }
-
-                if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                {
-                     dNMeankNBetascdFieldp *= dFielddEnergyConjugatedFieldp;
-                     dNMeankNBetascdFieldp += (dNMeankNBetascdField_auxp*dFielddEnergyConjugatedField2p);
-                     dNMeankNBetascdFieldm *= dFielddEnergyConjugatedFieldm;
-                     dNMeankNBetascdFieldm += (dNMeankNBetascdField_auxp*dFielddEnergyConjugatedField2m);
-                     dNMeankNBetascdField2p *= dFielddEnergyConjugatedFieldp;
-                     dNMeankNBetascdField2p += (dNMeankNBetascdField_aux2p*dFielddEnergyConjugatedField2p);
-                     dNMeankNBetascdField2m *= dFielddEnergyConjugatedFieldm;
-                     dNMeankNBetascdField2m += (dNMeankNBetascdField_aux2p*dFielddEnergyConjugatedField2m);
-                }
-
                 // Assembly stability (if not broken)
                 for(int j=0;j<nbFFm;j++)
                 {
                   for(int l=0;l<nbFFm;l++)
                   {
-                    if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) 
-                      stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += NMeankNBetasc*(Valsm[j+indexField*nbFFm]*Valsm[l+indexField2*nbFFm]*
-                                                                        wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    else 
-                      stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (dfieldJumpdFieldm*NMeankNBetasc+dfieldJumpdField2m*NMeank2NBetasc)*
+                    stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (dfieldJumpdFieldm*NMeankNBetasc+dfieldJumpdField2m*NMeank2NBetasc)*
                                           (Valsm[j+indexField*nbFFm]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                     stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
                                           (Valsm[j+indexField*nbFFm]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                   }
                   for(int l=0;l<nbFFp;l++)
                   {
-                    if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) 
-                       stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= NMeankNBetasc*(Valsm[j+indexField*nbFFm]*
-                                          Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    else 
-                       stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (dfieldJumpdFieldp*NMeankNBetasc+dfieldJumpdField2p*NMeank2NBetasc)*
+                    stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (dfieldJumpdFieldp*NMeankNBetasc+dfieldJumpdField2p*NMeank2NBetasc)*
                                           (Valsm[j+indexField*nbFFm]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                     stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
                                           (Valsm[j+indexField*nbFFm]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
@@ -3924,22 +4321,14 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 {
                   for(int l=0;l<nbFFm;l++)
                   {
-                    if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) 
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) -= NMeankNBetasc*
-                                                         (Valsp[j+indexField*nbFFp]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    else 
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += (dfieldJumpdFieldm*NMeankNBetasc+dfieldJumpdField2m*NMeank2NBetasc)*
+                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += (dfieldJumpdFieldm*NMeankNBetasc+dfieldJumpdField2m*NMeank2NBetasc)*
                                                           (Valsp[j+indexField*nbFFp]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                     stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
                                                           (Valsp[j+indexField*nbFFp]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                   }
                   for(int l=0;l<nbFFp;l++)
                   {
-                    if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) 
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += NMeankNBetasc*
-                                             (Valsp[j+indexField*nbFFp]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    else 
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dfieldJumpdFieldp*NMeankNBetasc+dfieldJumpdField2p*NMeank2NBetasc)*
+                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dfieldJumpdFieldp*NMeankNBetasc+dfieldJumpdField2p*NMeank2NBetasc)*
                                              (Valsp[j+indexField*nbFFp]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                     stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
                                              (Valsp[j+indexField*nbFFp]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
@@ -3947,56 +4336,56 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 }
      
 
-               for(int j=0;j<nbFFm;j++)
-               {
+                for(int j=0;j<nbFFm;j++)
+                {
                   for(int k=0;k<3;k++)
                   {
-                     for(int l=0;l<nbFFm;l++)
-                     {
-                        if(useBarF)
+                    for(int l=0;l<nbFFm;l++)
+                    {
+                      if(useBarF)
+                      {
+                        for(int ii=0; ii<3; ii++)
                         {
-                          for(int ii=0; ii<3; ii++)
+                          for(int p=0; p<3; p++)
                           {
-                            for(int p=0; p<3; p++)
-                            {
-                              stiff(j+indexField*nbFFm,l+k*nbFFm) -= fieldJump*dNMeankNBetascdFm(ii,p)*dBarFdum[i][l](ii,p,k)*Valsm[j+indexField*nbFFm]*
-                                                                 wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                            }
+                            stiff(j+indexField*nbFFm,l+k*nbFFm) -= fieldJump*dNMeankNBetascdFm(ii,p)*dBarFdum[i][l](ii,p,k)*Valsm[j+indexField*nbFFm]*
+                                                               wJ*getConstitutiveExtraDofDiffusionEqRatio();
                           }
                         }
-                        else
+                      }
+                      else
+                      {
+                        for(int p=0;p<3;p++)
                         {
-                          for(int p=0;p<3;p++)
-                          {
-                            stiff(j+indexField*nbFFm,l+k*nbFFm) -= fieldJump*dNMeankNBetascdFm(k,p)*Gradsm[l+0*nbFFm][p]*Valsm[j+indexField*nbFFm]*
-                                                                 wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                          }
+                          stiff(j+indexField*nbFFm,l+k*nbFFm) -= fieldJump*dNMeankNBetascdFm(k,p)*Gradsm[l+0*nbFFm][p]*Valsm[j+indexField*nbFFm]*
+                                                               wJ*getConstitutiveExtraDofDiffusionEqRatio();
                         }
                       }
-                      for(int l=0;l<nbFFp;l++)
+                    }
+                    for(int l=0;l<nbFFp;l++)
+                    {
+                      if(useBarF)
                       {
-                        if(useBarF)
+                        for(int ii=0; ii<3; ii++)
                         {
-                          for(int ii=0; ii<3; ii++)
+                          for(int p=0; p<3; p++)
                           {
-                            for(int p=0; p<3; p++)
-                            {
-                             stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= fieldJump*dNMeankNBetascdFp(ii,p)*dBarFdup[i][l](ii,p,k)*Valsm[j+indexField*nbFFm]*
-                                                                    wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                            }
+                           stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= fieldJump*dNMeankNBetascdFp(ii,p)*dBarFdup[i][l](ii,p,k)*Valsm[j+indexField*nbFFm]*
+                                                                  wJ*getConstitutiveExtraDofDiffusionEqRatio();
                           }
                         }
-                        else
+                      }
+                      else
+                      {
+                        for(int p=0;p<3;p++)
                         {
-                          for(int p=0;p<3;p++)
-                          {
-                            stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= fieldJump*dNMeankNBetascdFp(k,p)*Gradsp[l+0*nbFFp][p]*Valsm[j+indexField*nbFFm]*
-                                                                   wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                          }
+                          stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= fieldJump*dNMeankNBetascdFp(k,p)*Gradsp[l+0*nbFFp][p]*Valsm[j+indexField*nbFFm]*
+                                                                 wJ*getConstitutiveExtraDofDiffusionEqRatio();
                         }
                       }
-                    } 
-                  }
+                    }
+                  } 
+                }
 
                 for(int j=0;j<nbFFp;j++)
                 {
@@ -4060,21 +4449,11 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) 
-                           stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
-                                                       Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
-                        else 
-                           stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += ((k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*Valsm[l+indexField2*nbFFm]*
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += ((k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*Valsm[l+indexField2*nbFFm]*
                                           dfieldJumpdFieldm*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+((k02m(p,q)*Gradsm[j+indexField*nbFFm][q])*
                                           nu(p)*Valsm[l+indexField2*nbFFm]*dfieldJumpdField2m*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
 
-                        if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) 
-                           stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += (fieldJump*(dk0mdFieldm(p,q)*dFielddEnergyConjugatedFieldm+dk0mdField_auxm(p,q)*
-                                          dFielddEnergyConjugatedField2m)+fieldJump2*(dk0mdField2m(p,q)*dFielddEnergyConjugatedFieldm+dk0mdField_aux2m(p,q)*
-                                          dFielddEnergyConjugatedField2m))*Gradsm[j+indexField*nbFFm][q]*nu(p)*Valsm[l+indexField2*nbFFm]*
-                                          getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
-                        else 
-                           stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += (fieldJump*(dk0mdFieldm(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += (fieldJump*(dk0mdFieldm(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
                                           Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
                                           (fieldJump2*(dk0mdField2m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
                                           Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
@@ -4087,11 +4466,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) 
-                           stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) += (k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
-                                              Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
-                        else 
-                           stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) += ((k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) += ((k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
                                               Valsp[l+indexField2*nbFFp]*dfieldJumpdFieldp*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
                                               ((k02m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*Valsp[l+indexField2*nbFFp]*
                                               dfieldJumpdField2p*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
@@ -4108,11 +4483,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) 
-                          stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) -= (k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*
-                                               (nu(p)*Valsm[l+indexField2*nbFFm])*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
-                        else 
-                          stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += ((k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += ((k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
                                                Valsm[l+indexField2*nbFFm]*dfieldJumpdFieldm*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
                                                ((k02p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*Valsm[l+indexField2*nbFFm]*
                                                dfieldJumpdField2m*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
@@ -4125,23 +4496,11 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) 
-                          stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
-                                                      Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
-                        else 
-                          stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += ((k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += ((k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
                                                        Valsp[l+indexField2*nbFFp]*dfieldJumpdFieldp*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
                                                       ((k02p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*Valsp[l+indexField2*nbFFp]*
                                                       dfieldJumpdField2p*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-
-                        if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) 
-                           stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*(dk0pdFieldp(p,q)*
-                                                      dFielddEnergyConjugatedFieldp+dk0pdField_auxp(p,q)*dFielddEnergyConjugatedField2p)+
-                                                      fieldJump2*(dk0pdField2p(p,q)*dFielddEnergyConjugatedFieldp+
-                                                      dk0pdField_aux2p(p,q)*dFielddEnergyConjugatedField2p))*Gradsp[j+indexField*nbFFp][q]*
-                                                      (nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*(wJ/2.)*Valsp[l+indexField2*nbFFp]);
-                        else 
-                          stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*(dk0pdFieldp(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*(dk0pdFieldp(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
                                                       Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
                                                       (fieldJump2*(dk0pdField2p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
                                                       Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
@@ -4221,11 +4580,15 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     }
                   }
                 }
-
+                
               }
             }
           }
-          
+          else
+          {
+            Msg::Error("extraDof with more than 2 extra dofs not implemented");
+          }
+        
           // EXTRADOF - displacement
           for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
@@ -4354,12 +4717,6 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           if (getNumNonLocalVariable() > 0)
           {
             // only case when flux depend on nonlocal variables
-            /*
-            static bool mess=false;
-            if(!mess)
-              Msg::Info("Implement non-local / extra dof coupling in dG3DStiffnessInter::get");
-            mess=true;
-             */
              
           }
           
-- 
GitLab


From f82b3accae528d6edcd3568e0cb6efe2fac26b36 Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Tue, 2 Jun 2020 10:09:57 +0200
Subject: [PATCH 13/19] done thermomec

---
 dG3D/src/dG3DTerms.cpp | 147 ++++++++++++++++++++++-------------------
 1 file changed, 79 insertions(+), 68 deletions(-)

diff --git a/dG3D/src/dG3DTerms.cpp b/dG3D/src/dG3DTerms.cpp
index 6cbaa0ea2..8c65f6088 100644
--- a/dG3D/src/dG3DTerms.cpp
+++ b/dG3D/src/dG3DTerms.cpp
@@ -3375,10 +3375,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
      * */
     
     if ((getNumConstitutiveExtraDofDiffusionVariable() > 0) && getConstitutiveExtraDofDiffusionContinuity())
-    {
-      int nbFFm = em->getNumShapeFunctions();
-      int nbFFp = ep->getNumShapeFunctions();
-    
+    {    
       for(int i=0;i<npts; i++)
       {
         // IP
@@ -3462,66 +3459,70 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               dk0pdFieldp*=(1.)*2./fieldp;//the - is removed
             }
             
-            int indexField= 3+getNumNonLocalVariable();
-            int indexField2 = 3+getNumNonLocalVariable();
-            for(int j=0;j<nbFFm;j++)
+            int indexField= 3+getNumNonLocalVariable();            
+            int nbFFmExtraDof = _minusSpace->getNumShapeFunctions(em,indexField);
+            int nbFFmTotalLastExtraDof = _minusSpace->getShapeFunctionsIndex(em,indexField);
+            int nbFFpExtraDof = _plusSpace->getNumShapeFunctions(ep,indexField); 
+            int nbFFpTotalLastExtraDof = _plusSpace->getShapeFunctionsIndex(ep,indexField);
+            
+            for(int j=0;j<nbFFmExtraDof;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmExtraDof;l++)
               {
                 for(int p = 0; p< 3; p++)
                 {
-                  stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= dqdFieldm->operator()(p)*(Valsm[l+indexField2*nbFFm]*
-                                                        Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                  stiff(j+nbFFmTotalLastExtraDof,l+nbFFmTotalLastExtraDof) -= dqdFieldm->operator()(p)*(Valsm[l+nbFFmTotalLastExtraDof]*
+                                                        Valsm[j+nbFFmTotalLastExtraDof]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                   for(int q = 0; q< 3; q++)
                   {
-                    stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= dqdGradFieldm->operator()(q,p)*
-                                     (Gradsm[l+indexField2*nbFFm][p]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                    stiff(j+nbFFmTotalLastExtraDof,l+nbFFmTotalLastExtraDof) -= dqdGradFieldm->operator()(q,p)*
+                                     (Gradsm[l+nbFFmTotalLastExtraDof][p]*Valsm[j+nbFFmTotalLastExtraDof]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
                   }
                 }
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpExtraDof;l++)
               {
                 for(int p = 0; p< 3; p++)
                 {
-                  stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= dqdFieldp->operator()(p)*
-                               (Valsp[l+indexField2*nbFFp]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                  stiff(j+nbFFmTotalLastExtraDof,l+nbFFpTotalLastExtraDof+nbdofm) -= dqdFieldp->operator()(p)*
+                               (Valsp[l+nbFFpTotalLastExtraDof]*Valsm[j+nbFFmTotalLastExtraDof]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
 
                   for(int q = 0; q< 3; q++)
                   {
-                    stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= dqdGradFieldp->operator()(q,p)*
-                                                 (Gradsp[l+indexField2*nbFFp][p]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                    stiff(j+nbFFmTotalLastExtraDof,l+nbFFpTotalLastExtraDof+nbdofm) -= dqdGradFieldp->operator()(q,p)*
+                                                 (Gradsp[l+nbFFpTotalLastExtraDof][p]*Valsm[j+nbFFmTotalLastExtraDof]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
 
                   }
                 }
               }
             }
-            for(int j=0;j<nbFFp;j++)
+            for(int j=0;j<nbFFpExtraDof;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmExtraDof;l++)
               {
                 for(int p = 0; p< 3; p++)
                 {
-                  stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += dqdFieldm->operator()(p)*(Valsm[l+indexField2*nbFFm]*
-                                Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                  stiff(j+nbFFpTotalLastExtraDof+nbdofm,l+nbFFmTotalLastExtraDof) += dqdFieldm->operator()(p)*(Valsm[l+nbFFmTotalLastExtraDof]*
+                                Valsp[j+nbFFpTotalLastExtraDof]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                   for(int q = 0; q< 3; q++)
                   {
 
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += dqdGradFieldm->operator()(q,p)*
-                                    (Gradsm[l+indexField2*nbFFm][p]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                      stiff(j+nbFFpTotalLastExtraDof+nbdofm,l+nbFFmTotalLastExtraDof) += dqdGradFieldm->operator()(q,p)*
+                                    (Gradsm[l+nbFFmTotalLastExtraDof][p]*Valsp[j+nbFFpTotalLastExtraDof]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
                   }
                 }
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpExtraDof;l++)
               {
                 for(int p = 0; p< 3; p++)
                 {
-                  stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += dqdFieldp->operator()(p)*
-                              (Valsp[l+indexField2*nbFFp]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                  stiff(j+nbFFpTotalLastExtraDof+nbdofm,l+nbFFpTotalLastExtraDof+nbdofm) += dqdFieldp->operator()(p)*
+                              (Valsp[l+nbFFpTotalLastExtraDof]*Valsp[j+nbFFpTotalLastExtraDof]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                   for(int q = 0; q< 3; q++)
                   {
 
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += dqdGradFieldp->operator()(q,p)*(Gradsp[l+indexField2*nbFFp][p]*
-                                Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                    stiff(j+nbFFpTotalLastExtraDof+nbdofm,l+nbFFpTotalLastExtraDof+nbdofm) += dqdGradFieldp->operator()(q,p)*(Gradsp[l+nbFFpTotalLastExtraDof][p]*
+                                Valsp[j+nbFFpTotalLastExtraDof]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
                   }
                 }
               }
@@ -3544,98 +3545,98 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
             }
 
             // Assembly stability (if not broken)
-            for(int j=0;j<nbFFm;j++)
+            for(int j=0;j<nbFFmExtraDof;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmExtraDof;l++)
               {
-                stiff(j+indexField*nbFFm,l+indexField*nbFFm) -= dfieldJumpdFieldm*NMeankNBetasc*
-                                      (Valsm[j+indexField*nbFFm]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                stiff(j+nbFFmTotalLastExtraDof,l+nbFFmTotalLastExtraDof) -= dfieldJumpdFieldm*NMeankNBetasc*
+                                      (Valsm[j+nbFFmTotalLastExtraDof]*Valsm[l+nbFFmTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                  stiff(j+indexField*nbFFm,l+indexField*nbFFm) -= oneOverFieldJump*dNMeankNBetascdFieldm*
-                                      (Valsm[j+indexField*nbFFm]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  stiff(j+nbFFmTotalLastExtraDof,l+nbFFmTotalLastExtraDof) -= oneOverFieldJump*dNMeankNBetascdFieldm*
+                                      (Valsm[j+nbFFmTotalLastExtraDof]*Valsm[l+nbFFmTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpExtraDof;l++)
               {
-                stiff(j+indexField*nbFFm,l+indexField*nbFFp+nbdofm) -= dfieldJumpdFieldp*NMeankNBetasc*
-                                      (Valsm[j+indexField*nbFFm]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                stiff(j+nbFFmTotalLastExtraDof,l+nbFFpTotalLastExtraDof+nbdofm) -= dfieldJumpdFieldp*NMeankNBetasc*
+                                      (Valsm[j+nbFFmTotalLastExtraDof]*Valsp[l+nbFFpTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                  stiff(j+indexField*nbFFm,l+indexField*nbFFp+nbdofm) -= oneOverFieldJump*dNMeankNBetascdFieldp*
-                                                  (Valsm[j+indexField*nbFFm]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  stiff(j+nbFFmTotalLastExtraDof,l+nbFFpTotalLastExtraDof+nbdofm) -= oneOverFieldJump*dNMeankNBetascdFieldp*
+                                                  (Valsm[j+nbFFmTotalLastExtraDof]*Valsp[l+nbFFpTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
               }
             }
-            for(int j=0;j<nbFFp;j++)
+            for(int j=0;j<nbFFpExtraDof;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmExtraDof;l++)
               {
-                stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFm) += dfieldJumpdFieldm*NMeankNBetasc*
-                                                  (Valsp[j+indexField*nbFFp]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                stiff(j+nbFFpTotalLastExtraDof+nbdofm,l+nbFFmTotalLastExtraDof) += dfieldJumpdFieldm*NMeankNBetasc*
+                                                  (Valsp[j+nbFFpTotalLastExtraDof]*Valsm[l+nbFFmTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                  stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFm) += oneOverFieldJump*dNMeankNBetascdFieldm*
-                                                  (Valsp[j+indexField*nbFFp]*Valsm[l+indexField*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  stiff(j+nbFFpTotalLastExtraDof+nbdofm,l+nbFFmTotalLastExtraDof) += oneOverFieldJump*dNMeankNBetascdFieldm*
+                                                  (Valsp[j+nbFFpTotalLastExtraDof]*Valsm[l+nbFFmTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpExtraDof;l++)
               {
-                stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += dfieldJumpdFieldp*NMeankNBetasc*
-                                                  (Valsp[j+indexField*nbFFp]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                stiff(j+nbFFpTotalLastExtraDof+nbdofm,l+nbFFpTotalLastExtraDof+nbdofm) += dfieldJumpdFieldp*NMeankNBetasc*
+                                                  (Valsp[j+nbFFpTotalLastExtraDof]*Valsp[l+nbFFpTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                 if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                  stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += oneOverFieldJump*dNMeankNBetascdFieldp*
-                                                  (Valsp[j+indexField*nbFFp]*Valsp[l+indexField*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                  stiff(j+nbFFpTotalLastExtraDof+nbdofm,l+nbFFpTotalLastExtraDof+nbdofm) += oneOverFieldJump*dNMeankNBetascdFieldp*
+                                                  (Valsp[j+nbFFpTotalLastExtraDof]*Valsp[l+nbFFpTotalLastExtraDof]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
               }
             }
             // compatibility
             // Assembly (loop on shape function)
-            for(int j=0;j<nbFFm;j++)
+            for(int j=0;j<nbFFmExtraDof;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmExtraDof;l++)
               {
                 for(int p =0; p < 3; p++)
                 {
                   for(int q =0; q < 3; q++)
                   {
-                    stiff(j+indexField*nbFFm,l+indexField*nbFFm) += dfieldJumpdFieldm*(k0m(p,q)*
-                                                  Gradsm[j+indexField*nbFFm][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+indexField*nbFFm]);
+                    stiff(j+nbFFmTotalLastExtraDof,l+nbFFmTotalLastExtraDof) += dfieldJumpdFieldm*(k0m(p,q)*
+                                                  Gradsm[j+nbFFmTotalLastExtraDof][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+nbFFmTotalLastExtraDof]);
                     if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                      stiff(j+indexField*nbFFm,l+indexField*nbFFm) += oneOverFieldJump*(dk0mdFieldm(p,q)*
-                                                  Gradsm[j+indexField*nbFFm][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+indexField*nbFFm]);
+                      stiff(j+nbFFmTotalLastExtraDof,l+nbFFmTotalLastExtraDof) += oneOverFieldJump*(dk0mdFieldm(p,q)*
+                                                  Gradsm[j+nbFFmTotalLastExtraDof][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+nbFFmTotalLastExtraDof]);
                   }
                 }
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpExtraDof;l++)
               {
                 for(int p =0; p < 3; p++)
                 {
                   for(int q =0; q < 3; q++)
                   {
-                    stiff(j+indexField*nbFFm,l+indexField*nbFFp+nbdofm) += dfieldJumpdFieldp*(k0m(p,q)*
-                                                Gradsm[j+indexField*nbFFm][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+indexField*nbFFp]);
+                    stiff(j+nbFFmTotalLastExtraDof,l+nbFFpTotalLastExtraDof+nbdofm) += dfieldJumpdFieldp*(k0m(p,q)*
+                                                Gradsm[j+nbFFmTotalLastExtraDof][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+nbFFpTotalLastExtraDof]);
                   }
                 }
               }
             }
-            for(int j=0;j<nbFFp;j++)
+            for(int j=0;j<nbFFpExtraDof;j++)
             {
-              for(int l=0;l<nbFFm;l++)
+              for(int l=0;l<nbFFmExtraDof;l++)
               {
                 for(int p =0; p < 3; p++)
                 {
                   for(int q =0; q < 3; q++)
                   {
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFm) += dfieldJumpdFieldm*(k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*
-                                               (nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+indexField*nbFFm]);
+                    stiff(j+nbFFpTotalLastExtraDof+nbdofm,l+nbFFmTotalLastExtraDof) += dfieldJumpdFieldm*(k0p(p,q)*Gradsp[j+nbFFpTotalLastExtraDof][q])*
+                                               (nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsm[l+nbFFmTotalLastExtraDof]);
                   }
                 }
               }
-              for(int l=0;l<nbFFp;l++)
+              for(int l=0;l<nbFFpExtraDof;l++)
               {
                 for(int p =0; p < 3; p++)
                 {
                   for(int q =0; q < 3; q++)
                   {
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += dfieldJumpdFieldp*(k0p(p,q)*
-                                      Gradsp[j+indexField*nbFFp][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+indexField*nbFFp]);
+                    stiff(j+nbFFpTotalLastExtraDof+nbdofm,l+nbFFpTotalLastExtraDof+nbdofm) += dfieldJumpdFieldp*(k0p(p,q)*
+                                      Gradsp[j+nbFFpTotalLastExtraDof][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+nbFFpTotalLastExtraDof]);
                     if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += oneOverFieldJump*
-                                 (dk0pdFieldp(p,q)*Gradsp[j+indexField*nbFFp][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+indexField*nbFFp]);
+                      stiff(j+nbFFpTotalLastExtraDof+nbdofm,l+nbFFpTotalLastExtraDof+nbdofm) += oneOverFieldJump*
+                                 (dk0pdFieldp(p,q)*Gradsp[j+nbFFpTotalLastExtraDof][q])*(nu(p)*wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*Valsp[l+nbFFpTotalLastExtraDof]);
                   }
                 }
               }
@@ -3644,6 +3645,9 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           }
           else if (getNumConstitutiveExtraDofDiffusionVariable() == 2 && getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) // electro-thermomec
           {
+            int nbFFm = em->getNumShapeFunctions();
+            int nbFFp = ep->getNumShapeFunctions();
+            
             for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
             {
               const double fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
@@ -4143,6 +4147,8 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           }
           else if (getNumConstitutiveExtraDofDiffusionVariable() == 2 && !getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) // electro-thermomec
           {
+            int nbFFm = em->getNumShapeFunctions();
+            int nbFFp = ep->getNumShapeFunctions();
             for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
             {
               const double fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
@@ -4592,6 +4598,8 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           // EXTRADOF - displacement
           for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
+            int nbFFm = em->getNumShapeFunctions();
+            int nbFFp = ep->getNumShapeFunctions();
 
             const STensor33 *dqdFm = &(ipvm->getConstRefTodFluxdF()[extraDOFField]);
             const STensor33 *dqdFp = &(ipvp->getConstRefTodFluxdF()[extraDOFField]);
@@ -4723,6 +4731,9 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           // additional term 
           for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
+            int nbFFm = em->getNumShapeFunctions();
+            int nbFFp = ep->getNumShapeFunctions();
+            
             if(extraDOFField==0)
             {
               double fieldp=0.;
-- 
GitLab


From f3aca1be21c9002f78f596b7a6358fce185e1029 Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Tue, 2 Jun 2020 10:58:13 +0200
Subject: [PATCH 14/19] seperate extraDof-displacement coupling

---
 dG3D/src/dG3DTerms.cpp | 406 +++++++++++++----------------------------
 1 file changed, 128 insertions(+), 278 deletions(-)

diff --git a/dG3D/src/dG3DTerms.cpp b/dG3D/src/dG3DTerms.cpp
index 8c65f6088..8e47e0e4a 100644
--- a/dG3D/src/dG3DTerms.cpp
+++ b/dG3D/src/dG3DTerms.cpp
@@ -3675,9 +3675,6 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 const STensor3& dk0mdField2m = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField2];
                 const STensor3& dk0pdField2p = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField2];
 
-                const STensor43& dk0mdFm  = ipvm->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
-                const STensor43& dk0pdFp  = ipvp->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
-
                 const STensor3& dk0mdField_auxm = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField_aux];
                 const STensor3& dk0pdField_auxp = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField_aux];
                 const STensor3& dk0mdField_aux2m= ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField_aux];
@@ -3827,9 +3824,6 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 double dNMeankNBetascdField_auxm=0.;
                 double dNMeankNBetascdField_aux2p=0.;
                 double dNMeankNBetascdField_aux2m=0.;          
-                static STensor3 dNMeankNBetascdFm, dNMeankNBetascdFp;
-
-                STensorOperation::zero(dNMeankNBetascdFm); STensorOperation::zero(dNMeankNBetascdFp);
 
                 for(int l = 0; l <3; l++)
                 {
@@ -3846,15 +3840,6 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     dNMeankNBetascdField_auxm += dk0mdField_auxm(l,n)*nu(n)*nbetahs*nu(l)/2.; 
                     dNMeankNBetascdField_aux2p += dk0pdField_aux2p(l,n)*nu(n)*nbetahs*nu(l)/2.;         
                     dNMeankNBetascdField_aux2m += dk0mdField_aux2m(l,n)*nu(n)*nbetahs*nu(l)/2.;                 
-                  
-                    for(int j = 0; j<3; j++)
-                      {
-                       for(int p = 0; p<3; p++)
-                        {
-                          dNMeankNBetascdFm(j,p)+=dk0mdFm(l,n,j,p)*nu(j)*nbetahs*nu(p)/2.;
-                          dNMeankNBetascdFp(j,p)+=dk0pdFp(l,n,j,p)*nu(j)*nbetahs*nu(p)/2.;
-                       }                
-                     }
                   }
                 }
 
@@ -3905,108 +3890,6 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 }
      
 
-                for(int j=0;j<nbFFm;j++)
-                {
-                  for(int k=0;k<3;k++)
-                  {
-                    for(int l=0;l<nbFFm;l++)
-                    {
-                      if(useBarF)
-                      {
-                        for(int ii=0; ii<3; ii++)
-                        {
-                          for(int p=0; p<3; p++)
-                          {
-                            stiff(j+indexField*nbFFm,l+k*nbFFm) -= fieldJump*dNMeankNBetascdFm(ii,p)*dBarFdum[i][l](ii,p,k)*Valsm[j+indexField*nbFFm]*
-                                                               wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                          }
-                        }
-                      }
-                      else
-                      {
-                        for(int p=0;p<3;p++)
-                        {
-                          stiff(j+indexField*nbFFm,l+k*nbFFm) -= fieldJump*dNMeankNBetascdFm(k,p)*Gradsm[l+0*nbFFm][p]*Valsm[j+indexField*nbFFm]*
-                                                               wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                        }
-                      }
-                    }
-                    for(int l=0;l<nbFFp;l++)
-                    {
-                      if(useBarF)
-                      {
-                        for(int ii=0; ii<3; ii++)
-                        {
-                          for(int p=0; p<3; p++)
-                          {
-                           stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= fieldJump*dNMeankNBetascdFp(ii,p)*dBarFdup[i][l](ii,p,k)*Valsm[j+indexField*nbFFm]*
-                                                                  wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                          }
-                        }
-                      }
-                      else
-                      {
-                        for(int p=0;p<3;p++)
-                        {
-                          stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= fieldJump*dNMeankNBetascdFp(k,p)*Gradsp[l+0*nbFFp][p]*Valsm[j+indexField*nbFFm]*
-                                                                 wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                        }
-                      }
-                    }
-                  } 
-                }
-
-                for(int j=0;j<nbFFp;j++)
-                {
-                  for(int k=0;k<3;k++)
-                  {
-                    for(int l=0;l<nbFFm;l++)
-                    {
-                      if(useBarF)
-                      {
-                        for(int ii=0; ii<3; ii++)
-                        {
-                          for(int p=0; p<3; p++)
-                          {
-                            stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFm) += fieldJump*dNMeankNBetascdFm(ii,p)*dBarFdum[i][l](ii,p,k)*Valsp[j+indexField*nbFFp]*
-                                                                        wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                          }
-                        }
-                      }
-                      else
-                      {
-                        for(int p=0;p<3;p++)
-                        {
-                          stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFm) += fieldJump*dNMeankNBetascdFm(k,p)*Gradsm[l+0*nbFFm][p]*Valsp[j+indexField*nbFFp]*
-                                                                        wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                        }
-                      }
-                    }
-
-                    for(int l=0;l<nbFFp;l++)
-                    {
-                      if(useBarF)
-                      {
-                        for(int ii=0; ii<3; ii++)
-                        {
-                          for(int p=0; p<3; p++)
-                          {
-                            stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFp+nbdofm) +=fieldJump*dNMeankNBetascdFp(ii,p)*dBarFdup[i][l](ii,p,k)*Valsp[j+indexField*nbFFp]*
-                                                                         wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                          }
-                        }
-                      }
-                      else
-                      {
-                        for(int p=0;p<3;p++)
-                        {
-                          stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFp+nbdofm) +=fieldJump*dNMeankNBetascdFp(k,p)*Gradsp[l+0*nbFFp][p]*Valsp[j+indexField*nbFFp]*
-                                                                         wJ*getConstitutiveExtraDofDiffusionEqRatio();
-                        }
-                      }
-                    }
-                  }
-                }
                 // compatibility
                 // Assembly (loop on shape function)
 
@@ -4071,77 +3954,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                   }
                 }
                
-                for(int j=0;j<nbFFm;j++)
-                {
-                  for(int l=0;l<nbFFm;l++)
-                  {
-                    for(int m =0; m < 3; m++)
-                    {
-                      for(int p =0; p < 3; p++)
-                      {
-                        for(int q =0; q < 3; q++)
-                        {
-                          if(useBarF)
-                          {
-                            for(int ii=0; ii<3; ii++)
-                            {
-                              for(int n=0; n<3; n++)
-                              {
-                                stiff(j+indexField*nbFFm,l+m*nbFFm) += fieldJump*(dk0mdFm(p,q,ii,n)*
-                                          Gradsm[j+indexField*nbFFm][q]*dBarFdum[i][l](ii,n,m))*(nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-                              }
-                            }
-                          }
-                          else
-                          {
-                            for(int n =0; n< 3; n++)
-                            {
-                              stiff(j+indexField*nbFFm,l+m*nbFFm) += fieldJump*(dk0mdFm(p,q,m,n)*
-                                          Gradsm[j+indexField*nbFFm][q]*Gradsm[l+0*nbFFm][n])*(nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-                            }
-                          }
-                        }
-                      }
-                    }
-                  }
-                }
-
-                for(int j=0;j<nbFFp;j++)
-                {
-                  for(int l=0;l<nbFFp;l++)
-                  {
-                    for(int m =0; m < 3; m++)
-                    {
-                      for(int q =0; q< 3; q++)
-                      {
-                        for(int p =0; p < 3; p++)
-                        {
-                          if(useBarF)
-                          {
-                            for(int ii=0; ii<3; ii++)
-                            {
-                              for(int n=0; n<3; n++)
-                              {
-                                stiff(j+indexField*nbFFp+nbdofm,l+m*nbFFp+nbdofm) += fieldJump*(dk0pdFp(p,q,ii,n)*
-                                          Gradsp[j+indexField*nbFFp][q]*dBarFdup[i][l](ii,n,m))*
-                                          (nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-                              }
-                            }
-                          }
-                          else
-                          {
-                            for(int n =0; n < 3; n++)
-                            {
-                              stiff(j+indexField*nbFFp+nbdofm,l+m*nbFFp+nbdofm) += fieldJump*(dk0pdFp(p,q,m,n)*
-                                          Gradsp[j+indexField*nbFFp][q]*Gradsp[l+0*nbFFp][n])*
-                                          (nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-                            }
-                          }
-                        }
-                      }
-                    }
-                  }
-                }
+                
               }
             }
           }
@@ -4175,9 +3988,6 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 const STensor3& dk0pdFieldp  = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField2][extraDOFField2];
                 const STensor3& dk0mdField2m = ipvm->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField2];
                 const STensor3& dk0pdField2p = ipvp->getConstRefTodLinearKdField()[extraDOFField][extraDOFField_aux][extraDOFField2];
-
-                const STensor43& dk0mdFm  = ipvm->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
-                const STensor43& dk0pdFp  = ipvp->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
                 
                 double dfieldJumpdFieldp, dfieldJumpdFieldm, dfieldJumpdField2p, dfieldJumpdField2m;
                 static STensor3 k02m, k02p;
@@ -4278,10 +4088,6 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 double dNMeankNBetascdField_auxm=0.;
                 double dNMeankNBetascdField_aux2p=0.;
                 double dNMeankNBetascdField_aux2m=0.;          
-                static STensor3 dNMeankNBetascdFm, dNMeankNBetascdFp;
-
-                STensorOperation::zero(dNMeankNBetascdFm); 
-                STensorOperation::zero(dNMeankNBetascdFp);
 
                 for(int l = 0; l <3; l++)
                 {
@@ -4294,15 +4100,6 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     dNMeankNBetascdFieldm  += dk0mdFieldm(l,n)*nu(n)*nbetahs*nu(l)/2.;
                     dNMeankNBetascdField2p += dk0pdField2p(l,n)*nu(n)*nbetahs*nu(l)/2.;
                     dNMeankNBetascdField2m += dk0mdField2m(l,n)*nu(n)*nbetahs*nu(l)/2.; 
-                    
-                    for(int j = 0; j<3; j++)
-                      {
-                       for(int p = 0; p<3; p++)
-                        {
-                          dNMeankNBetascdFm(j,p)+=dk0mdFm(l,n,j,p)*nu(j)*nbetahs*nu(p)/2.;
-                          dNMeankNBetascdFp(j,p)+=dk0pdFp(l,n,j,p)*nu(j)*nbetahs*nu(p)/2.;
-                       }                
-                     }
                   }
                 }
                 // Assembly stability (if not broken)
@@ -4342,6 +4139,129 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 }
      
 
+                
+                // compatibility
+                // Assembly (loop on shape function)
+
+                for(int j=0;j<nbFFm;j++)
+                {
+                  for(int l=0;l<nbFFm;l++)
+                  {
+                    for(int p =0; p < 3; p++)
+                    {
+                      for(int q =0; q < 3; q++)
+                      {
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += ((k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*Valsm[l+indexField2*nbFFm]*
+                                          dfieldJumpdFieldm*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+((k02m(p,q)*Gradsm[j+indexField*nbFFm][q])*
+                                          nu(p)*Valsm[l+indexField2*nbFFm]*dfieldJumpdField2m*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += (fieldJump*(dk0mdFieldm(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
+                                          Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
+                                          (fieldJump2*(dk0mdField2m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
+                                          Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                      }
+                    }
+                  }
+                  for(int l=0;l<nbFFp;l++)
+                  {
+                    for(int p =0; p < 3; p++)
+                    {
+                      for(int q =0; q < 3; q++)
+                      {
+                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) += ((k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
+                                              Valsp[l+indexField2*nbFFp]*dfieldJumpdFieldp*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
+                                              ((k02m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*Valsp[l+indexField2*nbFFp]*
+                                              dfieldJumpdField2p*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                      }
+                    }
+                  }
+                }
+
+                for(int j=0;j<nbFFp;j++)
+                {
+                  for(int l=0;l<nbFFm;l++)
+                  {
+                    for(int p =0; p < 3; p++)
+                    {
+                      for(int q =0; q < 3; q++)
+                      {
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += ((k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
+                                               Valsm[l+indexField2*nbFFm]*dfieldJumpdFieldm*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
+                                               ((k02p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*Valsm[l+indexField2*nbFFm]*
+                                               dfieldJumpdField2m*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                      }
+                    }
+                  }
+                  for(int l=0;l<nbFFp;l++)
+                  {
+                    for(int p =0; p < 3; p++)
+                    {
+                      for(int q =0; q < 3; q++)
+                      {
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += ((k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
+                                                       Valsp[l+indexField2*nbFFp]*dfieldJumpdFieldp*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
+                                                      ((k02p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*Valsp[l+indexField2*nbFFp]*
+                                                      dfieldJumpdField2p*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*(dk0pdFieldp(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
+                                                      Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
+                                                      (fieldJump2*(dk0pdField2p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
+                                                      Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                      }
+                    }
+                  }
+                }
+               
+                
+                
+              }
+            }
+          }
+          else
+          {
+            Msg::Error("extraDof with more than 2 extra dofs not implemented");
+          }
+        
+          // EXTRADOF - displacement
+          
+          if (getNumConstitutiveExtraDofDiffusionVariable() == 1)
+          {
+            // not
+          }
+          else if (getNumConstitutiveExtraDofDiffusionVariable() == 2)
+          {
+            int nbFFm = em->getNumShapeFunctions();
+            int nbFFp = ep->getNumShapeFunctions();
+            
+            for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
+            {
+                        
+              int indexField=3+getNumNonLocalVariable()+extraDOFField;
+              for (int extraDOFField2 = 0; extraDOFField2< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField2++)
+              {
+                double fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField2);
+                const STensor43& dk0mdFm  = ipvm->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
+                const STensor43& dk0pdFp  = ipvp->getConstRefTodLinearKdF()[extraDOFField][extraDOFField2];
+                
+                static STensor3 dNMeankNBetascdFm, dNMeankNBetascdFp;
+                STensorOperation::zero(dNMeankNBetascdFm); 
+                STensorOperation::zero(dNMeankNBetascdFp);
+
+                for(int l = 0; l <3; l++)
+                {
+                  for(int n = 0; n <3; n++)
+                  {                    
+                    for(int j = 0; j<3; j++)
+                      {
+                       for(int p = 0; p<3; p++)
+                        {
+                          dNMeankNBetascdFm(j,p)+=dk0mdFm(l,n,j,p)*nu(j)*nbetahs*nu(p)/2.;
+                          dNMeankNBetascdFp(j,p)+=dk0pdFp(l,n,j,p)*nu(j)*nbetahs*nu(p)/2.;
+                       }                
+                     }
+                  }
+                }
+                
+                int indexField2=3+getNumNonLocalVariable()+extraDOFField2;
                 for(int j=0;j<nbFFm;j++)
                 {
                   for(int k=0;k<3;k++)
@@ -4444,77 +4364,8 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     }
                   }
                 }
-                // compatibility
-                // Assembly (loop on shape function)
-
-                for(int j=0;j<nbFFm;j++)
-                {
-                  for(int l=0;l<nbFFm;l++)
-                  {
-                    for(int p =0; p < 3; p++)
-                    {
-                      for(int q =0; q < 3; q++)
-                      {
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += ((k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*Valsm[l+indexField2*nbFFm]*
-                                          dfieldJumpdFieldm*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+((k02m(p,q)*Gradsm[j+indexField*nbFFm][q])*
-                                          nu(p)*Valsm[l+indexField2*nbFFm]*dfieldJumpdField2m*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += (fieldJump*(dk0mdFieldm(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
-                                          Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
-                                          (fieldJump2*(dk0mdField2m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
-                                          Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-                      }
-                    }
-                  }
-                  for(int l=0;l<nbFFp;l++)
-                  {
-                    for(int p =0; p < 3; p++)
-                    {
-                      for(int q =0; q < 3; q++)
-                      {
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) += ((k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
-                                              Valsp[l+indexField2*nbFFp]*dfieldJumpdFieldp*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
-                                              ((k02m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*Valsp[l+indexField2*nbFFp]*
-                                              dfieldJumpdField2p*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-                      }
-                    }
-                  }
-                }
-
-                for(int j=0;j<nbFFp;j++)
-                {
-                  for(int l=0;l<nbFFm;l++)
-                  {
-                    for(int p =0; p < 3; p++)
-                    {
-                      for(int q =0; q < 3; q++)
-                      {
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += ((k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
-                                               Valsm[l+indexField2*nbFFm]*dfieldJumpdFieldm*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
-                                               ((k02p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*Valsm[l+indexField2*nbFFm]*
-                                               dfieldJumpdField2m*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-                      }
-                    }
-                  }
-                  for(int l=0;l<nbFFp;l++)
-                  {
-                    for(int p =0; p < 3; p++)
-                    {
-                      for(int q =0; q < 3; q++)
-                      {
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += ((k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
-                                                       Valsp[l+indexField2*nbFFp]*dfieldJumpdFieldp*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
-                                                      ((k02p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*Valsp[l+indexField2*nbFFp]*
-                                                      dfieldJumpdField2p*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*(dk0pdFieldp(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
-                                                      Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
-                                                      (fieldJump2*(dk0pdField2p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
-                                                      Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-                      }
-                    }
-                  }
-                }
-               
+                //
+                
                 for(int j=0;j<nbFFm;j++)
                 {
                   for(int l=0;l<nbFFm;l++)
@@ -4586,7 +4437,6 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     }
                   }
                 }
-                
               }
             }
           }
@@ -4594,8 +4444,8 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           {
             Msg::Error("extraDof with more than 2 extra dofs not implemented");
           }
-        
-          // EXTRADOF - displacement
+          
+          
           for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
             int nbFFm = em->getNumShapeFunctions();
-- 
GitLab


From fed5bb4a10768d4ddd09c302e89606688287441a Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Tue, 2 Jun 2020 13:54:46 +0200
Subject: [PATCH 15/19] done dgterms

---
 dG3D/src/dG3DTerms.cpp | 512 +++++++++++++++++++++--------------------
 1 file changed, 267 insertions(+), 245 deletions(-)

diff --git a/dG3D/src/dG3DTerms.cpp b/dG3D/src/dG3DTerms.cpp
index 8e47e0e4a..3f7ea5d6d 100644
--- a/dG3D/src/dG3DTerms.cpp
+++ b/dG3D/src/dG3DTerms.cpp
@@ -3644,16 +3644,19 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
             
           }
           else if (getNumConstitutiveExtraDofDiffusionVariable() == 2 && getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) // electro-thermomec
-          {
-            int nbFFm = em->getNumShapeFunctions();
-            int nbFFp = ep->getNumShapeFunctions();
-            
+          {            
             for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
             {
               const double fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
               const double fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
                         
               int indexField=3+getNumNonLocalVariable()+extraDOFField;
+              int nbFFmTotalLastExtraDofRow = _minusSpace->getShapeFunctionsIndex(em,indexField);
+              int nbFFpTotalLastExtraDofRow = _plusSpace->getShapeFunctionsIndex(ep,indexField);
+              int nbFFmExtraDofRow = _minusSpace->getNumShapeFunctions(em,indexField);
+              int nbFFpExtraDofRow = _plusSpace->getNumShapeFunctions(ep,indexField);
+
+              
               for (int extraDOFField2 = 0; extraDOFField2< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField2++)
               {
                 const STensor3  *dqdGradFieldm = &(ipvm->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField2]);
@@ -3702,109 +3705,113 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 
                 //
                 int indexField2=3+getNumNonLocalVariable()+extraDOFField2;
-                for(int j=0;j<nbFFm;j++)
+                int nbFFmTotalLastExtraDofCol = _minusSpace->getShapeFunctionsIndex(em,indexField2);
+                int nbFFpTotalLastExtraDofCol = _plusSpace->getShapeFunctionsIndex(ep,indexField2);
+                int nbFFmExtraDofCol = _minusSpace->getNumShapeFunctions(em,indexField2);
+                int nbFFpExtraDofCol = _plusSpace->getNumShapeFunctions(ep,indexField2);
+                for(int j=0;j<nbFFmExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
                     for(int p = 0; p< 3; p++)
                     {
-                      stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (dqdFieldm->operator()(p)*dFielddEnergyConjugatedFieldm+dqdField2m(p)*
-                                                           dFielddEnergyConjugatedField2m)*(Valsm[l+indexField2*nbFFm]*Valsm[j+indexField*nbFFm]*
+                      stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) -= (dqdFieldm->operator()(p)*dFielddEnergyConjugatedFieldm+dqdField2m(p)*
+                                                           dFielddEnergyConjugatedField2m)*(Valsm[l+nbFFmTotalLastExtraDofCol]*Valsm[j+nbFFmTotalLastExtraDofRow]*
                                                            getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                    
                       for(int q = 0; q< 3; q++)
                       {
 
-                          stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -=(dqdGradFieldm->operator()(p,q)*dGradFielddEnergyConjugatedFieldm(q)+dqdGradField2m(p,q)*
-                                                        dGradFielddEnergyConjugatedField2m(q))*(Valsm[j+indexField*nbFFm]*
-                                                        Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                          stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) -=(dqdGradFieldm->operator()(p,q)*dGradFielddEnergyConjugatedFieldm(q)+dqdGradField2m(p,q)*
+                                                        dGradFielddEnergyConjugatedField2m(q))*(Valsm[j+nbFFmTotalLastExtraDofRow]*
+                                                        Valsm[l+nbFFmTotalLastExtraDofCol]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                    
 
                           for(int o = 0; o< 3; o++)
                           {
 
-                            stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -=(dqdGradFieldm->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldm(o,q)+dqdGradField2m(p,o)*
-                                                       dGradFielddGradEnergyConjugatedField2m(o,q))*Valsm[j+indexField*nbFFm]*
-                                                       (Gradsm[l+indexField2*nbFFm][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                            stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) -=(dqdGradFieldm->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldm(o,q)+dqdGradField2m(p,o)*
+                                                       dGradFielddGradEnergyConjugatedField2m(o,q))*Valsm[j+nbFFmTotalLastExtraDofRow]*
+                                                       (Gradsm[l+nbFFmTotalLastExtraDofCol][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                           }
                          
                       }
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
                     for(int p = 0; p< 3; p++)
                     {
                       
-                      stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (dqdFieldp->operator()(p)*dFielddEnergyConjugatedFieldp+dqdField2p(p)*
-                                    dFielddEnergyConjugatedField2p)*(Valsp[l+indexField2*nbFFp]*
-                                    Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                      stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFpTotalLastExtraDofCol+nbdofm) -= (dqdFieldp->operator()(p)*dFielddEnergyConjugatedFieldp+dqdField2p(p)*
+                                    dFielddEnergyConjugatedField2p)*(Valsp[l+nbFFpTotalLastExtraDofCol]*
+                                    Valsm[j+nbFFmTotalLastExtraDofRow]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
 
                       for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (dqdGradFieldp->operator()(p,q)*
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFpTotalLastExtraDofCol+nbdofm) -= (dqdGradFieldp->operator()(p,q)*
                                                      dGradFielddEnergyConjugatedFieldp(q)+dqdGradField2p(p,q)*dGradFielddEnergyConjugatedField2p(q))*
-                                                     Valsm[j+indexField*nbFFm]*(Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                                                     Valsm[j+nbFFmTotalLastExtraDofRow]*(Valsp[l+nbFFpTotalLastExtraDofCol]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
 
     
                         for(int o = 0; o< 3; o++)
                         {
 
-                          stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -=(dqdGradFieldp->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldp(o,q)+
-                                                      dqdGradField2p(p,o)*dGradFielddGradEnergyConjugatedField2p(o,q))*Valsm[j+indexField*nbFFm]*
-                                                      (Gradsp[l+indexField2*nbFFp][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                          stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFpTotalLastExtraDofCol+nbdofm) -=(dqdGradFieldp->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldp(o,q)+
+                                                      dqdGradField2p(p,o)*dGradFielddGradEnergyConjugatedField2p(o,q))*Valsm[j+nbFFmTotalLastExtraDofRow]*
+                                                      (Gradsp[l+nbFFpTotalLastExtraDofCol][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                         
                         }
                       }
                     }
                   }
                 }
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
                     for(int p = 0; p< 3; p++)
                     {
-                       stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += (dqdFieldm->operator()(p)*dFielddEnergyConjugatedFieldm+dqdField2m(p)*
+                       stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFmTotalLastExtraDofCol) += (dqdFieldm->operator()(p)*dFielddEnergyConjugatedFieldm+dqdField2m(p)*
                                    dFielddEnergyConjugatedField2m)*
-                                   (Valsm[l+indexField2*nbFFm]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                                   (Valsm[l+nbFFmTotalLastExtraDofCol]*Valsp[j+nbFFpTotalLastExtraDofRow]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                       for(int q = 0; q< 3; q++)
                       {
 
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) +=(dqdGradFieldm->operator()(p,q)*dGradFielddEnergyConjugatedFieldm(q)+
-                                        dqdGradField2m(p,q)*dGradFielddEnergyConjugatedField2m(q))*Valsp[j+indexField*nbFFp]*
-                                        (Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFmTotalLastExtraDofCol) +=(dqdGradFieldm->operator()(p,q)*dGradFielddEnergyConjugatedFieldm(q)+
+                                        dqdGradField2m(p,q)*dGradFielddEnergyConjugatedField2m(q))*Valsp[j+nbFFpTotalLastExtraDofRow]*
+                                        (Valsm[l+nbFFmTotalLastExtraDofCol]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                         for(int o = 0; o< 3; o++)
                         {
 
-                          stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) +=(dqdGradFieldm->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldm(o,q)+
-                                               dqdGradField2m(p,o)*dGradFielddGradEnergyConjugatedField2m(o,q))*Valsp[j+indexField*nbFFp]*
-                                               (Gradsm[l+indexField2*nbFFm][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                          stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFmTotalLastExtraDofCol) +=(dqdGradFieldm->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldm(o,q)+
+                                               dqdGradField2m(p,o)*dGradFielddGradEnergyConjugatedField2m(o,q))*Valsp[j+nbFFpTotalLastExtraDofRow]*
+                                               (Gradsm[l+nbFFmTotalLastExtraDofCol][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                         }
                         
                       }
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
                     for(int p = 0; p< 3; p++)
                     {
 
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dqdFieldp->operator()(p)*dFielddEnergyConjugatedFieldp+
+                      stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += (dqdFieldp->operator()(p)*dFielddEnergyConjugatedFieldp+
                                                               dqdField2p(p)*dFielddEnergyConjugatedField2p)*
-                                  (Valsp[l+indexField2*nbFFp]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                                  (Valsp[l+nbFFpTotalLastExtraDofCol]*Valsp[j+nbFFpTotalLastExtraDofRow]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                       for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dqdGradFieldp->operator()(p,q)*dGradFielddEnergyConjugatedFieldp(q)+
-                                    dqdGradField2p(p,q)*dGradFielddEnergyConjugatedField2p(q))*(Valsp[j+indexField*nbFFp]*
-                                    Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += (dqdGradFieldp->operator()(p,q)*dGradFielddEnergyConjugatedFieldp(q)+
+                                    dqdGradField2p(p,q)*dGradFielddEnergyConjugatedField2p(q))*(Valsp[j+nbFFpTotalLastExtraDofRow]*
+                                    Valsp[l+nbFFpTotalLastExtraDofCol]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
 
                         for(int o = 0; o< 3; o++)
                         {
 
-                          stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dqdGradFieldp->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldp(o,q)+
-                                   dqdGradField2p(p,o)*dGradFielddGradEnergyConjugatedField2p(o,q))*Valsp[j+indexField*nbFFp]*
-                                   (Gradsp[l+indexField2*nbFFp][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                          stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += (dqdGradFieldp->operator()(p,o)*dGradFielddGradEnergyConjugatedFieldp(o,q)+
+                                   dqdGradField2p(p,o)*dGradFielddGradEnergyConjugatedField2p(o,q))*Valsp[j+nbFFpTotalLastExtraDofRow]*
+                                   (Gradsp[l+nbFFpTotalLastExtraDofCol][q]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                         }
                         
                       }
@@ -3853,39 +3860,39 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 dNMeankNBetascdField2m += (dNMeankNBetascdField_aux2p*dFielddEnergyConjugatedField2m);
 
                 // Assembly stability (if not broken)
-                for(int j=0;j<nbFFm;j++)
+                for(int j=0;j<nbFFmExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
-                    stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += NMeankNBetasc*(Valsm[j+indexField*nbFFm]*Valsm[l+indexField2*nbFFm]*
+                    stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) += NMeankNBetasc*(Valsm[j+nbFFmTotalLastExtraDofRow]*Valsm[l+nbFFmTotalLastExtraDofCol]*
                                                                         wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
-                                          (Valsm[j+indexField*nbFFm]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) -= (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
+                                          (Valsm[j+nbFFmTotalLastExtraDofRow]*Valsm[l+nbFFmTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
-                    stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= NMeankNBetasc*(Valsm[j+indexField*nbFFm]*
-                                          Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
-                                          (Valsm[j+indexField*nbFFm]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFpTotalLastExtraDofCol+nbdofm) -= NMeankNBetasc*(Valsm[j+nbFFmTotalLastExtraDofRow]*
+                                          Valsp[l+nbFFpTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFpTotalLastExtraDofCol+nbdofm) -= (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
+                                          (Valsm[j+nbFFmTotalLastExtraDofRow]*Valsp[l+nbFFpTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                   }
                 }
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) -= NMeankNBetasc*
-                                                         (Valsp[j+indexField*nbFFp]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
-                                                          (Valsp[j+indexField*nbFFp]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFmTotalLastExtraDofCol) -= NMeankNBetasc*
+                                                         (Valsp[j+nbFFpTotalLastExtraDofRow]*Valsm[l+nbFFmTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFmTotalLastExtraDofCol) += (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
+                                                          (Valsp[j+nbFFpTotalLastExtraDofRow]*Valsm[l+nbFFmTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += NMeankNBetasc*
-                                             (Valsp[j+indexField*nbFFp]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += NMeankNBetasc*
+                                             (Valsp[j+nbFFpTotalLastExtraDofRow]*Valsp[l+nbFFpTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
 
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
-                                             (Valsp[j+indexField*nbFFp]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
+                                             (Valsp[j+nbFFpTotalLastExtraDofRow]*Valsp[l+nbFFpTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                   }
                 }
      
@@ -3893,62 +3900,62 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 // compatibility
                 // Assembly (loop on shape function)
 
-                for(int j=0;j<nbFFm;j++)
+                for(int j=0;j<nbFFmExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
                     for(int p =0; p < 3; p++)
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
-                                                       Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += (fieldJump*(dk0mdFieldm(p,q)*dFielddEnergyConjugatedFieldm+dk0mdField_auxm(p,q)*
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) -= (k0m(p,q)*Gradsm[j+nbFFmTotalLastExtraDofRow][q])*nu(p)*
+                                                       Valsm[l+nbFFmTotalLastExtraDofCol]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) += (fieldJump*(dk0mdFieldm(p,q)*dFielddEnergyConjugatedFieldm+dk0mdField_auxm(p,q)*
                                           dFielddEnergyConjugatedField2m)+fieldJump2*(dk0mdField2m(p,q)*dFielddEnergyConjugatedFieldm+dk0mdField_aux2m(p,q)*
-                                          dFielddEnergyConjugatedField2m))*Gradsm[j+indexField*nbFFm][q]*nu(p)*Valsm[l+indexField2*nbFFm]*
+                                          dFielddEnergyConjugatedField2m))*Gradsm[j+nbFFmTotalLastExtraDofRow][q]*nu(p)*Valsm[l+nbFFmTotalLastExtraDofCol]*
                                           getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
                       }
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
                     for(int p =0; p < 3; p++)
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) += (k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
-                                              Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFpTotalLastExtraDofCol+nbdofm) += (k0m(p,q)*Gradsm[j+nbFFmTotalLastExtraDofRow][q])*nu(p)*
+                                              Valsp[l+nbFFpTotalLastExtraDofCol]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
                       }
                     }
                   }
                 }
 
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
                     for(int p =0; p < 3; p++)
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) -= (k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*
-                                               (nu(p)*Valsm[l+indexField2*nbFFm])*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFmTotalLastExtraDofCol) -= (k0p(p,q)*Gradsp[j+nbFFpTotalLastExtraDofRow][q])*
+                                               (nu(p)*Valsm[l+nbFFmTotalLastExtraDofCol])*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
                       }
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
                     for(int p =0; p < 3; p++)
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
-                                                      Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*(dk0pdFieldp(p,q)*
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += (k0p(p,q)*Gradsp[j+nbFFpTotalLastExtraDofRow][q])*nu(p)*
+                                                      Valsp[l+nbFFpTotalLastExtraDofCol]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.;
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += (fieldJump*(dk0pdFieldp(p,q)*
                                                       dFielddEnergyConjugatedFieldp+dk0pdField_auxp(p,q)*dFielddEnergyConjugatedField2p)+
                                                       fieldJump2*(dk0pdField2p(p,q)*dFielddEnergyConjugatedFieldp+
-                                                      dk0pdField_aux2p(p,q)*dFielddEnergyConjugatedField2p))*Gradsp[j+indexField*nbFFp][q]*
-                                                      (nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*(wJ/2.)*Valsp[l+indexField2*nbFFp]);
+                                                      dk0pdField_aux2p(p,q)*dFielddEnergyConjugatedField2p))*Gradsp[j+nbFFpTotalLastExtraDofRow][q]*
+                                                      (nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*(wJ/2.)*Valsp[l+nbFFpTotalLastExtraDofCol]);
                       }
                     }
                   }
@@ -3960,14 +3967,16 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           }
           else if (getNumConstitutiveExtraDofDiffusionVariable() == 2 && !getConstitutiveExtraDofDiffusionUseEnergyConjugatedField()) // electro-thermomec
           {
-            int nbFFm = em->getNumShapeFunctions();
-            int nbFFp = ep->getNumShapeFunctions();
             for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
             {
               const double fieldp = ipvp->getConstRefToEnergyConjugatedField(extraDOFField);
               const double fieldm = ipvm->getConstRefToEnergyConjugatedField(extraDOFField);
               
               int indexField=3+getNumNonLocalVariable()+extraDOFField;
+              int nbFFmTotalLastExtraDofRow = _minusSpace->getShapeFunctionsIndex(em,indexField);
+              int nbFFpTotalLastExtraDofRow = _plusSpace->getShapeFunctionsIndex(ep,indexField);
+              int nbFFmExtraDofRow = _minusSpace->getNumShapeFunctions(em,indexField);
+              int nbFFpExtraDofRow = _plusSpace->getNumShapeFunctions(ep,indexField);
               for (int extraDOFField2 = 0; extraDOFField2< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField2++)
               {
                 const STensor3  *dqdGradFieldm = &(ipvm->getConstRefTodFluxdGradField()[extraDOFField][extraDOFField2]);
@@ -4015,63 +4024,67 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 }
                 //
                 int indexField2=3+getNumNonLocalVariable()+extraDOFField2;
-                for(int j=0;j<nbFFm;j++)
+                int nbFFmTotalLastExtraDofCol = _minusSpace->getShapeFunctionsIndex(em,indexField2);
+                int nbFFpTotalLastExtraDofCol = _plusSpace->getShapeFunctionsIndex(ep,indexField2);
+                int nbFFmExtraDofCol = _minusSpace->getNumShapeFunctions(em,indexField2);
+                int nbFFpExtraDofCol = _plusSpace->getNumShapeFunctions(ep,indexField2);
+                for(int j=0;j<nbFFmExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
                     for(int p = 0; p< 3; p++)
                     {
 
-                      stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= dqdFieldm->operator()(p)*(Valsm[l+indexField2*nbFFm]*
-                                                            Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                      stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) -= dqdFieldm->operator()(p)*(Valsm[l+nbFFmTotalLastExtraDofCol]*
+                                                            Valsm[j+nbFFmTotalLastExtraDofRow]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                       for(int q = 0; q< 3; q++)
                       {
 
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= dqdGradFieldm->operator()(q,p)*
-                                         (Gradsm[l+indexField2*nbFFm][p]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) -= dqdGradFieldm->operator()(q,p)*
+                                         (Gradsm[l+nbFFmTotalLastExtraDofCol][p]*Valsm[j+nbFFmTotalLastExtraDofRow]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
                       }
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
                     for(int p = 0; p< 3; p++)
                     {
-                      stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= dqdFieldp->operator()(p)*
-                                   (Valsp[l+indexField2*nbFFp]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                      stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFpTotalLastExtraDofCol+nbdofm) -= dqdFieldp->operator()(p)*
+                                   (Valsp[l+nbFFpTotalLastExtraDofCol]*Valsm[j+nbFFmTotalLastExtraDofRow]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
 
                       for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= dqdGradFieldp->operator()(q,p)*
-                                                     (Gradsp[l+indexField2*nbFFp][p]*Valsm[j+indexField*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFpTotalLastExtraDofCol+nbdofm) -= dqdGradFieldp->operator()(q,p)*
+                                                     (Gradsp[l+nbFFpTotalLastExtraDofCol][p]*Valsm[j+nbFFmTotalLastExtraDofRow]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
                       }
                     }
                   }
                 }
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
                     for(int p = 0; p< 3; p++)
                     {
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += dqdFieldm->operator()(p)*(Valsm[l+indexField2*nbFFm]*
-                                    Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                      stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFmTotalLastExtraDofCol) += dqdFieldm->operator()(p)*(Valsm[l+nbFFmTotalLastExtraDofCol]*
+                                    Valsp[j+nbFFpTotalLastExtraDofRow]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                       for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += dqdGradFieldm->operator()(q,p)*
-                                        (Gradsm[l+indexField2*nbFFm][p]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFmTotalLastExtraDofCol) += dqdGradFieldm->operator()(q,p)*
+                                        (Gradsm[l+nbFFmTotalLastExtraDofCol][p]*Valsp[j+nbFFpTotalLastExtraDofRow]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
                       }
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
                     for(int p = 0; p< 3; p++)
                     {
-                      stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += dqdFieldp->operator()(p)*
-                                  (Valsp[l+indexField2*nbFFp]*Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
+                      stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += dqdFieldp->operator()(p)*
+                                  (Valsp[l+nbFFpTotalLastExtraDofCol]*Valsp[j+nbFFpTotalLastExtraDofRow]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(p));
                       for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += dqdGradFieldp->operator()(q,p)*(Gradsp[l+indexField2*nbFFp][p]*
-                                    Valsp[j+indexField*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += dqdGradFieldp->operator()(q,p)*(Gradsp[l+nbFFpTotalLastExtraDofCol][p]*
+                                    Valsp[j+nbFFpTotalLastExtraDofRow]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.*nu(q));
                       }
                     }
                   }
@@ -4103,38 +4116,38 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                   }
                 }
                 // Assembly stability (if not broken)
-                for(int j=0;j<nbFFm;j++)
+                for(int j=0;j<nbFFmExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
-                    stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (dfieldJumpdFieldm*NMeankNBetasc+dfieldJumpdField2m*NMeank2NBetasc)*
-                                          (Valsm[j+indexField*nbFFm]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    stiff(j+indexField*nbFFm,l+indexField2*nbFFm) -= (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
-                                          (Valsm[j+indexField*nbFFm]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) -= (dfieldJumpdFieldm*NMeankNBetasc+dfieldJumpdField2m*NMeank2NBetasc)*
+                                          (Valsm[j+nbFFmTotalLastExtraDofRow]*Valsm[l+nbFFmTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) -= (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
+                                          (Valsm[j+nbFFmTotalLastExtraDofRow]*Valsm[l+nbFFmTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
-                    stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (dfieldJumpdFieldp*NMeankNBetasc+dfieldJumpdField2p*NMeank2NBetasc)*
-                                          (Valsm[j+indexField*nbFFm]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) -= (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
-                                          (Valsm[j+indexField*nbFFm]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFpTotalLastExtraDofCol+nbdofm) -= (dfieldJumpdFieldp*NMeankNBetasc+dfieldJumpdField2p*NMeank2NBetasc)*
+                                          (Valsm[j+nbFFmTotalLastExtraDofRow]*Valsp[l+nbFFpTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFpTotalLastExtraDofCol+nbdofm) -= (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
+                                          (Valsm[j+nbFFmTotalLastExtraDofRow]*Valsp[l+nbFFpTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                   }
                 }
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += (dfieldJumpdFieldm*NMeankNBetasc+dfieldJumpdField2m*NMeank2NBetasc)*
-                                                          (Valsp[j+indexField*nbFFp]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
-                                                          (Valsp[j+indexField*nbFFp]*Valsm[l+indexField2*nbFFm]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFmTotalLastExtraDofCol) += (dfieldJumpdFieldm*NMeankNBetasc+dfieldJumpdField2m*NMeank2NBetasc)*
+                                                          (Valsp[j+nbFFpTotalLastExtraDofRow]*Valsm[l+nbFFmTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFmTotalLastExtraDofCol) += (fieldJump*dNMeankNBetascdFieldm+fieldJump2*dNMeankNBetascdField2m)*
+                                                          (Valsp[j+nbFFpTotalLastExtraDofRow]*Valsm[l+nbFFmTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (dfieldJumpdFieldp*NMeankNBetasc+dfieldJumpdField2p*NMeank2NBetasc)*
-                                             (Valsp[j+indexField*nbFFp]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
-                    stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
-                                             (Valsp[j+indexField*nbFFp]*Valsp[l+indexField2*nbFFp]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += (dfieldJumpdFieldp*NMeankNBetasc+dfieldJumpdField2p*NMeank2NBetasc)*
+                                             (Valsp[j+nbFFpTotalLastExtraDofRow]*Valsp[l+nbFFpTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
+                    stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += (fieldJump*dNMeankNBetascdFieldp+fieldJump2*dNMeankNBetascdField2p)*
+                                             (Valsp[j+nbFFpTotalLastExtraDofRow]*Valsp[l+nbFFpTotalLastExtraDofCol]*wJ*getConstitutiveExtraDofDiffusionEqRatio());
                   }
                 }
      
@@ -4143,69 +4156,69 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 // compatibility
                 // Assembly (loop on shape function)
 
-                for(int j=0;j<nbFFm;j++)
+                for(int j=0;j<nbFFmExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
                     for(int p =0; p < 3; p++)
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += ((k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*Valsm[l+indexField2*nbFFm]*
-                                          dfieldJumpdFieldm*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+((k02m(p,q)*Gradsm[j+indexField*nbFFm][q])*
-                                          nu(p)*Valsm[l+indexField2*nbFFm]*dfieldJumpdField2m*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFm) += (fieldJump*(dk0mdFieldm(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
-                                          Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
-                                          (fieldJump2*(dk0mdField2m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
-                                          Valsm[l+indexField2*nbFFm]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) += ((k0m(p,q)*Gradsm[j+nbFFmTotalLastExtraDofRow][q])*nu(p)*Valsm[l+nbFFmTotalLastExtraDofCol]*
+                                          dfieldJumpdFieldm*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+((k02m(p,q)*Gradsm[j+nbFFmTotalLastExtraDofRow][q])*
+                                          nu(p)*Valsm[l+nbFFmTotalLastExtraDofCol]*dfieldJumpdField2m*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofCol) += (fieldJump*(dk0mdFieldm(p,q)*Gradsm[j+nbFFmTotalLastExtraDofRow][q])*nu(p)*
+                                          Valsm[l+nbFFmTotalLastExtraDofCol]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
+                                          (fieldJump2*(dk0mdField2m(p,q)*Gradsm[j+nbFFmTotalLastExtraDofRow][q])*nu(p)*
+                                          Valsm[l+nbFFmTotalLastExtraDofCol]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
                       }
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
                     for(int p =0; p < 3; p++)
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        stiff(j+indexField*nbFFm,l+indexField2*nbFFp+nbdofm) += ((k0m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*
-                                              Valsp[l+indexField2*nbFFp]*dfieldJumpdFieldp*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
-                                              ((k02m(p,q)*Gradsm[j+indexField*nbFFm][q])*nu(p)*Valsp[l+indexField2*nbFFp]*
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFpTotalLastExtraDofCol+nbdofm) += ((k0m(p,q)*Gradsm[j+nbFFmTotalLastExtraDofRow][q])*nu(p)*
+                                              Valsp[l+nbFFpTotalLastExtraDofCol]*dfieldJumpdFieldp*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
+                                              ((k02m(p,q)*Gradsm[j+nbFFmTotalLastExtraDofRow][q])*nu(p)*Valsp[l+nbFFpTotalLastExtraDofCol]*
                                               dfieldJumpdField2p*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
                       }
                     }
                   }
                 }
 
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofCol;l++)
                   {
                     for(int p =0; p < 3; p++)
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFm) += ((k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
-                                               Valsm[l+indexField2*nbFFm]*dfieldJumpdFieldm*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
-                                               ((k02p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*Valsm[l+indexField2*nbFFm]*
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFmTotalLastExtraDofCol) += ((k0p(p,q)*Gradsp[j+nbFFpTotalLastExtraDofRow][q])*nu(p)*
+                                               Valsm[l+nbFFmTotalLastExtraDofCol]*dfieldJumpdFieldm*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
+                                               ((k02p(p,q)*Gradsp[j+nbFFpTotalLastExtraDofRow][q])*nu(p)*Valsm[l+nbFFmTotalLastExtraDofCol]*
                                                dfieldJumpdField2m*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
                       }
                     }
                   }
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofCol;l++)
                   {
                     for(int p =0; p < 3; p++)
                     {
                       for(int q =0; q < 3; q++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += ((k0p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
-                                                       Valsp[l+indexField2*nbFFp]*dfieldJumpdFieldp*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
-                                                      ((k02p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*Valsp[l+indexField2*nbFFp]*
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += ((k0p(p,q)*Gradsp[j+nbFFpTotalLastExtraDofRow][q])*nu(p)*
+                                                       Valsp[l+nbFFpTotalLastExtraDofCol]*dfieldJumpdFieldp*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
+                                                      ((k02p(p,q)*Gradsp[j+nbFFpTotalLastExtraDofRow][q])*nu(p)*Valsp[l+nbFFpTotalLastExtraDofCol]*
                                                       dfieldJumpdField2p*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField2*nbFFp+nbdofm) += (fieldJump*(dk0pdFieldp(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
-                                                      Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
-                                                      (fieldJump2*(dk0pdField2p(p,q)*Gradsp[j+indexField*nbFFp][q])*nu(p)*
-                                                      Valsp[l+indexField2*nbFFp]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofCol+nbdofm) += (fieldJump*(dk0pdFieldp(p,q)*Gradsp[j+nbFFpTotalLastExtraDofRow][q])*nu(p)*
+                                                      Valsp[l+nbFFpTotalLastExtraDofCol]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.)+
+                                                      (fieldJump2*(dk0pdField2p(p,q)*Gradsp[j+nbFFpTotalLastExtraDofRow][q])*nu(p)*
+                                                      Valsp[l+nbFFpTotalLastExtraDofCol]*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
                       }
                     }
                   }
@@ -4228,14 +4241,18 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
             // not
           }
           else if (getNumConstitutiveExtraDofDiffusionVariable() == 2)
-          {
-            int nbFFm = em->getNumShapeFunctions();
-            int nbFFp = ep->getNumShapeFunctions();
-            
+          {            
             for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
             {
                         
               int indexField=3+getNumNonLocalVariable()+extraDOFField;
+              int nbFFmTotalLastExtraDofRow = _minusSpace->getShapeFunctionsIndex(em,indexField);
+              int nbFFpTotalLastExtraDofRow = _plusSpace->getShapeFunctionsIndex(ep,indexField);
+              int nbFFmExtraDofRow = _minusSpace->getNumShapeFunctions(em,indexField);
+              int nbFFpExtraDofRow = _plusSpace->getNumShapeFunctions(ep,indexField);
+              int nbFFmDispCol = _minusSpace->getNumShapeFunctions(em,0);// same for 0, 1, 2
+              int nbFFpDispCol = _plusSpace->getNumShapeFunctions(ep,0);
+              
               for (int extraDOFField2 = 0; extraDOFField2< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField2++)
               {
                 double fieldJump = ipvp->getConstRefToEnergyConjugatedFieldJump()(extraDOFField2);
@@ -4262,11 +4279,11 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 }
                 
                 int indexField2=3+getNumNonLocalVariable()+extraDOFField2;
-                for(int j=0;j<nbFFm;j++)
+                for(int j=0;j<nbFFmExtraDofRow;j++)
                 {
                   for(int k=0;k<3;k++)
                   {
-                    for(int l=0;l<nbFFm;l++)
+                    for(int l=0;l<nbFFmDispCol;l++)
                     {
                       if(useBarF)
                       {
@@ -4274,7 +4291,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                         {
                           for(int p=0; p<3; p++)
                           {
-                            stiff(j+indexField*nbFFm,l+k*nbFFm) -= fieldJump*dNMeankNBetascdFm(ii,p)*dBarFdum[i][l](ii,p,k)*Valsm[j+indexField*nbFFm]*
+                            stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFmDispCol) -= fieldJump*dNMeankNBetascdFm(ii,p)*dBarFdum[i][l](ii,p,k)*Valsm[j+nbFFmTotalLastExtraDofRow]*
                                                                wJ*getConstitutiveExtraDofDiffusionEqRatio();
                           }
                         }
@@ -4283,12 +4300,12 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                       {
                         for(int p=0;p<3;p++)
                         {
-                          stiff(j+indexField*nbFFm,l+k*nbFFm) -= fieldJump*dNMeankNBetascdFm(k,p)*Gradsm[l+0*nbFFm][p]*Valsm[j+indexField*nbFFm]*
+                          stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFmDispCol) -= fieldJump*dNMeankNBetascdFm(k,p)*Gradsm[l+k*nbFFmDispCol][p]*Valsm[j+nbFFmTotalLastExtraDofRow]*
                                                                wJ*getConstitutiveExtraDofDiffusionEqRatio();
                         }
                       }
                     }
-                    for(int l=0;l<nbFFp;l++)
+                    for(int l=0;l<nbFFpDispCol;l++)
                     {
                       if(useBarF)
                       {
@@ -4296,7 +4313,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                         {
                           for(int p=0; p<3; p++)
                           {
-                           stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= fieldJump*dNMeankNBetascdFp(ii,p)*dBarFdup[i][l](ii,p,k)*Valsm[j+indexField*nbFFm]*
+                           stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFpDispCol+nbdofm) -= fieldJump*dNMeankNBetascdFp(ii,p)*dBarFdup[i][l](ii,p,k)*Valsm[j+nbFFmTotalLastExtraDofRow]*
                                                                   wJ*getConstitutiveExtraDofDiffusionEqRatio();
                           }
                         }
@@ -4305,7 +4322,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                       {
                         for(int p=0;p<3;p++)
                         {
-                          stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= fieldJump*dNMeankNBetascdFp(k,p)*Gradsp[l+0*nbFFp][p]*Valsm[j+indexField*nbFFm]*
+                          stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFpDispCol+nbdofm) -= fieldJump*dNMeankNBetascdFp(k,p)*Gradsp[l+k*nbFFpDispCol][p]*Valsm[j+nbFFmTotalLastExtraDofRow]*
                                                                  wJ*getConstitutiveExtraDofDiffusionEqRatio();
                         }
                       }
@@ -4313,11 +4330,11 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                   } 
                 }
 
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpExtraDofRow;j++)
                 {
                   for(int k=0;k<3;k++)
                   {
-                    for(int l=0;l<nbFFm;l++)
+                    for(int l=0;l<nbFFmDispCol;l++)
                     {
                       if(useBarF)
                       {
@@ -4325,7 +4342,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                         {
                           for(int p=0; p<3; p++)
                           {
-                            stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFm) += fieldJump*dNMeankNBetascdFm(ii,p)*dBarFdum[i][l](ii,p,k)*Valsp[j+indexField*nbFFp]*
+                            stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFmDispCol) += fieldJump*dNMeankNBetascdFm(ii,p)*dBarFdum[i][l](ii,p,k)*Valsp[j+nbFFpTotalLastExtraDofRow]*
                                                                         wJ*getConstitutiveExtraDofDiffusionEqRatio();
                           }
                         }
@@ -4334,13 +4351,13 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                       {
                         for(int p=0;p<3;p++)
                         {
-                          stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFm) += fieldJump*dNMeankNBetascdFm(k,p)*Gradsm[l+0*nbFFm][p]*Valsp[j+indexField*nbFFp]*
+                          stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFmDispCol) += fieldJump*dNMeankNBetascdFm(k,p)*Gradsm[l+k*nbFFmDispCol][p]*Valsp[j+nbFFpTotalLastExtraDofRow]*
                                                                         wJ*getConstitutiveExtraDofDiffusionEqRatio();
                         }
                       }
                     }
 
-                    for(int l=0;l<nbFFp;l++)
+                    for(int l=0;l<nbFFpDispCol;l++)
                     {
                       if(useBarF)
                       {
@@ -4348,7 +4365,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                         {
                           for(int p=0; p<3; p++)
                           {
-                            stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFp+nbdofm) +=fieldJump*dNMeankNBetascdFp(ii,p)*dBarFdup[i][l](ii,p,k)*Valsp[j+indexField*nbFFp]*
+                            stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFpDispCol+nbdofm) +=fieldJump*dNMeankNBetascdFp(ii,p)*dBarFdup[i][l](ii,p,k)*Valsp[j+nbFFpTotalLastExtraDofRow]*
                                                                          wJ*getConstitutiveExtraDofDiffusionEqRatio();
                           }
                         }
@@ -4357,7 +4374,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                       {
                         for(int p=0;p<3;p++)
                         {
-                          stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFp+nbdofm) +=fieldJump*dNMeankNBetascdFp(k,p)*Gradsp[l+0*nbFFp][p]*Valsp[j+indexField*nbFFp]*
+                          stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFpDispCol+nbdofm) +=fieldJump*dNMeankNBetascdFp(k,p)*Gradsp[l+k*nbFFpDispCol][p]*Valsp[j+nbFFpTotalLastExtraDofRow]*
                                                                          wJ*getConstitutiveExtraDofDiffusionEqRatio();
                         }
                       }
@@ -4366,9 +4383,9 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 }
                 //
                 
-                for(int j=0;j<nbFFm;j++)
+                for(int j=0;j<nbFFmExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmDispCol;l++)
                   {
                     for(int m =0; m < 3; m++)
                     {
@@ -4382,8 +4399,8 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                             {
                               for(int n=0; n<3; n++)
                               {
-                                stiff(j+indexField*nbFFm,l+m*nbFFm) += fieldJump*(dk0mdFm(p,q,ii,n)*
-                                          Gradsm[j+indexField*nbFFm][q]*dBarFdum[i][l](ii,n,m))*(nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                                stiff(j+nbFFmTotalLastExtraDofRow,l+m*nbFFmDispCol) += fieldJump*(dk0mdFm(p,q,ii,n)*
+                                          Gradsm[j+nbFFmTotalLastExtraDofRow][q]*dBarFdum[i][l](ii,n,m))*(nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
                               }
                             }
                           }
@@ -4391,8 +4408,8 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                           {
                             for(int n =0; n< 3; n++)
                             {
-                              stiff(j+indexField*nbFFm,l+m*nbFFm) += fieldJump*(dk0mdFm(p,q,m,n)*
-                                          Gradsm[j+indexField*nbFFm][q]*Gradsm[l+0*nbFFm][n])*(nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
+                              stiff(j+nbFFmTotalLastExtraDofRow,l+m*nbFFmDispCol) += fieldJump*(dk0mdFm(p,q,m,n)*
+                                          Gradsm[j+nbFFmTotalLastExtraDofRow][q]*Gradsm[l+m*nbFFmDispCol][n])*(nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
                             }
                           }
                         }
@@ -4401,9 +4418,9 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                   }
                 }
 
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpDispCol;l++)
                   {
                     for(int m =0; m < 3; m++)
                     {
@@ -4417,8 +4434,8 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                             {
                               for(int n=0; n<3; n++)
                               {
-                                stiff(j+indexField*nbFFp+nbdofm,l+m*nbFFp+nbdofm) += fieldJump*(dk0pdFp(p,q,ii,n)*
-                                          Gradsp[j+indexField*nbFFp][q]*dBarFdup[i][l](ii,n,m))*
+                                stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+m*nbFFpDispCol+nbdofm) += fieldJump*(dk0pdFp(p,q,ii,n)*
+                                          Gradsp[j+nbFFpTotalLastExtraDofRow][q]*dBarFdup[i][l](ii,n,m))*
                                           (nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
                               }
                             }
@@ -4427,8 +4444,8 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                           {
                             for(int n =0; n < 3; n++)
                             {
-                              stiff(j+indexField*nbFFp+nbdofm,l+m*nbFFp+nbdofm) += fieldJump*(dk0pdFp(p,q,m,n)*
-                                          Gradsp[j+indexField*nbFFp][q]*Gradsp[l+0*nbFFp][n])*
+                              stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+m*nbFFpDispCol+nbdofm) += fieldJump*(dk0pdFp(p,q,m,n)*
+                                          Gradsp[j+nbFFpTotalLastExtraDofRow][q]*Gradsp[l+m*nbFFpDispCol][n])*
                                           (nu(p)*getConstitutiveExtraDofDiffusionEqRatio()*wJ/2.);
                             }
                           }
@@ -4448,20 +4465,22 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           
           for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
           {
-            int nbFFm = em->getNumShapeFunctions();
-            int nbFFp = ep->getNumShapeFunctions();
-
             const STensor33 *dqdFm = &(ipvm->getConstRefTodFluxdF()[extraDOFField]);
             const STensor33 *dqdFp = &(ipvp->getConstRefTodFluxdF()[extraDOFField]);
 
             int indexField=3+getNumNonLocalVariable()+extraDOFField;
-
+            int nbFFmTotalLastExtraDofRow = _minusSpace->getShapeFunctionsIndex(em,indexField);
+            int nbFFpTotalLastExtraDofRow = _plusSpace->getShapeFunctionsIndex(ep,indexField);
+            int nbFFmExtraDofRow = _minusSpace->getNumShapeFunctions(em,indexField);
+            int nbFFpExtraDofRow = _plusSpace->getNumShapeFunctions(ep,indexField);
+            int nbFFmDispCol = _minusSpace->getNumShapeFunctions(em,0);// same for 0, 1, 2
+            int nbFFpDispCol = _plusSpace->getNumShapeFunctions(ep,0);
             //F-related terms
-            for(int j=0;j<nbFFm;j++)
+            for(int j=0;j<nbFFmExtraDofRow;j++)
             {
               for(int k=0;k<3;k++)
               {
-                for(int l=0;l<nbFFm;l++)
+                for(int l=0;l<nbFFmDispCol;l++)
                 {
                   for(int N = 0; N< 3; N++)
                   {
@@ -4471,7 +4490,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                       {
                         for(int q=0; q<3; q++)
                         {
-                          stiff(j+indexField*nbFFm,l+k*nbFFm) -= dqdFm->operator()(N,ii,q)*(dBarFdum[i][l](ii,q,k)*Valsm[j+indexField*nbFFm]*
+                          stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFmDispCol) -= dqdFm->operator()(N,ii,q)*(dBarFdum[i][l](ii,q,k)*Valsm[j+nbFFmTotalLastExtraDofRow]*
                                                                wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*nu(N));
                         }
                       }
@@ -4480,13 +4499,13 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     {
                       for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFm,l+k*nbFFm) -= dqdFm->operator()(N,k,q)*(Gradsm[l+0*nbFFm][q]*Valsm[j+indexField*nbFFm]*
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFmDispCol) -= dqdFm->operator()(N,k,q)*(Gradsm[l+k*nbFFmDispCol][q]*Valsm[j+nbFFmTotalLastExtraDofRow]*
                                                                wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*nu(N));
                       }
                     }
                   }
                 }
-                for(int l=0;l<nbFFp;l++)
+                for(int l=0;l<nbFFpDispCol;l++)
                 {
                   for(int N = 0; N< 3; N++)
                   {
@@ -4496,7 +4515,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                       {
                         for(int q=0; q<3; q++)
                         {
-                          stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= dqdFp->operator()(N,ii,q)*(dBarFdup[i][l](ii,q,k)*Valsm[j+indexField*nbFFm]*
+                          stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFpDispCol+nbdofm) -= dqdFp->operator()(N,ii,q)*(dBarFdup[i][l](ii,q,k)*Valsm[j+nbFFmTotalLastExtraDofRow]*
                                                                wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*nu(N));
                         }
                       }
@@ -4505,7 +4524,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     {
                       for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) -= dqdFp->operator()(N,k,q)*(Gradsp[l+0*nbFFp][q]*Valsm[j+indexField*nbFFm]*
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFpDispCol+nbdofm) -= dqdFp->operator()(N,k,q)*(Gradsp[l+k*nbFFpDispCol][q]*Valsm[j+nbFFmTotalLastExtraDofRow]*
                                                                wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*nu(N));
                       }
                     }
@@ -4513,11 +4532,11 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                 }
               }
             }
-            for(int j=0;j<nbFFp;j++)
+            for(int j=0;j<nbFFpExtraDofRow;j++)
             {
               for(int k=0;k<3;k++)
               {
-                for(int l=0;l<nbFFm;l++)
+                for(int l=0;l<nbFFmDispCol;l++)
                 {
                   for(int N = 0; N< 3; N++)
                   {
@@ -4527,7 +4546,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                       {
                         for(int q=0; q<3; q++)
                         {
-                          stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFm) += dqdFm->operator()(N,ii,q)*(dBarFdum[i][l](ii,q,k)*Valsp[j+indexField*nbFFp]*
+                          stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFmDispCol) += dqdFm->operator()(N,ii,q)*(dBarFdum[i][l](ii,q,k)*Valsp[j+nbFFpTotalLastExtraDofRow]*
                                                                  wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*nu(N));
                         }
                       }
@@ -4536,13 +4555,13 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     {
                       for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFm) += dqdFm->operator()(N,k,q)*(Gradsm[l+0*nbFFm][q]*Valsp[j+indexField*nbFFp]*
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFmDispCol) += dqdFm->operator()(N,k,q)*(Gradsm[l+k*nbFFmDispCol][q]*Valsp[j+nbFFpTotalLastExtraDofRow]*
                                                                wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*nu(N));
                       }
                     }
                   }
                 }
-                for(int l=0;l<nbFFp;l++)
+                for(int l=0;l<nbFFpDispCol;l++)
                 {
                   for(int N = 0; N< 3; N++)
                   {
@@ -4552,7 +4571,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                       {
                         for(int q=0; q<3; q++)
                         {
-                          stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFp+nbdofm) += dqdFp->operator()(N,ii,q)*(dBarFdup[i][l](ii,q,k)*Valsp[j+indexField*nbFFp]*
+                          stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFpDispCol+nbdofm) += dqdFp->operator()(N,ii,q)*(dBarFdup[i][l](ii,q,k)*Valsp[j+nbFFpTotalLastExtraDofRow]*
                                                               wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*nu(N));
                         }
                       }
@@ -4561,7 +4580,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                     {
                       for(int q = 0; q< 3; q++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFp+nbdofm) += dqdFp->operator()(N,k,q)*(Gradsp[l+0*nbFFp][q]*Valsp[j+indexField*nbFFp]*
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFpDispCol+nbdofm) += dqdFp->operator()(N,k,q)*(Gradsp[l+k*nbFFpDispCol][q]*Valsp[j+nbFFpTotalLastExtraDofRow]*
                                                               wJ*getConstitutiveExtraDofDiffusionEqRatio()/2.*nu(N));
                       }
                     }
@@ -4580,10 +4599,7 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
           
           // additional term 
           for (int extraDOFField = 0; extraDOFField< ipvp->getNumConstitutiveExtraDofDiffusionVariable(); extraDOFField++)
-          {
-            int nbFFm = em->getNumShapeFunctions();
-            int nbFFp = ep->getNumShapeFunctions();
-            
+          {            
             if(extraDOFField==0)
             {
               double fieldp=0.;
@@ -4630,46 +4646,52 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               }
 
               int indexField=3+getNumNonLocalVariable()+extraDOFField;
-
+              int nbFFmTotalLastExtraDofRow = _minusSpace->getShapeFunctionsIndex(em,indexField);
+              int nbFFpTotalLastExtraDofRow = _plusSpace->getShapeFunctionsIndex(ep,indexField);
+              int nbFFmExtraDofRow = _minusSpace->getNumShapeFunctions(em,indexField);
+              int nbFFpExtraDofRow = _plusSpace->getNumShapeFunctions(ep,indexField);
+              int nbFFmDispCol = _minusSpace->getNumShapeFunctions(em,0);// same for 0, 1, 2
+              int nbFFpDispCol = _plusSpace->getNumShapeFunctions(ep,0);
+            
               double gamma=0.;
               if(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==1)
               {
-                for(int j=0;j<nbFFm;j++)
+                for(int j=0;j<nbFFmExtraDofRow;j++)
                 {
                   for(int k=0;k<3;k++)
                   {
-                    for(int l=0;l<nbFFm;l++)
+                    for(int l=0;l<nbFFmDispCol;l++)
                     {
                       for(int p =0; p < 3; p++)
                       {
-                        stiff(j+indexField*nbFFm,l+k*nbFFm) -= gamma*(Stiff_alphadialitationm(k,p)*Valsm[j+indexField*nbFFm])*(nu(p)*wJ/2.*Valsm[l+0*nbFFm])*(-1.);
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFmDispCol) -= gamma*(Stiff_alphadialitationm(k,p)*Valsm[j+nbFFmTotalLastExtraDofRow])*(nu(p)*wJ/2.*Valsm[l+k*nbFFmDispCol])*(-1.);
                       }
                     }
-                    for(int l=0;l<nbFFp;l++)
+                    for(int l=0;l<nbFFpDispCol;l++)
                     {
                       for(int p =0; p < 3; p++)
                       {
-                        stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) += gamma*(Stiff_alphadialitationm(k,p)*Valsm[j+indexField*nbFFm])*(nu(p)*wJ/2.*Valsp[l+0*nbFFp])*(-1.);
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFpDispCol+nbdofm) += gamma*(Stiff_alphadialitationm(k,p)*Valsm[j+nbFFmTotalLastExtraDofRow])*(nu(p)*wJ/2.*Valsp[l+k*nbFFpDispCol])*(-1.);
                       }
                     }
                   }
                 }
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpExtraDofRow;j++)
                 {
                   for(int k=0;k<3;k++)
                   {
-                    for(int l=0;l<nbFFm;l++)
+                    for(int l=0;l<nbFFmDispCol;l++)
                     {
                       for(int p =0; p < 3; p++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFm) -= gamma*(Stiff_alphadialitationp(k,p)*Valsp[j+indexField*nbFFp])*(nu(p)*wJ/2.*Valsm[l+0*nbFFm])*(-1.);
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFmDispCol) -= gamma*(Stiff_alphadialitationp(k,p)*Valsp[j+nbFFpTotalLastExtraDofRow])*(nu(p)*wJ/2.*Valsm[l+k*nbFFmDispCol])*(-1.);
                       }
                     }
-                    for(int l=0;l<nbFFp;l++)
+                    for(int l=0;l<nbFFpDispCol;l++)
                     {
                       for(int p =0; p < 3; p++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFp+nbdofm) += gamma*(Stiff_alphadialitationp(k,p)*Valsp[j+indexField*nbFFp])*(nu(p)*wJ/2.*Valsp[l+0*nbFFp])*(-1.);
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFpDispCol+nbdofm) += gamma*(Stiff_alphadialitationp(k,p)*Valsp[j+nbFFpTotalLastExtraDofRow])*(nu(p)*wJ/2.*Valsp[l+k*nbFFpDispCol])*(-1.);
                       }
                     }
                   }
@@ -4677,30 +4699,30 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
                
                 if(getConstitutiveExtraDofDiffusionUseEnergyConjugatedField())
                 {
-                  for(int j=0;j<nbFFm;j++)
+                  for(int j=0;j<nbFFmExtraDofRow;j++)
                   {
-                    for(int l=0;l<nbFFm;l++)
+                    for(int l=0;l<nbFFmExtraDofRow;l++)
                     {
                       for(int k =0; k < 3; k++)
                       {
                         for(int p =0; p < 3; p++)
                         {
-                          stiff(j+indexField*nbFFm,l+indexField*nbFFm) += gamma*jump(k)*
-                              (dStiff_alphadialitationmdFieldm(k,p)*Valsm[j+indexField*nbFFm])*nu(p)*Valsm[l+indexField*nbFFm]*wJ/2.*(-1.);
+                          stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofRow) += gamma*jump(k)*
+                              (dStiff_alphadialitationmdFieldm(k,p)*Valsm[j+nbFFmTotalLastExtraDofRow])*nu(p)*Valsm[l+nbFFmTotalLastExtraDofRow]*wJ/2.*(-1.);
                         }
                       }
                     }
                   }
-                  for(int j=0;j<nbFFp;j++)
+                  for(int j=0;j<nbFFpExtraDofRow;j++)
                   {
-                    for(int l=0;l<nbFFp;l++)
+                    for(int l=0;l<nbFFpExtraDofRow;l++)
                     {
                       for(int k =0; k < 3; k++)
                       {
                         for(int p =0; p< 3; p++)
                         {
-                          stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += gamma*jump(k)*
-                              (dStiff_alphadialitationpdFieldp(k,p)*Valsp[j+indexField*nbFFp])*nu(p)*Valsp[l+indexField*nbFFp]*wJ/2.*(-1.);
+                          stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofRow+nbdofm) += gamma*jump(k)*
+                              (dStiff_alphadialitationpdFieldp(k,p)*Valsp[j+nbFFpTotalLastExtraDofRow])*nu(p)*Valsp[l+nbFFpTotalLastExtraDofRow]*wJ/2.*(-1.);
                          }
                        }
                      }
@@ -4710,73 +4732,73 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
               if(ipvp->getNumConstitutiveExtraDofDiffusionVariable()==2)
               {
                 double gamma=0.;
-                for(int j=0;j<nbFFm;j++)
+                for(int j=0;j<nbFFmExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFm;l++)
+                  for(int l=0;l<nbFFmExtraDofRow;l++)
                   {
                     for(int k =0; k < 3; k++)
                     {
                       for(int p =0; p < 3; p++)
                       {
-                        stiff(j+indexField*nbFFm,l+indexField*nbFFm) += gamma*jump(k)*(Stiff_alphadialitationm(k,p)*
-                                                    Valsm[j+indexField*nbFFm])*(2.*fieldm)*nu(p)*Valsm[l+indexField*nbFFm]*wJ/2.*(-1.);
+                        stiff(j+nbFFmTotalLastExtraDofRow,l+nbFFmTotalLastExtraDofRow) += gamma*jump(k)*(Stiff_alphadialitationm(k,p)*
+                                                    Valsm[j+nbFFmTotalLastExtraDofRow])*(2.*fieldm)*nu(p)*Valsm[l+nbFFmTotalLastExtraDofRow]*wJ/2.*(-1.);
                       }
                     }
                   }
                 }
 
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpExtraDofRow;j++)
                 {
-                  for(int l=0;l<nbFFp;l++)
+                  for(int l=0;l<nbFFpExtraDofRow;l++)
                   {
                     for(int k =0; k < 3; k++)
                     {
                       for(int p =0; p< 3; p++)
                       {
 
-                        stiff(j+indexField*nbFFp+nbdofm,l+indexField*nbFFp+nbdofm) += gamma*jump(k)*(Stiff_alphadialitationp(k,p)*
-                                                    (2.*fieldp)*Valsp[j+indexField*nbFFp])*nu(p)*Valsp[l+indexField*nbFFp]*wJ/2.*(-1.);
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+nbFFpTotalLastExtraDofRow+nbdofm) += gamma*jump(k)*(Stiff_alphadialitationp(k,p)*
+                                                    (2.*fieldp)*Valsp[j+nbFFpTotalLastExtraDofRow])*nu(p)*Valsp[l+nbFFpTotalLastExtraDofRow]*wJ/2.*(-1.);
                       }
                     }
                   }
                 }
-                for(int j=0;j<nbFFm;j++)
+                for(int j=0;j<nbFFmExtraDofRow;j++)
                 {
                   for(int k=0;k<3;k++)
                   {
-                    for(int l=0;l<nbFFm;l++)
+                    for(int l=0;l<nbFFmDispCol;l++)
                     {
                       for(int p =0; p < 3; p++)
                       {
-                          stiff(j+indexField*nbFFm,l+k*nbFFm) -= gamma*(Stiff_alphadialitationm(k,p)*Valsm[j+indexField*nbFFm])*(nu(p)*wJ/2.*Valsm[l+0*nbFFm])*(-1.);
+                          stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFmDispCol) -= gamma*(Stiff_alphadialitationm(k,p)*Valsm[j+nbFFmTotalLastExtraDofRow])*(nu(p)*wJ/2.*Valsm[l+k*nbFFmDispCol])*(-1.);
                       }
                     }
-                    for(int l=0;l<nbFFp;l++)
+                    for(int l=0;l<nbFFpDispCol;l++)
                     {
                       for(int p =0; p < 3; p++)
                       {
-                          stiff(j+indexField*nbFFm,l+k*nbFFp+nbdofm) +=  gamma*(Stiff_alphadialitationm(k,p)*Valsm[j+indexField*nbFFm])*(nu(p)*wJ/2.*Valsp[l+0*nbFFp])*(-1.);
+                          stiff(j+nbFFmTotalLastExtraDofRow,l+k*nbFFpDispCol+nbdofm) +=  gamma*(Stiff_alphadialitationm(k,p)*Valsm[j+nbFFmTotalLastExtraDofRow])*(nu(p)*wJ/2.*Valsp[l+k*nbFFpDispCol])*(-1.);
                       }
                     }
                   }
                 }
 
-                for(int j=0;j<nbFFp;j++)
+                for(int j=0;j<nbFFpExtraDofRow;j++)
                 {
                   for(int k=0;k<3;k++)
                   {
-                    for(int l=0;l<nbFFm;l++)
+                    for(int l=0;l<nbFFmDispCol;l++)
                     {
                       for(int p =0; p < 3; p++)
                       {
-                        stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFm) -=  gamma*(Stiff_alphadialitationp(k,p)*Valsp[j+indexField*nbFFp])*(nu(p)*wJ/2.*Valsm[l+0*nbFFm])*(-1.);
+                        stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFmDispCol) -=  gamma*(Stiff_alphadialitationp(k,p)*Valsp[j+nbFFpTotalLastExtraDofRow])*(nu(p)*wJ/2.*Valsm[l+k*nbFFmDispCol])*(-1.);
                       }
                     }
-                    for(int l=0;l<nbFFp;l++)
+                    for(int l=0;l<nbFFpDispCol;l++)
                     {
                       for(int p =0; p < 3; p++)
                       {
-                          stiff(j+indexField*nbFFp+nbdofm,l+k*nbFFp+nbdofm) +=  gamma*(Stiff_alphadialitationp(k,p)*Valsp[j+indexField*nbFFp])*(nu(p)*wJ/2.*Valsp[l+0*nbFFp])*(-1.);
+                          stiff(j+nbFFpTotalLastExtraDofRow+nbdofm,l+k*nbFFpDispCol+nbdofm) +=  gamma*(Stiff_alphadialitationp(k,p)*Valsp[j+nbFFpTotalLastExtraDofRow])*(nu(p)*wJ/2.*Valsp[l+k*nbFFpDispCol])*(-1.);
                       }
                     }
                   }
@@ -4790,4 +4812,4 @@ void dG3DStiffnessInter::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double>
     }
   }
    //stiff.print("dginter");
-};
\ No newline at end of file
+};
-- 
GitLab


From 836a4749928ee4a420a59ab1f11df20b58211b3a Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Tue, 2 Jun 2020 14:59:46 +0200
Subject: [PATCH 16/19] functuoon space orrectio

---
 .../space/ThreeDLagrangeFunctionSpace.h       |  5 +++
 dG3D/src/dG3DDomain.cpp                       | 18 ++++++++-
 dG3D/src/dG3DFunctionSpace.h                  | 37 +++++++++++++++++--
 3 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
index 53ee05c1c..9ac6b619b 100644
--- a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
+++ b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
@@ -58,6 +58,11 @@ class VertexBasedLagrangeFunctionSpace : public nlsFunctionSpace<double>
       return _usePrimaryShapeFunctions.find(c) != _usePrimaryShapeFunctions.end();
     }
     
+    virtual const std::set<int>& getCompsWithPrimaryShapeFunction() const
+    {
+      return _usePrimaryShapeFunctions;
+    }
+    
     virtual int getNumShapeFunctions(MElement* ele, int c) const
     {
       if (withPrimaryShapeFunction(c))
diff --git a/dG3D/src/dG3DDomain.cpp b/dG3D/src/dG3DDomain.cpp
index 6fc926f59..7b5fc387f 100644
--- a/dG3D/src/dG3DDomain.cpp
+++ b/dG3D/src/dG3DDomain.cpp
@@ -315,7 +315,7 @@ FunctionSpaceBase* dG3DDomain::getSpaceForBC(const nonLinearBoundaryCondition::t
     // with others,
     // dof_comp is used, domcomp is not used
 
-    FunctionSpaceBase* spacebc;
+    FunctionSpaceBase* spacebc = NULL;
     if(bc_type == nonLinearBoundaryCondition::DIRICHLET)
     {
       switch(_wsp){
@@ -411,11 +411,25 @@ FunctionSpaceBase* dG3DDomain::getSpaceForBC(const nonLinearBoundaryCondition::t
          Msg::Error("Unknown function space type for an initial BC on domain %d",_phys);
       }
     }
+    // sync with space
+    if (spacebc != NULL)
+    {
+      VertexBasedLagrangeFunctionSpace* spacebcLag = dynamic_cast<VertexBasedLagrangeFunctionSpace*>(spacebc);
+      const VertexBasedLagrangeFunctionSpace* sp = dynamic_cast<const VertexBasedLagrangeFunctionSpace*>(this->getFunctionSpace());
+      if (sp != NULL && spacebcLag != NULL)
+      {
+        const std::set<int>& primaryComp = sp->getCompsWithPrimaryShapeFunction();
+        for (std::set<int>::const_iterator itt = primaryComp.begin(); itt != primaryComp.end(); itt++)
+        {
+          spacebcLag->usePrimaryShapeFunction(*itt);
+        }
+      };
+    }
     return spacebc;
   }
   else if (dofType == mixedFunctionSpaceBase::DOF_CURL)
   {
-    FunctionSpaceBase* spacebc;
+    FunctionSpaceBase* spacebc = NULL;
     if(bc_type == nonLinearBoundaryCondition::DIRICHLET)
     {
       spacebc = new g3DDirichletBoundaryConditionHierarchicalCurlFunctionSpace(getTag(),1,dof_comp);
diff --git a/dG3D/src/dG3DFunctionSpace.h b/dG3D/src/dG3DFunctionSpace.h
index a6c2a9a08..b2cbe3e0d 100644
--- a/dG3D/src/dG3DFunctionSpace.h
+++ b/dG3D/src/dG3DFunctionSpace.h
@@ -807,9 +807,11 @@ private:
     if (it == mapBoundaryInterfaces.end()){
       Msg::Error("mapBoundaryInterfaces is wrong initialized in dG3DBoundaryConditionLagrangeFunctionSpace::getKeys");
     }
-    else{
+    else
+    {
       const std::map<MElement*,std::vector<int> >& support = it->second;
-      for (std::map<MElement*,std::vector<int> >::const_iterator itm = support.begin(); itm != support.end(); itm++){
+      for (std::map<MElement*,std::vector<int> >::const_iterator itm = support.begin(); itm != support.end(); itm++)
+      {
         MElement* ebulk = itm->first;
         const std::vector<int>& posfind = itm->second;
         int nbcomp=comp.size();
@@ -817,19 +819,46 @@ private:
         #if defined(HAVE_MPI) // small duplication to avoid multiple if in a loop
         if( (ebulk->getPartition() != 0)and (ebulk->getPartition() != Msg::GetCommRank() +1))
         {
+          
           for (int j=0;j<nbcomp;++j)
+          {
             for (int i=0;i<posfind.size();i++)
             {
-              keys.push_back(Dof(ebulk->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],posfind[i])));
+              if (withPrimaryShapeFunction(comp[j]))
+              {
+                // check if posfind[i] is a primary vertix of ebulk
+                if (posfind[i] < ebulk->getNumPrimaryVertices())
+                {
+                  keys.push_back(Dof(ebulk->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],posfind[i])));
+                }
+              }
+              else
+              {
+                keys.push_back(Dof(ebulk->getNum(),-dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],posfind[i])));
+              }
             }
+          }
         }
         else
         #endif // HAVE_MPI
         {
           for (int j=0;j<nbcomp;++j)
+          {
             for (int i=0;i<posfind.size();i++)
             {
-              keys.push_back(Dof(ebulk->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],posfind[i])));
+              if (withPrimaryShapeFunction(comp[j]))
+              {
+                // check if posfind[i] is a primary vertix of ebulk
+                if (posfind[i] < ebulk->getNumPrimaryVertices())
+                {
+                  keys.push_back(Dof(ebulk->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],posfind[i])));
+                }
+              }
+              else
+              {
+                keys.push_back(Dof(ebulk->getNum(),dG3DDof3IntType::createTypeWithThreeInts(comp[j],ifield[j],posfind[i])));
+              }
+            }
           }
         }
       }
-- 
GitLab


From d41d38b46c375766ee1a220aeb97636f0d03158c Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Tue, 2 Jun 2020 17:32:14 +0200
Subject: [PATCH 17/19] fix problem with fixDof and initial dofs

---
 NonLinearSolver/nlsolver/nlsolAlgorithms.h    | 117 ++++++++++++------
 .../space/ThreeDLagrangeFunctionSpace.h       |  67 +++++++---
 dG3D/src/dG3DFunctionSpace.h                  |  43 ++++++-
 3 files changed, 167 insertions(+), 60 deletions(-)

diff --git a/NonLinearSolver/nlsolver/nlsolAlgorithms.h b/NonLinearSolver/nlsolver/nlsolAlgorithms.h
index 27aa2715b..a6f6f2d7e 100644
--- a/NonLinearSolver/nlsolver/nlsolAlgorithms.h
+++ b/NonLinearSolver/nlsolver/nlsolAlgorithms.h
@@ -20,6 +20,7 @@
 #include "solverAlgorithms.h"
 #include "staticDofManager.h"
 #include "dofManagerMultiSystems.h"
+#include "ThreeDLagrangeFunctionSpace.h"
 
 template <class Iterator, class Assembler>
 void AssembleItMap(LinearTermBase<double> &term, FunctionSpaceBase &space,
@@ -482,45 +483,73 @@ template<class Iterator,class Assembler> void FixInterfaceNodalDofs(FunctionSpac
 
 template<class Assembler> void FixNodalDofs(FunctionSpaceBase *space,MElement *e,Assembler &assembler,simpleFunction<typename Assembler::dataVec> &fct,FilterDof &filter,bool fullDg)
 {
-  std::vector<MVertex*> tabV;
-  int nv=e->getNumVertices();
-  std::vector<Dof> R;
-  space->getKeys(e,R);
-  tabV.reserve(nv);
-  for (int i=0;i<nv;++i) tabV.push_back(e->getVertex(i));
-
-  if(!fullDg){
-    for (std::vector<Dof>::iterator itd=R.begin();itd!=R.end();++itd)
+  VertexBasedLagrangeFunctionSpace* lagspace = dynamic_cast<VertexBasedLagrangeFunctionSpace*>(space);
+  if (lagspace != NULL)
+  {
+    staticDofManager<double> *dynass= static_cast<staticDofManager<double>*>(&assembler);
+    std::vector<int> comp;
+    lagspace->getComp(comp);
+    int nv = e->getNumVertices();
+    std::vector<Dof> R;
+    for (int i=0; i< nv; i++)
     {
-      Dof key=*itd;
-      if (filter(key))
+      R.clear();
+      space->getKeysOnVertex(e,e->getVertex(i),comp,R);
+      for (int iR =0; iR < R.size(); iR++)
       {
-        for (int i=0;i<nv;++i)
+        if(filter(R[iR]))
+        {
+          assembler.fixDof(R[iR], fct(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()));
+        }
+      }
+    }
+    
+    /*
+    std::vector<MVertex*> tabV;
+    int nv=e->getNumVertices();
+    std::vector<Dof> R;
+    space->getKeys(e,R);
+    tabV.reserve(nv);
+    for (int i=0;i<nv;++i) tabV.push_back(e->getVertex(i));
+
+    if(!fullDg){
+      for (std::vector<Dof>::iterator itd=R.begin();itd!=R.end();++itd)
+      {
+        Dof key=*itd;
+        if (filter(key))
         {
-          if (tabV[i]->getNum()==key.getEntity())
+          for (int i=0;i<nv;++i)
           {
-            //Msg::Info("Fix dof number %d comp %d",key.getEntity(),key.getType());
-            assembler.fixDof(key, fct(tabV[i]->x(),tabV[i]->y(),tabV[i]->z()));
-            break;
+            if (tabV[i]->getNum()==key.getEntity())
+            {
+              //Msg::Info("Fix dof number %d comp %d",key.getEntity(),key.getType());
+              assembler.fixDof(key, fct(tabV[i]->x(),tabV[i]->y(),tabV[i]->z()));
+              break;
+            }
           }
         }
       }
     }
-  }
-  else{
-    for (std::vector<Dof>::iterator itd=R.begin();itd!=R.end();++itd)
-    {
-      Dof key=*itd;
-      if (filter(key))
+    else{
+      for (std::vector<Dof>::iterator itd=R.begin();itd!=R.end();++itd)
       {
-        for (int i=0;i<nv;++i)
+        Dof key=*itd;
+        if (filter(key))
         {
-          //Msg::Info("Fix dof number %d comp %d on rank %d",key.getEntity(),key.getType(),Msg::GetCommRank());
-          assembler.fixDof(key, fct(tabV[i]->x(),tabV[i]->y(),tabV[i]->z()));
-          break;
+          for (int i=0;i<nv;++i)
+          {
+            //Msg::Info("Fix dof number %d comp %d on rank %d",key.getEntity(),key.getType(),Msg::GetCommRank());
+            assembler.fixDof(key, fct(tabV[i]->x(),tabV[i]->y(),tabV[i]->z()));
+            break;
+          }
         }
       }
     }
+     * */
+  }
+  else
+  {
+    Msg::Error("FixNodalDofs is not implemented for this kind of function space");
   }
 }
 
@@ -548,25 +577,35 @@ template<class Assembler> void SetInitialDofs(FunctionSpaceBase *space,MElement
                                               Assembler &assembler,const simpleFunctionTime<double> *fct,
                                               FilterDof &filter,bool fullDg)
 {
-  int nv=e->getNumVertices();
-  std::vector<Dof> R;
-  space->getKeys(e,R);
-  int ncomp = space->getNumKeys(e)/nv;
-  staticDofManager<double> *dynass= static_cast<staticDofManager<double>*>(&assembler);
-  for(int i=0; i<nv;i++)
+  VertexBasedLagrangeFunctionSpace* lagspace = dynamic_cast<VertexBasedLagrangeFunctionSpace*>(space);
+  if (lagspace != NULL)
   {
-    // get the value of velocity
-    double myvalue = fct->operator()(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z());
-    // set the value
-    for(int j=0;j<ncomp;j++)
+    staticDofManager<double> *dynass= static_cast<staticDofManager<double>*>(&assembler);
+    std::vector<int> comp;
+    lagspace->getComp(comp);
+    int nv = e->getNumVertices();
+    std::vector<Dof> R;
+    for (int i=0; i< nv; i++)
     {
-      if(filter(R[i+j*nv]))
+      double myvalue = fct->operator()(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z());
+      R.clear();
+      space->getKeysOnVertex(e,e->getVertex(i),comp,R);
+      for (int iR =0; iR < R.size(); iR++)
       {
-        dynass->setInitialCondition(R[i+j*nv],myvalue,whichC);
-        break;
+        if(filter(R[iR]))
+        {
+          dynass->setInitialCondition(R[iR],myvalue,whichC);
+          break;
+        }
       }
+      
     }
   }
+  else
+  {
+    Msg::Error("SetInitialDofs is not implemented for this kind of function space");
+  }
+  
 }
 
 template<class Iterator,class Assembler> void SetInitialDofs(FunctionSpaceBase *space,Iterator itbegin,Iterator itend,
diff --git a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
index 9ac6b619b..9f4dce449 100644
--- a/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
+++ b/NonLinearSolver/space/ThreeDLagrangeFunctionSpace.h
@@ -49,8 +49,14 @@ class VertexBasedLagrangeFunctionSpace : public nlsFunctionSpace<double>
     }
     virtual ~VertexBasedLagrangeFunctionSpace(){};
     
+    virtual std::string getFunctionSpaceName() const 
+    {
+      return "VertexBasedLagrangeFunctionSpace";
+    }
+    
     virtual void usePrimaryShapeFunction(int c)
     {
+      Msg::Info("use comp %d with primary shape function in %s !!!",c, getFunctionSpaceName().c_str());
       _usePrimaryShapeFunctions.insert(c);
     }
     virtual bool withPrimaryShapeFunction(int c) const
@@ -148,13 +154,15 @@ class VertexBasedLagrangeFunctionSpace : public nlsFunctionSpace<double>
         this->getKeysOnElement(ele,keys);
       }
     }
-    virtual void getKeysOnVertex(MElement* ele, MVertex* v, const std::vector<int>& vercomp, std::vector<Dof>& keys) const{
-      // get keys on element
+    virtual void getKeysOnVertex(MElement* ele, MVertex* v, const std::vector<int>& vercomp, std::vector<Dof>& keys) const
+    {
+      // all Keys on this elements
       std::vector<Dof> elekeys;
       this->getKeys(ele,elekeys);
+     
+      // find position of vextex in list vertex of element
       int numVer =ele->getNumVertices();
-      int idx = 0;
-
+      int idx = -1;
       // find vertex index in element
       bool found = false;
       for (int iv = 0; iv<numVer; iv++){
@@ -164,27 +172,36 @@ class VertexBasedLagrangeFunctionSpace : public nlsFunctionSpace<double>
           break;
         }
       }
-
-      std::vector<int> spaceComp;
-      this->getComp(spaceComp);
-
       if (found == false){
         Msg::Error("Vertex %d does not belong to element %d",v->getNum(),ele->getNum());
+        return;
       }
-
-      // push back to dofs vector for vextex
-      for (int vc =0; vc < vercomp.size(); vc++){
-        // check if vercomp[vc] belongs to spaceComp
-        bool foundComp = false;
-        for (int i=0; i< spaceComp.size(); i++){
-          if (vercomp[vc] == spaceComp[i]){
-            foundComp = true;
-            break;
+      
+      std::vector<int> spaceComp;
+      this->getComp(spaceComp);
+      
+      for (int ic = 0; ic < vercomp.size(); ic++)
+      {
+        // check if comp belong to comp list in space
+        if (std::find(spaceComp.begin(),spaceComp.end(),vercomp[ic]) == spaceComp.end())
+        {
+          Msg::Error("comp %d does not exist in %s",vercomp[ic], getFunctionSpaceName().c_str());
+        }
+        else
+        {
+          int nbFF = getNumShapeFunctions(ele,vercomp[ic]);
+          int nbFFTotalLastIndex  = getShapeFunctionsIndex(ele,vercomp[ic]);
+          if (idx < nbFF)
+          {
+            keys.push_back(elekeys[nbFFTotalLastIndex+idx]);
+          }
+          #ifdef _DEBUG
+          else
+          {
+            Msg::Warning("dof comp %d present only in primary vertices");
           }
+          #endif //_DEBUG
         }
-        // if found--> add keys
-        if (foundComp)
-          keys.push_back(elekeys[idx+numVer*vercomp[vc]]);
       }
     };
     
@@ -571,6 +588,11 @@ class ThreeDLagrangeFunctionSpace : public VertexBasedLagrangeFunctionSpace
                                 int comp4_, int comp5_, int comp6_, const bool hessc, const bool thirdc);
     virtual ~ThreeDLagrangeFunctionSpace(){}
     
+    virtual std::string getFunctionSpaceName() const 
+    {
+      return "ThreeDLagrangeFunctionSpace";
+    }
+    
     virtual FunctionSpaceBase* clone(const int id) const 
     {
       Msg::Error("define ThreeDLagrangeFunctionSpace::clone!!!");
@@ -592,6 +614,11 @@ class IsoparametricLagrangeFunctionSpace : public VertexBasedLagrangeFunctionSpa
     {
     }
     
+    virtual std::string getFunctionSpaceName() const 
+    {
+      return "IsoparametricLagrangeFunctionSpace";
+    }
+    
     virtual FunctionSpaceBase* clone(const int id) const 
     {
       Msg::Error("define IsoparametricLagrangeFunctionSpace::clone");
diff --git a/dG3D/src/dG3DFunctionSpace.h b/dG3D/src/dG3DFunctionSpace.h
index b2cbe3e0d..e7c112bd9 100644
--- a/dG3D/src/dG3DFunctionSpace.h
+++ b/dG3D/src/dG3DFunctionSpace.h
@@ -36,6 +36,11 @@ class g3DLagrangeFunctionSpace : public ThreeDLagrangeFunctionSpace{
   g3DLagrangeFunctionSpace(int id, int ncomp, int comp1,int comp2,int comp3,int comp4, int comp5, int comp6) : 
                                            ThreeDLagrangeFunctionSpace(id,ncomp,comp1,comp2,comp3,comp4,comp5,comp6,false,false){}
   virtual ~g3DLagrangeFunctionSpace(){};
+  
+  virtual std::string getFunctionSpaceName() const 
+  {
+    return "g3DLagrangeFunctionSpace";
+  }
 
  protected :
   virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const
@@ -137,6 +142,11 @@ class dG3DLagrangeFunctionSpace : public ThreeDLagrangeFunctionSpace{
   dG3DLagrangeFunctionSpace(int id, int ncomp,int comp1,int comp2, int comp3, int comp4, int comp5, int comp6) : 
                               ThreeDLagrangeFunctionSpace(id,ncomp,comp1,comp2,comp3,comp4,comp5,comp6,false,false){}
   virtual ~dG3DLagrangeFunctionSpace(){};
+  
+  virtual std::string getFunctionSpaceName() const 
+  {
+    return "dG3DLagrangeFunctionSpace";
+  }
 	
 	virtual FunctionSpaceBase* clone(const int id) const {
 		if (_ncomp == 1){
@@ -187,6 +197,10 @@ class g3DhoDGFunctionSpace : public ThreeDLagrangeFunctionSpace{
   g3DhoDGFunctionSpace(int id, int ncomp, int comp1, int comp2, int comp3, int comp4, int comp5) : 
                      ThreeDLagrangeFunctionSpace(id,ncomp,comp1,comp2,comp3,comp4,comp5,true,true){};
   virtual ~g3DhoDGFunctionSpace(){};
+  virtual std::string getFunctionSpaceName() const 
+  {
+    return "g3DhoDGFunctionSpace";
+  }
  protected :
   virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const
   {
@@ -247,6 +261,10 @@ class dG3DhoDGFunctionSpace : public ThreeDLagrangeFunctionSpace{
   dG3DhoDGFunctionSpace(int id, int ncomp, int comp1, int comp2, int comp3, int comp4, int comp5) : 
                                             ThreeDLagrangeFunctionSpace(id,ncomp,comp1,comp2,comp3,comp4,comp5,true,true){};
   virtual ~dG3DhoDGFunctionSpace(){};
+  virtual std::string getFunctionSpaceName() const 
+  {
+    return "dG3DhoDGFunctionSpace";
+  }
 
  protected: // avoid duplication of the following functions with dG3DLagrangeFunctionSpace HOW ??
   virtual void getKeysOnElement(MElement *ele, std::vector<Dof> &keys) const{
@@ -316,6 +334,11 @@ class g3DDirichletBoundaryConditionLagrangeFunctionSpace : public g3DLagrangeFun
   g3DDirichletBoundaryConditionLagrangeFunctionSpace(int id, int ncomp, int comp1, int comp2, int comp3, int comp4, int comp5, int comp6) : 
                g3DLagrangeFunctionSpace(id, ncomp, comp1, comp2, comp3, comp4, comp5, comp6){}
   virtual ~g3DDirichletBoundaryConditionLagrangeFunctionSpace(){};
+  
+  virtual std::string getFunctionSpaceName() const 
+  {
+    return "g3DDirichletBoundaryConditionLagrangeFunctionSpace";
+  }
 	
 	virtual FunctionSpaceBase* clone(const int id) const{
 		if (_ncomp == 1) return new g3DDirichletBoundaryConditionLagrangeFunctionSpace(id,1,comp[0]);
@@ -425,7 +448,10 @@ class g3DNeumannBoundaryConditionLagrangeFunctionSpace : public g3DLagrangeFunct
   g3DNeumannBoundaryConditionLagrangeFunctionSpace(int id, int ncomp, int comp1, int comp2, int comp3, int comp4, int comp5, int comp6) : 
           g3DLagrangeFunctionSpace(id, ncomp, comp1,comp2, comp3, comp4, comp5, comp6){this->setParallelMesh();}
   virtual ~g3DNeumannBoundaryConditionLagrangeFunctionSpace(){};
-	
+	virtual std::string getFunctionSpaceName() const 
+  {
+    return "g3DNeumannBoundaryConditionLagrangeFunctionSpace";
+  }
 	virtual FunctionSpaceBase* clone(const int id) const{
 		if (_ncomp == 1) return new g3DNeumannBoundaryConditionLagrangeFunctionSpace(id,1,comp[0]);
 		else if (_ncomp == 2) return new g3DNeumannBoundaryConditionLagrangeFunctionSpace(id,2,comp[0],comp[1]);
@@ -479,6 +505,11 @@ class g3DDirichletBoundaryConditionLagrangeFunctionSpaceGhost : public g3DDirich
 		else if (_ncomp == 6) return new g3DDirichletBoundaryConditionLagrangeFunctionSpaceGhost(id,4,comp[0],comp[1],comp[2],comp[3],comp[4],comp[5]);
 		else return new g3DDirichletBoundaryConditionLagrangeFunctionSpaceGhost(id,_ncomp);
 	} 
+  
+  virtual std::string getFunctionSpaceName() const 
+  {
+    return "g3DDirichletBoundaryConditionLagrangeFunctionSpaceGhost";
+  }
 
   // be sure that the type is negative !!
   virtual void getKeys(MElement *ele, std::vector<Dof> &keys) const{
@@ -796,6 +827,11 @@ private:
 	virtual FunctionSpaceBase* clone(const int id) const{
 		Msg::Error("dG3DBoundaryConditionLagrangeFunctionSpace::clone needs to be defined");
 	}
+  
+  virtual std::string getFunctionSpaceName() const 
+  {
+    return "dG3DBoundaryConditionLagrangeFunctionSpace";
+  }
 
   virtual void getKeys(MInterfaceElement *ielem, std::vector<Dof> &keys) const{
     Msg::Error("Impossible to get keys on interface element for a Dirichlet Boundary Conditions");
@@ -878,6 +914,11 @@ class dG3DLagrangeBetween2DomainsFunctionSpace : public ThreeDLagrangeFunctionSp
   dG3DLagrangeBetween2DomainsFunctionSpace(int ncomp, FunctionSpaceBase*sp1, FunctionSpaceBase *sp2) :
                                             ThreeDLagrangeFunctionSpace(0, ncomp,false,false), spaceMinus(sp1), spacePlus(sp2){}
   virtual ~dG3DLagrangeBetween2DomainsFunctionSpace(){}
+  
+  virtual std::string getFunctionSpaceName() const 
+  {
+    return "dG3DLagrangeBetween2DomainsFunctionSpace";
+  }
 	
 	virtual FunctionSpaceBase* clone(const int id) const{
 		return new dG3DLagrangeBetween2DomainsFunctionSpace(_ncomp,spaceMinus,spacePlus);
-- 
GitLab


From 06e16bf070fbdee95f164371177a16ce95d35729 Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Tue, 2 Jun 2020 18:41:44 +0200
Subject: [PATCH 18/19] correction curl space

---
 NonLinearSolver/nlsolver/nlsolAlgorithms.h |  4 +-
 NonLinearSolver/space/CurlFunctionSpace.h  |  8 ++
 NonLinearSolver/space/mixedFunctionSpace.h | 91 ++++++++++++++++++++--
 dG3D/src/dG3DCurlFunctionSpace.h           | 44 +++++++++++
 4 files changed, 137 insertions(+), 10 deletions(-)

diff --git a/NonLinearSolver/nlsolver/nlsolAlgorithms.h b/NonLinearSolver/nlsolver/nlsolAlgorithms.h
index a6f6f2d7e..5a4371e3e 100644
--- a/NonLinearSolver/nlsolver/nlsolAlgorithms.h
+++ b/NonLinearSolver/nlsolver/nlsolAlgorithms.h
@@ -483,7 +483,7 @@ template<class Iterator,class Assembler> void FixInterfaceNodalDofs(FunctionSpac
 
 template<class Assembler> void FixNodalDofs(FunctionSpaceBase *space,MElement *e,Assembler &assembler,simpleFunction<typename Assembler::dataVec> &fct,FilterDof &filter,bool fullDg)
 {
-  VertexBasedLagrangeFunctionSpace* lagspace = dynamic_cast<VertexBasedLagrangeFunctionSpace*>(space);
+  nlsFunctionSpace<double>* lagspace = dynamic_cast<nlsFunctionSpace<double>*>(space);
   if (lagspace != NULL)
   {
     staticDofManager<double> *dynass= static_cast<staticDofManager<double>*>(&assembler);
@@ -577,7 +577,7 @@ template<class Assembler> void SetInitialDofs(FunctionSpaceBase *space,MElement
                                               Assembler &assembler,const simpleFunctionTime<double> *fct,
                                               FilterDof &filter,bool fullDg)
 {
-  VertexBasedLagrangeFunctionSpace* lagspace = dynamic_cast<VertexBasedLagrangeFunctionSpace*>(space);
+  nlsFunctionSpace<double>* lagspace = dynamic_cast<nlsFunctionSpace<double>*>(space);
   if (lagspace != NULL)
   {
     staticDofManager<double> *dynass= static_cast<staticDofManager<double>*>(&assembler);
diff --git a/NonLinearSolver/space/CurlFunctionSpace.h b/NonLinearSolver/space/CurlFunctionSpace.h
index 8b68c07db..ef47dc198 100644
--- a/NonLinearSolver/space/CurlFunctionSpace.h
+++ b/NonLinearSolver/space/CurlFunctionSpace.h
@@ -44,6 +44,14 @@ class CurlFunctionSpaceBase
     
   public:
     virtual ~CurlFunctionSpaceBase(){}
+    
+    virtual int getNumComp() const =0;
+    virtual void getComp(std::vector<int> &comp) const = 0; // get all comp
+    
+    virtual int getNumShapeFunctions(MElement* ele, int c) const =0;
+    virtual int getShapeFunctionsIndex(MElement* ele, int c) const =0;
+    virtual int getTotalNumShapeFunctions(MElement* ele) const = 0;
+
     virtual int getNumKeys(MElement *ele) const = 0;
     virtual void getKeys(MElement *ele, std::vector<Dof> &keys) const = 0;
 
diff --git a/NonLinearSolver/space/mixedFunctionSpace.h b/NonLinearSolver/space/mixedFunctionSpace.h
index cedbd27c4..cc1689132 100644
--- a/NonLinearSolver/space/mixedFunctionSpace.h
+++ b/NonLinearSolver/space/mixedFunctionSpace.h
@@ -65,22 +65,97 @@ class CurlMixedFunctionSpace : public mixedFunctionSpaceBase,  public nlsFunctio
     
     virtual int getId(void) const { return _space->getId();}
     
-    virtual int getNumShapeFunctions(MElement* ele, int c) const {Msg::Error("implement CurlMixedFunctionSpace::getNumShapeFunctions");};
-    virtual int getShapeFunctionsIndex(MElement* ele, int c) const { Msg::Error("implement CurlMixedFunctionSpace::getShapeFunctionsIndex");}; // location of comp c
-    virtual int getTotalNumShapeFunctions(MElement* ele) const {Msg::Error("implement CurlMixedFunctionSpace::getTotalNumShapeFunctions");};
-
+    virtual int getNumComp() const {return _space->getNumComp() + _curlSpace->getNumComp();}
+    virtual void getComp(std::vector<int> &comp) const 
+    {
+      std::vector<int> standardComp, curlComp;
+      _space->getComp(standardComp);
+      _curlSpace->getComp(curlComp);
+      
+      comp.resize(getNumComp());
+      for (int i=0; i< standardComp.size(); i++)
+      {
+        comp[i] = standardComp[i];
+      }
+      for (int i=0; i< curlComp.size(); i++)
+      {
+        comp[standardComp.size()+i] = curlComp[i];
+      }
+    }
+    
+    virtual int getNumShapeFunctions(MElement* ele, int c) const 
+    {
+      std::vector<int> standardComp, curlComp;
+      _space->getComp(standardComp);
+      _curlSpace->getComp(curlComp);
+      if (std::find(standardComp.begin(),standardComp.end(),c) != standardComp.end())
+      {
+        return _space->getNumShapeFunctions(ele,c);
+      }
+      else if (std::find(curlComp.begin(),curlComp.end(),c) != curlComp.end())
+      {
+        return _curlSpace->getNumShapeFunctions(ele,c);
+      }
+      else
+      {
+        Msg::Error("comp %d does not exist in CurlMixedFunctionSpace::getNumShapeFunctions");
+      }
+    };
+    virtual int getShapeFunctionsIndex(MElement* ele, int c) const 
+    {
+      std::vector<int> standardComp, curlComp;
+      _space->getComp(standardComp);
+      _curlSpace->getComp(curlComp);
+      if (std::find(standardComp.begin(),standardComp.end(),c) != standardComp.end())
+      {
+        return _space->getShapeFunctionsIndex(ele,c);
+      }
+      else if (std::find(curlComp.begin(),curlComp.end(),c) != curlComp.end())
+      {
+        return _curlSpace->getShapeFunctionsIndex(ele,c);
+      }
+      else
+      {
+        Msg::Error("comp %d does not exist in CurlMixedFunctionSpace::getShapeFunctionsIndex");
+      }
+      
+    }; // location of comp c
+    virtual int getTotalNumShapeFunctions(MElement* ele) const 
+    {
+      return _space->getTotalNumShapeFunctions(ele)+_curlSpace->getTotalNumShapeFunctions(ele);
+    };
     
     virtual bool withHessianComputation() const {return _space->withHessianComputation();};
     virtual bool withThirdDevComputation() const {return _space->withThirdDevComputation();}
     
-    virtual int getNumComp() const {return _space->getNumComp();};
-    virtual void getComp(std::vector<int> &comp) const {_space->getComp(comp);};
-    virtual void setNewIdForComp(int cc, int type) {_space->setNewIdForComp(cc,type);};
+    virtual void setNewIdForComp(int cc, int type)
+    {
+      std::vector<int> standardComp, curlComp;
+      _space->getComp(standardComp);
+      if (std::find(standardComp.begin(),standardComp.end(),cc) != standardComp.end())
+      { 
+        _space->setNewIdForComp(cc,type);
+      }
+      else
+      {
+        Msg::Error("CurlMixedFunctionSpace::setNewIdForComp with comp %d cannot be called !!!");
+      }
+    };
     
     // functions from FunctionSpace
     virtual void getKeysOnVertex(MElement *ele, MVertex *v, const std::vector<int> &comp, std::vector<Dof> &keys) const
     {
-      _space->getKeysOnVertex(ele,v,comp,keys);
+      std::vector<int> standardComp;
+      _space->getComp(standardComp);
+      std::vector<int> nodeComp;
+      for (int i=0; i< comp.size(); i++)
+      {
+        if (std::find(standardComp.begin(),standardComp.end(),comp[i]) != standardComp.end())
+        {
+          nodeComp.push_back(comp[i]);
+        }
+      }
+      _space->getKeysOnVertex(ele,v,nodeComp,keys);
     }
     
     virtual int getNumKeys(MElement *ele) const 
diff --git a/dG3D/src/dG3DCurlFunctionSpace.h b/dG3D/src/dG3DCurlFunctionSpace.h
index be1c4c132..aba12f6fd 100644
--- a/dG3D/src/dG3DCurlFunctionSpace.h
+++ b/dG3D/src/dG3DCurlFunctionSpace.h
@@ -44,6 +44,50 @@ class g3DHierarchicalCurlFunctionSpace : public ScalarHierarchicalCurlFunctionSp
     
     virtual int getId(void) const {return _iField;};
     
+    virtual int getNumComp() const {return _ncomp;};
+    virtual void getComp(std::vector<int> &comp) const 
+    {
+      comp.resize(_comp.size());
+      std::copy(_comp.begin(),_comp.end(),comp.begin());
+    }
+    
+    virtual int getNumShapeFunctions(MElement* ele, int c) const 
+    {
+      // equal numer of edge
+      return ele->getNumEdges();
+    }
+    virtual int getShapeFunctionsIndex(MElement* ele, int c) const
+    {
+      int num = 0;
+      bool found = false;
+      for (int i=0; i< _comp.size(); i++)
+      {
+        if (c == _comp[i])
+        {
+          found = true;
+          break;
+        }
+        num += getNumShapeFunctions(ele,_comp[i]);
+      }
+      
+      if (!found)
+      {
+        Msg::Error("field index %d does not exist",c);
+      };
+      
+      return num;
+    };
+    
+    virtual int getTotalNumShapeFunctions(MElement* ele) const
+    {
+      int num = 0;
+      for (int i=0; i< _comp.size(); i++)
+      {
+        num += getNumShapeFunctions(ele,_comp[i]);
+      }
+      return num;
+    };
+    
     virtual int getNumKeys(MElement *ele) const 
     {
       return _ncomp*ele->getNumEdges();
-- 
GitLab


From 03dd24100be94ba13e457b359cef87fd836a767f Mon Sep 17 00:00:00 2001
From: Van Dung Nguyen <vdg.nguyen@gmail.com>
Date: Tue, 2 Jun 2020 19:14:02 +0200
Subject: [PATCH 19/19] correct initial dof and fixedDOf with functionspace

---
 NonLinearSolver/nlsolver/nlsolAlgorithms.h    | 51 ++++++++++++++-----
 .../nlsolver/nonLinearMechSolver.cpp          |  7 ++-
 2 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/NonLinearSolver/nlsolver/nlsolAlgorithms.h b/NonLinearSolver/nlsolver/nlsolAlgorithms.h
index 5a4371e3e..27d9b982d 100644
--- a/NonLinearSolver/nlsolver/nlsolAlgorithms.h
+++ b/NonLinearSolver/nlsolver/nlsolAlgorithms.h
@@ -481,11 +481,11 @@ template<class Iterator,class Assembler> void FixInterfaceNodalDofs(FunctionSpac
 }
 
 
-template<class Assembler> void FixNodalDofs(FunctionSpaceBase *space,MElement *e,Assembler &assembler,simpleFunction<typename Assembler::dataVec> &fct,FilterDof &filter,bool fullDg)
+template<class Assembler> void FixNodalDofs(FunctionSpaceBase *space,MElement *e,Assembler &assembler,simpleFunction<typename Assembler::dataVec> &fct,FilterDof &filter,bool fullDg, mixedFunctionSpaceBase::DofType dofType)
 {
-  nlsFunctionSpace<double>* lagspace = dynamic_cast<nlsFunctionSpace<double>*>(space);
-  if (lagspace != NULL)
+  if (dofType == mixedFunctionSpaceBase::DOF_STANDARD)
   {
+    nlsFunctionSpace<double>* lagspace = static_cast<nlsFunctionSpace<double>*>(space);
     staticDofManager<double> *dynass= static_cast<staticDofManager<double>*>(&assembler);
     std::vector<int> comp;
     lagspace->getComp(comp);
@@ -547,18 +547,31 @@ template<class Assembler> void FixNodalDofs(FunctionSpaceBase *space,MElement *e
     }
      * */
   }
+  else if (dofType == mixedFunctionSpaceBase::DOF_CURL)
+  {
+    std::vector<Dof> R;
+    space->getKeys(e,R);
+    for (int iR =0; iR < R.size(); iR++)
+    {
+      if(filter(R[iR]))
+      {
+        assembler.fixDof(R[iR], fct(0,0,0));
+      }
+    }
+  }
   else
   {
-    Msg::Error("FixNodalDofs is not implemented for this kind of function space");
+    Msg::Error("FixNodalDofs is not implemented for this kind of DOF");
   }
 }
 
 template<class Iterator,class Assembler> void FixNodalDofs(FunctionSpaceBase *space,Iterator itbegin,Iterator itend,Assembler &assembler,
-                                                           simpleFunction<typename Assembler::dataVec> &fct,FilterDof &filter,bool fullDg)
+                                                           simpleFunction<typename Assembler::dataVec> &fct,FilterDof &filter,bool fullDg,
+                                                           mixedFunctionSpaceBase::DofType dofType)
 {
   for (Iterator it=itbegin;it!=itend;++it)
   {
-    FixNodalDofs(space,it->second,assembler,fct,filter,fullDg);
+    FixNodalDofs(space,it->second,assembler,fct,filter,fullDg,dofType);
   }
 }
 
@@ -575,11 +588,11 @@ void FixNodalDofs(rigidContactSpaceBase *space,simpleFunction<typename Assembler
 
 template<class Assembler> void SetInitialDofs(FunctionSpaceBase *space,MElement *e,const nonLinearBoundaryCondition::whichCondition whichC,
                                               Assembler &assembler,const simpleFunctionTime<double> *fct,
-                                              FilterDof &filter,bool fullDg)
+                                              FilterDof &filter,bool fullDg, mixedFunctionSpaceBase::DofType dofType)
 {
-  nlsFunctionSpace<double>* lagspace = dynamic_cast<nlsFunctionSpace<double>*>(space);
-  if (lagspace != NULL)
+  if (dofType == mixedFunctionSpaceBase::DOF_STANDARD)
   {
+    nlsFunctionSpace<double>* lagspace = static_cast<nlsFunctionSpace<double>*>(space);
     staticDofManager<double> *dynass= static_cast<staticDofManager<double>*>(&assembler);
     std::vector<int> comp;
     lagspace->getComp(comp);
@@ -601,9 +614,23 @@ template<class Assembler> void SetInitialDofs(FunctionSpaceBase *space,MElement
       
     }
   }
+  else if (dofType == mixedFunctionSpaceBase::DOF_CURL)
+  {
+    staticDofManager<double> *dynass= static_cast<staticDofManager<double>*>(&assembler);
+    std::vector<Dof> R;
+    space->getKeys(e,R);
+    double myvalue = fct->operator()(0,0,0);
+    for (int iR =0; iR < R.size(); iR++)
+    {
+      if(filter(R[iR]))
+      {
+        dynass->setInitialCondition(R[iR],myvalue,whichC);
+      }
+    }
+  }
   else
   {
-    Msg::Error("SetInitialDofs is not implemented for this kind of function space");
+    Msg::Error("SetInitialDofs is not implemented for this kind of DOF");
   }
   
 }
@@ -611,11 +638,11 @@ template<class Assembler> void SetInitialDofs(FunctionSpaceBase *space,MElement
 template<class Iterator,class Assembler> void SetInitialDofs(FunctionSpaceBase *space,Iterator itbegin,Iterator itend,
                                                            const nonLinearBoundaryCondition::whichCondition whichC,
                                                             Assembler &assembler, const simpleFunctionTime<double> *fct,
-                                                            FilterDof &filter,bool fullDg)
+                                                            FilterDof &filter,bool fullDg, mixedFunctionSpaceBase::DofType dofType)
 {
   for (Iterator it=itbegin;it!=itend;++it)
   {
-    SetInitialDofs(space,it->second,whichC,assembler,fct,filter,fullDg);
+    SetInitialDofs(space,it->second,whichC,assembler,fct,filter,fullDg,dofType);
   }
 }
 
diff --git a/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
index c0eb54205..7b57cc136 100644
--- a/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
+++ b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
@@ -4420,14 +4420,14 @@ void nonLinearMechSolver::fixNodalDofs(){
         const elementGroup *gdiri = diri._vgroup[j];
         FilterDof* fdofdiri = diri._vfilter[j];
         bool fdg = diri._vdg[j];
-        FixNodalDofs(spdiri,gdiri->begin(),gdiri->end(),*currentManager,*diri._f,*(fdofdiri),fdg);
+        FixNodalDofs(spdiri,gdiri->begin(),gdiri->end(),*currentManager,*diri._f,*(fdofdiri),fdg,diri._dofType);
       }
     }
     else
     {
       for(int j=0;j<diri._vspace.size();j++){
         // allow to prescribed a velocity or acceleration over time using a dirichlet BC
-        SetInitialDofs(diri._vspace[j],diri._vgroup[j]->begin(),diri._vgroup[j]->end(),diri._mycondition,*currentManager,diri._f,*(diri._vfilter[j]),diri._vdg[j]);
+        SetInitialDofs(diri._vspace[j],diri._vgroup[j]->begin(),diri._vgroup[j]->end(),diri._mycondition,*currentManager,diri._f,*(diri._vfilter[j]),diri._vdg[j],diri._dofType);
       }
     }
   }
@@ -8156,7 +8156,7 @@ void nonLinearMechSolver::setInitialCondition(){
         currentManager = multiManager->getDofManagerByComp(initC._comp);
       }
       for(int j=0;j<initC._vspace.size();j++){
-        SetInitialDofs(initC._vspace[j],initC._vgroup[j]->begin(),initC._vgroup[j]->end(),initC._mycondition,*currentManager,initC._f,*(initC._vfilter[j]),initC._vdg[j]);
+        SetInitialDofs(initC._vspace[j],initC._vgroup[j]->begin(),initC._vgroup[j]->end(),initC._mycondition,*currentManager,initC._f,*(initC._vfilter[j]),initC._vdg[j],initC._dofType);
       }
     }
     else{
@@ -9222,7 +9222,6 @@ int nonLinearMechSolver::NewtonRaphson(const int numstep){
       break;
     }
   }
-  //this->fixNodalDofs(); // reset values of converged state in accordance to BC
   return iter;
 }
 
-- 
GitLab