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 mass matrix in lumped form */
18
/* The coefficient D has to be defined on the integration points or not present. */
20
/* lumpedMat has to be initialized before the routine is called. */
22
/**************************************************************/
30
#include "ShapeTable.h"
32
/* Disabled until the tests pass */
33
/* #define NEW_LUMPING */
35
/**************************************************************/
37
void Dudley_Assemble_LumpedSystem(Dudley_NodeFile * nodes, Dudley_ElementFile * elements, escriptDataC * lumpedMat,
41
bool_t reducedIntegrationOrder = FALSE, expandedD;
42
char error_msg[LenErrorMsg_MAX];
43
Dudley_Assemble_Parameters p;
44
dim_t dimensions[ESCRIPT_MAX_DATA_RANK], k, e, len_EM_lumpedMat, q, s;
46
index_t color, *row_index = NULL;
47
__const double *D_p = NULL;
48
const double *S = NULL;
49
double *EM_lumpedMat = NULL, *lumpedMat_p = NULL;
51
size_t len_EM_lumpedMat_size;
53
register double m_t = 0., diagS = 0.;
58
if (nodes == NULL || elements == NULL)
60
if (isEmpty(lumpedMat) || isEmpty(D))
62
if (isEmpty(lumpedMat) && !isEmpty(D))
64
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_LumpedSystem: coefficients are non-zero but no lumped matrix is given.");
67
funcspace = getFunctionSpaceType(D);
68
/* check if all function spaces are the same */
69
if (funcspace == DUDLEY_ELEMENTS)
71
reducedIntegrationOrder = FALSE;
73
else if (funcspace == DUDLEY_FACE_ELEMENTS)
75
reducedIntegrationOrder = FALSE;
77
else if (funcspace == DUDLEY_REDUCED_ELEMENTS)
79
reducedIntegrationOrder = TRUE;
81
else if (funcspace == DUDLEY_REDUCED_FACE_ELEMENTS)
83
reducedIntegrationOrder = TRUE;
87
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_LumpedSystem: assemblage failed because of illegal function space.");
89
if (!Dudley_noError())
92
/* set all parameters in p */
93
Dudley_Assemble_getAssembleParameters(nodes, elements, NULL, lumpedMat, reducedIntegrationOrder, &p);
94
if (!Dudley_noError())
97
/* check if all function spaces are the same */
98
if (!numSamplesEqual(D, p.numQuad, elements->numElements))
100
sprintf(error_msg, "Dudley_Assemble_LumpedSystem: sample points of coefficient D don't match (%d,%d)", p.numQuad,
101
elements->numElements);
102
Dudley_setError(TYPE_ERROR, error_msg);
105
/* check the dimensions: */
110
if (!isDataPointShapeEqual(D, 0, dimensions))
112
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_LumpedSystem: coefficient D, rank 0 expected.");
121
dimensions[0] = p.numEqu;
122
if (!isDataPointShapeEqual(D, 1, dimensions))
124
sprintf(error_msg, "Dudley_Assemble_LumpedSystem: coefficient D, expected shape (%d,)", dimensions[0]);
125
Dudley_setError(TYPE_ERROR, error_msg);
129
if (Dudley_noError())
131
requireWrite(lumpedMat);
132
lumpedMat_p = getSampleDataRW(lumpedMat, 0);
133
len_EM_lumpedMat = p.numShapes * p.numEqu;
134
len_EM_lumpedMat_size = len_EM_lumpedMat * sizeof(double);
136
expandedD = isExpanded(D);
137
if (!getQuadShape(elements->numDim, reducedIntegrationOrder, &S))
139
Dudley_setError(TYPE_ERROR, "Dudley_Assemble_LumpedSystem: Unable to locate shape function.");
142
#pragma omp parallel private(color, EM_lumpedMat, row_index, D_p, s, q, k, rtmp, diagS, m_t)
144
#pragma omp parallel private(color, EM_lumpedMat, row_index, D_p, s, q, k, rtmp)
147
EM_lumpedMat = THREAD_MEMALLOC(len_EM_lumpedMat, double);
148
row_index = THREAD_MEMALLOC(p.numShapes, index_t);
149
if (!Dudley_checkPtr(EM_lumpedMat) && !Dudley_checkPtr(row_index))
152
{ /* single equation */
154
{ /* with expanded D */
155
for (color = elements->minColor; color <= elements->maxColor; color++)
157
/* open loop over all elements: */
158
#pragma omp for private(e) schedule(static)
159
for (e = 0; e < elements->numElements; e++)
161
if (elements->Color[e] == color)
163
double vol = p.row_jac->absD[e] * p.row_jac->quadweight;
164
D_p = getSampleDataRO(D, e);
165
#ifdef NEW_LUMPING /* HRZ lumping */
166
m_t = 0; /* mass of the element: m_t */
167
for (q = 0; q < p.numQuad; q++)
168
m_t += vol * D_p[INDEX2(q, 0, p.numQuad)];
169
diagS = 0; /* diagonal sum: S */
170
for (s = 0; s < p.numShapes; s++)
173
for (q = 0; q < p.numQuad; q++)
175
vol * D_p[INDEX2(q, 0, p.numQuad)] * S[INDEX2(s, q, p.numShapes)] *
176
S[INDEX2(s, q, p.numShapes)];
177
EM_lumpedMat[INDEX2(0, s, p.numEqu)] = rtmp;
180
/* rescale diagonals by m_t/diagS to ensure consistent mass over element */
182
for (s = 0; s < p.numShapes; s++)
183
EM_lumpedMat[INDEX2(0, s, p.numEqu)] *= rtmp;
185
#else /* row-sum lumping */
186
for (s = 0; s < p.numShapes; s++)
189
for (q = 0; q < p.numQuad; q++)
190
rtmp += vol * S[INDEX2(s, q, p.numShapes)] * D_p[INDEX2(q, 0, p.numQuad)];
191
EM_lumpedMat[INDEX2(0, s, p.numEqu)] = rtmp;
194
for (q = 0; q < p.numShapes; q++)
196
row_index[q] = p.row_DOF[elements->Nodes[INDEX2(q, e, p.NN)]];
198
Dudley_Util_AddScatter(p.numShapes, row_index, p.numEqu, EM_lumpedMat, lumpedMat_p,
199
p.row_DOF_UpperBound);
200
} /* end color check */
201
} /* end element loop */
202
} /* end color loop */
205
{ /* with constant D */
207
for (color = elements->minColor; color <= elements->maxColor; color++)
209
/* open loop over all elements: */
210
#pragma omp for private(e) schedule(static)
211
for (e = 0; e < elements->numElements; e++)
213
if (elements->Color[e] == color)
215
double vol = p.row_jac->absD[e] * p.row_jac->quadweight;
216
D_p = getSampleDataRO(D, e);
217
#ifdef NEW_LUMPING /* HRZ lumping */
218
m_t = 0; /* mass of the element: m_t */
219
for (q = 0; q < p.numQuad; q++)
221
diagS = 0; /* diagonal sum: S */
222
for (s = 0; s < p.numShapes; s++)
225
for (q = 0; q < p.numQuad; q++)
227
rtmp += vol * S[INDEX2(s, q, p.numShapes)] * S[INDEX2(s, q, p.numShapes)];
229
EM_lumpedMat[INDEX2(0, s, p.numEqu)] = rtmp;
232
/* rescale diagonals by m_t/diagS to ensure consistent mass over element */
233
rtmp = m_t / diagS * D_p[0];
234
for (s = 0; s < p.numShapes; s++)
235
EM_lumpedMat[INDEX2(0, s, p.numEqu)] *= rtmp;
236
#else /* row-sum lumping */
237
for (s = 0; s < p.numShapes; s++)
240
for (q = 0; q < p.numQuad; q++)
241
rtmp += vol * S[INDEX2(s, q, p.numShapes)];
242
EM_lumpedMat[INDEX2(0, s, p.numEqu)] = rtmp * D_p[0];
245
for (q = 0; q < p.numShapes; q++)
246
row_index[q] = p.row_DOF[elements->Nodes[INDEX2(q, e, p.NN)]];
247
Dudley_Util_AddScatter(p.numShapes, row_index, p.numEqu, EM_lumpedMat, lumpedMat_p,
248
p.row_DOF_UpperBound);
249
} /* end color check */
250
} /* end element loop */
251
} /* end color loop */
256
{ /* system of equation */
258
{ /* with expanded D */
259
for (color = elements->minColor; color <= elements->maxColor; color++)
261
/* open loop over all elements: */
262
#pragma omp for private(e) schedule(static)
263
for (e = 0; e < elements->numElements; e++)
265
if (elements->Color[e] == color)
267
double vol = p.row_jac->absD[e] * p.row_jac->quadweight;
268
D_p = getSampleDataRO(D, e);
270
#ifdef NEW_LUMPING /* HRZ lumping */
271
for (k = 0; k < p.numEqu; k++)
273
m_t = 0; /* mass of the element: m_t */
274
for (q = 0; q < p.numQuad; q++)
275
m_t += vol * D_p[INDEX3(k, q, 0, p.numEqu, p.numQuad)];
277
diagS = 0; /* diagonal sum: S */
278
for (s = 0; s < p.numShapes; s++)
281
for (q = 0; q < p.numQuad; q++)
283
vol * D_p[INDEX3(k, q, 0, p.numEqu, p.numQuad)] *
284
S[INDEX2(s, q, p.numShapes)] * S[INDEX2(s, q, p.numShapes)];
285
EM_lumpedMat[INDEX2(k, s, p.numEqu)] = rtmp;
288
/* rescale diagonals by m_t/diagS to ensure consistent mass over element */
290
for (s = 0; s < p.numShapes; s++)
291
EM_lumpedMat[INDEX2(k, s, p.numEqu)] *= rtmp;
293
#else /* row-sum lumping */
294
for (s = 0; s < p.numShapes; s++)
296
for (k = 0; k < p.numEqu; k++)
299
for (q = 0; q < p.numQuad; q++)
301
vol * S[INDEX2(s, q, p.numShapes)] *
302
D_p[INDEX3(k, q, 0, p.numEqu, p.numQuad)];
303
EM_lumpedMat[INDEX2(k, s, p.numEqu)] = rtmp;
307
for (q = 0; q < p.numShapes; q++)
308
row_index[q] = p.row_DOF[elements->Nodes[INDEX2(q, e, p.NN)]];
309
Dudley_Util_AddScatter(p.numShapes, row_index, p.numEqu, EM_lumpedMat, lumpedMat_p,
310
p.row_DOF_UpperBound);
311
} /* end color check */
312
} /* end element loop */
313
} /* end color loop */
316
{ /* with constant D */
317
for (color = elements->minColor; color <= elements->maxColor; color++)
319
/* open loop over all elements: */
320
#pragma omp for private(e) schedule(static)
321
for (e = 0; e < elements->numElements; e++)
323
if (elements->Color[e] == color)
325
double vol = p.row_jac->absD[e] * p.row_jac->quadweight;
326
D_p = getSampleDataRO(D, e);
328
#ifdef NEW_LUMPING /* HRZ lumping */
329
m_t = 0; /* mass of the element: m_t */
330
for (q = 0; q < p.numQuad; q++)
332
diagS = 0; /* diagonal sum: S */
333
for (s = 0; s < p.numShapes; s++)
336
for (q = 0; q < p.numQuad; q++)
337
rtmp += vol * S[INDEX2(s, q, p.numShapes)] * S[INDEX2(s, q, p.numShapes)];
338
for (k = 0; k < p.numEqu; k++)
339
EM_lumpedMat[INDEX2(k, s, p.numEqu)] = rtmp;
342
/* rescale diagonals by m_t/diagS to ensure consistent mass over element */
344
for (s = 0; s < p.numShapes; s++)
346
for (k = 0; k < p.numEqu; k++)
347
EM_lumpedMat[INDEX2(k, s, p.numEqu)] *= rtmp * D_p[k];
349
#else /* row-sum lumping */
350
for (s = 0; s < p.numShapes; s++)
352
for (k = 0; k < p.numEqu; k++)
355
for (q = 0; q < p.numQuad; q++)
356
rtmp += vol * S[INDEX2(s, q, p.numShapes)];
357
EM_lumpedMat[INDEX2(k, s, p.numEqu)] = rtmp * D_p[k];
361
for (q = 0; q < p.numShapes; q++)
362
row_index[q] = p.row_DOF[elements->Nodes[INDEX2(q, e, p.NN)]];
363
Dudley_Util_AddScatter(p.numShapes, row_index, p.numEqu, EM_lumpedMat, lumpedMat_p,
364
p.row_DOF_UpperBound);
365
} /* end color check */
366
} /* end element loop */
367
} /* end color loop */
370
} /* end of pointer check */
371
THREAD_MEMFREE(EM_lumpedMat);
372
THREAD_MEMFREE(row_index);
373
} /* end parallel region */