⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c_geometry.cpp

📁 矩量法仿真电磁辐射和散射的源代码(c++)
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*	Copyright (C) 2004-2005  Timothy C.A. Molteno	tim@molteno.net		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 2 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, write to the Free Software	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include "c_geometry.h"#include "nec_context.h"#include "nec_exception.h"c_geometry::c_geometry(){	n = 0;	np = 0; 	// n is the number of segments		m = 0;	mp = 0;		// m is the number of patches?		m_ipsym = 0;		n_plus_m = 0;	n_plus_2m = 0;	n_plus_3m = 0;		jsno = 0;	nscon = 0;	maxcon = 0;		m_context = NULL;	m_output = NULL;}void c_geometry::set_context(nec_context* in_context){	m_context = in_context;	m_output = &m_context->m_output;}/*! \brief Get a segment number for a specified tag.	\param in_tag The tag	\param in_m The mth segment with the specified tag will be returned.	\return The segment number of the mth segment having the	tag number in_tag.  if in_tag=0 segment number m is returned.*/int c_geometry::get_segment_number( int in_tag, int in_m){	ASSERT(in_tag >= 0);	ASSERT(in_m >= 0);			if (in_m <= 0)	{		throw new nec_exception("CHECK DATA, PARAMETER SPECIFYING SEGMENT POSITION IN A GROUP OF EQUAL TAGS MUST NOT BE ZERO" );	}		if ( 0 == in_tag)	{		return( in_m );	}		int tag_seg_count=0;	for (int i = 0; i < n; i++ )	{		if ( segment_tags[i] == in_tag )		{			tag_seg_count++;			if ( tag_seg_count == in_m)			{				return( i+1 );			}		}	}		throw new nec_exception("NO SEGMENT HAS AN ITAG OF ", in_tag);		return 0;}/*	parse_geometry is the main routine for input of geometry data.	ANTLR Grammar for geometry input			geometry			:	(geometry_element {transform}*)+				geometry_end			;				geometry_element			:	wire			|	arc			|	helix			|	patch			|	multi_patch			;				transform			:	scale			|	reflect			|	rotate			|	move			;				wire = "GW" int int real real real real real real {taper}		taper = "GC" xxx		arc = "GA"		helix = "GH"				patch = "SP"		multi_patch = "SM" {patch_data}+		patch_data = "SC"				scale = "GS"		reflect = "GX"		rotate = "GR"		move = "GM"				geometry_end = "GE" .+				int:			[0-9]+;					real:			int:{.int};		*/#include "c_plot_card.h"	void c_geometry::parse_geometry(nec_context* in_context, FILE* input_fp ){	char gm[3];	char ifx[2] = {'*', 'X'}, ify[2]={'*','Y'}, ifz[2]={'*','Z'};	char ipt[4] = { 'P', 'R', 'T', 'Q' };		/* input card mnemonic list */	/* "XT" stands for "exit", added for testing */	#define GM_NUM  12	char *atst[GM_NUM] =	{		"GW", "GX", "GR", "GS", "GE", "GM", \		"SP", "SM", "GA", "SC", "GH", "GF"	};		bool print_structure_spec = true;		int nwire, isct, i1, i2, iy, iz;	int ix; 	int card_int_1, card_int_2; /* The two integer parameters from the geometry card */	nec_float rad, xs1, xs2, ys1, ys2, zs1, zs2, x4=0, y4=0, z4=0;	nec_float x3=0, y3=0, z3=0, xw1, xw2, yw1, yw2, zw1, zw2;	nec_float dummy;		m_ipsym=0;	nwire=0;	n=0;	np=0;	m=0;	mp=0;	isct=0;		/* read geometry data card and branch to */	/* section for operation requested */	do	{		read_geometry_card(input_fp, gm, &card_int_1, &card_int_2, &xw1, &yw1, &zw1, &xw2, &yw2, &zw2, &rad);			/* identify card id mnemonic */		int gm_num;		for( gm_num = 0; gm_num < GM_NUM; gm_num++ )			if ( strncmp( gm, atst[gm_num], 2) == 0 )				break;		if ( print_structure_spec )		{			m_output->end_section();			m_output->set_indent(32);			m_output->line("-------- STRUCTURE SPECIFICATION --------");			m_output->line("COORDINATES MUST BE INPUT IN" );			m_output->line("METERS OR BE SCALED TO METERS" );			m_output->line("BEFORE STRUCTURE INPUT IS ENDED" );			m_output->set_indent(0);					m_output->line("  WIRE                                                                                 SEG FIRST  LAST  TAG");			m_output->line("   No:        X1         Y1         Z1         X2         Y2         Z2       RADIUS   No:   SEG   SEG  No:" );					print_structure_spec = false;		}		if ( gm_num != 10 )			isct=0;		switch( gm_num )		{		case 0:		/* "gw" card, generate segment data for straight wire.			GW		STRAIGHT WIRE, ENDS 1,2				card_int_1- TAG NO.				card_int_2- NO. SEGMENTS				xw1- X1				F2- Y1				F3- Z1				F4- X2				F5- Y2				F6- Z2				F7- WIRE RAD., 0=USE GC FOR TAPERED WIRE		*/		{			int wire_segment_count = card_int_2;			int wire_tag = card_int_1;						nwire++;					// output some wire diagnostics.			m_output->nec_printf( "\n"				" %5d  %10.4f %10.4f %10.4f %10.4f"				" %10.4f %10.4f %10.4f %5d %5d %5d %4d",				nwire, xw1, yw1, zw1, xw2, yw2, zw2, rad, wire_segment_count, n+1, n + wire_segment_count, wire_tag );					if ( rad != 0)	// rad == 0 implies a tapered wire			{				xs1 = 1.0;				ys1 = 1.0;			}			else			{				read_geometry_card(input_fp, gm, &ix, &iy, &xs1, &ys1, &zs1,					&dummy, &dummy, &dummy, &dummy);							if ( strcmp(gm, "GC" ) != 0 )				{					throw new nec_exception("GEOMETRY DATA CARD ERROR" );				}							m_output->nec_printf(					"\n  ABOVE WIRE IS TAPERED.  SEGMENT LENGTH RATIO: %9.5f\n"					"                                 "					"RADIUS FROM: %9.5f TO: %9.5f", xs1, ys1, zs1 );							if ( (ys1 == 0) || (zs1 == 0) )				{					throw new nec_exception("GEOMETRY DATA CARD ERROR" );				}							rad= ys1;				ys1= pow( (zs1/ys1), (1./(wire_segment_count-1.)) );			}					wire(wire_tag, wire_segment_count, xw1, yw1, zw1, xw2, yw2, zw2, rad, xs1, ys1);		}		continue;		/* reflect structure along x,y, or z */		/* axes or rotate to form cylinder.  */		case 1: /* "gx" card */			iy= card_int_2/10;			iz= card_int_2- iy*10;			ix= iy/10;			iy= iy- ix*10;					if ( ix != 0)			ix=1;			if ( iy != 0)			iy=1;			if ( iz != 0)			iz=1;					m_output->nec_printf(				"\n  STRUCTURE REFLECTED ALONG THE AXES %c %c %c"				" - TAGS INCREMENTED BY %d\n",				ifx[ix], ify[iy], ifz[iz], card_int_1 );					reflect( ix, iy, iz, card_int_1, card_int_2);					continue;			case 2: /* "gr" card */					m_output->nec_printf(				"\n  STRUCTURE ROTATED ABOUT Z-AXIS %d TIMES"				" - LABELS INCREMENTED BY %d\n", card_int_2, card_int_1 );					ix=-1;			iz = 0;			reflect( ix, iy, iz, card_int_1, card_int_2);					continue;			case 3: /* "gs" card, scale structure dimensions by factor xw1. */					if ( n > 0)			{				for(int i = 0; i < n; i++ )				{					x[i]= x[i]* xw1;					y[i]= y[i]* xw1;					z[i]= z[i]* xw1;					x2[i]= x2[i]* xw1;					y2[i]= y2[i]* xw1;					z2[i]= z2[i]* xw1;					segment_radius[i]= segment_radius[i]* xw1;				}			} /* if ( n >= n2) */					if ( m > 0)			{				yw1= xw1* xw1;				for(int i = 0; i < m; i++ )				{					px[i]= px[i]* xw1;					py[i]= py[i]* xw1;					pz[i]= pz[i]* xw1;					pbi[i]= pbi[i]* yw1;				}			} /* if ( m >= m2) */					m_output->nec_printf(				"\n     STRUCTURE SCALED BY FACTOR: %10.5f", xw1 );					continue;		case 4: /* "ge" card, terminate structure geometry input. */			geometry_complete(in_context, card_int_1, card_int_2);						return;		/* "gm" card, move structure or reproduce */		/* original structure in new positions.   */		case 5:					m_output->nec_printf(				"\n     THE STRUCTURE HAS BEEN MOVED, MOVE DATA CARD IS:\n"				"   %3d %5d %10.5f %10.5f %10.5f %10.5f %10.5f %10.5f %10.5f",				card_int_1, card_int_2, xw1, yw1, zw1, xw2, yw2, zw2, rad );					xw1= degrees_to_rad(xw1);			yw1= degrees_to_rad(yw1);			zw1= degrees_to_rad(zw1);					move( xw1, yw1, zw1, xw2, yw2, zw2, (int)( rad+.5), card_int_2, card_int_1);			continue;				case 6: /* "sp" card, generate single new patch */					i1= m+1;			card_int_2++;					if ( card_int_1 != 0)			{				throw new nec_exception("PATCH DATA ERROR" );			}					m_output->nec_printf( "\n"				" %5d%c %10.5f %10.5f %10.5f %10.5f %10.5f %10.5f",				i1, ipt[card_int_2-1], xw1, yw1, zw1, xw2, yw2, zw2 );					if ( (card_int_2 == 2) || (card_int_2 == 4) )				isct=1;					if ( card_int_2 > 1)			{				// read another geometry card for the rest of the patch data				read_geometry_card(input_fp, gm, &ix, &iy, &x3, &y3, &z3, &x4, &y4, &z4, &dummy);							if ( (card_int_2 == 2) || (card_int_1 > 0) )				{					x4= xw1+ x3- xw2;					y4= yw1+ y3- yw2;					z4= zw1+ z3- zw2;				}							m_output->nec_printf( "\n"					"      %11.5f %11.5f %11.5f %11.5f %11.5f %11.5f",					x3, y3, z3, x4, y4, z4 );							if ( strcmp(gm, "SC") != 0 )				{					throw new nec_exception("PATCH DATA ERROR" );				}			} /* if ( card_int_2 > 1) */			else			{				xw2= degrees_to_rad(xw2);				yw2= degrees_to_rad(yw2);			}					patch( card_int_1, card_int_2, xw1, yw1, zw1, xw2, yw2, zw2, x3, y3, z3, x4, y4, z4);			continue;			case 7: /* "sm" card, generate multiple-patch surface */					i1= m+1;			m_output->nec_printf( "\n"				" %5d%c %10.5f %11.5f %11.5f %11.5f %11.5f %11.5f"				"     SURFACE - %d BY %d PATCHES",				i1, ipt[1], xw1, yw1, zw1, xw2, yw2, zw2, card_int_1, card_int_2 );					if ( (card_int_1 < 1) || (card_int_2 < 1) )			{				throw new nec_exception("PATCH DATA ERROR" );			}					read_geometry_card(input_fp, gm, &ix, &iy, &x3, &y3, &z3, &x4, &y4, &z4, &dummy);					if ( (card_int_2 == 2) || (card_int_1 > 0) )			{				x4= xw1+ x3- xw2;				y4= yw1+ y3- yw2;				z4= zw1+ z3- zw2;			}					m_output->nec_printf( "\n"				"      %11.5f %11.5f %11.5f %11.5f %11.5f %11.5f",				x3, y3, z3, x4, y4, z4 );					if ( strcmp(gm, "SC" ) != 0 )			{				throw new nec_exception("PATCH DATA ERROR" );			}					patch( card_int_1, card_int_2, xw1, yw1, zw1, xw2, yw2, zw2, x3, y3, z3, x4, y4, z4);			continue;				case 8: /* "ga" card, generate segment data for wire arc */					nwire++;			i1= n+1;			i2= n+ card_int_2;					m_output->nec_printf( "\n"				" %5d  ARC RADIUS: %9.5f  FROM: %8.3f TO: %8.3f DEGREES"				"       %11.5f %5d %5d %5d %4d",				nwire, xw1, yw1, zw1, xw2, card_int_2, i1, i2, card_int_1 );					arc( card_int_1, card_int_2, xw1, yw1, zw1, xw2);			continue;			case 9: /* "sc" card */					if ( isct == 0)			{				throw new nec_exception("PATCH DATA ERROR" );			}					i1= m+1;			card_int_2++;					if ( (card_int_1 != 0) || ((card_int_2 != 2) && (card_int_2 != 4)) )			{				throw new nec_exception("PATCH DATA ERROR" );			}					xs1= x4;			ys1= y4;			zs1= z4;			xs2= x3;			ys2= y3;			zs2= z3;			x3= xw1;			y3= yw1;			z3= zw1;					if ( card_int_2 == 4)			{				x4= xw2;				y4= yw2;				z4= zw2;			}					xw1= xs1;			yw1= ys1;			zw1= zs1;			xw2= xs2;			yw2= ys2;			zw2= zs2;					if ( card_int_2 != 4)			{				x4= xw1+ x3- xw2;				y4= yw1+ y3- yw2;				z4= zw1+ z3- zw2;			}					m_output->nec_printf( "\n"				" %5d%c %10.5f %11.5f %11.5f %11.5f %11.5f %11.5f",				i1, ipt[card_int_2-1], xw1, yw1, zw1, xw2, yw2, zw2 );					m_output->nec_printf( "\n"				"      %11.5f %11.5f %11.5f  %11.5f %11.5f %11.5f",				x3, y3, z3, x4, y4, z4 );					patch( card_int_1, card_int_2, xw1, yw1, zw1, xw2, yw2, zw2, x3, y3, z3, x4, y4, z4);					continue;			case 10: /* "gh" card, generate helix */					nwire++;			i1= n+1;			i2= n+ card_int_2;					m_output->nec_printf( "\n"				" %5d HELIX STRUCTURE - SPACING OF TURNS: %8.3f AXIAL"				" LENGTH: %8.3f  %8.3f %5d %5d %5d %4d\n      "				" RADIUS X1:%8.3f Y1:%8.3f X2:%8.3f Y2:%8.3f ",				nwire, xw1, yw1, rad, card_int_2, i1, i2, card_int_1, zw1, xw2, yw2, zw2 );					helix( xw1, yw1, zw1, xw2, yw2, zw2, rad, card_int_2, card_int_1);					continue;		case 11: /* "gf" card, not supported */			throw new nec_exception("NGF solution option not supported");			default: /* error message */					m_output->nec_printf( "\n  GEOMETRY DATA CARD ERROR" );			m_output->nec_printf( "\n"				" %2s %3d %5d %10.5f %10.5f %10.5f %10.5f %10.5f %10.5f %10.5f",				gm, card_int_1, card_int_2, xw1, yw1, zw1, xw2, yw2, zw2, rad );					throw new nec_exception("GEOMETRY DATA CARD ERROR");    } /* switch( gm_num ) */	} /* do */	while( true );}/**	We have finished with the geometry description, now connect 	things up.*/void c_geometry::geometry_complete(nec_context* in_context, int card_int_1, int card_int_2){	if (0 == np + mp)		throw new nec_exception("Geometry has no wires or patches.");			/* TCAM: The following does not make sense for the semantics of the plot	card. I have left this in, I hope someone will tell me why it is required.	*/	if (card_int_2 != 0)		in_context->plot_card.set_plot_real_imag_currents();			// now proceed and complete the geometry setup...		connect_segments( card_int_1);	if ( n != 0)	{		/* Allocate wire buffers */		segment_length.resize(n);		sab.resize(n);		cab.resize(n);		salp.resize(n);			m_output->nec_printf( "\n\n\n"			"                              "			" ---------- SEGMENTATION DATA ----------\n"			"                                       "			" COORDINATES IN METERS\n"			"                           "			" I+ AND I- INDICATE THE SEGMENTS BEFORE AND AFTER I\n" );			m_output->nec_printf( "\n"			"   SEG    COORDINATES OF SEGM CENTER     SEGM    ORIENTATION"			" ANGLES    WIRE    CONNECTION DATA   TAG\n"			"   No:       X         Y         Z      LENGTH     ALPHA     "			" BETA    RADIUS    I-     I    I+   NO:" );			for(int i = 0; i < n; i++ )		{			nec_float xw1= x2[i]- x[i];			nec_float yw1= y2[i]- y[i];			nec_float zw1= z2[i]- z[i];			x[i]=( x[i]+ x2[i])*.5;			y[i]=( y[i]+ y2[i])*.5;			z[i]=( z[i]+ z2[i])*.5;						nec_float xw2= xw1* xw1+ yw1* yw1+ zw1* zw1;			nec_float yw2= sqrt( xw2);			yw2=( xw2/ yw2+ yw2)*.5;			segment_length[i]= yw2;			cab[i]= xw1/ yw2;			sab[i]= yw1/ yw2;			xw2= zw1/ yw2;				if ( xw2 > 1.)				xw2=1.;			if ( xw2 < -1.)				xw2=-1.;				salp[i]= xw2;			xw2= rad_to_degrees(asin( xw2));			yw2= rad_to_degrees(atan2( yw1, xw1));				m_output->nec_printf( "\n"				" %5d %9.4f %9.4f %9.4f %9.4f"				" %9.4f %9.4f %9.4f %5d %5d %5d %5d",				i+1, x[i], y[i], z[i], segment_length[i], xw2, yw2,				segment_radius[i], icon1[i], i+1, icon2[i], segment_tags[i] );				in_context->plot_card.plot_segments(i,x,y,z,segment_length,xw2,yw2,segment_radius,icon1,icon2);				if ( (segment_length[i] <= 1.e-20) || (segment_radius[i] <= 0.) )			{				throw new nec_exception("SEGMENT DATA ERROR" );			}		} /* for( i = 0; i < n; i++ ) */	} /* if ( n != 0) */	if ( m != 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -