Import transcalc utility from Qucs Qt4 package
@ -37,6 +37,7 @@ ADD_SUBDIRECTORY( qucs-attenuator )
|
||||
#ADD_SUBDIRECTORY( qucs-doc )
|
||||
ADD_SUBDIRECTORY( qucs-filter )
|
||||
ADD_SUBDIRECTORY( qucs-lib )
|
||||
ADD_SUBDIRECTORY( qucs-transcalc )
|
||||
#ADD_SUBDIRECTORY( examples )
|
||||
ADD_SUBDIRECTORY( translations )
|
||||
|
||||
|
195
qucs-transcalc/CMakeLists.txt
Normal file
@ -0,0 +1,195 @@
|
||||
PROJECT(qucstrans CXX C)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
|
||||
cmake_policy(VERSION 3.0)
|
||||
|
||||
SET(QUCS_NAME "qucs-s")
|
||||
|
||||
# use top VERSION file
|
||||
file (STRINGS ${PROJECT_SOURCE_DIR}/../VERSION QUCS_VERSION)
|
||||
message(STATUS "Configuring ${PROJECT_NAME} (GUI): VERSION ${QUCS_VERSION}")
|
||||
|
||||
set(PROJECT_VERSION "${QUCS_VERSION}")
|
||||
|
||||
set(PROJECT_VENDOR "Qucs team. This program is licensed under the GNU GPL")
|
||||
set(PROJECT_COPYRIGHT_YEAR "2014")
|
||||
set(PROJECT_DOMAIN_FIRST "qucs")
|
||||
set(PROJECT_DOMAIN_SECOND "org")
|
||||
|
||||
SET(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
ADD_DEFINITIONS( -DHAVE_CONFIG_H )
|
||||
|
||||
# configure the header config.h
|
||||
CONFIGURE_FILE (
|
||||
"${PROJECT_SOURCE_DIR}/../config.h.cmake"
|
||||
"${PROJECT_BINARY_DIR}/config.h"
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES("${PROJECT_BINARY_DIR}")
|
||||
|
||||
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall ") # enable warning level
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x ") # enable C++11
|
||||
|
||||
# flag not available in mingw 4.8.2, MSVC10
|
||||
IF(NOT WIN32)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-register ")
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE( Qt5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${Qt5Core_INCLUDE_DIRS}
|
||||
${Qt5Widgets_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
# bug, the find package does not seem to set the QT_LIBRARIES, do it manually
|
||||
SET(QT_LIBRARIES ${Qt5Core_LIBRARIES} ${Qt5Widgets_LIBRARIES} )
|
||||
|
||||
ADD_DEFINITIONS(${QT_DEFINITIONS})
|
||||
|
||||
SET(QUCSTRANS_SRCS
|
||||
helpdialog.cpp
|
||||
main.cpp
|
||||
optionsdialog.cpp
|
||||
qucstrans.cpp
|
||||
)
|
||||
|
||||
SET(QUCSTRANS_HDRS
|
||||
c_microstrip.h
|
||||
coax.h
|
||||
coplanar.h
|
||||
microstrip.h
|
||||
rectwaveguide.h
|
||||
transline.h
|
||||
stripline.h
|
||||
units.h
|
||||
)
|
||||
|
||||
SET(QUCSTRANS_MOC_HDRS
|
||||
helpdialog.h
|
||||
optionsdialog.h
|
||||
qucstrans.h
|
||||
)
|
||||
|
||||
QT5_WRAP_CPP( QUCSTRANS_MOC_SRCS ${QUCSTRANS_MOC_HDRS} )
|
||||
|
||||
SET( LIB_SRC
|
||||
c_microstrip.cpp
|
||||
coax.cpp
|
||||
coplanar.cpp
|
||||
microstrip.cpp
|
||||
rectwaveguide.cpp
|
||||
transline.cpp
|
||||
stripline.cpp
|
||||
)
|
||||
|
||||
SET(RESOURCES qucstrans_.qrc)
|
||||
|
||||
QT5_ADD_RESOURCES(RESOURCES_SRCS ${RESOURCES})
|
||||
|
||||
ADD_LIBRARY(transcalc ${LIB_SRC} )
|
||||
|
||||
IF(APPLE)
|
||||
# set information on Info.plist file
|
||||
SET(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
|
||||
SET(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}")
|
||||
SET(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
|
||||
SET(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}")
|
||||
SET(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}")
|
||||
SET(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}")
|
||||
SET(MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}")
|
||||
SET(MACOSX_BUNDLE_ICON_FILE qucstrans.icns)
|
||||
|
||||
# set where in the bundle to put the icns file
|
||||
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/../qucs/bitmaps/qucstrans.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
# include the icns file in the target
|
||||
SET(QUCSTRANS_SRCS ${QUCSTRANS_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/../qucs/bitmaps/qucstrans.icns)
|
||||
|
||||
ENDIF(APPLE)
|
||||
|
||||
|
||||
ADD_EXECUTABLE(${QUCS_NAME}trans MACOSX_BUNDLE WIN32
|
||||
${QUCSTRANS_SRCS}
|
||||
${QUCSTRANS_HDRS}
|
||||
${QUCSTRANS_MOC_SRCS}
|
||||
${RESOURCES_SRCS} )
|
||||
|
||||
TARGET_LINK_LIBRARIES( ${QUCS_NAME}trans ${QT_LIBRARIES} transcalc )
|
||||
|
||||
#INSTALL(TARGETS ${QUCS_NAME}trans DESTINATION bin)
|
||||
|
||||
#ADD_SUBDIRECTORY( bitmaps ) -> added as resources
|
||||
ADD_SUBDIRECTORY( examples )
|
||||
|
||||
#INSTALL( FILES qucstrans.1 DESTINATION share/man/man1 )
|
||||
|
||||
#
|
||||
# Prepare the installation
|
||||
#
|
||||
SET(plugin_dest_dir bin)
|
||||
SET(qtconf_dest_dir bin)
|
||||
SET(APPS "${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}")
|
||||
IF(APPLE)
|
||||
SET(plugin_dest_dir ${PROJECT_NAME}.app/Contents/MacOS)
|
||||
SET(qtconf_dest_dir ${PROJECT_NAME}.app/Contents/Resources)
|
||||
SET(APPS "${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}.app")
|
||||
ENDIF(APPLE)
|
||||
|
||||
IF(WIN32)
|
||||
SET(APPS "${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}.exe")
|
||||
ENDIF(WIN32)
|
||||
|
||||
#
|
||||
# Install the Qucs application, on Apple, the bundle is at the root of the
|
||||
# install tree, and on other platforms it'll go into the bin directory.
|
||||
#
|
||||
INSTALL(TARGETS ${QUCS_NAME}trans
|
||||
BUNDLE DESTINATION bin COMPONENT Runtime
|
||||
RUNTIME DESTINATION bin COMPONENT Runtime
|
||||
)
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Install needed Qt plugins by copying directories from the qt installation
|
||||
# One can cull what gets copied by using 'REGEX "..." EXCLUDE'
|
||||
#
|
||||
IF(APPLE)
|
||||
INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats" DESTINATION bin/${plugin_dest_dir}/plugins COMPONENT Runtime)
|
||||
ENDIF()
|
||||
#
|
||||
# install a qt.conf file
|
||||
# this inserts some cmake code into the install script to write the file
|
||||
#
|
||||
IF(APPLE)
|
||||
INSTALL(CODE "
|
||||
file(WRITE \"\${CMAKE_INSTALL_PREFIX}/bin/${qtconf_dest_dir}/qt.conf\" \"\")
|
||||
" COMPONENT Runtime)
|
||||
ENDIF()
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
# Use BundleUtilities to get all other dependencies for the application to work.
|
||||
# It takes a bundle or executable along with possible plugins and inspects it
|
||||
# for dependencies. If they are not system dependencies, they are copied.
|
||||
|
||||
# directories to look for dependencies
|
||||
IF(APPLE)
|
||||
SET(DIRS ${QT_LIBRARY_DIRS})
|
||||
ENDIF()
|
||||
|
||||
# Now the work of copying dependencies into the bundle/package
|
||||
# The quotes are escaped and variables to use at install time have their $ escaped
|
||||
# An alternative is the do a configure_file() on a script and use install(SCRIPT ...).
|
||||
# Note that the image plugins depend on QtSvg and QtXml, and it got those copied
|
||||
# over.
|
||||
IF(APPLE)
|
||||
INSTALL(CODE "
|
||||
file(GLOB_RECURSE QTPLUGINS
|
||||
\"\${CMAKE_INSTALL_PREFIX}/bin/${plugin_dest_dir}/plugins/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
|
||||
include(BundleUtilities)
|
||||
fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\")
|
||||
" COMPONENT Runtime)
|
||||
ENDIF()
|
||||
|
91
qucs-transcalc/ChangeLog
Normal file
@ -0,0 +1,91 @@
|
||||
2011-04-03 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* rectwaveguide.cpp (analyze): Fixed calculation of Z0 in
|
||||
rectangular waveguide.
|
||||
|
||||
2011-03-02 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* coax.cpp (alphac_coax): Fixed factor of 2 in conductor loss
|
||||
calculation.
|
||||
|
||||
2009-05-14 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* coax.cpp (show_results): Fixed computation of cut-off
|
||||
frequencies.
|
||||
|
||||
2008-06-29 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* qucstrans.cpp (slotCopyToClipBoard): Added clipboard copy for
|
||||
rectangular waveguide schematic.
|
||||
|
||||
2008-03-16 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* qucstrans.cpp (slotCopyToClipBoard): Added clipboard copy for
|
||||
new coplanar line types.
|
||||
|
||||
2008-02-09 Michael Margraf <michael.margraf@alumni.tu-berlin.de>
|
||||
|
||||
* added new lines: coplanar with and without backside metal
|
||||
|
||||
2006-10-29 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* coax.cpp (synthesize): Fixed synthesis equations for coax
|
||||
cable.
|
||||
|
||||
2006-08-19 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* units.h (ZF0): Added definition for wave resistance in vacuum.
|
||||
|
||||
* coax.cpp (alphac_coax): Using 20/log(10) instead of 8.686.
|
||||
|
||||
* rectwaveguide.cpp, microstrip.cpp, coax.cpp, c_microstrip.cpp:
|
||||
Using ZF0 instead of 120*PI wherever possible and necessary.
|
||||
|
||||
2006-01-30 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* qucstrans.cpp (slotCopyToClipBoard): Added supportexport function
|
||||
for coaxial line into clipboard.
|
||||
|
||||
2005-06-06 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* c_microstrip.cpp (show_results): Added computation of
|
||||
electrical and physical length.
|
||||
|
||||
2005-04-09 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* qucstrans.cpp (slotCopyToClipBoard): Added schematic creation
|
||||
for coupled microstrip.
|
||||
|
||||
2005-04-04 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* qucstrans.cpp (slotCopyToClipBoard): Started to implement the
|
||||
clipboard functionality used to created a schematic part for
|
||||
Qucs. Added a regex validator for the editable values.
|
||||
|
||||
2005-04-03 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* optionsdialog.h: Added configuration option dialog.
|
||||
|
||||
* helpdialog.h: Implemented help dialog.
|
||||
|
||||
* qucstrans.cpp: Applied reasonable default values for line
|
||||
properties. Implemented status bar. Improved radio button
|
||||
behaviour. Implemented config file operations as well as loading
|
||||
and saving of transmission line files.
|
||||
|
||||
* microstrip.cpp (synthesize): Computing length of microstrip
|
||||
line based on electrical angle during synthesis.
|
||||
|
||||
* main.cpp: Saving and storing current property values in resource
|
||||
file on application startup and exit.
|
||||
|
||||
* c_microstrip.cpp (er_eff_freq): Fixed P_9 formula. Use '0.7913'
|
||||
instead of '0.7193'.
|
||||
(Z0_dispersion): Fixed Q_19 formula. Use '4.9' instead of '4.19'.
|
||||
|
||||
2005-03-03 Stefan Jahn <stefan@lkcc.org>
|
||||
|
||||
* qucstrans.cpp: Initial attempt to create a 'transcalc' like
|
||||
GUI for Qt. Thus the program can be ported for use with Qucs.
|
||||
|
||||
|
15
qucs-transcalc/bitmaps/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
SET(XPMS )
|
||||
|
||||
SET(PNGS
|
||||
c_microstrip.png
|
||||
coax.png
|
||||
microstrip.png
|
||||
stripline.png
|
||||
rectwaveguide.png
|
||||
cpw.png
|
||||
cpw_back.png)
|
||||
|
||||
SET(ICON )
|
||||
|
||||
INSTALL( FILES ${PNGS} DESTINATION share/qucs/bitmaps )
|
40
qucs-transcalc/bitmaps/Makefile.am
Normal file
@ -0,0 +1,40 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
#
|
||||
# qucs-transcalc/bitmaps/Makefile.am
|
||||
#
|
||||
# Automake input file.
|
||||
#
|
||||
# Copyright (C) 2005, 2008 Stefan Jahn <stefan@lkcc.org>
|
||||
#
|
||||
# This 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This software 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 package; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
XPMS =
|
||||
|
||||
PNGS = c_microstrip.png coax.png microstrip.png stripline.png rectwaveguide.png cpw.png \
|
||||
cpw_back.png \
|
||||
big.qucs.xpm
|
||||
|
||||
ICONS =
|
||||
|
||||
EXTRA_DIST = $(XPMS) $(PNGS) $(ICONS)
|
||||
|
||||
# installation of pictures
|
||||
picdatadir = ${prefix}/share/qucs/bitmaps
|
||||
picdata_DATA = $(EXTRA_DIST)
|
||||
|
||||
CLEANFILES = *~
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
225
qucs-transcalc/bitmaps/big.qucs.xpm
Normal file
@ -0,0 +1,225 @@
|
||||
/* XPM */
|
||||
static char *big_qucs_xpm[] = {
|
||||
"32 32 190 2",
|
||||
" c None",
|
||||
". c #BCA2BC",
|
||||
"+ c #B4B2D4",
|
||||
"@ c #BC96BC",
|
||||
"# c #7C6E9C",
|
||||
"$ c #ACB2CC",
|
||||
"% c #9C869C",
|
||||
"& c #BCA2CC",
|
||||
"* c #CCC6E4",
|
||||
"= c #140A1C",
|
||||
"- c #140A14",
|
||||
"; c #0C0A14",
|
||||
"> c #5C5A64",
|
||||
", c #ACB6C4",
|
||||
"' c #CCC6D4",
|
||||
") c #0C0614",
|
||||
"! c #0C0A1C",
|
||||
"~ c #1C121C",
|
||||
"{ c #1C1224",
|
||||
"] c #0C060C",
|
||||
"^ c #1C0A1C",
|
||||
"/ c #2C2234",
|
||||
"( c #0C0A24",
|
||||
"_ c #140A24",
|
||||
": c #1C0E2C",
|
||||
"< c #240E24",
|
||||
"[ c #3C323C",
|
||||
"} c #B49EC4",
|
||||
"| c #AC9ECC",
|
||||
"1 c #CCCEE4",
|
||||
"2 c #84768C",
|
||||
"3 c #140E24",
|
||||
"4 c #241634",
|
||||
"5 c #4C324C",
|
||||
"6 c #341A3C",
|
||||
"7 c #645E7C",
|
||||
"8 c #8472AC",
|
||||
"9 c #9486BC",
|
||||
"0 c #D4D6EC",
|
||||
"a c #4C4664",
|
||||
"b c #443A64",
|
||||
"c c #DCEAF4",
|
||||
"d c #CCBADC",
|
||||
"e c #1C1634",
|
||||
"f c #342644",
|
||||
"g c #7C628C",
|
||||
"h c #6C567C",
|
||||
"i c #4C3654",
|
||||
"j c #2C1634",
|
||||
"k c #1C0E24",
|
||||
"l c #645A7C",
|
||||
"m c #8C7AB4",
|
||||
"n c #9C92C4",
|
||||
"o c #D4DEF4",
|
||||
"p c #ACAECC",
|
||||
"q c #544A6C",
|
||||
"r c #A4A2C4",
|
||||
"s c #E4EEF4",
|
||||
"t c #CCCAE4",
|
||||
"u c #DCD2E4",
|
||||
"v c #540E1C",
|
||||
"w c #840E14",
|
||||
"x c #440E1C",
|
||||
"y c #24264C",
|
||||
"z c #44365C",
|
||||
"A c #ACAAC4",
|
||||
"B c #C4C6DC",
|
||||
"C c #8C7AAC",
|
||||
"D c #5C426C",
|
||||
"E c #3C2A44",
|
||||
"F c #2C162C",
|
||||
"G c #A49EB4",
|
||||
"H c #9492AC",
|
||||
"I c #8C82A4",
|
||||
"J c #340E1C",
|
||||
"K c #7C0E14",
|
||||
"L c #14122C",
|
||||
"M c #3C3A64",
|
||||
"N c #3C3E74",
|
||||
"O c #ACA6CC",
|
||||
"P c #D4DEEC",
|
||||
"Q c #BCB2DC",
|
||||
"R c #846694",
|
||||
"S c #5C3E64",
|
||||
"T c #2C1E3C",
|
||||
"U c #341E34",
|
||||
"V c #C4C2CC",
|
||||
"W c #ECEAEC",
|
||||
"X c #2C2A4C",
|
||||
"Y c #242254",
|
||||
"Z c #1C1A4C",
|
||||
"` c #7466A4",
|
||||
" . c #BCBADC",
|
||||
".. c #CCDEEC",
|
||||
"+. c #745A84",
|
||||
"@. c #24162C",
|
||||
"#. c #3C2A3C",
|
||||
"$. c #241E2C",
|
||||
"%. c #1C1E4C",
|
||||
"&. c #242654",
|
||||
"*. c #142E64",
|
||||
"=. c #1C326C",
|
||||
"-. c #1C265C",
|
||||
";. c #34366C",
|
||||
">. c #8476AC",
|
||||
",. c #CCD2EC",
|
||||
"'. c #C4CAE4",
|
||||
"). c #4C4254",
|
||||
"!. c #44325C",
|
||||
"~. c #4C2E54",
|
||||
"{. c #141234",
|
||||
"]. c #142654",
|
||||
"^. c #144274",
|
||||
"/. c #1C3E74",
|
||||
"(. c #1C2254",
|
||||
"_. c #1C1E54",
|
||||
":. c #4C4A7C",
|
||||
"<. c #A492C4",
|
||||
"[. c #6C6A7C",
|
||||
"}. c #64628C",
|
||||
"|. c #847A8C",
|
||||
"1. c #644A74",
|
||||
"2. c #14224C",
|
||||
"3. c #1C3674",
|
||||
"4. c #14427C",
|
||||
"5. c #143E7C",
|
||||
"6. c #1C3A7C",
|
||||
"7. c #2C2644",
|
||||
"8. c #D4E2F4",
|
||||
"9. c #B4AACC",
|
||||
"0. c #8C7AA4",
|
||||
"a. c #140E2C",
|
||||
"b. c #141634",
|
||||
"c. c #14366C",
|
||||
"d. c #1C427C",
|
||||
"e. c #1C3E7C",
|
||||
"f. c #141E44",
|
||||
"g. c #C4CEEC",
|
||||
"h. c #DCE6EC",
|
||||
"i. c #C4C6C4",
|
||||
"j. c #6C5E74",
|
||||
"k. c #445274",
|
||||
"l. c #A4B6DC",
|
||||
"m. c #2C528C",
|
||||
"n. c #6472AC",
|
||||
"o. c #14163C",
|
||||
"p. c #4C4684",
|
||||
"q. c #BCB6DC",
|
||||
"r. c #D4CEDC",
|
||||
"s. c #9C9EA4",
|
||||
"t. c #B4C2DC",
|
||||
"u. c #2C365C",
|
||||
"v. c #5C6A94",
|
||||
"w. c #8CA2CC",
|
||||
"x. c #BCBEE4",
|
||||
"y. c #8C86AC",
|
||||
"z. c #1C2A64",
|
||||
"A. c #74769C",
|
||||
"B. c #CCCADC",
|
||||
"C. c #C4CEE4",
|
||||
"D. c #A49EBC",
|
||||
"E. c #1C162C",
|
||||
"F. c #8C8AB4",
|
||||
"G. c #445A8C",
|
||||
"H. c #A49EC4",
|
||||
"I. c #B4BAD4",
|
||||
"J. c #B4B2DC",
|
||||
"K. c #CCCEEC",
|
||||
"L. c #CCDAF4",
|
||||
"M. c #BCC6E4",
|
||||
"N. c #746A8C",
|
||||
"O. c #949AB4",
|
||||
"P. c #9C8EB4",
|
||||
"Q. c #544E74",
|
||||
"R. c #342E4C",
|
||||
"S. c #242A54",
|
||||
"T. c #6C7AA4",
|
||||
"U. c #4C5E94",
|
||||
"V. c #7486B4",
|
||||
"W. c #9CAAD4",
|
||||
"X. c #C4D2EC",
|
||||
"Y. c #D4E2EC",
|
||||
"Z. c #DCEEF4",
|
||||
"`. c #D4DAEC",
|
||||
" + c #C4C6E4",
|
||||
".+ c #B4AED4",
|
||||
"++ c #7C7AA4",
|
||||
"@+ c #9496B4",
|
||||
"#+ c #9492B4",
|
||||
"$+ c #8C92AC",
|
||||
" ",
|
||||
" ",
|
||||
" . + ",
|
||||
" @ # $ ",
|
||||
" % & * $ ",
|
||||
" = - ; = = - > , ' ",
|
||||
" = ; ; = ) = ! ) = ! ",
|
||||
" ~ ; ) ) ; = ! = ! = { ",
|
||||
" = ; ] ) ; ) ) = ! = = ^ / ",
|
||||
" = ; ) ! ) = ! ( ! ! _ : < _ [ } | 1 2 ",
|
||||
" 3 = ) ! ) ( ( ( ( _ 3 4 5 6 { = 7 8 9 0 a b 0 c d ",
|
||||
" = ( = = ( = ! _ ! e f g h i j k l m n o p q r s t u ",
|
||||
" 3 _ v w x ) _ ( _ y z A B C D E j F n r C G H I ",
|
||||
" _ J w K < _ _ L M b N O P Q R S T E U V V W ",
|
||||
" _ _ x ^ _ 3 X M Y Z X ` ...| +.@.T #. ",
|
||||
" $.= _ _ L %.&.*.=.-.Z ;.>.,.'.).!.~. ",
|
||||
" = ! = 3 {.].^././.*.(._.:.<.[.}.|.1. ",
|
||||
" > = ! ( L 2.3.4.5.6.*._.Y 7.}.8.9. ",
|
||||
" 0.@.M 3 = a.b.].c.d.e.3.f.a.&.8 g.h. ",
|
||||
" i.j.k.l.b ; ( 3 f.*.4.m.n.o.Z %.p.q. ",
|
||||
" r.s.t.l. = ! 3 u.v.w.x.y.*.z._.A. ",
|
||||
" B.C.D.t. ! E.x.Q 9.+ F.6.G. ",
|
||||
" H.I.I. ! J. .K...'. ",
|
||||
"r.J.A L.M.D.N.O. ",
|
||||
"P.9. Q.R.%.S.T. ",
|
||||
" N U.V.W.X. ",
|
||||
" M.X.Y.c c ",
|
||||
" c Z.c `. + ",
|
||||
" B .+n ++@+ ",
|
||||
" #+$+p A ",
|
||||
" ",
|
||||
" "};
|
BIN
qucs-transcalc/bitmaps/c_microstrip.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
qucs-transcalc/bitmaps/coax.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
qucs-transcalc/bitmaps/cpw.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
qucs-transcalc/bitmaps/cpw_back.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
qucs-transcalc/bitmaps/microstrip.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
qucs-transcalc/bitmaps/rectwaveguide.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
qucs-transcalc/bitmaps/stripline.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
919
qucs-transcalc/c_microstrip.cpp
Normal file
@ -0,0 +1,919 @@
|
||||
/*
|
||||
* c_microstrip.cpp - coupled microstrip class implementation
|
||||
*
|
||||
* Copyright (C) 2002 Claudio Girardi <claudio.girardi@ieee.org>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* c_microstrip.c - Puts up window for coupled microstrips and
|
||||
* performs the associated calculations
|
||||
* Based on the original microstrip.c by Gopal Narayanan
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "units.h"
|
||||
#include "transline.h"
|
||||
#include "microstrip.h"
|
||||
#include "c_microstrip.h"
|
||||
|
||||
c_microstrip::c_microstrip() : transline()
|
||||
{
|
||||
aux_ms = NULL;
|
||||
}
|
||||
|
||||
c_microstrip::~c_microstrip()
|
||||
{
|
||||
if (aux_ms) delete aux_ms;
|
||||
}
|
||||
|
||||
/*
|
||||
* delta_u_thickness_single() computes the thickness effect on
|
||||
* normalized width for a single microstrip line
|
||||
*
|
||||
* References: H. A. Atwater, "Simplified Design Equations for
|
||||
* Microstrip Line Parameters", Microwave Journal, pp. 109-115,
|
||||
* November 1989.
|
||||
*/
|
||||
double c_microstrip::delta_u_thickness_single(double u, double t_h)
|
||||
{
|
||||
double delta_u;
|
||||
|
||||
if (t_h > 0.0) {
|
||||
delta_u = (1.25 * t_h / pi) * (1.0 + log((2.0 + (4.0 * pi * u - 2.0) / (1.0 + exp(-100.0 * (u - 1.0 / (2.0 * pi))))) / t_h));
|
||||
} else {
|
||||
delta_u = 0.0;
|
||||
}
|
||||
return delta_u;
|
||||
}
|
||||
|
||||
/*
|
||||
* delta_u_thickness() - compute the thickness effect on normalized
|
||||
* width for coupled microstrips
|
||||
*
|
||||
* References: Rolf Jansen, "High-Speed Cmputation of Single and
|
||||
* Coupled Microstrip Parameters Including Dispersion, High-Order
|
||||
* Modes, Loss and Finite Strip Thickness", IEEE Trans. MTT, vol. 26,
|
||||
* no. 2, pp. 75-82, Feb. 1978
|
||||
*/
|
||||
void c_microstrip::delta_u_thickness()
|
||||
{
|
||||
double e_r, u, g, t_h;
|
||||
double delta_u, delta_t, delta_u_e, delta_u_o;
|
||||
|
||||
e_r = er;
|
||||
u = w / h; /* normalized line width */
|
||||
g = s / h; /* normalized line spacing */
|
||||
t_h = t / h; /* normalized strip thickness */
|
||||
|
||||
if (t_h > 0.0) {
|
||||
/* single microstrip correction for finite strip thickness */
|
||||
delta_u = delta_u_thickness_single(u, t_h);
|
||||
delta_t = t_h / (g * e_r);
|
||||
/* thickness correction for the even- and odd-mode */
|
||||
delta_u_e = delta_u * (1.0 - 0.5 * exp(-0.69 * delta_u / delta_t));
|
||||
delta_u_o = delta_u_e + delta_t;
|
||||
} else {
|
||||
delta_u_e = delta_u_o = 0.0;
|
||||
}
|
||||
|
||||
w_t_e = w + delta_u_e * h;
|
||||
w_t_o = w + delta_u_o * h;
|
||||
}
|
||||
|
||||
/*
|
||||
* compute various parameters for a single line
|
||||
*/
|
||||
void c_microstrip::compute_single_line()
|
||||
{
|
||||
if (aux_ms == NULL)
|
||||
aux_ms = new microstrip ();
|
||||
|
||||
/* prepare parameters for single microstrip computations */
|
||||
aux_ms->er = er;
|
||||
aux_ms->w = w;
|
||||
aux_ms->h = h;
|
||||
aux_ms->t = 0.0;
|
||||
//aux_ms->t = t;
|
||||
aux_ms->ht = 1e12; /* arbitrarily high */
|
||||
aux_ms->f = f;
|
||||
aux_ms->mur = mur;
|
||||
aux_ms->microstrip_Z0();
|
||||
aux_ms->dispersion();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* filling_factor_even() - compute the filling factor for the coupled
|
||||
* microstrips even-mode without cover and zero conductor thickness
|
||||
*/
|
||||
double c_microstrip::filling_factor_even(double u, double g, double e_r)
|
||||
{
|
||||
double v, v3, v4, a_e, b_e, q_inf;
|
||||
|
||||
v = u * (20.0 + g * g) / (10.0 + g * g) + g * exp(-g);
|
||||
v3 = v * v * v;
|
||||
v4 = v3 * v;
|
||||
a_e = 1.0 + log((v4 + v * v / 2704.0) / (v4 + 0.432)) / 49.0 + log(1.0 + v3 / 5929.741)
|
||||
/ 18.7;
|
||||
b_e = 0.564 * pow(((e_r - 0.9) / (e_r + 3.0)), 0.053);
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
q_inf = pow((1.0 + 10.0 / v), -a_e * b_e);
|
||||
|
||||
return q_inf;
|
||||
}
|
||||
|
||||
/**
|
||||
* filling_factor_odd() - compute the filling factor for the coupled
|
||||
* microstrips odd-mode without cover and zero conductor thickness
|
||||
*/
|
||||
double c_microstrip::filling_factor_odd(double u, double g, double e_r)
|
||||
{
|
||||
double b_o, c_o, d_o, q_inf;
|
||||
|
||||
b_o = 0.747 * e_r / (0.15 + e_r);
|
||||
c_o = b_o - (b_o - 0.207) * exp(-0.414 * u);
|
||||
d_o = 0.593 + 0.694 * exp(-0.562 * u);
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
q_inf = exp(-c_o * pow(g, d_o));
|
||||
|
||||
return q_inf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* delta_q_cover_even() - compute the cover effect on filling factor
|
||||
* for the even-mode
|
||||
*/
|
||||
double c_microstrip::delta_q_cover_even(double h2h)
|
||||
{
|
||||
double q_c;
|
||||
|
||||
if (h2h <= 39) {
|
||||
q_c = tanh(1.626 + 0.107 * h2h - 1.733 / sqrt(h2h));
|
||||
} else {
|
||||
q_c = 1.0;
|
||||
}
|
||||
|
||||
return q_c;
|
||||
}
|
||||
|
||||
/*
|
||||
* delta_q_cover_odd() - compute the cover effect on filling factor
|
||||
* for the odd-mode
|
||||
*/
|
||||
double c_microstrip::delta_q_cover_odd(double h2h)
|
||||
{
|
||||
double q_c;
|
||||
|
||||
if (h2h <= 7) {
|
||||
q_c = tanh(9.575 / (7.0 - h2h) - 2.965 + 1.68 * h2h - 0.311 * h2h * h2h);
|
||||
} else {
|
||||
q_c = 1.0;
|
||||
}
|
||||
|
||||
return q_c;
|
||||
}
|
||||
|
||||
/**
|
||||
* er_eff_static() - compute the static effective dielectric constants
|
||||
*
|
||||
* References: Manfred Kirschning and Rolf Jansen, "Accurate
|
||||
* Wide-Range Design Equations for the Frequency-Dependent
|
||||
* Characteristic of Parallel Coupled Microstrip Lines", IEEE
|
||||
* Trans. MTT, vol. 32, no. 1, Jan. 1984
|
||||
*/
|
||||
void c_microstrip::er_eff_static()
|
||||
{
|
||||
double u_t_e, u_t_o, g, h2, h2h;
|
||||
double a_o, t_h, q, q_c, q_t, q_inf;
|
||||
double er_eff_single;
|
||||
|
||||
/* compute zero-thickness single line parameters */
|
||||
compute_single_line();
|
||||
er_eff_single = aux_ms->er_eff_0;
|
||||
|
||||
h2 = ht;
|
||||
u_t_e = w_t_e / h; /* normalized even_mode line width */
|
||||
u_t_o = w_t_o / h; /* normalized odd_mode line width */
|
||||
g = s / h; /* normalized line spacing */
|
||||
h2h = h2 / h; /* normalized cover height */
|
||||
t_h = t / h; /* normalized strip thickness */
|
||||
|
||||
/* filling factor, computed with thickness corrected width */
|
||||
q_inf = filling_factor_even(u_t_e, g, er);
|
||||
/* cover effect */
|
||||
q_c = delta_q_cover_even(h2h);
|
||||
/* thickness effect */
|
||||
q_t = aux_ms->delta_q_thickness(u_t_e, t_h);
|
||||
/* resultant filling factor */
|
||||
q = (q_inf - q_t) * q_c;
|
||||
/* static even-mode effective dielectric constant */
|
||||
er_eff_e_0 = 0.5 * (er + 1.0) + 0.5 * (er - 1.0) * q;
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
q_inf = filling_factor_odd(u_t_o, g, er);
|
||||
/* cover effect */
|
||||
q_c = delta_q_cover_odd(h2h);
|
||||
/* thickness effect */
|
||||
q_t = aux_ms->delta_q_thickness(u_t_o, t_h);
|
||||
/* resultant filling factor */
|
||||
q = (q_inf - q_t) * q_c;
|
||||
|
||||
a_o = 0.7287 * (er_eff_single - 0.5 * (er + 1.0)) * (1.0 - exp(-0.179 * u_t_o));
|
||||
|
||||
/* static odd-mode effective dielectric constant */
|
||||
er_eff_o_0 = (0.5 * (er + 1.0) + a_o - er_eff_single) * q + er_eff_single;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* delta_Z0_even_cover() - compute the even-mode impedance correction
|
||||
* for a homogeneous microstrip due to the cover
|
||||
*
|
||||
* References: S. March, "Microstrip Packaging: Watch the Last Step",
|
||||
* Microwaves, vol. 20, no. 13, pp. 83.94, Dec. 1981.
|
||||
*/
|
||||
double c_microstrip::delta_Z0_even_cover(double g, double u, double h2h)
|
||||
{
|
||||
double f_e, g_e, delta_Z0_even;
|
||||
double x, y, A, B, C, D, E, F;
|
||||
|
||||
A = -4.351 / pow(1.0 + h2h, 1.842);
|
||||
B = 6.639 / pow(1.0 + h2h, 1.861);
|
||||
C = -2.291 / pow(1.0 + h2h, 1.90);
|
||||
f_e = 1.0 - atanh(A + (B + C * u) * u);
|
||||
|
||||
if (g < 4.46631063751) {
|
||||
x = pow(10.0, 0.103 * g - 0.159);
|
||||
y = pow(10.0, 0.0492 * g - 0.073);
|
||||
D = 0.747 / sin(0.5 * pi * x);
|
||||
E = 0.725 * sin(0.5 * pi * y);
|
||||
F = pow(10.0, 0.11 - 0.0947 * g);
|
||||
g_e = 270.0 * (1.0 - tanh(D + E * sqrt(1.0 + h2h) - F / (1.0 + h2h)));
|
||||
} else
|
||||
g_e = 0.0;
|
||||
|
||||
delta_Z0_even = f_e * g_e;
|
||||
|
||||
return delta_Z0_even;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* delta_Z0_odd_cover() - compute the odd-mode impedance correction
|
||||
* for a homogeneous microstrip due to the cover
|
||||
*
|
||||
* References: S. March, "Microstrip Packaging: Watch the Last Step",
|
||||
* Microwaves, vol. 20, no. 13, pp. 83.94, Dec. 1981.
|
||||
*/
|
||||
double c_microstrip::delta_Z0_odd_cover(double g, double u, double h2h)
|
||||
{
|
||||
double f_o, g_o, delta_Z0_odd;
|
||||
double G, J, K, L;
|
||||
|
||||
J = tanh(pow(1.0 + h2h, 1.585) / 6.0);
|
||||
f_o = pow(u, J);
|
||||
|
||||
G = 2.178 - 0.796 * g;
|
||||
if (g > 0.858) {
|
||||
K = log10(20.492 * pow(g, 0.174));
|
||||
} else {
|
||||
K = 1.30;
|
||||
}
|
||||
if (g > 0.873) {
|
||||
L = 2.51 * pow(g, -0.462);
|
||||
} else {
|
||||
L = 2.674;
|
||||
}
|
||||
g_o = 270.0 * (1.0 - tanh(G + K * sqrt(1.0 + h2h) - L / (1.0 + h2h)));
|
||||
|
||||
delta_Z0_odd = f_o * g_o;
|
||||
|
||||
return delta_Z0_odd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Z0_even_odd() - compute the static even- and odd-mode static
|
||||
* impedances
|
||||
*
|
||||
* References: Manfred Kirschning and Rolf Jansen, "Accurate
|
||||
* Wide-Range Design Equations for the Frequency-Dependent
|
||||
* Characteristic of Parallel Coupled Microstrip Lines", IEEE
|
||||
* Trans. MTT, vol. 32, no. 1, Jan. 1984
|
||||
*/
|
||||
void c_microstrip::Z0_even_odd()
|
||||
{
|
||||
double er_eff, h2, u_t_e, u_t_o, g, h2h;
|
||||
double Q_1, Q_2, Q_3, Q_4, Q_5, Q_6, Q_7, Q_8, Q_9, Q_10;
|
||||
double delta_Z0_e_0, delta_Z0_o_0, Z0_single, er_eff_single;
|
||||
|
||||
h2 = ht;
|
||||
u_t_e = w_t_e / h; /* normalized even-mode line width */
|
||||
u_t_o = w_t_o / h; /* normalized odd-mode line width */
|
||||
g = s / h; /* normalized line spacing */
|
||||
h2h = h2 / h; /* normalized cover height */
|
||||
|
||||
Z0_single = aux_ms->Z0_0;
|
||||
er_eff_single = aux_ms->er_eff_0;
|
||||
|
||||
/* even-mode */
|
||||
er_eff = er_eff_e_0;
|
||||
Q_1 = 0.8695 * pow(u_t_e, 0.194);
|
||||
Q_2 = 1.0 + 0.7519 * g + 0.189 * pow(g, 2.31);
|
||||
Q_3 = 0.1975 + pow((16.6 + pow((8.4 / g), 6.0)), -0.387) + log(pow(g, 10.0) / (1.0 + pow(g / 3.4, 10.0))) / 241.0;
|
||||
Q_4 = 2.0 * Q_1 / (Q_2 * (exp(-g) * pow(u_t_e, Q_3) + (2.0 - exp(-g)) * pow(u_t_e, -Q_3)));
|
||||
/* static even-mode impedance */
|
||||
Z0_e_0 = Z0_single * sqrt(er_eff_single / er_eff) / (1.0 - sqrt(er_eff_single) * Q_4 * Z0_single / ZF0);
|
||||
/* correction for cover */
|
||||
delta_Z0_e_0 = delta_Z0_even_cover(g, u_t_e, h2h) / sqrt(er_eff);
|
||||
|
||||
Z0_e_0 = Z0_e_0 - delta_Z0_e_0;
|
||||
|
||||
/* odd-mode */
|
||||
er_eff = er_eff_o_0;
|
||||
Q_5 = 1.794 + 1.14 * log(1.0 + 0.638 / (g + 0.517 * pow(g, 2.43)));
|
||||
Q_6 = 0.2305 + log(pow(g, 10.0) / (1.0 + pow(g / 5.8, 10.0))) / 281.3 + log(1.0 + 0.598 * pow(g, 1.154)) / 5.1;
|
||||
Q_7 = (10.0 + 190.0 * g * g) / (1.0 + 82.3 * g * g * g);
|
||||
Q_8 = exp(-6.5 - 0.95 * log(g) - pow(g / 0.15, 5.0));
|
||||
Q_9 = log(Q_7) * (Q_8 + 1.0 / 16.5);
|
||||
Q_10 = (Q_2 * Q_4 - Q_5 * exp(log(u_t_o) * Q_6 * pow(u_t_o, -Q_9))) / Q_2;
|
||||
|
||||
/* static odd-mode impedance */
|
||||
Z0_o_0 = Z0_single * sqrt(er_eff_single / er_eff) / (1.0 - sqrt(er_eff_single) * Q_10 * Z0_single / ZF0);
|
||||
/* correction for cover */
|
||||
delta_Z0_o_0 = delta_Z0_odd_cover(g, u_t_o, h2h) / sqrt(er_eff);
|
||||
|
||||
Z0_o_0 = Z0_o_0 - delta_Z0_o_0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mur_eff() - returns effective magnetic permeability
|
||||
*/
|
||||
double c_microstrip::calc_mur_eff()
|
||||
{
|
||||
double mureff;
|
||||
mureff = mur; /* FIXME: ... */
|
||||
return mureff;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* er_eff_freq() - compute er_eff as a function of frequency
|
||||
*/
|
||||
void c_microstrip::er_eff_freq()
|
||||
{
|
||||
double P_1, P_2, P_3, P_4, P_5, P_6, P_7;
|
||||
double P_8, P_9, P_10, P_11, P_12, P_13, P_14, P_15;
|
||||
double F_e, F_o;
|
||||
double er_eff, u, g, f_n;
|
||||
|
||||
u = w / h; /* normalize line width */
|
||||
g = s / h; /* normalize line spacing */
|
||||
|
||||
/* normalized frequency [GHz * mm] */
|
||||
f_n = f * h / 1e06;
|
||||
|
||||
er_eff = er_eff_e_0;
|
||||
P_1 = 0.27488 + (0.6315 + 0.525 / pow(1.0 + 0.0157 * f_n, 20.0)) * u - 0.065683 * exp(-8.7513 * u);
|
||||
P_2 = 0.33622 * (1.0 - exp(-0.03442 * er));
|
||||
P_3 = 0.0363 * exp(-4.6 * u) * (1.0 - exp(-pow(f_n / 38.7, 4.97)));
|
||||
P_4 = 1.0 + 2.751 * (1.0 - exp(-pow(er / 15.916, 8.0)));
|
||||
P_5 = 0.334 * exp(-3.3 * pow(er / 15.0, 3.0)) + 0.746;
|
||||
P_6 = P_5 * exp(-pow(f_n / 18.0, 0.368));
|
||||
P_7 = 1.0 + 4.069 * P_6 * pow(g, 0.479) * exp(-1.347 * pow(g, 0.595) - 0.17 * pow(g, 2.5));
|
||||
|
||||
F_e = P_1 * P_2 * pow((P_3 * P_4 + 0.1844 * P_7) * f_n, 1.5763);
|
||||
/* even-mode effective dielectric constant */
|
||||
er_eff_e = er - (er - er_eff) / (1.0 + F_e);
|
||||
|
||||
er_eff = er_eff_o_0;
|
||||
P_8 = 0.7168 * (1.0 + 1.076 / (1.0 + 0.0576 * (er - 1.0)));
|
||||
P_9 = P_8 - 0.7913 * (1.0 - exp(-pow(f_n / 20.0, 1.424))) * atan(2.481 * pow(er / 8.0, 0.946));
|
||||
P_10 = 0.242 * pow(er - 1.0, 0.55);
|
||||
P_11 = 0.6366 * (exp(-0.3401 * f_n) - 1.0) * atan(1.263 * pow(u / 3.0, 1.629));
|
||||
P_12 = P_9 + (1.0 - P_9) / (1.0 + 1.183 * pow(u, 1.376));
|
||||
P_13 = 1.695 * P_10 / (0.414 + 1.605 * P_10);
|
||||
P_14 = 0.8928 + 0.1072 * (1.0 - exp(-0.42 * pow(f_n / 20.0, 3.215)));
|
||||
P_15 = std::abs(1.0 - 0.8928 * (1.0 + P_11) * P_12 * exp(-P_13 * pow(g, 1.092)) / P_14);
|
||||
|
||||
F_o = P_1 * P_2 * pow((P_3 * P_4 + 0.1844) * f_n * P_15, 1.5763);
|
||||
/* odd-mode effective dielectric constant */
|
||||
er_eff_o = er - (er - er_eff) / (1.0 + F_o);
|
||||
}
|
||||
|
||||
/*
|
||||
* conductor_losses() - compute microstrips conductor losses per unit
|
||||
* length
|
||||
*/
|
||||
void c_microstrip::conductor_losses()
|
||||
{
|
||||
double e_r_eff_e_0, e_r_eff_o_0, Z0_h_e, Z0_h_o, delta;
|
||||
double K, R_s, Q_c_e, Q_c_o, alpha_c_e, alpha_c_o;
|
||||
|
||||
e_r_eff_e_0 = er_eff_e_0;
|
||||
e_r_eff_o_0 = er_eff_o_0;
|
||||
Z0_h_e = Z0_e_0 * sqrt(e_r_eff_e_0); /* homogeneous stripline impedance */
|
||||
Z0_h_o = Z0_o_0 * sqrt(e_r_eff_o_0); /* homogeneous stripline impedance */
|
||||
delta = skindepth;
|
||||
|
||||
if (f > 0.0) {
|
||||
/* current distribution factor (same for the two modes) */
|
||||
K = exp(-1.2 * pow((Z0_h_e + Z0_h_o) / (2.0 * ZF0), 0.7));
|
||||
/* skin resistance */
|
||||
R_s = 1.0 / (sigma * delta);
|
||||
/* correction for surface roughness */
|
||||
R_s *= 1.0 + ((2.0 / pi) * atan(1.40 * pow((rough / delta), 2.0)));
|
||||
|
||||
/* even-mode strip inductive quality factor */
|
||||
Q_c_e = (pi * Z0_h_e * w * f) / (R_s * C0 * K);
|
||||
/* even-mode losses per unith length */
|
||||
alpha_c_e = (20.0 * pi / log(10.0)) * f * sqrt(e_r_eff_e_0) / (C0 * Q_c_e);
|
||||
|
||||
/* odd-mode strip inductive quality factor */
|
||||
Q_c_o = (pi * Z0_h_o * w * f) / (R_s * C0 * K);
|
||||
/* odd-mode losses per unith length */
|
||||
alpha_c_o = (20.0 * pi / log(10.0)) * f * sqrt(e_r_eff_o_0) / (C0 * Q_c_o);
|
||||
} else {
|
||||
alpha_c_e = alpha_c_o = 0.0;
|
||||
}
|
||||
|
||||
atten_cond_e = alpha_c_e * l;
|
||||
atten_cond_o = alpha_c_o * l;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dielectric_losses() - compute microstrips dielectric losses per
|
||||
* unit length
|
||||
*/
|
||||
void c_microstrip::dielectric_losses()
|
||||
{
|
||||
double e_r, e_r_eff_e_0, e_r_eff_o_0;
|
||||
double alpha_d_e, alpha_d_o;
|
||||
|
||||
e_r = er;
|
||||
e_r_eff_e_0 = er_eff_e_0;
|
||||
e_r_eff_o_0 = er_eff_o_0;
|
||||
|
||||
alpha_d_e = (20.0 * pi / log(10.0)) * (f / C0) * (e_r / sqrt(e_r_eff_e_0)) * ((e_r_eff_e_0 - 1.0) / (e_r - 1.0)) * tand;
|
||||
alpha_d_o = (20.0 * pi / log(10.0)) * (f / C0) * (e_r / sqrt(e_r_eff_o_0)) * ((e_r_eff_o_0 - 1.0) / (e_r - 1.0)) * tand;
|
||||
|
||||
atten_dielectric_e = alpha_d_e * l;
|
||||
atten_dielectric_o = alpha_d_o * l;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* c_microstrip_attenuation() - compute attenuation of coupled
|
||||
* microstrips
|
||||
*/
|
||||
void c_microstrip::attenuation()
|
||||
{
|
||||
skindepth = skin_depth();
|
||||
conductor_losses();
|
||||
dielectric_losses();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* line_angle() - calculate strips electrical lengths in radians
|
||||
*/
|
||||
void c_microstrip::line_angle()
|
||||
{
|
||||
double e_r_eff_e, e_r_eff_o;
|
||||
double v_e, v_o, lambda_g_e, lambda_g_o;
|
||||
|
||||
e_r_eff_e = er_eff_e;
|
||||
e_r_eff_o = er_eff_o;
|
||||
|
||||
/* even-mode velocity */
|
||||
v_e = C0 / sqrt(e_r_eff_e);
|
||||
/* odd-mode velocity */
|
||||
v_o = C0 / sqrt(e_r_eff_o);
|
||||
/* even-mode wavelength */
|
||||
lambda_g_e = v_e / f;
|
||||
/* odd-mode wavelength */
|
||||
lambda_g_o = v_o / f;
|
||||
/* electrical angles */
|
||||
ang_l_e = 2.0 * pi * l / lambda_g_e; /* in radians */
|
||||
ang_l_o = 2.0 * pi * l / lambda_g_o; /* in radians */
|
||||
}
|
||||
|
||||
|
||||
void c_microstrip::syn_err_fun(double *f1, double *f2, double s_h, double w_h, double e_r, double w_h_se, double w_h_so)
|
||||
{
|
||||
|
||||
double g, h;
|
||||
|
||||
g = cosh(0.5 * pi * s_h);
|
||||
h = cosh(pi * w_h + 0.5 * pi * s_h);
|
||||
|
||||
*f1 = (2.0 / pi) * acosh((2.0 * h - g + 1.0) / (g + 1.0));
|
||||
*f2 = (2.0 / pi) * acosh((2.0 * h - g - 1.0) / (g - 1.0));
|
||||
if (e_r <= 6.0) {
|
||||
*f2 += (4.0 / (pi * (1.0 + e_r / 2.0))) * acosh(1.0 + 2.0 * w_h / s_h);
|
||||
} else {
|
||||
*f2 += (1.0 / pi) * acosh(1.0 + 2.0 * w_h / s_h);
|
||||
}
|
||||
*f1 -= w_h_se;
|
||||
*f2 -= w_h_so;
|
||||
}
|
||||
|
||||
/*
|
||||
* synth_width - calculate widths given Z0 and e_r
|
||||
* from Akhtarzad S. et al., "The design of coupled microstrip lines",
|
||||
* IEEE Trans. MTT-23, June 1975 and
|
||||
* Hinton, J.H., "On design of coupled microstrip lines", IEEE Trans.
|
||||
* MTT-28, March 1980
|
||||
*/
|
||||
void c_microstrip::synth_width()
|
||||
{
|
||||
double Z0, e_r;
|
||||
double w_h_se, w_h_so, w_h, a, ce, co, s_h;
|
||||
double f1, f2, ft1, ft2, j11, j12, j21, j22, d_s_h, d_w_h, err;
|
||||
double eps = 1e-04;
|
||||
|
||||
f1 = f2 = 0;
|
||||
e_r = er;
|
||||
|
||||
Z0 = Z0e / 2.0;
|
||||
/* Wheeler formula for single microstrip synthesis */
|
||||
a = exp(Z0 * sqrt(e_r + 1.0) / 42.4) - 1.0;
|
||||
w_h_se = 8.0 * sqrt(a * ((7.0 + 4.0 / e_r) / 11.0) + ((1.0 + 1.0 / e_r) / 0.81)) / a;
|
||||
|
||||
Z0 = Z0o / 2.0;
|
||||
/* Wheeler formula for single microstrip synthesis */
|
||||
a = exp(Z0 * sqrt(e_r + 1.0) / 42.4) - 1.0;
|
||||
w_h_so = 8.0 * sqrt(a * ((7.0 + 4.0 / e_r) / 11.0) + ((1.0 + 1.0 / e_r) / 0.81)) / a;
|
||||
|
||||
ce = cosh(0.5 * pi * w_h_se);
|
||||
co = cosh(0.5 * pi * w_h_so);
|
||||
/* first guess at s/h */
|
||||
s_h = (2.0 / pi) * acosh((ce + co - 2.0) / (co - ce));
|
||||
/* first guess at w/h */
|
||||
w_h = acosh((ce * co - 1.0) / (co - ce)) / pi - s_h / 2.0;
|
||||
|
||||
s = s_h * h;
|
||||
w = w_h * h;
|
||||
|
||||
syn_err_fun(&f1, &f2, s_h, w_h, e_r, w_h_se, w_h_so);
|
||||
|
||||
/* rather crude Newton-Rhapson; we need this beacuse the estimate of */
|
||||
/* w_h is often quite far from the true value (see Akhtarzad S. et al.) */
|
||||
do {
|
||||
/* compute Jacobian */
|
||||
syn_err_fun(&ft1, &ft2, s_h + eps, w_h, e_r, w_h_se, w_h_so);
|
||||
j11 = (ft1 - f1) / eps;
|
||||
j21 = (ft2 - f2) / eps;
|
||||
syn_err_fun(&ft1, &ft2, s_h, w_h + eps, e_r, w_h_se, w_h_so);
|
||||
j12 = (ft1 - f1) / eps;
|
||||
j22 = (ft2 - f2) / eps;
|
||||
|
||||
/* compute next step */
|
||||
d_s_h = (-f1 * j22 + f2 * j12) / (j11 * j22 - j21 * j12);
|
||||
d_w_h = (-f2 * j11 + f1 * j21) / (j11 * j22 - j21 * j12);
|
||||
//g_print("j11 = %e\tj12 = %e\tj21 = %e\tj22 = %e\n", j11, j12, j21, j22);
|
||||
//g_print("det = %e\n", j11*j22 - j21*j22);
|
||||
//g_print("d_s_h = %e\td_w_h = %e\n", d_s_h, d_w_h);
|
||||
|
||||
s_h += d_s_h;
|
||||
w_h += d_w_h;
|
||||
|
||||
/* chech the error */
|
||||
syn_err_fun(&f1, &f2, s_h, w_h, e_r, w_h_se, w_h_so);
|
||||
|
||||
err = sqrt(f1 * f1 + f2 * f2);
|
||||
/* converged ? */
|
||||
} while (err > 1e-04);
|
||||
|
||||
|
||||
s = s_h * h;
|
||||
w = w_h * h;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Z0_dispersion() - calculate frequency dependency of characteristic
|
||||
* impedances
|
||||
*/
|
||||
void c_microstrip::Z0_dispersion()
|
||||
{
|
||||
double Q_0;
|
||||
double Q_11, Q_12, Q_13, Q_14, Q_15, Q_16, Q_17, Q_18, Q_19, Q_20, Q_21;
|
||||
double Q_22, Q_23, Q_24, Q_25, Q_26, Q_27, Q_28, Q_29;
|
||||
double r_e, q_e, p_e, d_e, C_e;
|
||||
double e_r_eff_o_f, e_r_eff_o_0;
|
||||
double e_r_eff_single_f, e_r_eff_single_0, Z0_single_f;
|
||||
double f_n, g, u, e_r;
|
||||
double R_1, R_2, R_7, R_10, R_11, R_12, R_15, R_16, tmpf;
|
||||
|
||||
e_r = er;
|
||||
|
||||
u = w / h; /* normalize line width */
|
||||
g = s / h; /* normalize line spacing */
|
||||
|
||||
/* normalized frequency [GHz * mm] */
|
||||
f_n = f * h / 1e06;
|
||||
|
||||
e_r_eff_single_f = aux_ms->er_eff;
|
||||
e_r_eff_single_0 = aux_ms->er_eff_0;
|
||||
Z0_single_f = aux_ms->Z0;
|
||||
|
||||
e_r_eff_o_f = er_eff_o;
|
||||
e_r_eff_o_0 = er_eff_o_0;
|
||||
|
||||
Q_11 = 0.893 * (1.0 - 0.3 / (1.0 + 0.7 * (e_r - 1.0)));
|
||||
Q_12 = 2.121 * (pow(f_n / 20.0, 4.91) / (1.0 + Q_11 * pow(f_n / 20.0, 4.91))) * exp(-2.87 * g) * pow(g, 0.902);
|
||||
Q_13 = 1.0 + 0.038 * pow(e_r / 8.0, 5.1);
|
||||
Q_14 = 1.0 + 1.203 * pow(e_r / 15.0, 4.0) / (1.0 + pow(e_r / 15.0, 4.0));
|
||||
Q_15 = 1.887 * exp(-1.5 * pow(g, 0.84)) * pow(g, Q_14) / (1.0 + 0.41 * pow(f_n / 15.0, 3.0) * pow(u, 2.0 / Q_13) / (0.125 + pow(u, 1.626 / Q_13)));
|
||||
Q_16 = (1.0 + 9.0 / (1.0 + 0.403 * pow(e_r - 1.0, 2))) * Q_15;
|
||||
Q_17 = 0.394 * (1.0 - exp(-1.47 * pow(u / 7.0, 0.672))) * (1.0 - exp(-4.25 * pow(f_n / 20.0, 1.87)));
|
||||
Q_18 = 0.61 * (1.0 - exp(-2.13 * pow(u / 8.0, 1.593))) / (1.0 + 6.544 * pow(g, 4.17));
|
||||
Q_19 = 0.21 * g * g * g * g / ((1.0 + 0.18 * pow(g, 4.9)) * (1.0 + 0.1 * u * u) * (1.0 + pow(f_n / 24.0, 3.0)));
|
||||
Q_20 = (0.09 + 1.0 / (1.0 + 0.1 * pow(e_r - 1, 2.7))) * Q_19;
|
||||
Q_21 = std::abs(1.0 - 42.54 * pow(g, 0.133) * exp(-0.812 * g) * pow(u, 2.5) / (1.0 + 0.033 * pow(u, 2.5)));
|
||||
|
||||
r_e = pow(f_n / 28.843, 12);
|
||||
q_e = 0.016 + pow(0.0514 * e_r * Q_21, 4.524);
|
||||
p_e = 4.766 * exp(-3.228 * pow(u, 0.641));
|
||||
d_e = 5.086 * q_e * (r_e / (0.3838 + 0.386 * q_e)) * (exp(-22.2 * pow(u, 1.92)) / (1.0 + 1.2992 * r_e)) * (pow(e_r - 1.0, 6.0) / (1.0 + 10 * pow(e_r - 1.0, 6.0)));
|
||||
C_e = 1.0 + 1.275 * (1.0 - exp(-0.004625 * p_e * pow(e_r, 1.674) * pow(f_n / 18.365, 2.745))) - Q_12 + Q_16 - Q_17 + Q_18 + Q_20;
|
||||
|
||||
|
||||
R_1 = 0.03891 * pow(e_r, 1.4);
|
||||
R_2 = 0.267 * pow(u, 7.0);
|
||||
R_7 = 1.206 - 0.3144 * exp(-R_1) * (1.0 - exp(-R_2));
|
||||
R_10 = 0.00044 * pow(e_r, 2.136) + 0.0184;
|
||||
tmpf = pow(f_n / 19.47, 6.0);
|
||||
R_11 = tmpf / (1.0 + 0.0962 * tmpf);
|
||||
R_12 = 1.0 / (1.0 + 0.00245 * u * u);
|
||||
R_15 = 0.707 * R_10 * pow(f_n / 12.3, 1.097);
|
||||
R_16 = 1.0 + 0.0503 * e_r * e_r * R_11 * (1.0 - exp(-pow(u / 15.0, 6.0)));
|
||||
Q_0 = R_7 * (1.0 - 1.1241 * (R_12 / R_16) * exp(-0.026 * pow(f_n, 1.15656) - R_15));
|
||||
|
||||
/* even-mode frequency-dependent characteristic impedances */
|
||||
Z0e = Z0_e_0 * pow(0.9408 * pow(e_r_eff_single_f, C_e) - 0.9603, Q_0) / pow((0.9408 - d_e) * pow(e_r_eff_single_0, C_e) - 0.9603, Q_0);
|
||||
|
||||
Q_29 = 15.16 / (1.0 + 0.196 * pow(e_r - 1.0, 2.0));
|
||||
tmpf = pow(e_r - 1.0, 3.0);
|
||||
Q_28 = 0.149 * tmpf / (94.5 + 0.038 * tmpf);
|
||||
tmpf = pow(e_r - 1.0, 1.5);
|
||||
Q_27 = 0.4 * pow(g, 0.84) * (1.0 + 2.5 * tmpf / (5.0 + tmpf));
|
||||
tmpf = pow((e_r - 1.0) / 13.0, 12.0);
|
||||
Q_26 = 30.0 - 22.2 * (tmpf / (1.0 + 3.0 * tmpf)) - Q_29;
|
||||
tmpf = (e_r - 1.0) * (e_r - 1.0);
|
||||
Q_25 = (0.3 * f_n * f_n / (10.0 + f_n * f_n)) * (1.0 + 2.333 * tmpf / (5.0 + tmpf));
|
||||
Q_24 = 2.506 * Q_28 * pow(u, 0.894) * pow((1.0 + 1.3 * u) * f_n / 99.25, 4.29) / (3.575 + pow(u, 0.894));
|
||||
Q_23 = 1.0 + 0.005 * f_n * Q_27 / ((1.0 + 0.812 * pow(f_n / 15.0, 1.9)) * (1.0 + 0.025 * u * u));
|
||||
Q_22 = 0.925 * pow(f_n / Q_26, 1.536) / (1.0 + 0.3 * pow(f_n / 30.0, 1.536));
|
||||
|
||||
/* odd-mode frequency-dependent characteristic impedances */
|
||||
Z0o = Z0_single_f + (Z0_o_0 * pow(e_r_eff_o_f / e_r_eff_o_0, Q_22) - Z0_single_f * Q_23) / (1.0 + Q_24 + pow(0.46 * g, 2.2) * Q_25);
|
||||
}
|
||||
|
||||
|
||||
void c_microstrip::calc()
|
||||
{
|
||||
/* compute thickness corrections */
|
||||
delta_u_thickness();
|
||||
/* get effective dielectric constants */
|
||||
er_eff_static();
|
||||
/* impedances for even- and odd-mode */
|
||||
Z0_even_odd();
|
||||
/* calculate freq dependence of er_eff_e, er_eff_o */
|
||||
er_eff_freq();
|
||||
/* FIXME: (not used) Get effective magnetic permeability */
|
||||
mur_eff = calc_mur_eff();
|
||||
/* calculate frequency dependence of Z0e, Z0o */
|
||||
Z0_dispersion();
|
||||
/* calculate losses */
|
||||
attenuation();
|
||||
/* calculate electrical lengths */
|
||||
line_angle();
|
||||
}
|
||||
|
||||
/*
|
||||
* get_microstrip_sub
|
||||
* get and assign microstrip substrate parameters
|
||||
* into microstrip structure
|
||||
*/
|
||||
void c_microstrip::get_c_microstrip_sub()
|
||||
{
|
||||
er = getProperty ("Er");
|
||||
mur = getProperty ("Mur");
|
||||
h = getProperty ("H", UNIT_LENGTH, LENGTH_M);
|
||||
ht = getProperty ("H_t", UNIT_LENGTH, LENGTH_M);
|
||||
t = getProperty ("T", UNIT_LENGTH, LENGTH_M);
|
||||
sigma = getProperty ("Cond");
|
||||
tand = getProperty ("Tand");
|
||||
rough = getProperty ("Rough", UNIT_LENGTH, LENGTH_M);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_c_microstrip_comp
|
||||
* get and assign microstrip component parameters
|
||||
* into microstrip structure
|
||||
*/
|
||||
void c_microstrip::get_c_microstrip_comp()
|
||||
{
|
||||
f = getProperty ("Freq", UNIT_FREQ, FREQ_HZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_c_microstrip_elec
|
||||
* get and assign microstrip electrical parameters
|
||||
* into microstrip structure
|
||||
*/
|
||||
void c_microstrip::get_c_microstrip_elec()
|
||||
{
|
||||
Z0e = getProperty ("Z0e", UNIT_RES, RES_OHM);
|
||||
Z0o = getProperty ("Z0o", UNIT_RES, RES_OHM);
|
||||
ang_l_e = getProperty ("Ang_l", UNIT_ANG, ANG_RAD);
|
||||
ang_l_o = getProperty ("Ang_l", UNIT_ANG, ANG_RAD);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_c_microstrip_phys
|
||||
* get and assign microstrip physical parameters
|
||||
* into microstrip structure
|
||||
*/
|
||||
void c_microstrip::get_c_microstrip_phys()
|
||||
{
|
||||
w = getProperty ("W", UNIT_LENGTH, LENGTH_M);
|
||||
s = getProperty ("S", UNIT_LENGTH, LENGTH_M);
|
||||
l = getProperty ("L", UNIT_LENGTH, LENGTH_M);
|
||||
}
|
||||
|
||||
|
||||
void c_microstrip::show_results()
|
||||
{
|
||||
setResult (0, er_eff_e, "");
|
||||
setResult (1, er_eff_o, "");
|
||||
setResult (2, atten_cond_e, "dB");
|
||||
setResult (3, atten_cond_o, "dB");
|
||||
setResult (4, atten_dielectric_e, "dB");
|
||||
setResult (5, atten_dielectric_o, "dB");
|
||||
|
||||
double val = convertProperty ("T", skindepth, UNIT_LENGTH, LENGTH_M);
|
||||
setResult (6, val, getUnit ("T"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* analysis function
|
||||
*/
|
||||
void c_microstrip::analyze()
|
||||
{
|
||||
/* Get and assign substrate parameters */
|
||||
get_c_microstrip_sub();
|
||||
/* Get and assign component parameters */
|
||||
get_c_microstrip_comp();
|
||||
/* Get and assign physical parameters */
|
||||
get_c_microstrip_phys();
|
||||
|
||||
/* compute coupled microstrip parameters */
|
||||
calc();
|
||||
|
||||
/* update electrical parameters */
|
||||
setProperty ("Z0e", Z0e, UNIT_RES, RES_OHM);
|
||||
setProperty ("Z0o", Z0o, UNIT_RES, RES_OHM);
|
||||
setProperty ("Ang_l", sqrt (ang_l_e * ang_l_o), UNIT_ANG, ANG_RAD);
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
}
|
||||
|
||||
|
||||
void c_microstrip::syn_fun(double *f1, double *f2, double s_h, double w_h, double Z0_e, double Z0_o)
|
||||
{
|
||||
s = s_h * h;
|
||||
w = w_h * h;
|
||||
|
||||
/* compute coupled microstrip parameters */
|
||||
calc();
|
||||
|
||||
*f1 = Z0e - Z0_e;
|
||||
*f2 = Z0o - Z0_o;
|
||||
}
|
||||
|
||||
/*
|
||||
* synthesis function
|
||||
*/
|
||||
int c_microstrip::synthesize()
|
||||
{
|
||||
double Z0_e, Z0_o;
|
||||
double f1, f2, ft1, ft2, j11, j12, j21, j22, d_s_h, d_w_h, err;
|
||||
double eps = 1e-04;
|
||||
double w_h, s_h, le, lo;
|
||||
int iter = 0;
|
||||
const int maxiter = 1000;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_c_microstrip_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_c_microstrip_comp();
|
||||
|
||||
/* Get and assign electrical parameters */
|
||||
get_c_microstrip_elec();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
/* at present it is required only for getting strips length */
|
||||
get_c_microstrip_phys();
|
||||
|
||||
|
||||
/* required value of Z0_e and Z0_o */
|
||||
Z0_e = Z0e;
|
||||
Z0_o = Z0o;
|
||||
|
||||
/* calculate width and use for initial value in Newton's method */
|
||||
synth_width();
|
||||
w_h = w / h;
|
||||
s_h = s / h;
|
||||
f1 = f2 = 0;
|
||||
|
||||
/* rather crude Newton-Rhapson */
|
||||
/* might fail due to overshooting or singular jacobian, should implement a better algorithm... */
|
||||
/* initial errors values */
|
||||
syn_fun(&f1, &f2, s_h, w_h, Z0_e, Z0_o);
|
||||
do {
|
||||
/* compute Jacobian */
|
||||
syn_fun(&ft1, &ft2, s_h + eps, w_h, Z0_e, Z0_o);
|
||||
j11 = (ft1 - f1) / eps;
|
||||
j21 = (ft2 - f2) / eps;
|
||||
syn_fun(&ft1, &ft2, s_h, w_h + eps, Z0_e, Z0_o);
|
||||
j12 = (ft1 - f1) / eps;
|
||||
j22 = (ft2 - f2) / eps;
|
||||
|
||||
/* compute next step; increments of s_h and w_h */
|
||||
d_s_h = (-f1 * j22 + f2 * j12) / (j11 * j22 - j21 * j12);
|
||||
d_w_h = (-f2 * j11 + f1 * j21) / (j11 * j22 - j21 * j12);
|
||||
|
||||
if (!std::isfinite(d_s_h) || !std::isfinite(d_w_h)) {
|
||||
/* a computed step is infinite: we are lost... */
|
||||
iter = maxiter+1; /* just to signal we did not converge */
|
||||
break;
|
||||
}
|
||||
s_h += d_s_h;
|
||||
if (s_h <= 0.0) s_h = eps; /* avoid negative values */
|
||||
w_h += d_w_h;
|
||||
if (w_h <= 0.0) w_h = eps; /* avoid negative values */
|
||||
|
||||
/* compute the error with the new values of s_h and w_h */
|
||||
syn_fun(&f1, &f2, s_h, w_h, Z0_e, Z0_o);
|
||||
err = sqrt(f1 * f1 + f2 * f2);
|
||||
|
||||
iter++;
|
||||
/* converged ? */
|
||||
} while ((err > 1e-04) && (iter < maxiter));
|
||||
|
||||
/* denormalize computed width and spacing */
|
||||
s = s_h * h;
|
||||
w = w_h * h;
|
||||
|
||||
/* calculate physical length */
|
||||
ang_l_e = getProperty ("Ang_l", UNIT_ANG, ANG_RAD);
|
||||
ang_l_o = getProperty ("Ang_l", UNIT_ANG, ANG_RAD);
|
||||
le = C0 / f / sqrt(er_eff_e * mur_eff) * ang_l_e / 2.0 / pi;
|
||||
lo = C0 / f / sqrt(er_eff_o * mur_eff) * ang_l_o / 2.0 / pi;
|
||||
l = sqrt (le * lo);
|
||||
|
||||
/* update physical parameters */
|
||||
setProperty ("W", w, UNIT_LENGTH, LENGTH_M);
|
||||
setProperty ("S", s, UNIT_LENGTH, LENGTH_M);
|
||||
setProperty ("L", l, UNIT_LENGTH, LENGTH_M);
|
||||
|
||||
calc();
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
|
||||
if (iter > maxiter)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
102
qucs-transcalc/c_microstrip.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* c_microstrip.h - coupled microstrip class definition
|
||||
*
|
||||
* Copyright (C) 2002 Claudio Girardi <in3otd@qsl.net>
|
||||
* Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _C_MICROSTRIP_H_
|
||||
#define _C_MICROSTRIP_H_
|
||||
|
||||
class c_microstrip : public transline {
|
||||
public:
|
||||
c_microstrip();
|
||||
~c_microstrip();
|
||||
|
||||
private:
|
||||
double er; /* dielectric constant */
|
||||
double h; /* height of substrate */
|
||||
double ht; /* height to the top of box */
|
||||
double t; /* thickness of top metal */
|
||||
double tand; /* Dielectric Loss Tangent */
|
||||
double rough; /* Roughness of top metal */
|
||||
double w; /* width of lines */
|
||||
double w_t_e; /* even-mode thickness-corrected line width */
|
||||
double w_t_o; /* odd-mode thickness-corrected line width */
|
||||
double l; /* length of lines */
|
||||
double s; /* spacing of lines */
|
||||
double Z0_e_0; /* static even-mode impedance */
|
||||
double Z0_o_0; /* static odd-mode impedance */
|
||||
double Z0e; /* even-mode impedance */
|
||||
double Z0o; /* odd-mode impedance */
|
||||
//double c_e; /* even-mode capacitance */
|
||||
//double c_o; /* odd-mode capacitance */
|
||||
double ang_l_e; /* even-mode electrical length in angle */
|
||||
double ang_l_o; /* odd-mode electrical length in angle */
|
||||
double er_eff_e; /* even-mode effective dielectric constant */
|
||||
double er_eff_o; /* odd-mode effective dielectric constant */
|
||||
double er_eff_e_0; /* static even-mode effective dielectric constant */
|
||||
double er_eff_o_0; /* static odd-mode effective dielectric constant */
|
||||
//double er_eff; /* FIXME: dummy */
|
||||
double mur_eff; /* Effective mag. permeability */
|
||||
//double w_eff; /* Effective width of line */
|
||||
double atten_dielectric_e; /* even-mode dielectric losses (dB) */
|
||||
double atten_cond_e; /* even-mode conductors losses (dB) */
|
||||
double atten_dielectric_o; /* odd-mode dielectric losses (dB) */
|
||||
double atten_cond_o; /* odd-mode conductors losses (dB) */
|
||||
|
||||
public:
|
||||
void analyze ();
|
||||
int synthesize ();
|
||||
|
||||
private:
|
||||
double delta_u_thickness_single(double, double);
|
||||
void delta_u_thickness();
|
||||
void compute_single_line();
|
||||
double filling_factor_even(double, double, double);
|
||||
double filling_factor_odd(double, double, double);
|
||||
double delta_q_cover_even(double);
|
||||
double delta_q_cover_odd(double);
|
||||
void er_eff_static();
|
||||
double delta_Z0_even_cover(double, double, double);
|
||||
double delta_Z0_odd_cover(double, double, double);
|
||||
void Z0_even_odd();
|
||||
double calc_mur_eff();
|
||||
void er_eff_freq();
|
||||
void conductor_losses();
|
||||
void dielectric_losses();
|
||||
void attenuation();
|
||||
void line_angle();
|
||||
void syn_err_fun(double *, double *, double, double, double, double, double);
|
||||
void synth_width();
|
||||
void Z0_dispersion();
|
||||
void calc();
|
||||
void get_c_microstrip_sub();
|
||||
void get_c_microstrip_comp();
|
||||
void get_c_microstrip_elec();
|
||||
void get_c_microstrip_phys();
|
||||
void show_results();
|
||||
void syn_fun(double *, double *, double, double, double, double);
|
||||
|
||||
|
||||
private:
|
||||
microstrip * aux_ms;
|
||||
};
|
||||
|
||||
#endif /* _C_MICROSTRIP_H_ */
|
223
qucs-transcalc/coax.cpp
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* coax.cpp - coaxial class implementation
|
||||
*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2002 Claudio Girardi <claudio.girardi@ieee.org>
|
||||
* Copyright (C) 2005, 2006, 2009, 2011 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* coax.c - Puts up window for microstrip and
|
||||
* performs the associated calculations
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "units.h"
|
||||
#include "transline.h"
|
||||
#include "coax.h"
|
||||
|
||||
coax::coax() : transline()
|
||||
{
|
||||
}
|
||||
|
||||
coax::~coax()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* get_coax_sub() - get and assign coax substrate parameters into coax
|
||||
* structure
|
||||
*/
|
||||
void coax::get_coax_sub ()
|
||||
{
|
||||
er = getProperty ("Er");
|
||||
mur = getProperty ("Mur");
|
||||
tand = getProperty ("Tand");
|
||||
sigma = getProperty ("Sigma");
|
||||
}
|
||||
|
||||
/*
|
||||
* get_coax_comp() - get and assign coax component parameters into
|
||||
* coax structure
|
||||
*/
|
||||
void coax::get_coax_comp ()
|
||||
{
|
||||
f = getProperty ("Freq", UNIT_FREQ, FREQ_HZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_coax_elec() - get and assign coax electrical parameters into
|
||||
* coax structure
|
||||
*/
|
||||
void coax::get_coax_elec ()
|
||||
{
|
||||
Z0 = getProperty ("Z0", UNIT_RES, RES_OHM);
|
||||
ang_l = getProperty ("Ang_l", UNIT_ANG, ANG_RAD);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_coax_phys() - get and assign coax physical parameters into coax
|
||||
* structure
|
||||
*/
|
||||
void coax::get_coax_phys ()
|
||||
{
|
||||
din = getProperty ("din", UNIT_LENGTH, LENGTH_M);
|
||||
dout = getProperty ("dout", UNIT_LENGTH, LENGTH_M);
|
||||
l = getProperty ("L", UNIT_LENGTH, LENGTH_M);
|
||||
}
|
||||
|
||||
double coax::alphad_coax ()
|
||||
{
|
||||
double ad;
|
||||
ad = (pi/C0) * f * sqrt(er) * tand;
|
||||
ad = ad * 20.0 / log(10.0);
|
||||
return ad;
|
||||
}
|
||||
|
||||
double coax::alphac_coax ()
|
||||
{
|
||||
double ac, Rs;
|
||||
Rs = sqrt((pi * f * mur* MU0)/sigma);
|
||||
ac = sqrt(er) * (((1/din) + (1/dout))/log(dout/din)) * (Rs/ZF0);
|
||||
ac = ac * 20.0 / log(10.0);
|
||||
return ac;
|
||||
}
|
||||
|
||||
/*
|
||||
* analyze() - analysis function
|
||||
*/
|
||||
void coax::analyze ()
|
||||
{
|
||||
double lambda_g;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_coax_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_coax_comp();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
get_coax_phys();
|
||||
|
||||
if (din != 0.0){
|
||||
Z0 = (ZF0/2/pi/sqrt(er))*log(dout/din);
|
||||
}
|
||||
|
||||
lambda_g = (C0/(f))/sqrt(er * mur);
|
||||
/* calculate electrical angle */
|
||||
ang_l = (2.0 * pi * l)/lambda_g; /* in radians */
|
||||
|
||||
setProperty ("Z0", Z0, UNIT_RES, RES_OHM);
|
||||
setProperty ("Ang_l", ang_l, UNIT_ANG, ANG_RAD);
|
||||
|
||||
show_results();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* synthesize() - synthesis function
|
||||
*/
|
||||
int coax::synthesize ()
|
||||
{
|
||||
double lambda_g;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_coax_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_coax_comp();
|
||||
|
||||
/* Get and assign electrical parameters */
|
||||
get_coax_elec ();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
get_coax_phys();
|
||||
|
||||
if (isSelected ("din")) {
|
||||
/* solve for din */
|
||||
din = dout / exp(Z0*sqrt(er)/ZF0*2*pi);
|
||||
setProperty ("din", din, UNIT_LENGTH, LENGTH_M);
|
||||
} else if (isSelected ("dout")) {
|
||||
/* solve for dout */
|
||||
dout = din * exp(Z0*sqrt(er)/ZF0*2*pi);
|
||||
setProperty ("dout", dout, UNIT_LENGTH, LENGTH_M);
|
||||
}
|
||||
|
||||
lambda_g = (C0/(f))/sqrt(er * mur);
|
||||
/* calculate physical length */
|
||||
l = (lambda_g * ang_l)/(2.0 * pi); /* in m */
|
||||
setProperty ("L", l, UNIT_LENGTH, LENGTH_M);
|
||||
|
||||
show_results();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* show_results() - show results
|
||||
*/
|
||||
void coax::show_results()
|
||||
{
|
||||
double fc;
|
||||
short m, n;
|
||||
|
||||
atten_dielectric = alphad_coax () * l;
|
||||
atten_cond = alphac_coax () * l;
|
||||
|
||||
setResult (0, atten_cond, "dB");
|
||||
setResult (1, atten_dielectric, "dB");
|
||||
|
||||
n = 1;
|
||||
fc = C0 / sqrt (er * mur) / (pi_over_2 * (dout + din)/(double) n);
|
||||
setResult (2, "none");
|
||||
if (fc <= f) {
|
||||
char text[256], txt[256];
|
||||
strcpy (text, "TE(1,1) ");
|
||||
m = 2;
|
||||
fc = C0 / sqrt (er * mur) / (pi_over_2 * (dout + din)/(double) m);
|
||||
while ((fc <= f) && (m<10)) {
|
||||
sprintf(txt, "TE(n,%d) ",m);
|
||||
strcat(text,txt);
|
||||
m++;
|
||||
fc = C0 / sqrt (er * mur) / (pi_over_2 * (dout + din)/(double) m);
|
||||
}
|
||||
setResult (2, text);
|
||||
}
|
||||
|
||||
setResult (3, "none");
|
||||
m = 1;
|
||||
fc = C0 / sqrt (er * mur) / ((dout - din)/(float) m);
|
||||
if (fc <= f) {
|
||||
char text[256], txt[256];
|
||||
strcpy (text, "");
|
||||
while ((fc <= f) && (m<10)) {
|
||||
sprintf(txt, "TM(n,%d) ",m);
|
||||
strcat(text,txt);
|
||||
m++;
|
||||
fc = C0 / sqrt (er * mur) / ((dout - din)/(double) m);
|
||||
}
|
||||
setResult (3, text);
|
||||
}
|
||||
}
|
61
qucs-transcalc/coax.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* microstrip.h - coaxial class definition
|
||||
*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __COAX_H
|
||||
#define __COAX_H
|
||||
|
||||
class coax : public transline {
|
||||
public:
|
||||
coax();
|
||||
~coax();
|
||||
|
||||
private:
|
||||
double er; /* dielectric constant */
|
||||
double tand; /* Dielectric Loss Tangent */
|
||||
double din; /* Inner diameter of cable */
|
||||
double dout; /* Outer diameter of cable */
|
||||
double l; /* Length of cable */
|
||||
double Z0; /* characteristic impedance */
|
||||
double ang_l; /* Electrical length in angle */
|
||||
double er_eff; /* Effective dielectric constant */
|
||||
double atten_dielectric; /* Loss in dielectric (dB) */
|
||||
double atten_cond; /* Loss in conductors (dB) */
|
||||
double fc; /* Cutoff frequency for higher order modes */
|
||||
|
||||
public:
|
||||
void analyze ();
|
||||
int synthesize ();
|
||||
|
||||
private:
|
||||
void get_coax_sub();
|
||||
void get_coax_comp();
|
||||
void get_coax_phys();
|
||||
void get_coax_elec();
|
||||
void fixdin();
|
||||
void fixdout();
|
||||
double alphad_coax();
|
||||
double alphac_coax();
|
||||
void show_results();
|
||||
};
|
||||
|
||||
#endif /* __COAX_H */
|
302
qucs-transcalc/coplanar.cpp
Normal file
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* coplanar.cpp - coplanar class implementation
|
||||
*
|
||||
* Copyright (C) 2008 Michael Margraf <michael.margraf@alumni.tu-berlin.de>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <float.h>
|
||||
|
||||
|
||||
#include "units.h"
|
||||
#include "transline.h"
|
||||
#include "coplanar.h"
|
||||
|
||||
coplanar::coplanar() : transline()
|
||||
{
|
||||
backMetal = false;
|
||||
}
|
||||
|
||||
groundedCoplanar::groundedCoplanar() : coplanar()
|
||||
{
|
||||
backMetal = true;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void coplanar::getProperties()
|
||||
{
|
||||
f = getProperty ("Freq", UNIT_FREQ, FREQ_HZ);
|
||||
w = getProperty ("W", UNIT_LENGTH, LENGTH_M);
|
||||
s = getProperty ("S", UNIT_LENGTH, LENGTH_M);
|
||||
len = getProperty ("L", UNIT_LENGTH, LENGTH_M);
|
||||
h = getProperty ("H", UNIT_LENGTH, LENGTH_M);
|
||||
t = getProperty ("T", UNIT_LENGTH, LENGTH_M);
|
||||
|
||||
er = getProperty ("Er");
|
||||
tand = getProperty ("Tand");
|
||||
sigma = getProperty ("Cond");
|
||||
Z0 = getProperty ("Z0", UNIT_RES, RES_OHM);
|
||||
ang_l = getProperty ("Ang_l", UNIT_ANG, ANG_RAD);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void coplanar::calc()
|
||||
{
|
||||
skindepth = skin_depth();
|
||||
|
||||
// other local variables (quasi-static constants)
|
||||
double k1, kk1, kpk1, k2, k3, q1, q2, q3 = 0, qz, er0 = 0;
|
||||
double zl_factor;
|
||||
|
||||
// compute the necessary quasi-static approx. (K1, K3, er(0) and Z(0))
|
||||
k1 = w / (w + s + s);
|
||||
kk1 = ellipk (k1);
|
||||
kpk1 = ellipk (sqrt (1 - k1 * k1));
|
||||
q1 = kk1 / kpk1;
|
||||
|
||||
// backside is metal
|
||||
if (backMetal) {
|
||||
k3 = tanh ((pi / 4) * (w / h)) / tanh ((pi / 4) * (w + s + s) / h);
|
||||
q3 = KoverKp(k3);
|
||||
qz = 1 / (q1 + q3);
|
||||
er0 = 1 + q3 * qz * (er - 1);
|
||||
zl_factor = ZF0 / 2 * qz;
|
||||
}
|
||||
// backside is air
|
||||
else {
|
||||
k2 = sinh ((pi / 4) * (w / h)) / sinh ((pi / 4) * (w + s + s) / h);
|
||||
q2 = KoverKp(k2);
|
||||
er0 = 1 + (er - 1) / 2 * q2 / q1;
|
||||
zl_factor = ZF0 / 4 / q1;
|
||||
}
|
||||
|
||||
// adds effect of strip thickness
|
||||
if (t > 0) {
|
||||
double d, ke, qe;
|
||||
d = (t * 1.25 / pi) * (1 + log (4 * pi * w / t));
|
||||
|
||||
// modifies k1 accordingly (k1 = ke)
|
||||
ke = k1 + (1 - k1 * k1) * d / 2 / s;
|
||||
qe = KoverKp(ke);
|
||||
// backside is metal
|
||||
if (backMetal) {
|
||||
qz = 1 / (qe + q3);
|
||||
//er0 = 1 + q3 * qz * (er - 1);
|
||||
zl_factor = ZF0 / 2 * qz;
|
||||
}
|
||||
// backside is air
|
||||
else {
|
||||
zl_factor = ZF0 / 4 / qe;
|
||||
}
|
||||
|
||||
// modifies er0 as well
|
||||
er0 = er0 - (0.7 * (er0 - 1) * t / s) / (q1 + (0.7 * t / s));
|
||||
}
|
||||
|
||||
// pre-compute square roots
|
||||
double sr_er = sqrt (er);
|
||||
double sr_er0 = sqrt (er0);
|
||||
|
||||
// cut-off frequency of the TE0 mode
|
||||
double fte = (C0 / 4) / (h * sqrt (er - 1));
|
||||
|
||||
// dispersion factor G
|
||||
double p = log (w / h);
|
||||
double u = 0.54 - (0.64 - 0.015 * p) * p;
|
||||
double v = 0.43 - (0.86 - 0.54 * p) * p;
|
||||
double G = exp (u * log (w / s) + v);
|
||||
|
||||
// loss constant factors (computed only once for efficency sake)
|
||||
double ac = 0;
|
||||
if (t > 0) {
|
||||
// equations by GHIONE
|
||||
double n = (1 - k1) * 8 * pi / (t * (1 + k1));
|
||||
double a = w / 2;
|
||||
double b = a + s;
|
||||
ac = (pi + log (n * a)) / a + (pi + log (n * b)) / b;
|
||||
}
|
||||
double ac_factor = ac / (4 * ZF0 * kk1 * kpk1 * (1 - k1 * k1));
|
||||
double ad_factor = (er / (er - 1)) * tand * pi / C0;
|
||||
|
||||
|
||||
// ....................................................
|
||||
double sr_er_f = sr_er0;
|
||||
|
||||
// add the dispersive effects to er0
|
||||
sr_er_f += (sr_er - sr_er0) / (1 + G * pow (f / fte, -1.8));
|
||||
|
||||
// for now, the loss are limited to strip losses (no radiation
|
||||
// losses yet) losses in neper/length
|
||||
atten_cond = 20.0 / log(10.0) * len
|
||||
* ac_factor * sr_er0 * sqrt (pi * MU0 * f / sigma);
|
||||
atten_dielectric = 20.0 / log(10.0) * len
|
||||
* ad_factor * f * (sr_er_f * sr_er_f - 1) / sr_er_f;
|
||||
|
||||
ang_l = 2.0 * pi * len * sr_er_f * f / C0; /* in radians */
|
||||
|
||||
er_eff = sr_er_f * sr_er_f;
|
||||
Z0 = zl_factor / sr_er_f;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void coplanar::show_results()
|
||||
{
|
||||
setProperty ("Z0", Z0, UNIT_RES, RES_OHM);
|
||||
setProperty ("Ang_l", ang_l, UNIT_ANG, ANG_RAD);
|
||||
|
||||
setResult (0, er_eff, "");
|
||||
setResult (1, atten_cond, "dB");
|
||||
setResult (2, atten_dielectric, "dB");
|
||||
|
||||
double val = convertProperty ("T", skindepth, UNIT_LENGTH, LENGTH_M);
|
||||
setResult (3, val, getUnit ("T"));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void coplanar::analyze()
|
||||
{
|
||||
getProperties();
|
||||
|
||||
/* compute coplanar parameters */
|
||||
calc();
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
int coplanar::synthesize()
|
||||
{
|
||||
double Z0_dest, Z0_current, Z0_result, increment, slope, error;
|
||||
int iteration;
|
||||
const int maxiter = 100;
|
||||
|
||||
getProperties();
|
||||
|
||||
/* required value of Z0 */
|
||||
Z0_dest = Z0;
|
||||
|
||||
/* Newton's method */
|
||||
iteration = 0;
|
||||
|
||||
/* compute coplanar parameters */
|
||||
calc();
|
||||
Z0_current = Z0;
|
||||
|
||||
error = std::abs(Z0_dest - Z0_current);
|
||||
|
||||
while (error > MAX_ERROR) {
|
||||
iteration++;
|
||||
if(isSelected ("W")) {
|
||||
increment = w / 100.0;
|
||||
w += increment;
|
||||
}
|
||||
else {
|
||||
increment = s / 100.0;
|
||||
s += increment;
|
||||
}
|
||||
/* compute coplanar parameters */
|
||||
calc();
|
||||
Z0_result = Z0;
|
||||
/* f(w(n)) = Z0 - Z0(w(n)) */
|
||||
/* f'(w(n)) = -f'(Z0(w(n))) */
|
||||
/* f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw */
|
||||
/* w(n+1) = w(n) - f(w(n))/f'(w(n)) */
|
||||
slope = (Z0_result - Z0_current) / increment;
|
||||
slope = (Z0_dest - Z0_current) / slope - increment;
|
||||
if(isSelected ("W"))
|
||||
w += slope;
|
||||
else
|
||||
s += slope;
|
||||
if (w <= 0.0)
|
||||
w = increment;
|
||||
if (s <= 0.0)
|
||||
s = increment;
|
||||
/* find new error */
|
||||
/* compute coplanar parameters */
|
||||
calc();
|
||||
Z0_current = Z0;
|
||||
error = std::abs(Z0_dest - Z0_current);
|
||||
if (iteration > maxiter)
|
||||
break;
|
||||
}
|
||||
|
||||
setProperty ("W", w, UNIT_LENGTH, LENGTH_M);
|
||||
setProperty ("S", s, UNIT_LENGTH, LENGTH_M);
|
||||
/* calculate physical length */
|
||||
ang_l = getProperty ("Ang_l", UNIT_ANG, ANG_RAD);
|
||||
len = C0 / f / sqrt(er_eff) * ang_l / 2.0 / pi; /* in m */
|
||||
setProperty ("L", len, UNIT_LENGTH, LENGTH_M);
|
||||
|
||||
/* compute coplanar parameters */
|
||||
calc();
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
|
||||
if (iteration > maxiter)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *****************************************************************
|
||||
********** **********
|
||||
********** mathematical functions **********
|
||||
********** **********
|
||||
***************************************************************** */
|
||||
|
||||
/* The function computes the complete elliptic integral of first kind
|
||||
K(k) using the arithmetic-geometric mean algorithm (AGM) found e.g.
|
||||
in Abramowitz and Stegun (17.6.1).
|
||||
Note that the argument of the function here is the elliptic modulus k
|
||||
and not the parameter m=k^2 . */
|
||||
double coplanar::ellipk (double k) {
|
||||
if ((k < 0.0) || (k >= 1.0))
|
||||
// we use only the range from 0 <= k < 1
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
double a = 1.0;
|
||||
double b = sqrt(1-k*k);
|
||||
double c = k;
|
||||
|
||||
while (c > NR_EPSI) {
|
||||
double tmp = (a + b) / 2.0;
|
||||
c = (a - b) / 2.0;
|
||||
b = sqrt(a * b);
|
||||
a = tmp;
|
||||
}
|
||||
return (pi_over_2 / a);
|
||||
}
|
||||
|
||||
double coplanar::KoverKp(double k) {
|
||||
if ((k < 0.0) || (k >= 1.0))
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
return (ellipk(k) / ellipk(sqrt(1-k*k)));
|
||||
}
|
67
qucs-transcalc/coplanar.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* coplanar.h - microstrip class definition
|
||||
*
|
||||
* Copyright (C) 2008 Michael Margraf <michael.margraf@alumni.tu-berlin.de>
|
||||
* Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __COPLANAR_H
|
||||
#define __COPLANAR_H
|
||||
|
||||
class coplanar : public transline {
|
||||
public:
|
||||
coplanar();
|
||||
|
||||
private:
|
||||
double er; /* dielectric constant */
|
||||
double h; /* height of substrate */
|
||||
double t; /* thickness of top metal */
|
||||
double tand; /* Dielectric Loss Tangent */
|
||||
double w; /* width of line */
|
||||
double s; /* width of gap between line and ground */
|
||||
double len; /* length of line */
|
||||
double Z0; /* characteristic impedance */
|
||||
double er_eff; /* effective dielectric constant */
|
||||
double ang_l; /* Electrical length in angle */
|
||||
double atten_dielectric; /* Loss in dielectric (dB) */
|
||||
double atten_cond; /* Loss in conductors (dB) */
|
||||
|
||||
public:
|
||||
void analyze();
|
||||
int synthesize();
|
||||
|
||||
protected:
|
||||
bool backMetal;
|
||||
|
||||
private:
|
||||
void calc();
|
||||
void show_results();
|
||||
void getProperties();
|
||||
|
||||
double ellipk(double);
|
||||
double KoverKp(double);
|
||||
};
|
||||
|
||||
|
||||
class groundedCoplanar : public coplanar {
|
||||
public:
|
||||
groundedCoplanar();
|
||||
};
|
||||
|
||||
#endif /* __COPLANAR_H */
|
11
qucs-transcalc/examples/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
SET(EXAMPLES
|
||||
hp.trc
|
||||
ustrip50fr4.trc
|
||||
ustrip_jansen.trc
|
||||
cstrip_kj_1.trc
|
||||
cstrip_kj_2.trc)
|
||||
|
||||
# installation of transmission lines
|
||||
INSTALL( FILES ${EXAMPLES} DESTINATION share/qucs-s/tline )
|
||||
|
35
qucs-transcalc/examples/Makefile.am
Normal file
@ -0,0 +1,35 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
#
|
||||
# qucs-transcalc/examples/Makefile.am
|
||||
#
|
||||
# Automake input file.
|
||||
#
|
||||
# Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
#
|
||||
# This 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This software 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 package; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
EXAMPLES = hp.trc ustrip50fr4.trc ustrip_jansen.trc cstrip_kj_1.trc \
|
||||
cstrip_kj_2.trc
|
||||
|
||||
EXTRA_DIST = $(EXAMPLES)
|
||||
|
||||
# installation of transmission lines
|
||||
linedatadir = ${prefix}/share/qucs/tline
|
||||
linedata_DATA = $(EXTRA_DIST)
|
||||
|
||||
CLEANFILES = *~
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
21
qucs-transcalc/examples/cstrip_kj_1.trc
Normal file
@ -0,0 +1,21 @@
|
||||
# QucsTranscalc 0.0.8 cstrip_kj_1.trc
|
||||
# Generated on Thu Dec 1 2005 at 20:28:35.
|
||||
# It is not suggested to edit the file, use QucsTranscalc instead.
|
||||
|
||||
<CoupledMicrostrip>
|
||||
Er 2.35 NA
|
||||
Mur 1 NA
|
||||
H 0.79 mm
|
||||
H_t 1e+20 mil
|
||||
T 0 mil
|
||||
Cond 4.1e+07 NA
|
||||
Tand 0 NA
|
||||
Rough 0 mil
|
||||
Freq 30 GHz
|
||||
W 1.7775 mm
|
||||
S 0.079 mm
|
||||
L 1 m
|
||||
Z0e 79.2774 Ohm
|
||||
Z0o 37.9688 Ohm
|
||||
Ang_l 50847.5 Deg
|
||||
</CoupledMicrostrip>
|
21
qucs-transcalc/examples/cstrip_kj_2.trc
Normal file
@ -0,0 +1,21 @@
|
||||
# QucsTranscalc 0.0.8 cstrip_kj_2.trc
|
||||
# Generated on Thu Dec 1 2005 at 20:30:57.
|
||||
# It is not suggested to edit the file, use QucsTranscalc instead.
|
||||
|
||||
<CoupledMicrostrip>
|
||||
Er 9.9 NA
|
||||
Mur 1 NA
|
||||
H 0.64 mm
|
||||
H_t 1e+20 mil
|
||||
T 5 um
|
||||
Cond 4.1e+07 NA
|
||||
Tand 0.0005 NA
|
||||
Rough 0.25 um
|
||||
Freq 3 GHz
|
||||
W 0.6 mm
|
||||
S 0.5 mm
|
||||
L 1 m
|
||||
Z0e 58.8883 Ohm
|
||||
Z0o 41.3621 Ohm
|
||||
Ang_l 9214.28 Deg
|
||||
</CoupledMicrostrip>
|
21
qucs-transcalc/examples/hp.trc
Normal file
@ -0,0 +1,21 @@
|
||||
# QucsTranscalc 0.0.8 hp.trc
|
||||
# Generated on Thu Dec 1 2005 at 20:02:07.
|
||||
# It is not suggested to edit the file, use QucsTranscalc instead.
|
||||
|
||||
<CoupledMicrostrip>
|
||||
Er 9.9 NA
|
||||
Mur 1 NA
|
||||
H 645 um
|
||||
H_t 3.9e+34 mil
|
||||
T 5 um
|
||||
Cond 4.1e+07 NA
|
||||
Tand 0 NA
|
||||
Rough 0 mil
|
||||
Freq 2 GHz
|
||||
W 609 um
|
||||
S 64.5 mil
|
||||
L 14.5521 mm
|
||||
Z0e 52.4548 Ohm
|
||||
Z0o 47.9635 Ohm
|
||||
Ang_l 90.0165 Deg
|
||||
</CoupledMicrostrip>
|
19
qucs-transcalc/examples/ustrip50fr4.trc
Normal file
@ -0,0 +1,19 @@
|
||||
# QucsTranscalc 0.0.8 ustrip50fr4.trc
|
||||
# Generated on Thu Dec 1 2005 at 19:53:13.
|
||||
# It is not suggested to edit the file, use QucsTranscalc instead.
|
||||
|
||||
<Microstrip>
|
||||
Er 4.3 NA
|
||||
Mur 1 NA
|
||||
H 210 um
|
||||
H_t 1e+20 mil
|
||||
T 30 um
|
||||
Cond 4.1e+07 NA
|
||||
Tand 0.025 NA
|
||||
Rough 0 mil
|
||||
Freq 1 GHz
|
||||
W 380 um
|
||||
L 1 mm
|
||||
Z0 50.7326 Ohm
|
||||
Ang_l 2.10486 Deg
|
||||
</Microstrip>
|
19
qucs-transcalc/examples/ustrip_jansen.trc
Normal file
@ -0,0 +1,19 @@
|
||||
# QucsTranscalc 0.0.8 ustrip_jansen.trc
|
||||
# Generated on Thu Dec 1 2005 at 19:56:38.
|
||||
# It is not suggested to edit the file, use QucsTranscalc instead.
|
||||
|
||||
<Microstrip>
|
||||
Er 9.9 NA
|
||||
Mur 1 NA
|
||||
H 0.64 mm
|
||||
H_t 1e+20 mil
|
||||
T 5 um
|
||||
Cond 4.1e+07 NA
|
||||
Tand 0.0005 NA
|
||||
Rough 0.25 um
|
||||
Freq 3 GHz
|
||||
W 0.6 mm
|
||||
L 1 m
|
||||
Z0 50.4142 Ohm
|
||||
Ang_l 9267.81 Deg
|
||||
</Microstrip>
|
72
qucs-transcalc/helpdialog.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/***************************************************************************
|
||||
helpdialog.cpp
|
||||
------------------
|
||||
begin : Sun Apr 03 2005
|
||||
copyright : (C) 2005 by Stefan Jahn
|
||||
email : stefan@lkcc.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QTextEdit>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "helpdialog.h"
|
||||
|
||||
|
||||
HelpDialog::HelpDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
setWindowTitle("QucsTranscalc "+tr("Help"));
|
||||
|
||||
// -------- set help text into dialog ------------
|
||||
QString s(tr("QucsTranscalc is an analysis and synthesis tool for "
|
||||
"calculating the electrical and physical properties of "
|
||||
"different kinds of RF and microwave transmission lines.")+
|
||||
"\n\n"+
|
||||
tr("For each type of transmission line, using dialog boxes, you can "
|
||||
"enter values for the various parameters, and either calculate its "
|
||||
"electrical properties, or use the given electrical requirements to "
|
||||
"synthesize physical parameters of the required transmission line."));
|
||||
|
||||
|
||||
// -------- create dialog widgets ------------
|
||||
resize(350, 230);
|
||||
|
||||
vLayout = new QVBoxLayout(this);
|
||||
vLayout->setMargin(3);
|
||||
vLayout->setSpacing(3);
|
||||
|
||||
Text = new QTextEdit(s, this);
|
||||
//Text->setTextFormat(Qt::PlainText);
|
||||
Text->setReadOnly(true);
|
||||
Text->setMinimumSize(300,200);
|
||||
vLayout->addWidget(Text);
|
||||
|
||||
QPushButton *ButtonClose = new QPushButton(tr("Dismiss"), this);
|
||||
vLayout->addWidget(ButtonClose);
|
||||
connect(ButtonClose, SIGNAL(clicked()), SLOT(slotClose()));
|
||||
ButtonClose->setFocus();
|
||||
}
|
||||
|
||||
HelpDialog::~HelpDialog()
|
||||
{
|
||||
delete vLayout;
|
||||
}
|
||||
|
||||
void HelpDialog::slotClose()
|
||||
{
|
||||
accept();
|
||||
}
|
45
qucs-transcalc/helpdialog.h
Normal file
@ -0,0 +1,45 @@
|
||||
/***************************************************************************
|
||||
helpdialog.h
|
||||
-------------------
|
||||
begin : Sun Apr 03 2005
|
||||
copyright : (C) 2005 by Stefan Jahn
|
||||
email : stefan@lkcc.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef HELPDIALOG_H
|
||||
#define HELPDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class QTextEdit;
|
||||
class QVBoxLayout;
|
||||
|
||||
/**
|
||||
*@author Stefan Jahn
|
||||
*/
|
||||
|
||||
class HelpDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
HelpDialog(QWidget *parent = 0);
|
||||
~HelpDialog();
|
||||
|
||||
private slots:
|
||||
void slotClose();
|
||||
|
||||
private:
|
||||
QVBoxLayout *vLayout;
|
||||
QTextEdit *Text;
|
||||
};
|
||||
|
||||
#endif
|
166
qucs-transcalc/main.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
/***************************************************************************
|
||||
main.cpp - description
|
||||
-------------------
|
||||
begin : Sun Feb 27 2005
|
||||
copyright : (C) 2005 by Stefan Jahn
|
||||
email : stefan@lkcc.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QString>
|
||||
#include <QTextCodec>
|
||||
#include <QTranslator>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
#include <QFont>
|
||||
#include <QSettings>
|
||||
|
||||
#include "qucstrans.h"
|
||||
|
||||
tQucsSettings QucsSettings;
|
||||
|
||||
extern struct TransUnit TransUnits[];
|
||||
|
||||
|
||||
// #########################################################################
|
||||
// Loads the settings file and stores the settings.
|
||||
bool loadSettings()
|
||||
{
|
||||
QSettings settings("qucs","qucs");
|
||||
settings.beginGroup("QucsTranscalc");
|
||||
if(settings.contains("x"))QucsSettings.x=settings.value("x").toInt();
|
||||
if(settings.contains("y"))QucsSettings.y=settings.value("y").toInt();
|
||||
if(settings.contains("dx"))QucsSettings.dx=settings.value("dx").toInt();
|
||||
if(settings.contains("dy"))QucsSettings.dy=settings.value("dy").toInt();
|
||||
if(settings.contains("Mode"))QucsSettings.Mode=settings.value("Mode").toString();
|
||||
if(settings.contains("FreqUnit"))QucsSettings.freq_unit=settings.value("FreqUnit").toInt();
|
||||
if(settings.contains("LengthUnit"))QucsSettings.length_unit=settings.value("LengthUnit").toInt();
|
||||
if(settings.contains("ResUnit"))QucsSettings.res_unit=settings.value("ResUnit").toInt();
|
||||
if(settings.contains("AngUnit"))QucsSettings.ang_unit=settings.value("AngUnit").toInt();
|
||||
|
||||
settings.endGroup();
|
||||
if(settings.contains("font"))QucsSettings.font.fromString(settings.value("font").toString());
|
||||
if(settings.contains("Language"))QucsSettings.Language=settings.value("Language").toString();
|
||||
if(settings.contains("QucsHomeDir"))
|
||||
if(settings.value("QucsHomeDir").toString() != "")
|
||||
QucsSettings.QucsHomeDir.setPath(settings.value("QucsHomeDir").toString());
|
||||
|
||||
QucsSettings.QucsWorkDir = QucsSettings.QucsHomeDir;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// #########################################################################
|
||||
// Saves the settings in the settings file.
|
||||
bool saveApplSettings(QucsTranscalc *qucs)
|
||||
{
|
||||
QSettings settings ("qucs","qucs");
|
||||
settings.beginGroup("QucsTranscalc");
|
||||
settings.setValue("x", qucs->x());
|
||||
settings.setValue("y", qucs->y());
|
||||
settings.setValue("dx", qucs->width());
|
||||
settings.setValue("dy", qucs->height());
|
||||
settings.setValue("Mode", qucs->getMode());
|
||||
settings.setValue("FreqUnit", TransUnits[0].units[QucsSettings.freq_unit]);
|
||||
settings.setValue("LengthUnit", TransUnits[1].units[QucsSettings.length_unit]);
|
||||
settings.setValue("ResUnit", TransUnits[2].units[QucsSettings.res_unit]);
|
||||
settings.setValue("AngUnit", TransUnits[3].units[QucsSettings.ang_unit]);
|
||||
settings.endGroup();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// #########################################################################
|
||||
// ########## ##########
|
||||
// ########## Program Start ##########
|
||||
// ########## ##########
|
||||
// #########################################################################
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
|
||||
// apply default settings
|
||||
QucsSettings.x = 100;
|
||||
QucsSettings.y = 50;
|
||||
QucsSettings.dx = 540;
|
||||
QucsSettings.dy = 400;
|
||||
QucsSettings.font = QFont("Helvetica", 12);
|
||||
QucsSettings.length_unit = 0;
|
||||
QucsSettings.res_unit = 0;
|
||||
QucsSettings.ang_unit = 0;
|
||||
QucsSettings.freq_unit = 0;
|
||||
QucsSettings.QucsHomeDir.setPath(QDir::homePath() + "/.qucs");
|
||||
|
||||
// is application relocated?
|
||||
char * var = getenv ("QUCSDIR");
|
||||
QDir QucsDir;
|
||||
if (var != NULL) {
|
||||
QucsDir = QDir (var);
|
||||
QString QucsDirStr = QucsDir.canonicalPath ();
|
||||
QucsSettings.LangDir =
|
||||
QDir::toNativeSeparators(QucsDirStr + "/share/qucs/lang/");
|
||||
} else {
|
||||
QString QucsApplicationPath = QCoreApplication::applicationDirPath();
|
||||
#ifdef __APPLE__
|
||||
QucsDir = QDir(QucsApplicationPath.section("/bin",0,0));
|
||||
#else
|
||||
QucsDir = QDir(QucsApplicationPath);
|
||||
QucsDir.cdUp();
|
||||
#endif
|
||||
QucsSettings.LangDir = QucsDir.canonicalPath() + "/share/qucs/lang/";
|
||||
}
|
||||
loadSettings();
|
||||
|
||||
a.setFont(QucsSettings.font);
|
||||
|
||||
QTranslator tor( 0 );
|
||||
QString lang = QucsSettings.Language;
|
||||
if(lang.isEmpty())
|
||||
lang = QString(QLocale::system().name());
|
||||
tor.load( QString("qucs_") + lang, QucsSettings.LangDir);
|
||||
a.installTranslator( &tor );
|
||||
|
||||
QucsTranscalc *qucs = new QucsTranscalc();
|
||||
qucs->raise();
|
||||
qucs->resize(QucsSettings.dx, QucsSettings.dy); // size and position ...
|
||||
qucs->move(QucsSettings.x, QucsSettings.y); // ... before "show" !!!
|
||||
qucs->show();
|
||||
|
||||
// load file with all the GUI input values from the Qucs Home
|
||||
qucs->loadFile(QucsSettings.QucsHomeDir.filePath("transrc"));
|
||||
qucs->setMode(QucsSettings.Mode);
|
||||
|
||||
// optional file argument
|
||||
if (argc > 1) {
|
||||
int _mode = 0;
|
||||
QString File = argv[1];
|
||||
qucs->loadFile(File,&_mode);
|
||||
}
|
||||
|
||||
int result = a.exec();
|
||||
saveApplSettings(qucs);
|
||||
// save file with all the GUI input values in the Qucs Home
|
||||
qucs->saveModes(QucsSettings.QucsHomeDir.filePath("transrc"));
|
||||
delete qucs;
|
||||
return result;
|
||||
}
|
578
qucs-transcalc/microstrip.cpp
Normal file
@ -0,0 +1,578 @@
|
||||
/*
|
||||
* microstrip.cpp - microstrip class implementation
|
||||
*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2002 Claudio Girardi <claudio.girardi@ieee.org>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* microstrip.c - Puts up window for microstrip and
|
||||
* performs the associated calculations
|
||||
* Based on the original microstrip.c by Gopal Narayanan
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "units.h"
|
||||
#include "transline.h"
|
||||
#include "microstrip.h"
|
||||
|
||||
microstrip::microstrip() : transline()
|
||||
{
|
||||
}
|
||||
|
||||
microstrip::~microstrip()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Z0_homogeneous() - compute the impedance for a stripline in a
|
||||
* homogeneous medium, without cover effects
|
||||
*/
|
||||
double microstrip::Z0_homogeneous(double u)
|
||||
{
|
||||
double f, Z0;
|
||||
f = 6.0 + (2.0 * pi - 6.0) * exp(-pow(30.666 / u, 0.7528));
|
||||
Z0 = (ZF0 / (2.0 * pi)) * log(f / u + sqrt(1.0 + 4.0 / (u * u)));
|
||||
return Z0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* delta_Z0_cover() - compute the cover effect on impedance for a
|
||||
* stripline in a homogeneous medium
|
||||
*/
|
||||
double microstrip::delta_Z0_cover(double u, double h2h)
|
||||
{
|
||||
double P, Q;
|
||||
double h2hp1;
|
||||
h2hp1 = 1.0 + h2h;
|
||||
P = 270.0 * (1.0 - tanh(1.192 + 0.706 * sqrt(h2hp1) - 1.389 / h2hp1));
|
||||
Q = 1.0109 - atanh((0.012 * u + 0.177 * u * u - 0.027 * u * u * u) / (h2hp1 * h2hp1));
|
||||
return (P * Q);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* filling_factor() - compute the filling factor for a microstrip
|
||||
* without cover and zero conductor thickness
|
||||
*/
|
||||
double microstrip::filling_factor(double u, double e_r)
|
||||
{
|
||||
double a, b, q_inf;
|
||||
double u2, u3, u4;
|
||||
u2 = u * u;
|
||||
u3 = u2 * u;
|
||||
u4 = u3 * u;
|
||||
a = 1.0 + log((u4 + u2 / 2704) / (u4 + 0.432)) / 49.0 + log(1.0 + u3 / 5929.741) / 18.7;
|
||||
b = 0.564 * pow((e_r - 0.9) / (e_r + 3.0), 0.053);
|
||||
q_inf = pow(1.0 + 10.0 / u, -a * b);
|
||||
return q_inf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* delta_q_cover() - compute the cover effect on filling factor
|
||||
*/
|
||||
double microstrip::delta_q_cover(double h2h)
|
||||
{
|
||||
double q_c;
|
||||
q_c = tanh(1.043 + 0.121 * h2h - 1.164 / h2h);
|
||||
return q_c;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* delta_q_thickness() - compute the thickness effect on filling factor
|
||||
*/
|
||||
double microstrip::delta_q_thickness(double u, double t_h)
|
||||
{
|
||||
double q_t;
|
||||
q_t = (2.0 * log(2.0) / pi) * (t_h / sqrt(u));
|
||||
return q_t;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* e_r_effective() - compute effective dielectric constant from
|
||||
* material e_r and filling factor
|
||||
*/
|
||||
double microstrip::e_r_effective(double e_r, double q)
|
||||
{
|
||||
double e_r_eff;
|
||||
e_r_eff = 0.5 * (e_r + 1.0) + 0.5 * q * (e_r - 1.0);
|
||||
return e_r_eff;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* delta_u_thickness - compute the thickness effect on normalized width
|
||||
*/
|
||||
double microstrip::delta_u_thickness(double u, double t_h, double e_r)
|
||||
{
|
||||
double delta_u;
|
||||
if (t_h > 0.0) {
|
||||
/* correction for thickness for a homogeneous microstrip */
|
||||
delta_u = (t_h / pi) * log(1.0 + (4.0 * e) * pow(tanh(sqrt(6.517 * u)), 2.0) / t_h);
|
||||
/* correction for strip on a substrate with relative permettivity e_r */
|
||||
delta_u = 0.5 * delta_u * (1.0 + 1.0 / cosh(sqrt(e_r - 1.0)));
|
||||
} else {
|
||||
delta_u = 0.0;
|
||||
}
|
||||
return delta_u;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* microstrip_Z0() - compute microstrip static impedance
|
||||
*/
|
||||
void microstrip::microstrip_Z0()
|
||||
{
|
||||
double e_r, h2, h2h, u, t_h;
|
||||
double Z0_h_r, Z0;
|
||||
double delta_u_1, delta_u_r, q_inf, q_c, q_t, e_r_eff, e_r_eff_t, q;
|
||||
|
||||
e_r = er;
|
||||
h2 = ht;
|
||||
h2h = h2 / h;
|
||||
u = w / h;
|
||||
t_h = t / h;
|
||||
|
||||
/* compute normalized width correction for e_r = 1.0 */
|
||||
delta_u_1 = delta_u_thickness(u, t_h, 1.0);
|
||||
/* compute homogeneous stripline impedance */
|
||||
Z0_h_1 = Z0_homogeneous(u + delta_u_1);
|
||||
/* compute normalized width corection */
|
||||
delta_u_r = delta_u_thickness(u, t_h, e_r);
|
||||
u += delta_u_r;
|
||||
/* compute homogeneous stripline impedance */
|
||||
Z0_h_r = Z0_homogeneous(u);
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
q_inf = filling_factor(u, e_r);
|
||||
/* cover effect */
|
||||
q_c = delta_q_cover(h2h);
|
||||
/* thickness effect */
|
||||
q_t = delta_q_thickness(u, t_h);
|
||||
/* resultant filling factor */
|
||||
q = (q_inf - q_t) * q_c;
|
||||
|
||||
/* e_r corrected for thickness and non homogeneous material */
|
||||
e_r_eff_t = e_r_effective(e_r, q);
|
||||
|
||||
/* effective dielectric constant */
|
||||
e_r_eff = e_r_eff_t * pow(Z0_h_1 / Z0_h_r, 2.0);
|
||||
|
||||
/* characteristic impedance, corrected for thickness, cover */
|
||||
/* and non homogeneous material */
|
||||
Z0 = Z0_h_r / sqrt(e_r_eff_t);
|
||||
|
||||
w_eff = u * h;
|
||||
er_eff_0 = e_r_eff;
|
||||
Z0_0 = Z0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* e_r_dispersion() - computes the dispersion correction factor for
|
||||
* the effective permeability
|
||||
*/
|
||||
double microstrip::e_r_dispersion(double u, double e_r, double f_n)
|
||||
{
|
||||
double P_1, P_2, P_3, P_4, P;
|
||||
|
||||
P_1 = 0.27488 + u * (0.6315 + 0.525 / pow(1.0 + 0.0157 * f_n, 20.0)) - 0.065683 * exp(-8.7513 * u);
|
||||
P_2 = 0.33622 * (1.0 - exp(-0.03442 * e_r));
|
||||
P_3 = 0.0363 * exp(-4.6 * u) * (1.0 - exp(-pow(f_n / 38.7, 4.97)));
|
||||
P_4 = 1.0 + 2.751 * (1.0 - exp(-pow(e_r / 15.916, 8.0)));
|
||||
|
||||
P = P_1 * P_2 * pow((P_3 * P_4 + 0.1844) * f_n, 1.5763);
|
||||
|
||||
return P;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Z0_dispersion() - computes the dispersion correction factor for the
|
||||
* characteristic impedance
|
||||
*/
|
||||
double microstrip::Z0_dispersion(double u, double e_r, double e_r_eff_0, double e_r_eff_f, double f_n)
|
||||
{
|
||||
double R_1, R_2, R_3, R_4, R_5, R_6, R_7, R_8, R_9, R_10, R_11, R_12, R_13, R_14, R_15, R_16, R_17, D, tmpf;
|
||||
|
||||
R_1 = 0.03891 * pow(e_r, 1.4);
|
||||
R_2 = 0.267 * pow(u, 7.0);
|
||||
R_3 = 4.766 * exp(-3.228 * pow(u, 0.641));
|
||||
R_4 = 0.016 + pow(0.0514 * e_r, 4.524);
|
||||
R_5 = pow(f_n / 28.843, 12.0);
|
||||
R_6 = 22.2 * pow(u, 1.92);
|
||||
R_7 = 1.206 - 0.3144 * exp(-R_1) * (1.0 - exp(-R_2));
|
||||
R_8 = 1.0 + 1.275 * (1.0 - exp(-0.004625 * R_3 * pow(e_r, 1.674) * pow(f_n / 18.365, 2.745)));
|
||||
tmpf = pow(e_r - 1.0, 6.0);
|
||||
R_9 = 5.086 * R_4 * (R_5 / (0.3838 + 0.386 * R_4)) * (exp(-R_6) / (1.0 + 1.2992 * R_5)) * (tmpf / (1.0 + 10.0 * tmpf));
|
||||
R_10 = 0.00044 * pow(e_r, 2.136) + 0.0184;
|
||||
tmpf = pow(f_n / 19.47, 6.0);
|
||||
R_11 = tmpf / (1.0 + 0.0962 * tmpf);
|
||||
R_12 = 1.0 / (1.0 + 0.00245 * u * u);
|
||||
R_13 = 0.9408 * pow(e_r_eff_f, R_8) - 0.9603;
|
||||
R_14 = (0.9408 - R_9) * pow(e_r_eff_0, R_8) - 0.9603;
|
||||
R_15 = 0.707 * R_10 * pow(f_n / 12.3, 1.097);
|
||||
R_16 = 1.0 + 0.0503 * e_r * e_r * R_11 * (1.0 - exp(-pow(u / 15.0, 6.0)));
|
||||
R_17 = R_7 * (1.0 - 1.1241 * (R_12 / R_16) * exp(-0.026 * pow(f_n, 1.15656) - R_15));
|
||||
|
||||
D = pow(R_13 / R_14, R_17);
|
||||
|
||||
return D;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dispersion() - compute frequency dependent parameters of
|
||||
* microstrip
|
||||
*/
|
||||
void microstrip::dispersion()
|
||||
{
|
||||
double e_r, e_r_eff_0;
|
||||
double u, f_n, P, e_r_eff_f, D, Z0_f;
|
||||
|
||||
e_r = er;
|
||||
e_r_eff_0 = er_eff_0;
|
||||
u = w / h;
|
||||
|
||||
/* normalized frequency [GHz * mm] */
|
||||
f_n = f * h / 1e06;
|
||||
|
||||
P = e_r_dispersion(u, e_r, f_n);
|
||||
/* effective dielectric constant corrected for dispersion */
|
||||
e_r_eff_f = e_r - (e_r - e_r_eff_0) / (1.0 + P);
|
||||
|
||||
D = Z0_dispersion(u, e_r, e_r_eff_0, e_r_eff_f, f_n);
|
||||
Z0_f = Z0_0 * D;
|
||||
|
||||
er_eff = e_r_eff_f;
|
||||
Z0 = Z0_f;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* conductor_losses() - compute microstrip conductor losses per unit
|
||||
* length
|
||||
*/
|
||||
double microstrip::conductor_losses()
|
||||
{
|
||||
double e_r_eff_0, delta;
|
||||
double K, R_s, Q_c, alpha_c;
|
||||
|
||||
e_r_eff_0 = er_eff_0;
|
||||
delta = skindepth;
|
||||
|
||||
if (f > 0.0) {
|
||||
/* current distribution factor */
|
||||
K = exp(-1.2 * pow(Z0_h_1 / ZF0, 0.7));
|
||||
/* skin resistance */
|
||||
R_s = 1.0 / (sigma * delta);
|
||||
|
||||
/* correction for surface roughness */
|
||||
R_s *= 1.0 + ((2.0 / pi) * atan(1.40 * pow((rough / delta), 2.0)));
|
||||
/* strip inductive quality factor */
|
||||
Q_c = (pi * Z0_h_1 * w * f) / (R_s * C0 * K);
|
||||
alpha_c = (20.0 * pi / log(10.0)) * f * sqrt(e_r_eff_0) / (C0 * Q_c);
|
||||
} else {
|
||||
alpha_c = 0.0;
|
||||
}
|
||||
|
||||
return alpha_c;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dielectric_losses() - compute microstrip dielectric losses per unit
|
||||
* length
|
||||
*/
|
||||
double microstrip::dielectric_losses()
|
||||
{
|
||||
double e_r, e_r_eff_0;
|
||||
double alpha_d;
|
||||
|
||||
e_r = er;
|
||||
e_r_eff_0 = er_eff_0;
|
||||
|
||||
alpha_d = (20.0 * pi / log(10.0)) * (f / C0) * (e_r / sqrt(e_r_eff_0)) * ((e_r_eff_0 - 1.0) / (e_r - 1.0)) * tand;
|
||||
|
||||
return alpha_d;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* attenuation() - compute attenuation of microstrip
|
||||
*/
|
||||
void microstrip::attenuation()
|
||||
{
|
||||
skindepth = skin_depth();
|
||||
|
||||
atten_cond = conductor_losses() * l;
|
||||
atten_dielectric = dielectric_losses() * l;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mur_eff_ms() - returns effective magnetic permeability
|
||||
*/
|
||||
void microstrip::mur_eff_ms()
|
||||
{
|
||||
double mureff;
|
||||
|
||||
mureff = (2.0 * mur) / ((1.0 + mur) + ((1.0 - mur) * pow((1.0 + (10.0 * h / w)), -0.5)));
|
||||
|
||||
mur_eff = mureff;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* synth_width - calculate width given Z0 and e_r
|
||||
*/
|
||||
double microstrip::synth_width()
|
||||
{
|
||||
double e_r, a, b;
|
||||
double w_h, w;
|
||||
|
||||
|
||||
e_r = er;
|
||||
|
||||
|
||||
a = ((Z0 / ZF0 / 2 / pi) * sqrt((e_r + 1) / 2.)) + ((e_r - 1) / (e_r + 1) * (0.23 + (0.11 / e_r)));
|
||||
b = ZF0 / 2 * pi / (Z0 * sqrt(e_r));
|
||||
|
||||
if (a > 1.52) {
|
||||
w_h = 8 * exp(a) / (exp(2. * a) - 2);
|
||||
} else {
|
||||
w_h = (2. / pi) * (b - 1. - log((2 * b) - 1.) + ((e_r - 1) / (2 * e_r)) * (log(b - 1.) + 0.39 - 0.61 / e_r));
|
||||
}
|
||||
|
||||
if (h > 0.0) {
|
||||
w = w_h * h;
|
||||
return w;
|
||||
} else {
|
||||
w = 0;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* line_angle() - calculate microstrip length in radians
|
||||
*/
|
||||
void microstrip::line_angle()
|
||||
{
|
||||
double e_r_eff;
|
||||
double v, lambda_g;
|
||||
|
||||
e_r_eff = er_eff;
|
||||
|
||||
/* velocity */
|
||||
v = C0 / sqrt(e_r_eff * mur_eff);
|
||||
/* wavelength */
|
||||
lambda_g = v / f;
|
||||
/* electrical angles */
|
||||
ang_l = 2.0 * pi * l / lambda_g; /* in radians */
|
||||
}
|
||||
|
||||
|
||||
void microstrip::calc()
|
||||
{
|
||||
/* effective permeability */
|
||||
mur_eff_ms();
|
||||
/* static impedance */
|
||||
microstrip_Z0();
|
||||
/* calculate freq dependence of er and Z0 */
|
||||
dispersion();
|
||||
/* calculate electrical lengths */
|
||||
line_angle();
|
||||
/* calculate losses */
|
||||
attenuation();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_microstrip_sub () - get and assign microstrip substrate
|
||||
* parameters into microstrip structure
|
||||
*/
|
||||
void microstrip::get_microstrip_sub()
|
||||
{
|
||||
er = getProperty ("Er");
|
||||
mur = getProperty ("Mur");
|
||||
h = getProperty ("H", UNIT_LENGTH, LENGTH_M);
|
||||
ht = getProperty ("H_t", UNIT_LENGTH, LENGTH_M);
|
||||
t = getProperty ("T", UNIT_LENGTH, LENGTH_M);
|
||||
sigma = getProperty ("Cond");
|
||||
tand = getProperty ("Tand");
|
||||
rough = getProperty ("Rough", UNIT_LENGTH, LENGTH_M);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_microstrip_comp() - get and assign microstrip component
|
||||
* parameters into microstrip structure
|
||||
*/
|
||||
void microstrip::get_microstrip_comp()
|
||||
{
|
||||
f = getProperty ("Freq", UNIT_FREQ, FREQ_HZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_microstrip_elec() - get and assign microstrip electrical
|
||||
* parameters into microstrip structure
|
||||
*/
|
||||
void microstrip::get_microstrip_elec()
|
||||
{
|
||||
Z0 = getProperty ("Z0", UNIT_RES, RES_OHM);
|
||||
ang_l = getProperty ("Ang_l", UNIT_ANG, ANG_RAD);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_microstrip_phys() - get and assign microstrip physical
|
||||
* parameters into microstrip structure
|
||||
*/
|
||||
void microstrip::get_microstrip_phys()
|
||||
{
|
||||
w = getProperty ("W", UNIT_LENGTH, LENGTH_M);
|
||||
l = getProperty ("L", UNIT_LENGTH, LENGTH_M);
|
||||
}
|
||||
|
||||
|
||||
void microstrip::show_results()
|
||||
{
|
||||
setProperty ("Z0", Z0, UNIT_RES, RES_OHM);
|
||||
setProperty ("Ang_l", ang_l, UNIT_ANG, ANG_RAD);
|
||||
|
||||
setResult (0, er_eff, "");
|
||||
setResult (1, atten_cond, "dB");
|
||||
setResult (2, atten_dielectric, "dB");
|
||||
|
||||
double val = convertProperty ("T", skindepth, UNIT_LENGTH, LENGTH_M);
|
||||
setResult (3, val, getUnit ("T"));
|
||||
}
|
||||
|
||||
/*
|
||||
* analysis function
|
||||
*/
|
||||
void microstrip::analyze()
|
||||
{
|
||||
/* Get and assign substrate parameters */
|
||||
get_microstrip_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_microstrip_comp();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
get_microstrip_phys();
|
||||
|
||||
/* compute microstrip parameters */
|
||||
calc();
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* synthesis function
|
||||
*/
|
||||
int microstrip::synthesize()
|
||||
{
|
||||
double Z0_dest, Z0_current, Z0_result, increment, slope, error;
|
||||
int iteration;
|
||||
const int maxiter = 100;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_microstrip_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_microstrip_comp();
|
||||
|
||||
/* Get and assign electrical parameters */
|
||||
get_microstrip_elec();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
/* at present it is required only for getting strips length */
|
||||
get_microstrip_phys();
|
||||
|
||||
|
||||
/* calculate width and use for initial value in Newton's method */
|
||||
w = synth_width();
|
||||
|
||||
/* required value of Z0 */
|
||||
Z0_dest = Z0;
|
||||
|
||||
/* Newton's method */
|
||||
iteration = 0;
|
||||
|
||||
/* compute microstrip parameters */
|
||||
calc();
|
||||
Z0_current = Z0;
|
||||
|
||||
error = std::abs(Z0_dest - Z0_current);
|
||||
|
||||
while (error > MAX_ERROR) {
|
||||
iteration++;
|
||||
increment = (w / 100.0);
|
||||
w += increment;
|
||||
/* compute microstrip parameters */
|
||||
calc();
|
||||
Z0_result = Z0;
|
||||
/* f(w(n)) = Z0 - Z0(w(n)) */
|
||||
/* f'(w(n)) = -f'(Z0(w(n))) */
|
||||
/* f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw */
|
||||
/* w(n+1) = w(n) - f(w(n))/f'(w(n)) */
|
||||
slope = (Z0_result - Z0_current) / increment;
|
||||
/* printf("%g\n",slope); */
|
||||
w += (Z0_dest - Z0_current) / slope - increment;
|
||||
/* printf("ms->w = %g\n", ms->w); */
|
||||
/* find new error */
|
||||
/* compute microstrip parameters */
|
||||
calc();
|
||||
Z0_current = Z0;
|
||||
error = std::abs(Z0_dest - Z0_current);
|
||||
/* printf("Iteration = %d\n",iteration);
|
||||
printf("w = %g\t Z0 = %g\n",ms->w, Z0_current); */
|
||||
if (iteration > maxiter)
|
||||
break;
|
||||
}
|
||||
|
||||
setProperty ("W", w, UNIT_LENGTH, LENGTH_M);
|
||||
/* calculate physical length */
|
||||
ang_l = getProperty ("Ang_l", UNIT_ANG, ANG_RAD);
|
||||
l = C0 / f / sqrt(er_eff * mur_eff) * ang_l / 2.0 / pi; /* in m */
|
||||
setProperty ("L", l, UNIT_LENGTH, LENGTH_M);
|
||||
|
||||
/* compute microstrip parameters */
|
||||
calc();
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
|
||||
if (iteration > maxiter)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
93
qucs-transcalc/microstrip.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* microstrip.h - microstrip class definition
|
||||
*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MICROSTRIP_H
|
||||
#define __MICROSTRIP_H
|
||||
|
||||
class microstrip : public transline {
|
||||
public:
|
||||
microstrip();
|
||||
~microstrip();
|
||||
|
||||
friend class c_microstrip;
|
||||
|
||||
private:
|
||||
double er; /* dielectric constant */
|
||||
double h; /* height of substrate */
|
||||
double ht; /* height to the top of box */
|
||||
double t; /* thickness of top metal */
|
||||
double tand; /* Dielectric Loss Tangent */
|
||||
double rough; /* Roughness of top metal */
|
||||
double w; /* width of line */
|
||||
double l; /* length of line */
|
||||
double Z0_0; /* static characteristic impedance */
|
||||
double Z0; /* characteristic impedance */
|
||||
double ang_l; /* Electrical length in angle */
|
||||
double er_eff_0; /* Static effective dielectric constant */
|
||||
double er_eff; /* Effective dielectric constant */
|
||||
double mur_eff; /* Effective mag. permeability */
|
||||
double w_eff; /* Effective width of line */
|
||||
double atten_dielectric; /* Loss in dielectric (dB) */
|
||||
double atten_cond; /* Loss in conductors (dB) */
|
||||
|
||||
/* private params */
|
||||
double Z0_h_1; /* homogeneous stripline impedance */
|
||||
|
||||
public:
|
||||
void analyze();
|
||||
int synthesize();
|
||||
|
||||
private:
|
||||
double er_eff_freq();
|
||||
double alpha_c();
|
||||
double alpha_c_roughness();
|
||||
double alpha_dielectric();
|
||||
double char_impedance_ht();
|
||||
double synth_width();
|
||||
double ereff_dispersion();
|
||||
double Z0_dispersion();
|
||||
double Z0_homogeneous(double);
|
||||
double delta_Z0_cover(double, double);
|
||||
double filling_factor(double, double);
|
||||
double delta_q_cover(double);
|
||||
double delta_q_thickness(double, double);
|
||||
double e_r_effective(double, double);
|
||||
double delta_u_thickness(double, double, double);
|
||||
double e_r_dispersion(double, double, double);
|
||||
double Z0_dispersion(double, double, double, double, double);
|
||||
double conductor_losses();
|
||||
double dielectric_losses();
|
||||
void microstrip_Z0();
|
||||
void dispersion();
|
||||
void attenuation();
|
||||
void mur_eff_ms();
|
||||
void line_angle();
|
||||
void calc();
|
||||
void get_microstrip_sub();
|
||||
void get_microstrip_comp();
|
||||
void get_microstrip_elec();
|
||||
void get_microstrip_phys();
|
||||
void show_results();
|
||||
};
|
||||
|
||||
#endif /* __MICROSTRIP_H */
|
109
qucs-transcalc/optionsdialog.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/***************************************************************************
|
||||
optionsdialog.cpp
|
||||
--------------------
|
||||
begin : Sun Apr 03 2005
|
||||
copyright : (C) 2005 by Stefan Jahn
|
||||
email : stefan@lkcc.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <QGroupBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
|
||||
#include "optionsdialog.h"
|
||||
#include "qucstrans.h"
|
||||
|
||||
extern struct TransUnit TransUnits[];
|
||||
|
||||
OptionsDialog::OptionsDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
setWindowTitle("QucsTranscalc "+tr("Options"));
|
||||
|
||||
// -------- create dialog widgets ------------
|
||||
vLayout = new QVBoxLayout(this);
|
||||
vLayout->setMargin(3);
|
||||
vLayout->setSpacing(3);
|
||||
|
||||
QGroupBox * unitsGroup = new QGroupBox(tr("Units"));
|
||||
QVBoxLayout * l = new QVBoxLayout();
|
||||
l->setSpacing(3);
|
||||
QLabel * lfr = new QLabel(tr("Frequency"));
|
||||
lfr->setAlignment (Qt::AlignRight);
|
||||
l->addWidget(lfr);
|
||||
QLabel * lle = new QLabel(tr("Length"));
|
||||
lle->setAlignment (Qt::AlignRight);
|
||||
l->addWidget(lle);
|
||||
QLabel * lre = new QLabel(tr("Resistance"));
|
||||
lre->setAlignment (Qt::AlignRight);
|
||||
l->addWidget(lre);
|
||||
QLabel * lan = new QLabel(tr("Angle"));
|
||||
lan->setAlignment (Qt::AlignRight);
|
||||
l->addWidget(lan);
|
||||
QVBoxLayout * r = new QVBoxLayout();
|
||||
r->setSpacing(3);
|
||||
for (int j = 0; j < 4; j++) {
|
||||
units[j] = new QComboBox(); //?r);
|
||||
r->addWidget(units[j]);
|
||||
for (int i = 0; TransUnits[j].units[i] != NULL; i++)
|
||||
units[j]->addItem(TransUnits[j].units[i]);
|
||||
}
|
||||
units[0]->setCurrentIndex(QucsSettings.freq_unit);
|
||||
units[1]->setCurrentIndex(QucsSettings.length_unit);
|
||||
units[2]->setCurrentIndex(QucsSettings.res_unit);
|
||||
units[3]->setCurrentIndex(QucsSettings.ang_unit);
|
||||
|
||||
QHBoxLayout * h1 = new QHBoxLayout();
|
||||
h1->addLayout(l);
|
||||
h1->addLayout(r);
|
||||
unitsGroup->setLayout(h1);
|
||||
|
||||
vLayout->addWidget(unitsGroup);
|
||||
|
||||
QHBoxLayout * h2 = new QHBoxLayout();
|
||||
|
||||
QPushButton *ButtonSave = new QPushButton(tr("Save as Default"));
|
||||
connect(ButtonSave, SIGNAL(clicked()), SLOT(slotSave()));
|
||||
|
||||
QPushButton *ButtonClose = new QPushButton(tr("Dismiss"));
|
||||
connect(ButtonClose, SIGNAL(clicked()), SLOT(slotClose()));
|
||||
ButtonClose->setFocus();
|
||||
|
||||
h2->addWidget(ButtonSave);
|
||||
h2->addWidget(ButtonClose);
|
||||
vLayout->addLayout(h2);
|
||||
}
|
||||
|
||||
OptionsDialog::~OptionsDialog()
|
||||
{
|
||||
delete vLayout;
|
||||
}
|
||||
|
||||
void OptionsDialog::slotClose()
|
||||
{
|
||||
accept();
|
||||
}
|
||||
|
||||
void OptionsDialog::slotSave()
|
||||
{
|
||||
QucsSettings.freq_unit = units[0]->currentIndex();
|
||||
QucsSettings.length_unit = units[1]->currentIndex();
|
||||
QucsSettings.res_unit = units[2]->currentIndex();
|
||||
QucsSettings.ang_unit = units[3]->currentIndex();
|
||||
accept();
|
||||
}
|
46
qucs-transcalc/optionsdialog.h
Normal file
@ -0,0 +1,46 @@
|
||||
/***************************************************************************
|
||||
optionsdialog.h
|
||||
-------------------
|
||||
begin : Sun Apr 03 2005
|
||||
copyright : (C) 2005 by Stefan Jahn
|
||||
email : stefan@lkcc.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef OPTIONSDIALOG_H
|
||||
#define OPTIONSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class QVBoxLayout;
|
||||
class QComboBox;
|
||||
|
||||
/**
|
||||
*@author Stefan Jahn
|
||||
*/
|
||||
|
||||
class OptionsDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OptionsDialog(QWidget *parent = 0);
|
||||
~OptionsDialog();
|
||||
|
||||
private slots:
|
||||
void slotClose();
|
||||
void slotSave();
|
||||
|
||||
private:
|
||||
QVBoxLayout *vLayout;
|
||||
QComboBox *units[4];
|
||||
};
|
||||
|
||||
#endif
|
52
qucs-transcalc/qucstrans.1.cmake.in
Normal file
@ -0,0 +1,52 @@
|
||||
.TH QucsTranscalc "1" "April 2005" "Debian/GNU Linux" "User Commands"
|
||||
.SH NAME
|
||||
QucsTranscalc \- A transmission line calculator.
|
||||
.SH SYNOPSIS
|
||||
.B qucstrans
|
||||
[\fIOPTION\fR] ...
|
||||
.SH DESCRIPTION
|
||||
|
||||
\fBQucs\fR is an integrated circuit simulator which means you are able
|
||||
to setup a circuit with a graphical user interface (GUI) and simulate
|
||||
the large-signal, small-signal and noise behaviour of the circuit.
|
||||
After that simulation has finished you can view the simulation results
|
||||
on a presentation page or window.
|
||||
|
||||
The software aims to support all kinds of circuit simulation types,
|
||||
e.g. DC, AC, S-parameter, harmonic balance analysis, noise analysis,
|
||||
etc.
|
||||
|
||||
\fBQucsTranscalc\fR is the transmission line tool used by Qucs. The
|
||||
application was somewhat inspired by \fBtranscalc\fR by Claudio
|
||||
Girardi and Gopal Narayanan. It is based on transcalc's latest CVS
|
||||
version with some minor fixes incorporated. The GUI has been ported
|
||||
from the GIMP toolkit (GTK) to Qt.
|
||||
|
||||
It is an analysis and synthesis tool for calculating the electrical
|
||||
and physical properties of different kinds of RF and microwave
|
||||
transmission lines.
|
||||
|
||||
For each type of transmission line, using dialog boxes, the user can
|
||||
enter values for the various parameters, and either calculate its
|
||||
electrical properties, or use the given electrical requirements to
|
||||
synthesize physical parameters of the required transmission line.
|
||||
|
||||
Available transmission lines are: Microstrip, Rectangular Waveguide,
|
||||
Coaxial Line, Coplanar and Coupled Microstrips.
|
||||
|
||||
.SH AVAILABILITY
|
||||
The latest version of Qucs can always be obtained from
|
||||
\fB${QUCS_URL}\fR
|
||||
.SH "REPORTING BUGS"
|
||||
Known bugs are documented within the BUGS file. Report bugs to
|
||||
\fB${QUCS_BUGREPORT}\fR
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
.PP
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.SH AUTHORS
|
||||
Written by Gopal Narayanan <gopal@astro.umass.edu>, Claudio Girardi
|
||||
<claudio.girardi@ieee.org>, Michael Margraf
|
||||
<michael.margraf@alumni.tu-berlin.de> and Stefan Jahn
|
||||
<stefan@lkcc.org>.
|
52
qucs-transcalc/qucstrans.1.in
Normal file
@ -0,0 +1,52 @@
|
||||
.TH QucsTranscalc "1" "April 2005" "Debian/GNU Linux" "User Commands"
|
||||
.SH NAME
|
||||
QucsTranscalc \- A transmission line calculator.
|
||||
.SH SYNOPSIS
|
||||
.B qucstrans
|
||||
[\fIOPTION\fR] ...
|
||||
.SH DESCRIPTION
|
||||
|
||||
\fBQucs\fR is an integrated circuit simulator which means you are able
|
||||
to setup a circuit with a graphical user interface (GUI) and simulate
|
||||
the large-signal, small-signal and noise behaviour of the circuit.
|
||||
After that simulation has finished you can view the simulation results
|
||||
on a presentation page or window.
|
||||
|
||||
The software aims to support all kinds of circuit simulation types,
|
||||
e.g. DC, AC, S-parameter, harmonic balance analysis, noise analysis,
|
||||
etc.
|
||||
|
||||
\fBQucsTranscalc\fR is the transmission line tool used by Qucs. The
|
||||
application was somewhat inspired by \fBtranscalc\fR by Claudio
|
||||
Girardi and Gopal Narayanan. It is based on transcalc's latest CVS
|
||||
version with some minor fixes incorporated. The GUI has been ported
|
||||
from the GIMP toolkit (GTK) to Qt.
|
||||
|
||||
It is an analysis and synthesis tool for calculating the electrical
|
||||
and physical properties of different kinds of RF and microwave
|
||||
transmission lines.
|
||||
|
||||
For each type of transmission line, using dialog boxes, the user can
|
||||
enter values for the various parameters, and either calculate its
|
||||
electrical properties, or use the given electrical requirements to
|
||||
synthesize physical parameters of the required transmission line.
|
||||
|
||||
Available transmission lines are: Microstrip, Rectangular Waveguide,
|
||||
Coaxial Line, Coplanar and Coupled Microstrips.
|
||||
|
||||
.SH AVAILABILITY
|
||||
The latest version of Qucs can always be obtained from
|
||||
\fB@PACKAGE_URL@\fR
|
||||
.SH "REPORTING BUGS"
|
||||
Known bugs are documented within the BUGS file. Report bugs to
|
||||
\fB@PACKAGE_BUGREPORT@\fR
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
.PP
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.SH AUTHORS
|
||||
Written by Gopal Narayanan <gopal@astro.umass.edu>, Claudio Girardi
|
||||
<claudio.girardi@ieee.org>, Michael Margraf
|
||||
<michael.margraf@alumni.tu-berlin.de> and Stefan Jahn
|
||||
<stefan@lkcc.org>.
|
1510
qucs-transcalc/qucstrans.cpp
Normal file
200
qucs-transcalc/qucstrans.h
Normal file
@ -0,0 +1,200 @@
|
||||
/***************************************************************************
|
||||
qucstrans.h - description
|
||||
-------------------
|
||||
begin : Sun Feb 27 2005
|
||||
copyright : (C) 2005 by Stefan Jahn
|
||||
email : stefan@lkcc.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QUCSTRANS_H
|
||||
#define QUCSTRANS_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QFont>
|
||||
#include <QString>
|
||||
#include <QGridLayout>
|
||||
#include <QTextStream>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QCloseEvent>
|
||||
#include <QMainWindow>
|
||||
#include <QDir>
|
||||
class QComboBox;
|
||||
class QLineEdit;
|
||||
class QLabel;
|
||||
class QGroupBox;
|
||||
class QVBoxLayout;
|
||||
class QRadioButton;
|
||||
class QGridLayout;
|
||||
class QStatusBar;
|
||||
class QTextStream;
|
||||
class QButtonGroup;
|
||||
class QStackedWidget;
|
||||
|
||||
class transline;
|
||||
|
||||
// Current limit defintions.
|
||||
#define MAX_TRANS_BOXES 4
|
||||
#define MAX_TRANS_TYPES 7 //Number of transmission lines
|
||||
#define MAX_TRANS_RESULTS 7
|
||||
|
||||
// Types of transmission line properties.
|
||||
#define TRANS_SUBSTRATE 0
|
||||
#define TRANS_COMPONENT 1
|
||||
#define TRANS_PHYSICAL 2
|
||||
#define TRANS_ELECTRICAL 3
|
||||
|
||||
#define TRANS_FREQS { "GHz", "Hz", "kHz", "MHz", NULL }
|
||||
#define TRANS_OHMS { "Ohm", "kOhm", NULL }
|
||||
#define TRANS_ANGLES { "Deg", "Rad", NULL }
|
||||
#define TRANS_LENGTHS { "mil", "cm", "mm", "m", "um", "in", "ft", NULL }
|
||||
#define TRANS_NONES { "NA", NULL }
|
||||
|
||||
// Application settings.
|
||||
struct tQucsSettings {
|
||||
int x, y, dx, dy; // position and size of main window
|
||||
QFont font; // font
|
||||
QString LangDir; // translation directory
|
||||
QString Language;
|
||||
int length_unit; // default length unit
|
||||
int freq_unit; // default frequency unit
|
||||
int res_unit; // default resistance unit
|
||||
int ang_unit; // default angle unit
|
||||
QString Mode; // current mode
|
||||
QDir QucsWorkDir;
|
||||
QDir QucsHomeDir;
|
||||
};
|
||||
|
||||
extern tQucsSettings QucsSettings;
|
||||
|
||||
// Transmission line value.
|
||||
struct TransValue {
|
||||
const char * name; // label
|
||||
double value; // value
|
||||
QString * tip; // tool tip description
|
||||
const char * units[8]; // unit choise
|
||||
int unit; // unit index
|
||||
QLabel * label; // Qt label widget
|
||||
QLineEdit * lineedit; // Qt value widget
|
||||
QComboBox * combobox; // Qt unit widget
|
||||
QRadioButton * radio; // Qt fixed widget
|
||||
};
|
||||
|
||||
// Array of transmission line values.
|
||||
struct TransArray {
|
||||
struct TransValue item[12];
|
||||
};
|
||||
|
||||
// Extraneous calculation results.
|
||||
struct TransResult {
|
||||
QString * name; // textual description
|
||||
QLabel * label; // Qt name widget
|
||||
QLabel * value; // Qt value widget
|
||||
};
|
||||
|
||||
// Transmission line types.
|
||||
enum TransMode {
|
||||
ModeMicrostrip = 0,
|
||||
ModeCoplanar = 1,
|
||||
ModeGroundedCoplanar = 2,
|
||||
ModeRectangular = 3,
|
||||
ModeCoaxial = 4,
|
||||
ModeCoupledMicrostrip = 5,
|
||||
ModeStripline = 6,
|
||||
ModeNone
|
||||
};
|
||||
|
||||
// A transmission line type structure.
|
||||
struct TransType {
|
||||
int type; // type of transmission line (see TransMode)
|
||||
const char * description; // description
|
||||
const char * bitmap; // bitmap file name
|
||||
transline * line; // transmission line instance
|
||||
struct TransArray array[MAX_TRANS_BOXES];
|
||||
int results; // number of extraneous results
|
||||
struct TransResult result[MAX_TRANS_RESULTS];
|
||||
int radio[4];
|
||||
};
|
||||
|
||||
struct TransUnit {
|
||||
const char * description;
|
||||
const char * units[8];
|
||||
};
|
||||
|
||||
/**
|
||||
*@author Stefan Jahn
|
||||
*/
|
||||
|
||||
class QucsTranscalc : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
QucsTranscalc();
|
||||
~QucsTranscalc();
|
||||
|
||||
void setProperty (QString, double);
|
||||
double getProperty (QString);
|
||||
void setUnit (QString, const char *);
|
||||
char * getUnit (QString);
|
||||
void setResult (int, const char *);
|
||||
bool isSelected (QString);
|
||||
|
||||
void saveMode (QTextStream&);
|
||||
bool saveModes (QString);
|
||||
bool loadFile (QString, int * _mode = 0);
|
||||
QString getMode (void);
|
||||
void setMode (QString);
|
||||
static int translateUnit(const char *, int);
|
||||
|
||||
private slots:
|
||||
void slotAbout();
|
||||
void slotQuit();
|
||||
void slotSelectType(int);
|
||||
void slotSynthesize();
|
||||
void slotAnalyze();
|
||||
void slotValueChanged();
|
||||
void slotFileLoad();
|
||||
void slotFileSave();
|
||||
void slotHelpIntro();
|
||||
void slotOptions();
|
||||
void slotRadioChecked(int);
|
||||
void slotCopyToClipBoard();
|
||||
|
||||
private:
|
||||
void updateSelection ();
|
||||
void createPropItem (QGridLayout *, TransValue *, int, QButtonGroup *);
|
||||
void createResultItem (QGridLayout *, TransResult *);
|
||||
void updateResultItem (TransResult *);
|
||||
void createResultItems (QGroupBox *);
|
||||
void updateResultItems ();
|
||||
void createPropItems (QGroupBox *, int);
|
||||
int getTypeIndex ();
|
||||
void updatePropItem (TransValue *);
|
||||
void setMode (int);
|
||||
struct TransValue * findProperty (QString);
|
||||
void setupTranslations ();
|
||||
bool saveFile (QString);
|
||||
void updateMode (void);
|
||||
void storeValues (void);
|
||||
void updatePixmap (int);
|
||||
|
||||
private:
|
||||
void closeEvent (QCloseEvent*);
|
||||
|
||||
private:
|
||||
QStatusBar * statBar;
|
||||
QLabel * pix;
|
||||
QComboBox * tranType;
|
||||
QGroupBox * calculated;
|
||||
int mode;
|
||||
};
|
||||
|
||||
#endif /* QUCSTRANS_H */
|
12
qucs-transcalc/qucstrans_.qrc
Normal file
@ -0,0 +1,12 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>bitmaps/c_microstrip.png</file>
|
||||
<file>bitmaps/coax.png</file>
|
||||
<file>bitmaps/cpw_back.png</file>
|
||||
<file>bitmaps/cpw.png</file>
|
||||
<file>bitmaps/microstrip.png</file>
|
||||
<file>bitmaps/stripline.png</file>
|
||||
<file>bitmaps/rectwaveguide.png</file>
|
||||
<file>bitmaps/big.qucs.xpm</file>
|
||||
</qresource>
|
||||
</RCC>
|
352
qucs-transcalc/rectwaveguide.cpp
Normal file
@ -0,0 +1,352 @@
|
||||
/*
|
||||
* rectwaveguide.cpp - rectangular waveguide class implementation
|
||||
*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "units.h"
|
||||
#include "transline.h"
|
||||
#include "rectwaveguide.h"
|
||||
|
||||
rectwaveguide::rectwaveguide() : transline()
|
||||
{
|
||||
}
|
||||
|
||||
rectwaveguide::~rectwaveguide()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* returns k
|
||||
*/
|
||||
double rectwaveguide::kval ()
|
||||
{
|
||||
double kval;
|
||||
kval = 2.0 * pi * f * sqrt (mur * er) / C0;
|
||||
return kval;
|
||||
}
|
||||
|
||||
/*
|
||||
* given mode numbers m and n
|
||||
* returns cutoff kc value
|
||||
*/
|
||||
double rectwaveguide::kc (int m, int n)
|
||||
{
|
||||
double kcval;
|
||||
kcval = sqrt (pow ((m * pi / a), 2.0) + pow ((n * pi / b), 2.0));
|
||||
return kcval;
|
||||
}
|
||||
|
||||
/*
|
||||
* given mode numbers m and n
|
||||
* returns cutoff fc value
|
||||
*/
|
||||
double rectwaveguide::fc (int m, int n)
|
||||
{
|
||||
double fcval;
|
||||
fcval = kc (m, n) * C0 / (2.0 * pi * sqrt (mur * er));
|
||||
return fcval;
|
||||
}
|
||||
|
||||
/*
|
||||
* alphac - returns attenuation due to conductor losses for all propagating
|
||||
* modes in the waveguide
|
||||
*/
|
||||
double rectwaveguide::alphac ()
|
||||
{
|
||||
double Rs, f_c;
|
||||
double ac;
|
||||
short m, n, mmax, nmax;
|
||||
|
||||
Rs = sqrt ((pi * f * mur * MU0) / sigma);
|
||||
ac = 0.0;
|
||||
mmax = (int) floor (f / fc (1,0));
|
||||
nmax = mmax;
|
||||
|
||||
/* below from Ramo, Whinnery & Van Duzer */
|
||||
|
||||
/* TE(m,n) modes */
|
||||
for (n = 0; n<= nmax; n++){
|
||||
for (m = 1; m <= mmax; m++){
|
||||
f_c = fc(m, n);
|
||||
if (f > f_c) {
|
||||
switch (n) {
|
||||
case 0:
|
||||
ac += (Rs/(b * ZF0 * sqrt(1.0 - pow((f_c/f),2.0)))) *
|
||||
(1.0 + ((2 * b/a)*pow((f_c/f),2.0)));
|
||||
break;
|
||||
default:
|
||||
ac += ((2. * Rs)/(b * ZF0 * sqrt(1.0 - pow((f_c/f),2.0)))) *
|
||||
(((1. + (b/a))*pow((f_c/f),2.0)) +
|
||||
((1. - pow((f_c/f),2.0)) * (((b/a)*(((b/a)*pow(m,2.)) + pow(n,2.)))/
|
||||
(pow((b*m/a),2.0) + pow(n,2.0)))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TM(m,n) modes */
|
||||
for (n = 1; n<= nmax; n++) {
|
||||
for (m = 1; m<= mmax; m++) {
|
||||
f_c = fc(m, n);
|
||||
if (f > f_c) {
|
||||
ac += ((2. * Rs)/(b * ZF0 * sqrt(1.0 - pow((f_c/f),2.0)))) *
|
||||
(((pow(m,2.0)*pow((b/a),3.0)) + pow(n,2.))/
|
||||
((pow((m*b/a),2.)) + pow(n,2.0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ac = ac * 20.0 * log10 (exp (1.0)); /* convert from Np/m to db/m */
|
||||
return ac;
|
||||
}
|
||||
|
||||
/*
|
||||
* alphac_cutoff - returns attenuation for a cutoff wg
|
||||
*/
|
||||
double rectwaveguide::alphac_cutoff ()
|
||||
{
|
||||
double acc;
|
||||
acc = sqrt (pow (kc(1,0), 2.0) - pow (kval (), 2.0));
|
||||
acc = 20 * log10 (exp (1.0)) * acc;
|
||||
return acc;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns attenuation due to dielectric losses
|
||||
*/
|
||||
double rectwaveguide::alphad()
|
||||
{
|
||||
double k, beta;
|
||||
double ad;
|
||||
|
||||
k = kval ();
|
||||
beta = sqrt (pow (k, 2.0) - pow (kc (1,0), 2.0));
|
||||
|
||||
ad = (pow (k, 2.0) * tand) / (2.0 * beta);
|
||||
ad = ad * 20.0 * log10 (exp (1.0)); /* convert from Np/m to db/m */
|
||||
return ad;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_rectwaveguide_sub
|
||||
* get and assign rectwaveguide substrate parameters
|
||||
* into rectwaveguide structure
|
||||
*/
|
||||
void rectwaveguide::get_rectwaveguide_sub ()
|
||||
{
|
||||
er = getProperty ("Er");
|
||||
mur = getProperty ("Mur");
|
||||
sigma = getProperty ("Cond");
|
||||
tand = getProperty ("Tand");
|
||||
tanm = getProperty ("TanM");
|
||||
}
|
||||
|
||||
/*
|
||||
* get_rectwaveguide_comp
|
||||
* get and assign rectwaveguide component parameters
|
||||
* into rectwaveguide structure
|
||||
*/
|
||||
void rectwaveguide::get_rectwaveguide_comp ()
|
||||
{
|
||||
f = getProperty ("Freq", UNIT_FREQ, FREQ_HZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_rectwaveguide_elec
|
||||
* get and assign rectwaveguide electrical parameters
|
||||
* into rectwaveguide structure
|
||||
*/
|
||||
void rectwaveguide::get_rectwaveguide_elec ()
|
||||
{
|
||||
Z0 = getProperty ("Z0", UNIT_RES, RES_OHM);
|
||||
ang_l = getProperty ("Ang_l", UNIT_ANG, ANG_RAD);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_rectwaveguide_phys
|
||||
* get and assign rectwaveguide physical parameters
|
||||
* into rectwaveguide structure
|
||||
*/
|
||||
void rectwaveguide::get_rectwaveguide_phys ()
|
||||
{
|
||||
a = getProperty ("a", UNIT_LENGTH, LENGTH_M);
|
||||
b = getProperty ("b", UNIT_LENGTH, LENGTH_M);
|
||||
l = getProperty ("L", UNIT_LENGTH, LENGTH_M);
|
||||
}
|
||||
|
||||
/*
|
||||
* analyze - analysis function
|
||||
*/
|
||||
void rectwaveguide::analyze ()
|
||||
{
|
||||
double lambda_g;
|
||||
double k;
|
||||
double beta;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_rectwaveguide_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_rectwaveguide_comp();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
get_rectwaveguide_phys();
|
||||
|
||||
k = kval ();
|
||||
|
||||
if (kc (1,0) <= k) {
|
||||
/* propagating modes */
|
||||
beta = sqrt (pow (k, 2.0) - pow (kc (1,0), 2.0));
|
||||
lambda_g = 2.0 * pi / beta;
|
||||
/* Z0 = (k * ZF0) / beta; */
|
||||
Z0 = k * ZF0 * sqrt(mur/er) / beta;
|
||||
|
||||
/* calculate electrical angle */
|
||||
lambda_g = 2.0 * pi / beta;
|
||||
ang_l = 2.0 * pi * l / lambda_g; /* in radians */
|
||||
atten_cond = alphac () * l;
|
||||
atten_dielectric = alphad () * l;
|
||||
er_eff = (1.0 - pow ((fc (1,0) / f), 2.0));
|
||||
} else {
|
||||
/* evanascent modes */
|
||||
Z0 = 0;
|
||||
ang_l = 0;
|
||||
er_eff = 0;
|
||||
atten_dielectric = 0.0;
|
||||
atten_cond = alphac_cutoff () * l;
|
||||
}
|
||||
|
||||
setProperty ("Z0", Z0, UNIT_RES, RES_OHM);
|
||||
setProperty ("Ang_l", ang_l, UNIT_ANG, ANG_RAD);
|
||||
|
||||
show_results ();
|
||||
}
|
||||
|
||||
/*
|
||||
* synthesize - synthesis function
|
||||
*/
|
||||
int rectwaveguide::synthesize ()
|
||||
{
|
||||
double lambda_g, k, beta;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_rectwaveguide_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_rectwaveguide_comp();
|
||||
|
||||
/* Get and assign electrical parameters */
|
||||
get_rectwaveguide_elec();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
get_rectwaveguide_phys();
|
||||
|
||||
|
||||
if (isSelected ("b")) {
|
||||
/* solve for b */
|
||||
b = Z0 * a * sqrt(1.0 - pow((fc(1,0)/f),2.0))/
|
||||
(2. * ZF0);
|
||||
setProperty ("b", b, UNIT_LENGTH, LENGTH_M);
|
||||
} else if (isSelected ("a")) {
|
||||
/* solve for a */
|
||||
a = sqrt(pow((2.0 * ZF0 * b/Z0), 2.0) +
|
||||
pow((C0/(2.0 * f)),2.0));
|
||||
setProperty ("a", a, UNIT_LENGTH, LENGTH_M);
|
||||
}
|
||||
|
||||
k = kval ();
|
||||
beta = sqrt(pow(k,2.) - pow(kc(1,0),2.0));
|
||||
lambda_g = (2. * pi)/beta;
|
||||
l = (ang_l * lambda_g)/(2.0 * pi); /* in m */
|
||||
|
||||
setProperty ("L", l, UNIT_LENGTH, LENGTH_M);
|
||||
|
||||
if (kc(1,0) <= k) {
|
||||
/*propagating modes */
|
||||
beta = sqrt(pow(k,2.) - pow(kc(1,0),2.0));
|
||||
lambda_g = (2. * pi)/beta;
|
||||
atten_cond = alphac () * l;
|
||||
atten_dielectric = alphad () * l;
|
||||
er_eff = (1.0 - pow((fc(1,0)/f),2.0));
|
||||
} else {
|
||||
/*evanascent modes */
|
||||
Z0 = 0;
|
||||
ang_l = 0;
|
||||
er_eff = 0;
|
||||
atten_dielectric = 0.0;
|
||||
atten_cond = alphac_cutoff () * l;
|
||||
}
|
||||
|
||||
show_results ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rectwaveguide::show_results ()
|
||||
{
|
||||
short m, n, mmax, nmax;
|
||||
|
||||
setResult (0, er_eff, "");
|
||||
setResult (1, atten_cond, "dB");
|
||||
setResult (2, atten_dielectric, "dB");
|
||||
|
||||
setResult (3, "none");
|
||||
if (f >= (2.*fc(1,0))) {
|
||||
char text[256], txt[256];
|
||||
strcpy (text, "");
|
||||
/* multiple modes possible in waveguide */
|
||||
/* mmax = floor(f/fc(1,0));*/
|
||||
mmax = 5;
|
||||
nmax = mmax;
|
||||
for (m = 2; m<= mmax; m++) {
|
||||
for (n=0; n<= nmax; n++) {
|
||||
if (f >= (fc(m,n))){
|
||||
sprintf(txt,"TE(%u,%u) ",m, n);
|
||||
strcat(text,txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
setResult (3, text);
|
||||
}
|
||||
|
||||
setResult (4, "none");
|
||||
if (f >= fc(1,1)){ /*TM(1,1) mode possible*/
|
||||
char text[256], txt[256];
|
||||
strcpy (text, "");
|
||||
/* mmax = floor(f/fc(1,1));*/
|
||||
mmax = 5;
|
||||
nmax = mmax;
|
||||
for (m = 1; m<= mmax; m++) {
|
||||
for (n=1; n<= nmax; n++) {
|
||||
if (f >= (fc(m,n))){
|
||||
sprintf(txt,"TM(%u,%u) ",m, n);
|
||||
strcat(text,txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
setResult (3, text);
|
||||
}
|
||||
}
|
65
qucs-transcalc/rectwaveguide.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* rectwaveguide.h - rectangular waveguide class definition
|
||||
*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RECTWAVEGUIDE_H
|
||||
#define __RECTWAVEGUIDE_H
|
||||
|
||||
class rectwaveguide : public transline {
|
||||
public:
|
||||
rectwaveguide();
|
||||
~rectwaveguide();
|
||||
|
||||
private:
|
||||
double er; /* dielectric constant */
|
||||
double tand; /* Dielectric Loss Tangent */
|
||||
double tanm; /* Magnetic Loss Tangent */
|
||||
double a; /* width of waveguide */
|
||||
double b; /* height of waveguide */
|
||||
double l; /* length of waveguide */
|
||||
double Z0; /* characteristic impedance */
|
||||
double ang_l; /* Electrical length in angle */
|
||||
double er_eff; /* Effective dielectric constant */
|
||||
//double mur_eff; /* Effective mag. permeability */
|
||||
double atten_dielectric; /* Loss in dielectric (dB) */
|
||||
double atten_cond; /* Loss in conductors (dB) */
|
||||
//double fc10; /* Cutoff frequency for TE10 mode */
|
||||
|
||||
public:
|
||||
void analyze ();
|
||||
int synthesize ();
|
||||
|
||||
private:
|
||||
double kval ();
|
||||
double kc (int, int);
|
||||
double fc (int, int);
|
||||
double alphac ();
|
||||
double alphac_cutoff ();
|
||||
double alphad ();
|
||||
void get_rectwaveguide_sub ();
|
||||
void get_rectwaveguide_comp ();
|
||||
void get_rectwaveguide_phys ();
|
||||
void get_rectwaveguide_elec ();
|
||||
void show_results ();
|
||||
};
|
||||
|
||||
#endif /* __RECTWAVEGUIDE_H */
|
222
qucs-transcalc/stripline.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* stripline.cpp - stripline class implementation
|
||||
*
|
||||
* Copyright (C) 2016 Andres Martinez-Mera <andresmartinezmera@gmail.com>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "units.h"
|
||||
#include "transline.h"
|
||||
#include "stripline.h"
|
||||
|
||||
stripline::stripline() : transline()
|
||||
{
|
||||
}
|
||||
|
||||
stripline::~stripline()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* get_stripline_sub() - get and assign stripline substrate parameters into stripline
|
||||
* structure
|
||||
*/
|
||||
void stripline::get_stripline_sub ()
|
||||
{
|
||||
er = getProperty ("Er");
|
||||
mur = getProperty ("Mur");
|
||||
tand = getProperty ("Tand");
|
||||
sigma = getProperty ("Sigma");
|
||||
t = getProperty ("T", UNIT_LENGTH, LENGTH_M);
|
||||
h = getProperty ("h", UNIT_LENGTH, LENGTH_M);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_stripline_comp() - get and assign stripline component parameters into
|
||||
* stripline structure
|
||||
*/
|
||||
void stripline::get_stripline_comp ()
|
||||
{
|
||||
f = getProperty ("Freq", UNIT_FREQ, FREQ_HZ);
|
||||
lambda_0 = C0/f;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_stripline_elec() - get and assign stripline electrical parameters into
|
||||
* stripline structure
|
||||
*/
|
||||
void stripline::get_stripline_elec ()
|
||||
{
|
||||
Z0 = getProperty ("Z0", UNIT_RES, RES_OHM);
|
||||
ang_l = getProperty ("Ang_l", UNIT_ANG, ANG_RAD);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_stripline_phys() - get and assign stripline physical parameters into stripline
|
||||
* structure
|
||||
*/
|
||||
void stripline::get_stripline_phys ()
|
||||
{
|
||||
W = getProperty ("W", UNIT_LENGTH, LENGTH_M);
|
||||
l = getProperty ("L", UNIT_LENGTH, LENGTH_M);
|
||||
}
|
||||
|
||||
/* This function calculates the dielectric attenuation coefficient*/
|
||||
double stripline::alphad_stripline ()
|
||||
{
|
||||
return 27.3*sqrt(er)*tand/lambda_0;
|
||||
}
|
||||
|
||||
/* This function calculates the conductor attenuation coefficient*/
|
||||
double stripline::alphac_stripline ()
|
||||
{
|
||||
double w = 2*pi*f, alpha_c;
|
||||
double mu = mur*pi*4e-7;
|
||||
double Rs = sqrt(w*mu/(2*sigma));//Skin effect resistance
|
||||
skindepth = sqrt(2/(w*mu*sigma));
|
||||
double A = 1 + 2*W/(2*h-t) + (1/pi)*((2*h+t)/(2*h-t))*log((4*h-t)/t);
|
||||
double B = 1 + (2*h/(0.5*W+0.7*t))*(0.5 + 0.414*t/W + (1/(2*pi))*log(4*pi*W/t));
|
||||
|
||||
(Z0 < 120/sqrt(er)) ?
|
||||
alpha_c = (23.4e-3*Rs*er*Z0*A)/(30*pi*(2*h-t)) :
|
||||
alpha_c = 1.4*Rs*B/(Z0*2*h);
|
||||
|
||||
return alpha_c;
|
||||
}
|
||||
|
||||
/*
|
||||
* analyze() - Reads both the substrate and the physical properties of the line and calculates Z0 and the electrical length
|
||||
*/
|
||||
void stripline::analyze ()
|
||||
{
|
||||
/* Get and assign substrate parameters */
|
||||
get_stripline_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_stripline_comp();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
get_stripline_phys();
|
||||
|
||||
calculateZ0(); // Z0
|
||||
getStriplineLength();// Line length
|
||||
alphac_stripline();// alpha_c and skin depth
|
||||
alphad_stripline();// alpha_d
|
||||
setProperty ("Z0", Z0, UNIT_RES, RES_OHM);
|
||||
setProperty ("Ang_l", ang_l, UNIT_ANG, ANG_RAD);
|
||||
show_results();
|
||||
}
|
||||
|
||||
|
||||
// This function calculates the characteristic impedance of a symmetric stripline according to [1], eq. 4.80-4.84
|
||||
double stripline::getZ0fromWidth(double W_)
|
||||
{
|
||||
double x = t/(2.*h);
|
||||
double m= 2/(1 + 2*x/3*(1-x));
|
||||
double B = (x/(pi*(1-x)))*(1 - 0.5*log(pow(x/(2.-x),2) + pow((0.0796*x)/((W_/(2.*h)) + 1.1*x),m)));
|
||||
double A = 1/((W_/(2*h - t)) + B);
|
||||
// Line impedance
|
||||
return (30/sqrt(er))*log(1 + (4/pi)*A*((8/pi)*A + sqrt(pow((8/pi)*A,2) + 6.27)));
|
||||
}
|
||||
|
||||
/* This function calculates the static line impedance*/
|
||||
void stripline::calculateZ0()
|
||||
{
|
||||
Z0 = getZ0fromWidth(W);
|
||||
}
|
||||
|
||||
void stripline::getStriplineLength()
|
||||
{
|
||||
double lambda_g = (C0/(f))/sqrt(er * mur);
|
||||
/* calculate electrical angle */
|
||||
ang_l = (2.0 * pi * l)/lambda_g; /* in radians */
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int stripline::synthesize ()
|
||||
{
|
||||
get_stripline_sub();//Substrate
|
||||
get_stripline_elec();//Z0 and electrical length
|
||||
get_stripline_phys();//Line size
|
||||
alphac_stripline();// alpha_c and skin depth
|
||||
alphad_stripline();// alpha_d
|
||||
|
||||
|
||||
// Zero-thickness approximation
|
||||
double B = exp(Z0*sqrt(er)/30)-1;
|
||||
double C = sqrt(4*B+6.27);
|
||||
double A = 2*B/C;
|
||||
double A1 = 8/(pi*A);
|
||||
|
||||
double x = t/(2*h);
|
||||
double m= 2/(1 + 2*x/3*(1-x));
|
||||
double We = (2*h - t)*A1;
|
||||
double A2 = (x/(pi*(1-x))) * (1 - 0.5*log( (x*x/(4-2*x+x*x)) + pow((0.0796*x/( (We/(2*h)) + 1.1*x)),m) ));
|
||||
|
||||
double Wi = (A1 - A2)*(2*h-t);//Width given by the zero-thickness approximation (Initial guess for the refinement)
|
||||
|
||||
double Zi;
|
||||
double dW = Wi*1e-4;//Differential width
|
||||
unsigned int MAX_ITER = 100, iter = 0;
|
||||
double MAX_ERR = 1e-5;
|
||||
double Zi_1 = 0, Zi_diff, step;
|
||||
|
||||
|
||||
// The Newton-Raphson method is employed to refine the width given by the zero-thickness approximation with the analysis formulae.
|
||||
while ((std::abs(Z0 - Zi_1) > MAX_ERR)&&(iter < MAX_ITER))//Stop condition: |Z0 - Z_i| < MAX_ERR or max. number iterations exceeded
|
||||
{
|
||||
Zi = getZ0fromWidth(Wi+dW);
|
||||
Zi_diff = (Zi - Zi_1) / dW;
|
||||
step = (Z0 - Zi_1) / Zi_diff - dW;
|
||||
Wi += step+dW;
|
||||
if (Wi <= 0.0) Wi = dW;
|
||||
Zi_1 = getZ0fromWidth(Wi);
|
||||
iter++;
|
||||
}
|
||||
|
||||
setProperty ("W", Wi, UNIT_LENGTH, LENGTH_M);
|
||||
double lambda_g = lambda_0/sqrt(er * mur);
|
||||
/* calculate physical length */
|
||||
l = (lambda_g * ang_l)/(2.0 * pi); /* in m */
|
||||
setProperty ("L", l, UNIT_LENGTH, LENGTH_M);
|
||||
|
||||
show_results();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* show_results() - show results
|
||||
*/
|
||||
void stripline::show_results()
|
||||
{
|
||||
atten_dielectric = alphad_stripline () * l;
|
||||
atten_cond = alphac_stripline () * l;
|
||||
|
||||
setResult (0, atten_cond, "dB");
|
||||
setResult (1, atten_dielectric, "dB");
|
||||
double val = convertProperty ("T", skindepth, UNIT_LENGTH, LENGTH_M);
|
||||
setResult (2, val, getUnit ("T"));//Skin depth
|
||||
}
|
70
qucs-transcalc/stripline.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* stripline.h - stripline class definition
|
||||
*
|
||||
* Copyright (C) 2016 Andres Martinez-Mera <andresmartinezmera@gmail.com>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __STRIPLINE_H
|
||||
#define __STRIPLINE_H
|
||||
|
||||
/*
|
||||
Reference:
|
||||
[1] Analysis Methods for RF, Microwave and Milimeter-Wave Planar Transmission Line Structures,
|
||||
Cam Nguyen. John Wiley and Sons Inc., 2001, Pages 76 - 78
|
||||
*/
|
||||
|
||||
class stripline : public transline {
|
||||
public:
|
||||
stripline();
|
||||
~stripline();
|
||||
|
||||
private:
|
||||
double er; /* dielectric constant */
|
||||
double tand; /* Dielectric Loss Tangent */
|
||||
double t; /* Thickness */
|
||||
double h; /* Substrate height */
|
||||
double W; /* Width of the conductor strip */
|
||||
double l; /* Length of cable */
|
||||
double Z0; /* characteristic impedance */
|
||||
double ang_l; /* Electrical length in angle */
|
||||
double er_eff; /* Effective dielectric constant */
|
||||
double atten_dielectric; /* Loss in dielectric (dB) */
|
||||
double atten_cond; /* Loss in conductors (dB) */
|
||||
double lambda_0; /* Wavelength */
|
||||
|
||||
public:
|
||||
void analyze ();
|
||||
int synthesize ();
|
||||
|
||||
private:
|
||||
void get_stripline_sub();
|
||||
void get_stripline_comp();
|
||||
void get_stripline_phys();
|
||||
void get_stripline_elec();
|
||||
void fixdin();
|
||||
void fixdout();
|
||||
double alphad_stripline();
|
||||
double alphac_stripline();
|
||||
void show_results();
|
||||
void getStriplineLength();
|
||||
void calculateZ0();
|
||||
double getZ0fromWidth(double);
|
||||
};
|
||||
|
||||
#endif /* __stripline_H */
|
187
qucs-transcalc/transline.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* transline.cpp - base for a transmission line implementation
|
||||
*
|
||||
* Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qucstrans.h"
|
||||
#include "transline.h"
|
||||
#include "units.h"
|
||||
|
||||
// Unit conversion array for length.
|
||||
static double conv_length[7][7] = {
|
||||
{ 1.0, 2.54e-3, 2.54e-2, 2.54e-5, 25.4, 1.e-3, 1./12000},
|
||||
{1./2.54e-3, 1.0, 10.0, 1.e-2, 1.e4, 1./2.54, 1./30.48},
|
||||
{1./2.54e-2, 1./10., 1.0, 1.e-3, 1.e3, 1./25.4, 1./304.8},
|
||||
{1./2.54e-5, 1.e2, 1.e3, 1.0, 1.e6, 1./2.54e-2, 1./0.3048},
|
||||
{1./25.4, 1.e-4, 1.e-3, 1.e-6, 1.0, 1./2.54e4, 1./3.048e5},
|
||||
{1.e3, 2.54, 25.4, 2.54e-2, 2.54e4, 1.0, 1./12.},
|
||||
{1.2e4, 30.48, 304.8, 0.3048, 3.048e5, 12.0, 1.0}
|
||||
};
|
||||
|
||||
// Unit conversion array for frequencies.
|
||||
static double conv_freq[4][4] = {
|
||||
{ 1.0, 1.e9, 1.e6, 1.e3},
|
||||
{ 1.e-9, 1.0, 1.e-3, 1.e-6},
|
||||
{ 1.e-6, 1.e3, 1.0, 1.e-3},
|
||||
{ 1.e-3, 1.e6, 1.e3, 1.0}
|
||||
};
|
||||
|
||||
// Unit conversion array for resistances.
|
||||
static double conv_res[2][2] = {
|
||||
{1.0, 1.e-3},
|
||||
{1.e3, 1.0}
|
||||
};
|
||||
|
||||
// Unit conversion array for angles.
|
||||
static double conv_ang[2][2] = {
|
||||
{1.0, pi/180.0},
|
||||
{180.0/pi, 1.0}
|
||||
};
|
||||
|
||||
/* Constructor creates a transmission line instance. */
|
||||
transline::transline () {
|
||||
app = 0;
|
||||
mur = 1.0;
|
||||
}
|
||||
|
||||
/* Destructor destroys a transmission line instance. */
|
||||
transline::~transline () {
|
||||
}
|
||||
|
||||
/* Sets the application instance. */
|
||||
void transline::setApplication (QucsTranscalc * a) {
|
||||
app = a;
|
||||
}
|
||||
|
||||
/* Sets a named property to the given value, access through the
|
||||
application. */
|
||||
void transline::setProperty (const char * prop, double value) {
|
||||
app->setProperty (prop, value);
|
||||
}
|
||||
|
||||
/* Sets a named property to a given value. Depending on the source
|
||||
and destination unit the value gets previously converted. */
|
||||
void transline::setProperty (const char * prop, double value, int type,
|
||||
int srcunit) {
|
||||
int dstunit = translateUnit (getUnit (prop));
|
||||
if (type == UNIT_LENGTH)
|
||||
value *= conv_length[srcunit][dstunit];
|
||||
else if (type == UNIT_RES)
|
||||
value *= conv_res[srcunit][dstunit];
|
||||
else if (type == UNIT_ANG)
|
||||
value *= conv_ang[srcunit][dstunit];
|
||||
else if (type == UNIT_FREQ)
|
||||
value *= conv_freq[srcunit][dstunit];
|
||||
setProperty (prop, value);
|
||||
}
|
||||
|
||||
/* Converts the given value/unit pair into a text representation and
|
||||
puts this into the given result line. */
|
||||
void transline::setResult (int line, double value, const char * unit) {
|
||||
char text[256];
|
||||
sprintf (text, "%g %s", value, unit);
|
||||
app->setResult (line, text);
|
||||
}
|
||||
|
||||
/* Puts the text into the given result line. */
|
||||
void transline::setResult (int line, const char * text) {
|
||||
app->setResult (line, text);
|
||||
}
|
||||
|
||||
/* Returns a named property value. */
|
||||
double transline::getProperty (const char * prop) {
|
||||
return app->getProperty (prop);
|
||||
}
|
||||
|
||||
/* Returns a named property selection. */
|
||||
bool transline::isSelected (const char * prop) {
|
||||
return app->isSelected (prop);
|
||||
}
|
||||
|
||||
/* Returns a named property value. Depending on the source and
|
||||
destination unit the actual value is converted. */
|
||||
double transline::getProperty (const char * prop, int type, int dstunit) {
|
||||
int srcunit = translateUnit (getUnit (prop));
|
||||
double value = getProperty (prop);
|
||||
if (type == UNIT_LENGTH)
|
||||
return value * conv_length[srcunit][dstunit];
|
||||
else if (type == UNIT_RES)
|
||||
return value * conv_res[srcunit][dstunit];
|
||||
else if (type == UNIT_ANG)
|
||||
return value * conv_ang[srcunit][dstunit];
|
||||
else if (type == UNIT_FREQ)
|
||||
return value * conv_freq[srcunit][dstunit];
|
||||
return value;
|
||||
}
|
||||
|
||||
/* The function converts the given value depending on the requested
|
||||
unit and its source unit. */
|
||||
double transline::convertProperty (const char * prop, double value, int type,
|
||||
int srcunit) {
|
||||
int dstunit = translateUnit (getUnit (prop));
|
||||
if (type == UNIT_LENGTH)
|
||||
value *= conv_length[srcunit][dstunit];
|
||||
else if (type == UNIT_RES)
|
||||
value *= conv_res[srcunit][dstunit];
|
||||
else if (type == UNIT_ANG)
|
||||
value *= conv_ang[srcunit][dstunit];
|
||||
else if (type == UNIT_FREQ)
|
||||
value *= conv_freq[srcunit][dstunit];
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Returns the unit of the given property. */
|
||||
char * transline::getUnit (const char * prop) {
|
||||
return app->getUnit (prop);
|
||||
}
|
||||
|
||||
/* The function translates the given textual unit into an
|
||||
identifier. */
|
||||
int transline::translateUnit (char * text) {
|
||||
if (!strcmp (text, "mil")) return LENGTH_MIL;
|
||||
else if (!strcmp (text, "cm")) return LENGTH_CM;
|
||||
else if (!strcmp (text, "mm")) return LENGTH_MM;
|
||||
else if (!strcmp (text, "m")) return LENGTH_M;
|
||||
else if (!strcmp (text, "um")) return LENGTH_UM;
|
||||
else if (!strcmp (text, "in")) return LENGTH_IN;
|
||||
else if (!strcmp (text, "ft")) return LENGTH_FT;
|
||||
|
||||
else if (!strcmp (text, "GHz")) return FREQ_GHZ;
|
||||
else if (!strcmp (text, "Hz")) return FREQ_HZ;
|
||||
else if (!strcmp (text, "kHz")) return FREQ_KHZ;
|
||||
else if (!strcmp (text, "MHz")) return FREQ_MHZ;
|
||||
|
||||
else if (!strcmp (text, "Ohm")) return RES_OHM;
|
||||
else if (!strcmp (text, "kOhm")) return RES_KOHM;
|
||||
|
||||
else if (!strcmp (text, "Deg")) return ANG_DEG;
|
||||
else if (!strcmp (text, "Rad")) return ANG_RAD;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* skin_depth - calculate skin depth
|
||||
*/
|
||||
double transline::skin_depth()
|
||||
{
|
||||
double depth;
|
||||
depth = 1.0 / (sqrt(pi * f * mur * MU0 * sigma));
|
||||
return depth;
|
||||
}
|
60
qucs-transcalc/transline.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* transline.h - base for a transmission line class definition
|
||||
*
|
||||
* Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __TRANSLINE_H
|
||||
#define __TRANSLINE_H
|
||||
|
||||
class QucsTranscalc;
|
||||
|
||||
|
||||
class transline {
|
||||
public:
|
||||
transline ();
|
||||
virtual ~transline ();
|
||||
|
||||
void setApplication (QucsTranscalc *);
|
||||
void setProperty (const char *, double);
|
||||
void setProperty (const char *, double, int, int);
|
||||
double getProperty (const char *);
|
||||
double getProperty (const char *, int, int);
|
||||
double convertProperty (const char *, double, int, int);
|
||||
void setResult (int, double, const char *);
|
||||
void setResult (int, const char *);
|
||||
int translateUnit (char *);
|
||||
char * getUnit (const char *);
|
||||
bool isSelected (const char *);
|
||||
|
||||
virtual int synthesize () { return -1; };
|
||||
virtual void analyze () { };
|
||||
|
||||
protected:
|
||||
double f; /* Frequency of operation */
|
||||
double sigma; /* Conductivity of the metal */
|
||||
double mur; /* mag. permeability */
|
||||
double skindepth; /* Skin depth */
|
||||
double skin_depth();
|
||||
|
||||
private:
|
||||
QucsTranscalc * app;
|
||||
};
|
||||
|
||||
#endif /* __TRANSLINE_H */
|
75
qucs-transcalc/units.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* units.h - some conversion definitions
|
||||
*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
*
|
||||
* 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 package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __UNITS_H
|
||||
#define __UNITS_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
||||
static const double pi = 3.1415926535897932384626433832795029; /* pi */
|
||||
static const double pi_over_2 = 1.5707963267948966192313216916397514; /* pi/2 */
|
||||
static const double e = 2.7182818284590452353602874713526625; /* e */
|
||||
|
||||
static const double MU0 = 12.566370614e-7; /* magnetic constant */
|
||||
static const double C0 = 299792458.0; /* speed of light in vacuum */
|
||||
static const double ZF0 = 376.73031346958504364963; /* wave resistance in vacuum */
|
||||
|
||||
#ifndef INFINITY
|
||||
const double INFINITY = -log (0.0);
|
||||
#endif
|
||||
|
||||
static const double NR_EPSI = 2.2204460492503131e-16;
|
||||
static const double MAX_ERROR = 0.000001;
|
||||
|
||||
// Types of units.
|
||||
#define UNIT_FREQ 0
|
||||
#define UNIT_LENGTH 1
|
||||
#define UNIT_RES 2
|
||||
#define UNIT_ANG 3
|
||||
|
||||
// Frequency units.
|
||||
#define FREQ_GHZ 0
|
||||
#define FREQ_HZ 1
|
||||
#define FREQ_KHZ 2
|
||||
#define FREQ_MHZ 3
|
||||
|
||||
// Length units.
|
||||
#define LENGTH_MIL 0
|
||||
#define LENGTH_CM 1
|
||||
#define LENGTH_MM 2
|
||||
#define LENGTH_M 3
|
||||
#define LENGTH_UM 4
|
||||
#define LENGTH_IN 5
|
||||
#define LENGTH_FT 6
|
||||
|
||||
// Resistance units.
|
||||
#define RES_OHM 0
|
||||
#define RES_KOHM 1
|
||||
|
||||
// Angle units.
|
||||
#define ANG_DEG 0
|
||||
#define ANG_RAD 1
|
||||
|
||||
|
||||
#endif /* __UNITS_H */
|
@ -814,7 +814,7 @@ void QucsApp::slotCallActiveFilter()
|
||||
// Is called to start the transmission line calculation program.
|
||||
void QucsApp::slotCallLine()
|
||||
{
|
||||
launchTool("qucstrans", "line calculation",QStringList(),true);
|
||||
launchTool(QUCS_NAME "trans", "line calculation",QStringList(),true);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|