Skip to content

Commit dd8b3e5

Browse files
authored
Merge pull request #176 from OpenSEMBA/dev
Dev
2 parents b7a4a5e + 28d0de2 commit dd8b3e5

31 files changed

+183251
-32
lines changed

doc/smbjson.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,14 +269,55 @@ A `material` with `type` `isotropic` represents an isotropic material with const
269269

270270
```json
271271
{
272-
"name": "teflon"
272+
"name": "teflon",
273273
"id": 1,
274274
"type": "isotropic",
275275
"relativePermittivity": 2.5,
276276
"electricConducitivity": 1e-6
277277
}
278278
```
279279

280+
### `lumped`
281+
282+
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.
283+
The specific behavior is described using the `<model>` keyword, described below. `resistor`, `inductor` and `capacitor` are based, with some additions, on the following reference
284+
285+
```
286+
Liu, Y., Mittra, R., Su, T., Yang, X., & Yu, W. (2006). Parallel finite-difference time-domain method. Artech.
287+
Chapter 3, Section 5.
288+
```
289+
290+
#### `resistor` model
291+
292+
Defined by:
293+
+ `<resistance>` a positive real number.
294+
+ `[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.
295+
296+
**Example:**
297+
298+
```json
299+
{
300+
"name": "100_ohm_resistor",
301+
"id": 1,
302+
"type": "lumped",
303+
"model": "resistor",
304+
"resistance": 100,
305+
"startingTime": 0.0,
306+
"endTime": 1.0
307+
}
308+
```
309+
310+
#### `inductor` model
311+
A series $LR$ circuit, $R$ is optional:
312+
+ `<inductance>` a positive real number
313+
+ `[resistance]` a positive or zero real number. Defaults to $0.0$.
314+
315+
#### `capacitor` model
316+
A parallel $CR$ circuit:
317+
+ `<capacitance>` a positive real number
318+
+ `<resistance>` a positive real number.
319+
320+
280321
### `multilayeredSurface`
281322

282323
A `multilayeredSurface` must contain the entry `<layers>` which is an array indicating materials which are described in the same way as [isotropic materials](#isotropic) and a `<thickness>`.

src_json_parser/smbjson.F90

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,8 @@ subroutine fillDielectricsOfCellType(res, cellType)
547547
integer :: i, j
548548
integer :: nCs, nDielectrics
549549

550-
mAs = this%getMaterialAssociations([J_MAT_TYPE_ISOTROPIC])
550+
mAs = this%getMaterialAssociations( &
551+
[J_MAT_TYPE_ISOTROPIC, J_MAT_TYPE_LUMPED])
551552
if (size(mAs) == 0) then
552553
allocate(res(0))
553554
return
@@ -567,11 +568,19 @@ subroutine fillDielectricsOfCellType(res, cellType)
567568
if (nDielectrics == 0) return
568569

569570
j = 0
571+
mAs = this%getMaterialAssociations([J_MAT_TYPE_ISOTROPIC])
570572
do i = 1, size(mAs)
571573
if (.not. containsCellRegionsWithType(mAs(i), cellType)) cycle
572574
j = j + 1
573575
res(j) = readDielectric(mAs(i), cellType)
574576
end do
577+
578+
mAs = this%getMaterialAssociations([J_MAT_TYPE_LUMPED])
579+
do i = 1, size(mAs)
580+
if (.not. containsCellRegionsWithType(mAs(i), cellType)) cycle
581+
j = j + 1
582+
res(j) = readLumped(mAs(i), cellType)
583+
end do
575584
end subroutine
576585

577586
function readDielectric(mA, cellType) result(res)
@@ -597,6 +606,78 @@ function readDielectric(mA, cellType) result(res)
597606

598607
end function
599608

609+
610+
function readLumped(mA, cellType) result(res)
611+
type(materialAssociation_t), intent(in) :: mA
612+
integer, intent(in) :: cellType
613+
type(Dielectric_t) :: res
614+
type(cell_region_t) :: cR
615+
type (coords), dimension(:), allocatable :: coords
616+
type(json_value_ptr) :: matPtr
617+
integer :: e, j
618+
character(len=:), allocatable :: model
619+
logical :: found
620+
621+
allocate(res%c1P(0))
622+
res%n_c1p = 0
623+
call this%matAssToCoords(res%c2p, mA, cellType)
624+
res%n_c2p = size(res%c2p)
625+
626+
matPtr = this%matTable%getId(mA%materialId)
627+
628+
! Get the model type
629+
model = this%getStrAt(matPtr%p, J_MAT_LUMPED_MODEL, found)
630+
if (.not. found) then
631+
write(error_unit, *) "ERROR reading lumped material: ", mA%materialId, " model not found."
632+
stop
633+
end if
634+
635+
! Not really needed for resistor, inductor, or capacitor.
636+
! But avoids error in lumped initialization.
637+
res%orient = 1
638+
res%DiodOri = 1
639+
640+
res%eps = EPSILON_VACUUM
641+
res%mu = MU_VACUUM
642+
643+
! Handle resistor model
644+
select case (model)
645+
case (J_MAT_LUMPED_MODEL_RESISTOR)
646+
res%resistor = .true.
647+
res%R = this%getRealAt(matPtr%p, J_MAT_LUMPED_RESISTANCE, found)
648+
if (.not. found) then
649+
write(error_unit, *) "ERROR reading lumped material: ", mA%materialId, " resistance not found."
650+
stop
651+
end if
652+
res%Rtime_on = this%getRealAt(matPtr%p, J_MAT_LUMPED_STARTING_TIME, default=0.0)
653+
res%Rtime_off = this%getRealAt(matPtr%p, J_MAT_LUMPED_END_TIME, default=1.0)
654+
case (J_MAT_LUMPED_MODEL_INDUCTOR)
655+
res%inductor = .true.
656+
res%L = this%getRealAt(matPtr%p, J_MAT_LUMPED_INDUCTANCE, found)
657+
if (.not. found) then
658+
write(error_unit, *) "ERROR reading lumped material: ", mA%materialId, " inductance not found."
659+
stop
660+
end if
661+
res%R = this%getRealAt(matPtr%p, J_MAT_LUMPED_RESISTANCE, default=0.0)
662+
case (J_MAT_LUMPED_MODEL_CAPACITOR)
663+
res%capacitor = .true.
664+
res%C = this%getRealAt(matPtr%p, J_MAT_LUMPED_CAPACITANCE, found)
665+
if (.not. found) then
666+
write(error_unit, *) "ERROR reading lumped material: ", mA%materialId, " capacitance not found."
667+
stop
668+
end if
669+
res%R = this%getRealAt(matPtr%p, J_MAT_LUMPED_RESISTANCE, found)
670+
if (.not. found) then
671+
write(error_unit, *) "ERROR reading lumped material: ", mA%materialId, " resistance not found."
672+
stop
673+
end if
674+
case default
675+
write(error_unit, *) "ERROR reading lumped material: ", mA%materialId, " invalid model."
676+
stop
677+
end select
678+
679+
end function
680+
600681
logical function containsCellRegionsWithType(mA, cellType)
601682
integer, intent(in) :: cellType
602683
type(materialAssociation_t), intent(in) :: mA

src_json_parser/smbjson_labels.F90

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ module smbjson_labels_mod
3030
character (len=*), parameter :: J_MAT_TYPE_PEC = "pec"
3131
character (len=*), parameter :: J_MAT_TYPE_PMC = "pmc"
3232
character (len=*), parameter :: J_MAT_TYPE_ISOTROPIC = "isotropic"
33+
character (len=*), parameter :: J_MAT_TYPE_LUMPED = "lumped"
3334
character (len=*), parameter :: J_MAT_TYPE_MULTILAYERED_SURFACE = "multilayeredSurface"
3435
character (len=*), parameter :: J_MAT_TYPE_SLOT = "thinSlot"
3536
character (len=*), parameter :: J_MAT_TYPE_WIRE = "wire"
@@ -46,7 +47,17 @@ module smbjson_labels_mod
4647
character (len=*), parameter :: J_MAT_WIRE_DIELECTRIC_RADIUS = "radius"
4748
character (len=*), parameter :: J_MAT_WIRE_DIELECTRIC_PERMITTIVITY = "relativePermittivity"
4849
character (len=*), parameter :: J_MAT_WIRE_PASS = "isPassthrough"
49-
50+
51+
character (len=*), parameter :: J_MAT_LUMPED_MODEL = "model"
52+
character (len=*), parameter :: J_MAT_LUMPED_MODEL_RESISTOR = "resistor"
53+
character (len=*), parameter :: J_MAT_LUMPED_MODEL_INDUCTOR = "inductor"
54+
character (len=*), parameter :: J_MAT_LUMPED_MODEL_CAPACITOR = "capacitor"
55+
character (len=*), parameter :: J_MAT_LUMPED_RESISTANCE = "resistance"
56+
character (len=*), parameter :: J_MAT_LUMPED_STARTING_TIME = "startingTime"
57+
character (len=*), parameter :: J_MAT_LUMPED_END_TIME = "endTime"
58+
character (len=*), parameter :: J_MAT_LUMPED_INDUCTANCE = "inductance"
59+
character (len=*), parameter :: J_MAT_LUMPED_CAPACITANCE = "capacitance"
60+
5061
character (len=*), parameter :: J_MAT_TERM_TERMINATIONS = "terminations"
5162
character (len=*), parameter :: J_MAT_TERM_TYPE_OPEN = "open"
5263
character (len=*), parameter :: J_MAT_TERM_TYPE_SHORT = "short"

src_main_pub/lumped.F90

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
2-
31
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
42
! Module Lumped
53
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6-
!!!!!17/08/15 update!!!!!!!!!!!
74
!!!Elimino el tratamiento de los campos magneticos de Lumped para programar un multiLumped
85
!!!solo teniendo en cuenta los parametros efectivos y sin actualizar los magneticos.
9-
!!!Mangento en el fichero Lumped_pre170815_noupdateababienH.F90 la version antigua
106
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
117

128
module Lumped
@@ -20,17 +16,14 @@ module Lumped
2016

2117
implicit none
2218

23-
!!!!!valiables locales
2419
type (LumpedElem_t), save, target :: LumpElem
2520

26-
!!!variables globales del modulo
2721
REAL (KIND=RKIND), save :: eps0,mu0,zvac,cluz
2822

2923
private
30-
3124
!!!
3225
!!!
33-
public LumpedElem_t,Nodes_t !el tipo es publico
26+
public LumpedElem_t,Nodes_t
3427
public AdvanceLumpedE,InitLumped,DestroyLumped,StoreFieldsLumpeds,calc_lumpedconstants,Getlumped
3528

3629
contains
@@ -192,7 +185,7 @@ subroutine InitLumped(sgg,sggMiEx,sggMiEy,sggMiEz,Ex,Ey,Ez,Hx,Hy,Hz,&
192185
lumped_ => LumpElem%Nodes(conta)
193186
lumped_%EfieldPrevPrev=0.0_RKIND
194187
lumped_%EfieldPrev =0.0_RKIND
195-
lumped_%Jcur =0.0_RKIND !olvide inicializar jcur 071118
188+
lumped_%Jcur =0.0_RKIND
196189
end do
197190
#ifdef CompileWithStochastic
198191
if (stochastic) then
@@ -207,13 +200,13 @@ subroutine InitLumped(sgg,sggMiEx,sggMiEy,sggMiEz,Ex,Ey,Ez,Hx,Hy,Hz,&
207200
else
208201
do conta=1,LumpElem%numnodes
209202
lumped_ => LumpElem%Nodes(conta)
210-
read(14) lumped_%EfieldPrevPrev,lumped_%EfieldPrev,lumped_%Jcur !olvide almacenar jcur 071118
203+
read(14) lumped_%EfieldPrevPrev,lumped_%EfieldPrev,lumped_%Jcur
211204
end do
212205
#ifdef CompileWithStochastic
213206
if (stochastic) then
214207
do conta=1,LumpElem%numnodes
215208
lumped_ => LumpElem%Nodes(conta)
216-
read(14) lumped_%EfieldPrevPrev_for_devia,lumped_%EfieldPrev_for_devia,lumped_%Jcur_for_devia !olvide almacenar jcur 071118
209+
read(14) lumped_%EfieldPrevPrev_for_devia,lumped_%EfieldPrev_for_devia,lumped_%Jcur_for_devia
217210
end do
218211
endif
219212
#endif
@@ -238,7 +231,8 @@ subroutine AdvanceLumpedE(sgg,timestep,simu_devia,stochastic)
238231
if (sgg%med(lumped_%jmed)%lumped(1)%inductor) then
239232
lumped_%EfieldPrevPrev = lumped_%EfieldPrev
240233
lumped_%EfieldPrev = lumped_%Efield
241-
lumped_%Jcur = lumped_%Jcur + lumped_%sigmaEffResistInduct * (lumped_%EfieldPrev + lumped_%EfieldPrevPrev)
234+
!!! The evolution of the current must be modified by a coefficient different from that shown in Mittra pag65.
235+
lumped_%Jcur = lumped_%currentCoeff * lumped_%Jcur + lumped_%sigmaEffResistInduct * (lumped_%EfieldPrev + lumped_%EfieldPrevPrev)
242236
else
243237
lumped_%Jcur=0.0_RKIND
244238
endif
@@ -250,14 +244,14 @@ subroutine AdvanceLumpedE(sgg,timestep,simu_devia,stochastic)
250244
else !debe entrar aqui si es un resistor, inductor o capacitor
251245
if (sgg%med(lumped_%jmed)%lumped(1)%resistor) then
252246
if ((timestep*sgg%dt >= sgg%Med(lumped_%jmed)%Lumped(1)%Rtime_on).and.(timestep*sgg%dt <= sgg%Med(lumped_%jmed)%Lumped(1)%Rtime_off)) then
253-
lumped_%Efield = lumped_%G1 * lumped_%Efield + (lumped_%G2a *(lumped_%Ha_Plus - lumped_%Ha_Minu ) - lumped_%G2b *(lumped_%Hb_Plus - lumped_%Hb_Minu ) ) + &
247+
lumped_%Efield = lumped_%G1 * lumped_%Efield + (lumped_%G2a *(lumped_%Ha_Plus - lumped_%Ha_Minu ) - lumped_%G2b *(lumped_%Hb_Plus - lumped_%Hb_Minu ) ) - &
254248
lumped_%GJ * lumped_%Jcur
255249
else
256250
lumped_%Efield = lumped_%G1_usual * lumped_%Efield +(lumped_%G2a_usual *(lumped_%Ha_Plus - lumped_%Ha_Minu) - &
257251
lumped_%G2b_usual *(lumped_%Hb_Plus - lumped_%Hb_Minu))
258252
endif
259253
else !inductor o capacitor
260-
lumped_%Efield = lumped_%G1 * lumped_%Efield + (lumped_%G2a *(lumped_%Ha_Plus - lumped_%Ha_Minu ) - lumped_%G2b *(lumped_%Hb_Plus - lumped_%Hb_Minu ) ) + &
254+
lumped_%Efield = lumped_%G1 * lumped_%Efield + (lumped_%G2a *(lumped_%Ha_Plus - lumped_%Ha_Minu ) - lumped_%G2b *(lumped_%Hb_Plus - lumped_%Hb_Minu ) ) - &
261255
lumped_%GJ * lumped_%Jcur
262256
endif
263257
endif
@@ -282,7 +276,7 @@ subroutine calc_lumpedconstants(sgg,eps00,mu00)
282276
real (kind=RKIND) :: epsilon,sigma,g1,g2,Resist,Induct,Capaci,sigmaeff,epsiloneff,DiodB,DiodIsat
283277
real (kind=RKIND) :: g1_usual,g2_usual
284278
real (kind=RKIND) :: epsilonEffCapac ,sigmaEffResistInduct,sigmaEffResist ,sigmaEffResistCapac ,sigmaEffResistDiode, &
285-
alignedDeltaE,transversalDeltaHa,transversalDeltaHb
279+
alignedDeltaE,transversalDeltaHa,transversalDeltaHb, currentCoeff
286280

287281
character(len=BUFSIZE) :: buff
288282
!
@@ -307,13 +301,13 @@ subroutine calc_lumpedconstants(sgg,eps00,mu00)
307301
alignedDeltaE =lumped_%alignedDeltaE
308302
transversalDeltaHa =lumped_%transversalDeltaHa
309303
transversalDeltaHb =lumped_%transversalDeltaHb
310-
311304
!
312305
epsilonEffCapac = alignedDeltaE * Capaci / ( transversalDeltaHa * transversalDeltaHb)
313306
sigmaEffResistInduct = alignedDeltaE * sgg%dt / (2.0_RKIND * transversalDeltaHa * transversalDeltaHb * (Induct + Resist * sgg%dt /2.0_RKIND))
314307
sigmaEffResist = alignedDeltaE / ( Resist * transversalDeltaHa * transversalDeltaHb)
315308
sigmaEffResistCapac = sigmaEffResist
316309
sigmaEffResistDiode = sigmaEffResist
310+
currentCoeff = (Induct - Resist * sgg%dt /2.0_RKIND) / (Induct + Resist * sgg%dt /2.0_RKIND)
317311

318312
!!!! Mittra pag65 Parallel Finite-Difference Time-Domain Method
319313
if (sgg%med(jmed)%lumped(1)%resistor) then
@@ -348,7 +342,6 @@ subroutine calc_lumpedconstants(sgg,eps00,mu00)
348342
(epsilonEff/sgg%dt + SigmaEff/2.0_RKIND )
349343

350344

351-
!!!!repensar si es necesario 27/08/15
352345
!!!lo he comentado a 050122 por consistencia con stochastic
353346
!!if (g1 < 0.0_RKIND) then !exponential time stepping
354347
!! g1=exp(- SigmaEff * sgg%dt / (epsilonEff ))
@@ -357,13 +350,13 @@ subroutine calc_lumpedconstants(sgg,eps00,mu00)
357350
lumped_%g1=g1
358351
lumped_%G2a= G2 / transversalDeltaHa
359352
lumped_%G2b= G2 / transversalDeltaHb
360-
lumped_%GJ = G2 !!!!Mittra pag65
353+
!!! The current derivation on page 65 of Mittra is incorrect and leads to saturation.
354+
!!! The correct coefficient is the one shown here.
355+
lumped_%GJ = G2 * (1 + currentCoeff) / 2 !!!!Mittra pag65
361356
lumped_%sigmaEffResistInduct = sigmaEffResistInduct
357+
lumped_%currentCoeff = currentCoeff
362358

363-
364-
365359
!!!!usual para resistencia que se encienden/apagan 200319
366-
367360
G1_usual=(1.0_RKIND - Sigma * sgg%dt / (2.0_RKIND * epsilon) ) / &
368361
(1.0_RKIND + Sigma * sgg%dt / (2.0_RKIND * epsilon) )
369362
G2_usual= sgg%dt / epsilon / &
@@ -377,7 +370,6 @@ subroutine calc_lumpedconstants(sgg,eps00,mu00)
377370
lumped_%G2a_usual= G2_usual / transversalDeltaHa
378371
lumped_%G2b_usual= G2_usual / transversalDeltaHb
379372

380-
381373
!!!only for diodes
382374
if (orient>0.0) then
383375
lumped_%diodeB = lumped_%diodeB * alignedDeltaE / 2.0_RKIND

src_main_pub/lumped_types.F90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module lumped_vars
55
use fdetypes
66

77
TYPE, public :: Nodes_t
8-
REAL (KIND=RKIND) :: EfieldPrev,EfieldPrevPrev,Jcur,sigmaEffResistInduct,alignedDeltaE ,transversalDeltaHa ,transversalDeltaHb
8+
REAL (KIND=RKIND) :: EfieldPrev,EfieldPrevPrev,Jcur,sigmaEffResistInduct,alignedDeltaE ,transversalDeltaHa ,transversalDeltaHb, currentCoeff
99
REAL (KIND=RKIND) :: diodepreA,diodeB
1010
REAL (KIND=RKIND), pointer :: Efield,Ha_Plus,Ha_Minu,Hb_Plus,Hb_Minu
1111
REAL (KIND=RKIND) :: g1

src_main_pub/semba_fdtd.F90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,8 @@ PROGRAM SEMBA_FDTD_launcher
722722
write(thefileno,'(a)') '# ( 8.0 , 8.0 ) '//trim(adjustl('Thin wire segments colliding with structure (Line)'))
723723
write(thefileno,'(a)') '# ( 8.5 , 8.5 ) '//trim(adjustl('Soft/Hard Nodal CURRENT/FIELD ELECTRIC DENSITY SOURCE (Line)'))
724724
write(thefileno,'(a)') '# ( 9.0 , 9.0 ) '//trim(adjustl('Soft/Hard Nodal CURRENT/FIELD MAGNETIC DENSITY SOURCE (Line)'))
725-
write(thefileno,'(a)') '# ( 10 , 11 ) '//trim(adjustl('LeftEnd/RightEnd/Ending segment (Wire)'))
726-
write(thefileno,'(a)') '# ( 20 , 20 ) '//trim(adjustl('Intermediate segment +number_holland_parallel or +number_berenger (Wire) '))
725+
write(thefileno,'(a)') '# ( 10 , 11 ) '//trim(adjustl('LeftEnd/RightEnd/Ending wire segment (Wire)'))
726+
write(thefileno,'(a)') '# ( 20 , 20 ) '//trim(adjustl('Intermediate wire segment +number_holland_parallel or +number_berenger (Wire) '))
727727
write(thefileno,'(a)') '# ( 400 , 499 ) '//trim(adjustl('Thin slot (+indexmedium) (Surface)'))
728728
write(thefileno,'(a)') '# ( -0.5 , -0.5 ) '//trim(adjustl('Other types of media (Line)'))
729729
write(thefileno,'(a)') '# ( -1.0 , -1.0 ) '//trim(adjustl('Other types of media (Surface)'))

src_pyWrapper/pyWrapper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ def getCurrentVTKMap(self):
390390
def getMaterialProperties(self, materialName):
391391
if 'materials' in self._input:
392392
for idx, element in enumerate(self._input['materials']):
393-
if element["name"] == materialName:
393+
if element.get("name") == materialName:
394394
return self._input['materials'][idx]
395395

396396

0 commit comments

Comments
 (0)