LCnetgen Home Page

Calculates the distributed inductance and capacitance of a network of coils, wires, and electrodes of various shapes.

Generates a Spice sub-circuit representing the coils and electrodes as a detailed LCR network.

LCnetgen is open source and runs on all system supporting the gcc compiler - that means almost any computer from a Raspberry Pi to a Cray - with the exception of those running Windows.

The program uses a quasi-static field approximation and is therefore applicable only when the dimensions of the system are small compared with the free-space wavelength of the highest frequency of interest.

Applications include: Tesla coils; LF and VLF antennas; Loading coils and variometers; High voltage systems.


LCnetgen calculates:

  • Self capacitance of each electrode;
  • Distributed self capacitance of each coil;
  • Distributed mutual capacitance between each pair of coils;
  • Distributed mutual capacitance between all coils and electrodes;
  • Self inductance of each coil;
  • Distributed mutual inductance between each pair of coils;
  • Distributed series resistance of each coil;
  • Response of each coil to incident electric and magnetic fields;
  • Response of each electrode to incident electric field;

Component types:

  • Spheres;
  • Toroids;
  • Discs and plates;
  • Cylinders and cones;
  • Wires;
  • Solenoids;
  • Loops;
  • Flat spiral coils;
  • Circular cross-section;
  • Any polygonal cross-section;
  • Incident electric and magnetic fields;
  • Infinite ground plane;

Contents

Installation

Download the latest version, lcnetgen-0.4e.tgz. Unpack and descend into the source directory with

   tar xzf lcnetgen-0.4e.tgz
   cd lcnetgen-0.4e
Then compile the program with
   make
There should be no errors unless you have a very unusual system. There are no dependencies other than gcc and the usual C libraries.

Then, as the superuser, install into /usr/local/bin with

   make install
or edit the makefile to install the executable somewhere else in your execution path. Then the command
   lcng -?
should give you a summary of command line options.

To test the program, run

   ./test
which exercises many of the functions of the program and checks for correct output. The script relies on you having ngspice installed.

Command line usage

   lcng [options] system

   options:

    -o spice   Generate spice sub-circuit
    -o list    Output a listing of R, L and C, charge and magnetic flux
    -o tiles   Generate a tiles file
    -o povray  Generate an input file for povray
    -o gnuplot Display system interactively using gnuplot
    -o geda    Output a gEDA symbol for the system

    -v     Increase verbosity

    -m dir        Use direct calculation for capacitance (default)
    -m fmm        Use fast multipole method for capacitance
  
    -m cgm        Use conjugate gradient method (default with -m dir)
    -m gmres      Use generalised minimum residuals method (default with -m fmm)
    -m ge         Use Gaussian elimination (only with -m dir)

    -m depth=num  Use fixed depth octree, 'num' gives depth (default 5)
    -m precon     Enable preconditioning (only with -m fmm)
    -m degree=num Maximum degree of spherical harmonics (default 6)

    -t factor  Scales the number of tiles by factor (default 1.0)
    -c cpus    Use number of threads in parallel (maximum 64, default 1)

    -r dc      Use DC resistance for coils
    -r ac      Use AC resistance for coils (default)
 
    -NC        Don't do capacitance calculation
    -NL        Don't do inductance calculation
    -NR        Don't do resistance calculation
By default, lcng only reports errors and is silent otherwise. A -v option produces some progress and info messages. -vv produces more detail, and -vvv is only useful for debuging the software.

The potential matrix is solved to obtain the capacitance matrix using the generalised minimum residuals method. This usually converges quite well. Using -m cgm switches to the conjugate gradient method which is a little slower but might converge better in some cases. Option -m ge abandons interative solution and switches to Gaussian elimination but this is very slow and is only useful for testing. If convergence is problematic then you probably need to reconsider the decomposition of electrodes and coils into tiles and sections. Convergence problems tend to occur when components interfere (overlap) or where components from different electrodes are very close to one another.

If the capacitance calculation is too large for available RAM, -m fmm must be used which invokes the fast multipole method. This is slower in most situations but will allow a very large number of tiles to be used.

Option -c specifies how many CPU threads to use. lcng makes efficient use of multi-core machines.

