1 |
/* $Id$ */ |
/* |
2 |
|
************************************************************ |
3 |
/**************************************************************/ |
* Copyright 2006 by ACcESS MNRF * |
4 |
|
* * |
5 |
/* assembles the system of numEq PDEs into the stiffness matrix S and right hand side F */ |
* http://www.access.edu.au * |
6 |
|
* Primary Business: Queensland, Australia * |
7 |
/* -div(A*grad u)-div(B*u)+C*grad u + D*u= -div X + Y */ |
* Licensed under the Open Software License version 3.0 * |
8 |
|
* http://www.opensource.org/licenses/osl-3.0.php * |
9 |
/* -(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 */ |
* * |
10 |
|
************************************************************ |
11 |
/* u has numComp components. */ |
*/ |
|
|
|
|
/* Shape of the coefficients: */ |
|
|
|
|
|
/* A = numEqu x numDim x numComp x numDim */ |
|
|
/* B = numDim x numEqu x numComp */ |
|
|
/* C = numEqu x numDim x numComp */ |
|
|
/* D = numEqu x numComp */ |
|
|
/* X = numEqu x numDim */ |
|
|
/* Y = numEqu */ |
|
|
|
|
|
/* The coefficients A,B,C,D,X and Y have to be defined on the integartion points or not present (=NULL). */ |
|
|
|
|
|
/* S and F have to be initialized before the routine is called. S or F can be NULL. In this case the left or */ |
|
|
/* the right hand side of the PDE is not processed. */ |
|
12 |
|
|
|
/* The routine does not consider any boundary conditions. */ |
|
13 |
|
|
14 |
/**************************************************************/ |
/**************************************************************/ |
15 |
|
|
16 |
/* Copyrights by ACcESS Australia, 2003,2004 */ |
/* Author: gross@access.edu.au */ |
17 |
/* author: gross@access.edu.au */ |
/* Version: $Id$ */ |
|
/* Version: $Id$ */ |
|
18 |
|
|
19 |
/**************************************************************/ |
/**************************************************************/ |
20 |
|
|
|
#include "escript/Data/DataC.h" |
|
|
#include "Finley.h" |
|
21 |
#include "Assemble.h" |
#include "Assemble.h" |
|
#include "NodeFile.h" |
|
|
#include "ElementFile.h" |
|
22 |
#include "Util.h" |
#include "Util.h" |
23 |
#ifdef _OPENMP |
#ifdef _OPENMP |
24 |
#include <omp.h> |
#include <omp.h> |
25 |
#endif |
#endif |
26 |
|
|
27 |
|
|
28 |
|
|
29 |
/**************************************************************/ |
/**************************************************************/ |
30 |
|
/* */ |
31 |
|
/* Jacobean 1D */ |
32 |
|
/* */ |
33 |
|
void Assemble_jacobeans_1D(double* coordinates, dim_t numQuad,double* QuadWeights, |
34 |
|
dim_t numShape, dim_t numElements, dim_t numNodes, index_t* nodes, |
35 |
|
double* DSDv, dim_t numTest,double* DTDv, |
36 |
|
double* dTdX, double* volume, index_t* element_id) { |
37 |
|
#define DIM 1 |
38 |
|
#define LOCALDIM 1 |
39 |
|
register int e,q,s; |
40 |
|
char error_msg[LenErrorMsg_MAX]; |
41 |
|
#pragma omp parallel |
42 |
|
{ |
43 |
|
register double D,invD; |
44 |
|
double X0[numShape]; |
45 |
|
#pragma omp for private(e,q,s) schedule(static) |
46 |
|
for(e=0;e<numElements;e++){ |
47 |
|
for (s=0;s<numShape; s++) X0[s]=coordinates[INDEX2(0,nodes[INDEX2(s,e,numNodes)],DIM)]; |
48 |
|
for (q=0;q<numQuad;q++) { |
49 |
|
D=0; |
50 |
|
for (s=0;s<numShape; s++) D+=X0[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
51 |
|
if (D==0.) { |
52 |
|
sprintf(error_msg,"Assemble_jacobeans_1D: element %d (id %d) has length zero.",e,element_id[e]); |
53 |
|
Finley_setError(ZERO_DIVISION_ERROR,error_msg); |
54 |
|
} else { |
55 |
|
invD=1./D; |
56 |
|
for (s=0;s<numTest; s++) dTdX[INDEX4(s,0,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numShape,LOCALDIM)]*invD; |
57 |
|
} |
58 |
|
volume[INDEX2(q,e,numQuad)]=ABS(D)*QuadWeights[q]; |
59 |
|
} |
60 |
|
} |
61 |
|
|
62 |
void Finley_Assemble_PDE(Finley_NodeFile* nodes,Finley_ElementFile* elements,Finley_SystemMatrix* S, escriptDataC* F, |
} |
63 |
escriptDataC* A, escriptDataC* B, escriptDataC* C, escriptDataC* D, escriptDataC* X, escriptDataC* Y ) { |
#undef DIM |
64 |
|
#undef LOCALDIM |
65 |
|
|
66 |
double *EM_S=NULL,*EM_F=NULL,*V=NULL,*dVdv=NULL,*dSdV=NULL,*Vol=NULL,*dvdV=NULL; |
} |
67 |
double time0; |
/**************************************************************/ |
68 |
dim_t dimensions[ESCRIPT_MAX_DATA_RANK],e,q; |
/* */ |
69 |
Assemble_Parameters p; |
/* Jacobean 2D with area element */ |
70 |
index_t *index_row=NULL,*index_col=NULL,color; |
/* */ |
71 |
|
void Assemble_jacobeans_2D(double* coordinates, dim_t numQuad,double* QuadWeights, |
72 |
if (nodes==NULL || elements==NULL) return; |
dim_t numShape, dim_t numElements, dim_t numNodes, index_t* nodes, |
73 |
if (S==NULL && isEmpty(F)) return; |
double* DSDv, dim_t numTest,double* DTDv, |
74 |
|
double* dTdX, double* volume, index_t* element_id) { |
75 |
/* set all parameters in p*/ |
#define DIM 2 |
76 |
Assemble_getAssembleParameters(nodes,elements,S,F,&p); |
#define LOCALDIM 2 |
77 |
if (Finley_ErrorCode!=NO_ERROR) return; |
register int e,q,s; |
78 |
|
char error_msg[LenErrorMsg_MAX]; |
79 |
/* this function assumes NS=NN */ |
#pragma omp parallel |
80 |
if (p.NN!=p.NS) { |
{ |
81 |
Finley_ErrorCode=SYSTEM_ERROR; |
register double dXdv00,dXdv10,dXdv01,dXdv11, |
82 |
sprintf(Finley_ErrorMsg,"for Finley_Assemble_PDE numNodes and numShapes have to be identical."); |
dvdX00,dvdX10,dvdX01,dvdX11, D,invD; |
83 |
return; |
double X0[numShape], X1[numShape]; |
84 |
} |
#pragma omp for private(e,q,s) schedule(static) |
85 |
if (p.numDim!=p.numElementDim) { |
for(e=0;e<numElements;e++){ |
86 |
Finley_ErrorCode=SYSTEM_ERROR; |
for (s=0;s<numShape; s++) { |
87 |
sprintf(Finley_ErrorMsg,"Finley_Assemble_PDE accepts volume elements only."); |
X0[s]=coordinates[INDEX2(0,nodes[INDEX2(s,e,numNodes)],DIM)]; |
88 |
return; |
X1[s]=coordinates[INDEX2(1,nodes[INDEX2(s,e,numNodes)],DIM)]; |
89 |
} |
} |
90 |
/* get a functionspace */ |
for (q=0;q<numQuad;q++) { |
91 |
type_t funcspace=UNKNOWN; |
dXdv00=0; |
92 |
updateFunctionSpaceType(funcspace,A); |
dXdv10=0; |
93 |
updateFunctionSpaceType(funcspace,B); |
dXdv01=0; |
94 |
updateFunctionSpaceType(funcspace,C); |
dXdv11=0; |
95 |
updateFunctionSpaceType(funcspace,D); |
for (s=0;s<numShape; s++) { |
96 |
updateFunctionSpaceType(funcspace,X); |
dXdv00+=X0[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
97 |
updateFunctionSpaceType(funcspace,Y); |
dXdv10+=X1[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
98 |
if (funcspace==UNKNOWN) return; /* all data are empty */ |
dXdv01+=X0[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
99 |
|
dXdv11+=X1[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
100 |
/* check if all function spaces are the same */ |
} |
101 |
|
D = dXdv00*dXdv11 - dXdv01*dXdv10; |
102 |
if (! functionSpaceTypeEqual(funcspace,A) ) { |
if (D==0.) { |
103 |
Finley_ErrorCode=TYPE_ERROR; |
sprintf(error_msg,"Assemble_jacobeans_2D: element %d (id %d) has area zero.",e,element_id[e]); |
104 |
sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient A"); |
Finley_setError(ZERO_DIVISION_ERROR,error_msg); |
105 |
} |
} else { |
106 |
if (! functionSpaceTypeEqual(funcspace,B) ) { |
invD=1./D; |
107 |
Finley_ErrorCode=TYPE_ERROR; |
dvdX00= dXdv11*invD; |
108 |
sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient B"); |
dvdX10=-dXdv10*invD; |
109 |
} |
dvdX01=-dXdv01*invD; |
110 |
if (! functionSpaceTypeEqual(funcspace,C) ) { |
dvdX11= dXdv00*invD; |
111 |
Finley_ErrorCode=TYPE_ERROR; |
|
112 |
sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient C"); |
for (s=0;s<numTest; s++) { |
113 |
} |
dTdX[INDEX4(s,0,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numShape,LOCALDIM)]*dvdX00+DTDv[INDEX3(s,1,q,numShape,LOCALDIM)]*dvdX10; |
114 |
if (! functionSpaceTypeEqual(funcspace,D) ) { |
dTdX[INDEX4(s,1,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numShape,LOCALDIM)]*dvdX01+DTDv[INDEX3(s,1,q,numShape,LOCALDIM)]*dvdX11; |
115 |
Finley_ErrorCode=TYPE_ERROR; |
} |
116 |
sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient D"); |
} |
117 |
} |
volume[INDEX2(q,e,numQuad)]=ABS(D)*QuadWeights[q]; |
118 |
if (! functionSpaceTypeEqual(funcspace,X) ) { |
} |
|
Finley_ErrorCode=TYPE_ERROR; |
|
|
sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient X"); |
|
|
} |
|
|
if (! functionSpaceTypeEqual(funcspace,Y) ) { |
|
|
Finley_ErrorCode=TYPE_ERROR; |
|
|
sprintf(Finley_ErrorMsg,"unexpected function space typ for coefficient Y"); |
|
|
} |
|
|
|
|
|
/* check if all function spaces are the same */ |
|
|
|
|
|
if (! numSamplesEqual(A,p.numQuad,elements->numElements) ) { |
|
|
Finley_ErrorCode=TYPE_ERROR; |
|
|
sprintf(Finley_ErrorMsg,"sample points of coefficient A don't match (%d,%d)",p.numQuad,elements->numElements); |
|
|
} |
|
|
|
|
|
if (! numSamplesEqual(B,p.numQuad,elements->numElements) ) { |
|
|
Finley_ErrorCode=TYPE_ERROR; |
|
|
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]); |
|
119 |
} |
} |
120 |
} |
|
121 |
if (!isEmpty(D)) { |
} |
122 |
if (!isDataPointShapeEqual(D,0,dimensions)) { |
#undef DIM |
123 |
Finley_ErrorCode=TYPE_ERROR; |
#undef LOCALDIM |
124 |
sprintf(Finley_ErrorMsg,"coefficient D, rank 0 expected."); |
} |
125 |
|
/**************************************************************/ |
126 |
|
/* */ |
127 |
|
/* Jacobean 1D manifold in 2D and 1D elements */ |
128 |
|
/* */ |
129 |
|
void Assemble_jacobeans_2D_M1D_E1D(double* coordinates, dim_t numQuad,double* QuadWeights, |
130 |
|
dim_t numShape, dim_t numElements, dim_t numNodes, index_t* nodes, |
131 |
|
double* DSDv, dim_t numTest,double* DTDv, |
132 |
|
double* dTdX, double* volume, index_t* element_id) { |
133 |
|
#define DIM 2 |
134 |
|
#define LOCALDIM 1 |
135 |
|
register int e,q,s; |
136 |
|
char error_msg[LenErrorMsg_MAX]; |
137 |
|
#pragma omp parallel |
138 |
|
{ |
139 |
|
register double dXdv00,dXdv10,dvdX00,dvdX01,D,invD; |
140 |
|
double X0[numShape], X1[numShape]; |
141 |
|
#pragma omp for private(e,q,s) schedule(static) |
142 |
|
for(e=0;e<numElements;e++){ |
143 |
|
for (s=0;s<numShape; s++) { |
144 |
|
X0[s]=coordinates[INDEX2(0,nodes[INDEX2(s,e,numNodes)],DIM)]; |
145 |
|
X1[s]=coordinates[INDEX2(1,nodes[INDEX2(s,e,numNodes)],DIM)]; |
146 |
|
} |
147 |
|
for (q=0;q<numQuad;q++) { |
148 |
|
dXdv00=0; |
149 |
|
dXdv10=0; |
150 |
|
for (s=0;s<numShape; s++) { |
151 |
|
dXdv00+=X0[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
152 |
|
dXdv10+=X1[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
153 |
|
} |
154 |
|
D=dXdv00*dXdv00+dXdv10*dXdv10; |
155 |
|
if (D==0.) { |
156 |
|
sprintf(error_msg,"Assemble_jacobeans_2D_M1D_E1D: element %d (id %d) has length zero.",e,element_id[e]); |
157 |
|
Finley_setError(ZERO_DIVISION_ERROR,error_msg); |
158 |
|
} else { |
159 |
|
invD=1./D; |
160 |
|
dvdX00=dXdv00*invD; |
161 |
|
dvdX01=dXdv10*invD; |
162 |
|
for (s=0;s<numTest; s++) { |
163 |
|
dTdX[INDEX4(s,0,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX00; |
164 |
|
dTdX[INDEX4(s,1,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX01; |
165 |
|
} |
166 |
|
volume[INDEX2(q,e,numQuad)]=sqrt(D)*QuadWeights[q]; |
167 |
|
} |
168 |
|
} |
169 |
} |
} |
170 |
} |
|
171 |
if (!isEmpty(X)) { |
} |
172 |
dimensions[0]=p.numDim; |
#undef DIM |
173 |
if (!isDataPointShapeEqual(X,1,dimensions)) { |
#undef LOCALDIM |
174 |
Finley_ErrorCode=TYPE_ERROR; |
} |
175 |
sprintf(Finley_ErrorMsg,"coefficient X, expected shape (%d,",dimensions[0]); |
/**************************************************************/ |
176 |
|
/* */ |
177 |
|
/* Jacobean 1D manifold in 2D and 2D elements */ |
178 |
|
/* */ |
179 |
|
void Assemble_jacobeans_2D_M1D_E2D(double* coordinates, dim_t numQuad,double* QuadWeights, |
180 |
|
dim_t numShape, dim_t numElements, dim_t numNodes, index_t* nodes, |
181 |
|
double* DSDv, dim_t numTest,double* DTDv, |
182 |
|
double* dTdX, double* volume, index_t* element_id) { |
183 |
|
#define DIM 2 |
184 |
|
#define LOCALDIM 2 |
185 |
|
register int e,q,s; |
186 |
|
char error_msg[LenErrorMsg_MAX]; |
187 |
|
#pragma omp parallel |
188 |
|
{ |
189 |
|
register double dXdv00,dXdv10,dXdv01,dXdv11, |
190 |
|
dvdX00,dvdX10,dvdX01,dvdX11, D,invD; |
191 |
|
double X0[numShape], X1[numShape]; |
192 |
|
#pragma omp for private(e,q,s) schedule(static) |
193 |
|
for(e=0;e<numElements;e++){ |
194 |
|
for (s=0;s<numShape; s++) { |
195 |
|
X0[s]=coordinates[INDEX2(0,nodes[INDEX2(s,e,numNodes)],DIM)]; |
196 |
|
X1[s]=coordinates[INDEX2(1,nodes[INDEX2(s,e,numNodes)],DIM)]; |
197 |
|
} |
198 |
|
for (q=0;q<numQuad;q++) { |
199 |
|
dXdv00=0; |
200 |
|
dXdv10=0; |
201 |
|
dXdv01=0; |
202 |
|
dXdv11=0; |
203 |
|
for (s=0;s<numShape; s++) { |
204 |
|
dXdv00+=X0[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
205 |
|
dXdv10+=X1[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
206 |
|
dXdv01+=X0[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
207 |
|
dXdv11+=X1[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
208 |
|
} |
209 |
|
D = dXdv00*dXdv11 - dXdv01*dXdv10; |
210 |
|
if (D==0.) { |
211 |
|
sprintf(error_msg,"Assemble_jacobeans_2D_E2D: element %d (id %d) has area zero.",e,element_id[e]); |
212 |
|
Finley_setError(ZERO_DIVISION_ERROR,error_msg); |
213 |
|
} else { |
214 |
|
invD=1./D; |
215 |
|
dvdX00= dXdv11*invD; |
216 |
|
dvdX10=-dXdv10*invD; |
217 |
|
dvdX01=-dXdv01*invD; |
218 |
|
dvdX11= dXdv00*invD; |
219 |
|
|
220 |
|
for (s=0;s<numTest; s++) { |
221 |
|
dTdX[INDEX4(s,0,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX00+DTDv[INDEX3(s,1,q,numTest,LOCALDIM)]*dvdX10; |
222 |
|
dTdX[INDEX4(s,1,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX01+DTDv[INDEX3(s,1,q,numTest,LOCALDIM)]*dvdX11; |
223 |
|
} |
224 |
|
} |
225 |
|
volume[INDEX2(q,e,numQuad)]=sqrt(dXdv00*dXdv00+dXdv10*dXdv10)*QuadWeights[q]; |
226 |
|
} |
227 |
} |
} |
228 |
} |
|
229 |
if (!isEmpty(Y)) { |
} |
230 |
if (!isDataPointShapeEqual(Y,0,dimensions)) { |
#undef DIM |
231 |
Finley_ErrorCode=TYPE_ERROR; |
#undef LOCALDIM |
232 |
sprintf(Finley_ErrorMsg,"coefficient Y, rank 0 expected."); |
} |
233 |
|
/**************************************************************/ |
234 |
|
/* */ |
235 |
|
/* Jacobean 3D */ |
236 |
|
/* */ |
237 |
|
void Assemble_jacobeans_3D(double* coordinates, dim_t numQuad,double* QuadWeights, |
238 |
|
dim_t numShape, dim_t numElements, dim_t numNodes, index_t* nodes, |
239 |
|
double* DSDv, dim_t numTest,double* DTDv, |
240 |
|
double* dTdX, double* volume, index_t* element_id) { |
241 |
|
#define DIM 3 |
242 |
|
#define LOCALDIM 3 |
243 |
|
register int e,q,s; |
244 |
|
char error_msg[LenErrorMsg_MAX]; |
245 |
|
#pragma omp parallel |
246 |
|
{ |
247 |
|
register double dXdv00,dXdv10,dXdv20,dXdv01,dXdv11,dXdv21,dXdv02,dXdv12,dXdv22, |
248 |
|
dvdX00,dvdX10,dvdX20,dvdX01,dvdX11,dvdX21,dvdX02,dvdX12,dvdX22, D,invD; |
249 |
|
double X0[numShape], X1[numShape], X2[numShape]; |
250 |
|
#pragma omp for private(e,q,s) schedule(static) |
251 |
|
for(e=0;e<numElements;e++){ |
252 |
|
for (s=0;s<numShape; s++) { |
253 |
|
X0[s]=coordinates[INDEX2(0,nodes[INDEX2(s,e,numNodes)],DIM)]; |
254 |
|
X1[s]=coordinates[INDEX2(1,nodes[INDEX2(s,e,numNodes)],DIM)]; |
255 |
|
X2[s]=coordinates[INDEX2(2,nodes[INDEX2(s,e,numNodes)],DIM)]; |
256 |
|
} |
257 |
|
for (q=0;q<numQuad;q++) { |
258 |
|
dXdv00=0; |
259 |
|
dXdv10=0; |
260 |
|
dXdv20=0; |
261 |
|
dXdv01=0; |
262 |
|
dXdv11=0; |
263 |
|
dXdv21=0; |
264 |
|
dXdv02=0; |
265 |
|
dXdv12=0; |
266 |
|
dXdv22=0; |
267 |
|
for (s=0;s<numShape; s++) { |
268 |
|
dXdv00+=X0[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
269 |
|
dXdv10+=X1[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
270 |
|
dXdv20+=X2[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
271 |
|
dXdv01+=X0[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
272 |
|
dXdv11+=X1[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
273 |
|
dXdv21+=X2[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
274 |
|
dXdv02+=X0[s]*DSDv[INDEX3(s,2,q,numShape,LOCALDIM)]; |
275 |
|
dXdv12+=X1[s]*DSDv[INDEX3(s,2,q,numShape,LOCALDIM)]; |
276 |
|
dXdv22+=X2[s]*DSDv[INDEX3(s,2,q,numShape,LOCALDIM)]; |
277 |
|
} |
278 |
|
D = dXdv00*(dXdv11*dXdv22-dXdv12*dXdv21)+ dXdv01*(dXdv20*dXdv12-dXdv10*dXdv22)+dXdv02*(dXdv10*dXdv21-dXdv20*dXdv11); |
279 |
|
if (D==0.) { |
280 |
|
sprintf(error_msg,"Assemble_jacobeans_3D: element %d (id %d) has volume zero.",e,element_id[e]); |
281 |
|
Finley_setError(ZERO_DIVISION_ERROR,error_msg); |
282 |
|
} else { |
283 |
|
invD=1./D; |
284 |
|
dvdX00=(dXdv11*dXdv22-dXdv12*dXdv21)*invD; |
285 |
|
dvdX10=(dXdv20*dXdv12-dXdv10*dXdv22)*invD; |
286 |
|
dvdX20=(dXdv10*dXdv21-dXdv20*dXdv11)*invD; |
287 |
|
dvdX01=(dXdv02*dXdv21-dXdv01*dXdv22)*invD; |
288 |
|
dvdX11=(dXdv00*dXdv22-dXdv20*dXdv02)*invD; |
289 |
|
dvdX21=(dXdv01*dXdv20-dXdv00*dXdv21)*invD; |
290 |
|
dvdX02=(dXdv01*dXdv12-dXdv02*dXdv11)*invD; |
291 |
|
dvdX12=(dXdv02*dXdv10-dXdv00*dXdv12)*invD; |
292 |
|
dvdX22=(dXdv00*dXdv11-dXdv01*dXdv10)*invD; |
293 |
|
|
294 |
|
for (s=0;s<numTest; s++) { |
295 |
|
dTdX[INDEX4(s,0,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX00+DTDv[INDEX3(s,1,q,numTest,LOCALDIM)]*dvdX10+DTDv[INDEX3(s,2,q,numTest,LOCALDIM)]*dvdX20; |
296 |
|
dTdX[INDEX4(s,1,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX01+DTDv[INDEX3(s,1,q,numTest,LOCALDIM)]*dvdX11+DTDv[INDEX3(s,2,q,numTest,LOCALDIM)]*dvdX21; |
297 |
|
dTdX[INDEX4(s,2,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX02+DTDv[INDEX3(s,1,q,numTest,LOCALDIM)]*dvdX12+DTDv[INDEX3(s,2,q,numTest,LOCALDIM)]*dvdX22; |
298 |
|
} |
299 |
|
volume[INDEX2(q,e,numQuad)]=ABS(D)*QuadWeights[q]; |
300 |
|
} |
301 |
|
} |
302 |
} |
} |
303 |
} |
|
304 |
} else { |
} |
305 |
if (!isEmpty(A)) { |
#undef DIM |
306 |
dimensions[0]=p.numEqu; |
#undef LOCALDIM |
307 |
dimensions[1]=p.numDim; |
} |
308 |
dimensions[2]=p.numComp; |
/**************************************************************/ |
309 |
dimensions[3]=p.numDim; |
/* */ |
310 |
if (!isDataPointShapeEqual(A,4,dimensions)) { |
/* Jacobean 2D manifold in 3D with 3D elements */ |
311 |
Finley_ErrorCode=TYPE_ERROR; |
/* */ |
312 |
sprintf(Finley_ErrorMsg,"coefficient A, expected shape (%d,%d,%d,%d)",dimensions[0],dimensions[1],dimensions[2],dimensions[3]); |
void Assemble_jacobeans_3D_M2D_E3D(double* coordinates, dim_t numQuad,double* QuadWeights, |
313 |
} |
dim_t numShape, dim_t numElements, dim_t numNodes, index_t* nodes, |
314 |
} |
double* DSDv, dim_t numTest,double* DTDv, |
315 |
if (!isEmpty(B)) { |
double* dTdX, double* volume, index_t* element_id) { |
316 |
dimensions[0]=p.numEqu; |
#define DIM 3 |
317 |
dimensions[1]=p.numDim; |
#define LOCALDIM 3 |
318 |
dimensions[2]=p.numComp; |
register int e,q,s; |
319 |
if (!isDataPointShapeEqual(B,3,dimensions)) { |
char error_msg[LenErrorMsg_MAX]; |
320 |
Finley_ErrorCode=TYPE_ERROR; |
#pragma omp parallel |
|
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) |
|
321 |
{ |
{ |
322 |
EM_S=EM_F=V=dVdv=dSdV=Vol=dvdV=NULL; |
register double dXdv00,dXdv10,dXdv20,dXdv01,dXdv11,dXdv21,dXdv02,dXdv12,dXdv22, |
323 |
index_row=index_col=NULL; |
dvdX00,dvdX10,dvdX20,dvdX01,dvdX11,dvdX21,dvdX02,dvdX12,dvdX22, D,invD; |
324 |
|
double X0[numShape], X1[numShape], X2[numShape], m0, m1, m2; |
325 |
|
#pragma omp for private(e,q,s) schedule(static) |
326 |
|
for(e=0;e<numElements;e++){ |
327 |
|
for (s=0;s<numShape; s++) { |
328 |
|
X0[s]=coordinates[INDEX2(0,nodes[INDEX2(s,e,numNodes)],DIM)]; |
329 |
|
X1[s]=coordinates[INDEX2(1,nodes[INDEX2(s,e,numNodes)],DIM)]; |
330 |
|
X2[s]=coordinates[INDEX2(2,nodes[INDEX2(s,e,numNodes)],DIM)]; |
331 |
|
} |
332 |
|
for (q=0;q<numQuad;q++) { |
333 |
|
dXdv00=0; |
334 |
|
dXdv10=0; |
335 |
|
dXdv20=0; |
336 |
|
dXdv01=0; |
337 |
|
dXdv11=0; |
338 |
|
dXdv21=0; |
339 |
|
dXdv02=0; |
340 |
|
dXdv12=0; |
341 |
|
dXdv22=0; |
342 |
|
for (s=0;s<numShape; s++) { |
343 |
|
dXdv00+=X0[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
344 |
|
dXdv10+=X1[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
345 |
|
dXdv20+=X2[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
346 |
|
dXdv01+=X0[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
347 |
|
dXdv11+=X1[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
348 |
|
dXdv21+=X2[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
349 |
|
dXdv02+=X0[s]*DSDv[INDEX3(s,2,q,numShape,LOCALDIM)]; |
350 |
|
dXdv12+=X1[s]*DSDv[INDEX3(s,2,q,numShape,LOCALDIM)]; |
351 |
|
dXdv22+=X2[s]*DSDv[INDEX3(s,2,q,numShape,LOCALDIM)]; |
352 |
|
} |
353 |
|
D = dXdv00*(dXdv11*dXdv22-dXdv12*dXdv21)+ dXdv01*(dXdv20*dXdv12-dXdv10*dXdv22)+dXdv02*(dXdv10*dXdv21-dXdv20*dXdv11); |
354 |
|
if (D==0.) { |
355 |
|
sprintf(error_msg,"Assemble_jacobeans_3D: element %d (id %d) has volume zero.",e,element_id[e]); |
356 |
|
Finley_setError(ZERO_DIVISION_ERROR,error_msg); |
357 |
|
} else { |
358 |
|
invD=1./D; |
359 |
|
dvdX00=(dXdv11*dXdv22-dXdv12*dXdv21)*invD; |
360 |
|
dvdX10=(dXdv20*dXdv12-dXdv10*dXdv22)*invD; |
361 |
|
dvdX20=(dXdv10*dXdv21-dXdv20*dXdv11)*invD; |
362 |
|
dvdX01=(dXdv02*dXdv21-dXdv01*dXdv22)*invD; |
363 |
|
dvdX11=(dXdv00*dXdv22-dXdv20*dXdv02)*invD; |
364 |
|
dvdX21=(dXdv01*dXdv20-dXdv00*dXdv21)*invD; |
365 |
|
dvdX02=(dXdv01*dXdv12-dXdv02*dXdv11)*invD; |
366 |
|
dvdX12=(dXdv02*dXdv10-dXdv00*dXdv12)*invD; |
367 |
|
dvdX22=(dXdv00*dXdv11-dXdv01*dXdv10)*invD; |
368 |
|
|
369 |
|
for (s=0;s<numTest; s++) { |
370 |
|
dTdX[INDEX4(s,0,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX00+DTDv[INDEX3(s,1,q,numTest,LOCALDIM)]*dvdX10+DTDv[INDEX3(s,2,q,numTest,LOCALDIM)]*dvdX20; |
371 |
|
dTdX[INDEX4(s,1,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX01+DTDv[INDEX3(s,1,q,numTest,LOCALDIM)]*dvdX11+DTDv[INDEX3(s,2,q,numTest,LOCALDIM)]*dvdX21; |
372 |
|
dTdX[INDEX4(s,2,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX02+DTDv[INDEX3(s,1,q,numTest,LOCALDIM)]*dvdX12+DTDv[INDEX3(s,2,q,numTest,LOCALDIM)]*dvdX22; |
373 |
|
} |
374 |
|
} |
375 |
|
m0=dXdv10*dXdv21-dXdv20*dXdv11; |
376 |
|
m1=dXdv20*dXdv01-dXdv00*dXdv21; |
377 |
|
m2=dXdv00*dXdv11-dXdv10*dXdv01; |
378 |
|
volume[INDEX2(q,e,numQuad)]=sqrt(m0*m0+m1*m1+m2*m2)*QuadWeights[q]; |
379 |
|
} |
380 |
|
} |
381 |
|
|
382 |
/* allocate work arrays: */ |
} |
383 |
|
#undef DIM |
384 |
|
#undef LOCALDIM |
385 |
|
} |
386 |
|
/**************************************************************/ |
387 |
|
/* */ |
388 |
|
/* Jacobean 2D manifold in 3D with 2D elements */ |
389 |
|
/* */ |
390 |
|
void Assemble_jacobeans_3D_M2D_E2D(double* coordinates, dim_t numQuad,double* QuadWeights, |
391 |
|
dim_t numShape, dim_t numElements, dim_t numNodes, index_t* nodes, |
392 |
|
double* DSDv, dim_t numTest,double* DTDv, |
393 |
|
double* dTdX, double* volume, index_t* element_id) { |
394 |
|
#define DIM 3 |
395 |
|
#define LOCALDIM 2 |
396 |
|
register int e,q,s; |
397 |
|
char error_msg[LenErrorMsg_MAX]; |
398 |
|
#pragma omp parallel |
399 |
|
{ |
400 |
|
register double dXdv00,dXdv10,dXdv20,dXdv01,dXdv11,dXdv21,m00,m01,m11, |
401 |
|
dvdX00,dvdX01,dvdX02,dvdX10,dvdX11,dvdX12,D,invD; |
402 |
|
double X0[numShape], X1[numShape], X2[numShape]; |
403 |
|
#pragma omp for private(e,q,s) schedule(static) |
404 |
|
for(e=0;e<numElements;e++){ |
405 |
|
for (s=0;s<numShape; s++) { |
406 |
|
X0[s]=coordinates[INDEX2(0,nodes[INDEX2(s,e,numNodes)],DIM)]; |
407 |
|
X1[s]=coordinates[INDEX2(1,nodes[INDEX2(s,e,numNodes)],DIM)]; |
408 |
|
X2[s]=coordinates[INDEX2(2,nodes[INDEX2(s,e,numNodes)],DIM)]; |
409 |
|
} |
410 |
|
for (q=0;q<numQuad;q++) { |
411 |
|
dXdv00=0; |
412 |
|
dXdv10=0; |
413 |
|
dXdv20=0; |
414 |
|
dXdv01=0; |
415 |
|
dXdv11=0; |
416 |
|
dXdv21=0; |
417 |
|
for (s=0;s<numShape; s++) { |
418 |
|
dXdv00+=X0[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
419 |
|
dXdv10+=X1[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
420 |
|
dXdv20+=X2[s]*DSDv[INDEX3(s,0,q,numShape,LOCALDIM)]; |
421 |
|
dXdv01+=X0[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
422 |
|
dXdv11+=X1[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
423 |
|
dXdv21+=X2[s]*DSDv[INDEX3(s,1,q,numShape,LOCALDIM)]; |
424 |
|
} |
425 |
|
m00=dXdv00*dXdv00+dXdv10*dXdv10+dXdv20*dXdv20; |
426 |
|
m01=dXdv00*dXdv01+dXdv10*dXdv11+dXdv20*dXdv21; |
427 |
|
m11=dXdv01*dXdv01+dXdv11*dXdv11+dXdv21*dXdv21; |
428 |
|
D=m00*m11-m01*m01; |
429 |
|
if (D==0.) { |
430 |
|
sprintf(error_msg,"Assemble_jacobeans_3D_M2D: element %d (id %d) has area zero.",e,element_id[e]); |
431 |
|
Finley_setError(ZERO_DIVISION_ERROR,error_msg); |
432 |
|
} else { |
433 |
|
invD=1./D; |
434 |
|
dvdX00=( m00*dXdv00-m01*dXdv01)*invD; |
435 |
|
dvdX01=( m00*dXdv10-m01*dXdv11)*invD; |
436 |
|
dvdX02=( m00*dXdv20-m01*dXdv21)*invD; |
437 |
|
dvdX10=(-m01*dXdv00+m11*dXdv01)*invD; |
438 |
|
dvdX11=(-m01*dXdv10+m11*dXdv11)*invD; |
439 |
|
dvdX12=(-m01*dXdv20+m11*dXdv21)*invD; |
440 |
|
for (s=0;s<numTest; s++) { |
441 |
|
dTdX[INDEX4(s,0,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX00+DTDv[INDEX3(s,1,q,numTest,LOCALDIM)]*dvdX10; |
442 |
|
dTdX[INDEX4(s,1,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX01+DTDv[INDEX3(s,1,q,numTest,LOCALDIM)]*dvdX11; |
443 |
|
dTdX[INDEX4(s,2,q,e,numTest,DIM,numQuad)]=DTDv[INDEX3(s,0,q,numTest,LOCALDIM)]*dvdX02+DTDv[INDEX3(s,1,q,numTest,LOCALDIM)]*dvdX12; |
444 |
|
} |
445 |
|
volume[INDEX2(q,e,numQuad)]=sqrt(D)*QuadWeights[q]; |
446 |
|
} |
447 |
|
} |
448 |
|
} |
449 |
|
|
|
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=(index_t*) THREAD_MEMALLOC(p.NN_col,index_t); |
|
|
index_row=(index_t*) THREAD_MEMALLOC(p.NN_row,index_t); |
|
|
|
|
|
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=elements->minColor;color<=elements->maxColor;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)); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
/* clean up */ |
|
|
THREAD_MEMFREE(EM_S); |
|
|
THREAD_MEMFREE(EM_F); |
|
|
THREAD_MEMFREE(V); |
|
|
THREAD_MEMFREE(dVdv); |
|
|
THREAD_MEMFREE(dvdV); |
|
|
THREAD_MEMFREE(dSdV); |
|
|
THREAD_MEMFREE(Vol); |
|
|
THREAD_MEMFREE(index_col); |
|
|
THREAD_MEMFREE(index_row); |
|
450 |
} |
} |
451 |
printf("timing: assemblage PDE: %.4e sec\n",Finley_timer()-time0); |
#undef DIM |
452 |
} |
#undef LOCALDIM |
453 |
} |
} |
454 |
/* |
/* |
455 |
* $Log$ |
* $Log$ |
|
* Revision 1.5 2005/07/08 04:07:46 jgs |
|
|
* Merge of development branch back to main trunk on 2005-07-08 |
|
|
* |
|
|
* Revision 1.4 2004/12/15 07:08:32 jgs |
|
|
* *** empty log message *** |
|
|
* Revision 1.1.1.1.2.2 2005/06/29 02:34:47 gross |
|
|
* some changes towards 64 integers in finley |
|
|
* |
|
|
* Revision 1.1.1.1.2.1 2004/11/24 01:37:12 gross |
|
|
* some changes dealing with the integer overflow in memory allocation. Finley solves 4M unknowns now |
|
|
* |
|
|
* |
|
456 |
* |
* |
457 |
*/ |
*/ |