From 702d402919a3818b884a43a2dd7247807fcde1f4 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Fri, 6 Dec 2024 10:23:40 +0100 Subject: [PATCH 01/25] Adding sgbc/composites/surfaces to smbjson --- doc/smbjson.md | 15 +-- src_json_parser/nfdetypes_extension.F90 | 8 ++ test/smbjson/CMakeLists.txt | 1 + test/smbjson/smbjson_tests.h | 2 + test/smbjson/test_read_sgbc.F90 | 116 ++++++++++++++++++++++++ testData/cases/sgbc.fdtd.json | 70 ++++++++++++++ 6 files changed, 198 insertions(+), 14 deletions(-) create mode 100644 test/smbjson/test_read_sgbc.F90 create mode 100644 testData/cases/sgbc.fdtd.json diff --git a/doc/smbjson.md b/doc/smbjson.md index 54f8e103..409890db 100644 --- a/doc/smbjson.md +++ b/doc/smbjson.md @@ -289,25 +289,12 @@ A `multilayeredSurface` must contain the entry `` which is an array indi "id": 2, "layers": [ {"thickness": 1e-3, "relativePermittivity": 1.3, "electricConductivity": 2e-4}, - {"thickness": 5e-3, "relativePermittivity": 1.3} + {"thickness": 5e-3, "relativePermittivity": 1.3}, {"thickness": 1e-3, "relativePermittivity": 1.3, "electricConductivity": 2e-4} ] } ``` -#### `frequencyDependentSurface` - -The entry `` is the path to a file containing the poles and residues which are used to model the surface impedance of the material. - -```json -{ - "name": "carbon_fiber_model", - "type": "frequencyDependentSurface", - "id": 3, - "file": "cfc.dat" -} -``` - ### Cable materials #### `wire` diff --git a/src_json_parser/nfdetypes_extension.F90 b/src_json_parser/nfdetypes_extension.F90 index e725bd4b..674937a3 100644 --- a/src_json_parser/nfdetypes_extension.F90 +++ b/src_json_parser/nfdetypes_extension.F90 @@ -7,6 +7,8 @@ module NFDETypes_extension public interface operator(==) + module procedure Parseador_eq + module procedure NFDEGeneral_eq module procedure desplazamiento_eq @@ -106,7 +108,13 @@ subroutine initializeProblemDescription(pD) allocate(pD%pmcRegs%vols(0)) allocate(pD%DielRegs) + allocate(pD%DielRegs%lins(0)) + allocate(pD%DielRegs%surfs(0)) + allocate(pD%DielRegs%vols(0)) + allocate(pD%LossyThinSurfs) + allocate(pD%LossyThinSurfs%cs(0)) + allocate(pD%frqDepMats) allocate(pD%aniMats) ! diff --git a/test/smbjson/CMakeLists.txt b/test/smbjson/CMakeLists.txt index 8b045393..1ef4eea1 100644 --- a/test/smbjson/CMakeLists.txt +++ b/test/smbjson/CMakeLists.txt @@ -9,6 +9,7 @@ add_library (smbjson_test_fortran "test_mesh.F90" "test_parser.F90" "test_read_planewave.F90" + "test_read_sgbc.F90" "test_read_holland1981.F90" "test_read_towelHanger.F90" "test_read_connectedWires.F90" diff --git a/test/smbjson/smbjson_tests.h b/test/smbjson/smbjson_tests.h index ae1ad59a..a4525da6 100644 --- a/test/smbjson/smbjson_tests.h +++ b/test/smbjson/smbjson_tests.h @@ -13,6 +13,7 @@ extern "C" int test_parser_ctor(); extern "C" int test_parser_read_mesh(); extern "C" int test_read_planewave(); +extern "C" int test_read_sgbc(); extern "C" int test_read_holland1981(); extern "C" int test_read_towelhanger(); extern "C" int test_read_connectedwires(); @@ -35,6 +36,7 @@ TEST(smbjson, mesh_polyline_to_linel) { EXPECT_EQ(0, test_mesh_polyline_to_li TEST(smbjson, parser_ctor) { EXPECT_EQ(0, test_parser_ctor()); } TEST(smbjson, parser_read_mesh) { EXPECT_EQ(0, test_parser_read_mesh()); } TEST(smbjson, read_planewave) { EXPECT_EQ(0, test_read_planewave()); } +TEST(smbjson, read_sgbc) { EXPECT_EQ(0, test_read_sgbc()); } TEST(smbjson, read_holland1981) { EXPECT_EQ(0, test_read_holland1981()); } TEST(smbjson, read_towelhanger) { EXPECT_EQ(0, test_read_towelhanger()); } TEST(smbjson, read_connectedwires) { EXPECT_EQ(0, test_read_connectedwires()); } diff --git a/test/smbjson/test_read_sgbc.F90 b/test/smbjson/test_read_sgbc.F90 new file mode 100644 index 00000000..3a3f677e --- /dev/null +++ b/test/smbjson/test_read_sgbc.F90 @@ -0,0 +1,116 @@ +integer function test_read_sgbc() bind (C) result(err) + use smbjson + use smbjson_testingTools + + implicit none + + character(len=*), parameter :: filename = PATH_TO_TEST_DATA//'cases/sgbc.fdtd.json' + type(Parseador) :: pr, ex + type(parser_t) :: parser + logical :: areSame + err = 0 + + ex = expectedProblemDescription() + parser = parser_t(filename) + pr = parser%readProblemDescription() + call expect_eq(err, ex, pr) + +contains + function expectedProblemDescription() result (expected) + type(Parseador) :: expected + + call initializeProblemDescription(expected) + + ! Expected general info. + expected%general%dt = 10e-12 + expected%general%nmax = 2000 + + ! Excected media matrix. + expected%matriz%totalX = 10 + expected%matriz%totalY = 10 + expected%matriz%totalZ = 10 + + ! Expected grid. + expected%despl%nX = 10 + expected%despl%nY = 10 + expected%despl%nZ = 10 + + allocate(expected%despl%desX(10)) + allocate(expected%despl%desY(10)) + allocate(expected%despl%desZ(10)) + expected%despl%desX = 0.1 + expected%despl%desY = 0.1 + expected%despl%desZ = 0.1 + expected%despl%mx1 = 0 + expected%despl%mx2 = 10 + expected%despl%my1 = 0 + expected%despl%my2 = 10 + expected%despl%mz1 = 0 + expected%despl%mz2 = 10 + + ! Expected boundaries. + expected%front%tipoFrontera(:) = F_MUR + + ! Expected materials + !! PECs + expected%pecRegs%nSurfs = 1 + expected%pecRegs%nLins = 0 + expected%pecRegs%nVols_max = 0 + expected%pecRegs%nSurfs_max = 1 + expected%pecRegs%nLins_max = 0 + allocate(expected%pecRegs%Vols(0)) + allocate(expected%pecRegs%Surfs(1)) + !!! 2x2 PEC square + expected%pecRegs%Surfs(1)%Or = +iEz + expected%pecRegs%Surfs(1)%Xi = 3 + expected%pecRegs%Surfs(1)%Xe = 4 + expected%pecRegs%Surfs(1)%Yi = 3 + expected%pecRegs%Surfs(1)%Ye = 4 + expected%pecRegs%Surfs(1)%Zi = 3 + expected%pecRegs%Surfs(1)%Ze = 3 + expected%pecRegs%Surfs(1)%tag = 'pec-layer' + + !! Composites + allocate(expected%lossyThinSurfs%cs(2)) + expected%lossyThinSurfs%length = 2 + expected%lossyThinSurfs%length_max = 2 + expected%lossyThinSurfs%nC_max = 2 + + !!! 2-layer composite + allocate(expected%lossyThinSurfs%cs(1)%c(1)) + expected%lossyThinSurfs%cs(1)%nc = 1 + expected%lossyThinSurfs%cs(1)%c(1)%tag = '2-layers-composite' + expected%lossyThinSurfs%cs(1)%c(1)%Or = +iEx + expected%lossyThinSurfs%cs(1)%c(1)%Xi = 3 + expected%lossyThinSurfs%cs(1)%c(1)%Xe = 4 + expected%lossyThinSurfs%cs(1)%c(1)%Yi = 3 + expected%lossyThinSurfs%cs(1)%c(1)%Ye = 3 + expected%lossyThinSurfs%cs(1)%c(1)%Zi = 3 + expected%lossyThinSurfs%cs(1)%c(1)%Ze = 4 + expected%lossyThinSurfs%cs(1)%numcapas = 2 + expected%lossyThinSurfs%cs(1)%thk = [ 1e-3, 5e-3] + expected%lossyThinSurfs%cs(1)%sigma = [ 2e-4, 0.0] + expected%lossyThinSurfs%cs(1)%eps = [1.3*EPSILON_VACUUM, 1.3*EPSILON_VACUUM] + expected%lossyThinSurfs%cs(1)%mu = [ MU_VACUUM, MU_VACUUM] + expected%lossyThinSurfs%cs(1)%sigmam = [ 0.0, 0.0] + + !!! 3-layer composite + allocate(expected%lossyThinSurfs%cs(2)%c(1)) + expected%lossyThinSurfs%cs(2)%nc = 1 + expected%lossyThinSurfs%cs(2)%c(1)%tag = '3-layers-composite' + expected%lossyThinSurfs%cs(2)%c(1)%Or = +iEy + expected%lossyThinSurfs%cs(2)%c(1)%Xi = 3 + expected%lossyThinSurfs%cs(2)%c(1)%Xe = 3 + expected%lossyThinSurfs%cs(2)%c(1)%Yi = 3 + expected%lossyThinSurfs%cs(2)%c(1)%Ye = 4 + expected%lossyThinSurfs%cs(2)%c(1)%Zi = 3 + expected%lossyThinSurfs%cs(2)%c(1)%Ze = 4 + expected%lossyThinSurfs%cs(2)%numcapas = 3 + expected%lossyThinSurfs%cs(2)%thk = [ 1e-3, 5e-3, 1e-3] + expected%lossyThinSurfs%cs(2)%sigma = [ 2e-4, 0.0, 0.0] + expected%lossyThinSurfs%cs(2)%eps = [EPSILON_VACUUM, EPSILON_VACUUM, EPSILON_VACUUM] + expected%lossyThinSurfs%cs(2)%mu = [ MU_VACUUM, 1.3*MU_VACUUM, MU_VACUUM] + expected%lossyThinSurfs%cs(2)%sigmam = [ 0.0, 0.0, 1e-4] + end function +end function + diff --git a/testData/cases/sgbc.fdtd.json b/testData/cases/sgbc.fdtd.json new file mode 100644 index 00000000..57f53dc0 --- /dev/null +++ b/testData/cases/sgbc.fdtd.json @@ -0,0 +1,70 @@ +{ + "format": "FDTD Input file", + "__comments": "Example input with sgbc material", + + "general": { + "timeStep": 10e-12, + "numberOfSteps": 2000 + }, + + "boundary": { + "all": {"type": "mur"} + }, + + "mesh": { + "grid": { + "numberOfCells": [10, 10, 10], + "steps": { "x": [0.1], "y": [0.1], "z": [0.1] } + }, + "elements": [ + {"id": 1, "type": "cell", "intervals": [ [ [3, 3, 3], [5, 5, 3] ] ]}, + {"id": 2, "type": "cell", "intervals": [ [ [3, 3, 3], [5, 3, 5] ] ]}, + {"id": 3, "type": "cell", "intervals": [ [ [3, 3, 3], [3, 5, 5] ] ]} + ] + }, + + "materials": [ + { + "name": "pec-layer", + "type": "pec", + "id": 1 + }, + { + "name": "2-layers-composite", + "type": "multilayeredSurface", + "id": 2, + "layers": [ + {"thickness": 1e-3, "relativePermittivity": 1.3, "electricConductivity": 2e-4}, + {"thickness": 5e-3, "relativePermittivity": 1.3} + ] + }, + { + "name": "3-layers-composite", + "type": "multilayeredSurface", + "id": 3, + "layers": [ + {"thickness": 1e-3, "electricConductivity": 2e-4}, + {"thickness": 5e-3, "relativePermeability": 1.3}, + {"thickness": 1e-3, "magneticConductivity": 1e-4} + ] + } + ], + + "materialAssociations": [ + { + "type": "surface", + "materialId": 1, + "elementIds": [ 1 ] + }, + { + "type": "surface", + "materialId": 2, + "elementIds": [ 2 ] + }, + { + "type": "surface", + "materialId": 3, + "elementIds": [ 3 ] + } + ] +} \ No newline at end of file From 481d48361a7ecb61d18aa7c3dd05a16f252eff59 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Fri, 6 Dec 2024 11:21:18 +0100 Subject: [PATCH 02/25] [WIP] Read composites --- .github/workflows/run_tests_windows.bat | 1 - .github/workflows/windows-intelLLVM.yml | 9 ++++- src_json_parser/smbjson.F90 | 53 ++++++++++++++++++++++--- src_json_parser/smbjson_labels.F90 | 1 + test/smbjson/test_read_sgbc.F90 | 11 +++++ 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/.github/workflows/run_tests_windows.bat b/.github/workflows/run_tests_windows.bat index b50453f2..0efa6dbe 100644 --- a/.github/workflows/run_tests_windows.bat +++ b/.github/workflows/run_tests_windows.bat @@ -19,5 +19,4 @@ IF "%VS_VER%"=="2017_build_tools" ( for /f "tokens=* usebackq" %%f in (`dir /b "C:\Program Files (x86)\Intel\oneAPI\compiler\" ^| findstr /V latest ^| sort`) do @set "LATEST_VERSION=%%f" @call "C:\Program Files (x86)\Intel\oneAPI\compiler\%LATEST_VERSION%\env\vars.bat" -build\bin\fdtd_tests.exe python -m pytest test \ No newline at end of file diff --git a/.github/workflows/windows-intelLLVM.yml b/.github/workflows/windows-intelLLVM.yml index a0e8a3f5..83f4f89f 100644 --- a/.github/workflows/windows-intelLLVM.yml +++ b/.github/workflows/windows-intelLLVM.yml @@ -46,8 +46,13 @@ jobs: run: | python -m pip install -r requirements.txt - - name: Run all tests + - name: Run unit tests shell: bash - timeout-minutes: 120 + timeout-minutes: 10 + run: build\bin\fdtd_tests.exe + + - name: Run system tests + shell: bash + timeout-minutes: 30 run: | .github/workflows/run_tests_windows.bat \ No newline at end of file diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index a9020438..c3072b7f 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -37,6 +37,7 @@ module smbjson procedure :: readMediaMatrix procedure :: readPECRegions procedure :: readPMCRegions + procedure :: readLossyThinSurfaces procedure :: readBoundary procedure :: readPlanewaves procedure :: readNodalSources @@ -130,6 +131,7 @@ function readProblemDescription(this) result (res) ! Materials res%pecRegs = this%readPECRegions() res%pmcRegs = this%readPMCRegions() + res%lossyThinSurfs = this%readLossyThinSurfaces() ! Sources res%plnSrc = this%readPlanewaves() @@ -145,11 +147,6 @@ function readProblemDescription(this) result (res) res%tWires = this%readThinWires() res%mtln = this%readMTLN(res%despl) - !! Cleanup - !call this%core%destroy() - !call this%jsonfile%destroy() - !nullify(this%root) - end function function readMesh(this) result(res) @@ -394,6 +391,52 @@ function buildPECPMCRegion(cRs) result(res) res%nVols_max = size(res%Vols) end function + function readLossyThinSurfaces(this) result (res) + class(parser_t), intent(in) :: this + type(LossyThinSurfaces) :: res + type(json_value), pointer :: matAss + type(json_value_ptr), dimension(:), allocatable :: surfaces + type(json_value_ptr) :: mat + integer :: nLossySurfaces + logical :: found + integer :: i + integer :: matId + + call this%core%get(this%root, J_MATERIAL_ASSOCIATIONS, matAss, found) + if (.not. found) then + res = emptyLossyThinSurfaces() + return + end if + + surfaces = this%jsonValueFilterByKeyValue(matAss, J_TYPE, J_MAT_ASS_TYPE_SURFACE) + nLossySurfaces = 0 + do i = 1, size(surfaces) + matId = this%getIntAt(surfaces(i)%p, J_MATERIAL_ID, found) + if (.not. found) then + write(error_unit, *) "ERROR: material id not found in surface mat. association." + end if + + mat = this%matTable%getId(matId) + if (this%getStrAt(mat%p, J_TYPE) == J_MAT_TYPE_MULTILAYERED_SURFACE) then + nLossySurfaces = nLossySurfaces + 1 + end if + end do + + if (nLossySurfaces == 0) then + res = emptyLossyThinSurfaces() + return + end if + + contains + function emptyLossyThinSurfaces() result (res) + type(LossyThinSurfaces) :: res + allocate(res%cs(0)) + res%length = 0 + res%length_max = 0 + res%nC_max = 0 + end function + end function + function readPlanewaves(this) result (res) class(parser_t) :: this type(PlaneWaves) :: res diff --git a/src_json_parser/smbjson_labels.F90 b/src_json_parser/smbjson_labels.F90 index c56001ac..d94364c5 100644 --- a/src_json_parser/smbjson_labels.F90 +++ b/src_json_parser/smbjson_labels.F90 @@ -26,6 +26,7 @@ module smbjson_labels_mod character (len=*), parameter :: J_MAT_TYPE_PEC = "pec" character (len=*), parameter :: J_MAT_TYPE_PMC = "pmc" character (len=*), parameter :: J_MAT_TYPE_SIMPLE = "simple" + character (len=*), parameter :: J_MAT_TYPE_MULTILAYERED_SURFACE = "multilayeredSurface" character (len=*), parameter :: J_MAT_TYPE_WIRE = "wire" character (len=*), parameter :: J_MAT_TYPE_MULTIWIRE = "multiwire" character (len=*), parameter :: J_MAT_TYPE_TERMINAL = "terminal" diff --git a/test/smbjson/test_read_sgbc.F90 b/test/smbjson/test_read_sgbc.F90 index 3a3f677e..91483031 100644 --- a/test/smbjson/test_read_sgbc.F90 +++ b/test/smbjson/test_read_sgbc.F90 @@ -60,6 +60,7 @@ function expectedProblemDescription() result (expected) expected%pecRegs%nLins_max = 0 allocate(expected%pecRegs%Vols(0)) allocate(expected%pecRegs%Surfs(1)) + !!! 2x2 PEC square expected%pecRegs%Surfs(1)%Or = +iEz expected%pecRegs%Surfs(1)%Xi = 3 @@ -88,6 +89,11 @@ function expectedProblemDescription() result (expected) expected%lossyThinSurfs%cs(1)%c(1)%Zi = 3 expected%lossyThinSurfs%cs(1)%c(1)%Ze = 4 expected%lossyThinSurfs%cs(1)%numcapas = 2 + allocate(expected%lossyThinSurfs%cs(1)%thk(2)) + allocate(expected%lossyThinSurfs%cs(1)%sigma(2)) + allocate(expected%lossyThinSurfs%cs(1)%eps(2)) + allocate(expected%lossyThinSurfs%cs(1)%mu(2)) + allocate(expected%lossyThinSurfs%cs(1)%sigmam(2)) expected%lossyThinSurfs%cs(1)%thk = [ 1e-3, 5e-3] expected%lossyThinSurfs%cs(1)%sigma = [ 2e-4, 0.0] expected%lossyThinSurfs%cs(1)%eps = [1.3*EPSILON_VACUUM, 1.3*EPSILON_VACUUM] @@ -106,6 +112,11 @@ function expectedProblemDescription() result (expected) expected%lossyThinSurfs%cs(2)%c(1)%Zi = 3 expected%lossyThinSurfs%cs(2)%c(1)%Ze = 4 expected%lossyThinSurfs%cs(2)%numcapas = 3 + allocate(expected%lossyThinSurfs%cs(2)%thk(3)) + allocate(expected%lossyThinSurfs%cs(2)%sigma(3)) + allocate(expected%lossyThinSurfs%cs(2)%eps(3)) + allocate(expected%lossyThinSurfs%cs(2)%mu(3)) + allocate(expected%lossyThinSurfs%cs(2)%sigmam(3)) expected%lossyThinSurfs%cs(2)%thk = [ 1e-3, 5e-3, 1e-3] expected%lossyThinSurfs%cs(2)%sigma = [ 2e-4, 0.0, 0.0] expected%lossyThinSurfs%cs(2)%eps = [EPSILON_VACUUM, EPSILON_VACUUM, EPSILON_VACUUM] From fca1fe9ce5c9fdc8d2561e72d54cb8595a00939e Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Sat, 7 Dec 2024 10:44:11 +0100 Subject: [PATCH 03/25] [WIP] --- .github/workflows/windows-intelLLVM.yml | 2 +- src_json_parser/idchildtable.F90 | 16 +++- src_json_parser/mesh.F90 | 17 +++- src_json_parser/smbjson.F90 | 105 ++++++++++++++++++------ test/smbjson/test_idchildtable.F90 | 2 +- 5 files changed, 108 insertions(+), 34 deletions(-) diff --git a/.github/workflows/windows-intelLLVM.yml b/.github/workflows/windows-intelLLVM.yml index 83f4f89f..e90fe55d 100644 --- a/.github/workflows/windows-intelLLVM.yml +++ b/.github/workflows/windows-intelLLVM.yml @@ -49,7 +49,7 @@ jobs: - name: Run unit tests shell: bash timeout-minutes: 10 - run: build\bin\fdtd_tests.exe + run: build/bin/fdtd_tests.exe - name: Run system tests shell: bash diff --git a/src_json_parser/idchildtable.F90 b/src_json_parser/idchildtable.F90 index 3372e88f..0aa9c029 100644 --- a/src_json_parser/idchildtable.F90 +++ b/src_json_parser/idchildtable.F90 @@ -11,7 +11,8 @@ module idchildtable_mod type(fhash_tbl_t) :: idToChilds contains procedure :: getId - procedure :: count + procedure :: totalSize + procedure :: checkId end type interface IdChildTable_t @@ -42,9 +43,17 @@ function ctor(core, root, path) result(res) end do end function - integer function count(this) + function totalSize(this) result(res) class(IdChildTable_t) :: this - call this%idToChilds%stats(num_items=count) + integer :: res + call this%idToChilds%stats(num_items=res) + end function + + function checkId(this, id) result(stat) + class(IdChildTable_t) :: this + integer, intent(in) :: id + integer :: stat + call this%idToChilds%check_key(key(id), stat) end function function getId(this, id) result(res) @@ -66,5 +75,6 @@ function getId(this, id) result(res) res = d end select end function + #endif end module diff --git a/src_json_parser/mesh.F90 b/src_json_parser/mesh.F90 index ca22073a..2da6bdb9 100644 --- a/src_json_parser/mesh.F90 +++ b/src_json_parser/mesh.F90 @@ -37,7 +37,8 @@ module mesh_mod contains procedure :: addCoordinate => mesh_addCoordinate procedure :: getCoordinate => mesh_getCoordinate - procedure :: checkId => mesh_checkId + procedure :: checkCoordinateId => mesh_checkCoordinateId + procedure :: checkElementId => mesh_checkElementId procedure :: addElement => mesh_addElement procedure :: addCellRegion => mesh_addCellRegion @@ -86,12 +87,20 @@ subroutine mesh_printCoordHashInfo(this) end subroutine - subroutine mesh_checkId(this, id, stat) + function mesh_checkCoordinateId(this, id) result(stat) class(mesh_t) :: this integer, intent(in) :: id - integer, intent(inout) :: stat + integer :: stat call this%coordinates%check_key(key(id), stat) - end subroutine + end function + + + function mesh_checkElementId(this, id) result(stat) + class(mesh_t) :: this + integer, intent(in) :: id + integer :: stat + call this%coordinates%check_key(key(id), stat) + end function subroutine mesh_addCoordinate(this, id, coordinate) class(mesh_t) :: this diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index c3072b7f..4a6987d6 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -61,6 +61,7 @@ module smbjson procedure :: existsAt procedure :: getCellRegionsWithMaterialType procedure :: getDomain + procedure :: buildMaterialAssociation procedure :: jsonValueFilterByKeyValue procedure :: jsonValueFilterByKeyValues procedure :: getSingleVolumeInElementsIds @@ -79,6 +80,12 @@ module smbjson real :: multiplier end type + type, private :: materialAssociation_t + character(:), allocatable :: name + integer :: materialId + integer, dimension(:), allocatable :: elementIds + character(:), allocatable :: matAssType + end type type, private :: domain_t real :: tstart, tstop, tstep @@ -89,6 +96,55 @@ module smbjson logical :: isLogarithmicFrequencySpacing end type contains + function buildMaterialAssociation(this, matAss) result(res) + class(parser_t) :: this + type(json_value_ptr), intent(in) :: matAss + type(materialAssociation_t) :: res + character (len=*), parameter :: errorMsgInit = "ERROR reading material association: " + logical :: found + + ! Fills material association. + res%materialId = this%getIntAt(matAss%p, J_MATERIAL_ID, found) + if (.not. found) call showLabelNotFoundError(J_MATERIAL_ID) + res%elementIds = this%getIntsAt(matAss%p, J_ELEMENTIDS, found) + if (.not. found) call showLabelNotFoundError(J_ELEMENTIDS) + res%matAssType = this%getStrAt(matAss%p, J_TYPE, found) + if (.not. found) call showLabelNotFoundError(J_TYPE) + res%name = this%getStrAt(matAss%p, J_NAME, found) + if (.not. found) then + res%name = "" + end if + + ! Checks validity of associations. + if (this%matTable%checkId(res%materialId) /= 0) then + write(error_unit, *) errorMsgInit, "material with id ", res%materialId, " not found." + endif + + if (size(res%elementIds) == 0) then + write(error_unit, *) errorMsgInit, J_ELEMENTIDS, "must not be empty." + end if + block + integer :: i + do i = 1, size(res%elementIds) + if (this%mesh%checkElementId(res%elementIds(i)) /= 0) then + write(error_unit, *) errorMsgInit, "element with id ", res%elementIds(i), " not found." + end if + end do + end block + + if (res%matAssType /= J_MAT_ASS_TYPE_BULK .or. & + res%matAssType /= J_MAT_ASS_TYPE_SURFACE .or. & + res%matAssType /= J_MAT_ASS_TYPE_CABLE) then + write(error_unit, *) errorMsgInit, "invalid type." + endif + + contains + subroutine showLabelNotFoundError(label) + character (len=*), intent(in) :: label + write(error_unit, *) errorMsgInit, label, " not found." + end subroutine + end function + function parser_ctor(filename) result(res) type(parser_t) :: res character(len=*), intent(in) :: filename @@ -395,46 +451,45 @@ function readLossyThinSurfaces(this) result (res) class(parser_t), intent(in) :: this type(LossyThinSurfaces) :: res type(json_value), pointer :: matAss - type(json_value_ptr), dimension(:), allocatable :: surfaces + type(json_value_ptr), dimension(:), allocatable :: surfsMatAssPtr type(json_value_ptr) :: mat + type(json_value), pointer :: jmrs, jmr + type(json_value_ptr) :: jm + integer, dimension(:), allocatable :: eIds + type(cell_region_t) :: cR integer :: nLossySurfaces logical :: found integer :: i - integer :: matId + type(materialAssociation_t) :: surfMatAss - call this%core%get(this%root, J_MATERIAL_ASSOCIATIONS, matAss, found) - if (.not. found) then - res = emptyLossyThinSurfaces() - return - end if - - surfaces = this%jsonValueFilterByKeyValue(matAss, J_TYPE, J_MAT_ASS_TYPE_SURFACE) nLossySurfaces = 0 - do i = 1, size(surfaces) - matId = this%getIntAt(surfaces(i)%p, J_MATERIAL_ID, found) - if (.not. found) then - write(error_unit, *) "ERROR: material id not found in surface mat. association." - end if - - mat = this%matTable%getId(matId) + surfsMatAssPtr = this%jsonValueFilterByKeyValue(matAss, J_TYPE, J_MAT_ASS_TYPE_SURFACE) + do i = 1, size(surfsMatAssPtr) + surfMatAss = this%buildMaterialAssociation(surfsMatAssPtr(i)) + mat = this%matTable%getId(surfMatAss%materialId) if (this%getStrAt(mat%p, J_TYPE) == J_MAT_TYPE_MULTILAYERED_SURFACE) then - nLossySurfaces = nLossySurfaces + 1 + nLossySurfaces = nLossySurfaces + size(surfMatAss%elementIds) end if end do if (nLossySurfaces == 0) then - res = emptyLossyThinSurfaces() - return - end if - - contains - function emptyLossyThinSurfaces() result (res) - type(LossyThinSurfaces) :: res allocate(res%cs(0)) res%length = 0 res%length_max = 0 res%nC_max = 0 - end function + return + end if + + allocate(res%cs(nLossySurfaces)) + res%length = nLossySurfaces + res%length_max = nLossySurfaces + res%nC_max = nLossySurfaces + do i = 1, size(surfsMatAssPtr) + surfMatAss = this%buildMaterialAssociation(surfsMatAssPtr(i)) + ! WIP + + end do + end function function readPlanewaves(this) result (res) diff --git a/test/smbjson/test_idchildtable.F90 b/test/smbjson/test_idchildtable.F90 index 9e1f2008..5d63cb79 100644 --- a/test/smbjson/test_idchildtable.F90 +++ b/test/smbjson/test_idchildtable.F90 @@ -55,7 +55,7 @@ integer function test_idchildtable() bind(C) result(err) tbl = IdChildTable_t(core, root, J_MATERIALS) - if (tbl%count() /= 2) err = err + 1 + if (tbl%totalSize() /= 2) err = err + 1 block character (len=:), allocatable :: matType logical :: found From f04f9ce90f0f4f14a08bb362bb5059172e872539 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Sat, 7 Dec 2024 11:55:24 +0100 Subject: [PATCH 04/25] [WIP] --- src_json_parser/mesh.F90 | 2 +- src_json_parser/smbjson.F90 | 199 +++++++++++++++++++---------- src_json_parser/smbjson_labels.F90 | 7 + 3 files changed, 138 insertions(+), 70 deletions(-) diff --git a/src_json_parser/mesh.F90 b/src_json_parser/mesh.F90 index 2da6bdb9..6213ef77 100644 --- a/src_json_parser/mesh.F90 +++ b/src_json_parser/mesh.F90 @@ -99,7 +99,7 @@ function mesh_checkElementId(this, id) result(stat) class(mesh_t) :: this integer, intent(in) :: id integer :: stat - call this%coordinates%check_key(key(id), stat) + call this%elements%check_key(key(id), stat) end function subroutine mesh_addCoordinate(this, id, coordinate) diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 4a6987d6..720f1333 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -96,55 +96,6 @@ module smbjson logical :: isLogarithmicFrequencySpacing end type contains - function buildMaterialAssociation(this, matAss) result(res) - class(parser_t) :: this - type(json_value_ptr), intent(in) :: matAss - type(materialAssociation_t) :: res - character (len=*), parameter :: errorMsgInit = "ERROR reading material association: " - logical :: found - - ! Fills material association. - res%materialId = this%getIntAt(matAss%p, J_MATERIAL_ID, found) - if (.not. found) call showLabelNotFoundError(J_MATERIAL_ID) - res%elementIds = this%getIntsAt(matAss%p, J_ELEMENTIDS, found) - if (.not. found) call showLabelNotFoundError(J_ELEMENTIDS) - res%matAssType = this%getStrAt(matAss%p, J_TYPE, found) - if (.not. found) call showLabelNotFoundError(J_TYPE) - res%name = this%getStrAt(matAss%p, J_NAME, found) - if (.not. found) then - res%name = "" - end if - - ! Checks validity of associations. - if (this%matTable%checkId(res%materialId) /= 0) then - write(error_unit, *) errorMsgInit, "material with id ", res%materialId, " not found." - endif - - if (size(res%elementIds) == 0) then - write(error_unit, *) errorMsgInit, J_ELEMENTIDS, "must not be empty." - end if - block - integer :: i - do i = 1, size(res%elementIds) - if (this%mesh%checkElementId(res%elementIds(i)) /= 0) then - write(error_unit, *) errorMsgInit, "element with id ", res%elementIds(i), " not found." - end if - end do - end block - - if (res%matAssType /= J_MAT_ASS_TYPE_BULK .or. & - res%matAssType /= J_MAT_ASS_TYPE_SURFACE .or. & - res%matAssType /= J_MAT_ASS_TYPE_CABLE) then - write(error_unit, *) errorMsgInit, "invalid type." - endif - - contains - subroutine showLabelNotFoundError(label) - character (len=*), intent(in) :: label - write(error_unit, *) errorMsgInit, label, " not found." - end subroutine - end function - function parser_ctor(filename) result(res) type(parser_t) :: res character(len=*), intent(in) :: filename @@ -450,33 +401,34 @@ function buildPECPMCRegion(cRs) result(res) function readLossyThinSurfaces(this) result (res) class(parser_t), intent(in) :: this type(LossyThinSurfaces) :: res + type(json_value_ptr), dimension(:), allocatable :: surfsMatAssPtrs type(json_value), pointer :: matAss - type(json_value_ptr), dimension(:), allocatable :: surfsMatAssPtr - type(json_value_ptr) :: mat - type(json_value), pointer :: jmrs, jmr - type(json_value_ptr) :: jm - integer, dimension(:), allocatable :: eIds - type(cell_region_t) :: cR + type(json_value_ptr), pointer :: mat integer :: nLossySurfaces logical :: found - integer :: i + integer :: i, j type(materialAssociation_t) :: surfMatAss + call this%core%get(this%root, J_MATERIAL_ASSOCIATIONS, matAss, found) + if (.not. found) then + res = emptyLossyThinSurfaces() + return + end if + + ! Precounts nLossySurfaces = 0 - surfsMatAssPtr = this%jsonValueFilterByKeyValue(matAss, J_TYPE, J_MAT_ASS_TYPE_SURFACE) - do i = 1, size(surfsMatAssPtr) - surfMatAss = this%buildMaterialAssociation(surfsMatAssPtr(i)) + surfsMatAssPtrs = this%jsonValueFilterByKeyValue(matAss, J_TYPE, J_MAT_ASS_TYPE_SURFACE) + do i = 1, size(surfsMatAssPtrs) + surfMatAss = this%buildMaterialAssociation(surfsMatAssPtrs(i)) mat = this%matTable%getId(surfMatAss%materialId) if (this%getStrAt(mat%p, J_TYPE) == J_MAT_TYPE_MULTILAYERED_SURFACE) then nLossySurfaces = nLossySurfaces + size(surfMatAss%elementIds) end if end do + ! Fills if (nLossySurfaces == 0) then - allocate(res%cs(0)) - res%length = 0 - res%length_max = 0 - res%nC_max = 0 + res = emptyLossyThinSurfaces() return end if @@ -484,12 +436,65 @@ function readLossyThinSurfaces(this) result (res) res%length = nLossySurfaces res%length_max = nLossySurfaces res%nC_max = nLossySurfaces - do i = 1, size(surfsMatAssPtr) - surfMatAss = this%buildMaterialAssociation(surfsMatAssPtr(i)) - ! WIP - + do i = 1, size(surfsMatAssPtrs) + surfMatAss = this%buildMaterialAssociation(surfsMatAssPtrs(i)) + mat = this%matTable%getId(surfMatAss%materialId) + if (this%getStrAt(mat%p, J_TYPE) == J_MAT_TYPE_MULTILAYERED_SURFACE) then + do j = 1, size(surfMatAss%elementIds) + res%cs(i+j) = readLossyThinSurface(mat%p, surfMatAss%elementIds(j)) + end do + end if end do + + contains + function readLossyThinSurface(mat, eId) result(res) + type(json_value), pointer, intent(in) :: mat + integer, intent(in) :: eId + type(LossyThinSurface) :: res + logical :: found + character (len=*), parameter :: errorMsgInit = "ERROR reading lossy thin surface: " + + ! Reads coordinates. + !!!! WIP + + ! Reads layers. + block + integer :: i + type(json_value), pointer :: layer + type(json_value), pointer :: layers + + call this%core%get(mat, J_MAT_MULTILAYERED_SURF_LAYERS, layers, found) + if (.not. found) then + write(error_unit, *) errorMsgInit, J_MAT_MULTILAYERED_SURF_LAYERS, " not found." + end if + res%numcapas = this%core%count(layers) + allocate(res%sigma( res%numcapas)) + allocate(res%eps( res%numcapas)) + allocate(res%mu( res%numcapas)) + allocate(res%sigmam(res%numcapas)) + allocate(res%thk( res%numcapas)) + do i = 1, res%numcapas + call this%core%get_child(layers, i, layer) + res%sigma(i) = this%getRealAt(layer, J_MAT_ELECTRIC_CONDUCTIVITY, default=0.0) + res%sigmam(i) = this%getRealAt(layer, J_MAT_MAGNETIC_CONDUCTIVITY, default=0.0) + res%eps(i) = this%getRealAt(layer, J_MAT_REL_PERMITTIVITY, default=1.0) * EPSILON_VACUUM + res%mu(i) = this%getRealAt(layer, J_MAT_REL_PERMEABILITY, default=1.0) * MU_VACUUM + res%thk(i) = this%getRealAt(layer, J_MAT_MULTILAYERED_SURF_THICKNESS, found) + if (.not. found) then + write(error_unit, *) errorMsgInit, J_MAT_MULTILAYERED_SURF_THICKNESS, " in layer not found." + end if + end do + end block + end function + + function emptyLossyThinSurfaces() result (res) + type(LossyThinSurfaces) :: res + allocate(res%cs(0)) + res%length = 0 + res%length_max = 0 + res%nC_max = 0 + end function end function function readPlanewaves(this) result (res) @@ -1542,6 +1547,61 @@ function getNPDomainType(typeLabel, hasTransferFunction) result(res) end function end function + function buildMaterialAssociation(this, matAss) result(res) + class(parser_t) :: this + type(json_value_ptr), intent(in) :: matAss + type(materialAssociation_t) :: res + character (len=*), parameter :: errorMsgInit = "ERROR reading material association: " + logical :: found + + ! Fills material association. + res%materialId = this%getIntAt(matAss%p, J_MATERIAL_ID, found) + if (.not. found) call showLabelNotFoundError(J_MATERIAL_ID) + res%elementIds = this%getIntsAt(matAss%p, J_ELEMENTIDS, found) + if (.not. found) call showLabelNotFoundError(J_ELEMENTIDS) + res%matAssType = this%getStrAt(matAss%p, J_TYPE, found) + if (.not. found) call showLabelNotFoundError(J_TYPE) + res%name = this%getStrAt(matAss%p, J_NAME, found) + if (.not. found) then + res%name = "" + end if + + ! Checks validity of associations. + if (this%matTable%checkId(res%materialId) /= 0) then + write(error_unit, *) errorMsgInit, "material with id ", res%materialId, " not found." + endif + + if (size(res%elementIds) == 0) then + write(error_unit, *) errorMsgInit, J_ELEMENTIDS, "must not be empty." + end if + block + integer :: i + do i = 1, size(res%elementIds) + if (this%mesh%checkElementId(res%elementIds(i)) /= 0) then + write(error_unit, *) errorMsgInit, "element with id ", res%elementIds(i), " not found." + end if + end do + end block + + if (res%matAssType /= J_MAT_ASS_TYPE_BULK .or. & + res%matAssType /= J_MAT_ASS_TYPE_SURFACE .or. & + res%matAssType /= J_MAT_ASS_TYPE_CABLE) then + write(error_unit, *) errorMsgInit, "invalid type." + endif + ! This function does not work with material associatiosn for cables. + ! DO NOT use it to read that. + if (res%matAssType /= J_MAT_ASS_TYPE_CABLE) then + write(error_unit, *) errorMsgInit, "invalid type." + endif + + + contains + subroutine showLabelNotFoundError(label) + character (len=*), intent(in) :: label + write(error_unit, *) errorMsgInit, label, " not found." + end subroutine + end function + function readMTLN(this, grid) result (mtln_res) class(parser_t) :: this type(Desplazamiento), intent(in) :: grid @@ -2797,13 +2857,14 @@ function getIntsAt(this, place, path, found) result(res) call this%core%get(place, path, res, found) end function - function getRealAt(this, place, path, found) result(res) + function getRealAt(this, place, path, found, default) result(res) real :: res class(parser_t) :: this type(json_value), pointer :: place character(len=*) :: path logical, intent(out), optional :: found - call this%core%get(place, path, res, found) + real, optional :: default + call this%core%get(place, path, res, found, default) end function function getRealsAt(this, place, path, found) result(res) diff --git a/src_json_parser/smbjson_labels.F90 b/src_json_parser/smbjson_labels.F90 index d94364c5..55d219f7 100644 --- a/src_json_parser/smbjson_labels.F90 +++ b/src_json_parser/smbjson_labels.F90 @@ -22,6 +22,10 @@ module smbjson_labels_mod ! -- materials character (len=*), parameter :: J_MATERIALS = "materials" + character (len=*), parameter :: J_MAT_REL_PERMITTIVITY = "relativePermittivity" + character (len=*), parameter :: J_MAT_REL_PERMEABILITY = "relativePermeability" + character (len=*), parameter :: J_MAT_ELECTRIC_CONDUCTIVITY = "electricConductivity" + character (len=*), parameter :: J_MAT_MAGNETIC_CONDUCTIVITY = "magneticConductivity" character (len=*), parameter :: J_MAT_TYPE_PEC = "pec" character (len=*), parameter :: J_MAT_TYPE_PMC = "pmc" @@ -60,6 +64,9 @@ module smbjson_labels_mod character (len=*), parameter :: J_MAT_MULTIWIRE_RESISTANCE = "resistancePerMeter" character (len=*), parameter :: J_MAT_MULTIWIRE_CONDUCTANCE = "conductancePerMeter" + character (len=*), parameter :: J_MAT_MULTILAYERED_SURF_LAYERS = "layers" + character (len=*), parameter :: J_MAT_MULTILAYERED_SURF_THICKNESS = "thickness" + ! -- materialAssociations character (len=*), parameter :: J_MATERIAL_ASSOCIATIONS = "materialAssociations" character (len=*), parameter :: J_MATERIAL_ID = "materialId" From 14c6221308a1a5813b0bf99e7f01149d06467658 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Sat, 7 Dec 2024 17:54:00 +0100 Subject: [PATCH 05/25] [WIP] Debugging sgbc test --- doc/smbjson.md | 2 +- src_json_parser/parser_tools.F90 | 28 +++++-- src_json_parser/smbjson.F90 | 138 ++++++++++++++++++++----------- 3 files changed, 112 insertions(+), 56 deletions(-) diff --git a/doc/smbjson.md b/doc/smbjson.md index 409890db..de4dc184 100644 --- a/doc/smbjson.md +++ b/doc/smbjson.md @@ -51,7 +51,7 @@ The following entries are shared by several FDTD-JSON objects and have a common + `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. ++ `[name]` is an optional entry which is used to make the FDTD-JSON input human-readable, helping to identify inputs and outputs. The following characters are reserved and can't be used in a `name`: `@`. ### `` diff --git a/src_json_parser/parser_tools.F90 b/src_json_parser/parser_tools.F90 index 07709aa6..5e058e8f 100644 --- a/src_json_parser/parser_tools.F90 +++ b/src_json_parser/parser_tools.F90 @@ -61,15 +61,21 @@ function getIntervalsInCellRegions(cellRegions, cellType) result (intervals) end function - subroutine cellRegionsToCoords(res, cellRegions, cellType) + subroutine cellRegionsToCoords(res, cellRegions, cellType, tag) type(coords), dimension(:), pointer :: res type(cell_region_t), dimension(:), intent(in) :: cellRegions integer, intent(in), optional :: cellType + character (LEN=BUFSIZE), optional, intent(in) :: tag + type(cell_interval_t), dimension(:), allocatable :: intervals type(coords), dimension(:), allocatable :: cs intervals = getIntervalsInCellRegions(cellRegions, cellType) - cs = cellIntervalsToCoords(intervals) + if (present(tag)) then + cs = cellIntervalsToCoords(intervals, tag) + else + cs = cellIntervalsToCoords(intervals) + endif allocate(res(size(cs))) res = cs end @@ -110,24 +116,30 @@ function coordsToScaledCoords(cs) result(res) end do end - subroutine cellRegionsToScaledCoords(res, cellRegions) + subroutine cellRegionsToScaledCoords(res, cellRegions, tag) type(coords_scaled), dimension(:), pointer :: res type(cell_region_t), dimension(:), intent(in) :: cellRegions type(cell_interval_t), dimension(:), allocatable :: intervals type(coords), dimension(:), allocatable :: cs type(coords_scaled), dimension(:), allocatable :: scaledCoords + character (LEN=BUFSIZE), optional, intent(in) :: tag intervals = getIntervalsInCellRegions(cellRegions, CELL_TYPE_LINEL) - cs = cellIntervalsToCoords(intervals) + if (present(tag)) then + cs = cellIntervalsToCoords(intervals, tag) + else + cs = cellIntervalsToCoords(intervals) + endif scaledCoords = coordsToScaledCoords(cs) allocate(res(size(scaledCoords))) res = scaledCoords end - function cellIntervalsToCoords(ivls) result(res) + function cellIntervalsToCoords(ivls, tag) result(res) type(coords), dimension(:), pointer :: res type(cell_interval_t), dimension(:), intent(in) :: ivls integer :: i + character (LEN=BUFSIZE), optional, intent(in) :: tag allocate(res(size(ivls))) do i = 1, size(ivls) @@ -135,7 +147,11 @@ function cellIntervalsToCoords(ivls) result(res) call convertInterval(res(i)%Xi, res(i)%Xe, ivls(i), DIR_X) call convertInterval(res(i)%Yi, res(i)%Ye, ivls(i), DIR_Y) call convertInterval(res(i)%Zi, res(i)%Ze, ivls(i), DIR_Z) - res(i)%tag = '' + if (present(tag)) then + res(i)%tag = tag + else + res(i)%tag = '' + end if end do contains subroutine convertInterval(xi, xe, interval, dir) diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 720f1333..d1aae30b 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -26,45 +26,46 @@ module smbjson type(json_core), pointer :: core => null() type(json_value), pointer :: root => null() type(mesh_t) :: mesh - type(IdChildTable_t) :: matTable + type(IdChildTable_t) :: matTable, elementTable contains procedure :: readProblemDescription + procedure :: readMesh ! private - procedure :: readGeneral - procedure :: readGrid - procedure :: readMediaMatrix - procedure :: readPECRegions - procedure :: readPMCRegions - procedure :: readLossyThinSurfaces - procedure :: readBoundary - procedure :: readPlanewaves - procedure :: readNodalSources - procedure :: readProbes - procedure :: readMoreProbes - procedure :: readBlockProbes - procedure :: readVolumicProbes - procedure :: readThinWires + procedure, private :: readGeneral + procedure, private :: readGrid + procedure, private :: readMediaMatrix + procedure, private :: readPECRegions + procedure, private :: readPMCRegions + procedure, private :: readLossyThinSurfaces + procedure, private :: readBoundary + procedure, private :: readPlanewaves + procedure, private :: readNodalSources + procedure, private :: readProbes + procedure, private :: readMoreProbes + procedure, private :: readBlockProbes + procedure, private :: readVolumicProbes + procedure, private :: readThinWires ! - procedure :: readMesh ! - procedure :: readMTLN + procedure, private :: readMTLN ! - procedure :: getLogicalAt - procedure :: getIntAt - procedure :: getIntsAt - procedure :: getRealAt - procedure :: getRealsAt - procedure :: getMatrixAt - procedure :: getStrAt - procedure :: existsAt - procedure :: getCellRegionsWithMaterialType - procedure :: getDomain - procedure :: buildMaterialAssociation - procedure :: jsonValueFilterByKeyValue - procedure :: jsonValueFilterByKeyValues - procedure :: getSingleVolumeInElementsIds + procedure, private :: getLogicalAt + procedure, private :: getIntAt + procedure, private :: getIntsAt + procedure, private :: getRealAt + procedure, private :: getRealsAt + procedure, private :: getMatrixAt + procedure, private :: getStrAt + procedure, private :: existsAt + procedure, private :: getCellRegionsWithMaterialType + procedure, private :: getDomain + procedure, private :: buildMaterialAssociation + procedure, private :: buildTagName + procedure, private :: jsonValueFilterByKeyValue + procedure, private :: jsonValueFilterByKeyValues + procedure, private :: getSingleVolumeInElementsIds end type interface parser_t module procedure parser_ctor @@ -126,6 +127,7 @@ function readProblemDescription(this) result (res) this%mesh = this%readMesh() this%matTable = IdChildTable_t(this%core, this%root, J_MATERIALS) + this%elementTable = IdChildTable_t(this%core, this%root, J_MESH//'.'//J_ELEMENTS) call initializeProblemDescription(res) @@ -403,7 +405,7 @@ function readLossyThinSurfaces(this) result (res) type(LossyThinSurfaces) :: res type(json_value_ptr), dimension(:), allocatable :: surfsMatAssPtrs type(json_value), pointer :: matAss - type(json_value_ptr), pointer :: mat + type(json_value_ptr) :: mat integer :: nLossySurfaces logical :: found integer :: i, j @@ -421,9 +423,8 @@ function readLossyThinSurfaces(this) result (res) do i = 1, size(surfsMatAssPtrs) surfMatAss = this%buildMaterialAssociation(surfsMatAssPtrs(i)) mat = this%matTable%getId(surfMatAss%materialId) - if (this%getStrAt(mat%p, J_TYPE) == J_MAT_TYPE_MULTILAYERED_SURFACE) then - nLossySurfaces = nLossySurfaces + size(surfMatAss%elementIds) - end if + if (this%getStrAt(mat%p, J_TYPE) /= J_MAT_TYPE_MULTILAYERED_SURFACE) cycle + nLossySurfaces = nLossySurfaces + size(surfMatAss%elementIds) end do ! Fills @@ -439,32 +440,41 @@ function readLossyThinSurfaces(this) result (res) do i = 1, size(surfsMatAssPtrs) surfMatAss = this%buildMaterialAssociation(surfsMatAssPtrs(i)) mat = this%matTable%getId(surfMatAss%materialId) - if (this%getStrAt(mat%p, J_TYPE) == J_MAT_TYPE_MULTILAYERED_SURFACE) then - do j = 1, size(surfMatAss%elementIds) - res%cs(i+j) = readLossyThinSurface(mat%p, surfMatAss%elementIds(j)) - end do - end if + if (this%getStrAt(mat%p, J_TYPE) /= J_MAT_TYPE_MULTILAYERED_SURFACE) cycle + do j = 1, size(surfMatAss%elementIds) + res%cs(i+j-1) = readLossyThinSurface(surfMatAss%materialId, surfMatAss%elementIds(j)) + end do end do contains - function readLossyThinSurface(mat, eId) result(res) - type(json_value), pointer, intent(in) :: mat + function readLossyThinSurface(matId, eId) result(res) + integer, intent(in) :: matId integer, intent(in) :: eId type(LossyThinSurface) :: res logical :: found character (len=*), parameter :: errorMsgInit = "ERROR reading lossy thin surface: " - + ! Reads coordinates. - !!!! WIP + block + type(cell_region_t), dimension(:), allocatable :: cRs + cRs = this%mesh%getCellRegions([eId]) + if (size(cRs) /= 1) then + write(error_unit, *) errorMsgInit, "problem finding cell regions in element ", eId + end if + res%nc = 1 + res%c = cellIntervalsToCoords(cRs(1)%intervals, this%buildTagName(matId, eId)) + end block ! Reads layers. block integer :: i + type(json_value_ptr) :: mat type(json_value), pointer :: layer type(json_value), pointer :: layers - call this%core%get(mat, J_MAT_MULTILAYERED_SURF_LAYERS, layers, found) + mat = this%matTable%getId(surfMatAss%materialId) + call this%core%get(mat%p, J_MAT_MULTILAYERED_SURF_LAYERS, layers, found) if (.not. found) then write(error_unit, *) errorMsgInit, J_MAT_MULTILAYERED_SURF_LAYERS, " not found." end if @@ -1583,17 +1593,16 @@ function buildMaterialAssociation(this, matAss) result(res) end do end block - if (res%matAssType /= J_MAT_ASS_TYPE_BULK .or. & - res%matAssType /= J_MAT_ASS_TYPE_SURFACE .or. & + if (res%matAssType /= J_MAT_ASS_TYPE_BULK .and. & + res%matAssType /= J_MAT_ASS_TYPE_SURFACE .and. & res%matAssType /= J_MAT_ASS_TYPE_CABLE) then write(error_unit, *) errorMsgInit, "invalid type." endif ! This function does not work with material associatiosn for cables. ! DO NOT use it to read that. - if (res%matAssType /= J_MAT_ASS_TYPE_CABLE) then + if (res%matAssType == J_MAT_ASS_TYPE_CABLE) then write(error_unit, *) errorMsgInit, "invalid type." endif - contains subroutine showLabelNotFoundError(label) @@ -1602,6 +1611,37 @@ subroutine showLabelNotFoundError(label) end subroutine end function + function buildTagName(this, matId, elementId) result(res) + class(parser_t) :: this + integer, intent(in) :: matId, elementId + character(len=BUFSIZE) :: res + character(len=BUFSIZE) :: matName, elemName + logical :: found + + block + type(json_value_ptr) :: mat + mat = this%matTable%getId(matId) + matName = this%getStrAt(mat%p, J_NAME, found) + if (.not. found) then + write(matName, *) 'material' + write(matName, '(a)') matId + end if + end block + + block + type(json_value_ptr) :: elem + elem = this%elementTable%getId(elementId) + elemName = this%getStrAt(elem%p, J_NAME, found) + if (.not. found) then + write(elemName, *) 'element' + write(elemName, '(a)') elementId + end if + end block + + res = trim(matName) // '@' // trim(elemName) + + end function + function readMTLN(this, grid) result (mtln_res) class(parser_t) :: this type(Desplazamiento), intent(in) :: grid From 05106013b3373dd20769c58c78ce9c97611f411e Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Sun, 8 Dec 2024 11:45:20 +0100 Subject: [PATCH 06/25] SGBC is parsed --- doc/smbjson.md | 2 +- src_json_parser/smbjson.F90 | 55 ++++++++++++++++++++++++++------- test/smbjson/test_read_sgbc.F90 | 7 +++-- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/doc/smbjson.md b/doc/smbjson.md index de4dc184..981f0887 100644 --- a/doc/smbjson.md +++ b/doc/smbjson.md @@ -51,7 +51,7 @@ The following entries are shared by several FDTD-JSON objects and have a common + `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. The following characters are reserved and can't be used in a `name`: `@`. ++ `[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 underscroes. The following characters are reserved and can't be used in a `name`: `@`. ### `` diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index d1aae30b..44bcfdfb 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -17,7 +17,9 @@ module smbjson implicit none - integer, private, parameter :: MAX_LINE = 256 + integer, private, parameter :: MAX_LINE = BUFSIZE + character (len=*), parameter :: TAG_MATERIAL = 'material' + character (len=*), parameter :: TAG_LAYER = 'layer' type, public :: parser_t private @@ -408,7 +410,7 @@ function readLossyThinSurfaces(this) result (res) type(json_value_ptr) :: mat integer :: nLossySurfaces logical :: found - integer :: i, j + integer :: i, j, k type(materialAssociation_t) :: surfMatAss call this%core%get(this%root, J_MATERIAL_ASSOCIATIONS, matAss, found) @@ -437,12 +439,14 @@ function readLossyThinSurfaces(this) result (res) res%length = nLossySurfaces res%length_max = nLossySurfaces res%nC_max = nLossySurfaces + k = 1 do i = 1, size(surfsMatAssPtrs) surfMatAss = this%buildMaterialAssociation(surfsMatAssPtrs(i)) mat = this%matTable%getId(surfMatAss%materialId) if (this%getStrAt(mat%p, J_TYPE) /= J_MAT_TYPE_MULTILAYERED_SURFACE) cycle do j = 1, size(surfMatAss%elementIds) - res%cs(i+j-1) = readLossyThinSurface(surfMatAss%materialId, surfMatAss%elementIds(j)) + res%cs(k) = readLossyThinSurface(surfMatAss%materialId, surfMatAss%elementIds(j)) + k = k + 1 end do end do @@ -463,7 +467,7 @@ function readLossyThinSurface(matId, eId) result(res) write(error_unit, *) errorMsgInit, "problem finding cell regions in element ", eId end if res%nc = 1 - res%c = cellIntervalsToCoords(cRs(1)%intervals, this%buildTagName(matId, eId)) + call cellRegionsToCoords(res%c, cRs, tag=this%buildTagName(matId, eId)) end block ! Reads layers. @@ -1615,7 +1619,7 @@ function buildTagName(this, matId, elementId) result(res) class(parser_t) :: this integer, intent(in) :: matId, elementId character(len=BUFSIZE) :: res - character(len=BUFSIZE) :: matName, elemName + character(len=:), allocatable :: matName, layerName logical :: found block @@ -1623,23 +1627,52 @@ function buildTagName(this, matId, elementId) result(res) mat = this%matTable%getId(matId) matName = this%getStrAt(mat%p, J_NAME, found) if (.not. found) then - write(matName, *) 'material' - write(matName, '(a)') matId + deallocate(matName) + allocate(character(len(TAG_MATERIAL) + 12) :: matName) + write(matName, '(a,i0)') TAG_MATERIAL, matId end if + matName = adaptName(matName) end block block type(json_value_ptr) :: elem elem = this%elementTable%getId(elementId) - elemName = this%getStrAt(elem%p, J_NAME, found) + layerName = this%getStrAt(elem%p, J_NAME, found) if (.not. found) then - write(elemName, *) 'element' - write(elemName, '(a)') elementId + deallocate(layerName) + allocate(character(len(TAG_LAYER) + 12) :: layerName) + write(layerName, '(a,i0)') TAG_LAYER, elementId end if + layerName = adaptName(layerName) end block - res = trim(matName) // '@' // trim(elemName) + call checkIsValidName(matName) + call checkIsValidName(layerName) + res = trim(matName // '@' // layerName) + contains + subroutine checkIsValidName(str) + character (len=:), allocatable, intent(in) :: str + character (len=*), parameter :: notAllowedChars = '@' + integer :: i + do i = 1, len((notAllowedChars)) + if (index(str, notAllowedChars(i:i)) /= 0) then + write(error_unit, *) "ERROR in name: ", str, & + " contains invalid character ", notAllowedChars(i:i) + end if + end do + end subroutine + function adaptName(str) result(res) + character (len=:), allocatable, intent(in) :: str + character (len=:), allocatable :: res + integer :: i + res = trim(adjustl(str)) + do i = 1, len(res) + if (res(i:i) == ' ') then + res(i:i) = '_' + end if + end do + end function end function function readMTLN(this, grid) result (mtln_res) diff --git a/test/smbjson/test_read_sgbc.F90 b/test/smbjson/test_read_sgbc.F90 index 91483031..601da26b 100644 --- a/test/smbjson/test_read_sgbc.F90 +++ b/test/smbjson/test_read_sgbc.F90 @@ -69,7 +69,8 @@ function expectedProblemDescription() result (expected) expected%pecRegs%Surfs(1)%Ye = 4 expected%pecRegs%Surfs(1)%Zi = 3 expected%pecRegs%Surfs(1)%Ze = 3 - expected%pecRegs%Surfs(1)%tag = 'pec-layer' + expected%pecRegs%Surfs(1)%tag = '' + ! expected%pecRegs%Surfs(1)%tag = 'pec-layer@layer1' !! Composites allocate(expected%lossyThinSurfs%cs(2)) @@ -80,7 +81,7 @@ function expectedProblemDescription() result (expected) !!! 2-layer composite allocate(expected%lossyThinSurfs%cs(1)%c(1)) expected%lossyThinSurfs%cs(1)%nc = 1 - expected%lossyThinSurfs%cs(1)%c(1)%tag = '2-layers-composite' + expected%lossyThinSurfs%cs(1)%c(1)%tag = '2-layers-composite@layer2' expected%lossyThinSurfs%cs(1)%c(1)%Or = +iEx expected%lossyThinSurfs%cs(1)%c(1)%Xi = 3 expected%lossyThinSurfs%cs(1)%c(1)%Xe = 4 @@ -103,7 +104,7 @@ function expectedProblemDescription() result (expected) !!! 3-layer composite allocate(expected%lossyThinSurfs%cs(2)%c(1)) expected%lossyThinSurfs%cs(2)%nc = 1 - expected%lossyThinSurfs%cs(2)%c(1)%tag = '3-layers-composite' + expected%lossyThinSurfs%cs(2)%c(1)%tag = '3-layers-composite@layer3' expected%lossyThinSurfs%cs(2)%c(1)%Or = +iEy expected%lossyThinSurfs%cs(2)%c(1)%Xi = 3 expected%lossyThinSurfs%cs(2)%c(1)%Xe = 3 From 73f67c137ae0ac2149aa739bda3fd436cd5f1eda Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Sun, 8 Dec 2024 13:04:48 +0100 Subject: [PATCH 07/25] Refactoring to include tags --- doc/smbjson.md | 10 +- src_json_parser/parser_tools.F90 | 9 +- src_json_parser/smbjson.F90 | 217 ++++++++++++++++---------- src_json_parser/smbjson_labels.F90 | 2 +- test/smbjson/smbjson_testingTools.F90 | 2 +- test/smbjson/test_read_sgbc.F90 | 3 +- testData/cases/sgbc.fdtd.json | 1 - 7 files changed, 146 insertions(+), 98 deletions(-) diff --git a/doc/smbjson.md b/doc/smbjson.md index 981f0887..133c8355 100644 --- a/doc/smbjson.md +++ b/doc/smbjson.md @@ -253,9 +253,9 @@ These materials represent a perfectly electrically conducting (`pec`) and perfec "materials": [ {"id": 1, "type": "pec"} ] ``` -#### `simple` +#### `isotropic` -A `material` with `type` `simple` 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$: +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$. @@ -268,7 +268,7 @@ A `material` with `type` `simple` represents an isotropic material with constant { "name": "teflon" "id": 1, - "type": "simple", + "type": "isotropic", "relativePermittivity": 2.5, "electricConducitivity": 1e-6 } @@ -280,7 +280,7 @@ In surface materials, `elementIds` must reference `cell` elements. All `interval #### `multilayeredSurface` -A `multilayeredSurface` must contain the entry `` which is an array indicating materials which are described in the same way as [simple materials](#simple) and a ``. +A `multilayeredSurface` must contain the entry `` which is an array indicating materials which are described in the same way as [isotropic materials](#isotropic) and a ``. ```json { @@ -456,7 +456,7 @@ This entry stores associations between `materials` and `elements` using their re ### `bulk` -Bulk materials such as `pec`, `pmc` or `simple` can be assigned to one or many elements of type `cell`. If the `cell` contains `intervals` representing points, these will be ignored. +Bulk 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. ```json "materialAssociations": [ diff --git a/src_json_parser/parser_tools.F90 b/src_json_parser/parser_tools.F90 index 5e058e8f..37427b7c 100644 --- a/src_json_parser/parser_tools.F90 +++ b/src_json_parser/parser_tools.F90 @@ -61,22 +61,21 @@ function getIntervalsInCellRegions(cellRegions, cellType) result (intervals) end function - subroutine cellRegionsToCoords(res, cellRegions, cellType, tag) - type(coords), dimension(:), pointer :: res - type(cell_region_t), dimension(:), intent(in) :: cellRegions + function cellRegionToCoords(cellRegion, cellType, tag) result(res) + type(cell_region_t), intent(in) :: cellRegion integer, intent(in), optional :: cellType character (LEN=BUFSIZE), optional, intent(in) :: tag + type(coords), dimension(:) :: res type(cell_interval_t), dimension(:), allocatable :: intervals type(coords), dimension(:), allocatable :: cs - intervals = getIntervalsInCellRegions(cellRegions, cellType) + intervals = getIntervalsInCellRegions([cellRegion], cellType) if (present(tag)) then cs = cellIntervalsToCoords(intervals, tag) else cs = cellIntervalsToCoords(intervals) endif - allocate(res(size(cs))) res = cs end diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 44bcfdfb..16a27951 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -61,8 +61,8 @@ module smbjson procedure, private :: getMatrixAt procedure, private :: getStrAt procedure, private :: existsAt - procedure, private :: getCellRegionsWithMaterialType procedure, private :: getDomain + procedure, private :: getMaterialAssociations procedure, private :: buildMaterialAssociation procedure, private :: buildTagName procedure, private :: jsonValueFilterByKeyValue @@ -375,58 +375,108 @@ function labelToBoundaryType(str) result (type) function readPECRegions(this) result (res) class(parser_t), intent(in) :: this type(PECRegions) :: res - type(cell_region_t), dimension(:), allocatable :: cRs - cRs = this%getCellRegionsWithMaterialType(J_MAT_TYPE_PEC) - res = buildPECPMCRegion(cRs) + res = buildPECPMCRegion(J_MAT_TYPE_PEC) end function function readPMCRegions(this) result (res) class(parser_t), intent(in) :: this type(PECRegions) :: res - type(cell_region_t), dimension(:), allocatable :: cRs - cRs = this%getCellRegionsWithMaterialType(J_MAT_TYPE_PMC) - res = buildPECPMCRegion(cRs) + res = buildPECPMCRegion(J_MAT_TYPE_PMC) end function - function buildPECPMCRegion(cRs) result(res) + function buildPECPMCRegion(this, matType) result(res) + class(parser_t) :: this + character (len=*), intent(in) :: matType type(PECRegions) :: res - type(cell_region_t), dimension(:), allocatable, intent(in) :: cRs - call cellRegionsToCoords(res%Lins, cRs, CELL_TYPE_LINEL) - call cellRegionsToCoords(res%Surfs, cRs, CELL_TYPE_SURFEL) - call cellRegionsToCoords(res%Vols, cRs, CELL_TYPE_VOXEL) - res%nLins = size(res%lins) - res%nSurfs = size(res%surfs) - res%nVols = size(res%vols) - res%nLins_max = size(res%Lins) - res%nSurfs_max = size(res%Surfs) - res%nVols_max = size(res%Vols) + integer :: nRegions + type(json_value_ptr), dimension(:), allocatable :: matAssPtrs + type(json_value), pointer :: matAss + type(materialAssociation_t) :: matAss + type(coords) :: auxCoords + + integer :: i, jLinel, jSurfs, jVols + character (len=:) :: tagName + + matAssPtrs = this%getMaterialAssociations(J_MAT_ASS_TYPE_BULK, matType) + + ! Precounts + res%nLins = countCoords(matAssPtrs, CELL_TYPE_LINEL) + res%nSurfs = countCoords(matAssPtrs, CELL_TYPE_SURFEL) + res%nVols = countCoords(matAssPtrs, CELL_TYPE_VOXEL) + res%nLins_max = res%nLins + res%nSurfs_max = res%nSurfs + res%nVols_max = res%nVols + + ! Fills + allocate(res%lins(res%nLins)) + allocate(res%surfs(res%nSurfs)) + allocate(res%vols(res%nLins)) + jLinel = 1 + jSurfs = 1 + jVols = 1 + do i = 1, size(matAssPtrs) + mat = this%buildMaterialAssociation(matAssPtrs(i)%p) + do e = 1, size(mat%elementIds) + tagName = this%buildTagName(mat%materialId, mat%elementIds(e)) + + auxCoords = cellRegionToCoords(cRs, CELL_TYPE_LINEL, tag=tagName) + res%lins(jLinel:(jLinel+size(auxCoords))) = auxCoords + jLinel = jLinel + size(auxCoords) + 1 + + auxCoords = cellRegionToCoords(cRs, CELL_TYPE_SURFEL, tag=tagName) + res%lins(jSurfs:(jSurfs+size(auxCoords))) = auxCoords + jSurfs = jSurfs + size(auxCoords) + 1 + + auxCoords = cellRegionToCoords(cRs, CELL_TYPE_VOXEL, tag=tagName) + res%vols(jVols:(jVols+size(auxCoords))) = auxCoords + jVols = jVols + size(auxCoords) + 1 + end do + end do + + contains + function countCoords(matAssPtrs, cellType) result(res) + type(json_value_ptr), dimension(:), allocatable, intent(in) :: matAssPtrs + character (len=:), intent(in) :: cellType + integer :: res + + type(materialAssociation_t) :: mat + type(cell_region_t) :: cR + integer :: i, j + type(coords), dimension(:), pointer :: cs + + res = 0 + do i = 1, size(matAssPtrs) + mat = this%buildMaterialAssociation(matAssPtrs%p) + do j = 1, size(mat%elementIds) + cR = this%mesh%getCellRegion(mat%elementIds(i)) + cs = cellRegionToCoords(cR, cellType) + res = res + size(cs) + end do + end do + end function + end function + + function readLossyThinSurfaces(this) result (res) class(parser_t), intent(in) :: this type(LossyThinSurfaces) :: res - type(json_value_ptr), dimension(:), allocatable :: surfsMatAssPtrs - type(json_value), pointer :: matAss + type(json_value_ptr), dimension(:), allocatable :: matAssPtrs type(json_value_ptr) :: mat integer :: nLossySurfaces logical :: found integer :: i, j, k - type(materialAssociation_t) :: surfMatAss + type(materialAssociation_t) :: matAss - call this%core%get(this%root, J_MATERIAL_ASSOCIATIONS, matAss, found) - if (.not. found) then - res = emptyLossyThinSurfaces() - return - end if + matAssPtrs = this%getMaterialAssociations(& + J_MAT_ASS_TYPE_SURFACE, J_MAT_TYPE_MULTILAYERED_SURFACE) - ! Precounts + ! Precounts nLossySurfaces = 0 - surfsMatAssPtrs = this%jsonValueFilterByKeyValue(matAss, J_TYPE, J_MAT_ASS_TYPE_SURFACE) - do i = 1, size(surfsMatAssPtrs) - surfMatAss = this%buildMaterialAssociation(surfsMatAssPtrs(i)) - mat = this%matTable%getId(surfMatAss%materialId) - if (this%getStrAt(mat%p, J_TYPE) /= J_MAT_TYPE_MULTILAYERED_SURFACE) cycle - nLossySurfaces = nLossySurfaces + size(surfMatAss%elementIds) + do i = 1, size(matAssPtrs) + matAss = this%buildMaterialAssociation(matAssPtrs(i)) + nLossySurfaces = nLossySurfaces + size(matAss%elementIds) end do ! Fills @@ -440,18 +490,15 @@ function readLossyThinSurfaces(this) result (res) res%length_max = nLossySurfaces res%nC_max = nLossySurfaces k = 1 - do i = 1, size(surfsMatAssPtrs) - surfMatAss = this%buildMaterialAssociation(surfsMatAssPtrs(i)) - mat = this%matTable%getId(surfMatAss%materialId) - if (this%getStrAt(mat%p, J_TYPE) /= J_MAT_TYPE_MULTILAYERED_SURFACE) cycle - do j = 1, size(surfMatAss%elementIds) - res%cs(k) = readLossyThinSurface(surfMatAss%materialId, surfMatAss%elementIds(j)) + do i = 1, size(matAssPtrs) + matAss = this%buildMaterialAssociation(matAssPtrs(i)) + do j = 1, size(matAss%elementIds) + res%cs(k) = readLossyThinSurface(matAss%materialId, matAss%elementIds(j)) k = k + 1 end do end do contains - function readLossyThinSurface(matId, eId) result(res) integer, intent(in) :: matId integer, intent(in) :: eId @@ -461,13 +508,8 @@ function readLossyThinSurface(matId, eId) result(res) ! Reads coordinates. block - type(cell_region_t), dimension(:), allocatable :: cRs - cRs = this%mesh%getCellRegions([eId]) - if (size(cRs) /= 1) then - write(error_unit, *) errorMsgInit, "problem finding cell regions in element ", eId - end if res%nc = 1 - call cellRegionsToCoords(res%c, cRs, tag=this%buildTagName(matId, eId)) + call cellRegionToCoords(res%c, cR = this%mesh%getCellRegion(eId), tag=this%buildTagName(matId, eId)) end block ! Reads layers. @@ -1615,6 +1657,52 @@ subroutine showLabelNotFoundError(label) end subroutine end function + function getMaterialAssociations(this, matAssType, materialType) + class(parser_t) :: this + type(json_value), pointer :: allMatAss + character(len=*), intent(in) :: matAssType + character(len=*), intent(in) :: materialType + type(json_value_ptr), dimension(:), allocatable :: res + + type(json_value_ptr), dimension(:), allocatable :: matAss + integer :: i, j + integer :: nMaterials + + call this%core%get(this%root, J_MATERIAL_ASSOCIATIONS, allMatAss, found) + if (.not. found) then + allocate(res(0)) + return + end if + + matAss = this%jsonValueFilterByKeyValue(matAss, J_TYPE, matAssType) + + nMaterials = 0 + do i = 1, size(matAssPtrs) + if (isAssociatedWithMaterial(materialType)) nMaterials = nMaterials + 1 + end do + + allocate(res(nMaterials)) + j = 1 + do i = 1, size(matAssPtrs) + if (isAssociatedWithMaterial(materialType)) then + res(j) = matAssPtrs(i) + j = j+1 + end if + end do + + contains + logical function isAssociatedWithMaterial(materialType) + character (len=*), intent(in) :: materialType + + type(materialAssociation_t) :: matAss + type(json_value_ptr) :: mat + + matAss = this%buildMaterialAssociation(matAssPtrs(i)) + mat = this%matTable%getId(matAss%materialId) + isAssociatedWithMaterial = this%getStrAt(mat%p, J_TYPE) == materialType + end function + end function + function buildTagName(this, matId, elementId) result(res) class(parser_t) :: this integer, intent(in) :: matId, elementId @@ -2989,43 +3077,6 @@ function existsAt(this, place, path) result(res) call this%core%info(place, path, found=res) end function - function getCellRegionsWithMaterialType(this, matType) result(res) - class(parser_t) :: this - character (len=*), intent(in) :: matType - type(cell_region_t), dimension(:), allocatable :: res - - logical :: found - type(json_value), pointer :: jmrs, jmr - type(json_value_ptr) :: jm - integer, dimension(:), allocatable :: eIds - type(cell_region_t) :: cR - integer :: i, j - integer :: numCellRegions - - call this%core%get(this%root, J_MATERIAL_ASSOCIATIONS, jmrs, found) - allocate(res(0)) - if (.not. found) then - return - end if - - do i = 1, this%core%count(jmrs) - call this%core%get_child(jmrs, i, jmr) - jm = this%matTable%getId(this%getIntAt(jmr, J_MATERIAL_ID, found)) - if (.not. found) & - write(error_unit, *) "Error reading material region: materialId label not found." - - if (matType == this%getStrAt(jm%p, J_TYPE)) then - eIds = this%getIntsAt(jmr, J_ELEMENTIDS) - do j = 1, size(eIds) - cR = this%mesh%getCellRegion(eIds(j), found) - if (found) then - res = [res, cR] - end if - end do - end if - end do - end function - function jsonValueFilterByKeyValues(this, srcs, key, values) result (res) class(parser_t) :: this type(json_value_ptr), dimension(:), allocatable :: res diff --git a/src_json_parser/smbjson_labels.F90 b/src_json_parser/smbjson_labels.F90 index 55d219f7..a5d3488f 100644 --- a/src_json_parser/smbjson_labels.F90 +++ b/src_json_parser/smbjson_labels.F90 @@ -29,7 +29,7 @@ module smbjson_labels_mod character (len=*), parameter :: J_MAT_TYPE_PEC = "pec" character (len=*), parameter :: J_MAT_TYPE_PMC = "pmc" - character (len=*), parameter :: J_MAT_TYPE_SIMPLE = "simple" + character (len=*), parameter :: J_MAT_TYPE_ISOTROPIC = "isotropic" character (len=*), parameter :: J_MAT_TYPE_MULTILAYERED_SURFACE = "multilayeredSurface" character (len=*), parameter :: J_MAT_TYPE_WIRE = "wire" character (len=*), parameter :: J_MAT_TYPE_MULTIWIRE = "multiwire" diff --git a/test/smbjson/smbjson_testingTools.F90 b/test/smbjson/smbjson_testingTools.F90 index 9460d3ff..9aedee6e 100644 --- a/test/smbjson/smbjson_testingTools.F90 +++ b/test/smbjson/smbjson_testingTools.F90 @@ -40,7 +40,6 @@ subroutine expect_eq(err, ex, pr, ignoreRegions) end if ! Sources - ! if (.not. ex%boxSrc == pr%boxSrc) call testFails(err, 'Expected and read "box sources" do not match') if (.not. ex%plnSrc == pr%plnSrc) call testFails(err, 'Expected and read "planewave sources" do not match') if (.not. ex%nodSrc == pr%nodSrc) call testFails(err, 'Expected and read "nodal sources" do not match') @@ -49,6 +48,7 @@ subroutine expect_eq(err, ex, pr, ignoreRegions) if (.not. ex%sonda == pr%sonda) call testFails(err, 'Expected and read "new probes" do not match') if (.not. ex%BloquePrb == pr%BloquePrb) call testFails(err, 'Expected and read "block probes" do not match') if (.not. ex%VolPrb == pr%VolPrb) call testFails(err, 'Expected and read "vol probes" do not match') + ! Thin elements if (.not. ex%tWires == pr%tWires) call testFails(err, 'Expected and read "thin wires" do not match') if (.not. ex%mtln == pr%mtln) call testFails(err, 'Expected and read mtln types do not match') diff --git a/test/smbjson/test_read_sgbc.F90 b/test/smbjson/test_read_sgbc.F90 index 601da26b..d64f8c35 100644 --- a/test/smbjson/test_read_sgbc.F90 +++ b/test/smbjson/test_read_sgbc.F90 @@ -69,8 +69,7 @@ function expectedProblemDescription() result (expected) expected%pecRegs%Surfs(1)%Ye = 4 expected%pecRegs%Surfs(1)%Zi = 3 expected%pecRegs%Surfs(1)%Ze = 3 - expected%pecRegs%Surfs(1)%tag = '' - ! expected%pecRegs%Surfs(1)%tag = 'pec-layer@layer1' + expected%pecRegs%Surfs(1)%tag = 'material1@layer1' !! Composites allocate(expected%lossyThinSurfs%cs(2)) diff --git a/testData/cases/sgbc.fdtd.json b/testData/cases/sgbc.fdtd.json index 57f53dc0..839d7c0d 100644 --- a/testData/cases/sgbc.fdtd.json +++ b/testData/cases/sgbc.fdtd.json @@ -25,7 +25,6 @@ "materials": [ { - "name": "pec-layer", "type": "pec", "id": 1 }, From 98eb056b4d6b8ba58e8921c7404f01d199648d01 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Mon, 9 Dec 2024 09:45:22 +0100 Subject: [PATCH 08/25] Compiles --- src_json_parser/parser_tools.F90 | 2 +- src_json_parser/smbjson.F90 | 169 ++++++++++++++----------------- 2 files changed, 79 insertions(+), 92 deletions(-) diff --git a/src_json_parser/parser_tools.F90 b/src_json_parser/parser_tools.F90 index 37427b7c..73551d90 100644 --- a/src_json_parser/parser_tools.F90 +++ b/src_json_parser/parser_tools.F90 @@ -65,7 +65,7 @@ function cellRegionToCoords(cellRegion, cellType, tag) result(res) type(cell_region_t), intent(in) :: cellRegion integer, intent(in), optional :: cellType character (LEN=BUFSIZE), optional, intent(in) :: tag - type(coords), dimension(:) :: res + type(coords), dimension(:), allocatable :: res type(cell_interval_t), dimension(:), allocatable :: intervals type(coords), dimension(:), allocatable :: cs diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 16a27951..3e191213 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -62,6 +62,7 @@ module smbjson procedure, private :: getStrAt procedure, private :: existsAt procedure, private :: getDomain + procedure, private :: buildPECPMCRegions procedure, private :: getMaterialAssociations procedure, private :: buildMaterialAssociation procedure, private :: buildTagName @@ -375,90 +376,79 @@ function labelToBoundaryType(str) result (type) function readPECRegions(this) result (res) class(parser_t), intent(in) :: this type(PECRegions) :: res - res = buildPECPMCRegion(J_MAT_TYPE_PEC) + res = this%buildPECPMCRegions(J_MAT_TYPE_PEC) end function function readPMCRegions(this) result (res) class(parser_t), intent(in) :: this type(PECRegions) :: res - res = buildPECPMCRegion(J_MAT_TYPE_PMC) + res = this%buildPECPMCRegions(J_MAT_TYPE_PMC) end function - function buildPECPMCRegion(this, matType) result(res) + function buildPECPMCRegions(this, matType) result(res) class(parser_t) :: this character (len=*), intent(in) :: matType type(PECRegions) :: res - integer :: nRegions - type(json_value_ptr), dimension(:), allocatable :: matAssPtrs - type(json_value), pointer :: matAss - type(materialAssociation_t) :: matAss - type(coords) :: auxCoords - - integer :: i, jLinel, jSurfs, jVols - character (len=:) :: tagName - - matAssPtrs = this%getMaterialAssociations(J_MAT_ASS_TYPE_BULK, matType) - - ! Precounts - res%nLins = countCoords(matAssPtrs, CELL_TYPE_LINEL) - res%nSurfs = countCoords(matAssPtrs, CELL_TYPE_SURFEL) - res%nVols = countCoords(matAssPtrs, CELL_TYPE_VOXEL) - res%nLins_max = res%nLins - res%nSurfs_max = res%nSurfs - res%nVols_max = res%nVols - - ! Fills - allocate(res%lins(res%nLins)) - allocate(res%surfs(res%nSurfs)) - allocate(res%vols(res%nLins)) - jLinel = 1 - jSurfs = 1 - jVols = 1 - do i = 1, size(matAssPtrs) - mat = this%buildMaterialAssociation(matAssPtrs(i)%p) - do e = 1, size(mat%elementIds) - tagName = this%buildTagName(mat%materialId, mat%elementIds(e)) - - auxCoords = cellRegionToCoords(cRs, CELL_TYPE_LINEL, tag=tagName) - res%lins(jLinel:(jLinel+size(auxCoords))) = auxCoords - jLinel = jLinel + size(auxCoords) + 1 - - auxCoords = cellRegionToCoords(cRs, CELL_TYPE_SURFEL, tag=tagName) - res%lins(jSurfs:(jSurfs+size(auxCoords))) = auxCoords - jSurfs = jSurfs + size(auxCoords) + 1 - - auxCoords = cellRegionToCoords(cRs, CELL_TYPE_VOXEL, tag=tagName) - res%vols(jVols:(jVols+size(auxCoords))) = auxCoords - jVols = jVols + size(auxCoords) + 1 - end do - end do + type(json_value_ptr), dimension(:), allocatable :: mA + + ma = this%getMaterialAssociations(J_MAT_ASS_TYPE_BULK, matType) + call fillRegion(res%lins, res%nLins, res%nLins_max, buildRegionCoords(mA, CELL_TYPE_LINEL)) + call fillRegion(res%surfs, res%nSurfs, res%nSurfs_max, buildRegionCoords(mA, CELL_TYPE_SURFEL)) + call fillRegion(res%vols, res%nVols, res%nVols_max, buildRegionCoords(mA, CELL_TYPE_VOXEL)) + contains - function countCoords(matAssPtrs, cellType) result(res) + subroutine fillRegion(resCoords, resNCoords, resNCoordsMax, cs) + type(coords), dimension(:), pointer :: resCoords + integer, intent(out) :: resNCoords, resNCoordsMax + type(coords), dimension(:), allocatable, intent(in) :: cs + + allocate(resCoords(size(cs))) + resCoords(:) = cs(:) + resNCoords = size(cs) + resNCoordsMax = size(cs) + end subroutine + + function buildRegionCoords(matAssPtrs, cellType) result(res) type(json_value_ptr), dimension(:), allocatable, intent(in) :: matAssPtrs - character (len=:), intent(in) :: cellType - integer :: res + integer, intent(in) :: cellType + type(coords), dimension(:), allocatable :: res - type(materialAssociation_t) :: mat + type(materialAssociation_t) :: mA type(cell_region_t) :: cR - integer :: i, j - type(coords), dimension(:), pointer :: cs + integer :: i, j, e + integer :: nCs + character (len=:), allocatable :: tagName + type(coords), dimension(:), allocatable :: cs - res = 0 + ! Precounts + nCs = 0 do i = 1, size(matAssPtrs) - mat = this%buildMaterialAssociation(matAssPtrs%p) - do j = 1, size(mat%elementIds) - cR = this%mesh%getCellRegion(mat%elementIds(i)) + mA = this%buildMaterialAssociation(matAssPtrs(i)%p) + do j = 1, size(mA%elementIds) + cR = this%mesh%getCellRegion(mA%elementIds(i)) cs = cellRegionToCoords(cR, cellType) - res = res + size(cs) + nCs = nCs + size(cs) + end do + end do + + ! Fills + allocate(res(nCs)) + j = 1 + do i = 1, size(matAssPtrs) + mA = this%buildMaterialAssociation(matAssPtrs(i)%p) + do e = 1, size(mA%elementIds) + tagName = this%buildTagName(mA%materialId, mA%elementIds(e)) + cR = this%mesh%getCellRegion(mA%elementIds(i)) + cs = cellRegionToCoords(cR, cellType, tag=tagName) + res(j:(j+size(cs))) = cs + j = j + size(cs) + 1 end do end do end function end function - - function readLossyThinSurfaces(this) result (res) class(parser_t), intent(in) :: this type(LossyThinSurfaces) :: res @@ -467,7 +457,7 @@ function readLossyThinSurfaces(this) result (res) integer :: nLossySurfaces logical :: found integer :: i, j, k - type(materialAssociation_t) :: matAss + type(materialAssociation_t) :: mA matAssPtrs = this%getMaterialAssociations(& J_MAT_ASS_TYPE_SURFACE, J_MAT_TYPE_MULTILAYERED_SURFACE) @@ -475,8 +465,8 @@ function readLossyThinSurfaces(this) result (res) ! Precounts nLossySurfaces = 0 do i = 1, size(matAssPtrs) - matAss = this%buildMaterialAssociation(matAssPtrs(i)) - nLossySurfaces = nLossySurfaces + size(matAss%elementIds) + mA = this%buildMaterialAssociation(matAssPtrs(i)%p) + nLossySurfaces = nLossySurfaces + size(mA%elementIds) end do ! Fills @@ -491,9 +481,9 @@ function readLossyThinSurfaces(this) result (res) res%nC_max = nLossySurfaces k = 1 do i = 1, size(matAssPtrs) - matAss = this%buildMaterialAssociation(matAssPtrs(i)) - do j = 1, size(matAss%elementIds) - res%cs(k) = readLossyThinSurface(matAss%materialId, matAss%elementIds(j)) + mA = this%buildMaterialAssociation(matAssPtrs(i)%p) + do j = 1, size(mA%elementIds) + res%cs(k) = readLossyThinSurface(mA%materialId, mA%elementIds(j)) k = k + 1 end do end do @@ -507,23 +497,16 @@ function readLossyThinSurface(matId, eId) result(res) character (len=*), parameter :: errorMsgInit = "ERROR reading lossy thin surface: " ! Reads coordinates. - block - res%nc = 1 - call cellRegionToCoords(res%c, cR = this%mesh%getCellRegion(eId), tag=this%buildTagName(matId, eId)) - end block + res%nc = 1 + res%c = cellRegionToCoords(this%mesh%getCellRegion(eId), & + tag = this%buildTagName(matId, eId)) ! Reads layers. block integer :: i - type(json_value_ptr) :: mat type(json_value), pointer :: layer type(json_value), pointer :: layers - mat = this%matTable%getId(surfMatAss%materialId) - call this%core%get(mat%p, J_MAT_MULTILAYERED_SURF_LAYERS, layers, found) - if (.not. found) then - write(error_unit, *) errorMsgInit, J_MAT_MULTILAYERED_SURF_LAYERS, " not found." - end if res%numcapas = this%core%count(layers) allocate(res%sigma( res%numcapas)) allocate(res%eps( res%numcapas)) @@ -1605,19 +1588,19 @@ function getNPDomainType(typeLabel, hasTransferFunction) result(res) function buildMaterialAssociation(this, matAss) result(res) class(parser_t) :: this - type(json_value_ptr), intent(in) :: matAss + type(json_value), pointer, intent(in) :: matAss type(materialAssociation_t) :: res character (len=*), parameter :: errorMsgInit = "ERROR reading material association: " logical :: found ! Fills material association. - res%materialId = this%getIntAt(matAss%p, J_MATERIAL_ID, found) + res%materialId = this%getIntAt(matAss, J_MATERIAL_ID, found) if (.not. found) call showLabelNotFoundError(J_MATERIAL_ID) - res%elementIds = this%getIntsAt(matAss%p, J_ELEMENTIDS, found) + res%elementIds = this%getIntsAt(matAss, J_ELEMENTIDS, found) if (.not. found) call showLabelNotFoundError(J_ELEMENTIDS) - res%matAssType = this%getStrAt(matAss%p, J_TYPE, found) + res%matAssType = this%getStrAt(matAss, J_TYPE, found) if (.not. found) call showLabelNotFoundError(J_TYPE) - res%name = this%getStrAt(matAss%p, J_NAME, found) + res%name = this%getStrAt(matAss, J_NAME, found) if (.not. found) then res%name = "" end if @@ -1657,16 +1640,17 @@ subroutine showLabelNotFoundError(label) end subroutine end function - function getMaterialAssociations(this, matAssType, materialType) + function getMaterialAssociations(this, matAssType, materialType) result(res) class(parser_t) :: this type(json_value), pointer :: allMatAss character(len=*), intent(in) :: matAssType character(len=*), intent(in) :: materialType type(json_value_ptr), dimension(:), allocatable :: res - type(json_value_ptr), dimension(:), allocatable :: matAss + type(json_value_ptr), dimension(:), allocatable :: mAPtrs integer :: i, j integer :: nMaterials + logical :: found call this%core%get(this%root, J_MATERIAL_ASSOCIATIONS, allMatAss, found) if (.not. found) then @@ -1674,30 +1658,33 @@ function getMaterialAssociations(this, matAssType, materialType) return end if - matAss = this%jsonValueFilterByKeyValue(matAss, J_TYPE, matAssType) + mAPtrs = this%jsonValueFilterByKeyValue(allMatAss, J_TYPE, matAssType) nMaterials = 0 - do i = 1, size(matAssPtrs) - if (isAssociatedWithMaterial(materialType)) nMaterials = nMaterials + 1 + do i = 1, size(mAPtrs) + if (isAssociatedWithMaterial(mAPtrs(i)%p, materialType)) then + nMaterials = nMaterials + 1 + end if end do allocate(res(nMaterials)) j = 1 - do i = 1, size(matAssPtrs) - if (isAssociatedWithMaterial(materialType)) then - res(j) = matAssPtrs(i) + do i = 1, size(mAPtrs) + if (isAssociatedWithMaterial(mAPtrs(i)%p, materialType)) then + res(j) = mAPtrs(i) j = j+1 end if end do contains - logical function isAssociatedWithMaterial(materialType) + logical function isAssociatedWithMaterial(mAPtr, materialType) + type(json_value), pointer, intent(in) :: mAPtr character (len=*), intent(in) :: materialType type(materialAssociation_t) :: matAss type(json_value_ptr) :: mat - matAss = this%buildMaterialAssociation(matAssPtrs(i)) + matAss = this%buildMaterialAssociation(mAPtr) mat = this%matTable%getId(matAss%materialId) isAssociatedWithMaterial = this%getStrAt(mat%p, J_TYPE) == materialType end function From 141135cd58bcfeeeb284818e8d95d5eff901e96a Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Mon, 9 Dec 2024 09:54:16 +0100 Subject: [PATCH 09/25] Debugging after refactoring --- src_json_parser/smbjson.F90 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 3e191213..b7719601 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -495,12 +495,15 @@ function readLossyThinSurface(matId, eId) result(res) type(LossyThinSurface) :: res logical :: found character (len=*), parameter :: errorMsgInit = "ERROR reading lossy thin surface: " - + type(coords), dimension(:), allocatable :: cs ! Reads coordinates. res%nc = 1 - res%c = cellRegionToCoords(this%mesh%getCellRegion(eId), & + cs = cellRegionToCoords(this%mesh%getCellRegion(eId), & tag = this%buildTagName(matId, eId)) - + allocate(res%c(size(cs))) + res%c = cs(:) + + ! Reads layers. block integer :: i From 8d1fbac8b13032cc87f2b35a1fd7502fc6e06ade Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Mon, 9 Dec 2024 12:27:41 +0100 Subject: [PATCH 10/25] All unit test pass --- src_json_parser/nfdetypes_extension.F90 | 11 +++++++---- src_json_parser/smbjson.F90 | 18 +++++++++++++----- test/smbjson/test_read_connectedWires.F90 | 2 +- test/smbjson/test_read_currentinjection.F90 | 6 +++--- test/smbjson/test_read_towelHanger.F90 | 2 +- testData/cases/connectedWires.fdtd.json | 3 ++- testData/cases/currentInjection.fdtd.json | 15 +++++++-------- testData/cases/sgbc.fdtd.json | 2 +- testData/cases/towelHanger.fdtd.json | 3 ++- 9 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src_json_parser/nfdetypes_extension.F90 b/src_json_parser/nfdetypes_extension.F90 index 674937a3..f43e6992 100644 --- a/src_json_parser/nfdetypes_extension.F90 +++ b/src_json_parser/nfdetypes_extension.F90 @@ -227,10 +227,13 @@ elemental logical function pecregions_eq(a, b) pecregions_eq = & (a%nVols == b%nVols) .and. & (a%nSurfs == b%nSurfs) .and. & - (a%nLins == b%nLins) .and. & - all(a%Lins == b%Lins) .and. & - all(a%Vols == b%Vols) .and. & - all(a%Surfs == b%Surfs) + (a%nLins_max == b%nLins_max) .and. & + (a%nVols_max == b%nVols_max) .and. & + (a%nSurfs_max == b%nSurfs_max) .and. & + (a%nLins == b%nLins) + pecregions_eq = pecregions_eq .and. all(a%Lins == b%Lins) + pecregions_eq = pecregions_eq .and. all(a%surfs == b%surfs) + pecregions_eq = pecregions_eq .and. all(a%vols == b%vols) end function pecregions_eq diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index b7719601..0be46863 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -425,8 +425,8 @@ function buildRegionCoords(matAssPtrs, cellType) result(res) nCs = 0 do i = 1, size(matAssPtrs) mA = this%buildMaterialAssociation(matAssPtrs(i)%p) - do j = 1, size(mA%elementIds) - cR = this%mesh%getCellRegion(mA%elementIds(i)) + do e = 1, size(mA%elementIds) + cR = this%mesh%getCellRegion(mA%elementIds(e)) cs = cellRegionToCoords(cR, cellType) nCs = nCs + size(cs) end do @@ -439,10 +439,11 @@ function buildRegionCoords(matAssPtrs, cellType) result(res) mA = this%buildMaterialAssociation(matAssPtrs(i)%p) do e = 1, size(mA%elementIds) tagName = this%buildTagName(mA%materialId, mA%elementIds(e)) - cR = this%mesh%getCellRegion(mA%elementIds(i)) + cR = this%mesh%getCellRegion(mA%elementIds(e)) cs = cellRegionToCoords(cR, cellType, tag=tagName) - res(j:(j+size(cs))) = cs - j = j + size(cs) + 1 + if (size(cs) == 0) cycle + res(j:(j+size(cs)-1)) = cs + j = j + size(cs) end do end do end function @@ -507,9 +508,16 @@ function readLossyThinSurface(matId, eId) result(res) ! Reads layers. block integer :: i + type(json_value_ptr) :: mat type(json_value), pointer :: layer type(json_value), pointer :: layers + mat = this%matTable%getId(matId) + call this%core%get(mat%p, J_MAT_MULTILAYERED_SURF_LAYERS, layers, found) + if (.not. found) then + write(error_unit, *) errorMsgInit, J_MAT_MULTILAYERED_SURF_LAYERS, " not found." + end if + res%numcapas = this%core%count(layers) allocate(res%sigma( res%numcapas)) allocate(res%eps( res%numcapas)) diff --git a/test/smbjson/test_read_connectedWires.F90 b/test/smbjson/test_read_connectedWires.F90 index a0b0cd2c..fd25b3d0 100644 --- a/test/smbjson/test_read_connectedWires.F90 +++ b/test/smbjson/test_read_connectedWires.F90 @@ -74,7 +74,7 @@ function expectedProblemDescription() result (expected) expected%pecRegs%Surfs(1)%Ytrancos = 1 expected%pecRegs%Surfs(1)%Ztrancos = 1 expected%pecRegs%Surfs(1)%Or = 3 - expected%pecRegs%Surfs(1)%tag = trim(adjustl(" ")) + expected%pecRegs%Surfs(1)%tag = "aluminum@ground_plane" ! Expected probes ! sonda diff --git a/test/smbjson/test_read_currentinjection.F90 b/test/smbjson/test_read_currentinjection.F90 index 355c41ed..edd19c66 100644 --- a/test/smbjson/test_read_currentinjection.F90 +++ b/test/smbjson/test_read_currentinjection.F90 @@ -64,7 +64,7 @@ function expectedProblemDescription() result (expected) allocate(expected%pecRegs%Surfs(1)) allocate(expected%pecRegs%Lins(1)) - ! PEC square + ! Body expected%pecRegs%Surfs(1)%Or = +iEz expected%pecRegs%Surfs(1)%Xi = 5 expected%pecRegs%Surfs(1)%Xe = 14 @@ -72,7 +72,7 @@ function expectedProblemDescription() result (expected) expected%pecRegs%Surfs(1)%Ye = 14 expected%pecRegs%Surfs(1)%Zi = 10 expected%pecRegs%Surfs(1)%Ze = 10 - expected%pecRegs%Surfs(1)%tag = '' + expected%pecRegs%Surfs(1)%tag = 'aluminum@body' ! Exit line expected%pecRegs%Lins(1)%Or = +iEy @@ -82,7 +82,7 @@ function expectedProblemDescription() result (expected) expected%pecRegs%Lins(1)%Ye = 19 expected%pecRegs%Lins(1)%Zi = 10 expected%pecRegs%Lins(1)%Ze = 10 - expected%pecRegs%Lins(1)%tag = '' + expected%pecRegs%Lins(1)%tag = 'aluminum@exit' ! Expected sources. expected%nodSrc%n_nodSrc = 1 diff --git a/test/smbjson/test_read_towelHanger.F90 b/test/smbjson/test_read_towelHanger.F90 index a12cc61f..3548ba2c 100644 --- a/test/smbjson/test_read_towelHanger.F90 +++ b/test/smbjson/test_read_towelHanger.F90 @@ -74,7 +74,7 @@ function expectedProblemDescription() result (expected) expected%pecRegs%Surfs(1)%Ytrancos = 1 expected%pecRegs%Surfs(1)%Ztrancos = 1 expected%pecRegs%Surfs(1)%Or = 3 - expected%pecRegs%Surfs(1)%tag = trim(adjustl(" ")) + expected%pecRegs%Surfs(1)%tag = "copper@ground_plane" ! Expected probes ! sonda diff --git a/testData/cases/connectedWires.fdtd.json b/testData/cases/connectedWires.fdtd.json index eb549f47..8fe95f1e 100644 --- a/testData/cases/connectedWires.fdtd.json +++ b/testData/cases/connectedWires.fdtd.json @@ -35,6 +35,7 @@ "terminations": [{"type": "short"}] }, { + "name": "aluminum", "id": 4, "type": "pec" } @@ -55,7 +56,7 @@ "elements": [ {"id": 1, "type": "node", "coordinateIds": [1]}, {"id": 2, "type": "polyline", "coordinateIds": [1, 2, 5] }, - {"id": 3, "type": "cell", "intervals": [[[25, 20, 30], [45, 30, 30]]] }, + {"id": 3, "type": "cell", "name": "ground_plane", "intervals": [[[25, 20, 30], [45, 30, 30]]] }, {"id": 4, "type": "node", "coordinateIds": [4]}, {"id": 5, "type": "polyline", "coordinateIds": [5, 3, 4] }, {"id": 6, "type": "node", "coordinateIds": [5]} diff --git a/testData/cases/currentInjection.fdtd.json b/testData/cases/currentInjection.fdtd.json index 25a97c0d..9fa3a2d7 100644 --- a/testData/cases/currentInjection.fdtd.json +++ b/testData/cases/currentInjection.fdtd.json @@ -15,19 +15,18 @@ "steps": { "x": [0.1], "y": [0.1], "z": [0.1] } }, "elements": [ - {"id": 1, "type": "cell", "intervals": [ [[10, 0, 10], [10, 5, 10]] ]}, - {"id": 2, "type": "cell", "intervals": [ [[ 5, 5, 10], [15, 15, 10]] ]}, - {"id": 3, "type": "cell", "intervals": [ [[10, 15, 10], [10, 20, 10]] ]}, - {"id": 4, "type": "cell", "intervals": [ [[ 9, 2, 9], [11, 2, 11]] ]}, - {"id": 5, "type": "cell", "intervals": [ [[ 9, 17, 9], [11, 17, 11]] ]} + {"id": 1, "type": "cell", "name": "entry", "intervals": [ [[10, 0, 10], [10, 5, 10]] ]}, + {"id": 2, "type": "cell", "name": "body", "intervals": [ [[ 5, 5, 10], [15, 15, 10]] ]}, + {"id": 3, "type": "cell", "name": "exit", "intervals": [ [[10, 15, 10], [10, 20, 10]] ]}, + {"id": 4, "type": "cell", "name": "bulk_current_entry", "intervals": [ [[ 9, 2, 9], [11, 2, 11]] ]}, + {"id": 5, "type": "cell", "name": "bulk_current_exit", "intervals": [ [[ 9, 17, 9], [11, 17, 11]] ]} ] }, - "materials": [ {"id": 1, "type": "pec"} ], + "materials": [ {"id": 1, "type": "pec", "name": "aluminum"} ], "materialAssociations": [ - {"type": "bulk", "materialId": 1, "elementIds": [2]}, - {"type": "bulk", "materialId": 1, "elementIds": [3]} + {"type": "bulk", "materialId": 1, "elementIds": [2, 3]} ], "sources": [ diff --git a/testData/cases/sgbc.fdtd.json b/testData/cases/sgbc.fdtd.json index 839d7c0d..63c0cf48 100644 --- a/testData/cases/sgbc.fdtd.json +++ b/testData/cases/sgbc.fdtd.json @@ -51,7 +51,7 @@ "materialAssociations": [ { - "type": "surface", + "type": "bulk", "materialId": 1, "elementIds": [ 1 ] }, diff --git a/testData/cases/towelHanger.fdtd.json b/testData/cases/towelHanger.fdtd.json index 14f62848..4a83b382 100644 --- a/testData/cases/towelHanger.fdtd.json +++ b/testData/cases/towelHanger.fdtd.json @@ -38,6 +38,7 @@ "type": "short"}] }, { + "name": "copper", "id": 4, "type": "pec" } @@ -59,7 +60,7 @@ "elements": [ {"id": 1, "type": "node", "coordinateIds": [1]}, {"id": 2, "type": "polyline", "coordinateIds": [1, 2, 5, 3, 4] }, - {"id": 3, "type": "cell", "intervals": [[[25, 20, 30], [45, 30, 30]]] }, + {"id": 3, "type": "cell", "name": "ground_plane", "intervals": [[[25, 20, 30], [45, 30, 30]]] }, {"id": 4, "type": "node", "coordinateIds": [4]}, {"id": 5, "type": "cell", "intervals": [[[1, 1, 1], [59, 59, 59]]] }, {"id": 6, "type": "node", "coordinateIds": [5]} From 6f5fa7ca8250be32d227fcfcd01aca2a6ded8599 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Mon, 9 Dec 2024 13:41:50 +0100 Subject: [PATCH 11/25] [WIP] Adds dielectric test case --- doc/smbjson.md | 6 +- test/smbjson/smbjson_tests.h | 2 + test/smbjson/test_read_dielectricslab.F90 | 104 ++++++++++++++++++++++ testData/cases/dielectricSlab.fdtd.json | 87 ++++++++++++++++++ 4 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 test/smbjson/test_read_dielectricslab.F90 create mode 100644 testData/cases/dielectricSlab.fdtd.json diff --git a/doc/smbjson.md b/doc/smbjson.md index 133c8355..44696a69 100644 --- a/doc/smbjson.md +++ b/doc/smbjson.md @@ -88,9 +88,9 @@ These objects must contain a `` label which can be: + `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. TODO Change to an optional input which defaults to 10 layers - + `[order]`: TODO Change to an optional input which defaults to order 2. - + `[reflection]`: TODO Change to an optional input which defaults to 0.001 refl. + + `[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:** diff --git a/test/smbjson/smbjson_tests.h b/test/smbjson/smbjson_tests.h index a4525da6..c8a74dfb 100644 --- a/test/smbjson/smbjson_tests.h +++ b/test/smbjson/smbjson_tests.h @@ -14,6 +14,7 @@ extern "C" int test_parser_read_mesh(); extern "C" int test_read_planewave(); extern "C" int test_read_sgbc(); +extern "C" int test_read_dielectricslab(); extern "C" int test_read_holland1981(); extern "C" int test_read_towelhanger(); extern "C" int test_read_connectedwires(); @@ -36,6 +37,7 @@ TEST(smbjson, mesh_polyline_to_linel) { EXPECT_EQ(0, test_mesh_polyline_to_li TEST(smbjson, parser_ctor) { EXPECT_EQ(0, test_parser_ctor()); } TEST(smbjson, parser_read_mesh) { EXPECT_EQ(0, test_parser_read_mesh()); } TEST(smbjson, read_planewave) { EXPECT_EQ(0, test_read_planewave()); } +TEST(smbjson, read_dielectricslab) { EXPECT_EQ(0, test_read_dielectricslab()); } TEST(smbjson, read_sgbc) { EXPECT_EQ(0, test_read_sgbc()); } TEST(smbjson, read_holland1981) { EXPECT_EQ(0, test_read_holland1981()); } TEST(smbjson, read_towelhanger) { EXPECT_EQ(0, test_read_towelhanger()); } diff --git a/test/smbjson/test_read_dielectricslab.F90 b/test/smbjson/test_read_dielectricslab.F90 new file mode 100644 index 00000000..e773b059 --- /dev/null +++ b/test/smbjson/test_read_dielectricslab.F90 @@ -0,0 +1,104 @@ +integer function test_read_dielectric() bind (C) result(err) + use smbjson + use smbjson_testingTools + + implicit none + + character(len=*), parameter :: filename = PATH_TO_TEST_DATA//'cases/planewave.fdtd.json' + type(Parseador) :: pr, ex + type(parser_t) :: parser + logical :: areSame + err = 0 + + ex = expectedProblemDescription() + parser = parser_t(filename) + pr = parser%readProblemDescription() + call expect_eq(err, ex, pr) + +contains + function expectedProblemDescription() result (expected) + type(Parseador) :: expected + + call initializeProblemDescription(expected) + + ! Expected general info. + expected%general%dt = 10e-12 + expected%general%nmax = 2000 + + ! Excected media matrix. + expected%matriz%totalX = 4 + expected%matriz%totalY = 4 + expected%matriz%totalZ = 50 + + ! Expected grid. + expected%despl%nX = 4 + expected%despl%nY = 4 + expected%despl%nZ = 50 + + allocate(expected%despl%desX(4)) + allocate(expected%despl%desY(4)) + allocate(expected%despl%desZ(50)) + expected%despl%desX = 0.1 + expected%despl%desY = 0.1 + expected%despl%desZ = 0.1 + expected%despl%mx1 = 0 + expected%despl%mx2 = 4 + expected%despl%my1 = 0 + expected%despl%my2 = 4 + expected%despl%mz1 = 0 + expected%despl%mz2 = 50 + + ! Expected boundaries. + expected%front%tipoFrontera(F_XL) = F_PEC + expected%front%tipoFrontera(F_XU) = F_PEC + expected%front%tipoFrontera(F_YL) = F_PMC + expected%front%tipoFrontera(F_YU) = F_PMC + expected%front%tipoFrontera(F_ZL) = F_PML + expected%front%tipoFrontera(F_ZU) = F_PML + + ! Expected sources. + allocate(expected%plnSrc%collection(1)) + expected%plnSrc%collection(1)%nombre_fichero = "gauss.exc" + expected%plnSrc%collection(1)%atributo = "" + expected%plnSrc%collection(1)%coor1 = [1, 1, 1] + expected%plnSrc%collection(1)%coor2 = [8, 8, 8] + expected%plnSrc%collection(1)%theta = 0.0 + expected%plnSrc%collection(1)%phi = 0.0 + expected%plnSrc%collection(1)%alpha = 1.5708 + expected%plnSrc%collection(1)%beta = 0.0 + expected%plnSrc%collection(1)%isRC=.false. + expected%plnSrc%collection(1)%nummodes=1 + expected%plnSrc%collection(1)%INCERTMAX=0.0 + expected%plnSrc%nc = 1 + expected%plnSrc%nC_max = 1 + + + ! Expected probes + ! sonda + expected%Sonda%len_cor_max = 0 + expected%Sonda%length = 1 + expected%Sonda%length_max = 1 + allocate(expected%Sonda%collection(1)) + expected%Sonda%collection(1)%outputrequest = "electric_field_point_probe" + expected%Sonda%collection(1)%type1 = NP_T1_PLAIN + expected%Sonda%collection(1)%type2 = NP_T2_TIME + expected%Sonda%collection(1)%filename = ' ' + expected%Sonda%collection(1)%tstart = 0.0 + expected%Sonda%collection(1)%tstop = 0.0 + expected%Sonda%collection(1)%tstep = 0.0 + expected%Sonda%collection(1)%fstart = 0.0 + expected%Sonda%collection(1)%fstop = 0.0 + expected%Sonda%collection(1)%fstep = 0.0 + allocate(expected%Sonda%collection(1)%cordinates(3)) + expected%Sonda%collection(1)%len_cor = 3 + expected%Sonda%collection(1)%cordinates(1:3)%tag = "electric_field_point_probe" + expected%Sonda%collection(1)%cordinates(1:3)%Xi = 4 + expected%Sonda%collection(1)%cordinates(1:3)%Yi = 4 + expected%Sonda%collection(1)%cordinates(1:3)%Zi = 4 + expected%Sonda%collection(1)%cordinates(1)%Or = NP_COR_EX + expected%Sonda%collection(1)%cordinates(2)%Or = NP_COR_EY + expected%Sonda%collection(1)%cordinates(3)%Or = NP_COR_EZ + + end function +end function + diff --git a/testData/cases/dielectricSlab.fdtd.json b/testData/cases/dielectricSlab.fdtd.json new file mode 100644 index 00000000..872f73a7 --- /dev/null +++ b/testData/cases/dielectricSlab.fdtd.json @@ -0,0 +1,87 @@ +{ + "format": "FDTD Input file", + "__comments": "Planewave illuminating dielectric slab.", + + "general": { + "timeStep": 10e-12, + "numberOfSteps": 2000 + }, + + "boundary": { + "xLower": {"type": "pec"}, + "xUpper": {"type": "pec"}, + "yLower": {"type": "pmc"}, + "yUpper": {"type": "pmc"}, + "zLower": {"type": "pml"}, + "zUpper": {"type": "pml"} + }, + + "mesh": { + "grid": { + "numberOfCells": [4, 4, 50], + "steps": { "x": [0.1], "y": [0.1], "z": [0.1] } + }, + "coordinates": [ + {"id": 1, "relativePosition": [2, 2, 10]}, + {"id": 2, "relativePosition": [2, 2, 25]}, + {"id": 3, "relativePosition": [2, 2, 40]} + ], + "elements": [ + {"id": 1, "type": "node", "coordinateIds": [1]}, + {"id": 2, "type": "node", "coordinateIds": [2]}, + {"id": 3, "type": "node", "coordinateIds": [3]}, + {"id": 4, "type": "cell", "name": "pw-box", "intervals": [ [ [0, 0, 2], [4, 4, 48] ] ]}, + {"id": 5, "type": "cell", "name": "slab", "intervals": [ [ [0, 0, 20], [4, 4, 30] ] ]} + ] + }, + + "materials": [ + { + "name": "teflon", + "id": 1, + "type": "isotropic", + "relativePermittivity": 2.1 + } + ], + + "materialAssociations": [ + {"type": "bulk", "materialId": 1, "elementIds": [5]} + ], + + "sources": [ + { + "type": "planewave", + "magnitudeFile": "gauss.exc", + "elementIds": [4], + "direction": { + "theta": 0.0, + "phi": 0.0 + }, + "polarization": { + "theta": 1.5708, + "phi": 0.0 + } + } + ], + + "probes": [ + { + "name": "front", + "type": "point", + "field": "electric", + "elementIds": [1] + }, + { + "name": "inner", + "type": "point", + "field": "electric", + "elementIds": [2] + }, + { + "name": "back", + "type": "point", + "field": "electric", + "elementIds": [3] + } + ] +} \ No newline at end of file From 1bb13be309f23e92d0306d945c858787360d037d Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Tue, 10 Dec 2024 07:30:07 +0100 Subject: [PATCH 12/25] Added test to read dielectricslab --- test/smbjson/CMakeLists.txt | 1 + test/smbjson/test_read_dielectricslab.F90 | 96 +++++++++++++++++------ 2 files changed, 72 insertions(+), 25 deletions(-) diff --git a/test/smbjson/CMakeLists.txt b/test/smbjson/CMakeLists.txt index 1ef4eea1..8670fc2d 100644 --- a/test/smbjson/CMakeLists.txt +++ b/test/smbjson/CMakeLists.txt @@ -9,6 +9,7 @@ add_library (smbjson_test_fortran "test_mesh.F90" "test_parser.F90" "test_read_planewave.F90" + "test_read_dielectricslab.F90" "test_read_sgbc.F90" "test_read_holland1981.F90" "test_read_towelHanger.F90" diff --git a/test/smbjson/test_read_dielectricslab.F90 b/test/smbjson/test_read_dielectricslab.F90 index e773b059..822905a7 100644 --- a/test/smbjson/test_read_dielectricslab.F90 +++ b/test/smbjson/test_read_dielectricslab.F90 @@ -1,4 +1,4 @@ -integer function test_read_dielectric() bind (C) result(err) +integer function test_read_dielectricslab() bind (C) result(err) use smbjson use smbjson_testingTools @@ -18,6 +18,7 @@ integer function test_read_dielectric() bind (C) result(err) contains function expectedProblemDescription() result (expected) type(Parseador) :: expected + integer :: i call initializeProblemDescription(expected) @@ -60,8 +61,8 @@ function expectedProblemDescription() result (expected) allocate(expected%plnSrc%collection(1)) expected%plnSrc%collection(1)%nombre_fichero = "gauss.exc" expected%plnSrc%collection(1)%atributo = "" - expected%plnSrc%collection(1)%coor1 = [1, 1, 1] - expected%plnSrc%collection(1)%coor2 = [8, 8, 8] + expected%plnSrc%collection(1)%coor1 = [0, 0, 2] + expected%plnSrc%collection(1)%coor2 = [3, 3, 47] expected%plnSrc%collection(1)%theta = 0.0 expected%plnSrc%collection(1)%phi = 0.0 expected%plnSrc%collection(1)%alpha = 1.5708 @@ -72,33 +73,78 @@ function expectedProblemDescription() result (expected) expected%plnSrc%nc = 1 expected%plnSrc%nC_max = 1 + ! dielectric slab region + expected%dielRegs%nVols = 1 + expected%dielRegs%nSurfs = 0 + expected%dielRegs%nLins = 0 + expected%dielRegs%nVols_max = 1 + expected%dielRegs%nSurfs_max = 0 + expected%dielRegs%n_C1P_max = 0 + expected%dielRegs%n_C2P_max = 1 + allocate(expected%dielRegs%Vols(1)) + allocate(expected%dielRegs%Surfs(0)) + allocate(expected%dielRegs%Lins(0)) + ! slab + allocate(expected%dielRegs%vols(1)%c1P(0)) + allocate(expected%dielRegs%vols(1)%c2P(1)) + expected%dielRegs%vols(1)%n_C1P = 0 + expected%dielRegs%vols(1)%n_C2P = 1 + expected%dielRegs%vols(1)%sigma = 0.0 + expected%dielRegs%vols(1)%eps = 1.3*EPSILON_VACUUM + expected%dielRegs%vols(1)%mu = MU_VACUUM + expected%dielRegs%vols(1)%sigmam = 0.0 + expected%dielRegs%vols(1)%c2P%Or = 0 + expected%dielRegs%vols(1)%c2P%Xi = 0 + expected%dielRegs%vols(1)%c2P%Xe = 4 + expected%dielRegs%vols(1)%c2P%Yi = 0 + expected%dielRegs%vols(1)%c2P%Ye = 4 + expected%dielRegs%vols(1)%c2P%Zi = 20 + expected%dielRegs%vols(1)%c2P%Ze = 30 + expected%dielRegs%vols(1)%c2P%tag = 'teflon@slab' ! Expected probes ! sonda expected%Sonda%len_cor_max = 0 - expected%Sonda%length = 1 - expected%Sonda%length_max = 1 - allocate(expected%Sonda%collection(1)) - expected%Sonda%collection(1)%outputrequest = "electric_field_point_probe" - expected%Sonda%collection(1)%type1 = NP_T1_PLAIN - expected%Sonda%collection(1)%type2 = NP_T2_TIME - expected%Sonda%collection(1)%filename = ' ' - expected%Sonda%collection(1)%tstart = 0.0 - expected%Sonda%collection(1)%tstop = 0.0 - expected%Sonda%collection(1)%tstep = 0.0 - expected%Sonda%collection(1)%fstart = 0.0 - expected%Sonda%collection(1)%fstop = 0.0 - expected%Sonda%collection(1)%fstep = 0.0 - allocate(expected%Sonda%collection(1)%cordinates(3)) - expected%Sonda%collection(1)%len_cor = 3 - expected%Sonda%collection(1)%cordinates(1:3)%tag = "electric_field_point_probe" - expected%Sonda%collection(1)%cordinates(1:3)%Xi = 4 - expected%Sonda%collection(1)%cordinates(1:3)%Yi = 4 - expected%Sonda%collection(1)%cordinates(1:3)%Zi = 4 - expected%Sonda%collection(1)%cordinates(1)%Or = NP_COR_EX - expected%Sonda%collection(1)%cordinates(2)%Or = NP_COR_EY - expected%Sonda%collection(1)%cordinates(3)%Or = NP_COR_EZ + expected%Sonda%length = 3 + expected%Sonda%length_max = 3 + allocate(expected%Sonda%collection(3)) + ! common data + do i = 1, 3 + expected%Sonda%collection(i)%type1 = NP_T1_PLAIN + expected%Sonda%collection(i)%type2 = NP_T2_TIME + expected%Sonda%collection(i)%filename = ' ' + expected%Sonda%collection(i)%tstart = 0.0 + expected%Sonda%collection(i)%tstop = 0.0 + expected%Sonda%collection(i)%tstep = 0.0 + expected%Sonda%collection(i)%fstart = 0.0 + expected%Sonda%collection(i)%fstop = 0.0 + expected%Sonda%collection(i)%fstep = 0.0 + allocate(expected%Sonda%collection(i)%cordinates(3)) + expected%Sonda%collection(i)%cordinates(1)%Or = NP_COR_EX + expected%Sonda%collection(i)%cordinates(2)%Or = NP_COR_EY + expected%Sonda%collection(i)%cordinates(3)%Or = NP_COR_EZ + expected%Sonda%collection(i)%len_cor = 3 + end do + ! point probe at front + expected%Sonda%collection(1)%outputrequest = "front" + expected%Sonda%collection(1)%cordinates(1:3)%tag = "probe@layer1" + expected%Sonda%collection(1)%cordinates(1:3)%Xi = 2 + expected%Sonda%collection(1)%cordinates(1:3)%Yi = 2 + expected%Sonda%collection(1)%cordinates(1:3)%Zi = 10 + ! point probe in dielectric slab + expected%Sonda%collection(2)%outputrequest = "inner" + expected%Sonda%collection(2)%cordinates(1:3)%tag = "probe@layer2" + expected%Sonda%collection(2)%cordinates(1:3)%Xi = 2 + expected%Sonda%collection(2)%cordinates(1:3)%Yi = 2 + expected%Sonda%collection(2)%cordinates(1:3)%Zi = 25 + ! point probe at back + expected%Sonda%collection(3)%outputrequest = "back" + expected%Sonda%collection(3)%cordinates(1:3)%tag = "probe@layer2" + expected%Sonda%collection(3)%cordinates(1:3)%Xi = 2 + expected%Sonda%collection(3)%cordinates(1:3)%Yi = 2 + expected%Sonda%collection(3)%cordinates(1:3)%Zi = 40 + end function end function From 99efa9152ca7e7104d0111ad4409e61c53d3ce59 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Tue, 10 Dec 2024 12:32:59 +0100 Subject: [PATCH 13/25] Debugging readdielectric slab --- doc/smbjson.md | 1 + src_json_parser/nfdetypes_extension.F90 | 32 +++++- src_json_parser/smbjson.F90 | 131 +++++++++++++++------- src_json_parser/smbjson_labels.F90 | 7 ++ test/smbjson/test_read_dielectricslab.F90 | 2 +- 5 files changed, 128 insertions(+), 45 deletions(-) diff --git a/doc/smbjson.md b/doc/smbjson.md index 44696a69..6e1aa09c 100644 --- a/doc/smbjson.md +++ b/doc/smbjson.md @@ -85,6 +85,7 @@ These objects must contain a `` 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: diff --git a/src_json_parser/nfdetypes_extension.F90 b/src_json_parser/nfdetypes_extension.F90 index f43e6992..bd08a3a3 100644 --- a/src_json_parser/nfdetypes_extension.F90 +++ b/src_json_parser/nfdetypes_extension.F90 @@ -239,11 +239,10 @@ end function pecregions_eq elemental logical function dielectric_eq(a, b) type(dielectric_t), intent(in) :: a, b + logical :: allAssociated dielectric_eq = & (a%n_C1P == b%n_C1P) .and. & (a%n_C2P == b%n_C2P) .and. & - all(a%C1P == b%C1P) .and. & - all(a%C2P == b%C2P) .and. & (a%sigma == b%sigma) .and. & (a%eps == b%eps) .and. & (a%mu == b%mu) .and. & @@ -266,6 +265,15 @@ elemental logical function dielectric_eq(a, b) (a%diodo .eqv. b%diodo) .and. & (a%plain .eqv. b%plain) .and. & (a%PMLbody .eqv. b%PMLbody) + + allAssociated = & + associated(a%C1P) .and. associated(b%C1P) .and. & + associated(a%C2P) .and. associated(b%C2P) + if (.not. allAssociated) then + dielectric_eq = .false. + return + end if + dielectric_eq = all(a%C1P == b%C1P) .and. all(a%C2P == b%C2P) end function dielectric_eq elemental logical function freqdepenmaterial_eq(a, b) @@ -390,6 +398,17 @@ end function anisotropicelements_eq elemental logical function dielectricregions_eq(a, b) type(DielectricRegions), intent(in) :: a, b + logical :: allAssociated + + allAssociated = & + associated(a%Lins) .and. associated(b%Lins) .and. & + associated(a%Surfs) .and. associated(b%Surfs) .and. & + associated(a%Vols) .and. associated(b%Vols) + if (.not. allAssociated) then + dielectricregions_eq = .false. + return + end if + dielectricregions_eq = & a%nVols == b%nVols .and. & a%nSurfs == b%nSurfs .and. & @@ -398,10 +417,11 @@ elemental logical function dielectricregions_eq(a, b) a%nSurfs_max == b%nSurfs_max .and. & a%nLins_max == b%nLins_max .and. & a%n_C1P_max == b%n_C1P_max .and. & - a%n_C2P_max == b%n_C2P_max .and. & - all(a%Vols == b%Vols) .and. & - all(a%Surfs == b%Surfs) .and. & - all(a%Lins == b%Lins) + a%n_C2P_max == b%n_C2P_max + + dielectricregions_eq = dielectricregions_eq .and. all(a%Lins == b%Lins) + dielectricregions_eq = dielectricregions_eq .and. all(a%surfs == b%surfs) + dielectricregions_eq = dielectricregions_eq .and. all(a%vols == b%vols) end function dielectricregions_eq elemental logical function LossyThinSurface_eq(a, b) diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 0be46863..b2bc84bb 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -330,45 +330,86 @@ subroutine assignDes(path, dest, numberOfCells) function readBoundary(this) result (res) class(parser_t) :: this type(Frontera) :: res - character(kind=json_CK,len=:), allocatable :: boundaryTypeLabel - logical(LK) :: allLabelFound = .false. - real :: orden, refl - call this%core%get(this%root, J_BOUNDARY//'.'//J_BND_ALL//'.'//J_TYPE, boundaryTypeLabel, allLabelFound) - if (allLabelFound) then - res%tipoFrontera(:) = labelToBoundaryType(boundaryTypeLabel) - if (all(res%tipoFrontera == F_PML)) then - res%propiedadesPML(:) = readPMLProperties(J_BOUNDARY//"."//J_BND_ALL) - end if - return - else - ! TODO Check every bound. - write(error_unit,*) 'WIP: Boundaries of different types not implemented.' + character (len=:), allocatable :: bdrType + type(json_value), pointer :: bdrs + logical :: found + character(len=*), parameter :: errorMsgInit = "ERROR reading boundary: " + + call this%core%get(this%root, J_BOUNDARY, bdrs, found) + if (.not. found) then + write(error_unit, * ) errorMsgInit, J_BOUNDARY, " object not found." end if + + block + call this%core%get(bdrs, J_BND_ALL//'.'//J_TYPE, bdrType, found) + if (found) then + res%tipoFrontera(:) = labelToBoundaryType(bdrType) + if (all(res%tipoFrontera == F_PML)) then + res%propiedadesPML(:) = readPMLProperties(J_BOUNDARY//"."//J_BND_ALL) + end if + return + end if + end block + + block + character(len=*), dimension(6), parameter :: placeLabels = & + [J_BND_XL, J_BND_XU, J_BND_YL, J_BND_YU, J_BND_ZL, J_BND_ZU] + integer :: i, j + do i = 1, 6 + bdrType = this%getStrAt(bdrs, placeLabels(i)//"."//J_TYPE, found) + if (.not. found) then + write(error_unit, *) errorMsgInit, placeLabels(i), " or ", J_BND_ALL, " not found." + end if + j = labelToBoundaryPlace(placeLabels(i)) + res%tipoFrontera(j) = labelToBoundaryType(bdrType) + if (res%tipoFrontera(j) == F_PML) then + res%propiedadesPML(j) = readPMLProperties(J_BOUNDARY//"."//placeLabels(i)) + end if + end do + end block + contains function readPMLProperties(p) result(res) type(FronteraPML) :: res character(len=*), intent(in) :: p call this%core%get(this%root, p//'.'//J_BND_PML_LAYERS, res%numCapas, default=8) - call this%core%get(this%root, p//'.'//J_BND_PML_ORDER, orden, default=2.0) - call this%core%get(this%root, p//'.'//J_BND_PML_REFLECTION, refl, default=0.001) - res%orden = orden - res%refl = refl + call this%core%get(this%root, p//'.'//J_BND_PML_ORDER, res%orden, default=2.0) + call this%core%get(this%root, p//'.'//J_BND_PML_REFLECTION, res%refl, default=0.001) end function - function labelToBoundaryType(str) result (type) - character(len=:), allocatable :: str - integer :: type + function labelToBoundaryPlace(str) result (place) + character(len=*), intent(in) :: str + integer :: place + select case (str) + case (J_BND_XL) + place = F_XL + case (J_BND_XU) + place = F_XU + case (J_BND_YL) + place = F_YL + case (J_BND_YU) + place = F_YU + case (J_BND_ZL) + place = F_ZL + case (J_BND_ZU) + place = F_ZU + end select + end function + + function labelToBoundaryType(str) result (bdrType) + character(len=:), allocatable, intent(in) :: str + integer :: bdrType select case (str) case (J_BND_TYPE_PEC) - type = F_PEC + bdrType = F_PEC case (J_BND_TYPE_PMC) - type = F_PMC + bdrType = F_PMC case (J_BND_TYPE_PERIODIC) - type = F_PER + bdrType = F_PER case (J_BND_TYPE_MUR) - type = F_MUR + bdrType = F_MUR case (J_BND_TYPE_PML) - type = F_PML + bdrType = F_PML end select end function end function @@ -581,8 +622,7 @@ function readPlanewave(pw) result (res) character (len=:), allocatable :: label logical :: found - res%nombre_fichero = trim(adjustl( & - this%getStrAt(pw,J_SRC_MAGNITUDE_FILE))) + res%nombre_fichero = trim(adjustl(this%getStrAt(pw,J_SRC_MAGNITUDE_FILE))) call this%core%get(pw, J_SRC_PW_ATTRIBUTE, label, found) if (found) then @@ -839,7 +879,7 @@ function readMoreProbes(this) result (res) do i=1, size(ps) call this%core%get(ps(i)%p, J_FIELD, fieldLbl) if (fieldLbl /= J_FIELD_VOLTAGE) then - res%collection(n) = readProbe(ps(i)%p) + res%collection(n) = readPointProbe(ps(i)%p) n = n + 1 end if end do @@ -848,9 +888,10 @@ function readMoreProbes(this) result (res) res%length_max = size(res%collection) res%len_cor_max = 0 contains - function readProbe(p) result (res) + function readPointProbe(p) result (res) type(MasSonda) :: res - type(json_value), pointer :: p, dirLabels, dirLabelPtr + type(json_value), pointer :: p, dirLabelPtr + character(len=1), dimension(:), allocatable :: dirLabels integer :: i, j, k character (len=:), allocatable :: typeLabel, fieldLabel, outputName, dirLabel type(pixel_t) :: pixel @@ -889,24 +930,24 @@ function readProbe(p) result (res) res%cordinates(1)%Zi = 0 res%cordinates(1)%Or = strToFieldType(fieldLabel) case (J_PR_TYPE_POINT) - call this%core%get(p, J_PR_POINT_DIRECTIONS, dirLabels, found=dirLabelsFound) - if (.not. dirLabelsFound) then - write(error_unit, *) "ERROR: Point probe direction labels not found." + call this%core%get(p, J_PR_POINT_DIRECTIONS, dirLabelPtr, found=dirLabelsFound) + if(dirLabelsFound) then + dirLabels = buildDirLabels(dirLabelPtr) + else + dirLabels = [J_DIR_X, J_DIR_Y, J_DIR_Z] end if call this%core%get(p, J_FIELD, fieldLabel, default=J_FIELD_ELECTRIC, found=fieldLabelFound) if (.not. fieldLabelFound) then write(error_unit, *) "ERROR: Point probe field label not found." end if if (dirLabelsFound) then - allocate(res%cordinates(this%core%count(dirLabels))) - do j = 1, this%core%count(dirLabels) + allocate(res%cordinates(size(dirLabels))) + do j = 1, size(dirLabels) res%cordinates(j)%tag = outputName res%cordinates(j)%Xi = int (pixel%cell(1)) res%cordinates(j)%Yi = int (pixel%cell(2)) res%cordinates(j)%Zi = int (pixel%cell(3)) - call this%core%get_child(dirLabels, j, dirLabelPtr) - call this%core%get(dirLabelPtr, dirLabel) - res%cordinates(j)%Or = strToFieldType(fieldLabel, dirLabel) + res%cordinates(j)%Or = strToFieldType(fieldLabel, dirLabels(j)) end do else do j = 1, 3 @@ -930,6 +971,20 @@ function readProbe(p) result (res) res%len_cor = size(res%cordinates) end function + function buildDirLabels(dirLabelsPtr) result (res) + type(json_value), pointer, intent(in) :: dirLabelsPtr + character(len=1), dimension(:), allocatable :: res + type(json_value), pointer :: child + character(len=:), allocatable :: str + integer :: i + allocate(res(this%core%count(dirLabelsPtr))) + do i = 1, this%core%count(dirLabelsPtr) + call this%core%get_child(dirLabelsPtr, i, child) + call this%core%get(child, str) + res(i) = str + end do + end function + subroutine setDomain(res, domain) type(MasSonda), intent(inout) :: res type(domain_t), intent(in) :: domain diff --git a/src_json_parser/smbjson_labels.F90 b/src_json_parser/smbjson_labels.F90 index a5d3488f..1c8e0ba4 100644 --- a/src_json_parser/smbjson_labels.F90 +++ b/src_json_parser/smbjson_labels.F90 @@ -127,6 +127,13 @@ module smbjson_labels_mod ! type(Frontera) character (len=*), parameter :: J_BOUNDARY = "boundary" character (len=*), parameter :: J_BND_ALL = "all" + character (len=*), parameter :: J_BND_XL = "xLower" + character (len=*), parameter :: J_BND_XU = "xUpper" + character (len=*), parameter :: J_BND_YL = "yLower" + character (len=*), parameter :: J_BND_YU = "yUpper" + character (len=*), parameter :: J_BND_ZL = "zLower" + character (len=*), parameter :: J_BND_ZU = "zUpper" + character (len=*), parameter :: J_BND_TYPE_PEC = "pec" character (len=*), parameter :: J_BND_TYPE_PMC = "pmc" diff --git a/test/smbjson/test_read_dielectricslab.F90 b/test/smbjson/test_read_dielectricslab.F90 index 822905a7..a7486a7f 100644 --- a/test/smbjson/test_read_dielectricslab.F90 +++ b/test/smbjson/test_read_dielectricslab.F90 @@ -4,7 +4,7 @@ integer function test_read_dielectricslab() bind (C) result(err) implicit none - character(len=*), parameter :: filename = PATH_TO_TEST_DATA//'cases/planewave.fdtd.json' + character(len=*), parameter :: filename = PATH_TO_TEST_DATA//'cases/dielectricSlab.fdtd.json' type(Parseador) :: pr, ex type(parser_t) :: parser logical :: areSame From 41625150d848492df049f9548487512853b92515 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Tue, 10 Dec 2024 13:03:39 +0100 Subject: [PATCH 14/25] passes test for read dielectric slab --- doc/smbjson.md | 6 +-- src_json_parser/nfdetypes_extension.F90 | 18 --------- src_json_parser/smbjson.F90 | 47 ++++++++--------------- test/smbjson/test_read_dielectricslab.F90 | 6 +-- 4 files changed, 19 insertions(+), 58 deletions(-) diff --git a/doc/smbjson.md b/doc/smbjson.md index 6e1aa09c..ffe7e10c 100644 --- a/doc/smbjson.md +++ b/doc/smbjson.md @@ -567,8 +567,6 @@ Performs a loop integral along on the contour of the surface reference in the `e 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 gives the total current passing through the surface. -TODO REVIEW DO BULK CURRENTS DO AVERAGES OF MAGNETIC FIELDS IN CELLS NEXT TO THE SELECTED? - In the following example `elementId` points an element describing a single oriented surface, therefore `direction` does not need to be stated explicitly. ```json @@ -590,8 +588,6 @@ In this example `elementId` points to a volume element, therefore `direction` mu } ``` -TODO EXAMPLE IMAGE - #### `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/scatterd field excitation, e.g. [a planewave](#planewave). @@ -637,7 +633,7 @@ An example follows: ### `[domain]` -If `domain` is not specified, it defaults to record from the beginning to the end of the simulation. +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 `` from the following ones: + `time`, means recording only in time domain. A probe with a `domain` of this `type` can contain the following entries: diff --git a/src_json_parser/nfdetypes_extension.F90 b/src_json_parser/nfdetypes_extension.F90 index bd08a3a3..3a490b99 100644 --- a/src_json_parser/nfdetypes_extension.F90 +++ b/src_json_parser/nfdetypes_extension.F90 @@ -804,28 +804,10 @@ elemental logical function abstractSonda_eq(a, b) result(res) res = .false. if (a%n_FarField /= b%n_FarField) return - ! if (a%n_Electric /= b%n_Electric) return - ! if (a%n_Magnetic /= b%n_Magnetic) return - ! if (a%n_NormalElectric /= b%n_NormalElectric) return - ! if (a%n_NormalMagnetic /= b%n_NormalMagnetic) return - ! if (a%n_SurfaceElectricCurrent /= b%n_SurfaceElectricCurrent) return - ! if (a%n_SurfaceMagneticCurrent /= b%n_SurfaceMagneticCurrent) return if (.not. associated(a%FarField) .or. .not. associated(b%FarField)) return - ! if (.not. associated(a%Electric) .or. .not. associated(b%Electric)) return - ! if (.not. associated(a%Magnetic) .or. .not. associated(b%Magnetic)) return - ! if (.not. associated(a%NormalElectric) .or. .not. associated(b%NormalElectric)) return - ! if (.not. associated(a%NormalMagnetic) .or. .not. associated(b%NormalMagnetic)) return - ! if (.not. associated(a%SurfaceElectricCurrent) .or. .not. associated(b%SurfaceElectricCurrent)) return - ! if (.not. associated(a%SurfaceMagneticCurrent) .or. .not. associated(b%SurfaceMagneticCurrent)) return if (any(.not. a%FarField == b%FarField)) return - ! if (any(.not. a%Electric == b%Electric)) return - ! if (any(.not. a%Magnetic == b%Magnetic)) return - ! if (any(.not. a%NormalElectric == b%NormalElectric)) return - ! if (any(.not. a%NormalMagnetic == b%NormalMagnetic)) return - ! if (any(.not. a%SurfaceElectricCurrent == b%SurfaceElectricCurrent)) return - ! if (any(.not. a%SurfaceMagneticCurrent == b%SurfaceMagneticCurrent)) return res = .true. end function abstractSonda_eq diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index b2bc84bb..26fddca8 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -92,12 +92,12 @@ module smbjson end type type, private :: domain_t - real :: tstart, tstop, tstep - real :: fstart, fstop - integer :: fstep + real :: tstart = 0.0, tstop = 0.0, tstep = 0.0 + real :: fstart = 0.0, fstop = 0.0 + integer :: fstep = 0 character(len=:), allocatable :: filename - integer :: type1, type2 - logical :: isLogarithmicFrequencySpacing + integer :: type1 = NP_T1_PLAIN, type2 = NP_T2_TIME + logical :: isLogarithmicFrequencySpacing = .false. end type contains function parser_ctor(filename) result(res) @@ -904,6 +904,7 @@ function readPointProbe(p) result (res) write(error_unit, *) "ERROR: name entry not found for probe." end if res%outputrequest = trim(adjustl(outputName)) + call setDomain(res, this%getDomain(p, J_PR_DOMAIN)) call this%core%get(p, J_ELEMENTIDS, elemIds, found=elementIdsFound) @@ -939,33 +940,15 @@ function readPointProbe(p) result (res) call this%core%get(p, J_FIELD, fieldLabel, default=J_FIELD_ELECTRIC, found=fieldLabelFound) if (.not. fieldLabelFound) then write(error_unit, *) "ERROR: Point probe field label not found." - end if - if (dirLabelsFound) then - allocate(res%cordinates(size(dirLabels))) - do j = 1, size(dirLabels) - res%cordinates(j)%tag = outputName - res%cordinates(j)%Xi = int (pixel%cell(1)) - res%cordinates(j)%Yi = int (pixel%cell(2)) - res%cordinates(j)%Zi = int (pixel%cell(3)) - res%cordinates(j)%Or = strToFieldType(fieldLabel, dirLabels(j)) - end do - else - do j = 1, 3 - res%cordinates(j)%tag = outputName - res%cordinates(j)%Xi = int (pixel%cell(1)) - res%cordinates(j)%Yi = int (pixel%cell(2)) - res%cordinates(j)%Zi = int (pixel%cell(3)) - select case (j) - case (1) - dirLabel = J_DIR_X - case (2) - dirLabel = J_DIR_Y - case (3) - dirLabel = J_DIR_Z - end select - res%cordinates(j)%Or = strToFieldType(fieldLabel, dirLabel) - end do - end if + end if + allocate(res%cordinates(size(dirLabels))) + do j = 1, size(dirLabels) + res%cordinates(j)%tag = outputName + res%cordinates(j)%Xi = int (pixel%cell(1)) + res%cordinates(j)%Yi = int (pixel%cell(2)) + res%cordinates(j)%Zi = int (pixel%cell(3)) + res%cordinates(j)%Or = strToFieldType(fieldLabel, dirLabels(j)) + end do end select res%len_cor = size(res%cordinates) diff --git a/test/smbjson/test_read_dielectricslab.F90 b/test/smbjson/test_read_dielectricslab.F90 index a7486a7f..2c6b3724 100644 --- a/test/smbjson/test_read_dielectricslab.F90 +++ b/test/smbjson/test_read_dielectricslab.F90 @@ -127,19 +127,19 @@ function expectedProblemDescription() result (expected) end do ! point probe at front expected%Sonda%collection(1)%outputrequest = "front" - expected%Sonda%collection(1)%cordinates(1:3)%tag = "probe@layer1" + expected%Sonda%collection(1)%cordinates(1:3)%tag = "front" expected%Sonda%collection(1)%cordinates(1:3)%Xi = 2 expected%Sonda%collection(1)%cordinates(1:3)%Yi = 2 expected%Sonda%collection(1)%cordinates(1:3)%Zi = 10 ! point probe in dielectric slab expected%Sonda%collection(2)%outputrequest = "inner" - expected%Sonda%collection(2)%cordinates(1:3)%tag = "probe@layer2" + expected%Sonda%collection(2)%cordinates(1:3)%tag = "inner" expected%Sonda%collection(2)%cordinates(1:3)%Xi = 2 expected%Sonda%collection(2)%cordinates(1:3)%Yi = 2 expected%Sonda%collection(2)%cordinates(1:3)%Zi = 25 ! point probe at back expected%Sonda%collection(3)%outputrequest = "back" - expected%Sonda%collection(3)%cordinates(1:3)%tag = "probe@layer2" + expected%Sonda%collection(3)%cordinates(1:3)%tag = "back" expected%Sonda%collection(3)%cordinates(1:3)%Xi = 2 expected%Sonda%collection(3)%cordinates(1:3)%Yi = 2 expected%Sonda%collection(3)%cordinates(1:3)%Zi = 40 From bea408798e877a638e078a40deef3b58c6716581 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Tue, 10 Dec 2024 13:10:01 +0100 Subject: [PATCH 15/25] drafting thinslot test --- test/smbjson/CMakeLists.txt | 5 +- test/smbjson/smbjson_tests.h | 2 + ...ion.F90 => test_read_currentInjection.F90} | 0 ...cslab.F90 => test_read_dielectricSlab.F90} | 0 test/smbjson/test_read_thinSlot.F90 | 150 ++++++++++++++++++ testData/cases/thinSlot.fdtd.json | 81 ++++++++++ 6 files changed, 236 insertions(+), 2 deletions(-) rename test/smbjson/{test_read_currentinjection.F90 => test_read_currentInjection.F90} (100%) rename test/smbjson/{test_read_dielectricslab.F90 => test_read_dielectricSlab.F90} (100%) create mode 100644 test/smbjson/test_read_thinSlot.F90 create mode 100644 testData/cases/thinSlot.fdtd.json diff --git a/test/smbjson/CMakeLists.txt b/test/smbjson/CMakeLists.txt index 8670fc2d..df6495f0 100644 --- a/test/smbjson/CMakeLists.txt +++ b/test/smbjson/CMakeLists.txt @@ -9,12 +9,13 @@ add_library (smbjson_test_fortran "test_mesh.F90" "test_parser.F90" "test_read_planewave.F90" - "test_read_dielectricslab.F90" + "test_read_dielectricSlab.F90" + "test_read_thinSlot.F90" "test_read_sgbc.F90" "test_read_holland1981.F90" "test_read_towelHanger.F90" "test_read_connectedWires.F90" - "test_read_currentinjection.F90" + "test_read_currentInjection.F90" "test_read_shieldedPair.F90" "test_read_mtln.F90" "test_read_sphere.F90" diff --git a/test/smbjson/smbjson_tests.h b/test/smbjson/smbjson_tests.h index c8a74dfb..0052e5a3 100644 --- a/test/smbjson/smbjson_tests.h +++ b/test/smbjson/smbjson_tests.h @@ -15,6 +15,7 @@ extern "C" int test_parser_read_mesh(); extern "C" int test_read_planewave(); extern "C" int test_read_sgbc(); extern "C" int test_read_dielectricslab(); +extern "C" int test_read_thinslot(); extern "C" int test_read_holland1981(); extern "C" int test_read_towelhanger(); extern "C" int test_read_connectedwires(); @@ -38,6 +39,7 @@ TEST(smbjson, parser_ctor) { EXPECT_EQ(0, test_parser_ctor()); } TEST(smbjson, parser_read_mesh) { EXPECT_EQ(0, test_parser_read_mesh()); } TEST(smbjson, read_planewave) { EXPECT_EQ(0, test_read_planewave()); } TEST(smbjson, read_dielectricslab) { EXPECT_EQ(0, test_read_dielectricslab()); } +TEST(smbjson, read_thinslot) { EXPECT_EQ(0, test_read_thinslot()); } TEST(smbjson, read_sgbc) { EXPECT_EQ(0, test_read_sgbc()); } TEST(smbjson, read_holland1981) { EXPECT_EQ(0, test_read_holland1981()); } TEST(smbjson, read_towelhanger) { EXPECT_EQ(0, test_read_towelhanger()); } diff --git a/test/smbjson/test_read_currentinjection.F90 b/test/smbjson/test_read_currentInjection.F90 similarity index 100% rename from test/smbjson/test_read_currentinjection.F90 rename to test/smbjson/test_read_currentInjection.F90 diff --git a/test/smbjson/test_read_dielectricslab.F90 b/test/smbjson/test_read_dielectricSlab.F90 similarity index 100% rename from test/smbjson/test_read_dielectricslab.F90 rename to test/smbjson/test_read_dielectricSlab.F90 diff --git a/test/smbjson/test_read_thinSlot.F90 b/test/smbjson/test_read_thinSlot.F90 new file mode 100644 index 00000000..92b85eee --- /dev/null +++ b/test/smbjson/test_read_thinSlot.F90 @@ -0,0 +1,150 @@ +integer function test_read_thinSlot() bind (C) result(err) + use smbjson + use smbjson_testingTools + + implicit none + + character(len=*), parameter :: filename = PATH_TO_TEST_DATA//'cases/thinSlot.fdtd.json' + type(Parseador) :: pr, ex + type(parser_t) :: parser + logical :: areSame + err = 0 + + ex = expectedProblemDescription() + parser = parser_t(filename) + pr = parser%readProblemDescription() + call expect_eq(err, ex, pr) + +contains + function expectedProblemDescription() result (expected) + type(Parseador) :: expected + integer :: i + + call initializeProblemDescription(expected) + + ! Expected general info. + expected%general%dt = 10e-12 + expected%general%nmax = 2000 + + ! Excected media matrix. + expected%matriz%totalX = 4 + expected%matriz%totalY = 4 + expected%matriz%totalZ = 50 + + ! Expected grid. + expected%despl%nX = 4 + expected%despl%nY = 4 + expected%despl%nZ = 50 + + allocate(expected%despl%desX(4)) + allocate(expected%despl%desY(4)) + allocate(expected%despl%desZ(50)) + expected%despl%desX = 0.1 + expected%despl%desY = 0.1 + expected%despl%desZ = 0.1 + expected%despl%mx1 = 0 + expected%despl%mx2 = 4 + expected%despl%my1 = 0 + expected%despl%my2 = 4 + expected%despl%mz1 = 0 + expected%despl%mz2 = 50 + + ! Expected boundaries. + expected%front%tipoFrontera(F_XL) = F_PEC + expected%front%tipoFrontera(F_XU) = F_PEC + expected%front%tipoFrontera(F_YL) = F_PMC + expected%front%tipoFrontera(F_YU) = F_PMC + expected%front%tipoFrontera(F_ZL) = F_PML + expected%front%tipoFrontera(F_ZU) = F_PML + + ! Expected sources. + allocate(expected%plnSrc%collection(1)) + expected%plnSrc%collection(1)%nombre_fichero = "gauss.exc" + expected%plnSrc%collection(1)%atributo = "" + expected%plnSrc%collection(1)%coor1 = [0, 0, 2] + expected%plnSrc%collection(1)%coor2 = [3, 3, 47] + expected%plnSrc%collection(1)%theta = 0.0 + expected%plnSrc%collection(1)%phi = 0.0 + expected%plnSrc%collection(1)%alpha = 1.5708 + expected%plnSrc%collection(1)%beta = 0.0 + expected%plnSrc%collection(1)%isRC=.false. + expected%plnSrc%collection(1)%nummodes=1 + expected%plnSrc%collection(1)%INCERTMAX=0.0 + expected%plnSrc%nc = 1 + expected%plnSrc%nC_max = 1 + + ! dielectric slab region + expected%dielRegs%nVols = 1 + expected%dielRegs%nSurfs = 0 + expected%dielRegs%nLins = 0 + expected%dielRegs%nVols_max = 1 + expected%dielRegs%nSurfs_max = 0 + expected%dielRegs%n_C1P_max = 0 + expected%dielRegs%n_C2P_max = 1 + allocate(expected%dielRegs%Vols(1)) + allocate(expected%dielRegs%Surfs(0)) + allocate(expected%dielRegs%Lins(0)) + ! slab + allocate(expected%dielRegs%vols(1)%c1P(0)) + allocate(expected%dielRegs%vols(1)%c2P(1)) + expected%dielRegs%vols(1)%n_C1P = 0 + expected%dielRegs%vols(1)%n_C2P = 1 + expected%dielRegs%vols(1)%sigma = 0.0 + expected%dielRegs%vols(1)%eps = 1.3*EPSILON_VACUUM + expected%dielRegs%vols(1)%mu = MU_VACUUM + expected%dielRegs%vols(1)%sigmam = 0.0 + expected%dielRegs%vols(1)%c2P%Or = 0 + expected%dielRegs%vols(1)%c2P%Xi = 0 + expected%dielRegs%vols(1)%c2P%Xe = 4 + expected%dielRegs%vols(1)%c2P%Yi = 0 + expected%dielRegs%vols(1)%c2P%Ye = 4 + expected%dielRegs%vols(1)%c2P%Zi = 20 + expected%dielRegs%vols(1)%c2P%Ze = 30 + expected%dielRegs%vols(1)%c2P%tag = 'teflon@slab' + + ! Expected probes + ! sonda + expected%Sonda%len_cor_max = 0 + expected%Sonda%length = 3 + expected%Sonda%length_max = 3 + allocate(expected%Sonda%collection(3)) + ! common data + do i = 1, 3 + expected%Sonda%collection(i)%type1 = NP_T1_PLAIN + expected%Sonda%collection(i)%type2 = NP_T2_TIME + expected%Sonda%collection(i)%filename = ' ' + expected%Sonda%collection(i)%tstart = 0.0 + expected%Sonda%collection(i)%tstop = 0.0 + expected%Sonda%collection(i)%tstep = 0.0 + expected%Sonda%collection(i)%fstart = 0.0 + expected%Sonda%collection(i)%fstop = 0.0 + expected%Sonda%collection(i)%fstep = 0.0 + allocate(expected%Sonda%collection(i)%cordinates(3)) + expected%Sonda%collection(i)%cordinates(1)%Or = NP_COR_EX + expected%Sonda%collection(i)%cordinates(2)%Or = NP_COR_EY + expected%Sonda%collection(i)%cordinates(3)%Or = NP_COR_EZ + expected%Sonda%collection(i)%len_cor = 3 + end do + ! point probe at front + expected%Sonda%collection(1)%outputrequest = "front" + expected%Sonda%collection(1)%cordinates(1:3)%tag = "front" + expected%Sonda%collection(1)%cordinates(1:3)%Xi = 2 + expected%Sonda%collection(1)%cordinates(1:3)%Yi = 2 + expected%Sonda%collection(1)%cordinates(1:3)%Zi = 10 + ! point probe in dielectric slab + expected%Sonda%collection(2)%outputrequest = "inner" + expected%Sonda%collection(2)%cordinates(1:3)%tag = "inner" + expected%Sonda%collection(2)%cordinates(1:3)%Xi = 2 + expected%Sonda%collection(2)%cordinates(1:3)%Yi = 2 + expected%Sonda%collection(2)%cordinates(1:3)%Zi = 25 + ! point probe at back + expected%Sonda%collection(3)%outputrequest = "back" + expected%Sonda%collection(3)%cordinates(1:3)%tag = "back" + expected%Sonda%collection(3)%cordinates(1:3)%Xi = 2 + expected%Sonda%collection(3)%cordinates(1:3)%Yi = 2 + expected%Sonda%collection(3)%cordinates(1:3)%Zi = 40 + + + end function +end function + diff --git a/testData/cases/thinSlot.fdtd.json b/testData/cases/thinSlot.fdtd.json new file mode 100644 index 00000000..84db68f7 --- /dev/null +++ b/testData/cases/thinSlot.fdtd.json @@ -0,0 +1,81 @@ +{ + "format": "FDTD Input file", + "__comments": "Planewave illuminating a thin slot.", + + "general": { + "timeStep": 10e-12, + "numberOfSteps": 2000 + }, + + "boundary": { + "xLower": {"type": "pec"}, + "xUpper": {"type": "pec"}, + "yLower": {"type": "pmc"}, + "yUpper": {"type": "pmc"}, + "zLower": {"type": "pml"}, + "zUpper": {"type": "pml"} + }, + + "mesh": { + "grid": { + "numberOfCells": [4, 4, 50], + "steps": { "x": [0.1], "y": [0.1], "z": [0.1] } + }, + "coordinates": [ + {"id": 1, "relativePosition": [2, 2, 10]}, + {"id": 2, "relativePosition": [2, 2, 25]}, + {"id": 3, "relativePosition": [2, 2, 40]} + ], + "elements": [ + {"id": 1, "type": "node", "coordinateIds": [1]}, + {"id": 2, "type": "node", "coordinateIds": [2]}, + {"id": 3, "type": "node", "coordinateIds": [3]}, + {"id": 4, "type": "cell", "name": "pw-box", "intervals": [ [ [0, 0, 2], [4, 4, 48] ] ]}, + {"id": 5, "type": "cell", "name": "square", "intervals": [ [ [0, 0, 25], [4, 4, 25] ] ]}, + {"id": 6, "type": "cell", "name": "slot", "intervals": [ [ [1, 2, 25], [3, 2, 25] ] ]} + ] + }, + + "materials": [ + { + "name": "copper", + "id": 1, + "type": "pec" + } + ], + + "materialAssociations": [ + {"type": "bulk", "materialId": 1, "elementIds": [5]} + ], + + "sources": [ + { + "type": "planewave", + "magnitudeFile": "gauss.exc", + "elementIds": [4], + "direction": { + "theta": 0.0, + "phi": 0.0 + }, + "polarization": { + "theta": 1.5708, + "phi": 0.0 + } + } + ], + + "probes": [ + { + "name": "front", + "type": "point", + "field": "electric", + "elementIds": [1] + }, + { + "name": "back", + "type": "point", + "field": "electric", + "elementIds": [2] + } + ] +} \ No newline at end of file From 2614fd12d8a8d3cf242bee446b9c0660f45dd382 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Wed, 11 Dec 2024 11:36:13 +0100 Subject: [PATCH 16/25] Passes test on sgbc --- src_json_parser/nfdetypes_extension.F90 | 23 ++++++++++++++---- src_json_parser/smbjson.F90 | 31 +++++++++++++++++++++++++ test/smbjson/smbjson_testingTools.F90 | 3 +++ test/smbjson/test_parser.F90 | 2 +- test/smbjson/test_read_sgbc.F90 | 24 +++++++++++++++++-- 5 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src_json_parser/nfdetypes_extension.F90 b/src_json_parser/nfdetypes_extension.F90 index 3a490b99..6b1b13dc 100644 --- a/src_json_parser/nfdetypes_extension.F90 +++ b/src_json_parser/nfdetypes_extension.F90 @@ -148,6 +148,7 @@ subroutine initializeProblemDescription(pD) allocate(pD%sWires) allocate(pD%tSlots) + allocate(pD%tSlots%tg(0)) allocate(pD%mtln) allocate(pD%mtln%cables(0)) @@ -556,8 +557,15 @@ end function SlantedWire_eq elemental logical function SlantedWires_eq(a, b) type(SlantedWires), intent(in) :: a, b - - SlantedWires_eq = all(a%sw == b%sw) .and. & + logical :: allAssociated + allAssociated = & + associated(a%sw) .and. associated(b%sw) + if (.not. allAssociated) then + SlantedWires_eq = .false. + return + end if + SlantedWires_eq = & + all(a%sw == b%sw) .and. & (a%n_sw == b%n_sw) .and. & (a%n_sw_max == b%n_sw_max) end function SlantedWires_eq @@ -576,8 +584,14 @@ end function ThinSlotComp_eq elemental logical function ThinSlot_eq(a, b) type(ThinSlot), intent(in) :: a, b - - ThinSlot_eq = all(a%tgc == b%tgc) .and. & + logical :: allAssociated + allAssociated = associated(a%tgc) .and. associated(b%tgc) + if (.not. allAssociated) then + ThinSlot_eq = .false. + return + end if + ThinSlot_eq = & + all(a%tgc == b%tgc) .and. & (a%width == b%width) .and. & (a%n_tgc == b%n_tgc) .and. & (a%n_tgc_max == b%n_tgc_max) @@ -586,6 +600,7 @@ end function ThinSlot_eq elemental logical function ThinSlots_eq(a, b) type(ThinSlots), intent(in) :: a, b + ThinSlots_eq = all(a%tg == b%tg) .and. & (a%n_tg == b%n_tg) .and. & (a%n_tg_max == b%n_tg_max) diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 26fddca8..9d1e9d8c 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -40,6 +40,7 @@ module smbjson procedure, private :: readMediaMatrix procedure, private :: readPECRegions procedure, private :: readPMCRegions + procedure, private :: readDielectricRegions procedure, private :: readLossyThinSurfaces procedure, private :: readBoundary procedure, private :: readPlanewaves @@ -49,6 +50,7 @@ module smbjson procedure, private :: readBlockProbes procedure, private :: readVolumicProbes procedure, private :: readThinWires + procedure, private :: readThinSlots ! ! procedure, private :: readMTLN @@ -143,6 +145,7 @@ function readProblemDescription(this) result (res) ! Materials res%pecRegs = this%readPECRegions() res%pmcRegs = this%readPMCRegions() + res%dielRegs = this%readDielectricRegions() res%lossyThinSurfs = this%readLossyThinSurfaces() ! Sources @@ -157,6 +160,7 @@ function readProblemDescription(this) result (res) ! Thin elements res%tWires = this%readThinWires() + res%tSlots = this%readThinSlots() res%mtln = this%readMTLN(res%despl) end function @@ -488,7 +492,16 @@ function buildRegionCoords(matAssPtrs, cellType) result(res) end do end do end function + end function + + function readDielectricRegions(this) result (res) + class(parser_t), intent(in) :: this + type(DielectricRegions) :: res + ! TODO + allocate(res%lins(0)) + allocate(res%surfs(0)) + allocate(res%vols(0)) end function function readLossyThinSurfaces(this) result (res) @@ -565,6 +578,11 @@ function readLossyThinSurface(matId, eId) result(res) allocate(res%mu( res%numcapas)) allocate(res%sigmam(res%numcapas)) allocate(res%thk( res%numcapas)) + allocate(res%sigma_devia( res%numcapas)) + allocate(res%eps_devia( res%numcapas)) + allocate(res%mu_devia( res%numcapas)) + allocate(res%sigmam_devia(res%numcapas)) + allocate(res%thk_devia( res%numcapas)) do i = 1, res%numcapas call this%core%get_child(layers, i, layer) res%sigma(i) = this%getRealAt(layer, J_MAT_ELECTRIC_CONDUCTIVITY, default=0.0) @@ -572,6 +590,11 @@ function readLossyThinSurface(matId, eId) result(res) res%eps(i) = this%getRealAt(layer, J_MAT_REL_PERMITTIVITY, default=1.0) * EPSILON_VACUUM res%mu(i) = this%getRealAt(layer, J_MAT_REL_PERMEABILITY, default=1.0) * MU_VACUUM res%thk(i) = this%getRealAt(layer, J_MAT_MULTILAYERED_SURF_THICKNESS, found) + res%sigma_devia(i) = 0.0 + res%eps_devia(i) = 0.0 + res%mu_devia(i) = 0.0 + res%sigmam_devia(i) = 0.0 + res%thk_devia(i) = 0.0 if (.not. found) then write(error_unit, *) errorMsgInit, J_MAT_MULTILAYERED_SURF_THICKNESS, " in layer not found." end if @@ -1246,6 +1269,14 @@ subroutine appendLogSufix(fn) fn = trim(fn) // SMBJSON_LOG_SUFFIX end subroutine + function readThinSlots(this) result (res) + class(parser_t) :: this + type(ThinSlots) :: res + + !! TODO + allocate(res%tg(0)) + end function + function readThinWires(this) result (res) class(parser_t) :: this type(ThinWires) :: res diff --git a/test/smbjson/smbjson_testingTools.F90 b/test/smbjson/smbjson_testingTools.F90 index 9aedee6e..79bb42b9 100644 --- a/test/smbjson/smbjson_testingTools.F90 +++ b/test/smbjson/smbjson_testingTools.F90 @@ -37,6 +37,8 @@ subroutine expect_eq(err, ex, pr, ignoreRegions) if (checkRegions) then if (.not. ex%pecRegs == pr%pecRegs) call testFails(err, 'Expected and read "pec regions" do not match') if (.not. ex%pmcRegs == pr%pmcRegs) call testFails(err, 'Expected and read "pmc regions" do not match') + if (.not. ex%dielRegs == pr%dielRegs) call testFails(err, 'Expected and read "dielectric regions" do not match') + if (.not. ex%lossyThinSurfs == pr%lossyThinSurfs) call testFails(err, 'Expected and read "lossy thin surfaces" do not match') end if ! Sources @@ -50,6 +52,7 @@ subroutine expect_eq(err, ex, pr, ignoreRegions) if (.not. ex%VolPrb == pr%VolPrb) call testFails(err, 'Expected and read "vol probes" do not match') ! Thin elements + if (.not. ex%tSlots == pr%tSlots) call testFails(err, 'Expected and read "thin slots" do not match') if (.not. ex%tWires == pr%tWires) call testFails(err, 'Expected and read "thin wires" do not match') if (.not. ex%mtln == pr%mtln) call testFails(err, 'Expected and read mtln types do not match') if (err == 0) write(*,*) "Read and expected inputs are equal." diff --git a/test/smbjson/test_parser.F90 b/test/smbjson/test_parser.F90 index 1f95a1b1..88b4c59b 100644 --- a/test/smbjson/test_parser.F90 +++ b/test/smbjson/test_parser.F90 @@ -84,7 +84,7 @@ integer function test_parser_read_mesh() bind(C) result(err) parser = parser_t(filename) mesh = parser%readMesh() - call mesh%printCoordHashInfo() + ! call mesh%printCoordHashInfo() !! For debugging only expected%position = [10,2,1] obtained = mesh%getCoordinate(59, found) diff --git a/test/smbjson/test_read_sgbc.F90 b/test/smbjson/test_read_sgbc.F90 index d64f8c35..9ae88d06 100644 --- a/test/smbjson/test_read_sgbc.F90 +++ b/test/smbjson/test_read_sgbc.F90 @@ -81,7 +81,7 @@ function expectedProblemDescription() result (expected) allocate(expected%lossyThinSurfs%cs(1)%c(1)) expected%lossyThinSurfs%cs(1)%nc = 1 expected%lossyThinSurfs%cs(1)%c(1)%tag = '2-layers-composite@layer2' - expected%lossyThinSurfs%cs(1)%c(1)%Or = +iEx + expected%lossyThinSurfs%cs(1)%c(1)%Or = +iEy expected%lossyThinSurfs%cs(1)%c(1)%Xi = 3 expected%lossyThinSurfs%cs(1)%c(1)%Xe = 4 expected%lossyThinSurfs%cs(1)%c(1)%Yi = 3 @@ -99,12 +99,22 @@ function expectedProblemDescription() result (expected) expected%lossyThinSurfs%cs(1)%eps = [1.3*EPSILON_VACUUM, 1.3*EPSILON_VACUUM] expected%lossyThinSurfs%cs(1)%mu = [ MU_VACUUM, MU_VACUUM] expected%lossyThinSurfs%cs(1)%sigmam = [ 0.0, 0.0] + allocate(expected%lossyThinSurfs%cs(1)%thk_devia(2)) + allocate(expected%lossyThinSurfs%cs(1)%sigma_devia(2)) + allocate(expected%lossyThinSurfs%cs(1)%eps_devia(2)) + allocate(expected%lossyThinSurfs%cs(1)%mu_devia(2)) + allocate(expected%lossyThinSurfs%cs(1)%sigmam_devia(2)) + expected%lossyThinSurfs%cs(1)%thk_devia(:) = 0.0 + expected%lossyThinSurfs%cs(1)%sigma_devia(:) = 0.0 + expected%lossyThinSurfs%cs(1)%eps_devia(:) = 0.0 + expected%lossyThinSurfs%cs(1)%mu_devia(:) = 0.0 + expected%lossyThinSurfs%cs(1)%sigmam_devia(:) = 0.0 !!! 3-layer composite allocate(expected%lossyThinSurfs%cs(2)%c(1)) expected%lossyThinSurfs%cs(2)%nc = 1 expected%lossyThinSurfs%cs(2)%c(1)%tag = '3-layers-composite@layer3' - expected%lossyThinSurfs%cs(2)%c(1)%Or = +iEy + expected%lossyThinSurfs%cs(2)%c(1)%Or = +iEx expected%lossyThinSurfs%cs(2)%c(1)%Xi = 3 expected%lossyThinSurfs%cs(2)%c(1)%Xe = 3 expected%lossyThinSurfs%cs(2)%c(1)%Yi = 3 @@ -122,6 +132,16 @@ function expectedProblemDescription() result (expected) expected%lossyThinSurfs%cs(2)%eps = [EPSILON_VACUUM, EPSILON_VACUUM, EPSILON_VACUUM] expected%lossyThinSurfs%cs(2)%mu = [ MU_VACUUM, 1.3*MU_VACUUM, MU_VACUUM] expected%lossyThinSurfs%cs(2)%sigmam = [ 0.0, 0.0, 1e-4] + allocate(expected%lossyThinSurfs%cs(2)%thk_devia(3)) + allocate(expected%lossyThinSurfs%cs(2)%sigma_devia(3)) + allocate(expected%lossyThinSurfs%cs(2)%eps_devia(3)) + allocate(expected%lossyThinSurfs%cs(2)%mu_devia(3)) + allocate(expected%lossyThinSurfs%cs(2)%sigmam_devia(3)) + expected%lossyThinSurfs%cs(2)%thk_devia(:) = 0.0 + expected%lossyThinSurfs%cs(2)%sigma_devia(:) = 0.0 + expected%lossyThinSurfs%cs(2)%eps_devia(:) = 0.0 + expected%lossyThinSurfs%cs(2)%mu_devia(:) = 0.0 + expected%lossyThinSurfs%cs(2)%sigmam_devia(:) = 0.0 end function end function From c398df2ac4f7ff08aab881525bc209a4f6fb9d37 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Wed, 11 Dec 2024 12:42:37 +0100 Subject: [PATCH 17/25] [WIP] Read dielectrics --- src_json_parser/smbjson.F90 | 70 +++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 9d1e9d8c..e5e3ce2f 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -66,7 +66,7 @@ module smbjson procedure, private :: getDomain procedure, private :: buildPECPMCRegions procedure, private :: getMaterialAssociations - procedure, private :: buildMaterialAssociation + procedure, private :: parseMaterialAssociation procedure, private :: buildTagName procedure, private :: jsonValueFilterByKeyValue procedure, private :: jsonValueFilterByKeyValues @@ -469,7 +469,7 @@ function buildRegionCoords(matAssPtrs, cellType) result(res) ! Precounts nCs = 0 do i = 1, size(matAssPtrs) - mA = this%buildMaterialAssociation(matAssPtrs(i)%p) + mA = this%parseMaterialAssociation(matAssPtrs(i)%p) do e = 1, size(mA%elementIds) cR = this%mesh%getCellRegion(mA%elementIds(e)) cs = cellRegionToCoords(cR, cellType) @@ -481,7 +481,7 @@ function buildRegionCoords(matAssPtrs, cellType) result(res) allocate(res(nCs)) j = 1 do i = 1, size(matAssPtrs) - mA = this%buildMaterialAssociation(matAssPtrs(i)%p) + mA = this%parseMaterialAssociation(matAssPtrs(i)%p) do e = 1, size(mA%elementIds) tagName = this%buildTagName(mA%materialId, mA%elementIds(e)) cR = this%mesh%getCellRegion(mA%elementIds(e)) @@ -497,11 +497,59 @@ function buildRegionCoords(matAssPtrs, cellType) result(res) function readDielectricRegions(this) result (res) class(parser_t), intent(in) :: this type(DielectricRegions) :: res + type(json_value_ptr), dimension(:), allocatable :: matAssPtrs + + res%vols = readDielectricsOfCellType(CELL_TYPE_VOXEL) + res%surfs = readDielectricsOfCellType(CELL_TYPE_SURFEL) + res%lins = readDielectricsOfCellType(CELL_TYPE_LINEL) + + res%nVols = size(res%vols) + res%nSurfs = size(res%nSurfs) + res%nLins = size(res%nLins) + contains + function readDielectricsOfCellType(cellType) result (res) + integer, intent(in) :: cellType + type(dielectric_t), dimension(:), allocatable :: res + + type(json_value_ptr), dimension(:), allocatable :: mAPtrs + type(materialAssociation_t) :: mA + type(cell_region_t) :: cR + + integer :: i, e + integer :: nCs, nDielectrics + + mAPtrs = this%getMaterialAssociations(J_MAT_ASS_TYPE_BULK, J_MAT_TYPE_ISOTROPIC) + + ! Precounts + nDielectrics = 0 + do i = 1, size(mAPtrs) + if (containsCellRegionsWithType(mAPtrs(i), cellType)) then + nDielectrics = nDielectrics + 1 + end if + end do - ! TODO - allocate(res%lins(0)) - allocate(res%surfs(0)) - allocate(res%vols(0)) + ! Fills + allocate(res(nDielectrics)) + + end function + + logical function containsCellRegionsWithType(mAPtr, cellType) + integer, intent(in) :: cellType + type(json_value_ptr), intent(in) :: mAPtr + type(materialAssociation_t) :: mA + type(cell_region_t) :: cR + + mA = this%parseMaterialAssociation(mAPtrs) + do e = 1, size(mA%elementIds) + cR = this%mesh%getCellRegion(mA%elementIds(e)) + if (size(cellRegionToCoords(cR, cellType)) /= 0) then + containsCellRegionsWithType = .true. + return + end if + end do + + containsCellRegionsWithType = .false. + end function end function function readLossyThinSurfaces(this) result (res) @@ -520,7 +568,7 @@ function readLossyThinSurfaces(this) result (res) ! Precounts nLossySurfaces = 0 do i = 1, size(matAssPtrs) - mA = this%buildMaterialAssociation(matAssPtrs(i)%p) + mA = this%parseMaterialAssociation(matAssPtrs(i)%p) nLossySurfaces = nLossySurfaces + size(mA%elementIds) end do @@ -536,7 +584,7 @@ function readLossyThinSurfaces(this) result (res) res%nC_max = nLossySurfaces k = 1 do i = 1, size(matAssPtrs) - mA = this%buildMaterialAssociation(matAssPtrs(i)%p) + mA = this%parseMaterialAssociation(matAssPtrs(i)%p) do j = 1, size(mA%elementIds) res%cs(k) = readLossyThinSurface(mA%materialId, mA%elementIds(j)) k = k + 1 @@ -1666,7 +1714,7 @@ function getNPDomainType(typeLabel, hasTransferFunction) result(res) end function end function - function buildMaterialAssociation(this, matAss) result(res) + function parseMaterialAssociation(this, matAss) result(res) class(parser_t) :: this type(json_value), pointer, intent(in) :: matAss type(materialAssociation_t) :: res @@ -1764,7 +1812,7 @@ logical function isAssociatedWithMaterial(mAPtr, materialType) type(materialAssociation_t) :: matAss type(json_value_ptr) :: mat - matAss = this%buildMaterialAssociation(mAPtr) + matAss = this%parseMaterialAssociation(mAPtr) mat = this%matTable%getId(matAss%materialId) isAssociatedWithMaterial = this%getStrAt(mat%p, J_TYPE) == materialType end function From 9f837cc5f01a7d4ef9359b68f1562c813913d571 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Thu, 12 Dec 2024 08:52:44 +0100 Subject: [PATCH 18/25] [WIP] --- src_json_parser/smbjson.F90 | 53 ++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index e5e3ce2f..05933f8d 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -515,7 +515,7 @@ function readDielectricsOfCellType(cellType) result (res) type(materialAssociation_t) :: mA type(cell_region_t) :: cR - integer :: i, e + integer :: i, j integer :: nCs, nDielectrics mAPtrs = this%getMaterialAssociations(J_MAT_ASS_TYPE_BULK, J_MAT_TYPE_ISOTROPIC) @@ -523,23 +523,68 @@ function readDielectricsOfCellType(cellType) result (res) ! Precounts nDielectrics = 0 do i = 1, size(mAPtrs) - if (containsCellRegionsWithType(mAPtrs(i), cellType)) then + if (containsCellRegionsWithType(mAPtrs(i)%p, cellType)) then nDielectrics = nDielectrics + 1 end if end do ! Fills allocate(res(nDielectrics)) + j = 0 + do i = 1, size(mAPtrs) + if (.not. containsCellRegionsWithType(mAPtrs(i)%p, cellType)) cycle + j = j + 1 + res(j) = readDielectric(mAPtrs(i)%p, cellType) + end do + end function + + function readDielectric(mA, cellType) result(res) + type(json_value), pointer, intent(in) :: mAPtr + integer, intent(in) :: cellType + type(Dielectric_t) :: res + type(materialAssociation_t) :: mA + type(cell_region_t) :: cR + + integer :: e, j + + mA = this%parseMaterialAssociation(mAPtr) + ! Precount + res%n_C2P = 0 + do e = 1, size(mA%elementIds) + cR = this%mesh%getCellRegion(mA%elementIds(e)) + if (size(cellRegionToCoords(cR, cellType)) /= 0) then + res%n_C2P = res%n_C2P + 1 + end if + end do + + ! Fills coords + j = 0 + allocate(res%c1P(0)) + allocate(res%c2P(res%n_C2P)) + do e = 1, size(mA%elementIds) + cR = this%mesh%getCellRegion(mA%elementIds(e)) + if (size(cellRegionToCoords(cR, cellType)) == 0) cycle + j = j + 1 + res%c2p(j) = cellRegionToCoords(cR) + end do + + ! Fills rest of dielectric data. + res%sigma = this%getRealAt(mAPtr, J_MAT_ELECTRIC_CONDUCTIVITY, default=0.0) + res%sigmam = this%getRealAt(mAPtr, J_MAT_MAGNETIC_CONDUCTIVITY, default=0.0) + res%eps = this%getRealAt(mAPtr, J_MAT_REL_PERMITTIVITY, default=1.0)*EPSILON_VACUUM + res%mu = this%getRealAt(mAPtr, J_MAT_REL_PERMEABILITY, default=1.0)*MU_VACUUM + end function logical function containsCellRegionsWithType(mAPtr, cellType) integer, intent(in) :: cellType - type(json_value_ptr), intent(in) :: mAPtr + type(json_value), pointer, intent(in) :: mAPtr type(materialAssociation_t) :: mA + integer :: e type(cell_region_t) :: cR - mA = this%parseMaterialAssociation(mAPtrs) + mA = this%parseMaterialAssociation(mAPtr) do e = 1, size(mA%elementIds) cR = this%mesh%getCellRegion(mA%elementIds(e)) if (size(cellRegionToCoords(cR, cellType)) /= 0) then From da5ab38bd086de0e5b46b53e36120e0e1c37890a Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Thu, 12 Dec 2024 13:19:41 +0100 Subject: [PATCH 19/25] [WIP] --- src_json_parser/smbjson.F90 | 152 ++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 75 deletions(-) diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 05933f8d..a05fbe6b 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -67,6 +67,7 @@ module smbjson procedure, private :: buildPECPMCRegions procedure, private :: getMaterialAssociations procedure, private :: parseMaterialAssociation + procedure, private :: matAssToCoords procedure, private :: buildTagName procedure, private :: jsonValueFilterByKeyValue procedure, private :: jsonValueFilterByKeyValues @@ -434,64 +435,49 @@ function buildPECPMCRegions(this, matType) result(res) class(parser_t) :: this character (len=*), intent(in) :: matType type(PECRegions) :: res - type(json_value_ptr), dimension(:), allocatable :: mA + type(json_value_ptr), dimension(:), allocatable :: mAPtrs + type(materialAssociation_t) :: mA + integer :: i - ma = this%getMaterialAssociations(J_MAT_ASS_TYPE_BULK, matType) + mAPtrs = this%getMaterialAssociations(J_MAT_ASS_TYPE_BULK, matType) + do i = 1, size(mAPtrs) + mA = this%parseMaterialAssociation(mAptrs(i)%p) + call appendRegion(res%lins, res%nLins, res%nLins_max, this%matAssToCoords(mA, CELL_TYPE_LINEL)) + call appendRegion(res%surfs, res%nSurfs, res%nSurfs_max, this%matAssToCoords(mA, CELL_TYPE_SURFEL)) + call appendRegion(res%vols, res%nVols, res%nVols_max, this%matAssToCoords(mA, CELL_TYPE_VOXEL)) + end do - call fillRegion(res%lins, res%nLins, res%nLins_max, buildRegionCoords(mA, CELL_TYPE_LINEL)) - call fillRegion(res%surfs, res%nSurfs, res%nSurfs_max, buildRegionCoords(mA, CELL_TYPE_SURFEL)) - call fillRegion(res%vols, res%nVols, res%nVols_max, buildRegionCoords(mA, CELL_TYPE_VOXEL)) - + block + type(coords), dimension(:), allocatable :: emptyCoords + allocate(emptyCoords(0)) + if (size(mAPtrs) == 0) then + call appendRegion(res%lins, res%nLins, res%nLins_max, emptyCoords) + call appendRegion(res%surfs, res%nSurfs, res%nSurfs_max, emptyCoords) + call appendRegion(res%vols, res%nVols, res%nVols_max, emptyCoords) + end if + end block contains - subroutine fillRegion(resCoords, resNCoords, resNCoordsMax, cs) + subroutine appendRegion(resCoords, resNCoords, resNCoordsMax, cs) type(coords), dimension(:), pointer :: resCoords integer, intent(out) :: resNCoords, resNCoordsMax type(coords), dimension(:), allocatable, intent(in) :: cs + type(coords) , dimension(:), allocatable :: auxCs - allocate(resCoords(size(cs))) - resCoords(:) = cs(:) - resNCoords = size(cs) - resNCoordsMax = size(cs) - end subroutine - - function buildRegionCoords(matAssPtrs, cellType) result(res) - type(json_value_ptr), dimension(:), allocatable, intent(in) :: matAssPtrs - integer, intent(in) :: cellType - type(coords), dimension(:), allocatable :: res - - type(materialAssociation_t) :: mA - type(cell_region_t) :: cR - integer :: i, j, e - integer :: nCs - character (len=:), allocatable :: tagName - type(coords), dimension(:), allocatable :: cs - - ! Precounts - nCs = 0 - do i = 1, size(matAssPtrs) - mA = this%parseMaterialAssociation(matAssPtrs(i)%p) - do e = 1, size(mA%elementIds) - cR = this%mesh%getCellRegion(mA%elementIds(e)) - cs = cellRegionToCoords(cR, cellType) - nCs = nCs + size(cs) - end do - end do - - ! Fills - allocate(res(nCs)) - j = 1 - do i = 1, size(matAssPtrs) - mA = this%parseMaterialAssociation(matAssPtrs(i)%p) - do e = 1, size(mA%elementIds) - tagName = this%buildTagName(mA%materialId, mA%elementIds(e)) - cR = this%mesh%getCellRegion(mA%elementIds(e)) - cs = cellRegionToCoords(cR, cellType, tag=tagName) - if (size(cs) == 0) cycle - res(j:(j+size(cs)-1)) = cs - j = j + size(cs) - end do - end do - end function + if (.not. associated(resCoords)) then + allocate(resCoords(size(cs))) + resCoords(:) = cs(:) + resNCoords = size(cs) + resNCoordsMax = size(cs) + else + auxCs(:) = resCoords(:) + deallocate(resCoords) + allocate(resCoords(resNCoords + size(cs))) + resCoords(1:resNCoords) = auxCs + resCoords(resNCoords+1 : resNCoords+size(cs)) = cs(:) + resNCoords = resNCoords + size(cs) + resNCoordsMax = resNCoordsMax + size(cs) + end if + end subroutine end function function readDielectricRegions(this) result (res) @@ -504,8 +490,8 @@ function readDielectricRegions(this) result (res) res%lins = readDielectricsOfCellType(CELL_TYPE_LINEL) res%nVols = size(res%vols) - res%nSurfs = size(res%nSurfs) - res%nLins = size(res%nLins) + res%nSurfs = size(res%Surfs) + res%nLins = size(res%Lins) contains function readDielectricsOfCellType(cellType) result (res) integer, intent(in) :: cellType @@ -519,7 +505,7 @@ function readDielectricsOfCellType(cellType) result (res) integer :: nCs, nDielectrics mAPtrs = this%getMaterialAssociations(J_MAT_ASS_TYPE_BULK, J_MAT_TYPE_ISOTROPIC) - + ! Precounts nDielectrics = 0 do i = 1, size(mAPtrs) @@ -538,37 +524,22 @@ function readDielectricsOfCellType(cellType) result (res) end do end function - function readDielectric(mA, cellType) result(res) + function readDielectric(mAPtr, cellType) result(res) type(json_value), pointer, intent(in) :: mAPtr integer, intent(in) :: cellType type(Dielectric_t) :: res type(materialAssociation_t) :: mA type(cell_region_t) :: cR + type (coords), dimension(:), allocatable :: coords integer :: e, j mA = this%parseMaterialAssociation(mAPtr) - - ! Precount - res%n_C2P = 0 - do e = 1, size(mA%elementIds) - cR = this%mesh%getCellRegion(mA%elementIds(e)) - if (size(cellRegionToCoords(cR, cellType)) /= 0) then - res%n_C2P = res%n_C2P + 1 - end if - end do - - ! Fills coords - j = 0 allocate(res%c1P(0)) - allocate(res%c2P(res%n_C2P)) - do e = 1, size(mA%elementIds) - cR = this%mesh%getCellRegion(mA%elementIds(e)) - if (size(cellRegionToCoords(cR, cellType)) == 0) cycle - j = j + 1 - res%c2p(j) = cellRegionToCoords(cR) - end do - + res%n_c1p = 0 + res%c2p = this%matAssToCoords(mA, cellType) + res%n_c2p = size(res%c2p) + ! Fills rest of dielectric data. res%sigma = this%getRealAt(mAPtr, J_MAT_ELECTRIC_CONDUCTIVITY, default=0.0) res%sigmam = this%getRealAt(mAPtr, J_MAT_MAGNETIC_CONDUCTIVITY, default=0.0) @@ -597,6 +568,37 @@ logical function containsCellRegionsWithType(mAPtr, cellType) end function end function + function matAssToCoords(this, mA, cellType) result(res) + class(parser_t) :: this + type(materialAssociation_t), intent(in) :: mA + integer, intent(in) :: cellType + character (len=:), allocatable :: tagName + type (coords), dimension(:), allocatable :: res + type (cell_region_t) :: cR + integer :: nCs + integer :: e, jIni, jEnd + + ! Precount + nCs = 0 + do e = 1, size(mA%elementIds) + cR = this%mesh%getCellRegion(mA%elementIds(e)) + nCs = nCs + size(cellRegionToCoords(cR, cellType)) + end do + + ! Fills coords + jIni = 1 + allocate(res(nCs)) + do e = 1, nCs + cR = this%mesh%getCellRegion(mA%elementIds(e)) + tagName = this%buildTagName(mA%materialId, mA%elementIds(e)) + res = cellRegionToCoords(cR, cellType, tag=tagName) + if (size(res) == 0) cycle + jEnd = jIni + size(res) + res(jIni:jEnd) = res(:) + jIni = jEnd + 1 + end do + end function + function readLossyThinSurfaces(this) result (res) class(parser_t), intent(in) :: this type(LossyThinSurfaces) :: res From d480ab265e854fcb69eb92d1629a41c40f71fd3e Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Fri, 13 Dec 2024 10:44:59 +0100 Subject: [PATCH 20/25] Passes read dielectric slab test --- src_json_parser/smbjson.F90 | 76 +++++++++++++++-------- test/smbjson/test_read_dielectricSlab.F90 | 8 +-- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index a05fbe6b..57cf9a29 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -437,30 +437,37 @@ function buildPECPMCRegions(this, matType) result(res) type(PECRegions) :: res type(json_value_ptr), dimension(:), allocatable :: mAPtrs type(materialAssociation_t) :: mA + type(coords), dimension(:), pointer :: cs integer :: i mAPtrs = this%getMaterialAssociations(J_MAT_ASS_TYPE_BULK, matType) - do i = 1, size(mAPtrs) - mA = this%parseMaterialAssociation(mAptrs(i)%p) - call appendRegion(res%lins, res%nLins, res%nLins_max, this%matAssToCoords(mA, CELL_TYPE_LINEL)) - call appendRegion(res%surfs, res%nSurfs, res%nSurfs_max, this%matAssToCoords(mA, CELL_TYPE_SURFEL)) - call appendRegion(res%vols, res%nVols, res%nVols_max, this%matAssToCoords(mA, CELL_TYPE_VOXEL)) - end do - + block - type(coords), dimension(:), allocatable :: emptyCoords - allocate(emptyCoords(0)) + type(coords), dimension(:), pointer :: emptyCoords if (size(mAPtrs) == 0) then + allocate(emptyCoords(0)) call appendRegion(res%lins, res%nLins, res%nLins_max, emptyCoords) call appendRegion(res%surfs, res%nSurfs, res%nSurfs_max, emptyCoords) call appendRegion(res%vols, res%nVols, res%nVols_max, emptyCoords) + return end if end block + + do i = 1, size(mAPtrs) + mA = this%parseMaterialAssociation(mAptrs(i)%p) + call this%matAssToCoords(cs, mA, CELL_TYPE_LINEL) + call appendRegion(res%lins, res%nLins, res%nLins_max, cs) + call this%matAssToCoords(cs, mA, CELL_TYPE_SURFEL) + call appendRegion(res%surfs, res%nSurfs, res%nSurfs_max, cs) + call this%matAssToCoords(cs, mA, CELL_TYPE_VOXEL) + call appendRegion(res%vols, res%nVols, res%nVols_max, cs) + end do + contains subroutine appendRegion(resCoords, resNCoords, resNCoordsMax, cs) type(coords), dimension(:), pointer :: resCoords integer, intent(out) :: resNCoords, resNCoordsMax - type(coords), dimension(:), allocatable, intent(in) :: cs + type(coords), dimension(:), pointer, intent(in) :: cs type(coords) , dimension(:), allocatable :: auxCs if (.not. associated(resCoords)) then @@ -485,17 +492,21 @@ function readDielectricRegions(this) result (res) type(DielectricRegions) :: res type(json_value_ptr), dimension(:), allocatable :: matAssPtrs - res%vols = readDielectricsOfCellType(CELL_TYPE_VOXEL) - res%surfs = readDielectricsOfCellType(CELL_TYPE_SURFEL) - res%lins = readDielectricsOfCellType(CELL_TYPE_LINEL) + call fillDielectricsOfCellType(res%vols, CELL_TYPE_VOXEL) + call fillDielectricsOfCellType(res%surfs, CELL_TYPE_SURFEL) + call fillDielectricsOfCellType(res%lins, CELL_TYPE_LINEL) res%nVols = size(res%vols) res%nSurfs = size(res%Surfs) res%nLins = size(res%Lins) + + res%nVols_max = res%nVols + res%nSurfs_max = res%nSurfs + res%nLins_max = res%nLins contains - function readDielectricsOfCellType(cellType) result (res) + subroutine fillDielectricsOfCellType(res, cellType) integer, intent(in) :: cellType - type(dielectric_t), dimension(:), allocatable :: res + type(dielectric_t), dimension(:), pointer :: res type(json_value_ptr), dimension(:), allocatable :: mAPtrs type(materialAssociation_t) :: mA @@ -503,8 +514,12 @@ function readDielectricsOfCellType(cellType) result (res) integer :: i, j integer :: nCs, nDielectrics - + mAPtrs = this%getMaterialAssociations(J_MAT_ASS_TYPE_BULK, J_MAT_TYPE_ISOTROPIC) + if (size(mAPtrs) == 0) then + allocate(res(0)) + return + end if ! Precounts nDielectrics = 0 @@ -516,13 +531,16 @@ function readDielectricsOfCellType(cellType) result (res) ! Fills allocate(res(nDielectrics)) + + if (nDielectrics == 0) return + j = 0 do i = 1, size(mAPtrs) if (.not. containsCellRegionsWithType(mAPtrs(i)%p, cellType)) cycle j = j + 1 res(j) = readDielectric(mAPtrs(i)%p, cellType) end do - end function + end subroutine function readDielectric(mAPtr, cellType) result(res) type(json_value), pointer, intent(in) :: mAPtr @@ -537,7 +555,7 @@ function readDielectric(mAPtr, cellType) result(res) mA = this%parseMaterialAssociation(mAPtr) allocate(res%c1P(0)) res%n_c1p = 0 - res%c2p = this%matAssToCoords(mA, cellType) + call this%matAssToCoords(res%c2p, mA, cellType) res%n_c2p = size(res%c2p) ! Fills rest of dielectric data. @@ -568,12 +586,13 @@ logical function containsCellRegionsWithType(mAPtr, cellType) end function end function - function matAssToCoords(this, mA, cellType) result(res) + subroutine matAssToCoords(this, res, mA, cellType) class(parser_t) :: this type(materialAssociation_t), intent(in) :: mA + type (coords), dimension(:), pointer :: res integer, intent(in) :: cellType character (len=:), allocatable :: tagName - type (coords), dimension(:), allocatable :: res + type (coords), dimension(:), allocatable :: newCoords type (cell_region_t) :: cR integer :: nCs integer :: e, jIni, jEnd @@ -591,13 +610,13 @@ function matAssToCoords(this, mA, cellType) result(res) do e = 1, nCs cR = this%mesh%getCellRegion(mA%elementIds(e)) tagName = this%buildTagName(mA%materialId, mA%elementIds(e)) - res = cellRegionToCoords(cR, cellType, tag=tagName) - if (size(res) == 0) cycle - jEnd = jIni + size(res) - res(jIni:jEnd) = res(:) + newCoords = cellRegionToCoords(cR, cellType, tag=tagName) + if (size(newCoords) == 0) cycle + jEnd = jIni + size(newCoords) - 1 + res(jIni:jEnd) = newCoords(:) jIni = jEnd + 1 end do - end function + end subroutine function readLossyThinSurfaces(this) result (res) class(parser_t), intent(in) :: this @@ -1832,8 +1851,13 @@ function getMaterialAssociations(this, matAssType, materialType) result(res) allocate(res(0)) return end if - + mAPtrs = this%jsonValueFilterByKeyValue(allMatAss, J_TYPE, matAssType) + if (size(mAPtrs) == 0) then + allocate(res(0)) + return + end if + nMaterials = 0 do i = 1, size(mAPtrs) diff --git a/test/smbjson/test_read_dielectricSlab.F90 b/test/smbjson/test_read_dielectricSlab.F90 index 2c6b3724..f79fcd12 100644 --- a/test/smbjson/test_read_dielectricSlab.F90 +++ b/test/smbjson/test_read_dielectricSlab.F90 @@ -79,8 +79,6 @@ function expectedProblemDescription() result (expected) expected%dielRegs%nLins = 0 expected%dielRegs%nVols_max = 1 expected%dielRegs%nSurfs_max = 0 - expected%dielRegs%n_C1P_max = 0 - expected%dielRegs%n_C2P_max = 1 allocate(expected%dielRegs%Vols(1)) allocate(expected%dielRegs%Surfs(0)) allocate(expected%dielRegs%Lins(0)) @@ -95,11 +93,11 @@ function expectedProblemDescription() result (expected) expected%dielRegs%vols(1)%sigmam = 0.0 expected%dielRegs%vols(1)%c2P%Or = 0 expected%dielRegs%vols(1)%c2P%Xi = 0 - expected%dielRegs%vols(1)%c2P%Xe = 4 + expected%dielRegs%vols(1)%c2P%Xe = 3 expected%dielRegs%vols(1)%c2P%Yi = 0 - expected%dielRegs%vols(1)%c2P%Ye = 4 + expected%dielRegs%vols(1)%c2P%Ye = 3 expected%dielRegs%vols(1)%c2P%Zi = 20 - expected%dielRegs%vols(1)%c2P%Ze = 30 + expected%dielRegs%vols(1)%c2P%Ze = 29 expected%dielRegs%vols(1)%c2P%tag = 'teflon@slab' ! Expected probes From fe84cabb9fd5d0b90ce0e4e01acd8c040bea6957 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Fri, 13 Dec 2024 12:58:28 +0100 Subject: [PATCH 21/25] Minor reading pecpmc regions. --- src_json_parser/smbjson.F90 | 3 ++- test/smbjson/test_mesh.F90 | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 57cf9a29..4485b4c2 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -461,6 +461,7 @@ function buildPECPMCRegions(this, matType) result(res) call appendRegion(res%surfs, res%nSurfs, res%nSurfs_max, cs) call this%matAssToCoords(cs, mA, CELL_TYPE_VOXEL) call appendRegion(res%vols, res%nVols, res%nVols_max, cs) + deallocate(cs) end do contains @@ -607,7 +608,7 @@ subroutine matAssToCoords(this, res, mA, cellType) ! Fills coords jIni = 1 allocate(res(nCs)) - do e = 1, nCs + do e = 1, size(mA%elementIds) cR = this%mesh%getCellRegion(mA%elementIds(e)) tagName = this%buildTagName(mA%materialId, mA%elementIds(e)) newCoords = cellRegionToCoords(cR, cellType, tag=tagName) diff --git a/test/smbjson/test_mesh.F90 b/test/smbjson/test_mesh.F90 index 4cac9913..b4f173c8 100644 --- a/test/smbjson/test_mesh.F90 +++ b/test/smbjson/test_mesh.F90 @@ -101,8 +101,8 @@ integer function test_mesh_add_get_long_list() bind(C) result(error_cnt) if (.not. found) error_cnt = error_cnt + 1 if (any(obtained%position /= expected%position)) error_cnt = error_cnt + 1 end block - - call mesh%printCoordHashInfo() + + ! call mesh%printCoordHashInfo() !! For debugging only end function From 2217b2a06279791142055cc5c353d437866b4cef Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Fri, 13 Dec 2024 13:32:26 +0100 Subject: [PATCH 22/25] [WIP] thin slot reading --- doc/smbjson.md | 27 +++++++++ src_json_parser/smbjson_labels.F90 | 4 ++ test/smbjson/test_read_thinSlot.F90 | 88 +++++++++++++++-------------- testData/cases/thinSlot.fdtd.json | 29 ++++++---- 4 files changed, 93 insertions(+), 55 deletions(-) diff --git a/doc/smbjson.md b/doc/smbjson.md index ffe7e10c..d019a485 100644 --- a/doc/smbjson.md +++ b/doc/smbjson.md @@ -296,6 +296,23 @@ A `multilayeredSurface` must contain the entry `` which is an array indi } ``` +### Line materials + +In line materials, `elementIds` must reference `cell` elements. All `intervals` modeling entities different to lines are ignored. + +#### `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 `` is a real number which defines the distance between the surfaces in meters. + +```json +{ + "name": "3mm-gap", + "type": "thinSlot", + "id": 2, + "width": 3e-3 +} +``` + ### Cable materials #### `wire` @@ -476,6 +493,16 @@ Surface materials can only be assigned to elements of type `cell`. If the `cell` ] ``` +### `line` + +Line materials can only be assigned to elements of type `cell`. If the `cell` contains `intervals` representing entities different to segments these will be ignored. + +```json +"materialAssociations": [ + {"type": "line", "materialId": 2, "elementIds": [4]} +] +``` + ### `cable` This object establishes the relationship between the physical models described in a `material` and parts of the geometry. Besides a `type`, `materialId` and `elementIds`; a `cable` can contain the following inputs: diff --git a/src_json_parser/smbjson_labels.F90 b/src_json_parser/smbjson_labels.F90 index 1c8e0ba4..a8d2aeed 100644 --- a/src_json_parser/smbjson_labels.F90 +++ b/src_json_parser/smbjson_labels.F90 @@ -31,6 +31,7 @@ module smbjson_labels_mod character (len=*), parameter :: J_MAT_TYPE_PMC = "pmc" character (len=*), parameter :: J_MAT_TYPE_ISOTROPIC = "isotropic" character (len=*), parameter :: J_MAT_TYPE_MULTILAYERED_SURFACE = "multilayeredSurface" + character (len=*), parameter :: J_MAT_TYPE_SLOT = "thinSlot" character (len=*), parameter :: J_MAT_TYPE_WIRE = "wire" character (len=*), parameter :: J_MAT_TYPE_MULTIWIRE = "multiwire" character (len=*), parameter :: J_MAT_TYPE_TERMINAL = "terminal" @@ -66,6 +67,8 @@ module smbjson_labels_mod character (len=*), parameter :: J_MAT_MULTILAYERED_SURF_LAYERS = "layers" character (len=*), parameter :: J_MAT_MULTILAYERED_SURF_THICKNESS = "thickness" + + character (len=*), parameter :: J_MAT_THINSLOT_WIDTH = "width" ! -- materialAssociations character (len=*), parameter :: J_MATERIAL_ASSOCIATIONS = "materialAssociations" @@ -73,6 +76,7 @@ module smbjson_labels_mod character (len=*), parameter :: J_MAT_ASS_TYPE_BULK = "bulk" character (len=*), parameter :: J_MAT_ASS_TYPE_SURFACE = "surface" + character (len=*), parameter :: J_MAT_ASS_TYPE_LINE = "line" character (len=*), parameter :: J_MAT_ASS_TYPE_CABLE = "cable" character (len=*), parameter :: J_MAT_ASS_CAB_INI_TERM_ID = "initialTerminalId" diff --git a/test/smbjson/test_read_thinSlot.F90 b/test/smbjson/test_read_thinSlot.F90 index 92b85eee..b08a6ec1 100644 --- a/test/smbjson/test_read_thinSlot.F90 +++ b/test/smbjson/test_read_thinSlot.F90 @@ -73,43 +73,52 @@ function expectedProblemDescription() result (expected) expected%plnSrc%nc = 1 expected%plnSrc%nC_max = 1 - ! dielectric slab region - expected%dielRegs%nVols = 1 - expected%dielRegs%nSurfs = 0 - expected%dielRegs%nLins = 0 - expected%dielRegs%nVols_max = 1 - expected%dielRegs%nSurfs_max = 0 - expected%dielRegs%n_C1P_max = 0 - expected%dielRegs%n_C2P_max = 1 - allocate(expected%dielRegs%Vols(1)) - allocate(expected%dielRegs%Surfs(0)) - allocate(expected%dielRegs%Lins(0)) - ! slab - allocate(expected%dielRegs%vols(1)%c1P(0)) - allocate(expected%dielRegs%vols(1)%c2P(1)) - expected%dielRegs%vols(1)%n_C1P = 0 - expected%dielRegs%vols(1)%n_C2P = 1 - expected%dielRegs%vols(1)%sigma = 0.0 - expected%dielRegs%vols(1)%eps = 1.3*EPSILON_VACUUM - expected%dielRegs%vols(1)%mu = MU_VACUUM - expected%dielRegs%vols(1)%sigmam = 0.0 - expected%dielRegs%vols(1)%c2P%Or = 0 - expected%dielRegs%vols(1)%c2P%Xi = 0 - expected%dielRegs%vols(1)%c2P%Xe = 4 - expected%dielRegs%vols(1)%c2P%Yi = 0 - expected%dielRegs%vols(1)%c2P%Ye = 4 - expected%dielRegs%vols(1)%c2P%Zi = 20 - expected%dielRegs%vols(1)%c2P%Ze = 30 - expected%dielRegs%vols(1)%c2P%tag = 'teflon@slab' + ! materials + !! pec square + expected%pecRegs%nVols = 0 + expected%pecRegs%nSurfs = 1 + expected%pecRegs%nLins = 0 + expected%pecRegs%nVols_max = 0 + expected%pecRegs%nSurfs_max = 1 + expected%pecRegs%nLins_max = 0 + allocate(expected%pecRegs%Vols(0)) + allocate(expected%pecRegs%Surfs(1)) + allocate(expected%pecRegs%Lins(0)) + expected%pecRegs%Surfs(1)%Or = +iEz + expected%pecRegs%Surfs(1)%Xi = 0 + expected%pecRegs%Surfs(1)%Xe = 3 + expected%pecRegs%Surfs(1)%Yi = 0 + expected%pecRegs%Surfs(1)%Ye = 3 + expected%pecRegs%Surfs(1)%Zi = 25 + expected%pecRegs%Surfs(1)%Ze = 25 + expected%pecRegs%Surfs(1)%tag = 'copper@square' + + !! thin slot + expected%tSlots%n_tg = 1 + expected%tSlots%n_tg_max = 1 + allocate(expected%tslots%tg(1)) + expected%tSlots%tg(1)%width = 3e-3 + expected%tSlots%tg(1)%n_tgc = 2 + expected%tSlots%tg(1)%n_tgc_max = 2 + allocate(expected%tSlots%tg(1)%tgc(2)) + expected%tSlots%tg(1)%tgc(1)%i = 1 + expected%tSlots%tg(1)%tgc(1)%j = 2 + expected%tSlots%tg(1)%tgc(1)%k = 25 + expected%tSlots%tg(1)%tgc(1)%node = 0 + expected%tSlots%tg(1)%tgc(1)%dir = iEx + expected%tSlots%tg(1)%tgc(1)%Or = -1 + expected%tSlots%tg(1)%tgc(1)%tag = "3mm-gap@slot" + expected%tSlots%tg(1)%tgc(2) = expected%tSlots%tg(1)%tgc(1) + expected%tSlots%tg(1)%tgc(2)%i = 2 ! Expected probes ! sonda expected%Sonda%len_cor_max = 0 - expected%Sonda%length = 3 - expected%Sonda%length_max = 3 - allocate(expected%Sonda%collection(3)) + expected%Sonda%length = 2 + expected%Sonda%length_max = 2 + allocate(expected%Sonda%collection(2)) ! common data - do i = 1, 3 + do i = 1, 2 expected%Sonda%collection(i)%type1 = NP_T1_PLAIN expected%Sonda%collection(i)%type2 = NP_T2_TIME expected%Sonda%collection(i)%filename = ' ' @@ -131,19 +140,12 @@ function expectedProblemDescription() result (expected) expected%Sonda%collection(1)%cordinates(1:3)%Xi = 2 expected%Sonda%collection(1)%cordinates(1:3)%Yi = 2 expected%Sonda%collection(1)%cordinates(1:3)%Zi = 10 - ! point probe in dielectric slab - expected%Sonda%collection(2)%outputrequest = "inner" - expected%Sonda%collection(2)%cordinates(1:3)%tag = "inner" + ! point probe at back + expected%Sonda%collection(2)%outputrequest = "back" + expected%Sonda%collection(2)%cordinates(1:3)%tag = "back" expected%Sonda%collection(2)%cordinates(1:3)%Xi = 2 expected%Sonda%collection(2)%cordinates(1:3)%Yi = 2 - expected%Sonda%collection(2)%cordinates(1:3)%Zi = 25 - ! point probe at back - expected%Sonda%collection(3)%outputrequest = "back" - expected%Sonda%collection(3)%cordinates(1:3)%tag = "back" - expected%Sonda%collection(3)%cordinates(1:3)%Xi = 2 - expected%Sonda%collection(3)%cordinates(1:3)%Yi = 2 - expected%Sonda%collection(3)%cordinates(1:3)%Zi = 40 - + expected%Sonda%collection(2)%cordinates(1:3)%Zi = 40 end function end function diff --git a/testData/cases/thinSlot.fdtd.json b/testData/cases/thinSlot.fdtd.json index 84db68f7..2b874ec8 100644 --- a/testData/cases/thinSlot.fdtd.json +++ b/testData/cases/thinSlot.fdtd.json @@ -8,10 +8,10 @@ }, "boundary": { - "xLower": {"type": "pec"}, - "xUpper": {"type": "pec"}, - "yLower": {"type": "pmc"}, - "yUpper": {"type": "pmc"}, + "xLower": {"type": "periodic"}, + "xUpper": {"type": "periodic"}, + "yLower": {"type": "periodic"}, + "yUpper": {"type": "periodic"}, "zLower": {"type": "pml"}, "zUpper": {"type": "pml"} }, @@ -23,16 +23,14 @@ }, "coordinates": [ {"id": 1, "relativePosition": [2, 2, 10]}, - {"id": 2, "relativePosition": [2, 2, 25]}, {"id": 3, "relativePosition": [2, 2, 40]} ], "elements": [ {"id": 1, "type": "node", "coordinateIds": [1]}, {"id": 2, "type": "node", "coordinateIds": [2]}, - {"id": 3, "type": "node", "coordinateIds": [3]}, - {"id": 4, "type": "cell", "name": "pw-box", "intervals": [ [ [0, 0, 2], [4, 4, 48] ] ]}, - {"id": 5, "type": "cell", "name": "square", "intervals": [ [ [0, 0, 25], [4, 4, 25] ] ]}, - {"id": 6, "type": "cell", "name": "slot", "intervals": [ [ [1, 2, 25], [3, 2, 25] ] ]} + {"id": 3, "type": "cell", "name": "pw-box", "intervals": [ [ [0, 0, 2], [4, 4, 48] ] ]}, + {"id": 4, "type": "cell", "name": "square", "intervals": [ [ [0, 0, 25], [4, 4, 25] ] ]}, + {"id": 5, "type": "cell", "name": "slot", "intervals": [ [ [1, 2, 25], [3, 2, 25] ] ]} ] }, @@ -41,18 +39,25 @@ "name": "copper", "id": 1, "type": "pec" - } + }, + { + "name": "3mm-gap", + "type": "thinSlot", + "id": 2, + "width": 3e-3 + } ], "materialAssociations": [ - {"type": "bulk", "materialId": 1, "elementIds": [5]} + {"type": "bulk", "materialId": 1, "elementIds": [4]} + {"type": "line", "materialId": 2, "elementIds": [5]} ], "sources": [ { "type": "planewave", "magnitudeFile": "gauss.exc", - "elementIds": [4], + "elementIds": [3], "direction": { "theta": 0.0, "phi": 0.0 From c685e2ac2d8dbcf4311d027893a772593acd166f Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Fri, 13 Dec 2024 23:28:33 +0100 Subject: [PATCH 23/25] Passes all parsing tests --- src_json_parser/nfdetypes_extension.F90 | 6 +- src_json_parser/smbjson.F90 | 100 +++++++++++++++++++++--- test/smbjson/test_read_thinSlot.F90 | 10 +-- testData/cases/thinSlot.fdtd.json | 4 +- 4 files changed, 102 insertions(+), 18 deletions(-) diff --git a/src_json_parser/nfdetypes_extension.F90 b/src_json_parser/nfdetypes_extension.F90 index 6b1b13dc..304f10d0 100644 --- a/src_json_parser/nfdetypes_extension.F90 +++ b/src_json_parser/nfdetypes_extension.F90 @@ -599,7 +599,11 @@ end function ThinSlot_eq elemental logical function ThinSlots_eq(a, b) type(ThinSlots), intent(in) :: a, b - + if (.not. associated(a%tg) .or. & + .not. associated(b%tg)) then + ThinSlots_eq = .false. + return + end if ThinSlots_eq = all(a%tg == b%tg) .and. & (a%n_tg == b%n_tg) .and. & diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 4485b4c2..6b9758e0 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -1387,9 +1387,96 @@ subroutine appendLogSufix(fn) function readThinSlots(this) result (res) class(parser_t) :: this type(ThinSlots) :: res + + type(json_value_ptr), dimension(:), allocatable :: mAPtrs + integer :: i + + mAPtrs = this%getMaterialAssociations(J_MAT_ASS_TYPE_LINE, J_MAT_TYPE_SLOT) + if (size(mAPtrs) == 0) then + allocate(res%tg(0)) + return + end if - !! TODO - allocate(res%tg(0)) + res%n_tg = size(mAPtrs) + allocate(res%tg(res%n_tg)) + do i = 1, size(mAPtrs) + res%tg = readThinSlot(mAPtrs(i)%p) + end do + contains + function readThinSlot(mAPtr) result(res) + type (json_value), pointer, intent(in) :: mAPtr + type (thinSlot) :: res + type (materialAssociation_t) :: mA + type (coords), dimension(:), pointer :: cs + type(json_value_ptr) :: mat + logical :: found + + mA = this%parseMaterialAssociation(mAPtr) + + mat = this%matTable%getId(mA%materialId) + res%width = this%getRealAt(mat%p, J_MAT_THINSLOT_WIDTH, found) + if (.not. found) then + write(error_unit, *) "ERROR reading thin slot: ", & + J_MAT_THINSLOT_WIDTH, "not found" + end if + + call this%matAssToCoords(cs, mA, CELL_TYPE_LINEL) + call coordsToThinSlotComp(res%tgc, cs) + res%n_tgc = size(res%tgc) + + end function + + subroutine coordsToThinSlotComp(tc, cs) + type(coords), dimension(:), pointer, intent(in) :: cs + type(thinSlotComp), dimension(:), pointer :: tc + integer :: i, j, k + integer :: nTgc, nXYZ + integer :: dir + ! Precount + nTgc = 0 + do i = 1, size(cs) + nXYZ = (cs(i)%xe - cs(i)%xi + 1) * & + (cs(i)%ye - cs(i)%yi + 1) * & + (cs(i)%ze - cs(i)%zi + 1) + nTgc = nTgc + nXYZ + end do + + ! Fill + j = 1 + allocate(tc(nTgc)) + do i = 1, size(cs) + select case (abs(cs(i)%Or)) + case (iEx) + do k = 1, (cs(i)%xe - cs(i)%xi + 1) + tc(j) = buildBaseThinSlotComponent(cs(i)) + tc(j)%i = cs(i)%xi + k - 1 + j = j + 1 + end do + case (iEy) + do k = 1, (cs(i)%xe - cs(i)%xi + 1) + tc(j) = buildBaseThinSlotComponent(cs(i)) + tc(j)%j = cs(i)%yi + k - 1 + j = j + 1 + end do + case (iEz) + do k = 1, (cs(i)%xe - cs(i)%xi + 1) + tc(j) = buildBaseThinSlotComponent(cs(i)) + tc(j)%k = cs(i)%zi + k - 1 + j = j + 1 + end do + end select + end do + end subroutine + + function buildBaseThinSlotComponent(cs) result(res) + type(coords), intent(in) :: cs + type(thinSlotComp) :: res + res%i = cs%xi + res%j = cs%yi + res%k = cs%zi + res%dir = abs(cs%Or) + res%tag = cs%tag + end function end function function readThinWires(this) result (res) @@ -1817,12 +1904,7 @@ function parseMaterialAssociation(this, matAss) result(res) end do end block - if (res%matAssType /= J_MAT_ASS_TYPE_BULK .and. & - res%matAssType /= J_MAT_ASS_TYPE_SURFACE .and. & - res%matAssType /= J_MAT_ASS_TYPE_CABLE) then - write(error_unit, *) errorMsgInit, "invalid type." - endif - ! This function does not work with material associatiosn for cables. + ! This function does not work with material associations for cables. ! DO NOT use it to read that. if (res%matAssType == J_MAT_ASS_TYPE_CABLE) then write(error_unit, *) errorMsgInit, "invalid type." @@ -1831,7 +1913,7 @@ function parseMaterialAssociation(this, matAss) result(res) contains subroutine showLabelNotFoundError(label) character (len=*), intent(in) :: label - write(error_unit, *) errorMsgInit, label, " not found." + end subroutine end function diff --git a/test/smbjson/test_read_thinSlot.F90 b/test/smbjson/test_read_thinSlot.F90 index b08a6ec1..1fa5b8e8 100644 --- a/test/smbjson/test_read_thinSlot.F90 +++ b/test/smbjson/test_read_thinSlot.F90 @@ -50,10 +50,10 @@ function expectedProblemDescription() result (expected) expected%despl%mz2 = 50 ! Expected boundaries. - expected%front%tipoFrontera(F_XL) = F_PEC - expected%front%tipoFrontera(F_XU) = F_PEC - expected%front%tipoFrontera(F_YL) = F_PMC - expected%front%tipoFrontera(F_YU) = F_PMC + expected%front%tipoFrontera(F_XL) = F_PER + expected%front%tipoFrontera(F_XU) = F_PER + expected%front%tipoFrontera(F_YL) = F_PER + expected%front%tipoFrontera(F_YU) = F_PER expected%front%tipoFrontera(F_ZL) = F_PML expected%front%tipoFrontera(F_ZU) = F_PML @@ -95,11 +95,9 @@ function expectedProblemDescription() result (expected) !! thin slot expected%tSlots%n_tg = 1 - expected%tSlots%n_tg_max = 1 allocate(expected%tslots%tg(1)) expected%tSlots%tg(1)%width = 3e-3 expected%tSlots%tg(1)%n_tgc = 2 - expected%tSlots%tg(1)%n_tgc_max = 2 allocate(expected%tSlots%tg(1)%tgc(2)) expected%tSlots%tg(1)%tgc(1)%i = 1 expected%tSlots%tg(1)%tgc(1)%j = 2 diff --git a/testData/cases/thinSlot.fdtd.json b/testData/cases/thinSlot.fdtd.json index 2b874ec8..510190bc 100644 --- a/testData/cases/thinSlot.fdtd.json +++ b/testData/cases/thinSlot.fdtd.json @@ -23,7 +23,7 @@ }, "coordinates": [ {"id": 1, "relativePosition": [2, 2, 10]}, - {"id": 3, "relativePosition": [2, 2, 40]} + {"id": 2, "relativePosition": [2, 2, 40]} ], "elements": [ {"id": 1, "type": "node", "coordinateIds": [1]}, @@ -49,7 +49,7 @@ ], "materialAssociations": [ - {"type": "bulk", "materialId": 1, "elementIds": [4]} + {"type": "bulk", "materialId": 1, "elementIds": [4]}, {"type": "line", "materialId": 2, "elementIds": [5]} ], From 3538f152d14f9b70d0f29516251889f68ad73150 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Fri, 13 Dec 2024 23:36:33 +0100 Subject: [PATCH 24/25] Rename dielectric_slab case --- test/smbjson/test_read_dielectricSlab.F90 | 2 +- .../{dielectricSlab.fdtd.json => dielectric_slab.fdtd.json} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename testData/cases/{dielectricSlab.fdtd.json => dielectric_slab.fdtd.json} (100%) diff --git a/test/smbjson/test_read_dielectricSlab.F90 b/test/smbjson/test_read_dielectricSlab.F90 index f79fcd12..2313e503 100644 --- a/test/smbjson/test_read_dielectricSlab.F90 +++ b/test/smbjson/test_read_dielectricSlab.F90 @@ -4,7 +4,7 @@ integer function test_read_dielectricslab() bind (C) result(err) implicit none - character(len=*), parameter :: filename = PATH_TO_TEST_DATA//'cases/dielectricSlab.fdtd.json' + character(len=*), parameter :: filename = PATH_TO_TEST_DATA//'cases/dielectric_slab.fdtd.json' type(Parseador) :: pr, ex type(parser_t) :: parser logical :: areSame diff --git a/testData/cases/dielectricSlab.fdtd.json b/testData/cases/dielectric_slab.fdtd.json similarity index 100% rename from testData/cases/dielectricSlab.fdtd.json rename to testData/cases/dielectric_slab.fdtd.json From b0e1fc765f26dbb1622982c23a98448fd25d8811 Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Fri, 13 Dec 2024 23:51:18 +0100 Subject: [PATCH 25/25] Minor --- src_json_parser/smbjson.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src_json_parser/smbjson.F90 b/src_json_parser/smbjson.F90 index 6b9758e0..bef3eb3c 100644 --- a/src_json_parser/smbjson.F90 +++ b/src_json_parser/smbjson.F90 @@ -1786,8 +1786,10 @@ function getDomain(this, place, path) result(res) real :: val call this%core%get(place, path, domain, found) - if (.not. found) return - + if (.not. found) then + res%filename = " " + return + end if call this%core%get(domain, J_PR_DOMAIN_MAGNITUDE_FILE, fn, transferFunctionFound) if (found) then