lcng specifies behavioral resistors for coil sections in the Spice sub-circuit in order to represent the frequency dependent AC resistance. Some versions of Spice may not work properly with this (or work very slowly). Option -r dc will switch to using the DC resistance for coil sections.

Input File

lcng expects an input file to describe the your system of coils, wires, and electrodes. This is a plain text file called system.in where 'system' is a name you give your project. The input file describes the position, size, and orientation of all the components.

Arithmetic expressions can be used for all the values. Standard arithmetic functions and operators are available and conventional operator precedence applies. Ternary operators provide conditionals and variables can be defined.

The file uses white-space separated tokens and is otherwise free format (you can put line breaks anywhere between tokens). A semicolon introduces a comment in the input file. The semicolon and everthing following it to end-of-line is ignored.

The input file consists of a list of electrode and coil descriptions, and possible ground plane and field descriptions:

   electrode { ...  }

   electrode { ...  }

   coil { ...  }

   ground { ... }

   field { ... }
Electrodes and coils can be listed in any order and you can declare as many of each as you need.

Coordinate system

A standard right-handed Cartesian coordinate system is used to specify points. A point is given by a comma separated triplet of expressions: x,y,z. If '+x' is considered to be 'east' then '+y' equates to 'north' and '+z' is the vertical direction.

Axes are given in polar coordinates with values in degrees. A comma separated pair of expressions pa,azim gives the polar angle and azimuth. pa gives the angle of the axis from the vertical towards the east (+x) and azim rotates the tilted axis anti-clockwise when looking down. Examples:

   pa,azim = 0,0    ; Vertical axis (+z)
   pa,azim = 90,0   ; Axis points east (+x)
   pa,azim = -90,0  ; Axis points west (-x)
   pa,azim = 90,90  ; Axis points north (+y)
   pa,azim = 90,-90 ; Axis points south (-y)
   pa,azim = 60,45  ; Axis points north-east,
                    ; 30 degrees to the horizontal

Transforms

Objects can be moved and rotated using a transform clause:

   transform {
      electrode { ... }
      coil { ... }
      coil { ... }
      
      rotate pa,azim angle
      shift x,y,z
   }
rotate rotates all the objects previously declared in the transform clause around the axis given by pa,azim by angle degrees. The rotation is right handed and the axis passes through the origin.

shift moves all the objects by adding x,y,z to their coordinates.

Rotations and shifts are applied in the order in which they are specified. Normally you would rotate objects first, then shift them to their final position. It can be very confusing to do it the other way around because the rotation axes always pass through the origin.

Transformations are applied only to the objects already declared in the transform clause:

   transform {
      coil { ... }  ; Coil 1
      shift 0,0,1   ; Raise coil 1 by 1 metre (+z)
      coil { ... }  ; Coil 2
      shift 1,0,0   ; Moves coil 1 and coil 2 by 1 metre along +x
      coil { ... }  ; Coil 3, not transformed at all
   }
Transforms also operate on the ground plane and fields. Transforms can be arbitrarily nested.

Transforms are used to simplify the construction of complicated electrodes and coils. The object is constructed in say, the xy plane centered at the origin, then rotated and shifted (in that order) into the desired position.

Units

By default all measurements are in metres. You can specify other units by following an expression with cm, mm, in, or ft.

Variables

These can be useful to parameterise the tunable aspects of your design. Define variables outside of any electrode or coil clause using the syntax

   name = expression
Names are case insensitive, should start with a letter, consist of letters, digits and underscore, and must be defined in the input file before they are used. Some variable names are reserved: field,coil,electrode,ground,shift,rotate,axis.

Variables are very useful when you want to move around a structure which consists of a bunch of components.

Electrodes

An electrode is built from an arbitrary list of the components defined below.

   electrode {
      name your_label

      sphere { ... }
      disc { ... }
      ...
   }
All the components specified with the electrode clause are considered to be electrically connected and all at the same potential. An optional name parameter can be used to label the electrode in the output files. Your name for the electrode is case sensitive and must not contain any spaces. If you don't supply a name, lcng will just number them 'E1', 'E2' and so on.

Your input file can specify any number of electrodes and each can contain any number of components. The order in which the components are defined does not matter. The available components and their syntax are described below.

