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
*******************************************************/
15
#include "MeshAdapter.h"
16
#include "escript/Data.h"
17
#include "escript/DataFactory.h"
19
#include <netcdfcpp.h>
22
#include "esysUtils/Esys_MPI.h"
25
#include "esysUtils/blocktimer.h"
29
using namespace escript;
34
// define the static constants
35
MeshAdapter::FunctionSpaceNamesMapType MeshAdapter::m_functionSpaceTypeNames;
36
const int MeshAdapter::DegreesOfFreedom=DUDLEY_DEGREES_OF_FREEDOM;
37
const int MeshAdapter::ReducedDegreesOfFreedom=DUDLEY_REDUCED_DEGREES_OF_FREEDOM;
38
const int MeshAdapter::Nodes=DUDLEY_NODES;
39
const int MeshAdapter::ReducedNodes=DUDLEY_REDUCED_NODES;
40
const int MeshAdapter::Elements=DUDLEY_ELEMENTS;
41
const int MeshAdapter::ReducedElements=DUDLEY_REDUCED_ELEMENTS;
42
const int MeshAdapter::FaceElements=DUDLEY_FACE_ELEMENTS;
43
const int MeshAdapter::ReducedFaceElements=DUDLEY_REDUCED_FACE_ELEMENTS;
44
const int MeshAdapter::Points=DUDLEY_POINTS;
46
MeshAdapter::MeshAdapter(Dudley_Mesh* dudleyMesh)
48
setFunctionSpaceTypeNames();
50
// need to use a null_deleter as Dudley_Mesh_free deletes the pointer
52
m_dudleyMesh.reset(dudleyMesh,null_deleter());
56
// The copy constructor should just increment the use count
57
MeshAdapter::MeshAdapter(const MeshAdapter& in):
58
m_dudleyMesh(in.m_dudleyMesh)
60
setFunctionSpaceTypeNames();
63
MeshAdapter::~MeshAdapter()
66
// I hope the case for the pointer being zero has been taken care of.
67
// cout << "In MeshAdapter destructor." << endl;
68
if (m_dudleyMesh.unique()) {
69
Dudley_Mesh_free(m_dudleyMesh.get());
73
int MeshAdapter::getMPISize() const
75
return m_dudleyMesh.get()->MPIInfo->size;
77
int MeshAdapter::getMPIRank() const
79
return m_dudleyMesh.get()->MPIInfo->rank;
81
void MeshAdapter::MPIBarrier() const
84
MPI_Barrier(m_dudleyMesh.get()->MPIInfo->comm);
88
bool MeshAdapter::onMasterProcessor() const
90
return m_dudleyMesh.get()->MPIInfo->rank == 0;
99
MeshAdapter::getMPIComm() const
102
return m_dudleyMesh->MPIInfo->comm;
109
Dudley_Mesh* MeshAdapter::getDudley_Mesh() const {
110
return m_dudleyMesh.get();
113
void MeshAdapter::write(const string& fileName) const
115
char *fName = (fileName.size()+1>0) ? TMPMEMALLOC(fileName.size()+1,char) : (char*)NULL;
116
strcpy(fName,fileName.c_str());
117
Dudley_Mesh_write(m_dudleyMesh.get(),fName);
122
void MeshAdapter::Print_Mesh_Info(const bool full) const
124
Dudley_PrintMesh_Info(m_dudleyMesh.get(), full);
127
void MeshAdapter::dump(const string& fileName) const
130
const NcDim* ncdims[12] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
133
Dudley_Mesh *mesh = m_dudleyMesh.get();
134
Dudley_TagMap* tag_map;
136
int mpi_size = mesh->MPIInfo->size;
137
int mpi_rank = mesh->MPIInfo->rank;
138
int numDim = mesh->Nodes->numDim;
139
int numNodes = mesh->Nodes->numNodes;
140
int num_Elements = mesh->Elements->numElements;
141
int num_FaceElements = mesh->FaceElements->numElements;
142
int num_Points = mesh->Points->numElements;
143
int num_Elements_numNodes = mesh->Elements->numNodes;
144
int num_FaceElements_numNodes = mesh->FaceElements->numNodes;
149
/* Incoming token indicates it's my turn to write */
151
if (mpi_rank>0) MPI_Recv(&num_Tags, 0, MPI_INT, mpi_rank-1, 81800, mesh->MPIInfo->comm, &status);
154
char *newFileName = Esys_MPI_appendRankToFileName(fileName.c_str(),
157
/* Figure out how much storage is required for tags */
158
tag_map = mesh->TagMap;
162
tag_map=tag_map->next;
165
// NetCDF error handler
166
NcError err(NcError::verbose_nonfatal);
168
NcFile dataFile(newFileName, NcFile::Replace);
169
string msgPrefix("Error in MeshAdapter::dump: NetCDF operation failed - ");
170
// check if writing was successful
171
if (!dataFile.is_valid())
172
throw DataException(msgPrefix+"Open file for output");
174
// Define dimensions (num_Elements and dim_Elements are identical,
175
// dim_Elements only appears if > 0)
176
if (! (ncdims[0] = dataFile.add_dim("numNodes", numNodes)) )
177
throw DataException(msgPrefix+"add_dim(numNodes)");
178
if (! (ncdims[1] = dataFile.add_dim("numDim", numDim)) )
179
throw DataException(msgPrefix+"add_dim(numDim)");
180
if (! (ncdims[2] = dataFile.add_dim("mpi_size_plus_1", mpi_size+1)) )
181
throw DataException(msgPrefix+"add_dim(mpi_size)");
183
if (! (ncdims[3] = dataFile.add_dim("dim_Elements", num_Elements)) )
184
throw DataException(msgPrefix+"add_dim(dim_Elements)");
185
if (num_FaceElements>0)
186
if (! (ncdims[4] = dataFile.add_dim("dim_FaceElements", num_FaceElements)) )
187
throw DataException(msgPrefix+"add_dim(dim_FaceElements)");
189
if (! (ncdims[6] = dataFile.add_dim("dim_Points", num_Points)) )
190
throw DataException(msgPrefix+"add_dim(dim_Points)");
192
if (! (ncdims[7] = dataFile.add_dim("dim_Elements_Nodes", num_Elements_numNodes)) )
193
throw DataException(msgPrefix+"add_dim(dim_Elements_Nodes)");
194
if (num_FaceElements>0)
195
if (! (ncdims[8] = dataFile.add_dim("dim_FaceElements_numNodes", num_FaceElements_numNodes)) )
196
throw DataException(msgPrefix+"add_dim(dim_FaceElements_numNodes)");
198
if (! (ncdims[10] = dataFile.add_dim("dim_Tags", num_Tags)) )
199
throw DataException(msgPrefix+"add_dim(dim_Tags)");
201
// Attributes: MPI size, MPI rank, Name, order, reduced_order
202
if (!dataFile.add_att("mpi_size", mpi_size) )
203
throw DataException(msgPrefix+"add_att(mpi_size)");
204
if (!dataFile.add_att("mpi_rank", mpi_rank) )
205
throw DataException(msgPrefix+"add_att(mpi_rank)");
206
if (!dataFile.add_att("Name",mesh->Name) )
207
throw DataException(msgPrefix+"add_att(Name)");
208
if (!dataFile.add_att("numDim",numDim) )
209
throw DataException(msgPrefix+"add_att(order)");
210
if (!dataFile.add_att("order",mesh->integrationOrder) )
211
throw DataException(msgPrefix+"add_att(order)");
212
if (!dataFile.add_att("reduced_order",mesh->reducedIntegrationOrder) )
213
throw DataException(msgPrefix+"add_att(reduced_order)");
214
if (!dataFile.add_att("numNodes",numNodes) )
215
throw DataException(msgPrefix+"add_att(numNodes)");
216
if (!dataFile.add_att("num_Elements",num_Elements) )
217
throw DataException(msgPrefix+"add_att(num_Elements)");
218
if (!dataFile.add_att("num_FaceElements",num_FaceElements) )
219
throw DataException(msgPrefix+"add_att(num_FaceElements)");
220
if (!dataFile.add_att("num_Points",num_Points) )
221
throw DataException(msgPrefix+"add_att(num_Points)");
222
if (!dataFile.add_att("num_Elements_numNodes",num_Elements_numNodes) )
223
throw DataException(msgPrefix+"add_att(num_Elements_numNodes)");
224
if (!dataFile.add_att("num_FaceElements_numNodes",num_FaceElements_numNodes) )
225
throw DataException(msgPrefix+"add_att(num_FaceElements_numNodes)");
226
if (!dataFile.add_att("Elements_TypeId", mesh->Elements->etype) )
227
throw DataException(msgPrefix+"add_att(Elements_TypeId)");
228
if (!dataFile.add_att("FaceElements_TypeId", mesh->FaceElements->etype) )
229
throw DataException(msgPrefix+"add_att(FaceElements_TypeId)");
230
if (!dataFile.add_att("Points_TypeId", mesh->Points->etype) )
231
throw DataException(msgPrefix+"add_att(Points_TypeId)");
232
if (!dataFile.add_att("num_Tags", num_Tags) )
233
throw DataException(msgPrefix+"add_att(num_Tags)");
235
// // // // // Nodes // // // // //
237
// Nodes nodeDistribution
238
if (! ( ids = dataFile.add_var("Nodes_NodeDistribution", ncInt, ncdims[2])) )
239
throw DataException(msgPrefix+"add_var(Nodes_NodeDistribution)");
240
int_ptr = &mesh->Nodes->nodesDistribution->first_component[0];
241
if (! (ids->put(int_ptr, mpi_size+1)) )
242
throw DataException(msgPrefix+"put(Nodes_NodeDistribution)");
244
// Nodes degreesOfFreedomDistribution
245
if (! ( ids = dataFile.add_var("Nodes_DofDistribution", ncInt, ncdims[2])) )
246
throw DataException(msgPrefix+"add_var(Nodes_DofDistribution)");
247
int_ptr = &mesh->Nodes->degreesOfFreedomDistribution->first_component[0];
248
if (! (ids->put(int_ptr, mpi_size+1)) )
249
throw DataException(msgPrefix+"put(Nodes_DofDistribution)");
251
// Only write nodes if non-empty because NetCDF doesn't like empty arrays
252
// (it treats them as NC_UNLIMITED)
256
if (! ( ids = dataFile.add_var("Nodes_Id", ncInt, ncdims[0])) )
257
throw DataException(msgPrefix+"add_var(Nodes_Id)");
258
int_ptr = &mesh->Nodes->Id[0];
259
if (! (ids->put(int_ptr, numNodes)) )
260
throw DataException(msgPrefix+"put(Nodes_Id)");
263
if (! ( ids = dataFile.add_var("Nodes_Tag", ncInt, ncdims[0])) )
264
throw DataException(msgPrefix+"add_var(Nodes_Tag)");
265
int_ptr = &mesh->Nodes->Tag[0];
266
if (! (ids->put(int_ptr, numNodes)) )
267
throw DataException(msgPrefix+"put(Nodes_Tag)");
270
if (! ( ids = dataFile.add_var("Nodes_gDOF", ncInt, ncdims[0])) )
271
throw DataException(msgPrefix+"add_var(Nodes_gDOF)");
272
int_ptr = &mesh->Nodes->globalDegreesOfFreedom[0];
273
if (! (ids->put(int_ptr, numNodes)) )
274
throw DataException(msgPrefix+"put(Nodes_gDOF)");
276
// Nodes global node index
277
if (! ( ids = dataFile.add_var("Nodes_gNI", ncInt, ncdims[0])) )
278
throw DataException(msgPrefix+"add_var(Nodes_gNI)");
279
int_ptr = &mesh->Nodes->globalNodesIndex[0];
280
if (! (ids->put(int_ptr, numNodes)) )
281
throw DataException(msgPrefix+"put(Nodes_gNI)");
284
if (! ( ids = dataFile.add_var("Nodes_grDfI", ncInt, ncdims[0])) )
285
throw DataException(msgPrefix+"add_var(Nodes_grDfI)");
286
int_ptr = &mesh->Nodes->globalReducedDOFIndex[0];
287
if (! (ids->put(int_ptr, numNodes)) )
288
throw DataException(msgPrefix+"put(Nodes_grDfI)");
291
if (! ( ids = dataFile.add_var("Nodes_grNI", ncInt, ncdims[0])) )
292
throw DataException(msgPrefix+"add_var(Nodes_grNI)");
293
int_ptr = &mesh->Nodes->globalReducedNodesIndex[0];
294
if (! (ids->put(int_ptr, numNodes)) )
295
throw DataException(msgPrefix+"put(Nodes_grNI)");
298
if (! ( ids = dataFile.add_var("Nodes_Coordinates", ncDouble, ncdims[0], ncdims[1]) ) )
299
throw DataException(msgPrefix+"add_var(Nodes_Coordinates)");
300
if (! (ids->put(&(mesh->Nodes->Coordinates[INDEX2(0,0,numDim)]), numNodes, numDim)) )
301
throw DataException(msgPrefix+"put(Nodes_Coordinates)");
305
// // // // // Elements // // // // //
307
if (num_Elements>0) {
310
if (! ( ids = dataFile.add_var("Elements_Id", ncInt, ncdims[3])) )
311
throw DataException(msgPrefix+"add_var(Elements_Id)");
312
int_ptr = &mesh->Elements->Id[0];
313
if (! (ids->put(int_ptr, num_Elements)) )
314
throw DataException(msgPrefix+"put(Elements_Id)");
317
if (! ( ids = dataFile.add_var("Elements_Tag", ncInt, ncdims[3])) )
318
throw DataException(msgPrefix+"add_var(Elements_Tag)");
319
int_ptr = &mesh->Elements->Tag[0];
320
if (! (ids->put(int_ptr, num_Elements)) )
321
throw DataException(msgPrefix+"put(Elements_Tag)");
324
if (! ( ids = dataFile.add_var("Elements_Owner", ncInt, ncdims[3])) )
325
throw DataException(msgPrefix+"add_var(Elements_Owner)");
326
int_ptr = &mesh->Elements->Owner[0];
327
if (! (ids->put(int_ptr, num_Elements)) )
328
throw DataException(msgPrefix+"put(Elements_Owner)");
331
if (! ( ids = dataFile.add_var("Elements_Color", ncInt, ncdims[3])) )
332
throw DataException(msgPrefix+"add_var(Elements_Color)");
333
int_ptr = &mesh->Elements->Color[0];
334
if (! (ids->put(int_ptr, num_Elements)) )
335
throw DataException(msgPrefix+"put(Elements_Color)");
338
if (! ( ids = dataFile.add_var("Elements_Nodes", ncInt, ncdims[3], ncdims[7]) ) )
339
throw DataException(msgPrefix+"add_var(Elements_Nodes)");
340
if (! (ids->put(&(mesh->Elements->Nodes[0]), num_Elements, num_Elements_numNodes)) )
341
throw DataException(msgPrefix+"put(Elements_Nodes)");
345
// // // // // Face_Elements // // // // //
347
if (num_FaceElements>0) {
350
if (! ( ids = dataFile.add_var("FaceElements_Id", ncInt, ncdims[4])) )
351
throw DataException(msgPrefix+"add_var(FaceElements_Id)");
352
int_ptr = &mesh->FaceElements->Id[0];
353
if (! (ids->put(int_ptr, num_FaceElements)) )
354
throw DataException(msgPrefix+"put(FaceElements_Id)");
357
if (! ( ids = dataFile.add_var("FaceElements_Tag", ncInt, ncdims[4])) )
358
throw DataException(msgPrefix+"add_var(FaceElements_Tag)");
359
int_ptr = &mesh->FaceElements->Tag[0];
360
if (! (ids->put(int_ptr, num_FaceElements)) )
361
throw DataException(msgPrefix+"put(FaceElements_Tag)");
363
// FaceElements_Owner
364
if (! ( ids = dataFile.add_var("FaceElements_Owner", ncInt, ncdims[4])) )
365
throw DataException(msgPrefix+"add_var(FaceElements_Owner)");
366
int_ptr = &mesh->FaceElements->Owner[0];
367
if (! (ids->put(int_ptr, num_FaceElements)) )
368
throw DataException(msgPrefix+"put(FaceElements_Owner)");
370
// FaceElements_Color
371
if (! ( ids = dataFile.add_var("FaceElements_Color", ncInt, ncdims[4])) )
372
throw DataException(msgPrefix+"add_var(FaceElements_Color)");
373
int_ptr = &mesh->FaceElements->Color[0];
374
if (! (ids->put(int_ptr, num_FaceElements)) )
375
throw DataException(msgPrefix+"put(FaceElements_Color)");
377
// FaceElements_Nodes
378
if (! ( ids = dataFile.add_var("FaceElements_Nodes", ncInt, ncdims[4], ncdims[8]) ) )
379
throw DataException(msgPrefix+"add_var(FaceElements_Nodes)");
380
if (! (ids->put(&(mesh->FaceElements->Nodes[0]), num_FaceElements, num_FaceElements_numNodes)) )
381
throw DataException(msgPrefix+"put(FaceElements_Nodes)");
385
// // // // // Points // // // // //
389
fprintf(stderr, "\n\n\nWARNING: MeshAdapter::dump has not been tested with Point elements\n\n\n");
392
if (! ( ids = dataFile.add_var("Points_Id", ncInt, ncdims[6])) )
393
throw DataException(msgPrefix+"add_var(Points_Id)");
394
int_ptr = &mesh->Points->Id[0];
395
if (! (ids->put(int_ptr, num_Points)) )
396
throw DataException(msgPrefix+"put(Points_Id)");
399
if (! ( ids = dataFile.add_var("Points_Tag", ncInt, ncdims[6])) )
400
throw DataException(msgPrefix+"add_var(Points_Tag)");
401
int_ptr = &mesh->Points->Tag[0];
402
if (! (ids->put(int_ptr, num_Points)) )
403
throw DataException(msgPrefix+"put(Points_Tag)");
406
if (! ( ids = dataFile.add_var("Points_Owner", ncInt, ncdims[6])) )
407
throw DataException(msgPrefix+"add_var(Points_Owner)");
408
int_ptr = &mesh->Points->Owner[0];
409
if (! (ids->put(int_ptr, num_Points)) )
410
throw DataException(msgPrefix+"put(Points_Owner)");
413
if (! ( ids = dataFile.add_var("Points_Color", ncInt, ncdims[6])) )
414
throw DataException(msgPrefix+"add_var(Points_Color)");
415
int_ptr = &mesh->Points->Color[0];
416
if (! (ids->put(int_ptr, num_Points)) )
417
throw DataException(msgPrefix+"put(Points_Color)");
420
// mesh->Nodes->Id[mesh->Points->Nodes[INDEX2(0,i,1)]]
421
if (! ( ids = dataFile.add_var("Points_Nodes", ncInt, ncdims[6]) ) )
422
throw DataException(msgPrefix+"add_var(Points_Nodes)");
423
if (! (ids->put(&(mesh->Points->Nodes[0]), num_Points)) )
424
throw DataException(msgPrefix+"put(Points_Nodes)");
428
// // // // // TagMap // // // // //
432
// Temp storage to gather node IDs
433
int *Tags_keys = TMPMEMALLOC(num_Tags, int);
434
char name_temp[4096];
436
/* Copy tag data into temp arrays */
437
tag_map = mesh->TagMap;
441
Tags_keys[i++] = tag_map->tag_key;
442
tag_map=tag_map->next;
447
if (! ( ids = dataFile.add_var("Tags_keys", ncInt, ncdims[10])) )
448
throw DataException(msgPrefix+"add_var(Tags_keys)");
449
int_ptr = &Tags_keys[0];
450
if (! (ids->put(int_ptr, num_Tags)) )
451
throw DataException(msgPrefix+"put(Tags_keys)");
454
// This is an array of strings, it should be stored as an array but
455
// instead I have hacked in one attribute per string because the NetCDF
456
// manual doesn't tell how to do an array of strings
457
tag_map = mesh->TagMap;
461
sprintf(name_temp, "Tags_name_%d", i);
462
if (!dataFile.add_att(name_temp, tag_map->name) )
463
throw DataException(msgPrefix+"add_att(Tags_names_XX)");
464
tag_map=tag_map->next;
469
TMPMEMFREE(Tags_keys);
472
/* Send token to next MPI process so he can take his turn */
474
if (mpi_rank<mpi_size-1) MPI_Send(&num_Tags, 0, MPI_INT, mpi_rank+1, 81800, mesh->MPIInfo->comm);
477
// NetCDF file is closed by destructor of NcFile object
480
Dudley_setError(IO_ERROR, "MeshAdapter::dump: not configured with NetCDF. Please contact your installation manager.");
481
#endif /* USE_NETCDF */
485
string MeshAdapter::getDescription() const
490
string MeshAdapter::functionSpaceTypeAsString(int functionSpaceType) const
492
FunctionSpaceNamesMapType::iterator loc;
493
loc=m_functionSpaceTypeNames.find(functionSpaceType);
494
if (loc==m_functionSpaceTypeNames.end()) {
495
return "Invalid function space type code.";
501
bool MeshAdapter::isValidFunctionSpaceType(int functionSpaceType) const
503
FunctionSpaceNamesMapType::iterator loc;
504
loc=m_functionSpaceTypeNames.find(functionSpaceType);
505
return (loc!=m_functionSpaceTypeNames.end());
508
void MeshAdapter::setFunctionSpaceTypeNames()
510
m_functionSpaceTypeNames.insert
511
(FunctionSpaceNamesMapType::value_type(DegreesOfFreedom,"Dudley_DegreesOfFreedom"));
512
m_functionSpaceTypeNames.insert
513
(FunctionSpaceNamesMapType::value_type(ReducedDegreesOfFreedom,"Dudley_ReducedDegreesOfFreedom"));
514
m_functionSpaceTypeNames.insert
515
(FunctionSpaceNamesMapType::value_type(Nodes,"Dudley_Nodes"));
516
m_functionSpaceTypeNames.insert
517
(FunctionSpaceNamesMapType::value_type(ReducedNodes,"Dudley_Reduced_Nodes"));
518
m_functionSpaceTypeNames.insert
519
(FunctionSpaceNamesMapType::value_type(Elements,"Dudley_Elements"));
520
m_functionSpaceTypeNames.insert
521
(FunctionSpaceNamesMapType::value_type(ReducedElements,"Dudley_Reduced_Elements"));
522
m_functionSpaceTypeNames.insert
523
(FunctionSpaceNamesMapType::value_type(FaceElements,"Dudley_Face_Elements"));
524
m_functionSpaceTypeNames.insert
525
(FunctionSpaceNamesMapType::value_type(ReducedFaceElements,"Dudley_Reduced_Face_Elements"));
526
m_functionSpaceTypeNames.insert
527
(FunctionSpaceNamesMapType::value_type(Points,"Dudley_Points"));
530
int MeshAdapter::getContinuousFunctionCode() const
534
int MeshAdapter::getReducedContinuousFunctionCode() const
539
int MeshAdapter::getFunctionCode() const
543
int MeshAdapter::getReducedFunctionCode() const
545
return ReducedElements;
548
int MeshAdapter::getFunctionOnBoundaryCode() const
552
int MeshAdapter::getReducedFunctionOnBoundaryCode() const
554
return ReducedFaceElements;
557
int MeshAdapter::getFunctionOnContactZeroCode() const
559
throw DudleyAdapterException("Dudley does not support contact elements.");
562
int MeshAdapter::getReducedFunctionOnContactZeroCode() const
564
throw DudleyAdapterException("Dudley does not support contact elements.");
567
int MeshAdapter::getFunctionOnContactOneCode() const
569
throw DudleyAdapterException("Dudley does not support contact elements.");
572
int MeshAdapter::getReducedFunctionOnContactOneCode() const
574
throw DudleyAdapterException("Dudley does not support contact elements.");
577
int MeshAdapter::getSolutionCode() const
579
return DegreesOfFreedom;
582
int MeshAdapter::getReducedSolutionCode() const
584
return ReducedDegreesOfFreedom;
587
int MeshAdapter::getDiracDeltaFunctionCode() const
593
// return the spatial dimension of the Mesh:
595
int MeshAdapter::getDim() const
597
Dudley_Mesh* mesh=m_dudleyMesh.get();
598
int numDim=Dudley_Mesh_getDim(mesh);
604
// Return the number of data points summed across all MPI processes
606
int MeshAdapter::getNumDataPointsGlobal() const
608
return Dudley_NodeFile_getGlobalNumNodes(m_dudleyMesh.get()->Nodes);
612
// return the number of data points per sample and the number of samples
613
// needed to represent data on a parts of the mesh.
615
pair<int,int> MeshAdapter::getDataShape(int functionSpaceCode) const
617
int numDataPointsPerSample=0;
619
Dudley_Mesh* mesh=m_dudleyMesh.get();
620
switch (functionSpaceCode) {
622
numDataPointsPerSample=1;
623
numSamples=Dudley_NodeFile_getNumNodes(mesh->Nodes);
626
numDataPointsPerSample=1;
627
numSamples=Dudley_NodeFile_getNumReducedNodes(mesh->Nodes);
630
if (mesh->Elements!=NULL) {
631
numSamples=mesh->Elements->numElements;
632
numDataPointsPerSample=mesh->Elements->numLocalDim+1/*referenceElementSet->referenceElement->BasisFunctions->numQuadNodes*/;
635
case(ReducedElements):
636
if (mesh->Elements!=NULL) {
637
numSamples=mesh->Elements->numElements;
638
numDataPointsPerSample=(mesh->Elements->numLocalDim==0)?0:1;
642
if (mesh->FaceElements!=NULL) {
643
numDataPointsPerSample=mesh->FaceElements->numLocalDim+1/*referenceElementSet->referenceElement->BasisFunctions->numQuadNodes*/;
644
numSamples=mesh->FaceElements->numElements;
647
case(ReducedFaceElements):
648
if (mesh->FaceElements!=NULL) {
649
numDataPointsPerSample=(mesh->FaceElements->numLocalDim==0)?0:1/*referenceElementSet->referenceElementReducedQuadrature->BasisFunctions->numQuadNodes*/;
650
numSamples=mesh->FaceElements->numElements;
654
if (mesh->Points!=NULL) {
655
numDataPointsPerSample=1;
656
numSamples=mesh->Points->numElements;
659
case(DegreesOfFreedom):
660
if (mesh->Nodes!=NULL) {
661
numDataPointsPerSample=1;
662
numSamples=Dudley_NodeFile_getNumDegreesOfFreedom(mesh->Nodes);
665
case(ReducedDegreesOfFreedom):
666
if (mesh->Nodes!=NULL) {
667
numDataPointsPerSample=1;
668
numSamples=Dudley_NodeFile_getNumReducedDegreesOfFreedom(mesh->Nodes);
673
temp << "Error - Invalid function space type: " << functionSpaceCode << " for domain: " << getDescription();
674
throw DudleyAdapterException(temp.str());
677
return pair<int,int>(numDataPointsPerSample,numSamples);
681
// adds linear PDE of second order into a given stiffness matrix and right hand side:
683
void MeshAdapter::addPDEToSystem(
684
SystemMatrixAdapter& mat, escript::Data& rhs,
685
const escript::Data& A, const escript::Data& B, const escript::Data& C,const escript::Data& D,const escript::Data& X,const escript::Data& Y,
686
const escript::Data& d, const escript::Data& y) const
688
escriptDataC _rhs=rhs.getDataC();
689
escriptDataC _A =A.getDataC();
690
escriptDataC _B=B.getDataC();
691
escriptDataC _C=C.getDataC();
692
escriptDataC _D=D.getDataC();
693
escriptDataC _X=X.getDataC();
694
escriptDataC _Y=Y.getDataC();
695
escriptDataC _d=d.getDataC();
696
escriptDataC _y=y.getDataC();
698
Dudley_Mesh* mesh=m_dudleyMesh.get();
700
Dudley_Assemble_PDE(mesh->Nodes,mesh->Elements,mat.getPaso_SystemMatrix(), &_rhs, &_A, &_B, &_C, &_D, &_X, &_Y );
704
Dudley_Assemble_PDE(mesh->Nodes,mesh->FaceElements, mat.getPaso_SystemMatrix(), &_rhs, 0, 0, 0, &_d, 0, &_y );
711
void MeshAdapter::addPDEToLumpedSystem(
713
const escript::Data& D,
714
const escript::Data& d) const
716
escriptDataC _mat=mat.getDataC();
717
escriptDataC _D=D.getDataC();
718
escriptDataC _d=d.getDataC();
720
Dudley_Mesh* mesh=m_dudleyMesh.get();
722
Dudley_Assemble_LumpedSystem(mesh->Nodes,mesh->Elements,&_mat, &_D);
725
Dudley_Assemble_LumpedSystem(mesh->Nodes,mesh->FaceElements,&_mat, &_d);
732
// adds linear PDE of second order into the right hand side only
734
void MeshAdapter::addPDEToRHS( escript::Data& rhs, const escript::Data& X,const escript::Data& Y, const escript::Data& y) const
736
Dudley_Mesh* mesh=m_dudleyMesh.get();
738
escriptDataC _rhs=rhs.getDataC();
739
escriptDataC _X=X.getDataC();
740
escriptDataC _Y=Y.getDataC();
741
escriptDataC _y=y.getDataC();
743
Dudley_Assemble_PDE(mesh->Nodes,mesh->Elements, 0, &_rhs, 0, 0, 0, 0, &_X, &_Y );
746
Dudley_Assemble_PDE(mesh->Nodes,mesh->FaceElements, 0, &_rhs, 0, 0, 0, 0, 0, &_y );
752
// adds PDE of second order into a transport problem
754
void MeshAdapter::addPDEToTransportProblem(
755
TransportProblemAdapter& tp, escript::Data& source, const escript::Data& M,
756
const escript::Data& A, const escript::Data& B, const escript::Data& C,
757
const escript::Data& D,const escript::Data& X,const escript::Data& Y,
758
const escript::Data& d, const escript::Data& y,
759
const escript::Data& d_contact,const escript::Data& y_contact) const
761
DataTypes::ShapeType shape;
763
escriptDataC _source=source.getDataC();
764
escriptDataC _M=M.getDataC();
765
escriptDataC _A=A.getDataC();
766
escriptDataC _B=B.getDataC();
767
escriptDataC _C=C.getDataC();
768
escriptDataC _D=D.getDataC();
769
escriptDataC _X=X.getDataC();
770
escriptDataC _Y=Y.getDataC();
771
escriptDataC _d=d.getDataC();
772
escriptDataC _y=y.getDataC();
773
escriptDataC _d_contact=d_contact.getDataC();
774
escriptDataC _y_contact=y_contact.getDataC();
776
Dudley_Mesh* mesh=m_dudleyMesh.get();
777
Paso_TransportProblem* _tp = tp.getPaso_TransportProblem();
779
Dudley_Assemble_PDE(mesh->Nodes,mesh->Elements,_tp->mass_matrix, &_source, 0, 0, 0, &_M, 0, 0 );
782
Dudley_Assemble_PDE(mesh->Nodes,mesh->Elements,_tp->transport_matrix, &_source, &_A, &_B, &_C, &_D, &_X, &_Y );
785
Dudley_Assemble_PDE(mesh->Nodes,mesh->FaceElements, _tp->transport_matrix, &_source, 0, 0, 0, &_d, 0, &_y );
792
// interpolates data between different function spaces:
794
void MeshAdapter::interpolateOnDomain(escript::Data& target,const escript::Data& in) const
796
const MeshAdapter& inDomain=dynamic_cast<const MeshAdapter&>(*(in.getFunctionSpace().getDomain()));
797
const MeshAdapter& targetDomain=dynamic_cast<const MeshAdapter&>(*(target.getFunctionSpace().getDomain()));
799
throw DudleyAdapterException("Error - Illegal domain of interpolant.");
800
if (targetDomain!=*this)
801
throw DudleyAdapterException("Error - Illegal domain of interpolation target.");
803
Dudley_Mesh* mesh=m_dudleyMesh.get();
804
escriptDataC _target=target.getDataC();
805
escriptDataC _in=in.getDataC();
806
switch(in.getFunctionSpace().getTypeCode()) {
808
switch(target.getFunctionSpace().getTypeCode()) {
811
case(DegreesOfFreedom):
812
case(ReducedDegreesOfFreedom):
813
Dudley_Assemble_CopyNodalData(mesh->Nodes,&_target,&_in);
816
case(ReducedElements):
817
Dudley_Assemble_interpolate(mesh->Nodes,mesh->Elements,&_in,&_target);
820
case(ReducedFaceElements):
821
Dudley_Assemble_interpolate(mesh->Nodes,mesh->FaceElements,&_in,&_target);
824
Dudley_Assemble_interpolate(mesh->Nodes,mesh->Points,&_in,&_target);
828
temp << "Error - Interpolation on Domain: Dudley does not know anything about function space type " << target.getFunctionSpace().getTypeCode();
829
throw DudleyAdapterException(temp.str());
834
switch(target.getFunctionSpace().getTypeCode()) {
837
case(DegreesOfFreedom):
838
case(ReducedDegreesOfFreedom):
839
Dudley_Assemble_CopyNodalData(mesh->Nodes,&_target,&_in);
842
case(ReducedElements):
843
Dudley_Assemble_interpolate(mesh->Nodes,mesh->Elements,&_in,&_target);
846
case(ReducedFaceElements):
847
Dudley_Assemble_interpolate(mesh->Nodes,mesh->FaceElements,&_in,&_target);
850
Dudley_Assemble_interpolate(mesh->Nodes,mesh->Points,&_in,&_target);
854
temp << "Error - Interpolation on Domain: Dudley does not know anything about function space type " << target.getFunctionSpace().getTypeCode();
855
throw DudleyAdapterException(temp.str());
860
if (target.getFunctionSpace().getTypeCode()==Elements) {
861
Dudley_Assemble_CopyElementData(mesh->Elements,&_target,&_in);
862
} else if (target.getFunctionSpace().getTypeCode()==ReducedElements) {
863
Dudley_Assemble_AverageElementData(mesh->Elements,&_target,&_in);
865
throw DudleyAdapterException("Error - No interpolation with data on elements possible.");
868
case(ReducedElements):
869
if (target.getFunctionSpace().getTypeCode()==ReducedElements) {
870
Dudley_Assemble_CopyElementData(mesh->Elements,&_target,&_in);
872
throw DudleyAdapterException("Error - No interpolation with data on elements with reduced integration order possible.");
876
if (target.getFunctionSpace().getTypeCode()==FaceElements) {
877
Dudley_Assemble_CopyElementData(mesh->FaceElements,&_target,&_in);
878
} else if (target.getFunctionSpace().getTypeCode()==ReducedFaceElements) {
879
Dudley_Assemble_AverageElementData(mesh->FaceElements,&_target,&_in);
881
throw DudleyAdapterException("Error - No interpolation with data on face elements possible.");
884
case(ReducedFaceElements):
885
if (target.getFunctionSpace().getTypeCode()==ReducedFaceElements) {
886
Dudley_Assemble_CopyElementData(mesh->FaceElements,&_target,&_in);
888
throw DudleyAdapterException("Error - No interpolation with data on face elements with reduced integration order possible.");
892
if (target.getFunctionSpace().getTypeCode()==Points) {
893
Dudley_Assemble_CopyElementData(mesh->Points,&_target,&_in);
895
throw DudleyAdapterException("Error - No interpolation with data on points possible.");
898
case(DegreesOfFreedom):
899
switch(target.getFunctionSpace().getTypeCode()) {
900
case(ReducedDegreesOfFreedom):
901
case(DegreesOfFreedom):
902
Dudley_Assemble_CopyNodalData(mesh->Nodes,&_target,&_in);
907
if (getMPISize()>1) {
908
escript::Data temp=escript::Data(in);
910
escriptDataC _in2 = temp.getDataC();
911
Dudley_Assemble_CopyNodalData(mesh->Nodes,&_target,&_in2);
913
Dudley_Assemble_CopyNodalData(mesh->Nodes,&_target,&_in);
917
case(ReducedElements):
918
if (getMPISize()>1) {
919
escript::Data temp=escript::Data( in, continuousFunction(*this) );
920
escriptDataC _in2 = temp.getDataC();
921
Dudley_Assemble_interpolate(mesh->Nodes,mesh->Elements,&_in2,&_target);
923
Dudley_Assemble_interpolate(mesh->Nodes,mesh->Elements,&_in,&_target);
927
case(ReducedFaceElements):
928
if (getMPISize()>1) {
929
escript::Data temp=escript::Data( in, continuousFunction(*this) );
930
escriptDataC _in2 = temp.getDataC();
931
Dudley_Assemble_interpolate(mesh->Nodes,mesh->FaceElements,&_in2,&_target);
934
Dudley_Assemble_interpolate(mesh->Nodes,mesh->FaceElements,&_in,&_target);
938
if (getMPISize()>1) {
939
escript::Data temp=escript::Data( in, continuousFunction(*this) );
940
escriptDataC _in2 = temp.getDataC();
942
Dudley_Assemble_interpolate(mesh->Nodes,mesh->Points,&_in,&_target);
947
temp << "Error - Interpolation On Domain: Dudley does not know anything about function space type " << target.getFunctionSpace().getTypeCode();
948
throw DudleyAdapterException(temp.str());
952
case(ReducedDegreesOfFreedom):
953
switch(target.getFunctionSpace().getTypeCode()) {
955
throw DudleyAdapterException("Error - Dudley does not support interpolation from reduced degrees of freedom to mesh nodes.");
958
if (getMPISize()>1) {
959
escript::Data temp=escript::Data(in);
961
escriptDataC _in2 = temp.getDataC();
962
Dudley_Assemble_CopyNodalData(mesh->Nodes,&_target,&_in2);
964
Dudley_Assemble_CopyNodalData(mesh->Nodes,&_target,&_in);
967
case(DegreesOfFreedom):
968
throw DudleyAdapterException("Error - Dudley does not support interpolation from reduced degrees of freedom to degrees of freedom");
970
case(ReducedDegreesOfFreedom):
971
Dudley_Assemble_CopyNodalData(mesh->Nodes,&_target,&_in);
974
case(ReducedElements):
975
if (getMPISize()>1) {
976
escript::Data temp=escript::Data( in, reducedContinuousFunction(*this) );
977
escriptDataC _in2 = temp.getDataC();
978
Dudley_Assemble_interpolate(mesh->Nodes,mesh->Elements,&_in2,&_target);
980
Dudley_Assemble_interpolate(mesh->Nodes,mesh->Elements,&_in,&_target);
984
case(ReducedFaceElements):
985
if (getMPISize()>1) {
986
escript::Data temp=escript::Data( in, reducedContinuousFunction(*this) );
987
escriptDataC _in2 = temp.getDataC();
988
Dudley_Assemble_interpolate(mesh->Nodes,mesh->FaceElements,&_in2,&_target);
990
Dudley_Assemble_interpolate(mesh->Nodes,mesh->FaceElements,&_in,&_target);
994
if (getMPISize()>1) {
995
escript::Data temp=escript::Data( in, reducedContinuousFunction(*this) );
996
escriptDataC _in2 = temp.getDataC();
997
Dudley_Assemble_interpolate(mesh->Nodes,mesh->Points,&_in2,&_target);
999
Dudley_Assemble_interpolate(mesh->Nodes,mesh->Points,&_in,&_target);
1004
temp << "Error - Interpolation On Domain: Dudley does not know anything about function space type " << target.getFunctionSpace().getTypeCode();
1005
throw DudleyAdapterException(temp.str());
1011
temp << "Error - Interpolation On Domain: Dudley does not know anything about function space type %d" << in.getFunctionSpace().getTypeCode();
1012
throw DudleyAdapterException(temp.str());
1019
// copies the locations of sample points into x:
1021
void MeshAdapter::setToX(escript::Data& arg) const
1023
const MeshAdapter& argDomain=dynamic_cast<const MeshAdapter&>(*(arg.getFunctionSpace().getDomain()));
1024
if (argDomain!=*this)
1025
throw DudleyAdapterException("Error - Illegal domain of data point locations");
1026
Dudley_Mesh* mesh=m_dudleyMesh.get();
1027
// in case of values node coordinates we can do the job directly:
1028
if (arg.getFunctionSpace().getTypeCode()==Nodes) {
1029
escriptDataC _arg=arg.getDataC();
1030
Dudley_Assemble_NodeCoordinates(mesh->Nodes,&_arg);
1032
escript::Data tmp_data=Vector(0.0,continuousFunction(*this),true);
1033
escriptDataC _tmp_data=tmp_data.getDataC();
1034
Dudley_Assemble_NodeCoordinates(mesh->Nodes,&_tmp_data);
1035
// this is then interpolated onto arg:
1036
interpolateOnDomain(arg,tmp_data);
1042
// return the normal vectors at the location of data points as a Data object:
1044
void MeshAdapter::setToNormal(escript::Data& normal) const
1046
/* const MeshAdapter& normalDomain=dynamic_cast<const MeshAdapter&>(normal.getFunctionSpace().getDomain());*/
1047
const MeshAdapter& normalDomain=dynamic_cast<const MeshAdapter&>(*(normal.getFunctionSpace().getDomain()));
1048
if (normalDomain!=*this)
1049
throw DudleyAdapterException("Error - Illegal domain of normal locations");
1050
Dudley_Mesh* mesh=m_dudleyMesh.get();
1051
escriptDataC _normal=normal.getDataC();
1052
switch(normal.getFunctionSpace().getTypeCode()) {
1054
throw DudleyAdapterException("Error - Dudley does not support surface normal vectors for nodes");
1057
throw DudleyAdapterException("Error - Dudley does not support surface normal vectors for reduced nodes");
1060
throw DudleyAdapterException("Error - Dudley does not support surface normal vectors for elements");
1062
case(ReducedElements):
1063
throw DudleyAdapterException("Error - Dudley does not support surface normal vectors for elements with reduced integration order");
1065
case (FaceElements):
1066
Dudley_Assemble_setNormal(mesh->Nodes,mesh->FaceElements,&_normal);
1068
case (ReducedFaceElements):
1069
Dudley_Assemble_setNormal(mesh->Nodes,mesh->FaceElements,&_normal);
1072
throw DudleyAdapterException("Error - Dudley does not support surface normal vectors for point elements");
1074
case(DegreesOfFreedom):
1075
throw DudleyAdapterException("Error - Dudley does not support surface normal vectors for degrees of freedom.");
1077
case(ReducedDegreesOfFreedom):
1078
throw DudleyAdapterException("Error - Dudley does not support surface normal vectors for reduced degrees of freedom.");
1082
temp << "Error - Normal Vectors: Dudley does not know anything about function space type " << normal.getFunctionSpace().getTypeCode();
1083
throw DudleyAdapterException(temp.str());
1090
// interpolates data to other domain:
1092
void MeshAdapter::interpolateACross(escript::Data& target,const escript::Data& source) const
1094
const_Domain_ptr targetDomain_p=target.getFunctionSpace().getDomain();
1095
const MeshAdapter* targetDomain=dynamic_cast<const MeshAdapter*>(targetDomain_p.get());
1096
if (targetDomain!=this)
1097
throw DudleyAdapterException("Error - Illegal domain of interpolation target");
1099
throw DudleyAdapterException("Error - Dudley does not allow interpolation across domains yet.");
1103
// calculates the integral of a function defined of arg:
1105
void MeshAdapter::setToIntegrals(vector<double>& integrals,const escript::Data& arg) const
1107
const MeshAdapter& argDomain=dynamic_cast<const MeshAdapter&>(*(arg.getFunctionSpace().getDomain()));
1108
if (argDomain!=*this)
1109
throw DudleyAdapterException("Error - Illegal domain of integration kernel");
1111
double blocktimer_start = blocktimer_time();
1112
Dudley_Mesh* mesh=m_dudleyMesh.get();
1115
escriptDataC _arg=arg.getDataC();
1116
switch(arg.getFunctionSpace().getTypeCode()) {
1118
temp=escript::Data( arg, escript::function(*this) );
1119
_temp=temp.getDataC();
1120
Dudley_Assemble_integrate(mesh->Nodes,mesh->Elements,&_temp,&integrals[0]);
1123
temp=escript::Data( arg, escript::function(*this) );
1124
_temp=temp.getDataC();
1125
Dudley_Assemble_integrate(mesh->Nodes,mesh->Elements,&_temp,&integrals[0]);
1128
Dudley_Assemble_integrate(mesh->Nodes,mesh->Elements,&_arg,&integrals[0]);
1130
case(ReducedElements):
1131
Dudley_Assemble_integrate(mesh->Nodes,mesh->Elements,&_arg,&integrals[0]);
1134
Dudley_Assemble_integrate(mesh->Nodes,mesh->FaceElements,&_arg,&integrals[0]);
1136
case(ReducedFaceElements):
1137
Dudley_Assemble_integrate(mesh->Nodes,mesh->FaceElements,&_arg,&integrals[0]);
1140
throw DudleyAdapterException("Error - Integral of data on points is not supported.");
1142
case(DegreesOfFreedom):
1143
temp=escript::Data( arg, escript::function(*this) );
1144
_temp=temp.getDataC();
1145
Dudley_Assemble_integrate(mesh->Nodes,mesh->Elements,&_temp,&integrals[0]);
1147
case(ReducedDegreesOfFreedom):
1148
temp=escript::Data( arg, escript::function(*this) );
1149
_temp=temp.getDataC();
1150
Dudley_Assemble_integrate(mesh->Nodes,mesh->Elements,&_temp,&integrals[0]);
1154
temp << "Error - Integrals: Dudley does not know anything about function space type " << arg.getFunctionSpace().getTypeCode();
1155
throw DudleyAdapterException(temp.str());
1159
blocktimer_increment("integrate()", blocktimer_start);
1163
// calculates the gradient of arg:
1165
void MeshAdapter::setToGradient(escript::Data& grad,const escript::Data& arg) const
1167
const MeshAdapter& argDomain=dynamic_cast<const MeshAdapter&>(*(arg.getFunctionSpace().getDomain()));
1168
if (argDomain!=*this)
1169
throw DudleyAdapterException("Error - Illegal domain of gradient argument");
1170
const MeshAdapter& gradDomain=dynamic_cast<const MeshAdapter&>(*(grad.getFunctionSpace().getDomain()));
1171
if (gradDomain!=*this)
1172
throw DudleyAdapterException("Error - Illegal domain of gradient");
1174
Dudley_Mesh* mesh=m_dudleyMesh.get();
1175
escriptDataC _grad=grad.getDataC();
1176
escriptDataC nodeDataC;
1178
if (getMPISize()>1) {
1179
if( arg.getFunctionSpace().getTypeCode() == DegreesOfFreedom ) {
1180
temp=escript::Data( arg, continuousFunction(*this) );
1181
nodeDataC = temp.getDataC();
1182
} else if( arg.getFunctionSpace().getTypeCode() == ReducedDegreesOfFreedom ) {
1183
temp=escript::Data( arg, reducedContinuousFunction(*this) );
1184
nodeDataC = temp.getDataC();
1186
nodeDataC = arg.getDataC();
1189
nodeDataC = arg.getDataC();
1191
switch(grad.getFunctionSpace().getTypeCode()) {
1193
throw DudleyAdapterException("Error - Gradient at nodes is not supported.");
1196
throw DudleyAdapterException("Error - Gradient at reduced nodes is not supported.");
1199
Dudley_Assemble_gradient(mesh->Nodes,mesh->Elements,&_grad,&nodeDataC);
1201
case(ReducedElements):
1202
Dudley_Assemble_gradient(mesh->Nodes,mesh->Elements,&_grad,&nodeDataC);
1205
Dudley_Assemble_gradient(mesh->Nodes,mesh->FaceElements,&_grad,&nodeDataC);
1207
case(ReducedFaceElements):
1208
Dudley_Assemble_gradient(mesh->Nodes,mesh->FaceElements,&_grad,&nodeDataC);
1211
throw DudleyAdapterException("Error - Gradient at points is not supported.");
1213
case(DegreesOfFreedom):
1214
throw DudleyAdapterException("Error - Gradient at degrees of freedom is not supported.");
1216
case(ReducedDegreesOfFreedom):
1217
throw DudleyAdapterException("Error - Gradient at reduced degrees of freedom is not supported.");
1221
temp << "Error - Gradient: Dudley does not know anything about function space type " << arg.getFunctionSpace().getTypeCode();
1222
throw DudleyAdapterException(temp.str());
1229
// returns the size of elements:
1231
void MeshAdapter::setToSize(escript::Data& size) const
1233
Dudley_Mesh* mesh=m_dudleyMesh.get();
1234
escriptDataC tmp=size.getDataC();
1235
switch(size.getFunctionSpace().getTypeCode()) {
1237
throw DudleyAdapterException("Error - Size of nodes is not supported.");
1240
throw DudleyAdapterException("Error - Size of reduced nodes is not supported.");
1243
Dudley_Assemble_getSize(mesh->Nodes,mesh->Elements,&tmp);
1245
case(ReducedElements):
1246
Dudley_Assemble_getSize(mesh->Nodes,mesh->Elements,&tmp);
1249
Dudley_Assemble_getSize(mesh->Nodes,mesh->FaceElements,&tmp);
1251
case(ReducedFaceElements):
1252
Dudley_Assemble_getSize(mesh->Nodes,mesh->FaceElements,&tmp);
1255
throw DudleyAdapterException("Error - Size of point elements is not supported.");
1257
case(DegreesOfFreedom):
1258
throw DudleyAdapterException("Error - Size of degrees of freedom is not supported.");
1260
case(ReducedDegreesOfFreedom):
1261
throw DudleyAdapterException("Error - Size of reduced degrees of freedom is not supported.");
1265
temp << "Error - Element size: Dudley does not know anything about function space type " << size.getFunctionSpace().getTypeCode();
1266
throw DudleyAdapterException(temp.str());
1273
// sets the location of nodes
1275
void MeshAdapter::setNewX(const escript::Data& new_x)
1277
Dudley_Mesh* mesh=m_dudleyMesh.get();
1279
const MeshAdapter& newDomain=dynamic_cast<const MeshAdapter&>(*(new_x.getFunctionSpace().getDomain()));
1280
if (newDomain!=*this)
1281
throw DudleyAdapterException("Error - Illegal domain of new point locations");
1282
if ( new_x.getFunctionSpace() == continuousFunction(*this) ) {
1283
tmp = new_x.getDataC();
1284
Dudley_Mesh_setCoordinates(mesh,&tmp);
1286
escript::Data new_x_inter=escript::Data( new_x, continuousFunction(*this) );
1287
tmp = new_x_inter.getDataC();
1288
Dudley_Mesh_setCoordinates(mesh,&tmp);
1294
// Helper for the save* methods. Extracts optional data variable names and the
1295
// corresponding pointers from python dictionary. Caller must free arrays.
1297
void MeshAdapter::extractArgsFromDict(const boost::python::dict& arg, int& numData, char**& names, escriptDataC*& data, escriptDataC**& dataPtr) const
1299
numData = boost::python::extract<int>(arg.attr("__len__")());
1300
/* win32 refactor */
1301
names = (numData>0) ? TMPMEMALLOC(numData, char*) : (char**)NULL;
1302
data = (numData>0) ? TMPMEMALLOC(numData,escriptDataC) : (escriptDataC*)NULL;
1303
dataPtr = (numData>0) ? TMPMEMALLOC(numData,escriptDataC*) : (escriptDataC**)NULL;
1305
boost::python::list keys=arg.keys();
1306
for (int i=0; i<numData; ++i) {
1307
string n=boost::python::extract<string>(keys[i]);
1308
escript::Data& d=boost::python::extract<escript::Data&>(arg[keys[i]]);
1309
if (dynamic_cast<const MeshAdapter&>(*(d.getFunctionSpace().getDomain())) !=*this)
1310
throw DudleyAdapterException("Error: Data must be defined on same Domain");
1311
data[i] = d.getDataC();
1312
dataPtr[i] = &(data[i]);
1313
names[i] = TMPMEMALLOC(n.length()+1, char);
1314
strcpy(names[i], n.c_str());
1319
// saves mesh and optionally data arrays in openDX format
1321
void MeshAdapter::saveDX(const string& filename,const boost::python::dict& arg) const
1326
escriptDataC **ptr_data;
1328
extractArgsFromDict(arg, num_data, names, data, ptr_data);
1329
Dudley_Mesh_saveDX(filename.c_str(), m_dudleyMesh.get(), num_data, names, ptr_data);
1332
/* win32 refactor */
1334
TMPMEMFREE(ptr_data);
1335
for(int i=0; i<num_data; i++)
1337
TMPMEMFREE(names[i]);
1345
// saves mesh and optionally data arrays in VTK format
1347
void MeshAdapter::saveVTK(const string& filename,const boost::python::dict& arg, const string& metadata, const string& metadata_schema) const
1352
escriptDataC **ptr_data;
1354
extractArgsFromDict(arg, num_data, names, data, ptr_data);
1355
Dudley_Mesh_saveVTK(filename.c_str(), m_dudleyMesh.get(), num_data, names, ptr_data, metadata.c_str(), metadata_schema.c_str());
1358
/* win32 refactor */
1360
TMPMEMFREE(ptr_data);
1361
for(int i=0; i<num_data; i++)
1363
TMPMEMFREE(names[i]);
1368
bool MeshAdapter::ownSample(int fs_code, index_t id) const
1371
index_t myFirstNode=0, myLastNode=0, k=0;
1372
index_t* globalNodeIndex=0;
1373
Dudley_Mesh* mesh_p=m_dudleyMesh.get();
1374
if (fs_code == DUDLEY_REDUCED_NODES)
1376
myFirstNode = Dudley_NodeFile_getFirstReducedNode(mesh_p->Nodes);
1377
myLastNode = Dudley_NodeFile_getLastReducedNode(mesh_p->Nodes);
1378
globalNodeIndex = Dudley_NodeFile_borrowGlobalReducedNodesIndex(mesh_p->Nodes);
1382
myFirstNode = Dudley_NodeFile_getFirstNode(mesh_p->Nodes);
1383
myLastNode = Dudley_NodeFile_getLastNode(mesh_p->Nodes);
1384
globalNodeIndex = Dudley_NodeFile_borrowGlobalNodesIndex(mesh_p->Nodes);
1386
k=globalNodeIndex[id];
1387
return static_cast<bool>( (myFirstNode <= k) && (k < myLastNode) );
1395
// creates a SystemMatrixAdapter stiffness matrix an initializes it with zeros
1397
ASM_ptr MeshAdapter::newSystemMatrix(
1398
const int row_blocksize,
1399
const escript::FunctionSpace& row_functionspace,
1400
const int column_blocksize,
1401
const escript::FunctionSpace& column_functionspace,
1402
const int type) const
1404
int reduceRowOrder=0;
1405
int reduceColOrder=0;
1406
// is the domain right?
1407
const MeshAdapter& row_domain=dynamic_cast<const MeshAdapter&>(*(row_functionspace.getDomain()));
1408
if (row_domain!=*this)
1409
throw DudleyAdapterException("Error - domain of row function space does not match the domain of matrix generator.");
1410
const MeshAdapter& col_domain=dynamic_cast<const MeshAdapter&>(*(column_functionspace.getDomain()));
1411
if (col_domain!=*this)
1412
throw DudleyAdapterException("Error - domain of columnn function space does not match the domain of matrix generator.");
1413
// is the function space type right
1414
if (row_functionspace.getTypeCode()==DegreesOfFreedom) {
1416
} else if (row_functionspace.getTypeCode()==ReducedDegreesOfFreedom) {
1419
throw DudleyAdapterException("Error - illegal function space type for system matrix rows.");
1421
if (column_functionspace.getTypeCode()==DegreesOfFreedom) {
1423
} else if (column_functionspace.getTypeCode()==ReducedDegreesOfFreedom) {
1426
throw DudleyAdapterException("Error - illegal function space type for system matrix columns.");
1430
Paso_SystemMatrixPattern* fsystemMatrixPattern=Dudley_getPattern(getDudley_Mesh(),reduceRowOrder,reduceColOrder);
1432
Paso_SystemMatrix* fsystemMatrix;
1436
/* Allocation Epetra_VrbMatrix here */
1440
fsystemMatrix=Paso_SystemMatrix_alloc(type,fsystemMatrixPattern,row_blocksize,column_blocksize,FALSE);
1443
Paso_SystemMatrixPattern_free(fsystemMatrixPattern);
1444
SystemMatrixAdapter* sma=new SystemMatrixAdapter(fsystemMatrix,row_blocksize,row_functionspace, column_blocksize,column_functionspace);
1445
return ASM_ptr(sma);
1449
// creates a TransportProblemAdapter
1451
ATP_ptr MeshAdapter::newTransportProblem(
1452
const bool useBackwardEuler,
1453
const int blocksize,
1454
const escript::FunctionSpace& functionspace,
1455
const int type) const
1458
// is the domain right?
1459
const MeshAdapter& domain=dynamic_cast<const MeshAdapter&>(*(functionspace.getDomain()));
1461
throw DudleyAdapterException("Error - domain of function space does not match the domain of transport problem generator.");
1462
// is the function space type right
1463
if (functionspace.getTypeCode()==DegreesOfFreedom) {
1465
} else if (functionspace.getTypeCode()==ReducedDegreesOfFreedom) {
1468
throw DudleyAdapterException("Error - illegal function space type for system matrix rows.");
1472
Paso_SystemMatrixPattern* fsystemMatrixPattern=Dudley_getPattern(getDudley_Mesh(),reduceOrder,reduceOrder);
1474
Paso_TransportProblem* transportProblem;
1475
transportProblem=Paso_TransportProblem_alloc(useBackwardEuler,fsystemMatrixPattern,blocksize);
1477
Paso_SystemMatrixPattern_free(fsystemMatrixPattern);
1478
AbstractTransportProblem* atp=new TransportProblemAdapter(transportProblem,useBackwardEuler,blocksize,functionspace);
1479
return ATP_ptr(atp);
1483
// vtkObject MeshAdapter::createVtkObject() const
1488
// returns true if data at the atom_type is considered as being cell centered:
1489
bool MeshAdapter::isCellOriented(int functionSpaceCode) const
1491
switch(functionSpaceCode) {
1493
case(DegreesOfFreedom):
1494
case(ReducedDegreesOfFreedom):
1500
case(ReducedElements):
1501
case(ReducedFaceElements):
1506
temp << "Error - Cell: Dudley does not know anything about function space type " << functionSpaceCode;
1507
throw DudleyAdapterException(temp.str());
1515
MeshAdapter::commonFunctionSpace(const vector<int>& fs, int& resultcode) const
1517
/* The idea is to use equivalence classes. [Types which can be interpolated back and forth]
1518
class 1: DOF <-> Nodes
1519
class 2: ReducedDOF <-> ReducedNodes
1522
class 5: ReducedElements
1523
class 6: FaceElements
1524
class 7: ReducedFaceElements
1525
class 8: ContactElementZero <-> ContactElementOne
1526
class 9: ReducedContactElementZero <-> ReducedContactElementOne
1528
There is also a set of lines. Interpolation is possible down a line but not between lines.
1529
class 1 and 2 belong to all lines so aren't considered.
1535
For classes with multiple members (eg class 2) we have vars to record if there is at least one instance.
1536
eg hasnodes is true if we have at least one instance of Nodes.
1542
vector<int> hasclass(10);
1543
vector<int> hasline(4);
1544
bool hasnodes=false;
1545
bool hasrednodes=false;
1546
for (int i=0;i<fs.size();++i)
1550
case(Nodes): hasnodes=true; // no break is deliberate
1551
case(DegreesOfFreedom):
1554
case(ReducedNodes): hasrednodes=true; // no break is deliberate
1555
case(ReducedDegreesOfFreedom):
1566
case(ReducedElements):
1574
case(ReducedFaceElements):
1582
int totlines=hasline[0]+hasline[1]+hasline[2]+hasline[3];
1583
// fail if we have more than one leaf group
1587
return false; // there are at least two branches we can't interpolate between
1589
else if (totlines==1)
1591
if (hasline[0]==1) // we have points
1595
else if (hasline[1]==1)
1599
resultcode=ReducedElements;
1603
resultcode=Elements;
1606
else if (hasline[2]==1)
1610
resultcode=ReducedFaceElements;
1614
resultcode=FaceElements;
1617
else // so we must be in line3
1620
throw DudleyAdapterException("Programmer Error - choosing between contact elements - we should never get here.");
1628
// something from class 2
1629
resultcode=(hasrednodes?ReducedNodes:ReducedDegreesOfFreedom);
1632
{ // something from class 1
1633
resultcode=(hasnodes?Nodes:DegreesOfFreedom);
1639
bool MeshAdapter::probeInterpolationOnDomain(int functionSpaceType_source,int functionSpaceType_target) const
1641
switch(functionSpaceType_source) {
1643
switch(functionSpaceType_target) {
1646
case(ReducedDegreesOfFreedom):
1647
case(DegreesOfFreedom):
1649
case(ReducedElements):
1651
case(ReducedFaceElements):
1656
temp << "Error - Interpolation On Domain: Dudley does not know anything about function space type " << functionSpaceType_target;
1657
throw DudleyAdapterException(temp.str());
1661
switch(functionSpaceType_target) {
1663
case(ReducedDegreesOfFreedom):
1665
case(ReducedElements):
1667
case(ReducedFaceElements):
1671
case(DegreesOfFreedom):
1675
temp << "Error - Interpolation On Domain: Dudley does not know anything about function space type " << functionSpaceType_target;
1676
throw DudleyAdapterException(temp.str());
1680
if (functionSpaceType_target==Elements) {
1682
} else if (functionSpaceType_target==ReducedElements) {
1687
case(ReducedElements):
1688
if (functionSpaceType_target==ReducedElements) {
1694
if (functionSpaceType_target==FaceElements) {
1696
} else if (functionSpaceType_target==ReducedFaceElements) {
1701
case(ReducedFaceElements):
1702
if (functionSpaceType_target==ReducedFaceElements) {
1708
if (functionSpaceType_target==Points) {
1713
case(DegreesOfFreedom):
1714
switch(functionSpaceType_target) {
1715
case(ReducedDegreesOfFreedom):
1716
case(DegreesOfFreedom):
1720
case(ReducedElements):
1723
case(ReducedFaceElements):
1727
temp << "Error - Interpolation On Domain: Dudley does not know anything about function space type " << functionSpaceType_target;
1728
throw DudleyAdapterException(temp.str());
1731
case(ReducedDegreesOfFreedom):
1732
switch(functionSpaceType_target) {
1733
case(ReducedDegreesOfFreedom):
1736
case(ReducedElements):
1738
case(ReducedFaceElements):
1742
case(DegreesOfFreedom):
1746
temp << "Error - Interpolation On Domain: Dudley does not know anything about function space type " << functionSpaceType_target;
1747
throw DudleyAdapterException(temp.str());
1752
temp << "Error - Interpolation On Domain: Dudley does not know anything about function space type " << functionSpaceType_source;
1753
throw DudleyAdapterException(temp.str());
1760
bool MeshAdapter::probeInterpolationACross(int functionSpaceType_source,const AbstractDomain& targetDomain, int functionSpaceType_target) const
1765
bool MeshAdapter::operator==(const AbstractDomain& other) const
1767
const MeshAdapter* temp=dynamic_cast<const MeshAdapter*>(&other);
1769
return (m_dudleyMesh==temp->m_dudleyMesh);
1775
bool MeshAdapter::operator!=(const AbstractDomain& other) const
1777
return !(operator==(other));
1780
int MeshAdapter::getSystemMatrixTypeId(const int solver, const int preconditioner, const int package, const bool symmetry) const
1782
Dudley_Mesh* mesh=m_dudleyMesh.get();
1783
int out=Paso_SystemMatrix_getSystemMatrixTypeId(SystemMatrixAdapter::mapOptionToPaso(solver),SystemMatrixAdapter::mapOptionToPaso(preconditioner), SystemMatrixAdapter::mapOptionToPaso(package),symmetry?1:0, mesh->MPIInfo);
1787
int MeshAdapter::getTransportTypeId(const int solver, const int preconditioner, const int package, const bool symmetry) const
1789
Dudley_Mesh* mesh=m_dudleyMesh.get();
1790
int out=Paso_TransportProblem_getTypeId(SystemMatrixAdapter::mapOptionToPaso(solver),SystemMatrixAdapter::mapOptionToPaso(preconditioner), SystemMatrixAdapter::mapOptionToPaso(package),symmetry?1:0, mesh->MPIInfo);
1795
escript::Data MeshAdapter::getX() const
1797
return continuousFunction(*this).getX();
1800
escript::Data MeshAdapter::getNormal() const
1802
return functionOnBoundary(*this).getNormal();
1805
escript::Data MeshAdapter::getSize() const
1807
return escript::function(*this).getSize();
1810
const int* MeshAdapter::borrowSampleReferenceIDs(int functionSpaceType) const
1813
Dudley_Mesh* mesh=m_dudleyMesh.get();
1814
switch (functionSpaceType) {
1816
out=mesh->Nodes->Id;
1819
out=mesh->Nodes->reducedNodesId;
1822
out=mesh->Elements->Id;
1824
case(ReducedElements):
1825
out=mesh->Elements->Id;
1828
out=mesh->FaceElements->Id;
1830
case(ReducedFaceElements):
1831
out=mesh->FaceElements->Id;
1834
out=mesh->Points->Id;
1836
case(DegreesOfFreedom):
1837
out=mesh->Nodes->degreesOfFreedomId;
1839
case(ReducedDegreesOfFreedom):
1840
out=mesh->Nodes->reducedDegreesOfFreedomId;
1844
temp << "Error - Invalid function space type: " << functionSpaceType << " for domain: " << getDescription();
1845
throw DudleyAdapterException(temp.str());
1850
int MeshAdapter::getTagFromSampleNo(int functionSpaceType, int sampleNo) const
1853
Dudley_Mesh* mesh=m_dudleyMesh.get();
1854
switch (functionSpaceType) {
1856
out=mesh->Nodes->Tag[sampleNo];
1859
throw DudleyAdapterException(" Error - ReducedNodes does not support tags.");
1862
out=mesh->Elements->Tag[sampleNo];
1864
case(ReducedElements):
1865
out=mesh->Elements->Tag[sampleNo];
1868
out=mesh->FaceElements->Tag[sampleNo];
1870
case(ReducedFaceElements):
1871
out=mesh->FaceElements->Tag[sampleNo];
1874
out=mesh->Points->Tag[sampleNo];
1876
case(DegreesOfFreedom):
1877
throw DudleyAdapterException(" Error - DegreesOfFreedom does not support tags.");
1879
case(ReducedDegreesOfFreedom):
1880
throw DudleyAdapterException(" Error - ReducedDegreesOfFreedom does not support tags.");
1884
temp << "Error - Invalid function space type: " << functionSpaceType << " for domain: " << getDescription();
1885
throw DudleyAdapterException(temp.str());
1892
void MeshAdapter::setTags(const int functionSpaceType, const int newTag, const escript::Data& mask) const
1894
Dudley_Mesh* mesh=m_dudleyMesh.get();
1895
escriptDataC tmp=mask.getDataC();
1896
switch(functionSpaceType) {
1898
Dudley_NodeFile_setTags(mesh->Nodes,newTag,&tmp);
1901
throw DudleyAdapterException("Error - ReducedNodes does not support tags");
1903
case(DegreesOfFreedom):
1904
throw DudleyAdapterException("Error - DegreesOfFreedom does not support tags");
1906
case(ReducedDegreesOfFreedom):
1907
throw DudleyAdapterException("Error - ReducedDegreesOfFreedom does not support tags");
1910
Dudley_ElementFile_setTags(mesh->Elements,newTag,&tmp);
1912
case(ReducedElements):
1913
Dudley_ElementFile_setTags(mesh->Elements,newTag,&tmp);
1916
Dudley_ElementFile_setTags(mesh->FaceElements,newTag,&tmp);
1918
case(ReducedFaceElements):
1919
Dudley_ElementFile_setTags(mesh->FaceElements,newTag,&tmp);
1922
Dudley_ElementFile_setTags(mesh->Points,newTag,&tmp);
1926
temp << "Error - Dudley does not know anything about function space type " << functionSpaceType;
1927
throw DudleyAdapterException(temp.str());
1933
void MeshAdapter::setTagMap(const string& name, int tag)
1935
Dudley_Mesh* mesh=m_dudleyMesh.get();
1936
Dudley_Mesh_addTagMap(mesh, name.c_str(),tag);
1938
// throwStandardException("MeshAdapter::set TagMap is not implemented.");
1941
int MeshAdapter::getTag(const string& name) const
1943
Dudley_Mesh* mesh=m_dudleyMesh.get();
1945
tag=Dudley_Mesh_getTag(mesh, name.c_str());
1947
// throwStandardException("MeshAdapter::getTag is not implemented.");
1951
bool MeshAdapter::isValidTagName(const string& name) const
1953
Dudley_Mesh* mesh=m_dudleyMesh.get();
1954
return Dudley_Mesh_isValidTagName(mesh,name.c_str());
1957
string MeshAdapter::showTagNames() const
1960
Dudley_Mesh* mesh=m_dudleyMesh.get();
1961
Dudley_TagMap* tag_map=mesh->TagMap;
1963
temp << tag_map->name;
1964
tag_map=tag_map->next;
1965
if (tag_map) temp << ", ";
1970
int MeshAdapter::getNumberOfTagsInUse(int functionSpaceCode) const
1972
Dudley_Mesh* mesh=m_dudleyMesh.get();
1974
switch(functionSpaceCode) {
1976
numTags=mesh->Nodes->numTagsInUse;
1979
throw DudleyAdapterException("Error - ReducedNodes does not support tags");
1981
case(DegreesOfFreedom):
1982
throw DudleyAdapterException("Error - DegreesOfFreedom does not support tags");
1984
case(ReducedDegreesOfFreedom):
1985
throw DudleyAdapterException("Error - ReducedDegreesOfFreedom does not support tags");
1988
case(ReducedElements):
1989
numTags=mesh->Elements->numTagsInUse;
1992
case(ReducedFaceElements):
1993
numTags=mesh->FaceElements->numTagsInUse;
1996
numTags=mesh->Points->numTagsInUse;
2000
temp << "Error - Dudley does not know anything about function space type " << functionSpaceCode;
2001
throw DudleyAdapterException(temp.str());
2006
const int* MeshAdapter::borrowListOfTagsInUse(int functionSpaceCode) const
2008
Dudley_Mesh* mesh=m_dudleyMesh.get();
2010
switch(functionSpaceCode) {
2012
tags=mesh->Nodes->tagsInUse;
2015
throw DudleyAdapterException("Error - ReducedNodes does not support tags");
2017
case(DegreesOfFreedom):
2018
throw DudleyAdapterException("Error - DegreesOfFreedom does not support tags");
2020
case(ReducedDegreesOfFreedom):
2021
throw DudleyAdapterException("Error - ReducedDegreesOfFreedom does not support tags");
2024
case(ReducedElements):
2025
tags=mesh->Elements->tagsInUse;
2028
case(ReducedFaceElements):
2029
tags=mesh->FaceElements->tagsInUse;
2032
tags=mesh->Points->tagsInUse;
2036
temp << "Error - Dudley does not know anything about function space type " << functionSpaceCode;
2037
throw DudleyAdapterException(temp.str());
2043
bool MeshAdapter::canTag(int functionSpaceCode) const
2045
switch(functionSpaceCode) {
2048
case(ReducedElements):
2050
case(ReducedFaceElements):
2054
case(DegreesOfFreedom):
2055
case(ReducedDegreesOfFreedom):
2062
AbstractDomain::StatusType MeshAdapter::getStatus() const
2064
Dudley_Mesh* mesh=m_dudleyMesh.get();
2065
return Dudley_Mesh_getStatus(mesh);
2068
int MeshAdapter::getApproximationOrder(const int functionSpaceCode) const
2071
Dudley_Mesh* mesh=m_dudleyMesh.get();
2073
switch(functionSpaceCode) {
2075
case(DegreesOfFreedom):
2076
order=mesh->approximationOrder;
2079
case(ReducedDegreesOfFreedom):
2080
order=mesh->reducedApproximationOrder;
2085
order=mesh->integrationOrder;
2087
case(ReducedElements):
2088
case(ReducedFaceElements):
2089
order=mesh->reducedIntegrationOrder;
2093
temp << "Error - Dudley does not know anything about function space type " << functionSpaceCode;
2094
throw DudleyAdapterException(temp.str());
2100
bool MeshAdapter::supportsContactElements() const
2105
} // end of namespace