Skip to content

Commit

Permalink
Separating correct read input tests from test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
lmdiazangulo committed Dec 23, 2024
1 parent 5008a70 commit fafcd0d
Show file tree
Hide file tree
Showing 40 changed files with 64,419 additions and 164 deletions.
118 changes: 86 additions & 32 deletions src_pyWrapper/pyWrapper.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import subprocess
import json
import os
import glob, re
import shutil
import glob
import re
import pandas as pd
import numpy as np

def positionStrToCell(pos_str):
pos = pos_str.split('_')
return np.array([int(pos[0]), int(pos[1]), int(pos[2])])
DEFAULT_SEMBA_FDTD_PATH = '/build/bin/semba-fdtd'

class Probe():

@staticmethod
def _positionStrToCell(pos_str):
pos = pos_str.split('_')
return np.array([int(pos[0]), int(pos[1]), int(pos[2])])

def __init__(self, probe_filename):
self.filename = probe_filename

Expand Down Expand Up @@ -39,14 +44,14 @@ def __init__(self, probe_filename):
if tag in current_probe_tags:
self.type = 'wire'
self.name, position_str = basename_with_no_case_name.split(tag)
self.cell = positionStrToCell(position_str)
self.cell = self._positionStrToCell(position_str)
self.segment_tag = int(position_str.split('_s')[1])
self.df = pd.read_csv(self.filename, sep='\s+')
self.df = self.df.rename(columns={'t': 'time', self.df.columns[1]: 'current'})
elif tag in point_probe_tags:
self.type = 'point'
self.name, position_str = basename_with_no_case_name.split(tag)
self.cell = positionStrToCell(position_str)
self.cell = self._positionStrToCell(position_str)
self.field = tag[1]
self.direction = tag[2]
self.df = pd.read_csv(self.filename, sep='\s+')
Expand All @@ -59,19 +64,19 @@ def __init__(self, probe_filename):
self.type = 'farField'
self.name, positions_str = basename_with_no_case_name.split(tag)
init_str, end_str = positions_str.split('__')
self.cell_init = positionStrToCell(init_str)
self.cell_end = positionStrToCell(end_str)
self.cell_init = self._positionStrToCell(init_str)
self.cell_end = self._positionStrToCell(end_str)
self.df = pd.read_csv(self.filename, sep='\s+')
elif tag in movie_tags:
self.type = 'movie'
self.name, positions_str = basename_with_no_case_name.split(tag)
init_str, end_str = positions_str.split('__')
self.cell_init = positionStrToCell(init_str)
self.cell_end = positionStrToCell(end_str)
self.cell_init = self._positionStrToCell(init_str)
self.cell_end = self._positionStrToCell(end_str)
elif tag in mtln_probe_tags:
self.type ='mtln'
self.name, position_str = basename_with_no_case_name.split(tag)
self.cell = positionStrToCell(position_str)
self.cell = self._positionStrToCell(position_str)
self.df = pd.read_csv(self.filename, sep='\s+')
else:
raise ValueError("Unable to determine probe name or type for a probe with name:" + basename)
Expand All @@ -86,26 +91,80 @@ def __getitem__(self, key):
return self.df[key]

class FDTD():
def __init__(self, input_filename, path_to_exe, flags = []):
self.filename = input_filename
self.path_to_exe = path_to_exe

def __init__(self, input_filename, path_to_exe=None, flags = [], run_in_folder = None):
self._setFilename(input_filename)

if path_to_exe == None:
self.path_to_exe = os.getcwd() + DEFAULT_SEMBA_FDTD_PATH
else:
self.path_to_exe = path_to_exe
assert os.path.isfile(self.path_to_exe)

self.flags = flags

self.folder = os.path.dirname(self.filename)
if len(self.folder) == 0:
self.folder = './'
self.case = os.path.basename(self.filename).split('.json')[0]
self.hasRun = False
self._hasRun = False

if run_in_folder != None:
self._setNewFolder(run_in_folder)


def getFolder(self):
res = os.path.dirname(self._filename)
if len(res) == 0:
return './'
return res

def getCaseName(self):
return os.path.basename(self._filename).split('.json')[0]

def _setFilename(self, newFilename):
assert os.path.isfile(newFilename)
self._filename = newFilename
self.input = json.load(open(self._filename))


def _getUsedFiles(self):
res = []

if 'sources' in self.input:
for src in self.input['sources']:
if 'magnitudeFile' in src:
res.append(src['magnitudeFile'])

if 'probes' in self.input:
for src in self.input['probes']:
if 'magnitudeFile' in src:
res.append(src['magnitudeFile'])
return res

def _setNewFolder(self, newFolder):
assert os.path.isdir(newFolder)

oldCaseFolder = self.getFolder()
usedFiles = self._getUsedFiles()
for usedFile in usedFiles:
newFile = os.path.join(oldCaseFolder, usedFile)
shutil.copy(newFile, newFolder)

newFilename = shutil.copy(self._filename, newFolder)
self._setFilename(newFilename)