Sphere component

A hollow sphere.

   sphere {
      center x,y,z
      radius r
      tiles nt
   }
center and radius give the position and size of the sphere. The optional tiles specifies how many tiles the sphere is decomposed into. The default is 200.

Disc component

A thin disc

   disc {
      center x,y,z
      radius1 r1     ; Inner radius
      radius2 r2     ; Outer radius
      axis pa,azim
      tiles nt
      uniform
   }
If the disc is complete (no hole in the middle so that radius1 is zero) you can just specify the outer radius with
      radius r
The optional tiles specifies how many tiles the disc is decomposed into. The default is 500.

By default, lcng will increase the tile density towards the inner and outer (or just the outer) rim. The optional keyword uniform turns this off to produce a uniform tiling of the disc.

Rectangle component

A flat rectangular thin plate.

   rectangle {
      center xc,yc,zc
      edge1 x1,y1,z1
      edge2 x2,y2,z2
      tiles nt
      uniform
   }
center is the center of the plate and the points edge1 and edge2 locate the mid-points of two adjacent edges. lcng will complain if the three points are not coplanar.

The optional keyword uniform instructs lcng to produce a uniform tiling of the rectangle. By default it will increase the tile density towards the edges.

The optional tiles specifies how many tiles the rectangle is decomposed into. The default is 500.

Wire component

A thin wire. Position and orientation can be given by fixing the two ends,

   wire {
      end1 x1,y1,z1
      end2 x2,y2,z2
      wirad r
      tiles nt
   }
or by fixing one end and giving a length and azis,
   wire {
      end1 x1,y1,z1
      length len
      axis pa,azim
      wirad r
      tiles nt
   }
For this component the ratio of length to diameter should be 100:1 or more. For smaller length/diameter ratios, better results may be obtained with a cylinder component.

wirad is the conductor radius in metres. The value may be postfixed with awg or any of the other unit specifiers.

The optional tiles specifies how many tiles the wire is decomposed into. The default is 200.

Toroid component

   toroid {
      center x,y,z
      inner_radius r1
      outer_radius r2
      axis pa,azim
      tiles nt
   }
The optional tiles specifies how many tiles the toroid is decomposed into. The default is 500.

Cylinder component

A cylinder or cone - any right circular frustum. Open at the ends. Position and orientation can be given by fixing the two ends,

   cylinder {
      end1 x1,y1,z1
      end2 x2,y2,z2
      radius1 r1     ; Radius at end1
      radius2 r2     ; Radius at end2
      tiles nt
      uniform
   }
or by fixing one end and giving a length and axis
   cylinder {
      end1 x1,y1,z1
      axis pa,azim
      length len
      radius1 r1     ; Radius at end1
      radius2 r2     ; Radius at end2
      tiles nt
      uniform
   }
If the component is a straight sided cylinder (radius1 = radius2) you can just give the radius with
      radius r
The optional tiles specifies how many tiles the cylinder is decomposed into. The default is 500.

The keyword uniform selects uniform tiling of the cylinder. By default it will increase the tile density towards the ends.

The cylinder component can be used with good accuracy from length:diameter radius of 100:1 through to 1:100. It is still fairly good for ratios out to 1000 both ways,

Polygonal plate component

This is a thin flat plate of any non self-intersecting polygonal shape. The perimeter is described by a list of consecutive points.
   plate {
      points { x1,y1,z1 } { x2,y2,z2 } ...
             ... { xn,yn,zn }
      tiles nt
   }
You should not supply a closing repeat of the first point. The points should all be in the same plane. An optional tiles parameter alters the number of tiles from the default of 500.

Coils

A coil can be of any straight-sided shape with circular or arbitrary polygonal cross-section. This includes discs, cylinders and cones (any right frustum), loops, and planar coils.

Coils are broken down into sections and the capacitance and inductance, mutual and self, of each is calculated. This allows resonances of the coils to be accurately represented if enough sections are used. Using 10 sections is usually enough to obtain the fundamental resonance to within 2%, the first overtone to within 5% and the second overtone to around 10% or so.

