Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/Application/vtkpost/matc.cpp
3203 views
1
/*****************************************************************************
2
* *
3
* Elmer, A Finite Element Software for Multiphysical Problems *
4
* *
5
* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland *
6
* *
7
* This program is free software; you can redistribute it and/or *
8
* modify it under the terms of the GNU General Public License *
9
* as published by the Free Software Foundation; either version 2 *
10
* of the License, or (at your option) any later version. *
11
* *
12
* This program is distributed in the hope that it will be useful, *
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
* GNU General Public License for more details. *
16
* *
17
* You should have received a copy of the GNU General Public License *
18
* along with this program (in file fem/GPL-2); if not, write to the *
19
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
20
* Boston, MA 02110-1301, USA. *
21
* *
22
*****************************************************************************/
23
24
/*****************************************************************************
25
* *
26
* ElmerGUI matc *
27
* *
28
*****************************************************************************
29
* *
30
* Authors: Mikko Lyly, Juha Ruokolainen and Peter R�back *
31
* Email: [email protected] *
32
* Web: http://www.csc.fi/elmer *
33
* Address: CSC - IT Center for Science Ltd. *
34
* Keilaranta 14 *
35
* 02101 Espoo, Finland *
36
* *
37
* Original Date: 15 Mar 2008 *
38
* *
39
*****************************************************************************/
40
41
#include <QtGui>
42
#include <iostream>
43
#include "epmesh.h"
44
#include "matc.h"
45
#include "vtkpost.h"
46
47
#include <vtkFloatArray.h>
48
#include <vtkUnstructuredGrid.h>
49
#include <vtkCellDerivatives.h>
50
#include <vtkPointData.h>
51
#include <vtkCellDataToPointData.h>
52
53
#ifndef FALSE
54
#define FALSE 0
55
#endif
56
57
58
59
using namespace std;
60
61
Matc::Matc(QWidget *parent)
62
: QDialog(parent)
63
{
64
ui.setupUi(this);
65
66
connect(ui.mcOK, SIGNAL(clicked()), this, SLOT(okButtonClicked()));
67
setWindowIcon(QIcon(":/icons/Mesh3D.png"));
68
69
mtc_init( NULL, stdout, stderr );
70
QString elmerGuiHome = getenv("ELMERGUI_HOME");
71
QString mcIniLoad = "source(\"" + elmerGuiHome.replace("\\", "/") + "/edf/mc.ini\")";
72
73
#if WITH_QT5 || WITH_QT6
74
mtc_domath( mcIniLoad.toLatin1().data() );
75
#else
76
mtc_domath( mcIniLoad.toAscii().data() );
77
#endif
78
79
com_init( (char *)"grad", FALSE, FALSE, com_grad, 1, 1,
80
(char *)"r = grad(f): compute gradient of a scalar variable f.\n") ;
81
82
com_init( (char *)"div", FALSE, FALSE, com_div, 1, 1,
83
(char *)"r = div(f): compute divergence of a vector variable f.\n") ;
84
85
com_init( (char *)"curl", FALSE, FALSE, com_curl, 1, 1,
86
(char *)"r = curl(f): compute curl of a vector variable f.\n") ;
87
88
com_init( (char *)"display", FALSE, FALSE, com_display, 0, 0, (char *)"display\n" );
89
90
}
91
92
Matc::~Matc()
93
{
94
}
95
96
97
void Matc::okButtonClicked()
98
{
99
close();
100
}
101
102
void Matc::grad(VtkPost* vtkPost, double *in, double *out)
103
{
104
vtkUnstructuredGrid* volumeGrid = vtkPost->GetVolumeGrid();
105
vtkUnstructuredGrid* surfaceGrid = vtkPost->GetSurfaceGrid();
106
107
vtkFloatArray *s = vtkFloatArray::New();
108
s->SetNumberOfComponents(1);
109
s->SetNumberOfTuples(vtkPost->NofNodes());
110
for( int i=0;i<vtkPost->NofNodes(); i++ )
111
s->SetValue(i,in[i] );
112
113
vtkCellDerivatives *cd = vtkCellDerivatives::New();
114
if ( volumeGrid->GetNumberOfCells()>0 ) {
115
volumeGrid->GetPointData()->SetScalars(s);
116
#if VTK_MAJOR_VERSION <= 5
117
cd->SetInput(volumeGrid);
118
#else
119
cd->SetInputData(volumeGrid);
120
#endif
121
} else {
122
surfaceGrid->GetPointData()->SetScalars(s);
123
#if VTK_MAJOR_VERSION <= 5
124
cd->SetInput(surfaceGrid);
125
#else
126
cd->SetInputData(surfaceGrid);
127
#endif
128
}
129
cd->SetVectorModeToComputeGradient();
130
cd->Update();
131
132
vtkCellDataToPointData *nd = vtkCellDataToPointData::New();
133
#if VTK_MAJOR_VERSION <= 5
134
nd->SetInput(cd->GetOutput());
135
#else
136
nd->SetInputConnection(cd->GetOutputPort());
137
#endif
138
nd->Update();
139
140
vtkDataArray *da = nd->GetOutput()->GetPointData()->GetVectors();
141
int ncomp = da->GetNumberOfComponents();
142
for( int i=0; i<vtkPost->NofNodes(); i++ )
143
for( int j=0; j<ncomp; j++ )
144
out[vtkPost->NofNodes()*j+i] = da->GetComponent(i,j);
145
146
cd->Delete();
147
nd->Delete();
148
s->Delete();
149
}
150
151
void Matc::div(VtkPost* vtkPost, double *in, double *out)
152
{
153
vtkUnstructuredGrid* volumeGrid = vtkPost->GetVolumeGrid();
154
vtkUnstructuredGrid* surfaceGrid = vtkPost->GetSurfaceGrid();
155
156
int n=volumeGrid->GetNumberOfCells();
157
int ncomp = 3;
158
159
vtkFloatArray *s = vtkFloatArray::New();
160
s->SetNumberOfComponents(ncomp);
161
s->SetNumberOfTuples(vtkPost->NofNodes());
162
163
for( int j=0;j<ncomp; j++ )
164
for( int i=0;i<vtkPost->NofNodes(); i++ )
165
s->SetComponent(i,j,in[j*vtkPost->NofNodes()+i] );
166
167
vtkCellDerivatives *cd = vtkCellDerivatives::New();
168
if ( n>0 ) {
169
volumeGrid->GetPointData()->SetVectors(s);
170
#if VTK_MAJOR_VERSION <= 5
171
cd->SetInput(volumeGrid);
172
#else
173
cd->SetInputData(volumeGrid);
174
#endif
175
} else {
176
surfaceGrid->GetPointData()->SetVectors(s);
177
#if VTK_MAJOR_VERSION <= 5
178
cd->SetInput(surfaceGrid);
179
#else
180
cd->SetInputData(surfaceGrid);
181
#endif
182
}
183
cd->SetTensorModeToComputeGradient();
184
cd->Update();
185
186
vtkCellDataToPointData *nd = vtkCellDataToPointData::New();
187
#if VTK_MAJOR_VERSION <= 5
188
nd->SetInput(cd->GetOutput());
189
#else
190
nd->SetInputConnection(cd->GetOutputPort());
191
#endif
192
nd->Update();
193
194
vtkDataArray *da = nd->GetOutput()->GetPointData()->GetTensors();
195
ncomp = da->GetNumberOfComponents();
196
for( int i=0; i<vtkPost->NofNodes(); i++ )
197
{
198
out[i] = da->GetComponent(i,0);
199
out[i] += da->GetComponent(i,4);
200
out[i] += da->GetComponent(i,8);
201
}
202
cd->Delete();
203
nd->Delete();
204
s->Delete();
205
}
206
207
208
void Matc::curl(VtkPost* vtkPost, double *in, double *out)
209
{
210
vtkUnstructuredGrid* volumeGrid = vtkPost->GetVolumeGrid();
211
vtkUnstructuredGrid* surfaceGrid = vtkPost->GetSurfaceGrid();
212
213
int n=volumeGrid->GetNumberOfCells();
214
int ncomp = 3;
215
216
vtkFloatArray *s = vtkFloatArray::New();
217
s->SetNumberOfComponents(ncomp);
218
s->SetNumberOfTuples(vtkPost->NofNodes());
219
220
for( int j=0;j<ncomp; j++ )
221
for( int i=0;i<vtkPost->NofNodes(); i++ )
222
s->SetComponent(i,j,in[j*vtkPost->NofNodes()+i] );
223
224
vtkCellDerivatives *cd = vtkCellDerivatives::New();
225
if ( n>0 ) {
226
volumeGrid->GetPointData()->SetVectors(s);
227
#if VTK_MAJOR_VERSION <= 5
228
cd->SetInput(volumeGrid);
229
#else
230
cd->SetInputData(volumeGrid);
231
#endif
232
} else {
233
surfaceGrid->GetPointData()->SetVectors(s);
234
#if VTK_MAJOR_VERSION <= 5
235
cd->SetInput(surfaceGrid);
236
#else
237
cd->SetInputData(surfaceGrid);
238
#endif
239
}
240
cd->SetTensorModeToComputeGradient();
241
cd->Update();
242
243
vtkCellDataToPointData *nd = vtkCellDataToPointData::New();
244
#if VTK_MAJOR_VERSION <= 5
245
nd->SetInput(cd->GetOutput());
246
#else
247
nd->SetInputConnection(cd->GetOutputPort());
248
#endif
249
nd->Update();
250
251
vtkDataArray *da = nd->GetOutput()->GetPointData()->GetTensors();
252
for( int i=0; i<vtkPost->NofNodes(); i++ )
253
{
254
double gx_x = da->GetComponent(i,0);
255
double gx_y = da->GetComponent(i,3);
256
double gx_z = da->GetComponent(i,6);
257
double gy_x = da->GetComponent(i,1);
258
double gy_y = da->GetComponent(i,4);
259
double gy_z = da->GetComponent(i,7);
260
double gz_x = da->GetComponent(i,2);
261
double gz_y = da->GetComponent(i,5);
262
double gz_z = da->GetComponent(i,8);
263
out[i] = gz_y-gy_z;
264
out[vtkPost->NofNodes()+i] = gx_z-gz_x;
265
out[2*vtkPost->NofNodes()+i] = gy_x-gx_y;
266
}
267
268
cd->Delete();
269
nd->Delete();
270
s->Delete();
271
}
272
273
bool Matc::SetCommand(QString cmd)
274
{
275
ui.mcEdit->setText(cmd);
276
return true;
277
}
278
279
280
QString Matc::domatc(VtkPost* vtkPost)
281
{
282
int scalarFields = vtkPost->GetScalarFields();
283
int n=vtkPost->NofNodes();
284
ScalarField* scalarField = vtkPost->GetScalarField();
285
286
QString res;
287
char *ptr;
288
LIST *lst;
289
VARIABLE *var;
290
291
QString cmd=ui.mcEdit->text().trimmed();
292
ui.mcEdit->clear();
293
294
#if WITH_QT5 || WITH_QT6
295
ptr=mtc_domath(cmd.toLatin1().data());
296
#else
297
ptr=mtc_domath(cmd.toAscii().data());
298
#endif
299
300
ui.mcHistory->append(cmd);
301
res = "";
302
if ( ptr ) {
303
res = ptr;
304
ui.mcOutput->append(res);
305
}
306
307
if ( n<=0 ) return res;
308
309
for( lst = listheaders[VARIABLES].next; lst; lst = NEXT(lst))
310
{
311
var = (VARIABLE *)lst;
312
if ( !NAME(var) || (NCOL(var) % n)!=0 ) continue;
313
if ( strcmp(NAME(var),"ans")==0 ) continue;
314
315
int found = false;
316
for( int i=0; i < scalarFields; i++ )
317
{
318
ScalarField *sf = &scalarField[i];
319
if ( NROW(var)==1 && sf->name == NAME(var) )
320
{
321
found = true;
322
if ( sf->value != MATR(var) ) {
323
free(sf->value);
324
sf->value = MATR(var);
325
sf->values = NCOL(var);
326
}
327
vtkPost->minMax(sf);
328
break;
329
} else if ( NROW(var)==3 ) {
330
QString vectorname = "";
331
int ns=sf->name.indexOf("_x"), ind=0;
332
if (ns<=0) { ns=sf->name.indexOf("_y"); ind=1; }
333
if (ns<=0) { ns=sf->name.indexOf("_z"); ind=2; }
334
if (ns >0) vectorname=sf->name.mid(0,ns);
335
336
if ( vectorname==NAME(var) )
337
{
338
found = true;
339
if ( sf->value != &M(var,ind,0) ) {
340
free(sf->value);
341
sf->values = NCOL(var);
342
sf->value = &M(var,ind,0);
343
}
344
vtkPost->minMax(sf);
345
}
346
}
347
}
348
349
if ( !found )
350
{
351
ScalarField *sf;
352
if ( NROW(var) == 1 ) {
353
sf = vtkPost->addScalarField( NAME(var),NCOL(var),MATR(var) );
354
vtkPost->minMax(sf);
355
} else if ( NROW(var) == 3 ) {
356
QString qs = NAME(var);
357
sf=vtkPost->addScalarField(qs+"_x",NCOL(var),&M(var,0,0));
358
vtkPost->minMax(sf);
359
sf=vtkPost->addScalarField(qs+"_y",NCOL(var),&M(var,1,0));
360
vtkPost->minMax(sf);
361
sf=vtkPost->addScalarField(qs+"_z",NCOL(var),&M(var,2,0));
362
vtkPost->minMax(sf);
363
}
364
}
365
}
366
367
// we may have added fields, ask again...
368
scalarFields = vtkPost->GetScalarFields();
369
370
int count=0;
371
for( int i=0; i<scalarFields; i++ )
372
{
373
ScalarField *sf = &scalarField[i];
374
375
QString vectorname = "";
376
int ns=sf->name.indexOf("_x");
377
if ( ns<=0 ) ns=sf->name.indexOf("_y");
378
if ( ns<=0 ) ns=sf->name.indexOf("_z");
379
if ( ns >0 ) vectorname=sf->name.mid(0,ns);
380
381
for( lst = listheaders[VARIABLES].next; lst; lst = NEXT(lst))
382
{
383
var = (VARIABLE *)lst;
384
if ( !NAME(var) || (NCOL(var) % n)!=0 ) continue;
385
if ( strcmp(NAME(var),"ans")==0 ) continue;
386
387
if ( NROW(var)==1 && sf->name == NAME(var) )
388
{
389
if ( count != i ) scalarField[count]=*sf;
390
count++;
391
break;
392
} else if ( NROW(var)==3 && vectorname==NAME(var) ) {
393
if ( count != i ) scalarField[count]=*sf;
394
count++;
395
}
396
}
397
}
398
if ( count<scalarFields ) vtkPost->SetScalarFields(count);
399
return res;
400
}
401
402
VARIABLE *Matc::com_grad(VARIABLE *in)
403
{
404
VARIABLE *out;
405
int n=vtkp->NofNodes(),nsteps=NCOL(in)/n;
406
407
out = var_temp_new(TYPE_DOUBLE,3,NCOL(in));
408
if ( nsteps==1 ) {
409
grad( vtkp, MATR(in), MATR(out) );
410
} else {
411
int nsize=n*sizeof(double);
412
double *outf = (double *)malloc(3*nsize);
413
for( int i=0; i<nsteps; i++ )
414
{
415
grad( vtkp, &M(in,0,i*n),outf );
416
417
memcpy( &M(out,0,i*n), &outf[0], nsize );
418
memcpy( &M(out,1,i*n), &outf[n], nsize );
419
memcpy( &M(out,2,i*n), &outf[2*n], nsize );
420
}
421
free(outf);
422
}
423
return out;
424
}
425
426
VARIABLE *Matc::com_div(VARIABLE *in)
427
{
428
VARIABLE *out;
429
int n=vtkp->NofNodes(),nsteps=NCOL(in)/n;
430
431
out = var_temp_new(TYPE_DOUBLE,1,NCOL(in));
432
if ( nsteps==1 ) {
433
div( vtkp, MATR(in), MATR(out) );
434
} else {
435
int nsize=n*sizeof(double);
436
double *inf = (double *)malloc(3*nsize);
437
for( int i=0; i<nsteps; i++ )
438
{
439
memcpy( &inf[0], &M(in,0,i*n), nsize );
440
memcpy( &inf[n], &M(in,1,i*n), nsize );
441
memcpy( &inf[2*n], &M(in,2,i*n), nsize );
442
443
div( vtkp, inf, &M(out,0,i*n));
444
}
445
free(inf);
446
}
447
return out;
448
}
449
450
VARIABLE *Matc::com_display(VARIABLE *)
451
{
452
vtkp->redrawSlot();
453
return NULL;
454
}
455
456
VARIABLE *Matc::com_curl(VARIABLE *in)
457
{
458
VARIABLE *out;
459
int n=vtkp->NofNodes(),nsteps=NCOL(in)/n;
460
461
out = var_temp_new(TYPE_DOUBLE,3,NCOL(in));
462
if ( nsteps==1 ) {
463
curl( vtkp, MATR(in), MATR(out) );
464
} else {
465
int nsize=n*sizeof(double);
466
double *inf = (double *)malloc(3*nsize);
467
double *outf = (double *)malloc(3*nsize);
468
for( int i=0; i<nsteps; i++ )
469
{
470
memcpy( &inf[0], &M(in,0,i*n), nsize);
471
memcpy( &inf[n], &M(in,1,i*n), nsize);
472
memcpy( &inf[2*n], &M(in,2,i*n), nsize);
473
474
curl( vtkp, inf, outf);
475
476
memcpy( &M(out,0,i*n), &outf[0], nsize );
477
memcpy( &M(out,1,i*n), &outf[n], nsize );
478
memcpy( &M(out,2,i*n), &outf[2*n], nsize );
479
}
480
free(inf); free(outf);
481
}
482
return out;
483
}
484
485