/[escript]/branches/domexper/dudley/src/Assemble_jacobeans.c
ViewVC logotype

Diff of /branches/domexper/dudley/src/Assemble_jacobeans.c

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

trunk/esys2/finley/src/finleyC/Assemble_PDE.c revision 102 by jgs, Wed Dec 15 07:08:39 2004 UTC branches/domexper/dudley/src/Assemble_jacobeans.c revision 3189 by jfenwick, Thu Sep 16 05:20:34 2010 UTC
# Line 1  Line 1 
 /* $Id$ */  
1    
2  /**************************************************************/  /*******************************************************
3    *
4    * Copyright (c) 2003-2010 by University of Queensland
5    * Earth Systems Science Computational Center (ESSCC)
6    * http://www.uq.edu.au/esscc
7    *
8    * Primary Business: Queensland, Australia
9    * Licensed under the Open Software License version 3.0
10    * http://www.opensource.org/licenses/osl-3.0.php
11    *
12    *******************************************************/
13    
 /*    assembles the system of numEq PDEs into the stiffness matrix S and right hand side F */  
14    
15  /*     -div(A*grad u)-div(B*u)+C*grad u + D*u= -div X + Y */  #include "Assemble.h"
16    #include "Util.h"
17    #ifdef _OPENMP
18    #include <omp.h>
19    #endif
20    
21  /*      -(A_{k,i,m,j} u_m,j)_i-(B_{k,i,m} u_m)_i+C_{k,m,j} u_m,j-D_{k,m} u_m = -(X_{k,i})_i + Y_k */  // Unless the loops in here get complicated again, this file should be compiled with loop unrolling
22    
 /*    u has numComp components. */  
23    
24  /*    Shape of the coefficients: */  /* input:
25    
26  /*      A = numEqu x numDim x numComp x numDim */  double* coordinates[DIM*(*)]
27  /*      B = numDim x numEqu x numComp  */  dim_t numQuad
28  /*      C = numEqu x numDim x numComp  */  double* QuadWeights[numQuad]
29  /*      D = numEqu x numComp  */  dim_t numShape
30  /*      X = numEqu x numDim   */  dim_t numElements
31  /*      Y = numEqu */  dim_t numNodes
32    index_t* nodes[numNodes*numElements]  where NUMSIDES*numShape<=numNodes
33    double* DSDv[numShape*DIM*numQuad]
34    dim_t numTest
35    double* DTDv[LOCDIM*numTest*numQuad]
36    index_t* element_id[numElements]
37    
38  /*    The coefficients A,B,C,D,X and Y have to be defined on the integartion points or not present (=NULL). */  output:
39    
40  /*    S and F have to be initialized before the routine is called. S or F can be NULL. In this case the left or */  double* dTdX[DIM*numTest*NUMSIDES*numQuad*numElements]
41  /*    the right hand side of the PDE is not processed.  */  double* volume[numQuad*numElements]
42    
43  /*    The routine does not consider any boundary conditions. */  */
44    
45  /**************************************************************/  #include "ShapeTable.h"
46    
47  /*   Copyrights by ACcESS Australia, 2003,2004 */  #define SCALING(_nsub_,_dim_) pow(1./(double)(_nsub_),1./(double)(_dim_))
 /*   author: gross@access.edu.au */  
 /*   Version: $Id$ */  