Position and orientation can be given by fixing the two ends, or by fixing one end and giving a length and axis.

   coil {
      name your_label
      wirad r
      turns t
      tap  t1
      tap  t2
      sections ns
      tiles nt
      ...
   }
wirad is the conductor radius in metres. The value may be postfixed with awg or any of the other unit specifiers.

turns can be fractional and may be positive or negative - this specifies the winding direction. With positive turns, viewing the coil from end1, looking towards end2 and tracing the path of the wire from end1 to end2, the winding rotates clockwise. If turns is negative, the winding rotates anti-clockwise. Any number of taps can be specified. If turns is negative, the taps must all have negative values. Tap positions are given as number of turns from end1.

sections specifies how many sections the coil will be modelled in. The default is 10. You may need to use more for greater accuracy of higher order resonant frequencies. lcng may adjust the number of sections upwards slightly and vary their length in order to place the taps at section boundaries.

tiles specifies how many tiles each coil sections is represented by for capacitance calculation. Default is 200.

The remainder of the coil description depends on the type of coil, described in the sections below.

Circular Solenoids

A circular solenoid is specified by either giving the coordinates of the two ends,
   coil {
      ...
      end1 x1,y1,z1
      end2 x2,y2,z2
      radius r
   }
or the coordinates of one end and a length and axis.
   coil {
      ...
      end1 x1,y1,z1
      axis pa,azim
      length len
      radius r
   }
The solenoid is cylindrical if only one radius is given. To make a cone shaped solenoid (frustum), specify a radius for each end:
      radius1  r1  ; Radius at end1
      radius2  r2  ; Radius at end2

Polygonal Solenoids

Polygonal solenoids are similar to circular solenoids above, but the center point of end one is replaced by a list of points which give the vertices of end one. For example a square solenoid with 1m sides in the xy plane centered at the origin would use

   end1 { -0.5, -0.5, 0 } { -0.5, 0.5, 0 }
        { 0.5, 0.5, 0 } { 0.5, -0.5, 0 }
An axis should not be given with polygonal coils, instead lcng works out the axis from the order of the points using the right hand rule. In the above example the axis is downwards (-z). Polygon cross-sections can be regular or irregular, convex or concave, but must not have any intersections of edges.

A cone shaped (frustum) solenoid with polygonal cross sections is specified by giving a second polygon to describe end two. Both polygons should have the same number of points and be parallel to each other.

The example below describes a conical hexagonal vertical solenoid

   rb = 0.8/2          ; 80cm overall diameter at the base
   rt = 0.3/2          ; 30cm overall diameter at the top
   a = 2 * pi / 6      ; Angle step per vertex
   base = 0.1          ; Base of coil 10cm above xy plane
   len  = 0.5          ; Length of coil is 50cm

   coil {
      name secondary
      turns 500
      wirad 30 awg

      end1 {  rb * sin(0*a), rb * cos(0*a), base }
           {  rb * sin(1*a), rb * cos(1*a), base }
           {  rb * sin(2*a), rb * cos(2*a), base }
           {  rb * sin(3*a), rb * cos(3*a), base }
           {  rb * sin(4*a), rb * cos(4*a), base }
           {  rb * sin(5*a), rb * cos(5*a), base }

      end2 {  rt * sin(0*a), rt * cos(0*a), base + len }
           {  rt * sin(1*a), rt * cos(1*a), base + len }
           {  rt * sin(2*a), rt * cos(2*a), base + len }
           {  rt * sin(3*a), rt * cos(3*a), base + len }
           {  rt * sin(4*a), rt * cos(4*a), base + len }
           {  rt * sin(5*a), rt * cos(5*a), base + len }
   }
To simplify constructing polygonal coils, it is often easiest to define the polygons in the xy plane, or parallel to it, then wrap the coil in a transform clause to tilt it to the required orientation and shift it into position.

Circular Loops

Circular loops are specified by giving the coil a length of zero and specifying a single radius and only one end. lcng does not attempt to calculate the internal capacitance of the loop because this depends signficantly on just how the turns of the loop are bundled. Therefore self-resonant frequencies of loops will not be accurately modelled.

Below is a 1m diameter loop in the yz plane with axis in the +x direction.

   coil {
      end1 0,0,2
      axis 90, 0   
      radius 0.5
      length 0
      turns 5
      wirad 22 awg
   }
