Skip to content

Latest commit

 

History

History
847 lines (632 loc) · 43.5 KB

File metadata and controls

847 lines (632 loc) · 43.5 KB

The FDTD-JSON format

This format aims to provide a way to input data for a full FDTD simulation. Being in JSON, it can be easily navigated with most text editors, such as Visual Studio Code or Notepad++. There are also multiple tools to read and write them. This document assumes that you are familiar with the basic JSON notation, a brief explanation on this notation can be found here.

The following are examples of valid inputs:

  1. An empty space illuminated by a plane wave: planewave.fdtd.json. The field at a point close to the center is recorded.
  2. A thin straight wire illuminated by a plane wave: holland1981.fdtd.json which aims to replicate the case described in https://doi.org/10.1109/TEMC.1981.303899. It contains a probe which records the wire at the middle of the wire.
  3. A current injection which mimics a lightning strike on a square metallic surface: currentinjection.fdtd.json. It contains two bulk current probes to measure the current at the entry and exit lines.
  4. A shielded pair of wires fed by a voltage source in one of its ends: shieldedPair.fdtd.json. The interior of the shield uses a multiconductor transmission line (MTL) algorithm to evolve the common mode currents which are induced in the shield and propagated inside using a transfer impedance.
  5. A multiconductor transmission line network (MTLN) case which includes three cable bundles with a shared junction: mtln.fdtd.json.

FDTD-JSON objects description

All units are assumed to be SI-MKS, except when specified otherwise.

Angle brackets surrounding an entry, as in <entry>, indicate that that entry is mandatory. Square brackets, as in [entry], are optional entries.

The following entries are shared by several FDTD-JSON objects and have a common description:

  • type followed by a string, indicates the type of JSON object that. Some examples of types are planewave for sources objects, and polyline for elements.
  • id is a unique integer identifier for objects that belong to a list and which can be referenced by other objects. For instance, an element in the elements list must contain a id which can be referenced by a source in sources through its list of elementIds.
  • [name] is an optional entry which is used to make the FDTD-JSON input human-readable, helping to identify inputs and outputs. Leading and trailing blank spaces are removed. Blank spaces are substituted by underscores. The following characters are reserved and can't be used in a name: @.

<general>

This object must always be present and contains general information regarding the solver. It must contain the following entries:

  • [timeStep]: A real number indicating the time step used by the solver, in seconds. If not specified, one will be automatically computed ensuring stability.
  • <numberOfSteps>: An integer for the number of steps which the solver will iterate.

Additionally, it may contain the following optional entry:

  • <mtlnProblem> : A boolean indicating whether the problem is a pure MTLN problem and will solved using only the MTLN solver. If it is not present, its default value is false
  • <additionalArguments> : A string with flags. Keep in mind that flags passed by console have higher priority.

Example:

"general": {
    "timeStep": 10e-12,
    "numberOfSteps": 2000,
    "additionalArguments": "-mapvtk -sgbc"
}

[background]

This object sets the background electromagnetic media properties to an specified value it can contain the following objects entries:

  • [absolutePermittivity]: a real number indicating the value of background permittivity. Defaults to the value specified in EPSILON_VACUUM at fdtypes.F90.
  • [absolutePermeability]: a real number indicating the value of background permeability. Defaults to the value specified in MU_VACUUM at fdtypes.F90.

[boundary]

This specifies the boundaries which will be used to terminate the computational domain. If boundary is not present it defaults to a mur absorbing condition in all bounds. The entries within boundary are objects labeled with the place where they will be applied:

  • all, or
  • xLower, xUpper, yLower, yUpper, zLower zUpper.

These objects must contain a <type> label which can be:

  • pec for perfectly electric conducting termination.

  • pmc for perfectly magnetic conducting termination.

  • periodic for periodic boundary conditions. Must be paired with the opposite side.

  • mur for Mur's first order absorbing boundary condition.

  • pml for perfectly matched layer termination. If this type is selected, it must also contain:

    • [layers]: with an integer indicating the number of pml layers which will be used. Defaults to $10$ layers
    • [order]: an integer indicating the order of the profile. defaults to order $2$.
    • [reflection]: Computed reflection coefficient, defaults to $0.001$.

Example:

"boundary": {
    "all": {
        "type": "pml",
        "layers": 6, 
        "order": 2.0,
        "reflection": 0.001
    }
}

<mesh>

All the geometrical information of the simulation case is exclusively stored by the mesh object. It is a JSON object which contains three objects: a <grid>, a list of [coordinates] and a list of [elements].

"mesh": {
    "grid": { ... },       
    "coordinates": [ ... ],
    "elements": [ ... ]    
}

<grid>

