expanded lumped elements
Adding support for simple RLC circuits as lumped elements, as well as more generalized networks that are described by an admittance transfer function in the Laplace domain. These elements get directly translated into equivalent PoleResidue medium given their admittance and geometric dimensions.
Implementation follows the LumpedResistor as far as how the lumped elements are added to the simulation, but allows for arbitrary networks. The formulation for the equivalent medium properties starts from the desired VI admittance $Y(s)$ relationship in the Laplace domain.
$$I(s) = Y(s)V(s)$$
Assume we connect the lumped element, so that the voltage drop is along the $z$ axis in a grid cell with $\Delta x$, $\Delta y$, $\Delta z$. Then, a current density associated with the lumped element $J_L$ and the electric field in the cell $$E(s)$$ can be related through $Y(s)$ as
$$J_{L}(s) = \frac{\Delta z}{\Delta x \Delta y} Y(s)E(s)$$
Assuming $Y(s)$ is causal, we replace $s$ with $j \omega$, which allows $J_L$ to be added to the FDTD update equations just like the polarization current densities used to model dispersive media. So all we need to do is put $\frac{\Delta z}{\Delta x \Delta y} Y(s)$ into the same format as the PoleResidue medium, which starts with converting the complex conductivity $\frac{\Delta z}{\Delta x \Delta y} Y(j \omega)$ into an equivalent complex permittivity. Then, we compute a partial fraction expansion to retrieve the poles and residues.
A couple of details:
- The lumped element can be distributed over multiple grid cells by scaling its admittance by the dimensions of the Box representing the lumped element. (Assuming E is constant within the box).
- The lumped element is represented by a Medium2D, so the scaling along the normal axis is factored in when the Medium2D is added to the simulation.
- A pure inductance either by itself or in parallel with the rest of a circuit requires modelling a lossless Drude medium with a second order pole at $\omega=0$. Currently, I add a bit of loss, so that it can be represented by a PoleResidue medium.
- Interestingly, a pure capacitance results in a non-dispersive medium which augments the background material by adding to $\varepsilon_\infty$
~~The first commit in this PR is from another PR being merged.~~
Maybe lets start with feedback from @QimingFlex and @weiliangjin2021 before we get @tylerflex to review.
First pass, all look quite good! Any notebook examples?
Forthcoming ... :smile:
@weiliangjin2021 @QimingFlex I have been considering modifying lumped elements so that they are a similar composition as Structure. Meaning that they are composed of a geometry with some additional details like voltage_axis and a circuit (instead of medium). Although right now the choice of geometry is limited either box or annulus in the special case of CoaxialLumpedResistor, it still might be nice for users to reuse the definition of a circuit in multiple places in the Simulation.
@dmarek-flex It looks good! I haven't had the chance to examine the RLC parameters as shown in the notebook in detail, but I'll do that if I have the time. One more question about _admittance_transfer_function_scaling: could we suggest a default box or handle this internally instead of asking users to define one? From the user's perspective, the lumped element should be dimensionless.
One more question about _admittance_transfer_function_scaling: could we suggest a default box or handle this internally instead of asking users to define one?
Users do not need to call this method directly, I need to have a Box parameter to handle the case when snapping is used and the precise geometry of the lumped element changes slightly.
I think that was your question :smile: . If you mean do we need users to define the size of the box of the lumped element to begin with, then the answer is yes. In the future we could have a better method that places a lumped element between two defined edges, but right now we need the user to size the Box correctly depending on how it is connected in the structure.
One more question about _admittance_transfer_function_scaling: could we suggest a default box or handle this internally instead of asking users to define one?
Users do not need to call this method directly, I need to have a
Boxparameter to handle the case when snapping is used and the precise geometry of the lumped element changes slightly.I think that was your question 😄 . If you mean do we need users to define the size of the box of the lumped element to begin with, then the answer is yes. In the future we could have a better method that places a lumped element between two defined edges, but right now we need the user to size the
Boxcorrectly depending on how it is connected in the structure.
Yeah, I mean the latter. I'm curious about how the box size would affect the final results. We can determine the optimal size internally in the future, so users won't need to define a box.
Yeah, I mean the latter. I'm curious about how the box size would affect the final results. We can determine the optimal size internally in the future, so users won't need to define a box.
So there are really 2 sizes that need to be determined 1) the size along the voltage axis, and 2) the lateral size, which is referred to as the current axis in the code. 1) is easy, it must be long enough to connect the two edges (e.g. the signal and ground of a microstrip). 2) is less obvious, but I have found that to get accurate results you need the element to be wide enough so that the current flows evenly from signal to ground, so you want the element to be wide enough so that it coincides with the region where the electric field is mostly uniform (e.g. make it as wide as the signal strip).
A more realistic choice is to size the box to roughly the size of the physical lumped element you would like to model by looking up its physical dimensions.
Since we had
LumpedResistoralready, I wonder if we shall haveLumpedCapacitorandLumpedInductor, even though they are just special cases of RLCNetwork?
The only reason I kept LumpedResistor was for backwards compatibility, I think RLCNetwork is a pretty simple interface that handles these cases, so I wasn't planning on add LumpedCapacitor and LumpedInductor .
I think the PR is close to its final state, so I invite ~@tylerflex~ @caseyflex to take a look too now. If it helps, you can take a look at my work in progress tutorial notebook .