def run(self):
os.chdir(self.folder)
case_name = self.case + ".json"
if self.input != json.load(open(self._filename, 'r')):
json.dump(self.input, open(self._filename,'w'))

os.chdir(self.getFolder())
case_name = self.getCaseName() + ".json"
self.output = subprocess.run([self.path_to_exe, "-i",case_name]+self.flags)
self.hasRun = True
self._hasRun = True

def hasFinishedSuccessfully(self):
if self._hasRun and (self.output.returncode == 0):
return True
else:
return False

def readJsonDict(self):
with open(self.filename) as input_file:
with open(self._filename) as input_file:
return json.load(input_file)

def getSolvedProbeFilenames(self, probe_name):
Expand All @@ -116,7 +175,7 @@ def getSolvedProbeFilenames(self, probe_name):
file_extensions = ('*.dat', '*.xdmf', '*.bin', '*.h5')
probeFiles = []
for ext in file_extensions:
newProbes = [x for x in glob.glob(ext) if re.match(self.case + '_' + probe_name, x)]
newProbes = [x for x in glob.glob(ext) if re.match(self.getCaseName() + '_' + probe_name, x)]
probeFiles.extend(newProbes)

return probeFiles
Expand All @@ -130,11 +189,6 @@ def getVTKMap(self):
assert os.path.isfile(mapFile)
return mapFile

def hasFinishedSuccessfully(self):
if self.hasRun:
if (self.output.returncode == 0):
return True
else:
return False



139 changes: 23 additions & 116 deletions test/pyWrapper/test_integration.py
Original file line number Diff line number Diff line change
@@ -1,75 +1,32 @@
from utils import *
import pytest


def test_probes_output_exists(tmp_path):
case = 'holland1981'
input_json = getCase(case)
input_json['general']['numberOfSteps'] = 1
fn = tmp_path._str + '/' + case + '.fdtd.json'
with open(fn, 'w') as modified_json:
json.dump(input_json, modified_json)

makeCopy(tmp_path, EXCITATIONS_FOLDER+'holland.exc')

solver = FDTD(input_filename = fn, path_to_exe=SEMBA_EXE)
solver.run()
probe_files = solver.getSolvedProbeFilenames("mid_point")
def test_holland_case_checking_number_of_outputs(tmp_path):
fn = CASE_FOLDER + 'holland/holland1981.fdtd.json'
solver = FDTD(fn, path_to_exe=SEMBA_EXE, run_in_folder=tmp_path)

assert solver.hasFinishedSuccessfully() == True
assert len(probe_files) == 1
assert 'holland1981.fdtd_mid_point_Wz_11_11_12_s2.dat' == probe_files[0]


def test_probes_output_number_of_steps(tmp_path):
case = 'holland1981'
input_json = getCase(case)
number_of_steps = 10
input_json['general']['numberOfSteps'] = number_of_steps
fn = tmp_path._str + '/' + case + '.fdtd.json'
with open(fn, 'w') as modified_json:
json.dump(input_json, modified_json)

makeCopy(tmp_path, EXCITATIONS_FOLDER+'holland.exc')

solver = FDTD(input_filename = fn, path_to_exe=SEMBA_EXE)
solver.run()
probe_files = solver.getSolvedProbeFilenames("mid_point")
solver.input['general']['numberOfSteps'] = number_of_steps

assert solver.hasFinishedSuccessfully() == True
assert len(probe_files) == 1
assert 'holland1981.fdtd_mid_point_Wz_11_11_12_s2.dat' == probe_files[0]
assert countLinesInFile(probe_files[0]) == number_of_steps + 2


def test_holland_case_creates_probes(tmp_path):
case = 'holland1981'
makeCopy(tmp_path, EXCITATIONS_FOLDER+'holland.exc')
makeCopy(tmp_path, CASE_FOLDER + case + '.fdtd.json')
fn = tmp_path._str + '/' + case + '.fdtd.json'

solver = FDTD(input_filename = fn, path_to_exe=SEMBA_EXE)
solver.run()
assert solver.hasFinishedSuccessfully()

probe_files = solver.getSolvedProbeFilenames("mid_point")

assert solver.hasFinishedSuccessfully() == True
assert len(probe_files) == 1
assert 'holland1981.fdtd_mid_point_Wz_11_11_12_s2.dat' == probe_files[0]
assert countLinesInFile(probe_files[0]) == 1002
assert countLinesInFile(probe_files[0]) == number_of_steps + 2


def test_towel_hanger_case_creates_output_probes(tmp_path):
case = 'towelHanger'
input_json = getCase(case)
input_json['general']['numberOfSteps'] = 1
fn = CASE_FOLDER + 'towelHanger/towelHanger.fdtd.json'
solver = FDTD(fn, path_to_exe=SEMBA_EXE, run_in_folder=tmp_path)
solver.input['general']['numberOfSteps'] = 1

fn = tmp_path._str + '/' + case + '.fdtd.json'
with open(fn, 'w') as modified_json:
json.dump(input_json, modified_json)

makeCopy(tmp_path, EXCITATIONS_FOLDER+'towelHanger.exc')