The grid object represents a collection of rectangular cuboids or cells which tessellate the space to form a structured mesh. This object is defined with the following entries:

  • <numberOfCells> is an array of three positive integers which indicate the number of cells in each Cartesian direction.
  • <steps> is an object which contains three arrays, labeled with <x>, <y> and <z> which represent the cell sizes, expressed in meters, in that direction. Each array may contain a single real to define a regular grid; or, alternatively, a number of reals equal to the number of cells to define a rectilinear grid.
  • [origin] is an array of three reals marking the position of the lowest vertex of the $(0, 0, 0)$ cell. Defaults to [0.0, 0.0, 0.0].

The following example describes a regular grid with $20$, $20$, and $22$ cells in the $x$, $y$, and $z$ directions respectively.

"mesh": {
    "grid": {
        "numberOfCells": [20, 20, 22], 
        "steps": { "x": [0.1], "y": [0.1], "z": [0.1] }
    }
}

[coordinates]

This is an array of objects which represent Cartesian coordinates within the grid. Each object of the array must contain the following entries:

  • <id>: an integer number that must be unique within this array.
  • <relativePosition>: Containing an array of 3 numbers which can be integers or reals. The whole part of the number indicates the cell and the fractional part indicates the fractional position within that cell.

Example: The following figure represents a grid with the numbers of the cells marked in light gray. The third dimension is ignored for clarity. The two coordinates (blue) represent positions in the grid. Note that coordinate 2 has a fractional position in the $x$ direction.

Coordinates in grid

"mesh": {
    "grid": {
        "numberOfCells": [8, 5, 1], 
        "steps": { "x": [0.1], "y": [0.1], "z": [0.1] }
    }
    "coordinates": [
        {"id": 1, "relativePosition": [2, 2, 0]},
        {"id": 2, "relativePosition": [3.4, 1, 0]}
    ]
}

[elements]

The elements entry contains an array of JSON objects, each of which represents a geometrical entity. Within the context of this format specification, an element can be a relatively simple entity such as node or a polyline, but it can also be a much more complex geometrical entity such as a cell. An element objects must contain the entries

  • <id> formed by an integer which uniquely identifies it within the elements array.

  • <type> which can be one of the following:

    • node, representing a point in space. Elements with this type include a <coordinateIds> entry which is an array of a single integer representing the id of a coordinate and which must exist in the within the mesh coordinates list.
    • polyline, representing an oriented collection of segments. It must contain a list <coordinateIds> with at least two coordinates.
    • cell, containing a list of one or more <intervals> defined following the interval convention.
      • If cell represents a conformal element it will contain a list of zero or more and a list of , describing a close outwards-pointing surface.
      • In this case, the cell must contain an entry subtype, which can be surface or volume, according to the dimension of the geometrical entity.

Below there is an example of a mesh object which includes several types of elements.

"mesh": {
    "grid": {
        "numberOfCells": [20, 20, 22],
        "steps": { "x": [0.1], "y": [0.1], "z": [0.1] }
    },
    "coordinates": [
        {"id": 1, "relativePosition": [11, 11,  7]},
        {"id": 2, "relativePosition": [11, 11, 12]},
        {"id": 3, "relativePosition": [11, 11, 17]}
    ],
    "elements": [
        {"id": 1, "type": "node", "coordinateIds": [2]},
        {"id": 2, "type": "polyline", "coordinateIds": [1, 2, 3] },
        {"id": 3, "type": "cell", "intervals": [ [ [1, 1, 1], [19, 19, 21] ] ] }
        {"id": 4, "type": "conformalVolume", "intervals": [ [ [1, 1, 1], [19, 19, 21] ] ], "triangles" : [[1,2,3]] }
    ]
}
The interval convention

A interval is defined by a pair of two triplets of integer numbers $\mathbf{a} = {a_x, a_y, a_z}$ and $\mathbf{b} = {b_x, b_y, b_z}$. Each of these triplets refers to a cell and the combination of the two represents a region formed by the closed-open intervals $[a_x, b_x) \times [a_y, b_y) \times [a_z, b_z)$. The size of the interval is defined as $|a_x - b_x| \times |a_y - b_y| \times |a_z - b_z|$ and therefore must be positive or zero. An interval allows specifying regions within the grid which can be a point, an oriented line, an oriented surface, or a volume:

  • A point is defined when $\mathbf{a} = \mathbf{b}$, i.e. the intersection of three grid planes. Points have no orientation.

  • An oriented line is defined when the interval has the same initial and ending values in all directions except one, for instance $a_x \neq b_x$. In this case there are two possibilities:

    • when $(b_x - a_x) &gt; 0$, the line is oriented towards $+\hat{x}$.
    • when $(b_x - a_x) &lt; 0$, the line is oriented towards $-\hat{x}$.
  • An oriented surface is defined when one initial and ending value is the same and the other two are different, e.g. $a_x = b_x$, $a_y \neq b_y$, $a_z \neq b_z$. In this case there are four possibilities:

    • when the $(b_y - a_y) &gt; 0$ and $(b_z - a_z) &gt; 0$, the surface normal is assumed to be oriented towards $+\hat{x}$.
    • when the $(b_y - a_y) &lt; 0$ and $(b_z - a_z) &lt; 0$, the surface normal is assumed to be oriented towards $-\hat{x}$.
    • The other two cases, in which there is a mix of positive and negative signs, are undefined.
  • A volume is defined when each component of $\mathbf{a}$ is strictly smaller than the corresponding component in $\mathbf{b}$ for each direction, i.e. $a_x &lt; b_x$, $a_y &lt; b_y$, and $a_z &lt; b_z$. The rest of the cases in which all numbers are different but not necessarily smaller are undefined.