48    
49  /**************************************************************/  /**************************************************************/
50    /*                                                            */
51  #include "escript/Data/DataC.h"  /*  Jacobean 2D with area element                             */
52  #include "Finley.h"  /*                                                            */
53  #include "Assemble.h"  void Assemble_jacobeans_2D(double* coordinates, dim_t numQuad, dim_t numElements, dim_t numNodes, index_t* nodes,
54  #include "NodeFile.h"                             double* dTdX, double* absD, double* quadweight, index_t* element_id)
55  #include "ElementFile.h"  {
56  #include "Util.h"      #define DIM 2
57  #ifdef _OPENMP      #define LOCDIM 2
58  #include <omp.h>      register int e,q,s;
59  #endif      char error_msg[LenErrorMsg_MAX];
60        *quadweight=(numQuad==1)?1./2:1./6; /* numQuad is 1 or 3 */
61        const dim_t numTest=3;      // hoping this is used in constant folding
62        #pragma omp parallel
63        {
64        register double dXdv00,dXdv10,dXdv01,dXdv11,
65                           dvdX00,dvdX10,dvdX01,dvdX11, D,invD;
66        #pragma omp for private(e,q,s,dXdv00,dXdv10,dXdv01,dXdv11,dvdX00,dvdX10,dvdX01,dvdX11, D,invD,X0_loc, X1_loc) schedule(static)
67        for(e=0;e<numElements;e++)
68        {
69    #define COMPDXDV0(P)  coordinates[INDEX2(P,nodes[INDEX2(0,e,numNodes)],DIM)]*(-1)+\
70    coordinates[INDEX2(P,nodes[INDEX2(1,e,numNodes)],DIM)]*1+\
71    coordinates[INDEX2(P,nodes[INDEX2(2,e,numNodes)],DIM)]*(0)
72    
73    #define COMPDXDV1(P)  coordinates[INDEX2(P,nodes[INDEX2(0,e,numNodes)],DIM)]*(-1)+\
74    coordinates[INDEX2(P,nodes[INDEX2(1,e,numNodes)],DIM)]*(0)+\
75    coordinates[INDEX2(P,nodes[INDEX2(2,e,numNodes)],DIM)]*(1)
76    
77            dXdv00=0;
78                dXdv10=0;
79                dXdv01=0;
80                dXdv11=0;
81            dXdv00=COMPDXDV0(0);
82            dXdv10=COMPDXDV0(1);
83            dXdv01=COMPDXDV1(0);
84            dXdv11=COMPDXDV1(1);
85                D  =  dXdv00*dXdv11 - dXdv01*dXdv10;
86            absD[e]=ABS(D);
87                if (D==0.)
88            {
89            sprintf(error_msg,"Assemble_jacobeans_2D: element %d (id %d) has area zero.",e,element_id[e]);
90                    Dudley_setError(ZERO_DIVISION_ERROR,error_msg);
91                }
92            else
93            {
94            invD=1./D;
95            dvdX00= dXdv11*invD;
96            dvdX10=-dXdv10*invD;
97            dvdX01=-dXdv01*invD;
98            dvdX11= dXdv00*invD;
99            if (numQuad==1)
100            {
101                for (s=0;s<3; s++)
102                {
103    #define DTDXSET(P,Q) dTdX[INDEX4(s,P,Q,e,numTest,DIM,numQuad)] = DTDV_2D[s][0]*dvdX0##P+DTDV_2D[s][1]*dvdX1##P
104    
105                DTDXSET(0,0);
106                DTDXSET(1,0);
107                }
108    //          volume[INDEX2(0,e,1)]=ABS(D)*(*quadweight);
109            }
110            else    // numQuad==3
111            {
112                for (q=0;q<numTest;++q) // relying on unroll loops to optimise this
113                {
114                for (s=0;s<3; s++)
115                {
116                    DTDXSET(0,q);
117                    DTDXSET(1,q);
118                }
119    //          volume[INDEX2(q,e,3)]=ABS(D)*(*quadweight);
120                }
121            }
122            }
123        }
124         }  // end parallel
125         #undef DIM
126         #undef LOCDIM
127         #undef DTDXSET
128         #undef COMPDXDV0
129         #undef COMPDXDV1
130    }
131  /**************************************************************/  /**************************************************************/
132    /*                                                            */
133    /*  Jacobean 1D manifold in 2D and 1D elements                */
134    /*                                                            */
135    void Assemble_jacobeans_2D_M1D_E1D(double* coordinates, dim_t numQuad,
136                                       dim_t numElements, dim_t numNodes, index_t* nodes,
137                                       double* dTdX, double* absD, double* quadweight, index_t* element_id)
138    {
139        #define DIM 2
140        #define LOCDIM 1
141        register int e;
142        char error_msg[LenErrorMsg_MAX];
143        const dim_t numTest=2;
144        *quadweight=(numQuad==1)?1.0:0.5;
145        // numQuad is 1 or 2
146        #pragma omp parallel
147        {
148        register double dXdv00,dXdv10,dvdX00,dvdX01,D,invD;
149        #pragma omp for private(e,q,s,dXdv00,dXdv10,dvdX00,dvdX01,D,invD,X0_loc, X1_loc) schedule(static)
150        for(e=0;e<numElements;e++)
151        {
152            dXdv00=0;
153            dXdv10=0;
154            dXdv00+=coordinates[INDEX2(0,nodes[INDEX2(0,e,numNodes)],DIM)]*(-1.)+coordinates[INDEX2(0,nodes[INDEX2(1,e,numNodes)],DIM)];
155            dXdv00+=coordinates[INDEX2(1,nodes[INDEX2(0,e,numNodes)],DIM)]*(-1.)+coordinates[INDEX2(1,nodes[INDEX2(1,e,numNodes)],DIM)];
156            D=dXdv00*dXdv00+dXdv10*dXdv10;
157            if (D==0.)
158            {
159            sprintf(error_msg,"Assemble_jacobeans_2D_M1D_E1D: element %d (id %d) has length zero.",e,element_id[e]);
160            Dudley_setError(ZERO_DIVISION_ERROR,error_msg);
161            } else {        
162            invD=1./D;
163            dvdX00=dXdv00*invD;
164            dvdX01=dXdv10*invD;
165            // The number of quad points is 1 or 2
166            dTdX[INDEX4(0,0,0,e,numTest,DIM,numQuad)]=-1*dvdX00;
167            dTdX[INDEX4(0,1,0,e,numTest,DIM,numQuad)]=-1*dvdX01;
168            dTdX[INDEX4(1,0,0,e,numTest,DIM,numQuad)]=-1*dvdX00;
169            dTdX[INDEX4(1,1,0,e,numTest,DIM,numQuad)]=-1*dvdX01;
170    //      volume[INDEX2(0,e,numQuad)]=sqrt(D)*(*quadweight);
171            absD[e]=sqrt(D);
172            if (numQuad==2)
173            {
174                dTdX[INDEX4(0,0,1,e,numTest,DIM,numQuad)]=dvdX00;
175                dTdX[INDEX4(0,1,1,e,numTest,DIM,numQuad)]=dvdX01;
176                dTdX[INDEX4(1,0,1,e,numTest,DIM,numQuad)]=dvdX00;
177                dTdX[INDEX4(1,1,1,e,numTest,DIM,numQuad)]=dvdX01;
178    //          volume[INDEX2(1,e,numQuad)]=sqrt(D)*(*quadweight);
179            }
180            }
181        }
182        }   // end parallel
183        #undef DIM
184        #undef LOCDIM
185    }
186    
187  void Finley_Assemble_PDE(Finley_NodeFile* nodes,Finley_ElementFile* elements,Finley_SystemMatrix* S, escriptDataC* F,  /**************************************************************/
188               escriptDataC* A, escriptDataC* B, escriptDataC* C, escriptDataC* D, escriptDataC* X, escriptDataC* Y ) {  /*                                                            */
189    /*  Jacobean 3D                                               */
190    double *EM_S=NULL,*EM_F=NULL,*V=NULL,*dVdv=NULL,*dSdV=NULL,*Vol=NULL,*dvdV=NULL;  /*                                                            */
191    double time0;  void Assemble_jacobeans_3D(double* coordinates, dim_t numQuad, dim_t numElements, dim_t numNodes, index_t* nodes,
192    int dimensions[ESCRIPT_MAX_DATA_RANK],e,q,color;                             double* dTdX, double* absD, double* quadweight, index_t* element_id)
193    Assemble_Parameters p;  {
194    maybelong *index_row=NULL,*index_col=NULL;      #define DIM 3
195        #define LOCDIM 3
196    if (nodes==NULL || elements==NULL) return;      int e,q,s;
197    if (S==NULL && isEmpty(F)) return;      char error_msg[LenErrorMsg_MAX];
198        // numQuad is 1 or 4
199    /* set all parameters in p*/      const dim_t numShape=4, numTest=4;
200    Assemble_getAssembleParameters(nodes,elements,S,F,&p);      *quadweight=(numQuad==1)?1./6:1./24;
201    if (Finley_ErrorCode!=NO_ERROR) return;  
202        #pragma omp parallel
203    /*  this function assumes NS=NN */      {
204    if (p.NN!=p.NS) {      register double dXdv00,dXdv10,dXdv20,dXdv01,dXdv11,dXdv21,dXdv02,dXdv12,dXdv22,
205      Finley_ErrorCode=SYSTEM_ERROR;                         dvdX00,dvdX10,dvdX20,dvdX01,dvdX11,dvdX21,dvdX02,dvdX12,dvdX22, D,invD,
206      sprintf(Finley_ErrorMsg,"for Finley_Assemble_PDE numNodes and numShapes have to be identical.");                         X0_loc,X1_loc,X2_loc;
207      return;      #pragma omp for private(e,q,s,dXdv00,dXdv10,dXdv20,dXdv01,dXdv11,dXdv21,dXdv02,dXdv12,dXdv22,dvdX00,dvdX10,dvdX20,dvdX01,dvdX11,dvdX21,dvdX02,dvdX12,dvdX22,D,invD,X0_loc,X1_loc,X2_loc) schedule(static)
208    }      for(e=0;e<numElements;e++)
209    if (p.numDim!=p.numElementDim) {      {
210      Finley_ErrorCode=SYSTEM_ERROR;          dXdv00=0;
211      sprintf(Finley_ErrorMsg,"Finley_Assemble_PDE accepts volume elements only.");          dXdv10=0;
212      return;          dXdv20=0;
213    }          dXdv01=0;
214    /*  get a functionspace */          dXdv11=0;
215    int funcspace=UNKNOWN;          dXdv21=0;
216    updateFunctionSpaceType(funcspace,A);          dXdv02=0;
217    updateFunctionSpaceType(funcspace,B);          dXdv12=0;
218    updateFunctionSpaceType(funcspace,C);          dXdv22=0;
219    updateFunctionSpaceType(funcspace,D);          for (s=0;s<numShape; s++)
220    updateFunctionSpaceType(funcspace,X);          {
221    updateFunctionSpaceType(funcspace,Y);          X0_loc=coordinates[INDEX2(0,nodes[INDEX2(s,e,numNodes)],DIM)];
222    if (funcspace==UNKNOWN) return; /* all  data are empty */          X1_loc=coordinates[INDEX2(1,nodes[INDEX2(s,e,numNodes)],DIM)];
223            X2_loc=coordinates[INDEX2(2,nodes[INDEX2(s,e,numNodes)],DIM)];
224    /* check if all function spaces are the same */          dXdv00+=X0_loc*DTDV_3D[s][0];
225            dXdv10+=X1_loc*DTDV_3D[s][0];
226    if (! functionSpaceTypeEqual(funcspace,A) ) {          dXdv20+=X2_loc*DTDV_3D[s][0];
227          Finley_ErrorCode=TYPE_ERROR;          dXdv01+=X0_loc*DTDV_3D[s][1];
228          sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient A");          dXdv11+=X1_loc*DTDV_3D[s][1];
229    }          dXdv21+=X2_loc*DTDV_3D[s][1];
230    if (! functionSpaceTypeEqual(funcspace,B) ) {          dXdv02+=X0_loc*DTDV_3D[s][2];
231          Finley_ErrorCode=TYPE_ERROR;          dXdv12+=X1_loc*DTDV_3D[s][2];
232          sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient B");          dXdv22+=X2_loc*DTDV_3D[s][2];
233    }          }
234    if (! functionSpaceTypeEqual(funcspace,C) ) {          D  =  dXdv00*(dXdv11*dXdv22-dXdv12*dXdv21)+ dXdv01*(dXdv20*dXdv12-dXdv10*dXdv22)+dXdv02*(dXdv10*dXdv21-dXdv20*dXdv11);
235          Finley_ErrorCode=TYPE_ERROR;          absD[e]=ABS(D);
236          sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient C");          if (D==0.)
237    }          {
238    if (! functionSpaceTypeEqual(funcspace,D) ) {          sprintf(error_msg,"Assemble_jacobeans_3D: element %d (id %d) has volume zero.",e,element_id[e]);
239          Finley_ErrorCode=TYPE_ERROR;          Dudley_setError(ZERO_DIVISION_ERROR,error_msg);
240          sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient D");          } else {
241    }          invD=1./D;
242    if (! functionSpaceTypeEqual(funcspace,X) ) {          dvdX00=(dXdv11*dXdv22-dXdv12*dXdv21)*invD;
243          Finley_ErrorCode=TYPE_ERROR;          dvdX10=(dXdv20*dXdv12-dXdv10*dXdv22)*invD;
244          sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient X");          dvdX20=(dXdv10*dXdv21-dXdv20*dXdv11)*invD;
245    }          dvdX01=(dXdv02*dXdv21-dXdv01*dXdv22)*invD;
246    if (! functionSpaceTypeEqual(funcspace,Y) ) {          dvdX11=(dXdv00*dXdv22-dXdv20*dXdv02)*invD;
247          Finley_ErrorCode=TYPE_ERROR;          dvdX21=(dXdv01*dXdv20-dXdv00*dXdv21)*invD;
248          sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient Y");          dvdX02=(dXdv01*dXdv12-dXdv02*dXdv11)*invD;
249    }          dvdX12=(dXdv02*dXdv10-dXdv00*dXdv12)*invD;
250            dvdX22=(dXdv00*dXdv11-dXdv01*dXdv10)*invD;
251    /* check if all function spaces are the same */          for (q=0;q<numQuad;q++)
252            {
253    if (! numSamplesEqual(A,p.numQuad,elements->numElements) ) {              for (s=0;s<numTest; s++)
254          Finley_ErrorCode=TYPE_ERROR;              {
255          sprintf(Finley_ErrorMsg,"sample points of coefficient A don't match (%d,%d)",p.numQuad,elements->numElements);              dTdX[INDEX4(s,0,q,e,numTest,DIM,numQuad)]=DTDV_3D[s][0]*dvdX00+DTDV_3D[s][1]*dvdX10+DTDV_3D[s][2]*dvdX20;
256    }              dTdX[INDEX4(s,1,q,e,numTest,DIM,numQuad)]=DTDV_3D[s][0]*dvdX01+DTDV_3D[s][1]*dvdX11+DTDV_3D[s][2]*dvdX21;
257                dTdX[INDEX4(s,2,q,e,numTest,DIM,numQuad)]=DTDV_3D[s][0]*dvdX02+DTDV_3D[s][1]*dvdX12+DTDV_3D[s][2]*dvdX22;
258    if (! numSamplesEqual(B,p.numQuad,elements->numElements) ) {              }
259          Finley_ErrorCode=TYPE_ERROR;  //          volume[INDEX2(q,e,numQuad)]=ABS(D)*(*quadweight);
         sprintf(Finley_ErrorMsg,"sample points of coefficient B don't match (%d,%d)",p.numQuad,elements->numElements);  
   }  
   
   if (! numSamplesEqual(C,p.numQuad,elements->numElements) ) {  
         Finley_ErrorCode=TYPE_ERROR;  
         sprintf(Finley_ErrorMsg,"sample points of coefficient C don't match (%d,%d)",p.numQuad,elements->numElements);  
   }  
   
   if (! numSamplesEqual(D,p.numQuad,elements->numElements) ) {  
         Finley_ErrorCode=TYPE_ERROR;  
         sprintf(Finley_ErrorMsg,"sample points of coefficient D don't match (%d,%d)",p.numQuad,elements->numElements);  
   }  
   
   if (! numSamplesEqual(X,p.numQuad,elements->numElements) ) {  
         Finley_ErrorCode=TYPE_ERROR;  
         sprintf(Finley_ErrorMsg,"sample points of coefficient X don't match (%d,%d)",p.numQuad,elements->numElements);  
   }  
   
   if (! numSamplesEqual(Y,p.numQuad,elements->numElements) ) {  
         Finley_ErrorCode=TYPE_ERROR;  
         sprintf(Finley_ErrorMsg,"sample points of coefficient Y don't match (%d,%d)",p.numQuad,elements->numElements);  
   }  
   
   /*  check the dimensions: */  
     
   if (p.numEqu==1 && p.numComp==1) {  
     if (!isEmpty(A)) {  
       dimensions[0]=p.numDim;  
       dimensions[1]=p.numDim;  
       if (!isDataPointShapeEqual(A,2,dimensions)) {  
           Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient A: illegal shape, expected shape (%d,%d)",dimensions[0],dimensions[1]);  
       }  
     }  
     if (!isEmpty(B)) {  
        dimensions[0]=p.numDim;  
        if (!isDataPointShapeEqual(B,1,dimensions)) {  
           Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient B: illegal shape (%d,)",dimensions[0]);  
        }  
     }  
     if (!isEmpty(C)) {  
        dimensions[0]=p.numDim;  
        if (!isDataPointShapeEqual(C,1,dimensions)) {  
           Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient C, expected shape (%d,)",dimensions[0]);  
        }  
     }  
     if (!isEmpty(D)) {  
        if (!isDataPointShapeEqual(D,0,dimensions)) {  
           Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient D, rank 0 expected.");  
        }  
     }  
     if (!isEmpty(X)) {  
        dimensions[0]=p.numDim;  
        if (!isDataPointShapeEqual(X,1,dimensions)) {  
           Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient X, expected shape (%d,",dimensions[0]);  
        }  
     }  
     if (!isEmpty(Y)) {  
        if (!isDataPointShapeEqual(Y,0,dimensions)) {  
           Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient Y, rank 0 expected.");  
        }  
     }  
   } else {  
     if (!isEmpty(A)) {  
       dimensions[0]=p.numEqu;  
       dimensions[1]=p.numDim;  
       dimensions[2]=p.numComp;  
       dimensions[3]=p.numDim;  
       if (!isDataPointShapeEqual(A,4,dimensions)) {  
           Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient A, expected shape (%d,%d,%d,%d)",dimensions[0],dimensions[1],dimensions[2],dimensions[3]);  
       }  
     }  
     if (!isEmpty(B)) {  
       dimensions[0]=p.numEqu;  
       dimensions[1]=p.numDim;  
       dimensions[2]=p.numComp;  
       if (!isDataPointShapeEqual(B,3,dimensions)) {  
           Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient B, expected shape (%d,%d,%d)",dimensions[0],dimensions[1],dimensions[2]);  
       }  
     }  
     if (!isEmpty(C)) {  
       dimensions[0]=p.numEqu;  
       dimensions[1]=p.numComp;  
       dimensions[2]=p.numDim;  
       if (!isDataPointShapeEqual(C,3,dimensions)) {  
            Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient C, expected shape (%d,%d,%d)",dimensions[0],dimensions[1],dimensions[2]);  
       }  
     }  
     if (!isEmpty(D)) {  
       dimensions[0]=p.numEqu;  
       dimensions[1]=p.numComp;  
       if (!isDataPointShapeEqual(D,2,dimensions)) {  
           Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient D, expected shape (%d,%d)",dimensions[0],dimensions[1]);  
       }  
     }  
     if (!isEmpty(X)) {  
       dimensions[0]=p.numEqu;  
       dimensions[1]=p.numDim;  
       if (!isDataPointShapeEqual(X,2,dimensions)) {  
            Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient X, expected shape (%d,%d)",dimensions[0],dimensions[1]);  
       }  
     }  
     if (!isEmpty(Y)) {  
       dimensions[0]=p.numEqu;  
       if (!isDataPointShapeEqual(Y,1,dimensions)) {  
            Finley_ErrorCode=TYPE_ERROR;  
           sprintf(Finley_ErrorMsg,"coefficient Y, expected shape (%d,)",dimensions[0]);  
       }  
     }  
   }  
   
   if (Finley_ErrorCode==NO_ERROR) {  
      time0=Finley_timer();  
      #pragma omp parallel private(index_col,index_row,EM_S,EM_F,V,dVdv,dSdV,Vol,dvdV,color,q) \  
             firstprivate(elements,nodes,S,F,A,B,C,D,X,Y)  
      {  
          EM_S=EM_F=V=dVdv=dSdV=Vol=dvdV=NULL;  
          index_row=index_col=NULL;  
   
          /* allocate work arrays: */  
   
          EM_S=(double*) THREAD_MEMALLOC(p.NN_row*p.NN_col*p.numEqu*p.numComp,double);  
          EM_F=(double*) THREAD_MEMALLOC(p.NN_row*p.numEqu,double);  
          V=(double*) THREAD_MEMALLOC(p.NN*p.numDim,double);  
          dVdv=(double*) THREAD_MEMALLOC(p.numDim*p.numDim*p.numQuad,double);  
          dvdV=(double*) THREAD_MEMALLOC(p.numDim*p.numDim*p.numQuad,double);  
          dSdV=(double*) THREAD_MEMALLOC(p.NS_row*p.numQuad*p.numDim,double);  
          Vol=(double*) THREAD_MEMALLOC(p.numQuad,double);  
          index_col=(maybelong*) THREAD_MEMALLOC(p.NN_col,maybelong);  
          index_row=(maybelong*) THREAD_MEMALLOC(p.NN_row,maybelong);  
   
          if (! (Finley_checkPtr(EM_S) || Finley_checkPtr(EM_F) || Finley_checkPtr(V) || Finley_checkPtr(index_col) ||  
                 Finley_checkPtr(index_row) || Finley_checkPtr(dVdv) || Finley_checkPtr(dSdV) || Finley_checkPtr(Vol) ))  {  
   
            /*  open loop over all colors: */  
            for (color=0;color<elements->numColors;color++) {  
               /*  open loop over all elements: */  
               #pragma omp for private(e) schedule(static)  
               for(e=0;e<elements->numElements;e++){  
                 if (elements->Color[e]==color) {  
                   for (q=0;q<p.NN_row;q++) index_row[q]=p.label_row[elements->Nodes[INDEX2(p.row_node[q],e,p.NN)]];  
                   /* gather V-coordinates of nodes into V: */  
           Finley_Util_Gather_double(p.NN,&(elements->Nodes[INDEX2(0,e,p.NN)]),p.numDim,nodes->Coordinates,V);  
                   /*  calculate dVdv(i,j,q)=V(i,k)*DSDv(k,j,q) */  
           Finley_Util_SmallMatMult(p.numDim,p.numDim*p.numQuad,dVdv,p.NS,V,p.referenceElement->dSdv);  
                   /*  dvdV=invert(dVdv) inplace */  
           Finley_Util_InvertSmallMat(p.numQuad,p.numDim,dVdv,dvdV,Vol);  
                   /*  calculate dSdV=DSDv*DvDV */  
           Finley_Util_SmallMatSetMult(p.numQuad,p.NS_row,p.numDim,dSdV,p.numDim,p.referenceElement_row->dSdv,dvdV);  
                   /*  scale volume: */  
           for (q=0;q<p.numQuad;q++) Vol[q]=ABS(Vol[q]*p.referenceElement->QuadWeights[q]);  
       
                    /*   integration for the stiffness matrix: */  
                    /*   in order to optimze the number of operations the case of constants coefficience needs a bit more work */  
                    /*   to make use of some symmetry. */  
   
                      if (S!=NULL) {  
                        for (q=0;q<p.NN_row*p.NN_col*p.numEqu*p.numComp;q++) EM_S[q]=0;  
                        if (p.numEqu==1 && p.numComp==1) {  
                        Finley_Assemble_PDEMatrix_Single2(p.NS_row,p.numDim,p.numQuad,  
                                                                      p.referenceElement_row->S,dSdV,Vol,p.NN_row,EM_S,  
                                                                      getSampleData(A,e),isExpanded(A),  
                                                                      getSampleData(B,e),isExpanded(B),  
                                                                      getSampleData(C,e),isExpanded(C),  
                                                                      getSampleData(D,e),isExpanded(D));  
                        } else {  
                        Finley_Assemble_PDEMatrix_System2(p.NS_row,p.numDim,p.numQuad,p.numEqu,p.numComp,  
                                                                      p.referenceElement_row->S,dSdV,Vol,p.NN_row,EM_S,  
                                                                      getSampleData(A,e),isExpanded(A),  
                                                                      getSampleData(B,e),isExpanded(B),  
                                                                      getSampleData(C,e),isExpanded(C),  
                                                                      getSampleData(D,e),isExpanded(D));  
                        }  
                        for (q=0;q<p.NN_col;q++) index_col[q]=p.label_col[elements->Nodes[INDEX2(p.col_node[q],e,p.NN)]];  
                        Finley_SystemMatrix_add(S,p.NN_row,index_row,p.numEqu,p.NN_col,index_col,p.numComp,EM_S);  
                      }  
                      if (!isEmpty(F)) {  
                        for (q=0;q<p.NN_row*p.numEqu;q++) EM_F[q]=0;  
                        if (p.numEqu==1) {  
                        Finley_Assemble_RHSMatrix_Single(p.NS_row,p.numDim,p.numQuad,  
                                                                  p.referenceElement_row->S,dSdV,Vol,p.NN_row,EM_F,  
                                                                  getSampleData(X,e),isExpanded(X),  
                                                                  getSampleData(Y,e),isExpanded(Y));  
                        } else {  
                        Finley_Assemble_RHSMatrix_System(p.NS_row,p.numDim,p.numQuad,  
                                                                  p.numEqu,p.referenceElement_row->S,dSdV,Vol,p.NN_row,EM_F,  
                                                                  getSampleData(X,e),isExpanded(X),  
                                                                  getSampleData(Y,e),isExpanded(Y));  
                        }  
                        /* add  */  
                        Finley_Util_AddScatter(p.NN_row,index_row,p.numEqu,EM_F,getSampleData(F,0));  
                     }  
260                  }                  }
261                }          }
262              }      }
263           }       }  // end parallel
264           /* clean up */       #undef DIM
265           THREAD_MEMFREE(EM_S);       #undef LOCDIM
266           THREAD_MEMFREE(EM_F);  }
267           THREAD_MEMFREE(V);  
268           THREAD_MEMFREE(dVdv);  /**************************************************************/
269           THREAD_MEMFREE(dvdV);  /*                                                            */
270           THREAD_MEMFREE(dSdV);  /*  Jacobean 2D manifold in 3D with 2D elements               */
271           THREAD_MEMFREE(Vol);  /*                                                            */
272           THREAD_MEMFREE(index_col);  void Assemble_jacobeans_3D_M2D_E2D(double* coordinates, dim_t numQuad, dim_t numElements, dim_t numNodes, index_t* nodes,
273           THREAD_MEMFREE(index_row);                                     double* dTdX, double* absD, double* quadweight, index_t* element_id)
274       }  {
275       printf("timing: assemblage PDE: %.4e sec\n",Finley_timer()-time0);      #define DIM 3
276    }      #define LOCDIM 2
277        register int e,q,s;
278        char error_msg[LenErrorMsg_MAX];
279        // numQuad is 1 or 3
280        *quadweight=(numQuad==1)?1./2:1./6;
281        const double DTDV[3][2]={{-1.,-1.},{1.,0.},{0.,1.}};
282        const dim_t numShape=3, numTest=3;
283        #pragma omp parallel
284        {
285        register double dXdv00,dXdv10,dXdv20,dXdv01,dXdv11,dXdv21,m00,m01,m11,
286                           dvdX00,dvdX01,dvdX02,dvdX10,dvdX11,dvdX12,D,invD,
287                           X0_loc, X1_loc, X2_loc;
288        #pragma omp for private(e,q,s,dXdv00,dXdv10,dXdv20,dXdv01,dXdv11,dXdv21,m00,m01,m11,dvdX00,dvdX01,dvdX02,dvdX10,dvdX11,dvdX12,D,invD, X0_loc, X1_loc, X2_loc) schedule(static)
289        for(e=0;e<numElements;e++)
290        {
291            dXdv00=0;
292            dXdv10=0;
293            dXdv20=0;
294            dXdv01=0;
295            dXdv11=0;
296            dXdv21=0;
297            for (s=0;s<numShape; s++)
298            {
299            X0_loc=coordinates[INDEX2(0,nodes[INDEX2(s,e,numNodes)],DIM)];
300            X1_loc=coordinates[INDEX2(1,nodes[INDEX2(s,e,numNodes)],DIM)];
301            X2_loc=coordinates[INDEX2(2,nodes[INDEX2(s,e,numNodes)],DIM)];
302            dXdv00+=X0_loc*DTDV[s][0];
303            dXdv10+=X1_loc*DTDV[s][0];
304            dXdv20+=X2_loc*DTDV[s][0];
305            dXdv01+=X0_loc*DTDV[s][1];
306            dXdv11+=X1_loc*DTDV[s][1];
307            dXdv21+=X2_loc*DTDV[s][1];
308            }
309            m00=dXdv00*dXdv00+dXdv10*dXdv10+dXdv20*dXdv20;
310            m01=dXdv00*dXdv01+dXdv10*dXdv11+dXdv20*dXdv21;
311            m11=dXdv01*dXdv01+dXdv11*dXdv11+dXdv21*dXdv21;
312            D=m00*m11-m01*m01;
313            absD[e]=sqrt(D);
314            if (D==0.)
315            {
316            sprintf(error_msg,"Assemble_jacobeans_3D_M2D: element %d (id %d) has area zero.",e,element_id[e]);
317            Dudley_setError(ZERO_DIVISION_ERROR,error_msg);
318            } else {
319            invD=1./D;
320            dvdX00=( m00*dXdv00-m01*dXdv01)*invD;
321            dvdX01=( m00*dXdv10-m01*dXdv11)*invD;
322            dvdX02=( m00*dXdv20-m01*dXdv21)*invD;
323            dvdX10=(-m01*dXdv00+m11*dXdv01)*invD;
324            dvdX11=(-m01*dXdv10+m11*dXdv11)*invD;
325            dvdX12=(-m01*dXdv20+m11*dXdv21)*invD;
326            for (q=0;q<numQuad;q++)
327            {
328                for (s=0;s<numTest; s++)
329                {
330                dTdX[INDEX4(s,0,q,e,numTest,DIM,numQuad)]=DTDV[s][0]*dvdX00+DTDV[s][1]*dvdX10;
331                dTdX[INDEX4(s,1,q,e,numTest,DIM,numQuad)]=DTDV[s][0]*dvdX01+DTDV[s][1]*dvdX11;
332                dTdX[INDEX4(s,2,q,e,numTest,DIM,numQuad)]=DTDV[s][0]*dvdX02+DTDV[s][1]*dvdX12;
333                }
334    //          volume[INDEX2(q,e,numQuad)]=sqrt(D)*(*quadweight);
335            }
336            }
337        }
338        }   // end parallel section
339        #undef DIM
340        #undef LOCDIM
341  }  }
 /*  
  * $Log$  
  * Revision 1.4  2004/12/15 07:08:32  jgs  
  * *** empty log message ***  
  *  
  *  
  *  
  */  

Legend:
Removed from v.102  
changed lines
  Added in v.3189

  ViewVC Help
Powered by ViewVC 1.1.26