solver = FDTD(input_filename = fn, path_to_exe=SEMBA_EXE)
solver.run()

probe_start = solver.getSolvedProbeFilenames("wire_start")
probe_mid = solver.getSolvedProbeFilenames("wire_mid")
probe_end = solver.getSolvedProbeFilenames("wire_end")
Expand All @@ -87,20 +44,12 @@ def test_towel_hanger_case_creates_output_probes(tmp_path):
assert countLinesInFile(probe_end[0]) == 3


def test_case_with_far_field_probe(tmp_path):
case = 'sphere'
input_json = getCase(case)
input_json['general']['numberOfSteps'] = 1
input_json['probes'][0]['domain']['numberOfFrequencies'] = 100

def test_sphere_case_with_far_field_probe_launches(tmp_path):
fn = CASE_FOLDER + 'sphere/sphere.fdtd.json'
solver = FDTD(fn, path_to_exe=SEMBA_EXE, run_in_folder=tmp_path)
solver.input['general']['numberOfSteps'] = 1
solver.input['probes'][0]['domain']['numberOfFrequencies'] = 100

fn = tmp_path._str + '/' + case + '.fdtd.json'
with open(fn, 'w') as modified_json:
json.dump(input_json, modified_json)

makeCopy(tmp_path, EXCITATIONS_FOLDER+'gauss.exc')

solver = FDTD(input_filename = fn, path_to_exe=SEMBA_EXE)
solver.run()

p = Probe(solver.getSolvedProbeFilenames("Far")[0])
Expand All @@ -112,62 +61,20 @@ def test_case_with_far_field_probe(tmp_path):
assert p.case_name == 'sphere'
assert p.type == 'movie'
assert np.all(p.cell_init == np.array([2,2,2]))


def test_case_with_mapvtk(tmp_path):
case = 'airplane'
input_json = getCase(case)
input_json['general']['numberOfSteps'] = 1

fn = tmp_path._str + '/' + case + '.fdtd.json'
with open(fn, 'w') as modified_json:
json.dump(input_json, modified_json)

makeCopy(tmp_path, EXCITATIONS_FOLDER+'gauss.exc')

solver = FDTD(input_filename = fn, path_to_exe=SEMBA_EXE, flags=['-mapvtk'])
solver.run()

assert solver.hasFinishedSuccessfully()

vtkmapfile = solver.getVTKMap()

assert os.path.isfile(vtkmapfile)


def test_sgbc_can_launch(tmp_path):
case = 'sgbc'
input_json = getCase(case)
input_json['general']['numberOfSteps'] = 1
fn = tmp_path._str + '/' + case + '.fdtd.json'
with open(fn, 'w') as modified_json:
json.dump(input_json, modified_json)

solver = FDTD(input_filename = fn, path_to_exe=SEMBA_EXE)
solver.run()

assert solver.hasFinishedSuccessfully() == True


def test_sgbc_with_mapvtk_checking_tagnumbers(tmp_path):
case = 'sgbc'
input_json = getCase(case)
input_json['general']['numberOfSteps'] = 1
fn = tmp_path._str + '/' + case + '.fdtd.json'
with open(fn, 'w') as modified_json:
json.dump(input_json, modified_json)

solver = FDTD(input_filename = fn, path_to_exe=SEMBA_EXE, flags=['-mapvtk'])
fn = CASE_FOLDER + 'sgbc/sgbc.fdtd.json'
solver = FDTD(input_filename = fn, path_to_exe=SEMBA_EXE, run_in_folder=tmp_path, flags=['-mapvtk'])
solver.input['general']['numberOfSteps'] = 1

solver.run()

assert solver.hasFinishedSuccessfully() == True

vtkmapfile = solver.getVTKMap()

vtkmapfile = solver.getVTKMap()
assert os.path.isfile(vtkmapfile)

d = createFaceTagDictionary(vtkmapfile)
assert d[64] == 4
assert d[128] == 4
assert d[192] == 4

assert d[192] == 4
12 changes: 11 additions & 1 deletion test/pyWrapper/test_pyWrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,14 @@ def test_read_point_probe():
assert len(p['incident']) == 5193
assert np.isclose(p['incident'][0], 0.134010895E-005)
assert p['incident'].iat[-1] == 0.0



def test_set_new_folder_to_run(tmp_path):
input = CASE_FOLDER + 'planewave/pw-in-box.fdtd.json'
solver = FDTD(input, path_to_exe=SEMBA_EXE, run_in_folder=tmp_path)

solver.input['general']['numberOfSteps'] = 1

solver.run()
assert solver.hasFinishedSuccessfully()

2 changes: 2 additions & 0 deletions test/smbjson/smbjson_testingTools.F90
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module smbjson_testingTools
implicit none

character(len=*), parameter :: PATH_TO_TEST_DATA = 'testData/'
character(len=*), parameter :: INPUT_EXAMPLES='input_examples/'

contains
subroutine expect_eq_int(err, ex, pr, msg)
integer, intent(inout) :: err
Expand Down
Loading

0 comments on commit fafcd0d

Please sign in to comment.