Example: The following figure represents a grid with the numbers of the cells marked in light gray. The third dimension is ignored for clarity. There are four cell elements.

  • The first one represents a single rectangular surface with its normal oriented towards the $+\hat{z}$ direction (light green).
  • The second one is formed by an square surface oriented towards the $-\hat{z}$ direction (light red) and a line oriented towards $-\hat{x}$.
  • The third is formed by two oriented lines towards $+\hat{x}$ and $+\hat{y}$, respectively.
  • Finally, the fourth cell is formed by a single line, oriented towards $-\hat{y}$.

Intervals example

"mesh": {
    "grid": {
        "numberOfCells": [8, 5, 1], 
        "steps": { "x": [0.1], "y": [0.1], "z": [0.1] }
    }
    "elements": [
        {"id": 1, "type": "cell", "intervals": [ [[1,1,0], [2,3,0]] ]},
        {"id": 2, "type": "cell", "intervals": [ [[3,5,0], [2,4,0]],
                                                       [[5,4,0], [3,4,0]] ]},
        {"id": 3, "type": "cell", "intervals": [ [[3,2,0], [5,2,0]],
                                                       [[5,2,0], [5,3,0]] ]},
        {"id": 4, "type": "cell", "intervals": [ [[7,3,0], [7,0,0]] ]},
    ]
}
Triangles

Each triangle is a list of three <coordinateId>, representing the vertices of the triangle. Vertices have to be oriented so the normal of each triangle points outwards the volume.

[materials]

This entry is an array formed by all the physical models contained in the simulation. Each object within the array must contain:

  • <id>, an integer number that uniquely identifies the material.
  • <type>, with one of the allowed labels described below.

Bulk materials

pec and pmc

These materials represent a perfectly electrically conducting (pec) and perfectly magnetically conducting (pmc).

Example:

"materials": [ {"id": 1, "type": "pec"} ]

isotropic

A material with type isotropic represents an isotropic material with constant (not frequency dependent) relative permittivity $\varepsilon_r$, relative permeability $\mu_r$, electric conductivity $\sigma$ and/or magnetic conductivity $\sigma_m$:

  • [relativePermittivity] is a real which defaults to $1.0$. Must be greater than $1.0$.
  • [relativePermeability] is a real which defaults to $1.0$. Must be greater than $1.0$.
  • [electricConductivity] is a real which defaults to $0.0$. Must be greater than $0.0$.
  • [magneticConductivity] is a real which defaults to $0.0$. Must be greater than $0.0$.

Example:

{
    "name": "teflon",
    "id": 1, 
    "type": "isotropic",
    "relativePermittivity": 2.5,
    "electricConducitivity": 1e-6
} 

lumped

A material with type lumped represents a lumped circuit model, e.g a resistor. Lumped materials can only be assigned to cell elements with intervals describing oriented lines. If multiple cells are assigned to a lumped element, only the first one of them will be treated as a lumped by the solver, the other cells will be treated as a PEC material. The specific behavior is described using the <model> keyword, described below. resistor, inductor and capacitor are based, with some additions, on the following reference

    Liu, Y., Mittra, R., Su, T., Yang, X., & Yu, W. (2006). Parallel finite-difference time-domain method. Artech.
    Chapter 3, Section 5.

resistor model

Defined by:

  • <resistance> a positive real number.
  • [startingTime] and [endTime] are the times in which the resistor will be active. Default to $0.0$ and $1.0$ seconds, respectively. When deactivated, the backgroung material properties will be used, i.e. the edge will be equivalent to an open circuit at low frequencies.

Example:

{
    "name": "100_ohm_resistor",
    "id": 1, 
    "type": "lumped",
    "model": "resistor",
    "resistance": 100,
    "startingTime": 0.0,
    "endTime": 1.0
} 

inductor model

