You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
709 lines
19 KiB
709 lines
19 KiB
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include "portmesh.h"
|
|
#include "material.h"
|
|
#include "bc.h"
|
|
#include "tensor.h"
|
|
#include "cvtr.h"
|
|
#include "Constants.h"
|
|
#include "tri.elem"
|
|
#include "vtkwriter.h"
|
|
|
|
portMesh::portMesh(){
|
|
faceCNT = 0;
|
|
edgeCNT = 0;
|
|
nodeCNT = 0;
|
|
objCNT = 0;
|
|
objMAP = 0;
|
|
ndArray = 0;
|
|
fcArray = 0;
|
|
modeIMP = 0.;
|
|
magE = 0.;
|
|
impZ = 0.;
|
|
globToLocMap_ = 0;
|
|
}
|
|
|
|
portMesh::~portMesh(){
|
|
delete [] fcArray;
|
|
delete [] ndArray;
|
|
delete [] objMAP;
|
|
delete globToLocMap_;
|
|
}
|
|
|
|
void portMesh::writeMesh(Material *propMAT, fp_t freq){
|
|
FILE *foo;
|
|
char meshName[180];
|
|
int i, j, k, objNum;
|
|
tensor epsr, mur;
|
|
node *nd;
|
|
vtr vv, vv2D;
|
|
|
|
sprintf(meshName, "%s.mesh", portName);
|
|
foo = fopen(meshName, "w");
|
|
fprintf(foo, "%.20e %.20e %.20e\n", (coord.O.getx()), (coord.O.gety()), (coord.O.getz()));
|
|
fprintf(foo, "%.20e %.20e %.20e\n", (coord.x_axis.getx()), (coord.x_axis.gety()), (coord.x_axis.getz()));
|
|
fprintf(foo, "%.20e %.20e %.20e\n", (coord.y_axis.getx()), (coord.y_axis.gety()), (coord.y_axis.getz()));
|
|
fprintf(foo, "1.0 \n");
|
|
fprintf(foo, "%d %d %d \n", objCNT, nodeCNT, faceCNT);
|
|
|
|
for(i = 0; i < nodeCNT; i++){
|
|
nd = ndArray[i];
|
|
vv = nd->getCoord();
|
|
vv2D = coord.Transform(vv);
|
|
|
|
fprintf(foo, "0 %.20e %.20e \n", (vv2D.getx()), (vv2D.gety()));
|
|
}
|
|
|
|
for(i = 0; i < faceCNT; i++){
|
|
objNum = fcArray[i]->gettetraPtr(0)->getobjNum();
|
|
fprintf(foo, "%d %d %d %d \n", getobjMAP(objNum) + 1, fcArray[i]->getNodePtr(0)->num2D, fcArray[i]->getNodePtr(1)->num2D, fcArray[i]->getNodePtr(2)->num2D);
|
|
for(j = 0; j < 3; j++){
|
|
if(fcArray[i]->getEdge(j) == 0)
|
|
fprintf(foo, " 1 ");
|
|
else
|
|
fprintf(foo, " 0 ");
|
|
}
|
|
|
|
fprintf(foo, "\n");
|
|
}
|
|
|
|
for(i = 0; i < objCNT; i++){
|
|
objNum = objMAP[i];
|
|
epsr = propMAT[objNum].epsr;
|
|
mur = propMAT[objNum].mur;
|
|
epsr = coord.Transform(epsr);
|
|
|
|
fprintf(foo, "%d \n", i + 1);
|
|
for(j = 0; j < 3; j++){
|
|
for(k = 0; k < 3; k++){
|
|
fprintf(foo, "%.20e ", (epsr.getEntry(j, k)));
|
|
}
|
|
fprintf(foo, "\n");
|
|
}
|
|
|
|
for(j = 0; j < 3; j++){
|
|
for(k = 0; k < 3; k++){
|
|
fprintf(foo, "%.20e ", (mur.getEntry(j, k)));
|
|
}
|
|
fprintf(foo, "\n");
|
|
}
|
|
|
|
for(j = 0; j < 3; j++){
|
|
for(k = 0; k < 3; k++){
|
|
fprintf(foo, "0.0 ");
|
|
}
|
|
fprintf(foo, "\n");
|
|
}
|
|
|
|
for(j = 0; j < 3; j++){
|
|
for(k = 0; k < 3; k++){
|
|
fprintf(foo, "0.0 ");
|
|
}
|
|
fprintf(foo, "\n");
|
|
}
|
|
}
|
|
|
|
fprintf(foo, "%d \n", vline.np);
|
|
for(i = 0; i < vline.np; i++){
|
|
vv = vline.coord[i];
|
|
cout << vv.getx() << " " << vv.gety() << " " << vv.getz() << endl;
|
|
vv2D = coord.Transform(vv);
|
|
fprintf(foo, "%.20e %.20e \n", vv2D.getx(), vv2D.gety());
|
|
}
|
|
fclose(foo);
|
|
}
|
|
|
|
|
|
void portMesh::writeMesh(Material* propMat){
|
|
int i, j, k;
|
|
vtr vv, vv2D;
|
|
|
|
char meshName[STRLEN];
|
|
memset(meshName, 0, STRLEN*sizeof(char));
|
|
sprintf(meshName, "%s.mesh", portName);
|
|
FILE* foo = fopen(meshName, "w");
|
|
vtr& O = coord.getO();
|
|
vtr& xAxis = coord.getXAxis();
|
|
vtr& yAxis = coord.getYAxis();
|
|
|
|
fprintf(foo, "%.20e %.20e %.20e\n", (O.getx()), (O.gety()), (O.getz()));
|
|
fprintf(foo, "%.20e %.20e %.20e\n", (xAxis.getx()), (xAxis.gety()), (xAxis.getz()));
|
|
fprintf(foo, "%.20e %.20e %.20e\n", (yAxis.getx()), (yAxis.gety()), (yAxis.getz()));
|
|
fprintf(foo, "1.0\n");
|
|
fprintf(foo, "%d %d %d \n", objCNT, nodeCNT, faceCNT);
|
|
|
|
for(i = 0; i < nodeCNT; i++){
|
|
node* nd = ndArray[i];
|
|
vv = nd->getCoord();
|
|
vv2D = coord.Transform(vv);
|
|
fprintf(foo, "0 %.20e %.20e\n", (vv2D.getx()), (vv2D.gety()));
|
|
}
|
|
|
|
int objNum = 0;
|
|
for(i = 0; i < faceCNT; i++){
|
|
objNum = fcArray[i]->getTetra(0).getobjNum();
|
|
fprintf(foo, "%d %d %d %d\n", getobjMAP(objNum) + 1,
|
|
globToLocMap_->find(fcArray[i]->getNode(0)->getid())->second,
|
|
globToLocMap_->find(fcArray[i]->getNode(1)->getid())->second,
|
|
globToLocMap_->find(fcArray[i]->getNode(2)->getid())->second);
|
|
for(j = 0; j < 3; j++){
|
|
if(fcArray[i]->getEdge(j)->getbType() == pecType)
|
|
fprintf(foo, " 1 ");
|
|
else
|
|
fprintf(foo, " 0 ");
|
|
}
|
|
fprintf(foo, "\n");
|
|
}
|
|
|
|
tensor epsr;
|
|
tensor mur;
|
|
for(i = 0; i < objCNT; i++){
|
|
objNum = objMAP[i];
|
|
epsr = propMat[objNum].epsr;
|
|
mur = propMat[objNum].mur;
|
|
epsr = coord.Transform(epsr);
|
|
|
|
fprintf(foo, "%d\n", i + 1);
|
|
for(j = 0; j < 3; j++){
|
|
for(k = 0; k < 3; k++)
|
|
fprintf(foo, "%.20e ", (epsr.getEntry(j, k)));
|
|
fprintf(foo, "\n");
|
|
}
|
|
for(j = 0; j < 3; j++){
|
|
for(k = 0; k < 3; k++)
|
|
fprintf(foo, "%.20e ", (mur.getEntry(j, k)));
|
|
fprintf(foo, "\n");
|
|
}
|
|
for(j = 0; j < 3; j++){
|
|
for(k = 0; k < 3; k++)
|
|
fprintf(foo, "%.20e ", 0.0);
|
|
fprintf(foo, "\n");
|
|
}
|
|
for(j = 0; j < 3; j++){
|
|
for(k = 0; k < 3; k++) fprintf(foo, "0.0 ");
|
|
fprintf(foo, "\n");
|
|
}
|
|
}
|
|
|
|
fprintf(foo, "%d\n", vline.np);
|
|
|
|
for(i = 0; i < vline.np; i++){
|
|
cout << vv.getx() << " " << vv.gety() << " " << vv.getz() << endl;
|
|
vv = vline.coord[i];
|
|
vv2D = coord.Transform(vv);
|
|
fprintf(foo, "%.20e %.20e\n", (vv2D.getx()), (vv2D.gety()));
|
|
}
|
|
|
|
fclose(foo);
|
|
}
|
|
|
|
void portMesh::makeObjMap(){
|
|
int i, tmpCNT, objNum;
|
|
|
|
tmpCNT = 0;
|
|
for(i = 0; i < faceCNT; i++){
|
|
objNum = fcArray[i]->gettetraPtr(0)->getobjNum();
|
|
tmpCNT = (tmpCNT > objNum) ? tmpCNT : objNum;
|
|
}
|
|
tmpCNT++;
|
|
|
|
objMAP = new int[tmpCNT];
|
|
for(i = 0; i < faceCNT; i++){
|
|
objNum = fcArray[i]->gettetraPtr(0)->getobjNum();
|
|
insertOBJ(objNum);
|
|
}
|
|
}
|
|
|
|
int portMesh::getobjMAP(int obj){
|
|
int i;
|
|
for(i = 0; i < objCNT; i++){
|
|
if(objMAP[i] == obj) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void portMesh::insertOBJ(int obj){
|
|
int i;
|
|
|
|
for(i = 0; i < objCNT; i++){
|
|
if(objMAP[i] == obj)
|
|
return;
|
|
}
|
|
|
|
objMAP[objCNT] = obj;
|
|
objCNT++;
|
|
}
|
|
|
|
void portMesh::setFaceCnt(int faceCnt){
|
|
faceCNT = faceCnt;
|
|
fcArray = new face*[faceCNT];
|
|
memset(fcArray, 0, faceCNT * sizeof(face*));
|
|
}
|
|
|
|
void portMesh::setNodeCnt(int nodeCnt){
|
|
nodeCNT = nodeCnt;
|
|
ndArray = new node*[nodeCNT];
|
|
memset(ndArray, 0, nodeCNT * sizeof(node*));
|
|
}
|
|
|
|
// Read from portnems.vpath the definition of the path which defines
|
|
// the voltage integration forthe mode. This is necessary to do
|
|
// de-embedding to 50 ohm transmission lines. ifthe file does not exist
|
|
// then the S parameters will be expressed in terms of the intrinsic
|
|
// impedances.
|
|
//
|
|
|
|
void portMesh::readVline(fp_t unit_conv){
|
|
FILE *foo;
|
|
char vlineName[180];
|
|
int i, np;
|
|
fp_t x, y, z;
|
|
double x_,y_,z_;
|
|
|
|
sprintf(vlineName, "%s.vpath", portName);
|
|
if((foo = fopen(vlineName, "r")) == NULL){
|
|
vline.np = 0;
|
|
vline.coord = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
fscanf(foo, "%d", &np);
|
|
vline.np = np;
|
|
vline.coord = new vtr[np];
|
|
for(i = 0; i < np; i++){
|
|
fscanf(foo, "%le", &x_);
|
|
fscanf(foo, "%le", &y_);
|
|
fscanf(foo, "%le", &z_);
|
|
(vline.coord[i]).setvtr((fp_t)x_ * unit_conv, (fp_t)y_ * unit_conv, (fp_t)z_ * unit_conv);
|
|
}
|
|
fclose(foo);
|
|
}
|
|
|
|
void portMesh::readVline(fp_t unit_conv, fp_t& xoff, fp_t& yoff, fp_t& zoff){
|
|
FILE *foo;
|
|
char vlineName[180];
|
|
int i, np;
|
|
fp_t x, y, z;
|
|
double x_,y_,z_;
|
|
|
|
sprintf(vlineName, "%s.vpath", portName);
|
|
if((foo = fopen(vlineName, "r")) == NULL){
|
|
vline.np = 0;
|
|
vline.coord = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
fscanf(foo, "%d", &np);
|
|
vline.np = np;
|
|
vline.coord = new vtr[np];
|
|
for(i = 0; i < np; i++){
|
|
fscanf(foo, "%le", &x_);
|
|
fscanf(foo, "%le", &y_);
|
|
fscanf(foo, "%le", &z_);
|
|
(vline.coord[i]).setvtr((fp_t)x_ * unit_conv + xoff, (fp_t)y_ * unit_conv + yoff, (fp_t)z_ * unit_conv + zoff);
|
|
}
|
|
fclose(foo);
|
|
}
|
|
|
|
// portMesh::makeRHS
|
|
// foreach port, we assemble a right-hand-side to be used as the
|
|
// excitation forthe computations of the entire scattering matrix
|
|
// of the multiport microwave components.
|
|
// void portMesh::makeRHS(fp_t freq, int dim, int *Part, portCounter pC){
|
|
// FILE *foo;
|
|
// char solname[180], cc;
|
|
// int i, j, k, tmpCNT, triMAP[8];
|
|
// vtr tmpVTR, nvtr[2];
|
|
// vtr hvtr[6], jvtr[6];
|
|
// cVtr tvtr;
|
|
// fp_t jval[8], rhs, cval;
|
|
// face *fc;
|
|
// denseMat elemM(8, 8);
|
|
// Material prop;
|
|
// fp_t scaleF;
|
|
|
|
// cval = -Uo;
|
|
// portY.N = dim;
|
|
// portY.entry = new fp_t[dim];
|
|
|
|
// sprintf(solname, "%s.1H1", portName);
|
|
// if((foo = fopen(solname, "rb")) == NULL){
|
|
// printf("Could not open File %s \n", solname);
|
|
// exit(1);
|
|
// }
|
|
// fread(&tmpCNT, sizeof(int ), 1, foo);
|
|
// fread(&cc, sizeof(char ), 1, foo);
|
|
// fread(&cc, sizeof(char ), 1, foo);
|
|
// fread(&tmpCNT, sizeof(int ), 1, foo);
|
|
// fread(&gamma, sizeof(fp_t ), 1, foo);
|
|
// fread(&gamma, sizeof(fp_t ), 1, foo);
|
|
// for(i = 0; i < 3; i++){
|
|
// fread(&tmpVTR, sizeof(vtr ), 1, foo);
|
|
// }
|
|
// fread(&modeIMP, sizeof(fp_t ), 1, foo);
|
|
// // scaleF = modeIMP;
|
|
// // scaleF = scaleF / impZ;
|
|
// // scaleF = sqrt(scaleF);
|
|
// scaleF = 1.0;
|
|
// for(i = 0; i < 8; i++)
|
|
// jval[i] = 0.0;
|
|
// for(i = 0; i < faceCNT; i++){
|
|
// fc = fcArray[i];
|
|
// maketriMAP(fc, Part, triMAP, pC);
|
|
|
|
// for(j = 0; j < 6; j++){
|
|
// fread(&tvtr, sizeof(cVtr ), 1, foo);
|
|
// hvtr[j].setvtr(tvtr.x.real(), tvtr.y.real(), tvtr.z.real());
|
|
// hvtr[j] = hvtr[j] * scaleF;
|
|
|
|
// jvtr[j].setvtr(hvtr[j].gety() * (-1.0), hvtr[j].getx(), 0.0);
|
|
// }
|
|
// fc->P2toH1(jvtr, jval, coord);
|
|
// fc->makeElemMatrix(prop, coord, 8, &elemM);
|
|
// for(j = 0; j < 8; j++){
|
|
// if(triMAP[j] < 0)
|
|
// continue;
|
|
// rhs = 0.0;
|
|
// for(k = 0; k < 8; k++){
|
|
// rhs = rhs + jval[k] * elemM.getEntry(j, k);
|
|
// }
|
|
// portY.addentry(triMAP[j], rhs * cval);
|
|
// }
|
|
// }
|
|
// fclose(foo);
|
|
// }
|
|
|
|
struct dbl_vtr{
|
|
double x,y,z;
|
|
};
|
|
|
|
struct dbl_cvtr{
|
|
complex<double> x,y,z;
|
|
};
|
|
|
|
void portMesh::makeRHS_E(){
|
|
FILE *foo;
|
|
char solname[StrOutput], cc;
|
|
int i, j, tmpCNT, triMAP[8];
|
|
vtr nvtr[2];
|
|
dbl_vtr tmpVTR;
|
|
vtr evtr[NumOfEdges];
|
|
dbl_cvtr tvtr;
|
|
fp_t cval;
|
|
face *fc;
|
|
fp_t scaleF;
|
|
|
|
double gamma_,modeIMP_;
|
|
|
|
sprintf(solname, "%s.1E1", portName);
|
|
if((foo = fopen(solname, "rb")) == NULL){
|
|
printf("Could not open File %s \n", solname);
|
|
exit(1);
|
|
}
|
|
|
|
fread(&tmpCNT, sizeof(int), 1, foo);
|
|
fread(&cc, sizeof(char), 1, foo);
|
|
fread(&cc, sizeof(char), 1, foo);
|
|
fread(&tmpCNT, sizeof(int), 1, foo);
|
|
fread(&gamma_, sizeof(double), 1, foo);
|
|
fread(&gamma_, sizeof(double), 1, foo);
|
|
for(i = 0; i < NumOfUnitaryVectors; i++){
|
|
fread(&tmpVTR, sizeof(dbl_vtr), 1, foo);
|
|
}
|
|
fread(&modeIMP_, sizeof(double), 1, foo);
|
|
|
|
gamma = (fp_t)gamma_;
|
|
modeIMP = (fp_t)modeIMP_;
|
|
|
|
scaleF = 1.0;
|
|
for(j = 0; j < NumOfEdges; j++){
|
|
evtr[j].setvtr(0.0, 0.0, 0.0);
|
|
}
|
|
|
|
for(i = 0; i < faceCNT; i++){
|
|
fc = fcArray[i];
|
|
for(j = 0; j < 6; j++){
|
|
fread(&tvtr, sizeof(dbl_cvtr), 1, foo);
|
|
|
|
evtr[j] = coord.x_axis * (fp_t)(tvtr.x.real()) + coord.y_axis * (fp_t)(tvtr.y.real()) + coord.z_axis * (fp_t)(tvtr.z.real());
|
|
evtr[j] = evtr[j] * scaleF;
|
|
}
|
|
fc->Set_WgSolverExcitation_E(evtr);
|
|
}
|
|
fclose(foo);
|
|
}
|
|
|
|
void portMesh::makeRHS_H(){
|
|
FILE *foo;
|
|
char solname[180], cc;
|
|
int i, j, tmpCNT, triMAP[8];
|
|
vtr nvtr[2];
|
|
dbl_vtr tmpVTR;
|
|
vtr hvtr[6];
|
|
dbl_cvtr tvtr;
|
|
fp_t cval;
|
|
face *fc;
|
|
fp_t scaleF;
|
|
double gamma_,modeIMP_;
|
|
|
|
sprintf(solname, "%s.1H1", portName);
|
|
if((foo = fopen(solname, "rb")) == NULL){
|
|
printf("Could not open File %s \n", solname);
|
|
exit(1);
|
|
}
|
|
fread(&tmpCNT, sizeof(int), 1, foo);
|
|
fread(&cc, sizeof(char), 1, foo);
|
|
fread(&cc, sizeof(char), 1, foo);
|
|
fread(&tmpCNT, sizeof(int), 1, foo);
|
|
fread(&gamma_, sizeof(double), 1, foo);
|
|
fread(&gamma_, sizeof(double), 1, foo);
|
|
|
|
for(i = 0; i < 3; i++)
|
|
fread(&tmpVTR, sizeof(dbl_vtr), 1, foo);
|
|
|
|
fread(&modeIMP_, sizeof(double ), 1, foo);
|
|
|
|
gamma = (fp_t)gamma_;
|
|
modeIMP = (fp_t)modeIMP_;
|
|
|
|
scaleF = 1.0;
|
|
for(j = 0; j < 6; j++){
|
|
hvtr[j].setvtr(0.0, 0.0, 0.0);
|
|
}
|
|
for(i = 0; i < faceCNT; i++){
|
|
fc = fcArray[i];
|
|
for(j = 0; j < 6; j++){
|
|
fread(&tvtr, sizeof(dbl_cvtr), 1, foo);
|
|
hvtr[j] = coord.x_axis * (fp_t)(tvtr.x.real()) + coord.y_axis * (fp_t)(tvtr.y.real()) + coord.z_axis * (fp_t)(tvtr.z.real());
|
|
hvtr[j] = hvtr[j] * scaleF;
|
|
}
|
|
fc->Set_WgSolverExcitation_H(hvtr);
|
|
}
|
|
fclose(foo);
|
|
}
|
|
|
|
void portMesh::makeCoordSystem(){
|
|
vtr zAxis = findFaceNormal(*(fcArray[0]));
|
|
zAxis = zAxis * (-1.0); //point inside tetr(0)
|
|
// zAxis = zAxis *(1.0); // forSMT
|
|
// forthe SMT example somehow the zAxis was (0,0,1) but from the geometry
|
|
// it should be (0,0,-1). So I flip the sign to make the right direction
|
|
coord.setz_axis(zAxis); // I always assume the zAxis is the portDirection
|
|
|
|
node* vertexNode = 0;
|
|
node* edgeNode = 0;
|
|
findNodes(&vertexNode, &edgeNode);
|
|
if(vertexNode == 0){
|
|
cerr << "ERROR: PortMesh::makeCoordSystem: " << "Could not find a vertex node forport " << portName << endl;
|
|
exit(1);
|
|
}
|
|
if(edgeNode == 0){
|
|
cerr << "ERROR: PortMesh::makeCoordSystem: " << "Could not find an edge node forport " << portName << endl;
|
|
exit(1);
|
|
}
|
|
vtr O = vertexNode->getCoord();
|
|
coord.setO(O);
|
|
|
|
vtr xAxis = edgeNode->getCoord() - O;
|
|
coord.setx_axis(xAxis);
|
|
|
|
vtr yAxis = zAxis * xAxis;
|
|
coord.sety_axis(yAxis);
|
|
vtr PortDirection = coord.getZAxis();
|
|
|
|
cout << portName << endl;
|
|
cout << "( " << PortDirection.getx() << ", " << PortDirection.gety() << ", " << PortDirection.getz() << " )" << endl;
|
|
|
|
fp_t Port_Direction_mag = sqrt(PortDirection.getx() * PortDirection.getx() + PortDirection.gety() * PortDirection.gety() + PortDirection.getz() * PortDirection.getz());
|
|
|
|
fp_t px = PortDirection.getx()/Port_Direction_mag;
|
|
fp_t py = PortDirection.gety()/Port_Direction_mag;
|
|
fp_t pz = PortDirection.getz()/Port_Direction_mag;
|
|
PortDirection_vtr.setvtr(px,py,pz);
|
|
|
|
for(int i = 0; i < faceCNT; i++)
|
|
fcArray[i]->getbcPtr()->set_PortDirection( PortDirection_vtr.getx(), PortDirection_vtr.gety(), PortDirection_vtr.getz());
|
|
}
|
|
|
|
vtr portMesh::findFaceNormal(face& Face){
|
|
int i;
|
|
|
|
vtr vv0 = Face.getNode(0)->getCoord();
|
|
vtr vv1 = Face.getNode(1)->getCoord();
|
|
vtr vv2 = Face.getNode(2)->getCoord();
|
|
vtr nvtr = (vv1 - vv0) * (vv2 - vv0);
|
|
nvtr = nvtr * 0.5;
|
|
|
|
tetra& Tetra = Face.getTetra(0);
|
|
if(Tetra == 0){
|
|
cerr << "ERROR: DgGroup::findFaceNormal: " << "Port face does not have a correct tetra link." << endl;
|
|
exit(1);
|
|
}else{
|
|
vv0.setvtr(0., 0., 0.);
|
|
for(i = 0; i < 4; i++){
|
|
vv0 = vv0 + Tetra.getNode(i)->getCoord();
|
|
}
|
|
vv0 = vv0 * 0.25;
|
|
vv0 = vv0 - vv1;
|
|
if(dotP(vv0, nvtr) > 0.)
|
|
nvtr = nvtr * (-1.);
|
|
}
|
|
nvtr = nvtr * (1.0 / nvtr.magnitude());
|
|
return nvtr;
|
|
}
|
|
|
|
void portMesh::findNodes(node** vNode, node** eNode){
|
|
int i, j;
|
|
vtr vv1;
|
|
vtr vv2;
|
|
|
|
for(i = 0; i < faceCNT; i++){
|
|
bool foundVertex = false;
|
|
bool foundEdge = false;
|
|
node* vertexNode = 0;
|
|
node* edgeNode = 0;
|
|
for(j = 0; j < 3; j++){
|
|
node* Node = fcArray[i]->getNodePtr(j);
|
|
if(Node->getPType() == VERTEX_NODE){
|
|
if(foundVertex == true){
|
|
if(foundEdge == true){
|
|
vv1 = edgeNode->getCoord() - vertexNode->getCoord();
|
|
vv2 = Node->getCoord() - vertexNode->getCoord();
|
|
if(vv2.magnitude() < vv1.magnitude()){
|
|
edgeNode = Node;
|
|
}
|
|
}else{
|
|
foundEdge = true;
|
|
edgeNode = Node;
|
|
}
|
|
}else{
|
|
vertexNode = Node;
|
|
foundVertex = true;
|
|
}
|
|
}
|
|
if(Node->getPType() == EDGE_NODE){
|
|
foundEdge = 1;
|
|
edgeNode = Node;
|
|
}
|
|
}
|
|
if((foundVertex) && (foundEdge)){
|
|
*vNode = vertexNode;
|
|
*eNode = edgeNode;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void portMesh::writeVtk(){
|
|
int i, j;
|
|
char hFileName[STRLEN];
|
|
char eFileName[STRLEN];
|
|
FILE* fdE;
|
|
FILE* fdH;
|
|
char cc;
|
|
int dummy;
|
|
dbl_vtr dummyVtr;
|
|
complex<double> gamma_;
|
|
double modeIMP_;
|
|
|
|
sprintf(eFileName, "%s.1E1", portName);
|
|
if((fdE = fopen(eFileName, "rb")) == 0){
|
|
cerr << "ERROR: PortMesh::makeRhs: " << "Could not open file " << eFileName << " forread." << endl;
|
|
exit(1);
|
|
}
|
|
|
|
fread(&dummy, sizeof(int), 1, fdE);
|
|
fread(&cc, sizeof(char), 1, fdE);
|
|
fread(&cc, sizeof(char), 1, fdE);
|
|
fread(&dummy, sizeof(int), 1, fdE);
|
|
fread(&gamma_, sizeof(complex<double>), 1, fdE);
|
|
for(i = 0; i < 3; i++)
|
|
fread(&dummyVtr, sizeof(dbl_vtr), 1, fdE);
|
|
fread(&modeIMP_, sizeof(double), 1, fdE);
|
|
|
|
sprintf(hFileName, "%s.1H1", portName);
|
|
if((fdH = fopen(hFileName, "rb")) == 0){
|
|
cerr << "ERROR: PortMesh::makeRhs: " << "Could not open file " << hFileName << " forread." << endl;
|
|
exit(1);
|
|
}
|
|
|
|
fread(&dummy, sizeof(int), 1, fdH);
|
|
fread(&cc, sizeof(char), 1, fdH);
|
|
fread(&cc, sizeof(char), 1, fdH);
|
|
fread(&dummy, sizeof(int), 1, fdH);
|
|
fread(&gamma_, sizeof(complex<double>), 1, fdH);
|
|
for(i = 0; i < 3; i++)
|
|
fread(&dummyVtr, sizeof(dbl_vtr), 1, fdH);
|
|
fread(&modeIMP_, sizeof(double), 1, fdH);
|
|
|
|
// fill the port field with averaged values
|
|
vtr* eField = new vtr[nodeCNT];
|
|
vtr* hField = new vtr[nodeCNT];
|
|
int* count = new int[nodeCNT];
|
|
memset(count, 0, nodeCNT*sizeof(int));
|
|
|
|
int index;
|
|
dbl_cvtr evtr;
|
|
dbl_cvtr hvtr;
|
|
vtr tmpE; // change here
|
|
vtr tmpH;
|
|
for(i = 0; i < faceCNT; i++){
|
|
for(j = 0; j < SEC_ORDER_FACE_NODES; j++){
|
|
fread(&evtr, sizeof(dbl_cvtr), 1, fdE);
|
|
fread(&hvtr, sizeof(dbl_cvtr), 1, fdH);
|
|
|
|
if(j < 3){
|
|
index = globToLocMap_->find(fcArray[i]->getNode(j)->getid())->second;
|
|
|
|
tmpE = coord.x_axis * (fp_t)(evtr.x.real()) + coord.y_axis * (fp_t)(evtr.y.real()) + coord.z_axis * (fp_t)(evtr.z.real());
|
|
tmpH = coord.x_axis * (fp_t)(hvtr.x.real()) + coord.y_axis * (fp_t)(hvtr.y.real()) + coord.z_axis * (fp_t)(hvtr.z.real());
|
|
|
|
eField[index] = eField[index] + tmpE;
|
|
hField[index] = hField[index] + tmpH;
|
|
(count[index])++;
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(fdE);
|
|
fclose(fdH);
|
|
|
|
for(i = 0; i < nodeCNT; i++){
|
|
eField[i] = eField[i] / static_cast<fp_t>(count[i]);
|
|
hField[i] = hField[i] / static_cast<fp_t>(count[i]);
|
|
}
|
|
|
|
node** locNodeArray = new node*[nodeCNT];
|
|
for(i = 0; i < nodeCNT; i++){
|
|
node& Node = *(ndArray[i]);
|
|
int index = globToLocMap_->find(Node.getid())->second;
|
|
locNodeArray[index] = new node(index, Node.getPType(), Node.getSingOrder(), Node.getCoord().getx(), Node.getCoord().gety(), Node.getCoord().getz());
|
|
}
|
|
|
|
face** locFaceArray = new face*[faceCNT];
|
|
for(i = 0; i < faceCNT; i++){
|
|
face& Face = *(fcArray[i]);
|
|
locFaceArray[i] = new face(Face);
|
|
locFaceArray[i]->setFace(
|
|
locNodeArray[globToLocMap_->find(Face.getNode(0)->getid())->second],
|
|
locNodeArray[globToLocMap_->find(Face.getNode(1)->getid())->second],
|
|
locNodeArray[globToLocMap_->find(Face.getNode(2)->getid())->second]);
|
|
}
|
|
|
|
VtkWriter vtkWriter(1.);
|
|
vtkWriter.writeTriUg(portName, nodeCNT, locNodeArray, faceCNT, locFaceArray, eField, hField, 1);
|
|
|
|
for(i = 0; i < nodeCNT; i++)
|
|
delete locNodeArray[i];
|
|
delete [] locNodeArray;
|
|
for(i = 0; i < faceCNT; i++)
|
|
delete locFaceArray[i];
|
|
delete [] locFaceArray;
|
|
delete [] eField;
|
|
delete [] hField;
|
|
delete [] count;
|
|
}
|
|
|