1 |
/* |
2 |
****************************************************************************** |
3 |
* * |
4 |
* COPYRIGHT ACcESS 2004 - All Rights Reserved * |
5 |
* * |
6 |
* This software is the property of ACcESS. No part of this code * |
7 |
* may be copied in any form or by any means without the expressed written * |
8 |
* consent of ACcESS. Copying, use or modification of this software * |
9 |
* by any unauthorised person is illegal unless that person has a software * |
10 |
* license agreement with ACcESS. * |
11 |
* * |
12 |
****************************************************************************** |
13 |
*/ |
14 |
|
15 |
#include "escript/Data/FunctionSpace.h" |
16 |
#include "finley/CPPAdapter/MeshAdapter.h" |
17 |
#include <iostream> |
18 |
|
19 |
using namespace std; |
20 |
using namespace escript; |
21 |
|
22 |
namespace finley { |
23 |
|
24 |
struct null_deleter |
25 |
{ |
26 |
void operator()(void const *ptr) const |
27 |
{ |
28 |
} |
29 |
}; |
30 |
|
31 |
MeshAdapter::MeshAdapter(Finley_Mesh* finleyMesh) |
32 |
{ |
33 |
// |
34 |
// need to use a null_deleter as Finley_Mesh_dealloc deletes the pointer |
35 |
// for us. |
36 |
m_finleyMesh.reset(finleyMesh,null_deleter()); |
37 |
} |
38 |
// |
39 |
// The copy constructor should just increment the use count |
40 |
MeshAdapter::MeshAdapter(const MeshAdapter& in): |
41 |
m_finleyMesh(in.m_finleyMesh) |
42 |
{ |
43 |
} |
44 |
|
45 |
MeshAdapter::~MeshAdapter() |
46 |
{ |
47 |
// |
48 |
// I hope the case for the pointer being zero has been taken care of. |
49 |
// cout << "In MeshAdapter destructor." << endl; |
50 |
if (m_finleyMesh.unique()) { |
51 |
// cout << "Calling dealloc." << endl; |
52 |
Finley_Mesh_dealloc(m_finleyMesh.get()); |
53 |
// cout << "Finished dealloc." << endl; |
54 |
} |
55 |
} |
56 |
|
57 |
void MeshAdapter::write(const std::string& fileName) const |
58 |
{ |
59 |
char fName[fileName.size()+1]; |
60 |
strcpy(fName,fileName.c_str()); |
61 |
Finley_Mesh_write(m_finleyMesh.get(),fName); |
62 |
} |
63 |
|
64 |
string MeshAdapter::getDescription() const |
65 |
{ |
66 |
return "FinleyMesh"; |
67 |
} |
68 |
|
69 |
bool MeshAdapter::isValidFunctionSpaceType(int functionSpaceType) const |
70 |
{ |
71 |
FunctionSpaceNamesMapType::iterator loc; |
72 |
loc=m_functionSpaceTypeNames.find(functionSpaceType); |
73 |
return (loc!=m_functionSpaceTypeNames.end()); |
74 |
} |
75 |
|
76 |
FunctionSpace MeshAdapter::createFunctionSpace(int functionSpaceType) const |
77 |
{ |
78 |
return FunctionSpace(*this,functionSpaceType); |
79 |
} |
80 |
|
81 |
void MeshAdapter::setFunctionSpaceTypeNames() |
82 |
{ |
83 |
m_functionSpaceTypeNames.insert |
84 |
(FunctionSpaceNamesMapType::value_type(DegreesOfFreedom,"Finley_DegreesOfFreedom")); |
85 |
m_functionSpaceTypeNames.insert |
86 |
(FunctionSpaceNamesMapType::value_type(ReducedDegreesOfFreedom,"Finley_ReducedDegreesOfFreedom")); |
87 |
m_functionSpaceTypeNames.insert |
88 |
(FunctionSpaceNamesMapType::value_type(Nodes,"Finley_Nodes")); |
89 |
m_functionSpaceTypeNames.insert |
90 |
(FunctionSpaceNamesMapType::value_type(Elements,"Finley_Elements")); |
91 |
m_functionSpaceTypeNames.insert |
92 |
(FunctionSpaceNamesMapType::value_type(FaceElements,"Finley_Face_Elements")); |
93 |
m_functionSpaceTypeNames.insert |
94 |
(FunctionSpaceNamesMapType::value_type(Points,"Finley_Points")); |
95 |
m_functionSpaceTypeNames.insert |
96 |
(FunctionSpaceNamesMapType::value_type(ContactElementsZero,"Finley_Contact_Elements_0")); |
97 |
m_functionSpaceTypeNames.insert |
98 |
(FunctionSpaceNamesMapType::value_type(ContactElementsOne,"Finley_Contact_Elements_1")); |
99 |
} |
100 |
|
101 |
FunctionSpace MeshAdapter::getContinuousFunctions() const |
102 |
{ |
103 |
return createFunctionSpace(Nodes); |
104 |
} |
105 |
FunctionSpace MeshAdapter::getFunctions() const |
106 |
{ |
107 |
return createFunctionSpace(Elements); |
108 |
} |
109 |
FunctionSpace MeshAdapter::getFunctionsOnBoundary() const |
110 |
{ |
111 |
return createFunctionSpace(FaceElements); |
112 |
} |
113 |
FunctionSpace MeshAdapter::getFunctionsOnContactZero() const |
114 |
{ |
115 |
return createFunctionSpace(ContactElementsZero); |
116 |
} |
117 |
FunctionSpace MeshAdapter::getFunctionsOnContactOne() const |
118 |
{ |
119 |
return createFunctionSpace(ContactElementsOne); |
120 |
} |
121 |
|
122 |
FunctionSpace MeshAdapter::getSolutionSpace() const |
123 |
{ |
124 |
return createFunctionSpace(DegreesOfFreedom); |
125 |
} |
126 |
FunctionSpace MeshAdapter::getReducedSolutionSpace() const |
127 |
{ |
128 |
return createFunctionSpace(ReducedDegreesOfFreedom); |
129 |
} |
130 |
FunctionSpace MeshAdapter::getDiracDeltaFunctions() const |
131 |
{ |
132 |
return createFunctionSpace(Points); |
133 |
} |
134 |
======================= |
135 |
FunctionSpace.getType() |
136 |
|
137 |
methods of Data |
138 |
|
139 |
createRandomAccess(FunctionSpace) : checks/interpolate data on FunctionSpace and returns a C-structure with a pointer to a double array |
140 |
createReadAccess(FunctionSpace) : checks/interpolate data on FunctionSpace and returns a C-structure which can be used to acess data through id and tag. |
141 |
the should be a possiblity to find out if the data are constant for a sample. |
142 |
if FunctionSpace=0 or not present any domain is accepted. |
143 |
|
144 |
it should also be possible to check the rank, and shape of the Data and the number of sample points and the function space type |
145 |
|
146 |
======================== |
147 |
//returns the spatial dimension: |
148 |
int MeshAdapter::getDim() const |
149 |
{ |
150 |
numDim=Finley_Mesh_getDim(m_finleyMesh.get()); |
151 |
checkFinleyError(); |
152 |
return numDim; |
153 |
} |
154 |
// returns the number of data points needed to represent data on a parts of the mesh. |
155 |
integerlist MeshAdapter::getDataShape(FunctionSpace m_FunctionSpace) const |
156 |
{ |
157 |
int primary_dim=0,second_dim=0; |
158 |
Finley_Mesh mesh=m_finleyMesh.get() |
159 |
switch (m_FunctionSpace.getType()) { |
160 |
case(FINLEY_NODES): |
161 |
primary_dim=1; |
162 |
if (mesh->Nodes!=NULL) secondary_dim=mesh->Nodes->numNodes; |
163 |
break; |
164 |
case(FINLEY_ELEMENTS): |
165 |
if (mesh->Elements!=NULL) { |
166 |
secondary_dim=mesh->Elements->numElements; |
167 |
primary_dim=mesh->Elements->ReferenceElement->numQuadNodes; |
168 |
} |
169 |
break; |
170 |
case(FINLEY_FACE_ELEMENTS): |
171 |
if (mesh->FaceElements!=NULL) { |
172 |
primary_dim=mesh->FaceElements->ReferenceElement->numQuadNodes; |
173 |
secondary_dim=mesh->FaceElements->numElements; |
174 |
} |
175 |
break; |
176 |
case(FINLEY_POINTS): |
177 |
if (mesh->Points!=NULL) { |
178 |
primary_dim=1; |
179 |
secondary_dim=mesh->Points->numElements; |
180 |
} |
181 |
break; |
182 |
case(FINLEY_CONTACT_ELEMENTS_1): |
183 |
if (mesh->ContactElements!=NULL) { |
184 |
primary_dim=mesh->ContactElements->ReferenceElement->numQuadNodes; |
185 |
secondary_dim=mesh->ContactElements->numElements; |
186 |
} |
187 |
break; |
188 |
case(FINLEY_CONTACT_ELEMENTS_2): |
189 |
if (mesh->ContactElements!=NULL) { |
190 |
primary_dim=mesh->ContactElements->ReferenceElement->numQuadNodes; |
191 |
secondary_dim=mesh->ContactElements->numElements; |
192 |
} |
193 |
break; |
194 |
case(FINLEY_DEGREES_OF_FREEDOM): |
195 |
if (mesh->Nodes!=NULL) { |
196 |
primary_dim=1; |
197 |
secondary_dim=mesh->Nodes->numDegreesOfFreedom; |
198 |
} |
199 |
break; |
200 |
case(FINLEY_REDUCED_DEGREES_OF_FREEDOM): |
201 |
if (mesh->Nodes!=NULL) { |
202 |
primary_dim=1; |
203 |
secondary_dim=mesh->Nodes->reducedNumDegreesOfFreedom; |
204 |
} |
205 |
break; |
206 |
default: |
207 |
Finley_ErrorCode=VALUE_ERROR; |
208 |
sprintf(Finley_ErrorMsg,"Finley does not know anything about function space type %d",m_FunctionSpace.getType()); |
209 |
break; |
210 |
} |
211 |
checkFinleyError(); |
212 |
return primary_dim,secondary_dim |
213 |
} |
214 |
// returns a handle to the sparse matrix generated by a mesh |
215 |
SystemMatrix MeshAdapter:: initSystemMatrix( |
216 |
rowBlockSize=1, |
217 |
reduceRowOrder=false, |
218 |
colBlockSize=1, |
219 |
reduceColOrder=false, |
220 |
type=Constants.UNKNOWN, |
221 |
sym=false) const |
222 |
{ |
223 |
out=SystemMatrix(m_finleyMesh.get(), |
224 |
rowBlockSize,reduceRowOrder, |
225 |
colBlockSize,reduceColOrder,type,sym); |
226 |
checkFinleyError(); |
227 |
return SystemMatrix::New(out); |
228 |
|
229 |
} |
230 |
// adds linear PDE of second order into a given stiffness matrix and right hand side: |
231 |
void MeshAdapter::assemblePDE( |
232 |
SystemMatrix mat, Data rhs, |
233 |
Data A, Data B, Data C, Data D, Data X, Data Y) const |
234 |
{ |
235 |
Finley_Mesh* mesh=m_finleyMesh.get() |
236 |
// get access to matrix: |
237 |
Finley_SystemMatrix* mat_access=mat.get() |
238 |
// get access to rhs: |
239 |
if (mat_acces->reduceRowOrder) { |
240 |
rhs_functionspace=getReducedSolutionSpace(); |
241 |
} else { |
242 |
rhs_functionspace=getSolutionSpace(); |
243 |
} |
244 |
rhs_access=rhs.createRandomAccess(rhs_functionspace); |
245 |
// get access to all coefficients and |
246 |
A_access=A.createReadAccess(getFunctions()) |
247 |
B_access=B.createReadAccess(getFunctions()) |
248 |
C_access=C.createReadAccess(getFunctions()) |
249 |
D_access=D.createReadAccess(getFunctions()) |
250 |
X_access=X.createReadAccess(getFunctions()) |
251 |
Y_access=Y.createReadAccess(getFunctions()) |
252 |
Finley_Assemble_PDE(mesh->Nodes,mesh->Elements,mat_access,rhs_access, |
253 |
A_access,B_access,C_access,D_access,X_access,Y_access); |
254 |
checkFinleyError(); |
255 |
} |
256 |
// adds Robin boundary conditions as natural boundary condition into a given stiffness matrix and right hand side: |
257 |
void MeshAdapter::assembleRobinConditions( |
258 |
SystemMatrix mat, Data rhs, |
259 |
Data d, Data y) const |
260 |
{ |
261 |
Finley_Mesh* mesh=m_finleyMesh.get() |
262 |
// get access to matrix: |
263 |
Finley_SystemMatrix* mat_access=mat.get() |
264 |
// get access to rhs: |
265 |
if (mat_acces->reduceRowOrder) { |
266 |
rhs_functionspace=getReducedSolutionSpace(); |
267 |
} else { |
268 |
rhs_functionspace=getSolutionSpace(); |
269 |
} |
270 |
rhs_access=rhs.createRandomAccess(rhs_functionspace); |
271 |
// get access to all coefficients and |
272 |
d_access=d.createReadAccess(FunctionOnBoundary(*this)) |
273 |
y_access=y.createReadAccess(FunctionOnBoundary(*this)) |
274 |
|
275 |
// and assemble things: |
276 |
Finley_Assemble_RobinCondition(mesh->Nodes,mesh->FaceElements,mat_access,rhs_access, |
277 |
d_access,y_access, |
278 |
Finley_Assemble_handelShapeMissMatch_Mean_out); |
279 |
// all done: |
280 |
checkFinleyError(); |
281 |
} |
282 |
// adds contact conditions as natural boundary condition into a given stiffness matrix and right hand side: |
283 |
void MeshAdapter::assembleContact( |
284 |
SystemMatrix mat, Data rhs, |
285 |
Data d_contact, Data y_contact) const |
286 |
{ |
287 |
Finley_Mesh* mesh=m_finleyMesh.get() |
288 |
// get access to matrix: |
289 |
Finley_SystemMatrix* mat_access=mat.get() |
290 |
// get access to rhs: |
291 |
if (mat_acces->reduceRowOrder) { |
292 |
rhs_functionspace=getReducedSolutionSpace(); |
293 |
} else { |
294 |
rhs_functionspace=getSolutionSpace(); |
295 |
} |
296 |
rhs_access=rhs.createRandomAccess(rhs_functionspace); |
297 |
// get access to all coefficients and |
298 |
d_contact_access=d.createReadAccess(FunctionsOnContactOne()) |
299 |
y_contact_access=y.createReadAccess(FunctionsOnContactOne()) |
300 |
|
301 |
Finley_Assemble_RobinCondition(mesh->Nodes,mesh->FaceElements,mat_access,rhs_access, |
302 |
d_contact_access,y_contact_access, |
303 |
Finley_Assemble_handelShapeMissMatch_Step_out); |
304 |
checkFinleyError(); |
305 |
} |
306 |
// |
307 |
// return the location of data points as a Data object: |
308 |
// |
309 |
void Data MeshAdapter::getX(Data x) const |
310 |
{ |
311 |
Finley_Mesh* mesh=m_finleyMesh.get(); |
312 |
// in case of values node coordinates we can do the job directly: |
313 |
if (x.getFunctionSpaceType()==FINLEY_NODES) { |
314 |
x_access=x.createRandomAccess(); |
315 |
Finley_Assemble_NodeCoordinates(mesh->Nodes,x_access); |
316 |
} else { |
317 |
// otherwise a temporay Data object with node cooredintes is used: |
318 |
tmp_data=Data::New(0,shape=(m_finleyMesh.getDim(),),what=m_finleyMesh.Nodes()); |
319 |
tmp_data_access=tmp_data.createRandomAccess(tmp_data.getFunctionSpace()); |
320 |
Finley_Assemble_NodeCoordinates(mesh->Nodes,tmp_data_access); |
321 |
// this is then interpolated onto x: |
322 |
m_finleyMesh.interpolate(tmp_data,x); |
323 |
} |
324 |
checkFinleyError(); |
325 |
} |
326 |
// |
327 |
// return the normal vectors at the location of data points as a Data object: |
328 |
// |
329 |
void MeshAdapter::getNormal(Data normal) const |
330 |
{ |
331 |
Finley_Mesh* mesh=m_finleyMesh.get() |
332 |
normal_access=normal.createRandomAccess(normal.getFunctionSpace()); |
333 |
switch(normal.getFunctionSpaceType()) { |
334 |
case(FINLEY_NODES): |
335 |
Finley_ErrorCode=VALUE_ERROR; |
336 |
sprintf(Finley_ErrorMsg,"Finley does not support surface normal vectors for nodes"); |
337 |
break; |
338 |
case(FINLEY_ELEMENTS): |
339 |
Finley_ErrorCode=VALUE_ERROR; |
340 |
sprintf(Finley_ErrorMsg,"Finley does not support surface normal vectors for elements"); |
341 |
break; |
342 |
case (FINLEY_FACE_ELEMENTS): |
343 |
Finley_Assemble_setNormal(mesh->Nodes,mesh->FaceElements,normal_access); |
344 |
break; |
345 |
case(FINLEY_POINTS): |
346 |
Finley_ErrorCode=VALUE_ERROR; |
347 |
sprintf(Finley_ErrorMsg,"Finley does not support surface normal vectors for point elements"); |
348 |
break; |
349 |
case (FINLEY_CONTACT_ELEMENTS_2): |
350 |
Finley_Assemble_setNormal(mesh->Nodes,mesh->ContactElements,normal_access); |
351 |
break; |
352 |
case (FINLEY_CONTACT_ELEMENTS_1): |
353 |
Finley_Assemble_setNormal(mesh->Nodes,mesh->ContactElements,normal_access); |
354 |
break; |
355 |
case(FINLEY_DEGREES_OF_FREEDOM) { |
356 |
Finley_ErrorCode=VALUE_ERROR; |
357 |
sprintf(Finley_ErrorMsg,"Finley does not support surface normal vectors for degrees of freedom."); |
358 |
break; |
359 |
case(FINLEY_REDUCED_DEGREES_OF_FREEDOM) { |
360 |
Finley_ErrorCode=VALUE_ERROR; |
361 |
sprintf(Finley_ErrorMsg,"Finley does not support surface normal vectors for reduced degrees of freedom."); |
362 |
break; |
363 |
default: |
364 |
Finley_ErrorCode=VALUE_ERROR; |
365 |
sprintf(Finley_ErrorMsg,"Finley does not know anything about function space type %d",normal.getFunctionSpaceType()); |
366 |
break; |
367 |
} |
368 |
checkFinleyError(); |
369 |
} |
370 |
// |
371 |
// replaces the values of an Data object data by the corresponding values from new_data where tagged with tag: |
372 |
// |
373 |
void MeshAdapter::insertTaggedValue(Data data,int tag, Data new_data) const |
374 |
{ |
375 |
Finley_Mesh* mesh=m_finleyMesh.get() |
376 |
data_access=data.createRandomAccess(); |
377 |
new_data_access=new_data.createReadAccess(); |
378 |
|
379 |
switch(data.getFunctionSpaceType()) { |
380 |
case(FINLEY_NODES): |
381 |
Finley_Assemble_insertTaggedValue(data_access,mesh->Nodes,(maybelong)tag,new_data_access); |
382 |
break; |
383 |
case(FINLEY_ELEMENTS): |
384 |
Finley_Assemble_insertTaggedValue(data_access,mesh->Elements,(maybelong)tag,new_data_access); |
385 |
break; |
386 |
case(FINLEY_FACE_ELEMENTS): |
387 |
Finley_Assemble_insertTaggedValue(data_access,mesh->FaceElements,(maybelong)tag,new_data_access); |
388 |
break; |
389 |
case(FINLEY_POINTS): |
390 |
Finley_Assemble_insertTaggedValue(data_access,mesh->Points,(maybelong)tag,new_data_access); |
391 |
break; |
392 |
case(FINLEY_CONTACT_ELEMENTS_1): |
393 |
Finley_Assemble_insertTaggedValue(data_access,mesh->ContactElements,(maybelong)tag,new_data_access); |
394 |
break; |
395 |
case(FINLEY_CONTACT_ELEMENTS_2): |
396 |
Finley_Assemble_insertTaggedValue(data_access,mesh->ContactElements,(maybelong)tag,new_data_access); |
397 |
break; |
398 |
case(FINLEY_DEGREES_OF_FREEDOM): |
399 |
Finley_ErrorCode=VALUE_ERROR; |
400 |
sprintf(Finley_ErrorMsg,"Tagged values for degrees of freedorm is not supported."); |
401 |
break; |
402 |
case(FINLEY_REDUCED_DEGREES_OF_FREEDOM): |
403 |
Finley_ErrorCode=VALUE_ERROR; |
404 |
sprintf(Finley_ErrorMsg,"Tagged values for reduced degrees of freedom is not supported."); |
405 |
break; |
406 |
default: |
407 |
Finley_ErrorCode=VALUE_ERROR; |
408 |
sprintf(Finley_ErrorMsg,"Finley does not know anything about function space type %d",normal.getFunctionSpaceType()); |
409 |
break; |
410 |
} |
411 |
checkFinleyError(); |
412 |
return; |
413 |
} |
414 |
// interpolates data to other domain: |
415 |
Data MeshAdapter::interpolateACross(Data out, Data in) const |
416 |
{ |
417 |
Finley_ErrorCode=SYSTEM_ERROR; |
418 |
sprintf(Finley_ErrorMsg,"Finley does not allow interpolation across domains yet."); |
419 |
checkFinleyError(); |
420 |
} |
421 |
// interpolates data between different function spaces: |
422 |
Data MeshAdapter::interpolateOnDomain(Data out, Data in) const |
423 |
{ |
424 |
Finley_Mesh* mesh=m_finleyMesh.get() |
425 |
out_access=out.createReadAccess(); |
426 |
in_access=in.createRandomAccess(); |
427 |
switch(in.getFunctionSpaceType()) { |
428 |
case(FINLEY_NODES): |
429 |
switch(out.getFunctionSpaceType()) { |
430 |
case(FINLEY_NODES): |
431 |
if (mesh->Nodes!=NULL) Finley_DataArray_FromData(out_access,mesh->Nodes->Tag,in_access); |
432 |
break; |
433 |
case(FINLEY_ELEMENTS): |
434 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->Elements,in_access,out_access) |
435 |
break; |
436 |
case(FINLEY_FACE_ELEMENTS): |
437 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->FaceElements,in_access,out_access) |
438 |
break; |
439 |
case(FINLEY_POINTS): |
440 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->Points,in_access,out_access) |
441 |
break; |
442 |
case(FINLEY_CONTACT_ELEMENTS_1): |
443 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->ContactElements,in_access,out_access) |
444 |
break; |
445 |
case(FINLEY_CONTACT_ELEMENTS_2): |
446 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->ContactElements,in_access,out_access) |
447 |
break; |
448 |
case(FINLEY_DEGREES_OF_FREEDOM): |
449 |
if (mesh->Nodes!=NULL) |
450 |
Finley_Assemble_ScatterFromData(out_access,mesh->Nodes->numNodes,mesh->Nodes->degreeOfFreedom,mesh->Nodes->Tag,in_access); |
451 |
break; |
452 |
case(FINLEY_REDUCED_DEGREES_OF_FREEDOM): |
453 |
if (mesh->Nodes!=NULL) |
454 |
Finley_Assemble_ScatterFromData(out_access,mesh->Nodes->numNodes,mesh->Nodes->reducedDegreeOfFreedom,mesh->Nodes->Tag,in_access); |
455 |
break; |
456 |
default: |
457 |
Finley_ErrorCode=VALUE_ERROR; |
458 |
sprintf(Finley_ErrorMsg,"Finley does not know anything about function space type %d",out.getFunctionSpaceType()); |
459 |
break; |
460 |
} |
461 |
break; |
462 |
case(FINLEY_ELEMENTS): |
463 |
Finley_ErrorCode=VALUE_ERROR; |
464 |
sprintf(Finley_ErrorMsg,"No interpolation with data on elements possible."); |
465 |
break; |
466 |
case(FINLEY_FACE_ELEMENTS): |
467 |
Finley_ErrorCode=VALUE_ERROR; |
468 |
sprintf(Finley_ErrorMsg,"No interpolation with data on face elements possible."); |
469 |
break; |
470 |
case(FINLEY_POINTS): |
471 |
Finley_ErrorCode=VALUE_ERROR; |
472 |
sprintf(Finley_ErrorMsg,"No interpolation with data on points possible."); |
473 |
break; |
474 |
case(FINLEY_CONTACT_ELEMENTS_1): |
475 |
case(FINLEY_CONTACT_ELEMENTS_2): |
476 |
switch(out.getFunctionSpaceType()) { |
477 |
case(FINLEY_NODES): |
478 |
Finley_ErrorCode=VALUE_ERROR; |
479 |
sprintf(Finley_ErrorMsg,"No interpolation from contact elements to nodes possible."); |
480 |
break; |
481 |
case(FINLEY_ELEMENTS): |
482 |
sprintf(Finley_ErrorMsg,"No interpolation from contact elements to elements possible."); |
483 |
break; |
484 |
case(FINLEY_FACE_ELEMENTS): |
485 |
sprintf(Finley_ErrorMsg,"No interpolation from contact elements to face elements possible."); |
486 |
break; |
487 |
case(FINLEY_POINTS): |
488 |
sprintf(Finley_ErrorMsg,"No interpolation from contact elements to points possible."); |
489 |
break; |
490 |
case(FINLEY_CONTACT_ELEMENTS_2): |
491 |
case(FINLEY_CONTACT_ELEMENTS_1): |
492 |
if (mesh->ContactElements!=NULL) Finley_DataArray_FromData(out_access,mesh->ContactElements->Tag,in_access); |
493 |
break; |
494 |
case(FINLEY_DEGREES_OF_FREEDOM): |
495 |
sprintf(Finley_ErrorMsg,"No interpolation from contact elements to degrees of freedom possible."); |
496 |
break; |
497 |
case(FINLEY_REDUCED_DEGREES_OF_FREEDOM): |
498 |
sprintf(Finley_ErrorMsg,"No interpolation from contact elements to reduced degrees of freedom possible."); |
499 |
break; |
500 |
default: |
501 |
Finley_ErrorCode=VALUE_ERROR; |
502 |
sprintf(Finley_ErrorMsg,"Finley does not know anything about function space type %d",out.getFunctionSpaceType()); |
503 |
break; |
504 |
} |
505 |
break; |
506 |
case(FINLEY_DEGREES_OF_FREEDOM): |
507 |
switch(out.getFunctionSpaceType()) { |
508 |
case(FINLEY_NODES): |
509 |
if (mesh->Nodes!=NULL) Finley_DataArray_GatherFromData(out_access,mesh->Nodes->degreeOfFreedom,mesh->Nodes->Tag,data_access); |
510 |
break; |
511 |
case(FINLEY_ELEMENTS): |
512 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->Elements,in_access,out_access); |
513 |
break; |
514 |
case(FINLEY_FACE_ELEMENTS): |
515 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->FaceElements,in_access,out_access); |
516 |
break; |
517 |
case(FINLEY_POINTS): |
518 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->Points,in_access,out_access); |
519 |
break; |
520 |
case(FINLEY_CONTACT_ELEMENTS_1): |
521 |
case(FINLEY_CONTACT_ELEMENTS_2): |
522 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->ContactElements,in_access,out_access); |
523 |
break; |
524 |
case(FINLEY_DEGREES_OF_FREEDOM): |
525 |
if (mesh->Nodes!=NULL) Finley_DataArray_FromData(out_access,mesh->Nodes->Tag,in_access); |
526 |
break; |
527 |
case(FINLEY_REDUCED_DEGREES_OF_FREEDOM): |
528 |
if (mesh->Nodes!=NULL) Finley_DataArray_GatherFromData(out,mesh->Nodes->reducedDegreeOfFreedom,mesh->Nodes->Tag,data); |
529 |
break; |
530 |
default: |
531 |
Finley_ErrorCode=VALUE_ERROR; |
532 |
sprintf(Finley_ErrorMsg,"Finley does not know anything about function space type %d",out.getFunctionSpaceType()); |
533 |
break; |
534 |
} |
535 |
break; |
536 |
case(FINLEY_REDUCED_DEGREES_OF_FREEDOM): |
537 |
switch(out.getFunctionSpaceType()) { |
538 |
case(FINLEY_NODES): |
539 |
if (mesh->Nodes!=NULL) Finley_DataArray_GatherFromData(out,mesh->Nodes->reducedDegreeOfFreedom,mesh->Nodes->Tag,data); |
540 |
break; |
541 |
case(FINLEY_ELEMENTS): |
542 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->Elements,in_access,out_access); |
543 |
break; |
544 |
case(FINLEY_FACE_ELEMENTS): |
545 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->FaceElements,in_access,out_access); |
546 |
break; |
547 |
case(FINLEY_POINTS): |
548 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->Points,in_access,out_access); |
549 |
break; |
550 |
case(FINLEY_CONTACT_ELEMENTS_1): |
551 |
case(FINLEY_CONTACT_ELEMENTS_2): |
552 |
Finley_Assemble_interpolate(mesh->Nodes,mesh->ContactElements,in_access,out_access); |
553 |
break; |
554 |
case(FINLEY_DEGREES_OF_FREEDOM): |
555 |
Finley_ErrorCode=VALUE_ERROR; |
556 |
sprintf(Finley_ErrorMsg,"Finley does not support interpolation from reduced degrees of freedom to degrees of freedom"); |
557 |
break; |
558 |
case(FINLEY_REDUCED_DEGREES_OF_FREEDOM): |
559 |
if (mesh->Nodes!=NULL) Finley_DataArray_FromData(out_access,mesh->Nodes->Tag,in_access); |
560 |
break; |
561 |
default: |
562 |
Finley_ErrorCode=VALUE_ERROR; |
563 |
sprintf(Finley_ErrorMsg,"Finley does not know anything about function space type %d",out.getFunctionSpaceType()); |
564 |
break; |
565 |
} |
566 |
break; |
567 |
default: |
568 |
Finley_ErrorCode=VALUE_ERROR; |
569 |
sprintf(Finley_ErrorMsg,"Finley does not know anything about function space type %d",in.getFunctionSpaceType()); |
570 |
break; |
571 |
} |
572 |
checkFinleyError(); |
573 |
} |
574 |
// calculates the gradient of data: |
575 |
Data MeshAdapter::gradient(Data grad, Data arg) const |
576 |
{ |
577 |
Finley_Mesh* mesh=m_finleyMesh.get() |
578 |
arg_access=arg.createReadAccess(); |
579 |
grad_access=grad.createRandomAccess(); |
580 |
|
581 |
switch(grad.getFunctionSpaceType()) { |
582 |
case(FINLEY_NODES): |
583 |
Finley_ErrorCode=VALUE_ERROR; |
584 |
sprintf(Finley_ErrorMsg,"Gradient at nodes is not supported."); |
585 |
break; |
586 |
case(FINLEY_ELEMENTS): |
587 |
Finley_Assemble_gradient(mesh->Nodes,mesh->Elements,grad_access,arg_access); |
588 |
break; |
589 |
case(FINLEY_FACE_ELEMENTS): |
590 |
Finley_Assemble_gradient(mesh->Nodes,mesh->FaceElements,grad_access,arg_access); |
591 |
break; |
592 |
case(FINLEY_POINTS): |
593 |
Finley_ErrorCode=VALUE_ERROR; |
594 |
sprintf(Finley_ErrorMsg,"Gradient at points is not supported."); |
595 |
break; |
596 |
case(FINLEY_CONTACT_ELEMENTS_1): |
597 |
Finley_Assemble_gradient(mesh->Nodes,mesh->ContactElements,grad_access,arg_access); |
598 |
break; |
599 |
case(FINLEY_CONTACT_ELEMENTS_2): |
600 |
Finley_Assemble_gradient(mesh->Nodes,mesh->ContactElements,grad_access,arg_access); |
601 |
break; |
602 |
case(FINLEY_DEGREES_OF_FREEDOM): |
603 |
Finley_ErrorCode=VALUE_ERROR; |
604 |
sprintf(Finley_ErrorMsg,"Gradient at degrees of freedom is not supported."); |
605 |
break; |
606 |
case(FINLEY_REDUCED_DEGREES_OF_FREEDOM): |
607 |
Finley_ErrorCode=VALUE_ERROR; |
608 |
sprintf(Finley_ErrorMsg,"Gradient at reduced degrees of freedom is not supported."); |
609 |
break; |
610 |
default: |
611 |
Finley_ErrorCode=VALUE_ERROR; |
612 |
sprintf(Finley_ErrorMsg,"Finley does not know anything about function space type %d",arg.getFunctionSpaceType()); |
613 |
break; |
614 |
} |
615 |
checkFinleyError(); |
616 |
} |
617 |
|
618 |
// calculates the integral of a function defined of arg: |
619 |
PyArrayObject* MeshAdapter::integrate(Data arg) const |
620 |
{ |
621 |
Finley_Mesh* mesh=m_finleyMesh.get() |
622 |
arg=arg.createReadAccess(); |
623 |
double* integrals=(double*) TMPMEMALLOC(sizeof(double)*arg->numComponents); |
624 |
if (integrals==NULL) ? |
625 |
|
626 |
switch(arg.getFunctionSpaceType()) { |
627 |
case(FINLEY_NODES): |
628 |
Finley_ErrorCode=VALUE_ERROR; |
629 |
sprintf(Finley_ErrorMsg,"Integral of data on nodes is not supported."); |
630 |
break; |
631 |
case(FINLEY_ELEMENTS): |
632 |
Finley_Assemble_integrate(mesh->Nodes,mesh->Elements,arg,integrals); |
633 |
break; |
634 |
case(FINLEY_FACE_ELEMENTS): |
635 |
Finley_Assemble_integrate(mesh->Nodes,mesh->FaceElements,arg,integrals); |
636 |
break; |
637 |
case(FINLEY_POINTS): |
638 |
Finley_ErrorCode=VALUE_ERROR; |
639 |
sprintf(Finley_ErrorMsg,"Integral of data on points is not supported."); |
640 |
break; |
641 |
case(FINLEY_CONTACT_ELEMENTS_1): |
642 |
Finley_Assemble_integrate(mesh->Nodes,mesh->ContactElements,arg,integrals); |
643 |
break; |
644 |
case(FINLEY_CONTACT_ELEMENTS_2): |
645 |
Finley_Assemble_integrate(mesh->Nodes,mesh->ContactElements,arg,integrals); |
646 |
break; |
647 |
case(FINLEY_DEGREES_OF_FREEDOM): |
648 |
Finley_ErrorCode=VALUE_ERROR; |
649 |
sprintf(Finley_ErrorMsg,"Integral of data on degrees of freedom is not supported."); |
650 |
break; |
651 |
case(FINLEY_REDUCED_DEGREES_OF_FREEDOM): |
652 |
Finley_ErrorCode=VALUE_ERROR; |
653 |
sprintf(Finley_ErrorMsg,"Integral of data on reduced degrees of freedom is not supported."); |
654 |
break; |
655 |
default: |
656 |
Finley_ErrorCode=VALUE_ERROR; |
657 |
sprintf(Finley_ErrorMsg,"Finley does not know anything about function space type %d",arg.getFunctionSpaceType()); |
658 |
break; |
659 |
} |
660 |
checkFinleyError(); |
661 |
TMPMEMFREE(integrals); |
662 |
|
663 |
return FinleyPy_turnToPyArrayObject(arg->rank,arg->dimensions,integrals); |
664 |
} |
665 |
|
666 |
// returns the size of elements: |
667 |
Data MeshAdapter::getSize(Data size) const |
668 |
{ |
669 |
Finley_Mesh* mesh=m_finleyMesh.get() |
670 |
size_access=size.createReadAccess(); |
671 |
|
672 |
switch(grad.getFunctionSpaceType()) { |
673 |
case(FINLEY_NODES): |
674 |
Finley_ErrorCode=VALUE_ERROR; |
675 |
sprintf(Finley_ErrorMsg,"Size of nodes is not supported."); |
676 |
break; |
677 |
case(FINLEY_ELEMENTS): |
678 |
Finley_Assemble_getSize(mesh->Nodes,mesh->Elements,size_access); |
679 |
break; |
680 |
case(FINLEY_FACE_ELEMENTS): |
681 |
Finley_Assemble_getSize(mesh->Nodes,mesh->FaceElements,size_access); |
682 |
break; |
683 |
case(FINLEY_POINTS): |
684 |
Finley_ErrorCode=VALUE_ERROR; |
685 |
sprintf(Finley_ErrorMsg,"Size of point elements is not supported."); |
686 |
break; |
687 |
case(FINLEY_CONTACT_ELEMENTS_1): |
688 |
case(FINLEY_CONTACT_ELEMENTS_2): |
689 |
Finley_Assemble_getSize(mesh->Nodes,mesh->ContactElements,size_access); |
690 |
break; |
691 |
case(FINLEY_DEGREES_OF_FREEDOM): |
692 |
Finley_ErrorCode=VALUE_ERROR; |
693 |
sprintf(Finley_ErrorMsg,"Size of degrees of freedom is not supported."); |
694 |
break; |
695 |
case(FINLEY_REDUCED_DEGREES_OF_FREEDOM): |
696 |
Finley_ErrorCode=VALUE_ERROR; |
697 |
sprintf(Finley_ErrorMsg,"Size of reduced degrees of freedom is not supported."); |
698 |
break; |
699 |
default: |
700 |
Finley_ErrorCode=VALUE_ERROR; |
701 |
sprintf(Finley_ErrorMsg,"Finley does not know anything about function space type %d",size.getFunctionSpaceType()); |
702 |
break; |
703 |
} |
704 |
checkFinleyError(); |
705 |
} |
706 |
// sets the location of nodes: |
707 |
void MeshAdapter::setX(Data new_x) const |
708 |
{ |
709 |
Finley_Mesh* mesh=m_finleyMesh.get() |
710 |
new_x_access=new_x.createRandomAccess(m_finleyMesh.ContinuousFunction()); |
711 |
if (mesh->Nodes!=NULL) Finley_NodeFile_setCoordinates(mesh->Nodes,new_x_access); |
712 |
checkFinleyError(); |
713 |
} |
714 |
// saves a data array in openDX format: |
715 |
void MeshAdapter::saveDX(char* filename,Data arg) const |
716 |
{ |
717 |
Finley_Mesh* mesh=m_finleyMesh.get() |
718 |
arg_access=arg.createRandomAccess(); |
719 |
Finley_saveDX(filename,mesh, arg_access); |
720 |
checkFinleyError(); |
721 |
} |
722 |
// |
723 |
// vtkObject MeshAdapter::createVtkObject() const |
724 |
// |
725 |
// returns true if data at the atom_type is considered as being cell centered: |
726 |
bool MeshAdapter::isCellOrientedAtoms(atom_type) const |
727 |
{ |
728 |
if atom_type=="Finley_Elements": return true |
729 |
elif atom_type=="Finley_Face_Elements": return true |
730 |
elif atom_type=="Finley_Points": return true |
731 |
elif atom_type=="Finley_Contact_Elements_1": return true |
732 |
elif atom_type=="Finley_Contact_Elements_0": return true |
733 |
else: |
734 |
return false |
735 |
} |
736 |
// returns a sequence of function spaces needed to interpolate data on source_atoms onto |
737 |
// target_atoms. The function returns a tuple of atoms where the last atom is target_atoms. |
738 |
// null is returned if there is no path to interpolate data from source_atoms onto |
739 |
// target_atoms. |
740 |
|
741 |
functionspacelist getInterpolationPath(source_atom_type,target_atoms) const |
742 |
{ |
743 |
|
744 |
} |
745 |
|
746 |
} // end of namespace |