A series $LR$ circuit, $R$ is optional:

  • <inductance> a positive real number
  • [resistance] a positive or zero real number. Defaults to $0.0$.

capacitor model

A parallel $CR$ circuit:

  • <capacitance> a positive real number
  • <resistance> a positive real number.

multilayeredSurface

A multilayeredSurface must contain the entry <layers> which is an array indicating materials which are described in the same way as isotropic materials and a <thickness>. Its elementIds must reference cell elements. All intervals modeling entities different to oriented surfaces are ignored.

{
    "name": "Composite",
    "type": "multilayeredSurface",
    "id": 2,
    "layers": [
        {"thickness": 1e-3, "relativePermittivity": 1.3, "electricConductivity": 2e-4},
        {"thickness": 5e-3, "relativePermittivity": 1.3},
        {"thickness": 1e-3, "relativePermittivity": 1.3, "electricConductivity": 2e-4}
    ]
}

thinSlot

A thinSlot represents a gap between two conductive surfaces. Therefore it must be located at a surface and be defined using line cell elements only. Its <width> is a real number which defines the distance between the surfaces in meters.

{
    "name": "3mm-gap",
    "type": "thinSlot",
    "id": 2,
    "width": 3e-3
}

wire

A wire, or thin wire, represents an electrically conducting wire-like structure with a radius much smaller than the surrounding cell sizes. Materials of type wire can only be defined if the compilation flag for MTLN was OFF, i.e. SEMBA_FDTD_ENABLE_MTLN = OFF. Otherwise, the program execution will fail at runtime. These structures are solved by an algorithm similar to the one described in:

R. Holland and L. Simpson, 
"Finite-Difference Analysis of EMP Coupling to Thin Struts and Wires," 
IEEE Transactions on Electromagnetic Compatibility, vol. EMC-23, no. 2, pp. 88-97, May 1981,
doi: 10.1109/TEMC.1981.303899.

Materials of this type must contain:

  • <radius> as a real number.
  • <resistancePerMeter> as a real number.
  • [inductancePerMeter] as a real number. Defaults to 0.0.

Example:

{
    "name": "Shield",
    "id": 2,
    "type": "wire",
    "radius": 0.0001,
    "resistancePerMeter": 22.9e-3
}

shieldedMultiwire

A shieldedMultiwire, models $N+1$ electrical wires inside a bundled. The voltages and currents on these wires are solved by a multiconductor transmission lines (MTLN) solver described in:

Paul, C. R. (2007). Analysis of multiconductor transmission lines. John Wiley & Sons.

shieldedMultiwire materials are assumed to be contained within an unshieldedMultiwire or another shieldedMultiwire which is the external domain and is used as voltage reference. Materials of type shieldedMultiwire and unshieldedMultiwre can only be defined if the compilation flag for MTLN was ON, i.e. SEMBA_FDTD_ENABLE_MTLN = ON. Otherwise, the program execution will fail at runtime. They must contain the following entries:

  • <inductancePerMeter> and <capacitancePerMeter> which must be matrices with a size $N \times N$. If the number of wires is equal to $1$, this property must be a $1 \times 1$ matrix, e.g [[1e-7]]
  • [resistancePerMeter] and [conductancePerMeter] which must be arrays of size $N$. Defaults to zero. If the number of wires is equal to $1$, must be an array of size $1$, e.g. [50].
  • [transferImpedancePerMeter] which represents the coupling with the external domain, described below. If not present, it defaults to zero, i.e. perfect shielding.

transferImpedancePerMeter can contain:

  • [resistiveTerm] defined by a real representing transfer impedance resistance. Defaults to 0.0
  • [inductiveTerm] defined by a real representing transfer impedance inductance. Defaults to 0.0.
  • [direction] which can be both, inwards, or outwards. Indicating the type of coupling considered. Defaults to both meaning that fields can couple from the exterior to interior and the other way round.

Example:

{
    "name": "Bundle_2_level_2",
    "id": 62,
    "type": "shieldedMultiwire",
    "resistancePerMeter" : [62.0e-3,62.0e-3],
    "inductancePerMeter": [
        [2.4382084E-07, 4.7377505E-08],
        [4.7377508E-08, 2.4382081E-07]
    ],
    "capacitancePerMeter": [
        [105.5e-12, -20.5e-12],
        [-20.5e-12, 105.5e-12 ]
    ],
    "transferImpedancePerMeter" : {
        "inductiveTerm" : 4.2e-9,
        "direction" : "inwards"
    }
}

unshieldedMultiwire

A unshieldedMultiwire, models a bundle of $N$ electrical wires. The charges and currents on these wires are solved using the model described in:

Berenger, J. P. A Multiwire formalism for the FDTD Method. IEEE Transactions on Electromagnetic Compatibility. August, 2000.