end1 locates the center of the loop.

If your loop has a flat winding rather than a bundle, then treat it as a solenoid (albeit a short one) by specifying a length for the winding.

Loops will be modelled with just one section (ignoring any sections statement), unless you specify taps.

Polygonal Loops

Polygonal loops are similar to circular the circular loops above, but supply a polygon for end1. length is set to zero to indicate a loop and there is no radius specified.

The example below is an octoloop in the yz plane with axis in the +x direction.

   r = 1/2          ; 1 metre overall diameter
   p = 2 * pi / 16  ; Starting angle to give horizonal top
                    ; and bottom edges
   a = 2 * pi / 8   ; Angle step per vertex

   coil {
      turns 50
      wirad 1e-3
      length 0
   
      end1 {  r * sin(0*a + p), 0,  r * cos(0*a + p) }
           {  r * sin(1*a + p), 0,  r * cos(1*a + p) }
           {  r * sin(2*a + p), 0,  r * cos(2*a + p) }
           {  r * sin(3*a + p), 0,  r * cos(3*a + p) }
           {  r * sin(4*a + p), 0,  r * cos(4*a + p) }
           {  r * sin(5*a + p), 0,  r * cos(5*a + p) }
           {  r * sin(6*a + p), 0,  r * cos(6*a + p) }
           {  r * sin(7*a + p), 0,  r * cos(7*a + p) }
   }

Circular Planar Coils

A circular planar coil is specified by setting length zero and giving two radii. end1 locates the center of the disc. An example of a circular disc coil with vertical axis is given below,

   coil {
      turns 20
      wirad 18 awg
      length 0
      radius1 0.1   ; 10cm inner radius
      radius2 0.8   ; 80cm outer radius
      end1 2,3,4    ; Center of the coil
      axis 0,0      ; Vertical
   }

Polygonal Planar Coils

A polygonal planar coil is specified by giving coplanar polygons for end1 and end2.

   ro = 0.8/2       ; 80cm overall outside diameter
   ri = 0.3/2       ; 30cm overall inner diameter
   a = 2 * pi / 6   ; Angle step per vertex
   plane = 0.1      ; Plane of the coil 10cm above xy plane

   coil {
      name primary
      turns 20
      wirad 12 awg

      ;  Inner end of the coil
      end1 {  ri * sin(0*a), ri * cos(0*a), plane }
           {  ri * sin(1*a), ri * cos(1*a), plane }
           {  ri * sin(2*a), ri * cos(2*a), plane }
           {  ri * sin(3*a), ri * cos(3*a), plane }
           {  ri * sin(4*a), ri * cos(4*a), plane }
           {  ri * sin(5*a), ri * cos(5*a), plane }

      ;  Outer end of the coil
      end2 {  ro * sin(0*a), ro * cos(0*a), plane }
           {  ro * sin(1*a), ro * cos(1*a), plane }
           {  ro * sin(2*a), ro * cos(2*a), plane }
           {  ro * sin(3*a), ro * cos(3*a), plane }
           {  ro * sin(4*a), ro * cos(4*a), plane }
           {  ro * sin(5*a), ro * cos(5*a), plane }
   }

Ground Plane

You can specify an infinite ground plane with

   ground {
      center x,y,z
      axis pa,azim
   }
center specifies an arbitrary point on the ground plane and axis gives the orientation of the normal vector and should point to the side of the ground plane away from the earth. All components must be on this side of the ground plane.

The ground plane can be placed anywhere with any orientation, but is commonly fixed at the xy plane with

   ground {
      center 0,0,0
      axis 0,0
   }

Incident Fields

Incident electric and magnetic fields are given by a field clause,

   field {
      electric pa,azim
      magnetic pa,axim
   }
If either field is missing, it defaults to zero. The input file specifies only the orientation of the field vector. The amplitude and phase of each field is given by an input signal to the Spice sub-circuit.

Spice Sub-circuit

Generated with -o spice on the command line. lcng outputs a file called system.spice containing a Spice sub-circuit to represent your system. The sub-circuit has a separate terminal for each of your electrodes, and a terminal for both ends and every tap of each coil.

