2
/*******************************************************
4
* Copyright (c) 2003-2010 by University of Queensland
5
* Earth Systems Science Computational Center (ESSCC)
6
* http://www.uq.edu.au/esscc
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
12
*******************************************************/
14
/**************************************************************/
16
/* assembles the system of numEq PDEs into the stiffness matrix S and right hand side F */
18
/* -div(A*grad u)-div(B*u)+C*grad u + D*u= -div X + Y */
20
/* -(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 */
22
/* u has numComp components. */
24
/* Shape of the coefficients: */
26
/* A = numEqu x numDim x numComp x numDim */
27
/* B = numDim x numEqu x numComp */
28
/* C = numEqu x numDim x numComp */
29
/* D = numEqu x numComp */
30
/* X = numEqu x numDim */
33
/* The coefficients A,B,C,D,X and Y have to be defined on the integartion points or not present (=NULL). */
35
/* S and F have to be initialized before the routine is called. S or F can be NULL. In this case the left or */
36
/* the right hand side of the PDE is not processed. */
38
/* The routine does not consider any boundary conditions. */
40
/**************************************************************/
44
#include "esysUtils/blocktimer.h"
49
/**************************************************************/
51
void Dudley_Assemble_PDE(Dudley_NodeFile * nodes, Dudley_ElementFile * elements, Paso_SystemMatrix * S,
52
escriptDataC * F, escriptDataC * A, escriptDataC * B, escriptDataC * C, escriptDataC * D,
53
escriptDataC * X, escriptDataC * Y)
56
bool_t reducedIntegrationOrder = FALSE;
57
char error_msg[LenErrorMsg_MAX];
58
Dudley_Assemble_Parameters p;
60
dim_t dimensions[ESCRIPT_MAX_DATA_RANK];
62
double blocktimer_start = blocktimer_time();
69
iam = elements->MPIInfo->rank;
70
numCPUs = elements->MPIInfo->size;
74
if (nodes == NULL || elements == NULL)
76
if (S == NULL && isEmpty(F))
79
if (isEmpty(F) && !isEmpty(X) && !isEmpty(F))
81
Dudley_setError(TYPE_ERROR,
82
"Dudley_Assemble_PDE: right hand side coefficients are non-zero bat no right hand side vector given.");
85
if (S == NULL && !isEmpty(A) && !isEmpty(B) && !isEmpty(C) && !isEmpty(D))
87
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_PDE: coefficients are non-zero but no matrix is given.");
90
/* get the functionspace for this assemblage call */
92
updateFunctionSpaceType(funcspace, A);
93
updateFunctionSpaceType(funcspace, B);
94
updateFunctionSpaceType(funcspace, C);
95
updateFunctionSpaceType(funcspace, D);
96
updateFunctionSpaceType(funcspace, X);
97
updateFunctionSpaceType(funcspace, Y);
98
if (funcspace == UNKNOWN)
99
return; /* all data are empty */
101
/* check if all function spaces are the same */
102
if (!functionSpaceTypeEqual(funcspace, A))
104
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_PDE: unexpected function space type for coefficient A");
106
if (!functionSpaceTypeEqual(funcspace, B))
108
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_PDE: unexpected function space type for coefficient B");
110
if (!functionSpaceTypeEqual(funcspace, C))
112
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_PDE: unexpected function space type for coefficient C");
114
if (!functionSpaceTypeEqual(funcspace, D))
116
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_PDE: unexpected function space type for coefficient D");
118
if (!functionSpaceTypeEqual(funcspace, X))
120
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_PDE: unexpected function space type for coefficient X");
122
if (!functionSpaceTypeEqual(funcspace, Y))
124
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_PDE: unexpected function space type for coefficient Y");
126
if (!Dudley_noError())
129
/* check if all function spaces are the same */
130
if (funcspace == DUDLEY_ELEMENTS)
132
reducedIntegrationOrder = FALSE;
134
else if (funcspace == DUDLEY_FACE_ELEMENTS)
136
reducedIntegrationOrder = FALSE;
138
else if (funcspace == DUDLEY_REDUCED_ELEMENTS)
140
reducedIntegrationOrder = TRUE;
142
else if (funcspace == DUDLEY_REDUCED_FACE_ELEMENTS)
144
reducedIntegrationOrder = TRUE;
148
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_PDE: assemblage failed because of illegal function space.");
150
if (!Dudley_noError())
153
/* set all parameters in p */
154
Dudley_Assemble_getAssembleParameters(nodes, elements, S, F, reducedIntegrationOrder, &p);
155
if (!Dudley_noError())
158
/* check if all function spaces are the same */
160
if (!numSamplesEqual(A, p.numQuad, elements->numElements))
162
sprintf(error_msg, "Dudley_Assemble_PDE: sample points of coefficient A don't match (%d,%d)", p.numQuad,
163
elements->numElements);
164
Dudley_setError(TYPE_ERROR, error_msg);
167
if (!numSamplesEqual(B, p.numQuad, elements->numElements))
169
sprintf(error_msg, "Dudley_Assemble_PDE: sample points of coefficient B don't match (%d,%d)", p.numQuad,
170
elements->numElements);
171
Dudley_setError(TYPE_ERROR, error_msg);
174
if (!numSamplesEqual(C, p.numQuad, elements->numElements))
176
sprintf(error_msg, "Dudley_Assemble_PDE: sample points of coefficient C don't match (%d,%d)", p.numQuad,
177
elements->numElements);
178
Dudley_setError(TYPE_ERROR, error_msg);
181
if (!numSamplesEqual(D, p.numQuad, elements->numElements))
183
sprintf(error_msg, "Dudley_Assemble_PDE: sample points of coefficient D don't match (%d,%d)", p.numQuad,
184
elements->numElements);
185
Dudley_setError(TYPE_ERROR, error_msg);
188
if (!numSamplesEqual(X, p.numQuad, elements->numElements))
190
sprintf(error_msg, "Dudley_Assemble_PDE: sample points of coefficient X don't match (%d,%d)", p.numQuad,
191
elements->numElements);
192
Dudley_setError(TYPE_ERROR, error_msg);
195
if (!numSamplesEqual(Y, p.numQuad, elements->numElements))
197
sprintf(error_msg, "Dudley_Assemble_PDE: sample points of coefficient Y don't match (%d,%d)", p.numQuad,
198
elements->numElements);
199
Dudley_setError(TYPE_ERROR, error_msg);
202
/* check the dimensions: */
204
if (p.numEqu == 1 && p.numComp == 1)
208
dimensions[0] = p.numDim;
209
dimensions[1] = p.numDim;
210
if (!isDataPointShapeEqual(A, 2, dimensions))
212
sprintf(error_msg, "Dudley_Assemble_PDE: coefficient A: illegal shape, expected shape (%d,%d)",
213
dimensions[0], dimensions[1]);
214
Dudley_setError(TYPE_ERROR, error_msg);
219
dimensions[0] = p.numDim;
220
if (!isDataPointShapeEqual(B, 1, dimensions))
222
sprintf(error_msg, "Dudley_Assemble_PDE: coefficient B: illegal shape (%d,)", dimensions[0]);
223
Dudley_setError(TYPE_ERROR, error_msg);
228
dimensions[0] = p.numDim;
229
if (!isDataPointShapeEqual(C, 1, dimensions))
231
sprintf(error_msg, "Dudley_Assemble_PDE: coefficient C, expected shape (%d,)", dimensions[0]);
232
Dudley_setError(TYPE_ERROR, error_msg);
237
if (!isDataPointShapeEqual(D, 0, dimensions))
239
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_PDE: coefficient D, rank 0 expected.");
244
dimensions[0] = p.numDim;
245
if (!isDataPointShapeEqual(X, 1, dimensions))
247
sprintf(error_msg, "Dudley_Assemble_PDE: coefficient X, expected shape (%d,", dimensions[0]);
248
Dudley_setError(TYPE_ERROR, error_msg);
253
if (!isDataPointShapeEqual(Y, 0, dimensions))
255
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_PDE: coefficient Y, rank 0 expected.");
263
dimensions[0] = p.numEqu;
264
dimensions[1] = p.numDim;
265
dimensions[2] = p.numComp;
266
dimensions[3] = p.numDim;
267
if (!isDataPointShapeEqual(A, 4, dimensions))
269
sprintf(error_msg, "Dudley_Assemble_PDE: coefficient A, expected shape (%d,%d,%d,%d)", dimensions[0],
270
dimensions[1], dimensions[2], dimensions[3]);
271
Dudley_setError(TYPE_ERROR, error_msg);
276
dimensions[0] = p.numEqu;
277
dimensions[1] = p.numDim;
278
dimensions[2] = p.numComp;
279
if (!isDataPointShapeEqual(B, 3, dimensions))
281
sprintf(error_msg, "Dudley_Assemble_PDE: coefficient B, expected shape (%d,%d,%d)", dimensions[0],
282
dimensions[1], dimensions[2]);
283
Dudley_setError(TYPE_ERROR, error_msg);
288
dimensions[0] = p.numEqu;
289
dimensions[1] = p.numComp;
290
dimensions[2] = p.numDim;
291
if (!isDataPointShapeEqual(C, 3, dimensions))
293
sprintf(error_msg, "Dudley_Assemble_PDE: coefficient C, expected shape (%d,%d,%d)", dimensions[0],
294
dimensions[1], dimensions[2]);
295
Dudley_setError(TYPE_ERROR, error_msg);
300
dimensions[0] = p.numEqu;
301
dimensions[1] = p.numComp;
302
if (!isDataPointShapeEqual(D, 2, dimensions))
304
sprintf(error_msg, "Dudley_Assemble_PDE: coefficient D, expected shape (%d,%d)", dimensions[0],
306
Dudley_setError(TYPE_ERROR, error_msg);
311
dimensions[0] = p.numEqu;
312
dimensions[1] = p.numDim;
313
if (!isDataPointShapeEqual(X, 2, dimensions))
315
sprintf(error_msg, "Dudley_Assemble_PDE: coefficient X, expected shape (%d,%d)", dimensions[0],
317
Dudley_setError(TYPE_ERROR, error_msg);
322
dimensions[0] = p.numEqu;
323
if (!isDataPointShapeEqual(Y, 1, dimensions))
325
sprintf(error_msg, "Dudley_Assemble_PDE: coefficient Y, expected shape (%d,)", dimensions[0]);
326
Dudley_setError(TYPE_ERROR, error_msg);
330
if (Dudley_noError())
332
time0 = Dudley_timer();
333
if (p.numEqu == p.numComp)
337
/* system of PDESs */
340
Dudley_Assemble_PDE_System2_3D(p, elements, S, F, A, B, C, D, X, Y);
342
else if (p.numDim == 2)
344
Dudley_Assemble_PDE_System2_2D(p, elements, S, F, A, B, C, D, X, Y);
348
Dudley_setError(VALUE_ERROR, "Dudley_Assemble_PDE supports spatial dimensions 2 and 3 only.");
356
Dudley_Assemble_PDE_Single2_3D(p, elements, S, F, A, B, C, D, X, Y);
358
else if (p.numDim == 2)
360
Dudley_Assemble_PDE_Single2_2D(p, elements, S, F, A, B, C, D, X, Y);
364
Dudley_setError(VALUE_ERROR, "Dudley_Assemble_PDE supports spatial dimensions 2 and 3 only.");
370
Dudley_setError(VALUE_ERROR, "Dudley_Assemble_PDE requires number of equations == number of solutions .");
373
blocktimer_increment("Dudley_Assemble_PDE()", blocktimer_start);