They must contain the following entries:

  • <inCellParameters> which can be defined in two ways:
    • By fixed values defined in inductancePerMeter and capacitancePerMeter which must be matrices with a size $N \times N$. If the number of wires is equal to $1$, this property must be a $1 \times 1$ matrix, e.g [[1e-7]].
    • By a multipolarExpansion object which allows to calculate the in-cell inductances and capacitances. This object can be obtained using the opensemba/pulmtln tool containing:
      • An <innerRegionBox> object, containing two pairs of real numbers, named min and max which describe a cross sectional bounding box. This box must contain all the conductors and dielectrics which form the bundle cross section. It also must be smaller or equal than the minimum side of the FDTD dual cells which are crossed by the bundle.
      • Two arrays, <electric> and <magnetic> in which each contain a field reconstruction object described below. They must contain a $N$ multipolar expansions, one for each conductor. Each entry assumes that the $n$-th conductor has a prescribed potential of $1 , \text{V}$ and the rest are floating.
  • [resistancePerMeter] and [conductancePerMeter] which must be arrays of size $N$. Defaults to zero. If the number of wires is equal to $1$, must be an array of size $1$, e.g. [50].

Field reconstruction

The field reconstruction objects contains information necessary to calculate the in-cell parameters for an unshieldedMultiwire with $N$ conductors. The electric and magneticpotentials are used to compute the in-cell capacitances and in-cell inductances, respectively. Each contains information to perform a multipolar expansion based on

Tsogtgerel Gantumur. Multipole Expansions in the plane. 2016, lecture notes. 

and which must contain

  • <conductorPotentials> is an array of size $N$ indicating the potentials for each conductor. The $n$-th entry of this array should be equal to $1$, for the active conductor, and less than one for the rest (floating conductors).
  • <ab> which is an array of $P$ pairs of real numbers $(a_p, b_p)$, which are the pole coefficients of the field expansion when the $n$-th conductor is active.
  • <expansionCenter> is an pair of real numbers indicating the place in which the dipole moment is zero, a concept similar to the center of charge.
  • <innerRegionAveragePotential> is the potential averaged within the innerRegionBox. The multipolar expansion only valid outside the inner region.

terminal

A terminal models a lumped circuit which is assumed to located at one end of a wire, shieldedMultiwire or unshieldedMultiwire. Terminals are assumed to be assigned on points and therefore have zero dimension.

  • If the terminal is associated with a wire or unshieldedMultiwire, the terminations array must contain a termination for each conductor.
  • In the case it is associated with a $N+1$ conductors shieldedMultiwire, the terminations array must contain $N$ entries.

Each entry in terminations is specified by a type

  • short if the wire is short-circuited with another wire or with any surface which might be present.
  • open if the wire does not end in an ohmic contact with any other structure.
  • Different configurations of passive circuit elements R, L, and C can be defined:
    • series (for RLC series circuits),
    • parallel (for RLC parallel circuits),
    • RsLCp (LC parallel in series with R),
    • RLsCp (RL series in parallel with C),
    • LsRCp (RC parallel in series with L),
    • CsLRp (LR parallel in parallel with C),
    • RCsLp (RC series in parallel with L), and
    • LCsRp (LC series in parallel with R).

The values are defined defined as follows:

  • [resistance] which defaults to 0.0,
  • [inductance] which defaults to 0.0,
  • [capacitance] which defaults to 1e22.
  • 2-terminals SPICE models can used in a termination. In this case the type is circuit, and is defined with:
    • [file] which is the name of the file where the SPICE model is defined
    • [name] which is the name of the subcircuit as defined inside file
    • [terminal] which is the number of the subcircuit terminals the termination is connected to. It can be equal to 1 or 2, depending on the side of the SPICE model the termination is connected to. By default it equals 1, meaning that the termination is connected to the first external node in the netlist definition
  • N-terminals SPICE models can be used to connect a series of terminations to a subcircuit. The type is network, and is defined with:
    • [file] which is the name of the file where the SPICE model is defined
    • [name] which is the name of the subcircuit as defined inside file
    • [node] which is the subcircuit node the termination is connected to. Generally, subcircuits will have their terminals external nodes named in non-numerical way. [node] is an integer that refers to the position of the node in the netlist

Example:

{
    "name": "shieldTerminal",
    "id": 4,
    "type": "terminal",
    "terminations": [ {"type": "series", "resistance": 50.0} ]
}

SPICE terminations

There are two types of SPICE terminations, circuit and network. circuit terminations are equivalent to 2-terminal networks. The netlist representing the connection can be composed of an arbitrary number of components, but it must have only two external nodes.

Example:

