예제 #1
0
파일: operator.cpp 프로젝트: ho-y/openEMS
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;
}
예제 #2
0
파일: operator.cpp 프로젝트: ho-y/openEMS
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;
}
예제 #3
0
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");
	}
예제 #4
0
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;
}
예제 #5
0
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");
	}
예제 #6
0
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();
	}
}
예제 #7
0
파일: operator.cpp 프로젝트: ho-y/openEMS
//! \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;
}
예제 #8
0
파일: operator.cpp 프로젝트: ho-y/openEMS
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;
}