/*
* Copyright (C) 2010 Thorsten Liebig (Thorsten.Liebig@gmx.de)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "processfields.h"
#include "H5Cpp.h"
ProcessFields::ProcessFields(Operator* op, Engine* eng) : Processing(op, eng)
{
m_DumpMode = NO_INTERPOLATION;
m_DumpType = E_FIELD_DUMP;
// vtk-file is default
m_fileType = VTK_FILETYPE;
// SetSubSampling(1);
for (int n=0;n<3;++n)
{
numLines[n]=0;
discDLines[n]=NULL;
discLines[n]=NULL;
}
}
ProcessFields::~ProcessFields()
{
for (int n=0;n<3;++n)
{
delete[] discDLines[n];
discDLines[n]=NULL;
delete[] discLines[n];
discLines[n]=NULL;
}
}
void ProcessFields::InitProcess()
{
string names[] = {"x","y","z"};
if (m_fileType==HDF5_FILETYPE)
{
unsigned int* NrLines;
double** Lines;
if (m_DumpMode==CELL_INTERPOLATE)
{
NrLines = numDLines;
Lines = discDLines;
}
else if (m_DumpMode==NO_INTERPOLATION)
{
NrLines = numLines;
Lines = discLines;
}
else
return;
m_fileName+= ".h5";
H5::H5File* file = new H5::H5File( m_fileName , H5F_ACC_TRUNC );
H5::Group* group = new H5::Group( file->createGroup( "/Mesh" ));
for (int n=0;n<3;++n)
{
hsize_t dimsf[1]; // dataset dimensions
dimsf[0] = NrLines[n];
H5::DataSpace dataspace( 1, dimsf );
H5::FloatType datatype( H5::PredType::NATIVE_FLOAT );
H5::DataSet dataset = group->createDataSet( names[n].c_str(), datatype, dataspace );
//convert to float...
float* array = new float[NrLines[n]];
for (int i=0;icreateGroup( "/FieldData" ));
delete group;
delete file;
}
}
string ProcessFields::GetFieldNameByType(DumpType type)
{
switch (type)
{
case E_FIELD_DUMP:
return "E-Field";
case H_FIELD_DUMP:
return "H-Field";
}
return "unknown field";
}
void ProcessFields::DefineStartStopCoord(double* dstart, double* dstop)
{
if (m_DumpMode==NO_INTERPOLATION)
{
if (Op->SnapToMesh(dstart,start)==false) cerr << "ProcessFields::DefineStartStopCoord: Warning: Snapping problem, check start value!!" << endl;
if (Op->SnapToMesh(dstop,stop)==false) cerr << "ProcessFields::DefineStartStopCoord: Warning: Snapping problem, check stop value!!" << endl;
//create dual mesh
for (int n=0;n<3;++n)
{
// cerr << "start " << start[n] << "stop " << stop[n];
if (start[n]>stop[n])
{
unsigned int help = start[n];
start[n]=stop[n];
stop[n]=help;
}
numLines[n]=stop[n]-start[n]+1;
// cerr << " number of lines " << numDLines[n] << endl;
delete[] discLines[n];
discLines[n] = new double[numLines[n]];
for (unsigned int i=0;idiscLines[n][start[n]+i];
// cerr << n << " : " << discDLines[n][i] << endl;
}
}
}
else if (m_DumpMode==CELL_INTERPOLATE)
{
if (Op->SnapToMesh(dstart,start,true)==false) cerr << "ProcessFields::DefineStartStopCoord: Warning: Snapping problem, check start value!!" << endl;
if (Op->SnapToMesh(dstop,stop,true)==false) cerr << "ProcessFields::DefineStartStopCoord: Warning: Snapping problem, check stop value!!" << endl;
//create dual mesh
for (int n=0;n<3;++n)
{
// cerr << "start " << start[n] << "stop " << stop[n];
if (start[n]>stop[n])
{
unsigned int help = start[n];
start[n]=stop[n];
stop[n]=help;
}
++stop[n];
numDLines[n]=stop[n]-start[n];
// cerr << " number of lines " << numDLines[n] << endl;
delete[] discDLines[n];
discDLines[n] = new double[numDLines[n]];
for (unsigned int i=0;idiscLines[n][start[n]+i+1] + Op->discLines[n][start[n]+i]);
// cerr << n << " : " << discDLines[n][i] << endl;
}
}
}
}
double ProcessFields::CalcTotalEnergy()
{
FDTD_FLOAT**** volt = Eng->GetVoltages();
FDTD_FLOAT**** curr = Eng->GetCurrents();
double energy=0;
if (Eng==NULL) return 0.0;
unsigned int pos[3];
for (pos[0]=0;pos[0]numLines[0];++pos[0])
{
for (pos[1]=0;pos[1]numLines[1];++pos[1])
{
for (pos[2]=0;pos[2]numLines[2];++pos[2])
{
energy+=fabs(volt[0][pos[0]][pos[1]][pos[2]] * curr[1][pos[0]][pos[1]][pos[2]]);
energy+=fabs(volt[0][pos[0]][pos[1]][pos[2]] * curr[2][pos[0]][pos[1]][pos[2]]);
energy+=fabs(volt[1][pos[0]][pos[1]][pos[2]] * curr[0][pos[0]][pos[1]][pos[2]]);
energy+=fabs(volt[1][pos[0]][pos[1]][pos[2]] * curr[2][pos[0]][pos[1]][pos[2]]);
energy+=fabs(volt[2][pos[0]][pos[1]][pos[2]] * curr[0][pos[0]][pos[1]][pos[2]]);
energy+=fabs(volt[2][pos[0]][pos[1]][pos[2]] * curr[1][pos[0]][pos[1]][pos[2]]);
}
}
}
return energy*0.5;
}
//void ProcessFields::SetSubSampling(unsigned int subSampleRate, int dir)
//{
// if (dir>2) return;
// if (dir<0)
// {
// subSample[0]=subSampleRate;
// subSample[1]=subSampleRate;
// subSample[2]=subSampleRate;
// }
// else subSample[dir]=subSampleRate;
//}
void ProcessFields::WriteVTKHeader(ofstream &file, double** discLines, unsigned int* numLines)
{
file << "# vtk DataFile Version 2.0" << endl;
file << "Rectilinear Grid openEMS_ProcessFields" << endl;
file << "ASCII" << endl;
file << "DATASET RECTILINEAR_GRID " << endl;
file << "DIMENSIONS " << numLines[0] << " " << numLines[1] << " " << numLines[2] << endl;
file << "X_COORDINATES " << numLines[0] << " float" << endl;
for (unsigned int i=0;i