{
    "name": "SpiceTerminal",
    "id": 5,
    "type": "terminal",
    "terminations": [ {"type": "circuit", "file": "ListOfComponents.lib", "name": "Component_1"} ]
}

ListOfComponents.lib is a file where one or more SPICE subcircuits (definitions beggining with .subckt) are defined. The file does not need to contain only the subcircuit that is going to be used in the termination. The particular subcircuit among those defined in the file is selected using the key name.

network represent a series of wires connected to the same circuit. The subcircuit node that the wire is connected to is defined with the keyword node:

{
    "name" : "NetworkTerminal",
    "id" : 5,
    "type" : "terminal", 
    "terminations" : [ {"type": "network", "file": "ListOfComponents.lib", "name": "Component_2", "node" : 1},
                       {"type": "network", "file": "ListOfComponents.lib", "name": "Component_2", "node" : 2},
                       {"type": "network", "file": "ListOfComponents.lib", "name": "Component_2", "node" : 3} ]
}

In this case, the three wires of a e-conductor cable are connected to the nodes of a subcircuit. This circuit might have more external nodes, connected to wires in another cable.

connector

The connector represents the physical connection of a bundle to a structure. connector assigns properties to the initial or last segment of a wire, a shieldedMultiwire or an unshieldedMultiwire. The connector can have the following properties:

  • [resistances], an array of real numbers which will be converted to resistances per unit length and will replace the resistancePerMeter of that segment.
  • [transferImpedancesPerMeter], an array of [transferImpedancePerMeter], as described in the shieldedMultiwire section.

The most common situation will be having the connector of a shielded bundle. In that case, the arrays have a single component. However, the connector can describe the connections of a (unshielded) bundle of $N$ shielded conductors. In that case, the connector has to describe the connections, if any, of the $N$ shielded conductors.

Example:

{
    "name": "SegmentConnector",
    "id": 204,
    "type": "connector",
    "resistances": [100e-3],
    "transferImpedancesPerMeter" : [
        {
        "resistiveTerm" : 3.33,
        "inductiveTerm" : 2.6e-9,
        "direction" : "inwards"
        }
    ]
}

[materialAssociations]

This entry stores associations between materials and elements using their respective ids as follows:

  • <materialId>: A single integer indicating the id of a material which must be present in the materials list.
  • <elementIds>: A list of ids of the elements to which this material will be associated.

Material associations with bulk or surface materials such as pec, pmc or isotropic can be assigned to one or many elements of type cell. If the cell contains intervals representing points, these will be ignored.

"materialAssociations": [
    {"materialId": 1, "elementIds": [2]},
    {"materialId": 1, "elementIds": [3]}
]

Associations with cables can contain the following inputs:

  • <initialTerminalId> and <endTerminalId> which must be present within the materials list of type. These entries indicate the lumped circuits connected at the ends of the cable.
  • [initialConnectorId] and [endConnectorId] entries which must point to materials of type connector and are assigned to the last segments of the corresponding ends of the cable.
  • Its materialId must point to a wire, a shieldedMultiwire or an unshieldedMultiwire material. If it points to a shieldedMultiwire, it must also contain an entry named <containedWithinElementId> which indicates the polyline in which this shieldedMultiwire is embedded.

Example:

{
    "name": "line_0_0",
    "elementIds": [ 1 ],
    "materialId": 10,
    "initialTerminalId": 20,
    "endTerminalId": 7,
    "initialConnectorId": 24
}

[probes]

The objects in the probes array define the outputs of the simulation. Each probe must contain:

  • A <type> of the ones described below.
  • <elementIds> indicating the place in which the probe is defined. The allowed elements depend on the particular probe type.
  • A [domain] as described in the domain section

Probe types

point

Records a vector field a single position referenced by elementIds which must contain a single id referencing an element of type node. The vector field to be recorded is selected using the following entries:

  • [field], electric or magnetic. Defaults to electric.
  • [directions] which contains a list of the field components to be recorded. Defaults to ["x", "y", "z"].

Example:

{
    "name": "electric_field_point_probe",
    "type": "point",
    "field": "electric",
    "elementIds": [1],
    "directions": ["x", "y", "z"],
    "domain": { "type": "time" }
}

wire

Records a scalar field at a single position referenced by elementIds. elementIds must contain a single id referencing an element of type node. Additionally, this node must point to a coordinateId belonging to at least one polyline. If the node's coordinateId is shared by more than one polyline a probe will be defined for each one of them The [field] can be voltage, current or charge (defaults to current). Voltage probes are properly defined only when used placed on shieldedMultiwires. The voltage on a conductor will be referred to the shield surrounding that conductor. In an unshielded wire, there is not a well defined reference, and thus the probe is not reliable. Charge probes are implemented only for wires not treated with the MTL module.

