Path: blob/devel/ElmerGUI/Application/vtkpost/matc.cpp
3203 views
/*****************************************************************************1* *2* Elmer, A Finite Element Software for Multiphysical Problems *3* *4* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland *5* *6* This program is free software; you can redistribute it and/or *7* modify it under the terms of the GNU General Public License *8* as published by the Free Software Foundation; either version 2 *9* of the License, or (at your option) any later version. *10* *11* This program is distributed in the hope that it will be useful, *12* but WITHOUT ANY WARRANTY; without even the implied warranty of *13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *14* GNU General Public License for more details. *15* *16* You should have received a copy of the GNU General Public License *17* along with this program (in file fem/GPL-2); if not, write to the *18* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *19* Boston, MA 02110-1301, USA. *20* *21*****************************************************************************/2223/*****************************************************************************24* *25* ElmerGUI matc *26* *27*****************************************************************************28* *29* Authors: Mikko Lyly, Juha Ruokolainen and Peter R�back *30* Email: [email protected] *31* Web: http://www.csc.fi/elmer *32* Address: CSC - IT Center for Science Ltd. *33* Keilaranta 14 *34* 02101 Espoo, Finland *35* *36* Original Date: 15 Mar 2008 *37* *38*****************************************************************************/3940#include <QtGui>41#include <iostream>42#include "epmesh.h"43#include "matc.h"44#include "vtkpost.h"4546#include <vtkFloatArray.h>47#include <vtkUnstructuredGrid.h>48#include <vtkCellDerivatives.h>49#include <vtkPointData.h>50#include <vtkCellDataToPointData.h>5152#ifndef FALSE53#define FALSE 054#endif55565758using namespace std;5960Matc::Matc(QWidget *parent)61: QDialog(parent)62{63ui.setupUi(this);6465connect(ui.mcOK, SIGNAL(clicked()), this, SLOT(okButtonClicked()));66setWindowIcon(QIcon(":/icons/Mesh3D.png"));6768mtc_init( NULL, stdout, stderr );69QString elmerGuiHome = getenv("ELMERGUI_HOME");70QString mcIniLoad = "source(\"" + elmerGuiHome.replace("\\", "/") + "/edf/mc.ini\")";7172#if WITH_QT5 || WITH_QT673mtc_domath( mcIniLoad.toLatin1().data() );74#else75mtc_domath( mcIniLoad.toAscii().data() );76#endif7778com_init( (char *)"grad", FALSE, FALSE, com_grad, 1, 1,79(char *)"r = grad(f): compute gradient of a scalar variable f.\n") ;8081com_init( (char *)"div", FALSE, FALSE, com_div, 1, 1,82(char *)"r = div(f): compute divergence of a vector variable f.\n") ;8384com_init( (char *)"curl", FALSE, FALSE, com_curl, 1, 1,85(char *)"r = curl(f): compute curl of a vector variable f.\n") ;8687com_init( (char *)"display", FALSE, FALSE, com_display, 0, 0, (char *)"display\n" );8889}9091Matc::~Matc()92{93}949596void Matc::okButtonClicked()97{98close();99}100101void Matc::grad(VtkPost* vtkPost, double *in, double *out)102{103vtkUnstructuredGrid* volumeGrid = vtkPost->GetVolumeGrid();104vtkUnstructuredGrid* surfaceGrid = vtkPost->GetSurfaceGrid();105106vtkFloatArray *s = vtkFloatArray::New();107s->SetNumberOfComponents(1);108s->SetNumberOfTuples(vtkPost->NofNodes());109for( int i=0;i<vtkPost->NofNodes(); i++ )110s->SetValue(i,in[i] );111112vtkCellDerivatives *cd = vtkCellDerivatives::New();113if ( volumeGrid->GetNumberOfCells()>0 ) {114volumeGrid->GetPointData()->SetScalars(s);115#if VTK_MAJOR_VERSION <= 5116cd->SetInput(volumeGrid);117#else118cd->SetInputData(volumeGrid);119#endif120} else {121surfaceGrid->GetPointData()->SetScalars(s);122#if VTK_MAJOR_VERSION <= 5123cd->SetInput(surfaceGrid);124#else125cd->SetInputData(surfaceGrid);126#endif127}128cd->SetVectorModeToComputeGradient();129cd->Update();130131vtkCellDataToPointData *nd = vtkCellDataToPointData::New();132#if VTK_MAJOR_VERSION <= 5133nd->SetInput(cd->GetOutput());134#else135nd->SetInputConnection(cd->GetOutputPort());136#endif137nd->Update();138139vtkDataArray *da = nd->GetOutput()->GetPointData()->GetVectors();140int ncomp = da->GetNumberOfComponents();141for( int i=0; i<vtkPost->NofNodes(); i++ )142for( int j=0; j<ncomp; j++ )143out[vtkPost->NofNodes()*j+i] = da->GetComponent(i,j);144145cd->Delete();146nd->Delete();147s->Delete();148}149150void Matc::div(VtkPost* vtkPost, double *in, double *out)151{152vtkUnstructuredGrid* volumeGrid = vtkPost->GetVolumeGrid();153vtkUnstructuredGrid* surfaceGrid = vtkPost->GetSurfaceGrid();154155int n=volumeGrid->GetNumberOfCells();156int ncomp = 3;157158vtkFloatArray *s = vtkFloatArray::New();159s->SetNumberOfComponents(ncomp);160s->SetNumberOfTuples(vtkPost->NofNodes());161162for( int j=0;j<ncomp; j++ )163for( int i=0;i<vtkPost->NofNodes(); i++ )164s->SetComponent(i,j,in[j*vtkPost->NofNodes()+i] );165166vtkCellDerivatives *cd = vtkCellDerivatives::New();167if ( n>0 ) {168volumeGrid->GetPointData()->SetVectors(s);169#if VTK_MAJOR_VERSION <= 5170cd->SetInput(volumeGrid);171#else172cd->SetInputData(volumeGrid);173#endif174} else {175surfaceGrid->GetPointData()->SetVectors(s);176#if VTK_MAJOR_VERSION <= 5177cd->SetInput(surfaceGrid);178#else179cd->SetInputData(surfaceGrid);180#endif181}182cd->SetTensorModeToComputeGradient();183cd->Update();184185vtkCellDataToPointData *nd = vtkCellDataToPointData::New();186#if VTK_MAJOR_VERSION <= 5187nd->SetInput(cd->GetOutput());188#else189nd->SetInputConnection(cd->GetOutputPort());190#endif191nd->Update();192193vtkDataArray *da = nd->GetOutput()->GetPointData()->GetTensors();194ncomp = da->GetNumberOfComponents();195for( int i=0; i<vtkPost->NofNodes(); i++ )196{197out[i] = da->GetComponent(i,0);198out[i] += da->GetComponent(i,4);199out[i] += da->GetComponent(i,8);200}201cd->Delete();202nd->Delete();203s->Delete();204}205206207void Matc::curl(VtkPost* vtkPost, double *in, double *out)208{209vtkUnstructuredGrid* volumeGrid = vtkPost->GetVolumeGrid();210vtkUnstructuredGrid* surfaceGrid = vtkPost->GetSurfaceGrid();211212int n=volumeGrid->GetNumberOfCells();213int ncomp = 3;214215vtkFloatArray *s = vtkFloatArray::New();216s->SetNumberOfComponents(ncomp);217s->SetNumberOfTuples(vtkPost->NofNodes());218219for( int j=0;j<ncomp; j++ )220for( int i=0;i<vtkPost->NofNodes(); i++ )221s->SetComponent(i,j,in[j*vtkPost->NofNodes()+i] );222223vtkCellDerivatives *cd = vtkCellDerivatives::New();224if ( n>0 ) {225volumeGrid->GetPointData()->SetVectors(s);226#if VTK_MAJOR_VERSION <= 5227cd->SetInput(volumeGrid);228#else229cd->SetInputData(volumeGrid);230#endif231} else {232surfaceGrid->GetPointData()->SetVectors(s);233#if VTK_MAJOR_VERSION <= 5234cd->SetInput(surfaceGrid);235#else236cd->SetInputData(surfaceGrid);237#endif238}239cd->SetTensorModeToComputeGradient();240cd->Update();241242vtkCellDataToPointData *nd = vtkCellDataToPointData::New();243#if VTK_MAJOR_VERSION <= 5244nd->SetInput(cd->GetOutput());245#else246nd->SetInputConnection(cd->GetOutputPort());247#endif248nd->Update();249250vtkDataArray *da = nd->GetOutput()->GetPointData()->GetTensors();251for( int i=0; i<vtkPost->NofNodes(); i++ )252{253double gx_x = da->GetComponent(i,0);254double gx_y = da->GetComponent(i,3);255double gx_z = da->GetComponent(i,6);256double gy_x = da->GetComponent(i,1);257double gy_y = da->GetComponent(i,4);258double gy_z = da->GetComponent(i,7);259double gz_x = da->GetComponent(i,2);260double gz_y = da->GetComponent(i,5);261double gz_z = da->GetComponent(i,8);262out[i] = gz_y-gy_z;263out[vtkPost->NofNodes()+i] = gx_z-gz_x;264out[2*vtkPost->NofNodes()+i] = gy_x-gx_y;265}266267cd->Delete();268nd->Delete();269s->Delete();270}271272bool Matc::SetCommand(QString cmd)273{274ui.mcEdit->setText(cmd);275return true;276}277278279QString Matc::domatc(VtkPost* vtkPost)280{281int scalarFields = vtkPost->GetScalarFields();282int n=vtkPost->NofNodes();283ScalarField* scalarField = vtkPost->GetScalarField();284285QString res;286char *ptr;287LIST *lst;288VARIABLE *var;289290QString cmd=ui.mcEdit->text().trimmed();291ui.mcEdit->clear();292293#if WITH_QT5 || WITH_QT6294ptr=mtc_domath(cmd.toLatin1().data());295#else296ptr=mtc_domath(cmd.toAscii().data());297#endif298299ui.mcHistory->append(cmd);300res = "";301if ( ptr ) {302res = ptr;303ui.mcOutput->append(res);304}305306if ( n<=0 ) return res;307308for( lst = listheaders[VARIABLES].next; lst; lst = NEXT(lst))309{310var = (VARIABLE *)lst;311if ( !NAME(var) || (NCOL(var) % n)!=0 ) continue;312if ( strcmp(NAME(var),"ans")==0 ) continue;313314int found = false;315for( int i=0; i < scalarFields; i++ )316{317ScalarField *sf = &scalarField[i];318if ( NROW(var)==1 && sf->name == NAME(var) )319{320found = true;321if ( sf->value != MATR(var) ) {322free(sf->value);323sf->value = MATR(var);324sf->values = NCOL(var);325}326vtkPost->minMax(sf);327break;328} else if ( NROW(var)==3 ) {329QString vectorname = "";330int ns=sf->name.indexOf("_x"), ind=0;331if (ns<=0) { ns=sf->name.indexOf("_y"); ind=1; }332if (ns<=0) { ns=sf->name.indexOf("_z"); ind=2; }333if (ns >0) vectorname=sf->name.mid(0,ns);334335if ( vectorname==NAME(var) )336{337found = true;338if ( sf->value != &M(var,ind,0) ) {339free(sf->value);340sf->values = NCOL(var);341sf->value = &M(var,ind,0);342}343vtkPost->minMax(sf);344}345}346}347348if ( !found )349{350ScalarField *sf;351if ( NROW(var) == 1 ) {352sf = vtkPost->addScalarField( NAME(var),NCOL(var),MATR(var) );353vtkPost->minMax(sf);354} else if ( NROW(var) == 3 ) {355QString qs = NAME(var);356sf=vtkPost->addScalarField(qs+"_x",NCOL(var),&M(var,0,0));357vtkPost->minMax(sf);358sf=vtkPost->addScalarField(qs+"_y",NCOL(var),&M(var,1,0));359vtkPost->minMax(sf);360sf=vtkPost->addScalarField(qs+"_z",NCOL(var),&M(var,2,0));361vtkPost->minMax(sf);362}363}364}365366// we may have added fields, ask again...367scalarFields = vtkPost->GetScalarFields();368369int count=0;370for( int i=0; i<scalarFields; i++ )371{372ScalarField *sf = &scalarField[i];373374QString vectorname = "";375int ns=sf->name.indexOf("_x");376if ( ns<=0 ) ns=sf->name.indexOf("_y");377if ( ns<=0 ) ns=sf->name.indexOf("_z");378if ( ns >0 ) vectorname=sf->name.mid(0,ns);379380for( lst = listheaders[VARIABLES].next; lst; lst = NEXT(lst))381{382var = (VARIABLE *)lst;383if ( !NAME(var) || (NCOL(var) % n)!=0 ) continue;384if ( strcmp(NAME(var),"ans")==0 ) continue;385386if ( NROW(var)==1 && sf->name == NAME(var) )387{388if ( count != i ) scalarField[count]=*sf;389count++;390break;391} else if ( NROW(var)==3 && vectorname==NAME(var) ) {392if ( count != i ) scalarField[count]=*sf;393count++;394}395}396}397if ( count<scalarFields ) vtkPost->SetScalarFields(count);398return res;399}400401VARIABLE *Matc::com_grad(VARIABLE *in)402{403VARIABLE *out;404int n=vtkp->NofNodes(),nsteps=NCOL(in)/n;405406out = var_temp_new(TYPE_DOUBLE,3,NCOL(in));407if ( nsteps==1 ) {408grad( vtkp, MATR(in), MATR(out) );409} else {410int nsize=n*sizeof(double);411double *outf = (double *)malloc(3*nsize);412for( int i=0; i<nsteps; i++ )413{414grad( vtkp, &M(in,0,i*n),outf );415416memcpy( &M(out,0,i*n), &outf[0], nsize );417memcpy( &M(out,1,i*n), &outf[n], nsize );418memcpy( &M(out,2,i*n), &outf[2*n], nsize );419}420free(outf);421}422return out;423}424425VARIABLE *Matc::com_div(VARIABLE *in)426{427VARIABLE *out;428int n=vtkp->NofNodes(),nsteps=NCOL(in)/n;429430out = var_temp_new(TYPE_DOUBLE,1,NCOL(in));431if ( nsteps==1 ) {432div( vtkp, MATR(in), MATR(out) );433} else {434int nsize=n*sizeof(double);435double *inf = (double *)malloc(3*nsize);436for( int i=0; i<nsteps; i++ )437{438memcpy( &inf[0], &M(in,0,i*n), nsize );439memcpy( &inf[n], &M(in,1,i*n), nsize );440memcpy( &inf[2*n], &M(in,2,i*n), nsize );441442div( vtkp, inf, &M(out,0,i*n));443}444free(inf);445}446return out;447}448449VARIABLE *Matc::com_display(VARIABLE *)450{451vtkp->redrawSlot();452return NULL;453}454455VARIABLE *Matc::com_curl(VARIABLE *in)456{457VARIABLE *out;458int n=vtkp->NofNodes(),nsteps=NCOL(in)/n;459460out = var_temp_new(TYPE_DOUBLE,3,NCOL(in));461if ( nsteps==1 ) {462curl( vtkp, MATR(in), MATR(out) );463} else {464int nsize=n*sizeof(double);465double *inf = (double *)malloc(3*nsize);466double *outf = (double *)malloc(3*nsize);467for( int i=0; i<nsteps; i++ )468{469memcpy( &inf[0], &M(in,0,i*n), nsize);470memcpy( &inf[n], &M(in,1,i*n), nsize);471memcpy( &inf[2*n], &M(in,2,i*n), nsize);472473curl( vtkp, inf, outf);474475memcpy( &M(out,0,i*n), &outf[0], nsize );476memcpy( &M(out,1,i*n), &outf[n], nsize );477memcpy( &M(out,2,i*n), &outf[2*n], nsize );478}479free(inf); free(outf);480}481return out;482}483484485