/[escript]/branches/diaplayground/ripley/src/Brick.cpp
ViewVC logotype

Diff of /branches/diaplayground/ripley/src/Brick.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3792 by caltinay, Wed Feb 1 06:16:25 2012 UTC revision 4009 by caltinay, Tue Oct 2 05:53:37 2012 UTC
# Line 1  Line 1 
1    
2  /*******************************************************  /*****************************************************************************
3  *  *
4  * Copyright (c) 2003-2012 by University of Queensland  * Copyright (c) 2003-2012 by University of Queensland
5  * Earth Systems Science Computational Center (ESSCC)  * http://www.uq.edu.au
 * http://www.uq.edu.au/esscc  
6  *  *
7  * Primary Business: Queensland, Australia  * Primary Business: Queensland, Australia
8  * Licensed under the Open Software License version 3.0  * Licensed under the Open Software License version 3.0
9  * http://www.opensource.org/licenses/osl-3.0.php  * http://www.opensource.org/licenses/osl-3.0.php
10  *  *
11  *******************************************************/  * Development until 2012 by Earth Systems Science Computational Center (ESSCC)
12    * Development since 2012 by School of Earth Sciences
13    *
14    *****************************************************************************/
15    
16  #include <ripley/Brick.h>  #include <ripley/Brick.h>
17  extern "C" {  extern "C" {
# Line 32  namespace ripley { Line 34  namespace ripley {
34  Brick::Brick(int n0, int n1, int n2, double x0, double y0, double z0,  Brick::Brick(int n0, int n1, int n2, double x0, double y0, double z0,
35               double x1, double y1, double z1, int d0, int d1, int d2) :               double x1, double y1, double z1, int d0, int d1, int d2) :
36      RipleyDomain(3),      RipleyDomain(3),
     m_gNE0(n0),  
     m_gNE1(n1),  
     m_gNE2(n2),  
37      m_x0(x0),      m_x0(x0),
38      m_y0(y0),      m_y0(y0),
39      m_z0(z0),      m_z0(z0),
40      m_l0(x1-x0),      m_l0(x1-x0),
41      m_l1(y1-y0),      m_l1(y1-y0),
42      m_l2(z1-z0),      m_l2(z1-z0)
     m_NX(d0),  
     m_NY(d1),  
     m_NZ(d2)  
43  {  {
44        // ignore subdivision parameters for serial run
45        if (m_mpiInfo->size == 1) {
46            d0=1;
47            d1=1;
48            d2=1;
49        }
50    
51        bool warn=false;
52        // if number of subdivisions is non-positive, try to subdivide by the same
53        // ratio as the number of elements
54        if (d0<=0 && d1<=0 && d2<=0) {
55            warn=true;
56            d0=(int)(pow(m_mpiInfo->size*(n0+1)*(n0+1)/((float)(n1+1)*(n2+1)), 1.f/3));
57            d1=(int)(d0*n1/(float)n0);
58            d2=m_mpiInfo->size/(d0*d1);
59            if (d0*d1*d2 != m_mpiInfo->size) {
60                // ratios not the same so leave "smallest" side undivided and try
61                // dividing 2 sides only
62                if (n0>=n1) {
63                    if (n1>=n2) {
64                        d0=d1=0;
65                        d2=1;
66                    } else {
67                        d0=d2=0;
68                        d1=1;
69                    }
70                } else {
71                    if (n0>=n2) {
72                        d0=d1=0;
73                        d2=1;
74                    } else {
75                        d0=1;
76                        d1=d2=0;
77                    }
78                }
79            }
80        }
81        if (d0<=0 && d1<=0) {
82            warn=true;
83            d0=int(sqrt(m_mpiInfo->size*(n0+1)/(float)(n1+1)));
84            d1=m_mpiInfo->size/d0;
85            if (d0*d1*d2 != m_mpiInfo->size) {
86                // ratios not the same so subdivide side with more elements only
87                if (n0>n1) {
88                    d0=0;
89                    d1=1;
90                } else {
91                    d0=1;
92                    d1=0;
93                }
94            }
95        } else if (d0<=0 && d2<=0) {
96            warn=true;
97            d0=int(sqrt(m_mpiInfo->size*(n0+1)/(float)(n2+1)));
98            d2=m_mpiInfo->size/d0;
99            if (d0*d1*d2 != m_mpiInfo->size) {
100                // ratios not the same so subdivide side with more elements only
101                if (n0>n2) {
102                    d0=0;
103                    d2=1;
104                } else {
105                    d0=1;
106                    d2=0;
107                }
108            }
109        } else if (d1<=0 && d2<=0) {
110            warn=true;
111            d1=int(sqrt(m_mpiInfo->size*(n1+1)/(float)(n2+1)));
112            d2=m_mpiInfo->size/d1;
113            if (d0*d1*d2 != m_mpiInfo->size) {
114                // ratios not the same so subdivide side with more elements only
115                if (n1>n2) {
116                    d1=0;
117                    d2=1;
118                } else {
119                    d1=1;
120                    d2=0;
121                }
122            }
123        }
124        if (d0<=0) {
125            // d1,d2 are preset, determine d0
126            d0=m_mpiInfo->size/(d1*d2);
127        } else if (d1<=0) {
128            // d0,d2 are preset, determine d1
129            d1=m_mpiInfo->size/(d0*d2);
130        } else if (d2<=0) {
131            // d0,d1 are preset, determine d2
132            d2=m_mpiInfo->size/(d0*d1);
133        }
134    
135        m_NX=d0;
136        m_NY=d1;
137        m_NZ=d2;
138    
139      // ensure number of subdivisions is valid and nodes can be distributed      // ensure number of subdivisions is valid and nodes can be distributed
140      // among number of ranks      // among number of ranks
141      if (m_NX*m_NY*m_NZ != m_mpiInfo->size)      if (m_NX*m_NY*m_NZ != m_mpiInfo->size)
142          throw RipleyException("Invalid number of spatial subdivisions");          throw RipleyException("Invalid number of spatial subdivisions");
143    
144      if ((n0+1)%m_NX > 0 || (n1+1)%m_NY > 0 || (n2+1)%m_NZ > 0)      if (warn) {
145          throw RipleyException("Number of elements+1 must be separable into number of ranks in each dimension");          cout << "Warning: Automatic domain subdivision (d0=" << d0 << ", d1="
146                << d1 << ", d2=" << d2 << "). This may not be optimal!" << endl;
147        }
148    
149        if ((n0+1)%m_NX > 0) {
150            double Dx=m_l0/n0;
151            n0=(int)round((float)(n0+1)/d0+0.5)*d0-1;
152            m_l0=Dx*n0;
153            cout << "Warning: Adjusted number of elements and length. N0="
154                << n0 << ", l0=" << m_l0 << endl;
155        }
156        if ((n1+1)%m_NY > 0) {
157            double Dy=m_l1/n1;
158            n1=(int)round((float)(n1+1)/d1+0.5)*d1-1;
159            m_l1=Dy*n1;
160            cout << "Warning: Adjusted number of elements and length. N1="
161                << n1 << ", l1=" << m_l1 << endl;
162        }
163        if ((n2+1)%m_NZ > 0) {
164            double Dz=m_l2/n2;
165            n2=(int)round((float)(n2+1)/d2+0.5)*d2-1;
166            m_l2=Dz*n2;
167            cout << "Warning: Adjusted number of elements and length. N2="
168                << n2 << ", l2=" << m_l2 << endl;
169        }
170    
171        m_gNE0=n0;
172        m_gNE1=n1;
173        m_gNE2=n2;
174    
175      if ((m_NX > 1 && (n0+1)/m_NX<2) || (m_NY > 1 && (n1+1)/m_NY<2) || (m_NZ > 1 && (n2+1)/m_NZ<2))      if ((m_NX > 1 && (n0+1)/m_NX<2) || (m_NY > 1 && (n1+1)/m_NY<2) || (m_NZ > 1 && (n2+1)/m_NZ<2))
176          throw RipleyException("Too few elements for the number of ranks");          throw RipleyException("Too few elements for the number of ranks");
# Line 121  bool Brick::operator==(const AbstractDom Line 240  bool Brick::operator==(const AbstractDom
240      return false;      return false;
241  }  }
242    
243    void Brick::readBinaryGrid(escript::Data& out, string filename,
244                               const vector<int>& first,
245                               const vector<int>& numValues) const
246    {
247        // check destination function space
248        int myN0, myN1, myN2;
249        if (out.getFunctionSpace().getTypeCode() == Nodes) {
250            myN0 = m_N0;
251            myN1 = m_N1;
252            myN2 = m_N2;
253        } else if (out.getFunctionSpace().getTypeCode() == Elements ||
254                    out.getFunctionSpace().getTypeCode() == ReducedElements) {
255            myN0 = m_NE0;
256            myN1 = m_NE1;
257            myN2 = m_NE2;
258        } else
259            throw RipleyException("readBinaryGrid(): invalid function space for output data object");
260    
261        // check file existence and size
262        ifstream f(filename.c_str(), ifstream::binary);
263        if (f.fail()) {
264            throw RipleyException("readBinaryGrid(): cannot open file");
265        }
266        f.seekg(0, ios::end);
267        const int numComp = out.getDataPointSize();
268        const int filesize = f.tellg();
269        const int reqsize = numValues[0]*numValues[1]*numValues[2]*numComp*sizeof(float);
270        if (filesize < reqsize) {
271            f.close();
272            throw RipleyException("readBinaryGrid(): not enough data in file");
273        }
274    
275        // check if this rank contributes anything
276        if (first[0] >= m_offset0+myN0 || first[0]+numValues[0] <= m_offset0 ||
277                first[1] >= m_offset1+myN1 || first[1]+numValues[1] <= m_offset1 ||
278                first[2] >= m_offset2+myN2 || first[2]+numValues[2] <= m_offset2) {
279            f.close();
280            return;
281        }
282    
283        // now determine how much this rank has to write
284    
285        // first coordinates in data object to write to
286        const int first0 = max(0, first[0]-m_offset0);
287        const int first1 = max(0, first[1]-m_offset1);
288        const int first2 = max(0, first[2]-m_offset2);
289        // indices to first value in file
290        const int idx0 = max(0, m_offset0-first[0]);
291        const int idx1 = max(0, m_offset1-first[1]);
292        const int idx2 = max(0, m_offset2-first[2]);
293        // number of values to write
294        const int num0 = min(numValues[0]-idx0, myN0-first0);
295        const int num1 = min(numValues[1]-idx1, myN1-first1);
296        const int num2 = min(numValues[2]-idx2, myN2-first2);
297    
298        out.requireWrite();
299        vector<float> values(num0*numComp);
300        const int dpp = out.getNumDataPointsPerSample();
301    
302        for (index_t z=0; z<num2; z++) {
303            for (index_t y=0; y<num1; y++) {
304                const int fileofs = numComp*(idx0+(idx1+y)*numValues[0]+(idx2+z)*numValues[0]*numValues[1]);
305                f.seekg(fileofs*sizeof(float));
306                f.read((char*)&values[0], num0*numComp*sizeof(float));
307                const int dataIndex = first0+(first1+y)*myN0+(first2+z)*myN0*myN1;
308    
309                for (index_t x=0; x<num0; x++) {
310                    double* dest = out.getSampleDataRW(dataIndex+x);
311                    for (index_t c=0; c<numComp; c++) {
312                        for (index_t q=0; q<dpp; q++) {
313                            *dest++ = static_cast<double>(values[x*numComp+c]);
314                        }
315                    }
316                }
317            }
318        }
319    
320        f.close();
321    }
322    
323  void Brick::dump(const string& fileName) const  void Brick::dump(const string& fileName) const
324  {  {
325  #if USE_SILO  #if USE_SILO
# Line 129  void Brick::dump(const string& fileName) Line 328  void Brick::dump(const string& fileName)
328          fn+=".silo";          fn+=".silo";
329      }      }
330    
     const int NUM_SILO_FILES = 1;  
     const char* blockDirFmt = "/block%04d";  
331      int driver=DB_HDF5;          int driver=DB_HDF5;    
332      string siloPath;      string siloPath;
333      DBfile* dbfile = NULL;      DBfile* dbfile = NULL;
334    
335  #ifdef ESYS_MPI  #ifdef ESYS_MPI
336      PMPIO_baton_t* baton = NULL;      PMPIO_baton_t* baton = NULL;
337        const int NUM_SILO_FILES = 1;
338        const char* blockDirFmt = "/block%04d";
339  #endif  #endif
340    
341      if (m_mpiInfo->size > 1) {      if (m_mpiInfo->size > 1) {
# Line 528  void Brick::setToSize(escript::Data& out Line 727  void Brick::setToSize(escript::Data& out
727          const double xSize=getFirstCoordAndSpacing(0).second;          const double xSize=getFirstCoordAndSpacing(0).second;
728          const double ySize=getFirstCoordAndSpacing(1).second;          const double ySize=getFirstCoordAndSpacing(1).second;
729          const double zSize=getFirstCoordAndSpacing(2).second;          const double zSize=getFirstCoordAndSpacing(2).second;
730          const double size=min(min(xSize,ySize),zSize);          const double size=sqrt(xSize*xSize+ySize*ySize+zSize*zSize);
731  #pragma omp parallel for  #pragma omp parallel for
732          for (index_t k = 0; k < getNumElements(); ++k) {          for (index_t k = 0; k < getNumElements(); ++k) {
733              double* o = out.getSampleDataRW(k);              double* o = out.getSampleDataRW(k);
# Line 759  void Brick::assembleGradient(escript::Da Line 958  void Brick::assembleGradient(escript::Da
958      const dim_t numComp = in.getDataPointSize();      const dim_t numComp = in.getDataPointSize();
959      const double h0 = m_l0/m_gNE0;      const double h0 = m_l0/m_gNE0;
960      const double h1 = m_l1/m_gNE1;      const double h1 = m_l1/m_gNE1;
961      const double h2 = m_l1/m_gNE2;      const double h2 = m_l2/m_gNE2;
962      const double C0 = .044658198738520451079;      const double C0 = .044658198738520451079;
963      const double C1 = .16666666666666666667;      const double C1 = .16666666666666666667;
964      const double C2 = .21132486540518711775;      const double C2 = .21132486540518711775;
# Line 770  void Brick::assembleGradient(escript::Da Line 969  void Brick::assembleGradient(escript::Da
969    
970      if (out.getFunctionSpace().getTypeCode() == Elements) {      if (out.getFunctionSpace().getTypeCode() == Elements) {
971          out.requireWrite();          out.requireWrite();
972  #pragma omp parallel for  #pragma omp parallel
973          for (index_t k2=0; k2 < m_NE2; ++k2) {          {
974              for (index_t k1=0; k1 < m_NE1; ++k1) {              vector<double> f_000(numComp);
975                  for (index_t k0=0; k0 < m_NE0; ++k0) {              vector<double> f_001(numComp);
976                      const double* f_000 = in.getSampleDataRO(INDEX3(k0,k1,k2, m_N0,m_N1));              vector<double> f_010(numComp);
977                      const double* f_001 = in.getSampleDataRO(INDEX3(k0,k1,k2+1, m_N0,m_N1));              vector<double> f_011(numComp);
978                      const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,k1,k2+1, m_N0,m_N1));              vector<double> f_100(numComp);
979                      const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,k1+1,k2+1, m_N0,m_N1));              vector<double> f_101(numComp);
980                      const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,k1+1,k2, m_N0,m_N1));              vector<double> f_110(numComp);
981                      const double* f_011 = in.getSampleDataRO(INDEX3(k0,k1+1,k2+1, m_N0,m_N1));              vector<double> f_111(numComp);
982                      const double* f_010 = in.getSampleDataRO(INDEX3(k0,k1+1,k2, m_N0,m_N1));  #pragma omp for
983                      const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,k1,k2, m_N0,m_N1));              for (index_t k2=0; k2 < m_NE2; ++k2) {
984                      double* o = out.getSampleDataRW(INDEX3(k0,k1,k2,m_NE0,m_NE1));                  for (index_t k1=0; k1 < m_NE1; ++k1) {
985                      for (index_t i=0; i < numComp; ++i) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
986                          const double V0=((f_100[i]-f_000[i])*C5 + (f_111[i]-f_011[i])*C0 + (f_101[i]+f_110[i]-f_001[i]-f_010[i])*C1) / h0;                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
987                          const double V1=((f_110[i]-f_010[i])*C5 + (f_101[i]-f_001[i])*C0 + (f_100[i]+f_111[i]-f_000[i]-f_011[i])*C1) / h0;                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
988                          const double V2=((f_101[i]-f_001[i])*C5 + (f_110[i]-f_010[i])*C0 + (f_100[i]+f_111[i]-f_000[i]-f_011[i])*C1) / h0;                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
989                          const double V3=((f_111[i]-f_011[i])*C5 + (f_100[i]-f_000[i])*C0 + (f_101[i]+f_110[i]-f_001[i]-f_010[i])*C1) / h0;                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
990                          const double V4=((f_010[i]-f_000[i])*C5 + (f_111[i]-f_101[i])*C0 + (f_011[i]+f_110[i]-f_001[i]-f_100[i])*C1) / h1;                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
991                          const double V5=((f_110[i]-f_100[i])*C5 + (f_011[i]-f_001[i])*C0 + (f_010[i]+f_111[i]-f_000[i]-f_101[i])*C1) / h1;                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
992                          const double V6=((f_011[i]-f_001[i])*C5 + (f_110[i]-f_100[i])*C0 + (f_010[i]+f_111[i]-f_000[i]-f_101[i])*C1) / h1;                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
993                          const double V7=((f_111[i]-f_101[i])*C5 + (f_010[i]-f_000[i])*C0 + (f_011[i]+f_110[i]-f_001[i]-f_100[i])*C1) / h1;                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
994                          const double V8=((f_001[i]-f_000[i])*C5 + (f_111[i]-f_110[i])*C0 + (f_011[i]+f_101[i]-f_010[i]-f_100[i])*C1) / h2;                          double* o = out.getSampleDataRW(INDEX3(k0,k1,k2,m_NE0,m_NE1));
995                          const double V9=((f_101[i]-f_100[i])*C5 + (f_011[i]-f_010[i])*C0 + (f_001[i]+f_111[i]-f_000[i]-f_110[i])*C1) / h2;                          for (index_t i=0; i < numComp; ++i) {
996                          const double V10=((f_011[i]-f_010[i])*C5 + (f_101[i]-f_100[i])*C0 + (f_001[i]+f_111[i]-f_000[i]-f_110[i])*C1) / h2;                              const double V0=((f_100[i]-f_000[i])*C5 + (f_111[i]-f_011[i])*C0 + (f_101[i]+f_110[i]-f_001[i]-f_010[i])*C1) / h0;
997                          const double V11=((f_111[i]-f_110[i])*C5 + (f_001[i]-f_000[i])*C0 + (f_011[i]+f_101[i]-f_010[i]-f_100[i])*C1) / h2;                              const double V1=((f_110[i]-f_010[i])*C5 + (f_101[i]-f_001[i])*C0 + (f_100[i]+f_111[i]-f_000[i]-f_011[i])*C1) / h0;
998                          o[INDEX3(i,0,0,numComp,3)] = V0;                              const double V2=((f_101[i]-f_001[i])*C5 + (f_110[i]-f_010[i])*C0 + (f_100[i]+f_111[i]-f_000[i]-f_011[i])*C1) / h0;
999                          o[INDEX3(i,1,0,numComp,3)] = V4;                              const double V3=((f_111[i]-f_011[i])*C5 + (f_100[i]-f_000[i])*C0 + (f_101[i]+f_110[i]-f_001[i]-f_010[i])*C1) / h0;
1000                          o[INDEX3(i,2,0,numComp,3)] = V8;                              const double V4=((f_010[i]-f_000[i])*C5 + (f_111[i]-f_101[i])*C0 + (f_011[i]+f_110[i]-f_001[i]-f_100[i])*C1) / h1;
1001                          o[INDEX3(i,0,1,numComp,3)] = V0;                              const double V5=((f_110[i]-f_100[i])*C5 + (f_011[i]-f_001[i])*C0 + (f_010[i]+f_111[i]-f_000[i]-f_101[i])*C1) / h1;
1002                          o[INDEX3(i,1,1,numComp,3)] = V5;                              const double V6=((f_011[i]-f_001[i])*C5 + (f_110[i]-f_100[i])*C0 + (f_010[i]+f_111[i]-f_000[i]-f_101[i])*C1) / h1;
1003                          o[INDEX3(i,2,1,numComp,3)] = V9;                              const double V7=((f_111[i]-f_101[i])*C5 + (f_010[i]-f_000[i])*C0 + (f_011[i]+f_110[i]-f_001[i]-f_100[i])*C1) / h1;
1004                          o[INDEX3(i,0,2,numComp,3)] = V1;                              const double V8=((f_001[i]-f_000[i])*C5 + (f_111[i]-f_110[i])*C0 + (f_011[i]+f_101[i]-f_010[i]-f_100[i])*C1) / h2;
1005                          o[INDEX3(i,1,2,numComp,3)] = V4;                              const double V9=((f_101[i]-f_100[i])*C5 + (f_011[i]-f_010[i])*C0 + (f_001[i]+f_111[i]-f_000[i]-f_110[i])*C1) / h2;
1006                          o[INDEX3(i,2,2,numComp,3)] = V10;                              const double V10=((f_011[i]-f_010[i])*C5 + (f_101[i]-f_100[i])*C0 + (f_001[i]+f_111[i]-f_000[i]-f_110[i])*C1) / h2;
1007                          o[INDEX3(i,0,3,numComp,3)] = V1;                              const double V11=((f_111[i]-f_110[i])*C5 + (f_001[i]-f_000[i])*C0 + (f_011[i]+f_101[i]-f_010[i]-f_100[i])*C1) / h2;
1008                          o[INDEX3(i,1,3,numComp,3)] = V5;                              o[INDEX3(i,0,0,numComp,3)] = V0;
1009                          o[INDEX3(i,2,3,numComp,3)] = V11;                              o[INDEX3(i,1,0,numComp,3)] = V4;
1010                          o[INDEX3(i,0,4,numComp,3)] = V2;                              o[INDEX3(i,2,0,numComp,3)] = V8;
1011                          o[INDEX3(i,1,4,numComp,3)] = V6;                              o[INDEX3(i,0,1,numComp,3)] = V0;
1012                          o[INDEX3(i,2,4,numComp,3)] = V8;                              o[INDEX3(i,1,1,numComp,3)] = V5;
1013                          o[INDEX3(i,0,5,numComp,3)] = V2;                              o[INDEX3(i,2,1,numComp,3)] = V9;
1014                          o[INDEX3(i,1,5,numComp,3)] = V7;                              o[INDEX3(i,0,2,numComp,3)] = V1;
1015                          o[INDEX3(i,2,5,numComp,3)] = V9;                              o[INDEX3(i,1,2,numComp,3)] = V4;
1016                          o[INDEX3(i,0,6,numComp,3)] = V3;                              o[INDEX3(i,2,2,numComp,3)] = V10;
1017                          o[INDEX3(i,1,6,numComp,3)] = V6;                              o[INDEX3(i,0,3,numComp,3)] = V1;
1018                          o[INDEX3(i,2,6,numComp,3)] = V10;                              o[INDEX3(i,1,3,numComp,3)] = V5;
1019                          o[INDEX3(i,0,7,numComp,3)] = V3;                              o[INDEX3(i,2,3,numComp,3)] = V11;
1020                          o[INDEX3(i,1,7,numComp,3)] = V7;                              o[INDEX3(i,0,4,numComp,3)] = V2;
1021                          o[INDEX3(i,2,7,numComp,3)] = V11;                              o[INDEX3(i,1,4,numComp,3)] = V6;
1022                      } // end of component loop i                              o[INDEX3(i,2,4,numComp,3)] = V8;
1023                  } // end of k0 loop                              o[INDEX3(i,0,5,numComp,3)] = V2;
1024              } // end of k1 loop                              o[INDEX3(i,1,5,numComp,3)] = V7;
1025          } // end of k2 loop                              o[INDEX3(i,2,5,numComp,3)] = V9;
1026                                o[INDEX3(i,0,6,numComp,3)] = V3;
1027                                o[INDEX3(i,1,6,numComp,3)] = V6;
1028                                o[INDEX3(i,2,6,numComp,3)] = V10;
1029                                o[INDEX3(i,0,7,numComp,3)] = V3;
1030                                o[INDEX3(i,1,7,numComp,3)] = V7;
1031                                o[INDEX3(i,2,7,numComp,3)] = V11;
1032                            } // end of component loop i
1033                        } // end of k0 loop
1034                    } // end of k1 loop
1035                } // end of k2 loop
1036            } // end of parallel section
1037      } else if (out.getFunctionSpace().getTypeCode() == ReducedElements) {      } else if (out.getFunctionSpace().getTypeCode() == ReducedElements) {
1038          out.requireWrite();          out.requireWrite();
1039  #pragma omp parallel for  #pragma omp parallel
1040          for (index_t k2=0; k2 < m_NE2; ++k2) {          {
1041              for (index_t k1=0; k1 < m_NE1; ++k1) {              vector<double> f_000(numComp);
1042                  for (index_t k0=0; k0 < m_NE0; ++k0) {              vector<double> f_001(numComp);
1043                      const double* f_000 = in.getSampleDataRO(INDEX3(k0,k1,k2, m_N0,m_N1));              vector<double> f_010(numComp);
1044                      const double* f_001 = in.getSampleDataRO(INDEX3(k0,k1,k2+1, m_N0,m_N1));              vector<double> f_011(numComp);
1045                      const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,k1,k2+1, m_N0,m_N1));              vector<double> f_100(numComp);
1046                      const double* f_011 = in.getSampleDataRO(INDEX3(k0,k1+1,k2+1, m_N0,m_N1));              vector<double> f_101(numComp);
1047                      const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,k1,k2, m_N0,m_N1));              vector<double> f_110(numComp);
1048                      const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,k1+1,k2, m_N0,m_N1));              vector<double> f_111(numComp);
1049                      const double* f_010 = in.getSampleDataRO(INDEX3(k0,k1+1,k2, m_N0,m_N1));  #pragma omp for
1050                      const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,k1+1,k2+1, m_N0,m_N1));              for (index_t k2=0; k2 < m_NE2; ++k2) {
1051                      double* o = out.getSampleDataRW(INDEX3(k0,k1,k2,m_NE0,m_NE1));                  for (index_t k1=0; k1 < m_NE1; ++k1) {
1052                      for (index_t i=0; i < numComp; ++i) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
1053                          o[INDEX3(i,0,0,numComp,3)] = (f_100[i]+f_101[i]+f_110[i]+f_111[i]-f_000[i]-f_001[i]-f_010[i]-f_011[i])*C3 / h0;                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
1054                          o[INDEX3(i,1,0,numComp,3)] = (f_010[i]+f_011[i]+f_110[i]+f_111[i]-f_000[i]-f_001[i]-f_100[i]-f_101[i])*C3 / h1;                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1055                          o[INDEX3(i,2,0,numComp,3)] = (f_001[i]+f_011[i]+f_101[i]+f_111[i]-f_000[i]-f_010[i]-f_100[i]-f_110[i])*C3 / h2;                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
1056                      } // end of component loop i                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1057                  } // end of k0 loop                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
1058              } // end of k1 loop                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1059          } // end of k2 loop                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
1060                            memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1061                            double* o = out.getSampleDataRW(INDEX3(k0,k1,k2,m_NE0,m_NE1));
1062                            for (index_t i=0; i < numComp; ++i) {
1063                                o[INDEX3(i,0,0,numComp,3)] = (f_100[i]+f_101[i]+f_110[i]+f_111[i]-f_000[i]-f_001[i]-f_010[i]-f_011[i])*C3 / h0;
1064                                o[INDEX3(i,1,0,numComp,3)] = (f_010[i]+f_011[i]+f_110[i]+f_111[i]-f_000[i]-f_001[i]-f_100[i]-f_101[i])*C3 / h1;
1065                                o[INDEX3(i,2,0,numComp,3)] = (f_001[i]+f_011[i]+f_101[i]+f_111[i]-f_000[i]-f_010[i]-f_100[i]-f_110[i])*C3 / h2;
1066                            } // end of component loop i
1067                        } // end of k0 loop
1068                    } // end of k1 loop
1069                } // end of k2 loop
1070            } // end of parallel section
1071      } else if (out.getFunctionSpace().getTypeCode() == FaceElements) {      } else if (out.getFunctionSpace().getTypeCode() == FaceElements) {
1072          out.requireWrite();          out.requireWrite();
1073  #pragma omp parallel  #pragma omp parallel
1074          {          {
1075                vector<double> f_000(numComp);
1076                vector<double> f_001(numComp);
1077                vector<double> f_010(numComp);
1078                vector<double> f_011(numComp);
1079                vector<double> f_100(numComp);
1080                vector<double> f_101(numComp);
1081                vector<double> f_110(numComp);
1082                vector<double> f_111(numComp);
1083              if (m_faceOffset[0] > -1) {              if (m_faceOffset[0] > -1) {
1084  #pragma omp for nowait  #pragma omp for nowait
1085                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
1086                      for (index_t k1=0; k1 < m_NE1; ++k1) {                      for (index_t k1=0; k1 < m_NE1; ++k1) {
1087                          const double* f_000 = in.getSampleDataRO(INDEX3(0,k1,k2, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(0,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
1088                          const double* f_001 = in.getSampleDataRO(INDEX3(0,k1,k2+1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(0,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1089                          const double* f_101 = in.getSampleDataRO(INDEX3(1,k1,k2+1, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(0,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
1090                          const double* f_111 = in.getSampleDataRO(INDEX3(1,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(0,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1091                          const double* f_110 = in.getSampleDataRO(INDEX3(1,k1+1,k2, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(1,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
1092                          const double* f_011 = in.getSampleDataRO(INDEX3(0,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(1,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1093                          const double* f_010 = in.getSampleDataRO(INDEX3(0,k1+1,k2, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(1,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
1094                          const double* f_100 = in.getSampleDataRO(INDEX3(1,k1,k2, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(1,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1095                          double* o = out.getSampleDataRW(m_faceOffset[0]+INDEX2(k1,k2,m_NE1));                          double* o = out.getSampleDataRW(m_faceOffset[0]+INDEX2(k1,k2,m_NE1));
1096                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1097                              const double V0=((f_010[i]-f_000[i])*C6 + (f_011[i]-f_001[i])*C2) / h1;                              const double V0=((f_010[i]-f_000[i])*C6 + (f_011[i]-f_001[i])*C2) / h1;
# Line 889  void Brick::assembleGradient(escript::Da Line 1118  void Brick::assembleGradient(escript::Da
1118  #pragma omp for nowait  #pragma omp for nowait
1119                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
1120                      for (index_t k1=0; k1 < m_NE1; ++k1) {                      for (index_t k1=0; k1 < m_NE1; ++k1) {
1121                          const double* f_000 = in.getSampleDataRO(INDEX3(m_N0-2,k1,k2, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(m_N0-2,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
1122                          const double* f_001 = in.getSampleDataRO(INDEX3(m_N0-2,k1,k2+1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(m_N0-2,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1123                          const double* f_101 = in.getSampleDataRO(INDEX3(m_N0-1,k1,k2+1, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(m_N0-2,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
1124                          const double* f_111 = in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(m_N0-2,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1125                          const double* f_110 = in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(m_N0-1,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
1126                          const double* f_011 = in.getSampleDataRO(INDEX3(m_N0-2,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(m_N0-1,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1127                          const double* f_010 = in.getSampleDataRO(INDEX3(m_N0-2,k1+1,k2, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
1128                          const double* f_100 = in.getSampleDataRO(INDEX3(m_N0-1,k1,k2, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1129                          double* o = out.getSampleDataRW(m_faceOffset[1]+INDEX2(k1,k2,m_NE1));                          double* o = out.getSampleDataRW(m_faceOffset[1]+INDEX2(k1,k2,m_NE1));
1130                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1131                              const double V0=((f_110[i]-f_100[i])*C6 + (f_111[i]-f_101[i])*C2) / h1;                              const double V0=((f_110[i]-f_100[i])*C6 + (f_111[i]-f_101[i])*C2) / h1;
# Line 923  void Brick::assembleGradient(escript::Da Line 1152  void Brick::assembleGradient(escript::Da
1152  #pragma omp for nowait  #pragma omp for nowait
1153                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
1154                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
1155                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,0,k2, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,0,k2, m_N0,m_N1)), numComp*sizeof(double));
1156                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,0,k2+1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,0,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1157                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,0,k2+1, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,1,k2, m_N0,m_N1)), numComp*sizeof(double));
1158                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,0,k2, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1159                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,1,k2+1, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,0,k2, m_N0,m_N1)), numComp*sizeof(double));
1160                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,1,k2, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,0,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1161                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,1,k2+1, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,1,k2, m_N0,m_N1)), numComp*sizeof(double));
1162                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,1,k2, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1163                          double* o = out.getSampleDataRW(m_faceOffset[2]+INDEX2(k0,k2,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[2]+INDEX2(k0,k2,m_NE0));
1164                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1165                              const double V0=((f_100[i]-f_000[i])*C6 + (f_101[i]-f_001[i])*C2) / h0;                              const double V0=((f_100[i]-f_000[i])*C6 + (f_101[i]-f_001[i])*C2) / h0;
# Line 956  void Brick::assembleGradient(escript::Da Line 1185  void Brick::assembleGradient(escript::Da
1185  #pragma omp for nowait  #pragma omp for nowait
1186                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
1187                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
1188                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,m_N1-1,k2+1, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,m_N1-2,k2, m_N0,m_N1)), numComp*sizeof(double));
1189                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,m_N1-2,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1190                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,m_N1-1,k2, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,m_N1-1,k2, m_N0,m_N1)), numComp*sizeof(double));
1191                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2+1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,m_N1-1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1192                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,m_N1-2,k2, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-2,k2, m_N0,m_N1)), numComp*sizeof(double));
1193                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,m_N1-2,k2+1, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-2,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1194                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,m_N1-2,k2+1, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2, m_N0,m_N1)), numComp*sizeof(double));
1195                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,m_N1-2,k2, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1196                          double* o = out.getSampleDataRW(m_faceOffset[3]+INDEX2(k0,k2,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[3]+INDEX2(k0,k2,m_NE0));
1197                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1198                              const double V0=((f_110[i]-f_010[i])*C6 + (f_111[i]-f_011[i])*C2) / h0;                              const double V0=((f_110[i]-f_010[i])*C6 + (f_111[i]-f_011[i])*C2) / h0;
# Line 990  void Brick::assembleGradient(escript::Da Line 1219  void Brick::assembleGradient(escript::Da
1219  #pragma omp for nowait  #pragma omp for nowait
1220                  for (index_t k1=0; k1 < m_NE1; ++k1) {                  for (index_t k1=0; k1 < m_NE1; ++k1) {
1221                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
1222                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,k1,0, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,k1,0, m_N0,m_N1)), numComp*sizeof(double));
1223                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,k1,0, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,k1,1, m_N0,m_N1)), numComp*sizeof(double));
1224                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,k1+1,0, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,k1+1,0, m_N0,m_N1)), numComp*sizeof(double));
1225                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,k1+1,0, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,k1+1,1, m_N0,m_N1)), numComp*sizeof(double));
1226                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,k1,1, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,k1,0, m_N0,m_N1)), numComp*sizeof(double));
1227                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,k1,1, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,k1,1, m_N0,m_N1)), numComp*sizeof(double));
1228                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,k1+1,1, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,0, m_N0,m_N1)), numComp*sizeof(double));
1229                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,k1+1,1, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,1, m_N0,m_N1)), numComp*sizeof(double));
1230                          double* o = out.getSampleDataRW(m_faceOffset[4]+INDEX2(k0,k1,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[4]+INDEX2(k0,k1,m_NE0));
1231                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1232                              const double V0=((f_100[i]-f_000[i])*C6 + (f_110[i]-f_010[i])*C2) / h0;                              const double V0=((f_100[i]-f_000[i])*C6 + (f_110[i]-f_010[i])*C2) / h0;
# Line 1024  void Brick::assembleGradient(escript::Da Line 1253  void Brick::assembleGradient(escript::Da
1253  #pragma omp for nowait  #pragma omp for nowait
1254                  for (index_t k1=0; k1 < m_NE1; ++k1) {                  for (index_t k1=0; k1 < m_NE1; ++k1) {
1255                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
1256                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,k1,m_N2-1, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,k1,m_N2-2, m_N0,m_N1)), numComp*sizeof(double));
1257                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,k1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
1258                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-1, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-2, m_N0,m_N1)), numComp*sizeof(double));
1259                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
1260                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,k1,m_N2-2, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-2, m_N0,m_N1)), numComp*sizeof(double));
1261                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-2, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
1262                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-2, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-2, m_N0,m_N1)), numComp*sizeof(double));
1263                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-2, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
1264                          double* o = out.getSampleDataRW(m_faceOffset[5]+INDEX2(k0,k1,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[5]+INDEX2(k0,k1,m_NE0));
1265                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1266                              const double V0=((f_101[i]-f_001[i])*C6 + (f_111[i]-f_011[i])*C2) / h0;                              const double V0=((f_101[i]-f_001[i])*C6 + (f_111[i]-f_011[i])*C2) / h0;
# Line 1059  void Brick::assembleGradient(escript::Da Line 1288  void Brick::assembleGradient(escript::Da
1288          out.requireWrite();          out.requireWrite();
1289  #pragma omp parallel  #pragma omp parallel
1290          {          {
1291                vector<double> f_000(numComp);
1292                vector<double> f_001(numComp);
1293                vector<double> f_010(numComp);
1294                vector<double> f_011(numComp);
1295                vector<double> f_100(numComp);
1296                vector<double> f_101(numComp);
1297                vector<double> f_110(numComp);
1298                vector<double> f_111(numComp);
1299              if (m_faceOffset[0] > -1) {              if (m_faceOffset[0] > -1) {
1300  #pragma omp for nowait  #pragma omp for nowait
1301                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
1302                      for (index_t k1=0; k1 < m_NE1; ++k1) {                      for (index_t k1=0; k1 < m_NE1; ++k1) {
1303                          const double* f_000 = in.getSampleDataRO(INDEX3(0,k1,k2, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(0,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
1304                          const double* f_001 = in.getSampleDataRO(INDEX3(0,k1,k2+1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(0,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1305                          const double* f_101 = in.getSampleDataRO(INDEX3(1,k1,k2+1, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(0,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
1306                          const double* f_011 = in.getSampleDataRO(INDEX3(0,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(0,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1307                          const double* f_100 = in.getSampleDataRO(INDEX3(1,k1,k2, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(1,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
1308                          const double* f_110 = in.getSampleDataRO(INDEX3(1,k1+1,k2, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(1,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1309                          const double* f_010 = in.getSampleDataRO(INDEX3(0,k1+1,k2, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(1,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
1310                          const double* f_111 = in.getSampleDataRO(INDEX3(1,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(1,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1311                          double* o = out.getSampleDataRW(m_faceOffset[0]+INDEX2(k1,k2,m_NE1));                          double* o = out.getSampleDataRW(m_faceOffset[0]+INDEX2(k1,k2,m_NE1));
1312                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1313                              o[INDEX3(i,0,0,numComp,3)] = (f_100[i]+f_101[i]+f_110[i]+f_111[i]-f_000[i]-f_001[i]-f_010[i]-f_011[i])*C3 / h0;                              o[INDEX3(i,0,0,numComp,3)] = (f_100[i]+f_101[i]+f_110[i]+f_111[i]-f_000[i]-f_001[i]-f_010[i]-f_011[i])*C3 / h0;
# Line 1084  void Brick::assembleGradient(escript::Da Line 1321  void Brick::assembleGradient(escript::Da
1321  #pragma omp for nowait  #pragma omp for nowait
1322                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
1323                      for (index_t k1=0; k1 < m_NE1; ++k1) {                      for (index_t k1=0; k1 < m_NE1; ++k1) {
1324                          const double* f_000 = in.getSampleDataRO(INDEX3(m_N0-2,k1,k2, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(m_N0-2,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
1325                          const double* f_001 = in.getSampleDataRO(INDEX3(m_N0-2,k1,k2+1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(m_N0-2,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1326                          const double* f_101 = in.getSampleDataRO(INDEX3(m_N0-1,k1,k2+1, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(m_N0-2,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
1327                          const double* f_011 = in.getSampleDataRO(INDEX3(m_N0-2,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(m_N0-2,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1328                          const double* f_100 = in.getSampleDataRO(INDEX3(m_N0-1,k1,k2, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(m_N0-1,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
1329                          const double* f_110 = in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(m_N0-1,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1330                          const double* f_010 = in.getSampleDataRO(INDEX3(m_N0-2,k1+1,k2, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
1331                          const double* f_111 = in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1332                          double* o = out.getSampleDataRW(m_faceOffset[1]+INDEX2(k1,k2,m_NE1));                          double* o = out.getSampleDataRW(m_faceOffset[1]+INDEX2(k1,k2,m_NE1));
1333                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1334                              o[INDEX3(i,0,0,numComp,3)] = (f_100[i]+f_101[i]+f_110[i]+f_111[i]-f_000[i]-f_001[i]-f_010[i]-f_011[i])*C3 / h0;                              o[INDEX3(i,0,0,numComp,3)] = (f_100[i]+f_101[i]+f_110[i]+f_111[i]-f_000[i]-f_001[i]-f_010[i]-f_011[i])*C3 / h0;
# Line 1105  void Brick::assembleGradient(escript::Da Line 1342  void Brick::assembleGradient(escript::Da
1342  #pragma omp for nowait  #pragma omp for nowait
1343                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
1344                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
1345                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,0,k2, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,0,k2, m_N0,m_N1)), numComp*sizeof(double));
1346                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,0,k2+1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,0,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1347                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,0,k2+1, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,1,k2, m_N0,m_N1)), numComp*sizeof(double));
1348                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,0,k2, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1349                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,1,k2+1, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,0,k2, m_N0,m_N1)), numComp*sizeof(double));
1350                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,1,k2, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,0,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1351                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,1,k2, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,1,k2, m_N0,m_N1)), numComp*sizeof(double));
1352                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,1,k2+1, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1353                          double* o = out.getSampleDataRW(m_faceOffset[2]+INDEX2(k0,k2,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[2]+INDEX2(k0,k2,m_NE0));
1354                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1355                              o[INDEX3(i,0,0,numComp,3)] = (f_100[i]+f_101[i]-f_000[i]-f_001[i])*C4 / h0;                              o[INDEX3(i,0,0,numComp,3)] = (f_100[i]+f_101[i]-f_000[i]-f_001[i])*C4 / h0;
# Line 1126  void Brick::assembleGradient(escript::Da Line 1363  void Brick::assembleGradient(escript::Da
1363  #pragma omp for nowait  #pragma omp for nowait
1364                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
1365                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
1366                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,m_N1-1,k2+1, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,m_N1-2,k2, m_N0,m_N1)), numComp*sizeof(double));
1367                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,m_N1-2,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1368                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,m_N1-1,k2, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,m_N1-1,k2, m_N0,m_N1)), numComp*sizeof(double));
1369                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2+1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,m_N1-1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1370                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,m_N1-2,k2, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-2,k2, m_N0,m_N1)), numComp*sizeof(double));
1371                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,m_N1-2,k2+1, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-2,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1372                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,m_N1-2,k2+1, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2, m_N0,m_N1)), numComp*sizeof(double));
1373                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,m_N1-2,k2, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
1374                          double* o = out.getSampleDataRW(m_faceOffset[3]+INDEX2(k0,k2,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[3]+INDEX2(k0,k2,m_NE0));
1375                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1376                              o[INDEX3(i,0,0,numComp,3)] = (f_110[i]+f_111[i]-f_010[i]-f_011[i])*C4 / h0;                              o[INDEX3(i,0,0,numComp,3)] = (f_110[i]+f_111[i]-f_010[i]-f_011[i])*C4 / h0;
# Line 1147  void Brick::assembleGradient(escript::Da Line 1384  void Brick::assembleGradient(escript::Da
1384  #pragma omp for nowait  #pragma omp for nowait
1385                  for (index_t k1=0; k1 < m_NE1; ++k1) {                  for (index_t k1=0; k1 < m_NE1; ++k1) {
1386                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
1387                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,k1,0, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,k1,0, m_N0,m_N1)), numComp*sizeof(double));
1388                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,k1,0, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,k1,1, m_N0,m_N1)), numComp*sizeof(double));
1389                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,k1+1,0, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,k1+1,0, m_N0,m_N1)), numComp*sizeof(double));
1390                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,k1+1,0, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,k1+1,1, m_N0,m_N1)), numComp*sizeof(double));
1391                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,k1,1, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,k1,0, m_N0,m_N1)), numComp*sizeof(double));
1392                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,k1,1, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,k1,1, m_N0,m_N1)), numComp*sizeof(double));
1393                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,k1+1,1, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,0, m_N0,m_N1)), numComp*sizeof(double));
1394                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,k1+1,1, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,1, m_N0,m_N1)), numComp*sizeof(double));
1395                          double* o = out.getSampleDataRW(m_faceOffset[4]+INDEX2(k0,k1,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[4]+INDEX2(k0,k1,m_NE0));
1396                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1397                              o[INDEX3(i,0,0,numComp,3)] = (f_100[i]+f_110[i]-f_000[i]-f_010[i])*C4 / h0;                              o[INDEX3(i,0,0,numComp,3)] = (f_100[i]+f_110[i]-f_000[i]-f_010[i])*C4 / h0;
# Line 1168  void Brick::assembleGradient(escript::Da Line 1405  void Brick::assembleGradient(escript::Da
1405  #pragma omp for nowait  #pragma omp for nowait
1406                  for (index_t k1=0; k1 < m_NE1; ++k1) {                  for (index_t k1=0; k1 < m_NE1; ++k1) {
1407                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
1408                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,k1,m_N2-1, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,k1,m_N2-2, m_N0,m_N1)), numComp*sizeof(double));
1409                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,k1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
1410                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-1, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-2, m_N0,m_N1)), numComp*sizeof(double));
1411                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
1412                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,k1,m_N2-2, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-2, m_N0,m_N1)), numComp*sizeof(double));
1413                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-2, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
1414                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-2, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-2, m_N0,m_N1)), numComp*sizeof(double));
1415                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-2, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
1416                          double* o = out.getSampleDataRW(m_faceOffset[5]+INDEX2(k0,k1,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[5]+INDEX2(k0,k1,m_NE0));
1417                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
1418                              o[INDEX3(i,0,0,numComp,3)] = (f_101[i]+f_111[i]-f_001[i]-f_011[i])*C4 / h0;                              o[INDEX3(i,0,0,numComp,3)] = (f_101[i]+f_111[i]-f_001[i]-f_011[i])*C4 / h0;
# Line 1199  void Brick::assembleIntegrate(vector<dou Line 1436  void Brick::assembleIntegrate(vector<dou
1436      const index_t left = (m_offset0==0 ? 0 : 1);      const index_t left = (m_offset0==0 ? 0 : 1);
1437      const index_t bottom = (m_offset1==0 ? 0 : 1);      const index_t bottom = (m_offset1==0 ? 0 : 1);
1438      const index_t front = (m_offset2==0 ? 0 : 1);      const index_t front = (m_offset2==0 ? 0 : 1);
1439      if (arg.getFunctionSpace().getTypeCode() == Elements) {      const int fs = arg.getFunctionSpace().getTypeCode();
1440        if (fs == Elements && arg.actsExpanded()) {
1441          const double w_0 = h0*h1*h2/8.;          const double w_0 = h0*h1*h2/8.;
1442  #pragma omp parallel  #pragma omp parallel
1443          {          {
# Line 1228  void Brick::assembleIntegrate(vector<dou Line 1466  void Brick::assembleIntegrate(vector<dou
1466              for (index_t i=0; i<numComp; i++)              for (index_t i=0; i<numComp; i++)
1467                  integrals[i]+=int_local[i];                  integrals[i]+=int_local[i];
1468          } // end of parallel section          } // end of parallel section
1469      } else if (arg.getFunctionSpace().getTypeCode() == ReducedElements) {  
1470        } else if (fs==ReducedElements || (fs==Elements && !arg.actsExpanded())) {
1471          const double w_0 = h0*h1*h2;          const double w_0 = h0*h1*h2;
1472  #pragma omp parallel  #pragma omp parallel
1473          {          {
# Line 1249  void Brick::assembleIntegrate(vector<dou Line 1488  void Brick::assembleIntegrate(vector<dou
1488              for (index_t i=0; i<numComp; i++)              for (index_t i=0; i<numComp; i++)
1489                  integrals[i]+=int_local[i];                  integrals[i]+=int_local[i];
1490          } // end of parallel section          } // end of parallel section
1491      } else if (arg.getFunctionSpace().getTypeCode() == FaceElements) {  
1492        } else if (fs == FaceElements && arg.actsExpanded()) {
1493          const double w_0 = h1*h2/4.;          const double w_0 = h1*h2/4.;
1494          const double w_1 = h0*h2/4.;          const double w_1 = h0*h2/4.;
1495          const double w_2 = h0*h1/4.;          const double w_2 = h0*h1/4.;
# Line 1357  void Brick::assembleIntegrate(vector<dou Line 1597  void Brick::assembleIntegrate(vector<dou
1597                  integrals[i]+=int_local[i];                  integrals[i]+=int_local[i];
1598          } // end of parallel section          } // end of parallel section
1599    
1600      } else if (arg.getFunctionSpace().getTypeCode() == ReducedFaceElements) {      } else if (fs==ReducedFaceElements || (fs==FaceElements && !arg.actsExpanded())) {
1601          const double w_0 = h1*h2;          const double w_0 = h1*h2;
1602          const double w_1 = h0*h2;          const double w_1 = h0*h2;
1603          const double w_2 = h0*h1;          const double w_2 = h0*h1;
# Line 1440  void Brick::assembleIntegrate(vector<dou Line 1680  void Brick::assembleIntegrate(vector<dou
1680              for (index_t i=0; i<numComp; i++)              for (index_t i=0; i<numComp; i++)
1681                  integrals[i]+=int_local[i];                  integrals[i]+=int_local[i];
1682          } // end of parallel section          } // end of parallel section
1683        } // function space selector
     }  
1684  }  }
1685    
1686  //protected  //protected
# Line 1521  void Brick::dofToNodes(escript::Data& ou Line 1760  void Brick::dofToNodes(escript::Data& ou
1760                  : &buffer[(m_dofMap[i]-numDOF)*numComp]);                  : &buffer[(m_dofMap[i]-numDOF)*numComp]);
1761          copy(src, src+numComp, out.getSampleDataRW(i));          copy(src, src+numComp, out.getSampleDataRW(i));
1762      }      }
1763        Paso_Coupler_free(coupler);
1764  }  }
1765    
1766  //private  //private
# Line 1763  void Brick::createPattern() Line 2003  void Brick::createPattern()
2003                          offsetInShared.push_back(offsetInShared.back()+nDOF0);                          offsetInShared.push_back(offsetInShared.back()+nDOF0);
2004                          const int firstDOF=(i1+1)/2*nDOF0*(nDOF1-1)                          const int firstDOF=(i1+1)/2*nDOF0*(nDOF1-1)
2005                                             +(i2+1)/2*nDOF0*nDOF1*(nDOF2-1);                                             +(i2+1)/2*nDOF0*nDOF1*(nDOF2-1);
2006                          const int firstNode=(i1+1)/2*m_N0*(m_N1-1)                          const int firstNode=left+(i1+1)/2*m_N0*(m_N1-1)
2007                                              +(i2+1)/2*m_N0*m_N1*(m_N2-1);                                              +(i2+1)/2*m_N0*m_N1*(m_N2-1);
2008                          for (dim_t i=0; i<nDOF0; i++, numShared++) {                          for (dim_t i=0; i<nDOF0; i++, numShared++) {
2009                              sendShared.push_back(firstDOF+i);                              sendShared.push_back(firstDOF+i);
# Line 1780  void Brick::createPattern() Line 2020  void Brick::createPattern()
2020                          offsetInShared.push_back(offsetInShared.back()+nDOF1);                          offsetInShared.push_back(offsetInShared.back()+nDOF1);
2021                          const int firstDOF=(i0+1)/2*(nDOF0-1)                          const int firstDOF=(i0+1)/2*(nDOF0-1)
2022                                             +(i2+1)/2*nDOF0*nDOF1*(nDOF2-1);                                             +(i2+1)/2*nDOF0*nDOF1*(nDOF2-1);
2023                          const int firstNode=(i0+1)/2*(m_N0-1)                          const int firstNode=bottom*m_N0
2024                                                +(i0+1)/2*(m_N0-1)
2025                                              +(i2+1)/2*m_N0*m_N1*(m_N2-1);                                              +(i2+1)/2*m_N0*m_N1*(m_N2-1);
2026                          for (dim_t i=0; i<nDOF1; i++, numShared++) {                          for (dim_t i=0; i<nDOF1; i++, numShared++) {
2027                              sendShared.push_back(firstDOF+i*nDOF0);                              sendShared.push_back(firstDOF+i*nDOF0);
# Line 1797  void Brick::createPattern() Line 2038  void Brick::createPattern()
2038                          offsetInShared.push_back(offsetInShared.back()+nDOF2);                          offsetInShared.push_back(offsetInShared.back()+nDOF2);
2039                          const int firstDOF=(i0+1)/2*(nDOF0-1)                          const int firstDOF=(i0+1)/2*(nDOF0-1)
2040                                             +(i1+1)/2*nDOF0*(nDOF1-1);                                             +(i1+1)/2*nDOF0*(nDOF1-1);
2041                          const int firstNode=(i0+1)/2*(m_N0-1)                          const int firstNode=front*m_N0*m_N1
2042                                                +(i0+1)/2*(m_N0-1)
2043                                              +(i1+1)/2*m_N0*(m_N1-1);                                              +(i1+1)/2*m_N0*(m_N1-1);
2044                          for (dim_t i=0; i<nDOF2; i++, numShared++) {                          for (dim_t i=0; i<nDOF2; i++, numShared++) {
2045                              sendShared.push_back(firstDOF+i*nDOF0*nDOF1);                              sendShared.push_back(firstDOF+i*nDOF0*nDOF1);
# Line 1956  void Brick::interpolateNodesOnElements(e Line 2198  void Brick::interpolateNodesOnElements(e
2198      if (reduced) {      if (reduced) {
2199          out.requireWrite();          out.requireWrite();
2200          const double c0 = .125;          const double c0 = .125;
2201  #pragma omp parallel for  #pragma omp parallel
2202          for (index_t k2=0; k2 < m_NE2; ++k2) {          {
2203              for (index_t k1=0; k1 < m_NE1; ++k1) {              vector<double> f_000(numComp);
2204                  for (index_t k0=0; k0 < m_NE0; ++k0) {              vector<double> f_001(numComp);
2205                      const double* f_000 = in.getSampleDataRO(INDEX3(k0,k1,k2, m_N0,m_N1));              vector<double> f_010(numComp);
2206                      const double* f_001 = in.getSampleDataRO(INDEX3(k0,k1,k2+1, m_N0,m_N1));              vector<double> f_011(numComp);
2207                      const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,k1,k2+1, m_N0,m_N1));              vector<double> f_100(numComp);
2208                      const double* f_011 = in.getSampleDataRO(INDEX3(k0,k1+1,k2+1, m_N0,m_N1));              vector<double> f_101(numComp);
2209                      const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,k1,k2, m_N0,m_N1));              vector<double> f_110(numComp);
2210                      const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,k1+1,k2, m_N0,m_N1));              vector<double> f_111(numComp);
2211                      const double* f_010 = in.getSampleDataRO(INDEX3(k0,k1+1,k2, m_N0,m_N1));  #pragma omp for
2212                      const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,k1+1,k2+1, m_N0,m_N1));              for (index_t k2=0; k2 < m_NE2; ++k2) {
2213                      double* o = out.getSampleDataRW(INDEX3(k0,k1,k2,m_NE0,m_NE1));                  for (index_t k1=0; k1 < m_NE1; ++k1) {
2214                      for (index_t i=0; i < numComp; ++i) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
2215                          o[INDEX2(i,numComp,0)] = c0*(f_000[i] + f_001[i] + f_010[i] + f_011[i] + f_100[i] + f_101[i] + f_110[i] + f_111[i]);                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
2216                      } // end of component loop i                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2217                  } // end of k0 loop                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
2218              } // end of k1 loop                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2219          } // end of k2 loop                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
2220                            memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2221                            memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
2222                            memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2223                            double* o = out.getSampleDataRW(INDEX3(k0,k1,k2,m_NE0,m_NE1));
2224                            for (index_t i=0; i < numComp; ++i) {
2225                                o[INDEX2(i,numComp,0)] = c0*(f_000[i] + f_001[i] + f_010[i] + f_011[i] + f_100[i] + f_101[i] + f_110[i] + f_111[i]);
2226                            } // end of component loop i
2227                        } // end of k0 loop
2228                    } // end of k1 loop
2229                } // end of k2 loop
2230            } // end of parallel section
2231      } else {      } else {
2232          out.requireWrite();          out.requireWrite();
2233          const double c0 = .0094373878376559314545;          const double c0 = .0094373878376559314545;
2234          const double c1 = .035220810900864519624;          const double c1 = .035220810900864519624;
2235          const double c2 = .13144585576580214704;          const double c2 = .13144585576580214704;
2236          const double c3 = .49056261216234406855;          const double c3 = .49056261216234406855;
2237  #pragma omp parallel for  #pragma omp parallel
2238          for (index_t k2=0; k2 < m_NE2; ++k2) {          {
2239              for (index_t k1=0; k1 < m_NE1; ++k1) {              vector<double> f_000(numComp);
2240                  for (index_t k0=0; k0 < m_NE0; ++k0) {              vector<double> f_001(numComp);
2241                      const double* f_000 = in.getSampleDataRO(INDEX3(k0,k1,k2, m_N0,m_N1));              vector<double> f_010(numComp);
2242                      const double* f_001 = in.getSampleDataRO(INDEX3(k0,k1,k2+1, m_N0,m_N1));              vector<double> f_011(numComp);
2243                      const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,k1,k2+1, m_N0,m_N1));              vector<double> f_100(numComp);
2244                      const double* f_011 = in.getSampleDataRO(INDEX3(k0,k1+1,k2+1, m_N0,m_N1));              vector<double> f_101(numComp);
2245                      const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,k1+1,k2, m_N0,m_N1));              vector<double> f_110(numComp);
2246                      const double* f_010 = in.getSampleDataRO(INDEX3(k0,k1+1,k2, m_N0,m_N1));              vector<double> f_111(numComp);
2247                      const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,k1,k2, m_N0,m_N1));  #pragma omp for
2248                      const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,k1+1,k2+1, m_N0,m_N1));              for (index_t k2=0; k2 < m_NE2; ++k2) {
2249                      double* o = out.getSampleDataRW(INDEX3(k0,k1,k2,m_NE0,m_NE1));                  for (index_t k1=0; k1 < m_NE1; ++k1) {
2250                      for (index_t i=0; i < numComp; ++i) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
2251                          o[INDEX2(i,numComp,0)] = f_000[i]*c3 + f_111[i]*c0 + c2*(f_001[i] + f_010[i] + f_100[i]) + c1*(f_011[i] + f_101[i] + f_110[i]);                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
2252                          o[INDEX2(i,numComp,1)] = f_011[i]*c0 + f_100[i]*c3 + c2*(f_000[i] + f_101[i] + f_110[i]) + c1*(f_001[i] + f_010[i] + f_111[i]);                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2253                          o[INDEX2(i,numComp,2)] = f_010[i]*c3 + f_101[i]*c0 + c2*(f_000[i] + f_011[i] + f_110[i]) + c1*(f_001[i] + f_100[i] + f_111[i]);                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
2254                          o[INDEX2(i,numComp,3)] = f_001[i]*c0 + f_110[i]*c3 + c2*(f_010[i] + f_100[i] + f_111[i]) + c1*(f_000[i] + f_011[i] + f_101[i]);                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2255                          o[INDEX2(i,numComp,4)] = f_001[i]*c3 + f_110[i]*c0 + c2*(f_000[i] + f_011[i] + f_101[i]) + c1*(f_010[i] + f_100[i] + f_111[i]);                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
2256                          o[INDEX2(i,numComp,5)] = f_010[i]*c0 + f_101[i]*c3 + c2*(f_001[i] + f_100[i] + f_111[i]) + c1*(f_000[i] + f_011[i] + f_110[i]);                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2257                          o[INDEX2(i,numComp,6)] = f_011[i]*c3 + f_100[i]*c0 + c2*(f_001[i] + f_010[i] + f_111[i]) + c1*(f_000[i] + f_101[i] + f_110[i]);                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
2258                          o[INDEX2(i,numComp,7)] = f_000[i]*c0 + f_111[i]*c3 + c2*(f_011[i] + f_101[i] + f_110[i]) + c1*(f_001[i] + f_010[i] + f_100[i]);                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2259                      } // end of component loop i                          double* o = out.getSampleDataRW(INDEX3(k0,k1,k2,m_NE0,m_NE1));
2260                  } // end of k0 loop                          for (index_t i=0; i < numComp; ++i) {
2261              } // end of k1 loop                              o[INDEX2(i,numComp,0)] = f_000[i]*c3 + f_111[i]*c0 + c2*(f_001[i] + f_010[i] + f_100[i]) + c1*(f_011[i] + f_101[i] + f_110[i]);
2262          } // end of k2 loop                              o[INDEX2(i,numComp,1)] = f_011[i]*c0 + f_100[i]*c3 + c2*(f_000[i] + f_101[i] + f_110[i]) + c1*(f_001[i] + f_010[i] + f_111[i]);
2263                                o[INDEX2(i,numComp,2)] = f_010[i]*c3 + f_101[i]*c0 + c2*(f_000[i] + f_011[i] + f_110[i]) + c1*(f_001[i] + f_100[i] + f_111[i]);
2264                                o[INDEX2(i,numComp,3)] = f_001[i]*c0 + f_110[i]*c3 + c2*(f_010[i] + f_100[i] + f_111[i]) + c1*(f_000[i] + f_011[i] + f_101[i]);
2265                                o[INDEX2(i,numComp,4)] = f_001[i]*c3 + f_110[i]*c0 + c2*(f_000[i] + f_011[i] + f_101[i]) + c1*(f_010[i] + f_100[i] + f_111[i]);
2266                                o[INDEX2(i,numComp,5)] = f_010[i]*c0 + f_101[i]*c3 + c2*(f_001[i] + f_100[i] + f_111[i]) + c1*(f_000[i] + f_011[i] + f_110[i]);
2267                                o[INDEX2(i,numComp,6)] = f_011[i]*c3 + f_100[i]*c0 + c2*(f_001[i] + f_010[i] + f_111[i]) + c1*(f_000[i] + f_101[i] + f_110[i]);
2268                                o[INDEX2(i,numComp,7)] = f_000[i]*c0 + f_111[i]*c3 + c2*(f_011[i] + f_101[i] + f_110[i]) + c1*(f_001[i] + f_010[i] + f_100[i]);
2269                            } // end of component loop i
2270                        } // end of k0 loop
2271                    } // end of k1 loop
2272                } // end of k2 loop
2273            } // end of parallel section
2274      }      }
2275  }  }
2276    
# Line 2020  void Brick::interpolateNodesOnFaces(escr Line 2284  void Brick::interpolateNodesOnFaces(escr
2284          const double c0 = .25;          const double c0 = .25;
2285  #pragma omp parallel  #pragma omp parallel
2286          {          {
2287                vector<double> f_000(numComp);
2288                vector<double> f_001(numComp);
2289                vector<double> f_010(numComp);
2290                vector<double> f_011(numComp);
2291                vector<double> f_100(numComp);
2292                vector<double> f_101(numComp);
2293                vector<double> f_110(numComp);
2294                vector<double> f_111(numComp);
2295              if (m_faceOffset[0] > -1) {              if (m_faceOffset[0] > -1) {
2296  #pragma omp for nowait  #pragma omp for nowait
2297                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
2298                      for (index_t k1=0; k1 < m_NE1; ++k1) {                      for (index_t k1=0; k1 < m_NE1; ++k1) {
2299                          const double* f_011 = in.getSampleDataRO(INDEX3(0,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(0,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
2300                          const double* f_010 = in.getSampleDataRO(INDEX3(0,k1+1,k2, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(0,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2301                          const double* f_001 = in.getSampleDataRO(INDEX3(0,k1,k2+1, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(0,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
2302                          const double* f_000 = in.getSampleDataRO(INDEX3(0,k1,k2, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(0,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2303                          double* o = out.getSampleDataRW(m_faceOffset[0]+INDEX2(k1,k2,m_NE1));                          double* o = out.getSampleDataRW(m_faceOffset[0]+INDEX2(k1,k2,m_NE1));
2304                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2305                              o[INDEX2(i,numComp,0)] = c0*(f_000[i] + f_001[i] + f_010[i] + f_011[i]);                              o[INDEX2(i,numComp,0)] = c0*(f_000[i] + f_001[i] + f_010[i] + f_011[i]);
# Line 2039  void Brick::interpolateNodesOnFaces(escr Line 2311  void Brick::interpolateNodesOnFaces(escr
2311  #pragma omp for nowait  #pragma omp for nowait
2312                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
2313                      for (index_t k1=0; k1 < m_NE1; ++k1) {                      for (index_t k1=0; k1 < m_NE1; ++k1) {
2314                          const double* f_110 = in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(m_N0-1,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
2315                          const double* f_100 = in.getSampleDataRO(INDEX3(m_N0-1,k1,k2, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(m_N0-1,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2316                          const double* f_101 = in.getSampleDataRO(INDEX3(m_N0-1,k1,k2+1, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
2317                          const double* f_111 = in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2318                          double* o = out.getSampleDataRW(m_faceOffset[1]+INDEX2(k1,k2,m_NE1));                          double* o = out.getSampleDataRW(m_faceOffset[1]+INDEX2(k1,k2,m_NE1));
2319                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2320                              o[INDEX2(i,numComp,0)] = c0*(f_100[i] + f_101[i] + f_110[i] + f_111[i]);                              o[INDEX2(i,numComp,0)] = c0*(f_100[i] + f_101[i] + f_110[i] + f_111[i]);
# Line 2054  void Brick::interpolateNodesOnFaces(escr Line 2326  void Brick::interpolateNodesOnFaces(escr
2326  #pragma omp for nowait  #pragma omp for nowait
2327                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
2328                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
2329                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,0,k2, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,0,k2, m_N0,m_N1)), numComp*sizeof(double));
2330                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,0,k2+1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,0,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2331                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,0,k2+1, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,0,k2, m_N0,m_N1)), numComp*sizeof(double));
2332                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,0,k2, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,0,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2333                          double* o = out.getSampleDataRW(m_faceOffset[2]+INDEX2(k0,k2,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[2]+INDEX2(k0,k2,m_NE0));
2334                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2335                              o[INDEX2(i,numComp,0)] = c0*(f_000[i] + f_001[i] + f_100[i] + f_101[i]);                              o[INDEX2(i,numComp,0)] = c0*(f_000[i] + f_001[i] + f_100[i] + f_101[i]);
# Line 2069  void Brick::interpolateNodesOnFaces(escr Line 2341  void Brick::interpolateNodesOnFaces(escr
2341  #pragma omp for nowait  #pragma omp for nowait
2342                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
2343                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
2344                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,m_N1-1,k2, m_N0,m_N1)), numComp*sizeof(double));
2345                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,m_N1-1,k2+1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,m_N1-1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2346                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,m_N1-1,k2, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2, m_N0,m_N1)), numComp*sizeof(double));
2347                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2+1, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2348                          double* o = out.getSampleDataRW(m_faceOffset[3]+INDEX2(k0,k2,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[3]+INDEX2(k0,k2,m_NE0));
2349                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2350                              o[INDEX2(i,numComp,0)] = c0*(f_010[i] + f_011[i] + f_110[i] + f_111[i]);                              o[INDEX2(i,numComp,0)] = c0*(f_010[i] + f_011[i] + f_110[i] + f_111[i]);
# Line 2084  void Brick::interpolateNodesOnFaces(escr Line 2356  void Brick::interpolateNodesOnFaces(escr
2356  #pragma omp for nowait  #pragma omp for nowait
2357                  for (index_t k1=0; k1 < m_NE1; ++k1) {                  for (index_t k1=0; k1 < m_NE1; ++k1) {
2358                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
2359                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,k1+1,0, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,k1,0, m_N0,m_N1)), numComp*sizeof(double));
2360                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,k1+1,0, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,k1+1,0, m_N0,m_N1)), numComp*sizeof(double));
2361                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,k1,0, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,k1,0, m_N0,m_N1)), numComp*sizeof(double));
2362                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,k1,0, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,0, m_N0,m_N1)), numComp*sizeof(double));
2363                          double* o = out.getSampleDataRW(m_faceOffset[4]+INDEX2(k0,k1,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[4]+INDEX2(k0,k1,m_NE0));
2364                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2365                              o[INDEX2(i,numComp,0)] = c0*(f_000[i] + f_010[i] + f_100[i] + f_110[i]);                              o[INDEX2(i,numComp,0)] = c0*(f_000[i] + f_010[i] + f_100[i] + f_110[i]);
# Line 2099  void Brick::interpolateNodesOnFaces(escr Line 2371  void Brick::interpolateNodesOnFaces(escr
2371  #pragma omp for nowait  #pragma omp for nowait
2372                  for (index_t k1=0; k1 < m_NE1; ++k1) {                  for (index_t k1=0; k1 < m_NE1; ++k1) {
2373                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
2374                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,k1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
2375                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,k1,m_N2-1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
2376                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-1, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
2377                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-1, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
2378                          double* o = out.getSampleDataRW(m_faceOffset[5]+INDEX2(k0,k1,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[5]+INDEX2(k0,k1,m_NE0));
2379                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2380                              o[INDEX2(i,numComp,0)] = c0*(f_001[i] + f_011[i] + f_101[i] + f_111[i]);                              o[INDEX2(i,numComp,0)] = c0*(f_001[i] + f_011[i] + f_101[i] + f_111[i]);
# Line 2118  void Brick::interpolateNodesOnFaces(escr Line 2390  void Brick::interpolateNodesOnFaces(escr
2390          const double c2 = 0.62200846792814621559;          const double c2 = 0.62200846792814621559;
2391  #pragma omp parallel  #pragma omp parallel
2392          {          {
2393                vector<double> f_000(numComp);
2394                vector<double> f_001(numComp);
2395                vector<double> f_010(numComp);
2396                vector<double> f_011(numComp);
2397                vector<double> f_100(numComp);
2398                vector<double> f_101(numComp);
2399                vector<double> f_110(numComp);
2400                vector<double> f_111(numComp);
2401              if (m_faceOffset[0] > -1) {              if (m_faceOffset[0] > -1) {
2402  #pragma omp for nowait  #pragma omp for nowait
2403                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
2404                      for (index_t k1=0; k1 < m_NE1; ++k1) {                      for (index_t k1=0; k1 < m_NE1; ++k1) {
2405                          const double* f_000 = in.getSampleDataRO(INDEX3(0,k1,k2, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(0,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
2406                          const double* f_001 = in.getSampleDataRO(INDEX3(0,k1,k2+1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(0,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2407                          const double* f_011 = in.getSampleDataRO(INDEX3(0,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(0,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
2408                          const double* f_010 = in.getSampleDataRO(INDEX3(0,k1+1,k2, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(0,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2409                          double* o = out.getSampleDataRW(m_faceOffset[0]+INDEX2(k1,k2,m_NE1));                          double* o = out.getSampleDataRW(m_faceOffset[0]+INDEX2(k1,k2,m_NE1));
2410                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2411                              o[INDEX2(i,numComp,0)] = f_000[i]*c2 + f_011[i]*c0 + c1*(f_001[i] + f_010[i]);                              o[INDEX2(i,numComp,0)] = f_000[i]*c2 + f_011[i]*c0 + c1*(f_001[i] + f_010[i]);
# Line 2140  void Brick::interpolateNodesOnFaces(escr Line 2420  void Brick::interpolateNodesOnFaces(escr
2420  #pragma omp for nowait  #pragma omp for nowait
2421                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
2422                      for (index_t k1=0; k1 < m_NE1; ++k1) {                      for (index_t k1=0; k1 < m_NE1; ++k1) {
2423                          const double* f_101 = in.getSampleDataRO(INDEX3(m_N0-1,k1,k2+1, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(m_N0-1,k1,k2, m_N0,m_N1)), numComp*sizeof(double));
2424                          const double* f_100 = in.getSampleDataRO(INDEX3(m_N0-1,k1,k2, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(m_N0-1,k1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2425                          const double* f_110 = in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2, m_N0,m_N1)), numComp*sizeof(double));
2426                          const double* f_111 = in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2+1, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(m_N0-1,k1+1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2427                          double* o = out.getSampleDataRW(m_faceOffset[1]+INDEX2(k1,k2,m_NE1));                          double* o = out.getSampleDataRW(m_faceOffset[1]+INDEX2(k1,k2,m_NE1));
2428                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2429                              o[INDEX2(i,numComp,0)] = f_100[i]*c2 + f_111[i]*c0 + c1*(f_101[i] + f_110[i]);                              o[INDEX2(i,numComp,0)] = f_100[i]*c2 + f_111[i]*c0 + c1*(f_101[i] + f_110[i]);
# Line 2158  void Brick::interpolateNodesOnFaces(escr Line 2438  void Brick::interpolateNodesOnFaces(escr
2438  #pragma omp for nowait  #pragma omp for nowait
2439                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
2440                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
2441                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,0,k2, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,0,k2, m_N0,m_N1)), numComp*sizeof(double));
2442                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,0,k2+1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,0,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2443                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,0,k2+1, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,0,k2, m_N0,m_N1)), numComp*sizeof(double));
2444                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,0,k2, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,0,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2445                          double* o = out.getSampleDataRW(m_faceOffset[2]+INDEX2(k0,k2,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[2]+INDEX2(k0,k2,m_NE0));
2446                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2447                              o[INDEX2(i,numComp,0)] = f_000[i]*c2 + f_101[i]*c0 + c1*(f_001[i] + f_100[i]);                              o[INDEX2(i,numComp,0)] = f_000[i]*c2 + f_101[i]*c0 + c1*(f_001[i] + f_100[i]);
# Line 2176  void Brick::interpolateNodesOnFaces(escr Line 2456  void Brick::interpolateNodesOnFaces(escr
2456  #pragma omp for nowait  #pragma omp for nowait
2457                  for (index_t k2=0; k2 < m_NE2; ++k2) {                  for (index_t k2=0; k2 < m_NE2; ++k2) {
2458                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
2459                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,m_N1-1,k2, m_N0,m_N1)), numComp*sizeof(double));
2460                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,m_N1-1,k2+1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,m_N1-1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2461                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,m_N1-1,k2, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2, m_N0,m_N1)), numComp*sizeof(double));
2462                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2+1, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,m_N1-1,k2+1, m_N0,m_N1)), numComp*sizeof(double));
2463                          double* o = out.getSampleDataRW(m_faceOffset[3]+INDEX2(k0,k2,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[3]+INDEX2(k0,k2,m_NE0));
2464                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2465                              o[INDEX2(i,numComp,0)] = f_010[i]*c2 + f_111[i]*c0 + c1*(f_011[i] + f_110[i]);                              o[INDEX2(i,numComp,0)] = f_010[i]*c2 + f_111[i]*c0 + c1*(f_011[i] + f_110[i]);
# Line 2194  void Brick::interpolateNodesOnFaces(escr Line 2474  void Brick::interpolateNodesOnFaces(escr
2474  #pragma omp for nowait  #pragma omp for nowait
2475                  for (index_t k1=0; k1 < m_NE1; ++k1) {                  for (index_t k1=0; k1 < m_NE1; ++k1) {
2476                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
2477                          const double* f_000 = in.getSampleDataRO(INDEX3(k0,k1,0, m_N0,m_N1));                          memcpy(&f_000[0], in.getSampleDataRO(INDEX3(k0,k1,0, m_N0,m_N1)), numComp*sizeof(double));
2478                          const double* f_100 = in.getSampleDataRO(INDEX3(k0+1,k1,0, m_N0,m_N1));                          memcpy(&f_010[0], in.getSampleDataRO(INDEX3(k0,k1+1,0, m_N0,m_N1)), numComp*sizeof(double));
2479                          const double* f_110 = in.getSampleDataRO(INDEX3(k0+1,k1+1,0, m_N0,m_N1));                          memcpy(&f_100[0], in.getSampleDataRO(INDEX3(k0+1,k1,0, m_N0,m_N1)), numComp*sizeof(double));
2480                          const double* f_010 = in.getSampleDataRO(INDEX3(k0,k1+1,0, m_N0,m_N1));                          memcpy(&f_110[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,0, m_N0,m_N1)), numComp*sizeof(double));
2481                          double* o = out.getSampleDataRW(m_faceOffset[4]+INDEX2(k0,k1,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[4]+INDEX2(k0,k1,m_NE0));
2482                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2483                              o[INDEX2(i,numComp,0)] = f_000[i]*c2 + f_110[i]*c0 + c1*(f_010[i] + f_100[i]);                              o[INDEX2(i,numComp,0)] = f_000[i]*c2 + f_110[i]*c0 + c1*(f_010[i] + f_100[i]);
# Line 2212  void Brick::interpolateNodesOnFaces(escr Line 2492  void Brick::interpolateNodesOnFaces(escr
2492  #pragma omp for nowait  #pragma omp for nowait
2493                  for (index_t k1=0; k1 < m_NE1; ++k1) {                  for (index_t k1=0; k1 < m_NE1; ++k1) {
2494                      for (index_t k0=0; k0 < m_NE0; ++k0) {                      for (index_t k0=0; k0 < m_NE0; ++k0) {
2495                          const double* f_001 = in.getSampleDataRO(INDEX3(k0,k1,m_N2-1, m_N0,m_N1));                          memcpy(&f_001[0], in.getSampleDataRO(INDEX3(k0,k1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
2496                          const double* f_101 = in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-1, m_N0,m_N1));                          memcpy(&f_011[0], in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
2497                          const double* f_011 = in.getSampleDataRO(INDEX3(k0,k1+1,m_N2-1, m_N0,m_N1));                          memcpy(&f_101[0], in.getSampleDataRO(INDEX3(k0+1,k1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
2498                          const double* f_111 = in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-1, m_N0,m_N1));                          memcpy(&f_111[0], in.getSampleDataRO(INDEX3(k0+1,k1+1,m_N2-1, m_N0,m_N1)), numComp*sizeof(double));
2499                          double* o = out.getSampleDataRW(m_faceOffset[5]+INDEX2(k0,k1,m_NE0));                          double* o = out.getSampleDataRW(m_faceOffset[5]+INDEX2(k0,k1,m_NE0));
2500                          for (index_t i=0; i < numComp; ++i) {                          for (index_t i=0; i < numComp; ++i) {
2501                              o[INDEX2(i,numComp,0)] = f_001[i]*c2 + f_111[i]*c0 + c1*(f_011[i] + f_101[i]);                              o[INDEX2(i,numComp,0)] = f_001[i]*c2 + f_111[i]*c0 + c1*(f_011[i] + f_101[i]);
# Line 9438  void Brick::assemblePDEBoundarySingle(Pa Line 9718  void Brick::assemblePDEBoundarySingle(Pa
9718      {      {
9719          if (m_faceOffset[0] > -1) {          if (m_faceOffset[0] > -1) {
9720              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
9721  #pragma omp for nowait  #pragma omp for
9722                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
9723                      for (index_t k1=0; k1<m_NE1; ++k1) {                      for (index_t k1=0; k1<m_NE1; ++k1) {
9724                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 9562  void Brick::assemblePDEBoundarySingle(Pa Line 9842  void Brick::assemblePDEBoundarySingle(Pa
9842    
9843          if (m_faceOffset[1] > -1) {          if (m_faceOffset[1] > -1) {
9844              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
9845  #pragma omp for nowait  #pragma omp for
9846                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
9847                      for (index_t k1=0; k1<m_NE1; ++k1) {                      for (index_t k1=0; k1<m_NE1; ++k1) {
9848                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 9686  void Brick::assemblePDEBoundarySingle(Pa Line 9966  void Brick::assemblePDEBoundarySingle(Pa
9966    
9967          if (m_faceOffset[2] > -1) {          if (m_faceOffset[2] > -1) {
9968              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
9969  #pragma omp for nowait  #pragma omp for
9970                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
9971                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
9972                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 9810  void Brick::assemblePDEBoundarySingle(Pa Line 10090  void Brick::assemblePDEBoundarySingle(Pa
10090    
10091          if (m_faceOffset[3] > -1) {          if (m_faceOffset[3] > -1) {
10092              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
10093  #pragma omp for nowait  #pragma omp for
10094                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
10095                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
10096                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 9934  void Brick::assemblePDEBoundarySingle(Pa Line 10214  void Brick::assemblePDEBoundarySingle(Pa
10214    
10215          if (m_faceOffset[4] > -1) {          if (m_faceOffset[4] > -1) {
10216              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring
10217  #pragma omp for nowait  #pragma omp for
10218                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {
10219                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
10220                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 10058  void Brick::assemblePDEBoundarySingle(Pa Line 10338  void Brick::assemblePDEBoundarySingle(Pa
10338    
10339          if (m_faceOffset[5] > -1) {          if (m_faceOffset[5] > -1) {
10340              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring
10341  #pragma omp for nowait  #pragma omp for
10342                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {
10343                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
10344                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 10202  void Brick::assemblePDEBoundarySingleRed Line 10482  void Brick::assemblePDEBoundarySingleRed
10482      {      {
10483          if (m_faceOffset[0] > -1) {          if (m_faceOffset[0] > -1) {
10484              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
10485  #pragma omp for nowait  #pragma omp for
10486                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
10487                      for (index_t k1=0; k1<m_NE1; ++k1) {                      for (index_t k1=0; k1<m_NE1; ++k1) {
10488                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 10254  void Brick::assemblePDEBoundarySingleRed Line 10534  void Brick::assemblePDEBoundarySingleRed
10534    
10535          if (m_faceOffset[1] > -1) {          if (m_faceOffset[1] > -1) {
10536              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
10537  #pragma omp for nowait  #pragma omp for
10538                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
10539                      for (index_t k1=0; k1<m_NE1; ++k1) {                      for (index_t k1=0; k1<m_NE1; ++k1) {
10540                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 10306  void Brick::assemblePDEBoundarySingleRed Line 10586  void Brick::assemblePDEBoundarySingleRed
10586    
10587          if (m_faceOffset[2] > -1) {          if (m_faceOffset[2] > -1) {
10588              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
10589  #pragma omp for nowait  #pragma omp for
10590                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
10591                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
10592                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 10357  void Brick::assemblePDEBoundarySingleRed Line 10637  void Brick::assemblePDEBoundarySingleRed
10637    
10638          if (m_faceOffset[3] > -1) {          if (m_faceOffset[3] > -1) {
10639              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
10640  #pragma omp for nowait  #pragma omp for
10641                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
10642                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
10643                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 10409  void Brick::assemblePDEBoundarySingleRed Line 10689  void Brick::assemblePDEBoundarySingleRed
10689    
10690          if (m_faceOffset[4] > -1) {          if (m_faceOffset[4] > -1) {
10691              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring
10692  #pragma omp for nowait  #pragma omp for
10693                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {
10694                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
10695                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 10461  void Brick::assemblePDEBoundarySingleRed Line 10741  void Brick::assemblePDEBoundarySingleRed
10741    
10742          if (m_faceOffset[5] > -1) {          if (m_faceOffset[5] > -1) {
10743              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring
10744  #pragma omp for nowait  #pragma omp for
10745                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {
10746                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
10747                          vector<double> EM_S(8*8, 0);                          vector<double> EM_S(8*8, 0);
# Line 10570  void Brick::assemblePDEBoundarySystem(Pa Line 10850  void Brick::assemblePDEBoundarySystem(Pa
10850      {      {
10851          if (m_faceOffset[0] > -1) {          if (m_faceOffset[0] > -1) {
10852              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
10853  #pragma omp for nowait  #pragma omp for
10854                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
10855                      for (index_t k1=0; k1<m_NE1; ++k1) {                      for (index_t k1=0; k1<m_NE1; ++k1) {
10856                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);
# Line 10708  void Brick::assemblePDEBoundarySystem(Pa Line 10988  void Brick::assemblePDEBoundarySystem(Pa
10988    
10989          if (m_faceOffset[1] > -1) {          if (m_faceOffset[1] > -1) {
10990              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
10991  #pragma omp for nowait  #pragma omp for
10992                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
10993                      for (index_t k1=0; k1<m_NE1; ++k1) {                      for (index_t k1=0; k1<m_NE1; ++k1) {
10994                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);
# Line 10846  void Brick::assemblePDEBoundarySystem(Pa Line 11126  void Brick::assemblePDEBoundarySystem(Pa
11126    
11127          if (m_faceOffset[2] > -1) {          if (m_faceOffset[2] > -1) {
11128              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
11129  #pragma omp for nowait  #pragma omp for
11130                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
11131                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
11132                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);
# Line 10984  void Brick::assemblePDEBoundarySystem(Pa Line 11264  void Brick::assemblePDEBoundarySystem(Pa
11264    
11265          if (m_faceOffset[3] > -1) {          if (m_faceOffset[3] > -1) {
11266              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
11267  #pragma omp for nowait  #pragma omp for
11268                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
11269                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
11270                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);
# Line 11122  void Brick::assemblePDEBoundarySystem(Pa Line 11402  void Brick::assemblePDEBoundarySystem(Pa
11402    
11403          if (m_faceOffset[4] > -1) {          if (m_faceOffset[4] > -1) {
11404              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring
11405  #pragma omp for nowait  #pragma omp for
11406                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {
11407                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
11408                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);
# Line 11260  void Brick::assemblePDEBoundarySystem(Pa Line 11540  void Brick::assemblePDEBoundarySystem(Pa
11540    
11541          if (m_faceOffset[5] > -1) {          if (m_faceOffset[5] > -1) {
11542              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring
11543  #pragma omp for nowait  #pragma omp for
11544                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {
11545                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
11546                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);
# Line 11425  void Brick::assemblePDEBoundarySystemRed Line 11705  void Brick::assemblePDEBoundarySystemRed
11705      {      {
11706          if (m_faceOffset[0] > -1) {          if (m_faceOffset[0] > -1) {
11707              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
11708  #pragma omp for nowait  #pragma omp for
11709                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
11710                      for (index_t k1=0; k1<m_NE1; ++k1) {                      for (index_t k1=0; k1<m_NE1; ++k1) {
11711                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);
# Line 11483  void Brick::assemblePDEBoundarySystemRed Line 11763  void Brick::assemblePDEBoundarySystemRed
11763    
11764          if (m_faceOffset[1] > -1) {          if (m_faceOffset[1] > -1) {
11765              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
11766  #pragma omp for nowait  #pragma omp for
11767                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
11768                      for (index_t k1=0; k1<m_NE1; ++k1) {                      for (index_t k1=0; k1<m_NE1; ++k1) {
11769                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);
# Line 11541  void Brick::assemblePDEBoundarySystemRed Line 11821  void Brick::assemblePDEBoundarySystemRed
11821    
11822          if (m_faceOffset[2] > -1) {          if (m_faceOffset[2] > -1) {
11823              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
11824  #pragma omp for nowait  #pragma omp for
11825                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
11826                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
11827                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);
# Line 11599  void Brick::assemblePDEBoundarySystemRed Line 11879  void Brick::assemblePDEBoundarySystemRed
11879    
11880          if (m_faceOffset[3] > -1) {          if (m_faceOffset[3] > -1) {
11881              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring              for (index_t k2_0=0; k2_0<2; k2_0++) { // colouring
11882  #pragma omp for nowait  #pragma omp for
11883                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {                  for (index_t k2=k2_0; k2<m_NE2; k2+=2) {
11884                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
11885                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);
# Line 11657  void Brick::assemblePDEBoundarySystemRed Line 11937  void Brick::assemblePDEBoundarySystemRed
11937    
11938          if (m_faceOffset[4] > -1) {          if (m_faceOffset[4] > -1) {
11939              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring
11940  #pragma omp for nowait  #pragma omp for
11941                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {
11942                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
11943                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);
# Line 11715  void Brick::assemblePDEBoundarySystemRed Line 11995  void Brick::assemblePDEBoundarySystemRed
11995    
11996          if (m_faceOffset[5] > -1) {          if (m_faceOffset[5] > -1) {
11997              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring              for (index_t k1_0=0; k1_0<2; k1_0++) { // colouring
11998  #pragma omp for nowait  #pragma omp for
11999                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {                  for (index_t k1=k1_0; k1<m_NE1; k1+=2) {
12000                      for (index_t k0=0; k0<m_NE0; ++k0) {                      for (index_t k0=0; k0<m_NE0; ++k0) {
12001                          vector<double> EM_S(8*8*numEq*numComp, 0);                          vector<double> EM_S(8*8*numEq*numComp, 0);

Legend:
Removed from v.3792  
changed lines
  Added in v.4009

  ViewVC Help
Powered by ViewVC 1.1.26