When current is selected, the orientation of the polyline on which the probe is located indicates the direction of the current. Voltages are well defined at polyline points. However, currents are defined over segments so:

  • If the point is in the interior of the wire, the output will be an average on the currents of the segments which are contiguous to it.
  • If the point is at one wire end, the current will be the output of the last segment.
{
    "name": "mid_point",
    "type": "wire",
    "field": "voltage",
    "elementIds": [1]
}

bulkCurrent

Performs a loop integral along on the contour of the surface reference in the elementIds entry. This must point to a single cell containing a single interval which is used to define one or several surfaces. These surfaces are build by enlarging half grid step in the directions perpendicular to the entry direction which can take one of the following values: x, y or z. Depending on the type of interval, direction can be assumed (and therefore is optional), or not, specifically:

  • If it is a point or a volume, direction must be present.
  • For an oriented line, direction is optional and the orientation of the line will be used as default.
  • For an oriented surface, direction is also optional, and if not value is given it is assumed to be the the positive axis of the surface normal.

Due to Ampere's law, the loop integral of the magnetic field is equal to the total electric current passing through the surfaces. [field], can be electric or magnetic. Defaults to electric, which returns the total current passing through the surface.

In the following example elementId points an element describing a single oriented surface, therefore direction does not need to be stated explicitly.

{
    "name": "bulk_current_at_surface",
    "type": "bulkCurrent",
    "elementIds": [4]
}

In this example elementId points to a volume element, therefore direction must be present

{
    "name": "bulk_current_at_volume",
    "type": "bulkCurrent",
    "elementIds": [8],
    "direction": "x"
}

One important aspect to keep in mind when working with bulkCurrent with electric field type is its natural offset. This arises from the fact that to measure the electric current it is necessary to calculate the closed path integral of the magnetic field, then, the electric current is defined on the dual mesh of the inserted grid -- i.e., the mesh corresponding to the magnetic field. The dual mesh is constructed by placing a point at the center of each cell in the original (primal) mesh and connecting these points.

Because of this, the code internally shifts the bulkCurrent you define to align with the dual mesh, causing a half-cell offset. In the case of surfaces, the coordinates perpendicular to the current flowing through the surface experience a negative offset, as shown in the figure below:

Negative offset

If the current is flowing out of the page and the defined bulkCurrent corresponds to the blue surface, the algorithm will actually evaluate the current on the green surface. Mathematically, this can be interpreted as follows: if the bulkCurrent is defined as a rectangle with bounds [a, b] × [c, d], the measurement is performed on the half-open domain [a, b) × [c, d).

On the other hand, the coordinate parallel to the current also experiences a half-cell offset, but this time in the positive direction, as illustrated in the figure below:

Positive offset

Again, with the current flowing in the direction of the red line, the blue line represents a cross-sectional view of the plane where the bulkCurrent is defined, while the green line shows the actual location used for current evaluation by the method.

line

A line probe computes the electric field line integral along a given polyline. At low frequencies, this quantity can be equivalent to a DC voltage difference between the extremes of the line. At higher frequencies, "voltage" is no longer a proper name. The integral is performed along a geometric line, hence the polyline does not have to be associated with any material. [field] defaults to electric, the only field supported at this point. The probe is only valid in the time domain.

    {
        "name" : "vprobe",
        "type" : "line",
        "elementIds" : [4],
        "field" : "electric"
    }

farField

Probes of type farField perform a near to far field transformation of the electric and magnetic vector fields and are typically located in the scattered field region which is defined by a total/scattered field excitation, e.g. a planewave. They must be defined with a single cell element which must contain a single interval defining a cuboid. The direction of the radiated field $\hat{r}(\theta, \phi)$ is defined with <theta> and <phi>, which must contain <initial>, <final>, and <step>, expressed in degrees. The domain of a farField probe can only be of type frequency. If not magnitudeFile is specified and only one source is defined, the magnitudeFile of that source will be used to calculate as normalizing function.

{
    "name": "far_field_example",
    "type": "farField",
    "elementIds": [4],
    "theta": {"initial": 0, "final": 180, "step": 10},
    "phi": {"initial": 0, "final": 0, "step": 0},
    "domain": {
        "type": "frequency",
        "initialFrequency": 1e6,
        "finalFrequency": 1e9,
        "numberOfFrequencies": 30,
        "frequencySpacing": "logarithmic"
    }
}

movie

Probes of type movie record a vector field in a volume region indicated by elementIds. [field] can be electric, magnetic, or currentDensity; defaults to electric. currentDensity will store only the surface density currents on pec or lossy surfaces. For movies in time domain, the initialTime, finalTime, and samplingPeriod must be specified by the user; there is no default value.
The stored values can be selected using the [component] entry, which stores one of the following labels x, y, z, or magnitude; if no component is specified, defaults to magnitude.

