bool Operator::Calc_ECPos(int ny, const unsigned int* pos, double* EC) const { double EffMat[4]; Calc_EffMatPos(ny,pos,EffMat); if (m_epsR) m_epsR[ny][pos[0]][pos[1]][pos[2]] = EffMat[0]; if (m_kappa) m_kappa[ny][pos[0]][pos[1]][pos[2]] = EffMat[1]; if (m_mueR) m_mueR[ny][pos[0]][pos[1]][pos[2]] = EffMat[2]; if (m_sigma) m_sigma[ny][pos[0]][pos[1]][pos[2]] = EffMat[3]; double delta = GetEdgeLength(ny,pos); double area = GetEdgeArea(ny,pos); // if (isnan(EffMat[0])) // { // cerr << ny << " " << pos[0] << " " << pos[1] << " " << pos[2] << " : " << EffMat[0] << endl; // } if (delta) { EC[0] = EffMat[0] * area/delta; EC[1] = EffMat[1] * area/delta; } else { EC[0] = 0; EC[1] = 0; } delta = GetEdgeLength(ny,pos,true); area = GetEdgeArea(ny,pos,true); if (delta) { EC[2] = EffMat[2] * area/delta; EC[3] = EffMat[3] * area/delta; } else { EC[2] = 0; EC[3] = 0; } return true; }
double Operator::GetCellVolume(const unsigned int pos[3], bool dualMesh) const { double vol=1; for (int n=0;n<3;++n) vol*=GetEdgeLength(n,pos,dualMesh); return vol; }
void Tree::ToFileNodeRooted(TextFile &File, unsigned uNodeIndex) const { assert(IsRooted()); bool bGroup = !IsLeaf(uNodeIndex) || IsRoot(uNodeIndex); if (bGroup) File.PutString("(\n"); if (IsLeaf(uNodeIndex)) File.PutString(GetName(uNodeIndex)); else { ToFileNodeRooted(File, GetLeft(uNodeIndex)); File.PutString(",\n"); ToFileNodeRooted(File, GetRight(uNodeIndex)); } if (bGroup) File.PutString(")"); if (!IsRoot(uNodeIndex)) { unsigned uParent = GetParent(uNodeIndex); if (HasEdgeLength(uNodeIndex, uParent)) File.PutFormat(":%g", GetEdgeLength(uNodeIndex, uParent)); } File.PutString("\n"); }
vtkDataArray * avtEdgeLength::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex) { vtkDataArray *arr = CreateArrayFromMesh(in_ds); vtkIdType ncells = in_ds->GetNumberOfCells(); arr->SetNumberOfTuples(ncells); for (vtkIdType i = 0 ; i < ncells ; i++) { vtkCell *cell = in_ds->GetCell(i); double vol = GetEdgeLength(cell); arr->SetTuple1(i, vol); } return arr; }
void Tree::ToFileNodeUnrooted(TextFile &File, unsigned uNodeIndex, unsigned uParent) const { assert(!IsRooted()); bool bGroup = !IsLeaf(uNodeIndex); if (bGroup) File.PutString("(\n"); if (IsLeaf(uNodeIndex)) File.PutString(GetName(uNodeIndex)); else { ToFileNodeUnrooted(File, GetFirstNeighbor(uNodeIndex, uParent), uNodeIndex); File.PutString(",\n"); ToFileNodeUnrooted(File, GetSecondNeighbor(uNodeIndex, uParent), uNodeIndex); } if (bGroup) File.PutString(")"); if (HasEdgeLength(uNodeIndex, uParent)) File.PutFormat(":%g", GetEdgeLength(uNodeIndex, uParent)); File.PutString("\n"); }
void vtLevel::SetRoofType(RoofType rt, int iSlope) { int i, edges = NumEdges(); if (rt == ROOF_FLAT) { // all edges are horizontal for (i = 0; i < edges; i++) m_Edges[i]->m_iSlope = 0; m_fStoryHeight = 0.0f; } if (rt == ROOF_SHED) { // all edges are vertical for (i = 0; i < edges; i++) m_Edges[i]->m_iSlope = 90; // except for the first edge m_Edges[0]->m_iSlope = iSlope; DetermineHeightFromSlopes(); } if (rt == ROOF_GABLE) { // Algorithm for guessing which edges makes up the gable roof: if (NumEdges() == 4) { // In the case of a rectangular footprint, assume that the // shorter edge has the gable if (GetEdgeLength(1) > GetEdgeLength(0)) { m_Edges[0]->m_iSlope = 90; m_Edges[1]->m_iSlope = iSlope; m_Edges[2]->m_iSlope = 90; m_Edges[3]->m_iSlope = iSlope; } else { m_Edges[0]->m_iSlope = iSlope; m_Edges[1]->m_iSlope = 90; m_Edges[2]->m_iSlope = iSlope; m_Edges[3]->m_iSlope = 90; } } else { // Assume that only convex edges can be gables, and no more than // one edge in a row is a gable. All other edges are hip. bool last_gable = false; for (i = 0; i < edges; i++) { if (IsEdgeConvex(i) && !last_gable && !((i == edges - 1) && (m_Edges[0]->m_iSlope == 90))) { m_Edges[i]->m_iSlope = 90; last_gable = true; } else { m_Edges[i]->m_iSlope = iSlope; last_gable = false; } } } DetermineHeightFromSlopes(); } if (rt == ROOF_HIP) { for (i = 0; i < edges; i++) m_Edges[i]->m_iSlope = iSlope; DetermineHeightFromSlopes(); } }
//! \brief dump PEC (perfect electric conductor) information (into VTK-file) //! visualization via paraview //! visualize only one component (x, y or z) void Operator::DumpPEC2File( string filename ) { cout << "Operator: Dumping PEC information to vtk file: " << filename << " ..." << flush; FDTD_FLOAT**** pec = Create_N_3DArray<FDTD_FLOAT>( numLines ); unsigned int pos[3]; #ifdef OUTPUT_IN_DRAWINGUNITS double scaling = 1.0/GetGridDelta(); #else double scaling = 1; #endif for (pos[0]=0; pos[0]<numLines[0]-1; pos[0]++) { for (pos[1]=0; pos[1]<numLines[1]-1; pos[1]++) { for (pos[2]=0; pos[2]<numLines[2]-1; pos[2]++) { if ((pos[1] != 0) && (pos[2] != 0)) { // PEC surrounds the computational area; do not output this if ((GetVV(0,pos) == 0) && (GetVI(0,pos) == 0)) pec[0][pos[0]][pos[1]][pos[2]] = GetEdgeLength( 0, pos ) * scaling; // PEC-x found } if ((pos[0] != 0) && (pos[2] != 0)) { // PEC surrounds the computational area; do not output this if ((GetVV(1,pos) == 0) && (GetVI(1,pos) == 0)) pec[1][pos[0]][pos[1]][pos[2]] = GetEdgeLength( 1, pos ) * scaling; // PEC-y found } if ((pos[0] != 0) && (pos[1] != 0)) { // PEC surrounds the computational area; do not output this if ((GetVV(2,pos) == 0) && (GetVI(2,pos) == 0)) pec[2][pos[0]][pos[1]][pos[2]] = GetEdgeLength( 2, pos ) * scaling; // PEC-z found } } } } // evaluate boundary conditions for (int n=0; n<3; n++) { int nP = (n+1)%3; int nPP = (n+2)%3; for (pos[nP]=0; pos[nP]<numLines[nP]; pos[nP]++) { for (pos[nPP]=0; pos[nPP]<numLines[nPP]; pos[nPP]++) { pos[n] = 0; if ((pos[nP] != numLines[nP]-1) && (m_BC[2*n] == 0)) pec[nP ][pos[0]][pos[1]][pos[2]] = GetEdgeLength( nP, pos ) * scaling; if ((pos[nPP] != numLines[nPP]-1) && (m_BC[2*n] == 0)) pec[nPP][pos[0]][pos[1]][pos[2]] = GetEdgeLength( nPP, pos ) * scaling; pos[n] = numLines[n]-1; if ((pos[nP] != numLines[nP]-1) && (m_BC[2*n+1] == 0)) pec[nP ][pos[0]][pos[1]][pos[2]] = GetEdgeLength( nP, pos ) * scaling; if ((pos[nPP] != numLines[nPP]-1) && (m_BC[2*n+1] == 0)) pec[nPP][pos[0]][pos[1]][pos[2]] = GetEdgeLength( nPP, pos ) * scaling; } } } #ifdef OUTPUT_IN_DRAWINGUNITS scaling = 1; #else scaling = GetGridDelta(); #endif VTK_File_Writer* vtk_Writer = new VTK_File_Writer(filename.c_str(), m_MeshType); vtk_Writer->SetMeshLines(discLines,numLines,scaling); vtk_Writer->SetHeader("openEMS - PEC dump"); vtk_Writer->SetNativeDump(true); vtk_Writer->AddVectorField("PEC",pec); Delete_N_3DArray(pec,numLines); if (vtk_Writer->Write()==false) cerr << "Operator::DumpPEC2File: Error: Can't write file... skipping!" << endl; cout << " done!" << endl; }
bool Operator::Calc_LumpedElements() { vector<CSProperties*> props = CSX->GetPropertyByType(CSProperties::LUMPED_ELEMENT); for (size_t i=0;i<props.size();++i) { CSPropLumpedElement* PLE = dynamic_cast<CSPropLumpedElement*>(props.at(i)); if (PLE==NULL) return false; //sanity check: this should never happen! vector<CSPrimitives*> prims = PLE->GetAllPrimitives(); for (size_t bn=0;bn<prims.size();++bn) { CSPrimBox* box = dynamic_cast<CSPrimBox*>(prims.at(bn)); if (box) { //calculate lumped element parameter double C = PLE->GetCapacity(); if (C<=0) C = NAN; double R = PLE->GetResistance(); if (R<0) R = NAN; if ((isnan(R)) && (isnan(C))) { cerr << "Operator::Calc_LumpedElements(): Warning: Lumped Element R or C not specified! skipping. " << " ID: " << prims.at(bn)->GetID() << " @ Property: " << PLE->GetName() << endl; continue; } int ny = PLE->GetDirection(); if ((ny<0) || (ny>2)) { cerr << "Operator::Calc_LumpedElements(): Warning: Lumped Element direction is invalid! skipping. " << " ID: " << prims.at(bn)->GetID() << " @ Property: " << PLE->GetName() << endl; continue; } int nyP = (ny+1)%3; int nyPP = (ny+2)%3; unsigned int uiStart[3]; unsigned int uiStop[3]; // snap to the native coordinate system int Snap_Dimension = Operator::SnapBox2Mesh(box->GetStartCoord()->GetCoords(m_MeshType), box->GetStopCoord()->GetCoords(m_MeshType), uiStart, uiStop); if (Snap_Dimension<=0) { if (Snap_Dimension>=-1) cerr << "Operator::Calc_LumpedElements(): Warning: Lumped Element snapping failed! Dimension is: " << Snap_Dimension << " skipping. " << " ID: " << prims.at(bn)->GetID() << " @ Property: " << PLE->GetName() << endl; // Snap_Dimension == -2 means outside the simulation domain --> no special warning, but box probably marked as unused! continue; } if (uiStart[ny]==uiStop[ny]) { cerr << "Operator::Calc_LumpedElements(): Warning: Lumped Element with zero (snapped) length is invalid! skipping. " << " ID: " << prims.at(bn)->GetID() << " @ Property: " << PLE->GetName() << endl; continue; } //calculate geometric property for this lumped element unsigned int pos[3]; double unitGC=0; int ipos=0; for (pos[ny]=uiStart[ny];pos[ny]<uiStop[ny];++pos[ny]) { double unitGC_Plane=0; for (pos[nyP]=uiStart[nyP];pos[nyP]<=uiStop[nyP];++pos[nyP]) { for (pos[nyPP]=uiStart[nyPP];pos[nyPP]<=uiStop[nyPP];++pos[nyPP]) { // capacity/conductivity in parallel: add values unitGC_Plane += GetEdgeArea(ny,pos)/GetEdgeLength(ny,pos); } } //capacity/conductivity in series: add reciprocal values unitGC += 1/unitGC_Plane; } unitGC = 1/unitGC; bool caps = PLE->GetCaps(); double kappa = 0; double epsilon = 0; if (R>0) kappa = 1 / R / unitGC; if (C>0) { epsilon = C / unitGC; if (epsilon< __EPS0__) { cerr << "Operator::Calc_LumpedElements(): Warning: Lumped Element capacity is too small for its size! skipping. " << " ID: " << prims.at(bn)->GetID() << " @ Property: " << PLE->GetName() << endl; C = 0; } } for (pos[ny]=uiStart[ny];pos[ny]<uiStop[ny];++pos[ny]) { for (pos[nyP]=uiStart[nyP];pos[nyP]<=uiStop[nyP];++pos[nyP]) { for (pos[nyPP]=uiStart[nyPP];pos[nyPP]<=uiStop[nyPP];++pos[nyPP]) { ipos = MainOp->SetPos(pos[0],pos[1],pos[2]); if (C>0) EC_C[ny][ipos] = epsilon * GetEdgeArea(ny,pos)/GetEdgeLength(ny,pos); if (R>0) EC_G[ny][ipos] = kappa * GetEdgeArea(ny,pos)/GetEdgeLength(ny,pos); if (R==0) //make lumped element a PEC if resistance is zero { SetVV(ny,pos[0],pos[1],pos[2], 0 ); SetVI(ny,pos[0],pos[1],pos[2], 0 ); } else //recalculate operator inside the lumped element Calc_ECOperatorPos(ny,pos); } } } // setup metal caps if (caps) { for (pos[nyP]=uiStart[nyP];pos[nyP]<=uiStop[nyP];++pos[nyP]) { for (pos[nyPP]=uiStart[nyPP];pos[nyPP]<=uiStop[nyPP];++pos[nyPP]) { pos[ny]=uiStart[ny]; SetVV(nyP,pos[0],pos[1],pos[2], 0 ); SetVI(nyP,pos[0],pos[1],pos[2], 0 ); ++m_Nr_PEC[nyP]; SetVV(nyPP,pos[0],pos[1],pos[2], 0 ); SetVI(nyPP,pos[0],pos[1],pos[2], 0 ); ++m_Nr_PEC[nyPP]; pos[ny]=uiStop[ny]; SetVV(nyP,pos[0],pos[1],pos[2], 0 ); SetVI(nyP,pos[0],pos[1],pos[2], 0 ); ++m_Nr_PEC[nyP]; SetVV(nyPP,pos[0],pos[1],pos[2], 0 ); SetVI(nyPP,pos[0],pos[1],pos[2], 0 ); ++m_Nr_PEC[nyPP]; } } } box->SetPrimitiveUsed(true); } else cerr << "Operator::Calc_LumpedElements(): Warning: Primitves other than boxes are not supported for lumped elements! skipping " << prims.at(bn)->GetTypeName() << " ID: " << prims.at(bn)->GetID() << " @ Property: " << PLE->GetName() << endl; } } return true; }