There is also a separate terminal for the potential at infinity. This provides the return path for all the self-capacitances. Normally you would connect this to node 0 (ground) within your Spice model, unless your Spice model requires the ground node to float to its own potential.

If a ground plane is specified, it is connected within the sub-circuit to the infinity terminal.

If fields have been specified, input terminals are provided so that the external circuit can specify the field amplitude. For electric fields, one volt on the input terminal produces a field of 1 V/m. For magnetic fields, one amp in the input terminal produces a 1 Tesla field.

View the sub-circuit as a text file,

   less system.spice
and see from the comments how the terminals have been assigned.

The generated Spice sub-circuit includes the self inductance and DC resistance of each coil section, and the mutual inductance between all pairs of coil sections. It also includes mutual capacitance between all pairs of coil sections, self capacitance of each section, and mutual capacitance between each coil section and every electrode in the system.

Tiles Output

Generated with the -o tiles option. An output file called system.tiles is produced which is 3-column space separated data file listing the x,y,z coordinates of every tile in the system.

You can use the tiles file to get a rough 3D view of your system using gnuplot. Generate a tiles file with

   lcng -o tiles system
Then run gnuplot and give it the following commands
   set terminal x11
   set style data points
   set view equal xyz
   splot 'system.tiles' using 1:2:3
You can move the image around with the mouse or arrow keys. The view is good enough as a sanity check on your input coordinates.

Gnuplot Output

Output option -o gnuplot runs gnuplot to interactively display a view of the system, using commands similar to those described above for the tiles output.

Povray Output

Running

   lcng -o povray system
produces a file system.pov containing a POV-Ray scene description. Display this with, for example
   povray +P +H720 +W1280 system.pov
The scene is generated with a 16:9 aspect ratio with the camera pointing at the centroid. You will probably want to edit system.pov to adjust the view point, lighting, colours, textures, and so on.

gEDA Symbol Output

Running lcng with option -m geda will generate a file called system.sym which contains a schematic symbol in gEDA format for use with the gschem schematic capture program. The symbol includes all the pin sequence information required to simply insert the system model into your overall schematic.

You can manually edit the symbol to fine-adjust the layout with

   gschem system.sym
but make sure you don't modify the pinseq values. These numbers ensure that the correct connections to the sub-circuit are used in the Spice netlist. After editing the symbol you must run the option Edit -> Symbol Translate... and translate to zero offset before saving.

You may need to edit or create the file ~/.gEDA/gafrc and include your working directory in the search path for component symbols with the line

   (component-library "/your/lcng/directory")
After restarting gschem you should find system.sym in the component library. It needs two attributes setting: value=system and file=system.spice.

You don't need to regenerate the symbol if you alter the dimensions of the system. But if you add or remove any coils or electrodes, or change their order in the input file, then you must produce a new schematic symbol because the sequence and number of connections to the sub-circuit will have altered.

Examples

The shell script test provided in the distribution runs a series of test cases to check that everything is working properly. The script contains plenty of example input files for simple cases and systems.

Some more complete systems are given below as examples. The examples all use ngspice for modelling.

Principle of Operation

Capacitance

The electrode and coil surfaces are decomposed into a large number of small tiles. The electric field at the center of each tile is calculated using Coulomb's law as a function of the charge on all the tiles. The resulting large potential matrix is then partially inverted to produce a capacitance matrix for all the electrodes and coil sections.

Inductance

The coils are decomposed into a large number of circular or polygonal filaments. The mutual inductance between every pair of filaments is calculated by integration of the vector potential. Elements of the resulting inductance matrix are then summed and scaled by the actual number of turns to obtain the inductance matrix which relates each coil section.

Ground Plane

The electric and magnetic effects of the infinite ground plane are modelled using the method of images.

Limitations

Limitations of the current version are:

Authors and Contributers

Software

Pieter-Tjerk de Boer PA3FWM, Enschede, Netherlands;
Paul Nicholson, Todmorden, UK;

Test measurements

Bart Anderson, USA;
Marco Denicolai, Finland;
Renato Romero IK1QFK, Cumiana, Italy;
Markus Vester DF6NM, Nuernberg, Germany;


Maintained by Paul Nicholson lcng01@abelian.org