An example follows:

{
    "name": "electric_field_movie",
    "type": "movie",
    "field": "electric",
    "component": "x",
    "elementIds": [4]
}

[domain]

If domain is not specified, it defaults to a time domain recording from the beginning to the end of the simulation. The domain must specify a <type> from the following ones:

  • time, means recording only in time domain. A probe with a domain of this type can contain the following entries:

    • [initialTime], the probe will be active for times greater than or equal to the selected value. Defaults to 0.0.
    • [finalTime], the probe will be active for times smaller than the selected value. Defaults to the final time of the simulation.
    • [samplingPeriod]. Defaults to the simulation time step which is the minimum sampling period.
  • frequency, means that the output will be converted into the frequency domain.

    • <initialFrequency>, <finalFrequency> as real numbers, and <numberOfFrequencies> as an integer.
    • [frequencySpacing] can be linear or logarithmic. Defaults to linear.
  • timeFrequency will record both time and frequency.

Additionally, a domain can contain a [magnitudeFile] as specified in sources. This file will be used as to compute a transfer function between the recorded output and the specified magnitude.

[sources]

This entry is an array which stores all the electromagnetic sources of the simulation case. Each source is a JSON object which must contain the following entries:

  • <magnitudeFile> contains a relative path to the plain text file which will be used as a magnitude for this source. This file must contain two columns, with the first stating the time and the second one the magnitude value; an example magnitude file can be found at gauss.exc.
  • <type> must be a label of the ones defined below. Some examples of source type are planewave or nodalSource.
  • <elementIds> is an array of integers which must exist within the mesh elements list. These indicate the geometrical place where this source is located. The type and number of the allowed elements depends on the source type and can be check in the descriptions of each source object, below.

planewave

The planewave type represents an electromagnetic wave with a plane phase-front which propagates towards a $\hat{k}$ direction and with an electric field pointing towards $\hat{E}$. elementIds must point to a single cell element formed by a single cuboid region which defines the total and scattered field regions, respectively. Besides the other common entries in sources, it must also contain the following ones:

  • <direction>, is an object containing <theta> and <phi>, which are the angles of the propagation vector $\hat{k} (\theta, \phi)$.
  • <polarization>, is an object containing <theta> and <phi> which indicates the direction of the electric field vector $\hat{E}(\theta, \phi)$.

An example of a planewave propagating towards $\hat{z}$ and polarized in the $+\hat{x}$ follows,

{
    "type": "planewave",
    "magnitudeFile": "gauss.exc",
    "elementIds": [2],
    "direction": {
        "theta": 0.0,
        "phi": 0.0
    },
    "polarization": {
        "theta": 1.5708,
        "phi": 0.0
    }
}

nodalSource

This object represents a time-varying vector field applied along an oriented line with the same orientation of the line. Therefore, the elementIds within must contain only elements of type cell with intervals describing a collection of oriented lines. Additionally, it may contain:

  • [field] with a current label which indicates the vector field which will be applied. If not present, it defaults to current.
  • [hardness] with soft or hard label. A soft hardness indicated that the magnitude will be added to the field this situation is typical for a waveport. hard sources mean that the field is substituted by the value established by the magnitudeFile, which for an electric field nodalSource would be equivalent to a pec material if the magnitude is zero.

Example:

{
    "name": "entry_line_curent",
    "type": "nodalSource", 
    "magnitudeFile": "gauss.exc", 
    "elementIds": [1],
    "hardness": "soft"
}

generator

A generator source must be located on a single node whose coordinateId is used by a single polyline. The entry [field] can be voltage or current; defaults to voltage.

Example:

{
    "name": "voltage_source",
    "type": "generator",
    "field": "current",
    "magnitudeFile": "gauss.exc", 
    "elementIds": [1]
}

Using classic wires, generators can be located on any node of the lines. Using MTLN wires there are some restrictions:

Syntax unshieldedMultiwire shieldedMultiwire
Voltage Only wire extremes Any point
Current Any point Only wire extremes

In case a generator is on a wire extreme, the current direction will be from the generator in the direction of the other wire extreme. If the generator is on an interior wire point, the current direction will be oriented as the wire.

In case the generator is located at the junction (connection point) of two of more lines, the node shared by the lines will share the same coordinateId. If more than two lines are connected together, it is necessary to know to which of the lines the generator is connected to. The entry [attachedToLineId] is an integer which refers to the elementId of the polyline the source is connected to.

Example:

{
    "name": "voltage_source",
    "type": "generator",
    "field": "voltage",
    "magnitudeFile": "gauss.exc", 
    "elementIds": [1], 
    "attachedToLineId" : 2
}