diff --git a/scripts/geouned b/scripts/geouned index 7ef6df68..5f398a38 100644 --- a/scripts/geouned +++ b/scripts/geouned @@ -38,8 +38,8 @@ else: if not runReverse : - GEO = CadToCsg(inifile) - GEO.SetOptions() + GEO = CadToCsg() + GEO.SetConfiguration(inifile) GEO.Start() else: diff --git a/scripts/geouned.py b/scripts/geouned.py index 7b453ec7..98fb81f4 100644 --- a/scripts/geouned.py +++ b/scripts/geouned.py @@ -38,8 +38,8 @@ raise ValueError("Too many input arguments") if not runReverse: - GEO = CadToCsg(inifile) - GEO.SetOptions() + GEO = CadToCsg() + GEO.SetConfiguration(inifile) GEO.Start() else: diff --git a/scripts/geounedClassCall.py b/scripts/geounedClassCall.py new file mode 100644 index 00000000..b60e757f --- /dev/null +++ b/scripts/geounedClassCall.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +# Path to GEOUNED Package + + +# only if modules are not in the PYTHONPATH or directly installed in the python distribution used +import sys + +geo_path="C:\\Users\\Patrick\\Documents\\GitHub\\GEOUNED\\src" +sys.path.append(geo_path) +sys.path.append('C:\\Program Files\\FreeCAD 0.19\\bin...') + +from geouned import CadToCsg + +stepFileName = 'placa.stp' + +GEO = CadToCsg('Conversion Example') + +GEO.set('stepFile', stepFileName) +GEO.set('geometryName','Placa') +GEO.set('outFormat', ('mcnp', 'openMC_XML')) +GEO.set('planeDistance', 0.05) +GEO.set('quadricPY', True) +GEO.set('P_abc', '12f') +GEO.set('P_d', '12f') +GEO.Start() + + diff --git a/src/geouned/GEOUNED/Utils/Options/Classes.py b/src/geouned/GEOUNED/Utils/Options/Classes.py index e1225583..16a27875 100644 --- a/src/geouned/GEOUNED/Utils/Options/Classes.py +++ b/src/geouned/GEOUNED/Utils/Options/Classes.py @@ -1,10 +1,38 @@ class Options: - pass + from .optionsDefault import defaultValues, typeDict + @classmethod + def setDefaultAttribute(cls): + for key,value in cls.defaultValues.items(): + setattr(cls, key, value) + @classmethod + def setAttribute(cls,key,value): + if key in cls.defaultValues.keys(): + setattr(cls, key, value) -class McnpNumericFormat: - pass +class Tolerances: + from .tolerancesDefault import defaultValues, typeDict, KwrdEquiv + @classmethod + def setDefaultAttribute(cls): + for key,value in cls.defaultValues.items(): + setattr(cls, key, value) -class Tolerances: - pass + @classmethod + def setAttribute(cls,key,value): + if key in cls.defaultValues.keys(): + setattr(cls, key, value) + + +class McnpNumericFormat: + from .mcnpNumericDefault import defaultValues + + @classmethod + def setDefaultAttribute(cls): + for key,value in cls.defaultValues.items(): + setattr(cls, key, value) + + @classmethod + def setAttribute(cls,key,value): + if key in cls.defaultValues.keys(): + setattr(cls, key, value) diff --git a/src/geouned/GEOUNED/Utils/Options/__init__.py b/src/geouned/GEOUNED/Utils/Options/__init__.py index cf7dd128..e69de29b 100644 --- a/src/geouned/GEOUNED/Utils/Options/__init__.py +++ b/src/geouned/GEOUNED/Utils/Options/__init__.py @@ -1,77 +0,0 @@ -from .Classes import McnpNumericFormat, Options, Tolerances - -# default options values -forceCylinder = True # Force using cylinders instead cones for auxillary surfaces of torus surface definition -newSplitPlane = True # Use new module for planes splitting in decomposition module -delLastNumber = False # Deleting the last word in the comment if it is a number -verbose = False # Display information during conversion process -enlargeBox = 2 # Enlarge box Boundary when evaluating Ctable (dimension in mm) -nPlaneReverse = 0 # numbers of plane thresold whether cut of parallel planes are made fisrt with lowest or highest number -splitTolerance = 0 # First try for fuzzy tolerance used in BOPTOOL Split function. If BOPTSplit crash try lower value for tolerance -scaleUp = True # Scale up Fuzzy tolerance once get below 1e-12 -quadricPY = False # use quadric form of cones and cylinder not aligned with X,Y,Z axis when write openMC script file -Facets = False # use alternative conversion module when geometry is defined by cells compound by only triangular plane faces -prnt3PPlane = ( - False # print 3 point plane definition in MCNP output as 3 points coordinates -) -forceNoOverlap = False # force no overlaping cell definition. Adjacent cell definition are rested from current cell definition - -tolValueDict = { - "relativeTol": False, - "relativePrecision": 1.0e-6, # relative precision - "value": 1.0e-6, # Tolerance in single value comparison - "distance": 1.0e-4, # General Distance Tolerance - "angle": 1.0e-4, # General Angle Tolerance - "pln_distance": 1.0e-4, # distance between planes equal planes if distance between parallel planes < 1e-4 cm - "pln_angle": 1.0e-4, # angle between axis. 1e-4 : planes separate each other 0.1mm each 1m - "cyl_distance": 1.0e-4, # distance between radius/center - "cyl_angle": 1.0e-4, # angle between axis - "sph_distance": 1.0e-4, # distance between radius/center - "kne_distance": 1.0e-4, # distance between apex - "kne_angle": 1.0e-4, # angle between semiangles/axis - "tor_distance": 1.0e-4, # distance between Major/Minor radii/center - "tor_angle": 1.0e-4, # angle between axis - "min_area": 1.0e-2, -} # minimun face area to consider in cell definition - - -numValueDict = { - "P_abc": "14.7e", # Plane general a,b,c params - "P_d": "14.7e", # Plane general d params - "P_xyz": "14.7e", # PX/PY/PZ params - "S_r": "14.7e", # SO/SX/SY/SZ/S radius - "S_xyz": "14.7e", # SO/SX/SY/SZ/S center - "C_r": "12f", # Cylinder radius - "C_xyz": "12f", # Cylinder center - "K_xyz": "13.6e", # Cone apex - "K_tan2": "12f", # Cone tan^2 value - "T_r": "14.7e", # Torus radii - "T_xyz": "14.7e", # Torus center - "GQ_1to6": "18.15f", # GQ 1 to 6 coefficients (order 2 x2,y2,z2,xy,...) - "GQ_7to9": "18.15f", # GQ 7 to 9 coefficients (order 1 x,y,z) - "GQ_10": "18.15f", -} # GQ 10 coefficient (order 0) - - -# Set default attributes to Options class -setattr(Options, "forceCylinder", forceCylinder) -setattr(Options, "newSplitPlane", newSplitPlane) -setattr(Options, "enlargeBox", enlargeBox) -setattr(Options, "delLastNumber", delLastNumber) -setattr(Options, "verbose", verbose) -setattr(Options, "nPlaneReverse", nPlaneReverse) -setattr(Options, "splitTolerance", splitTolerance) -setattr(Options, "scaleUp", scaleUp) -setattr(Options, "quadricPY", quadricPY) -setattr(Options, "Facets", Facets) -setattr(Options, "prnt3PPlane", prnt3PPlane) -setattr(Options, "forceNoOverlap", forceNoOverlap) - -# Set default attributes to Tolerances class -for key in tolValueDict.keys(): - setattr(Tolerances, key, tolValueDict[key]) - - -# Set default attributes to MCNP number format class -for key in numValueDict.keys(): - setattr(McnpNumericFormat, key, numValueDict[key]) diff --git a/src/geouned/GEOUNED/Utils/Options/mcnpNumericDefault.py b/src/geouned/GEOUNED/Utils/Options/mcnpNumericDefault.py new file mode 100644 index 00000000..24957c93 --- /dev/null +++ b/src/geouned/GEOUNED/Utils/Options/mcnpNumericDefault.py @@ -0,0 +1,16 @@ +defaultValues = { + "P_abc": "14.7e", # Plane general a,b,c params + "P_d": "14.7e", # Plane general d params + "P_xyz": "14.7e", # PX/PY/PZ params + "S_r": "14.7e", # SO/SX/SY/SZ/S radius + "S_xyz": "14.7e", # SO/SX/SY/SZ/S center + "C_r": "12f", # Cylinder radius + "C_xyz": "12f", # Cylinder center + "K_xyz": "13.6e", # Cone apex + "K_tan2": "12f", # Cone tan^2 value + "T_r": "14.7e", # Torus radii + "T_xyz": "14.7e", # Torus center + "GQ_1to6": "18.15f", # GQ 1 to 6 coefficients (order 2 x2,y2,z2,xy,...) + "GQ_7to9": "18.15f", # GQ 7 to 9 coefficients (order 1 x,y,z) + "GQ_10": "18.15f", # GQ 10 coefficient (order 0) +} \ No newline at end of file diff --git a/src/geouned/GEOUNED/Utils/Options/optionsDefault.py b/src/geouned/GEOUNED/Utils/Options/optionsDefault.py new file mode 100644 index 00000000..b00b8323 --- /dev/null +++ b/src/geouned/GEOUNED/Utils/Options/optionsDefault.py @@ -0,0 +1,30 @@ +# default options values +defaultValues = { + "forceCylinder" : False, # Force using cylinders instead cones for auxillary surfaces of torus surface definition + "newSplitPlane" : True, # Use new module for planes splitting in decomposition module + "delLastNumber" : False, # Deleting the last word in the comment if it is a number + "verbose" : False, # Display information during conversion process + "enlargeBox" : 2, # Enlarge box Boundary when evaluating Ctable (dimension in mm) + "nPlaneReverse" : 0, # numbers of plane thresold whether cut of parallel planes are made fisrt with lowest or highest number + "splitTolerance" : 0, # First try for fuzzy tolerance used in BOPTOOL Split function. If BOPTSplit crash try lower value for tolerance + "scaleUp" : True, # Scale up Fuzzy tolerance once get below 1e-12 + "quadricPY" : False, # use quadric form of cones and cylinder not aligned with X,Y,Z axis when write openMC script file + "Facets" : False, # use alternative conversion module when geometry is defined by cells compound by only triangular plane faces + "prnt3PPlane" : False, # print 3 point plane definition in MCNP output as 3 points coordinates + "forceNoOverlap" : False, # force no overlaping cell definition. Adjacent cell definition are rested from current cell definition +} + +typeDict = { + "forceCylinder" : bool, # Force using cylinders instead cones for auxillary surfaces of torus surface definition + "newSplitPlane" : bool, # Use new module for planes splitting in decomposition module + "delLastNumber" : bool, # Deleting the last word in the comment if it is a number + "verbose" : bool, # Display information during conversion process + "enlargeBox" : float, # Enlarge box Boundary when evaluating Ctable (dimension in mm) + "nPlaneReverse" : int, # numbers of plane thresold whether cut of parallel planes are made fisrt with lowest or highest number + "splitTolerance" : int, # First try for fuzzy tolerance used in BOPTOOL Split function. If BOPTSplit crash try lower value for tolerance + "scaleUp" : bool, # Scale up Fuzzy tolerance once get below 1e-12 + "quadricPY" : bool, # use quadric form of cones and cylinder not aligned with X,Y,Z axis when write openMC script file + "Facets" : bool, # use alternative conversion module when geometry is defined by cells compound by only triangular plane faces + "prnt3PPlane" : bool, # print 3 point plane definition in MCNP output as 3 points coordinates + "forceNoOverlap" : bool, # force no overlaping cell definition. Adjacent cell definition are rested from current cell definition +} \ No newline at end of file diff --git a/src/geouned/GEOUNED/Utils/Options/tolerancesDefault.py b/src/geouned/GEOUNED/Utils/Options/tolerancesDefault.py new file mode 100644 index 00000000..bf3aa02e --- /dev/null +++ b/src/geouned/GEOUNED/Utils/Options/tolerancesDefault.py @@ -0,0 +1,53 @@ +defaultValues = { + "relativeTol": False, + "relativePrecision": 1.0e-6, # relative precision + "value": 1.0e-6, # Tolerance in single value comparison + "distance": 1.0e-4, # General Distance Tolerance + "angle": 1.0e-4, # General Angle Tolerance + "pln_distance": 1.0e-4, # distance between planes equal planes if distance between parallel planes < 1e-4 cm + "pln_angle": 1.0e-4, # angle between axis. 1e-4 : planes separate each other 0.1mm each 1m + "cyl_distance": 1.0e-4, # distance between radius/center + "cyl_angle": 1.0e-4, # angle between axis + "sph_distance": 1.0e-4, # distance between radius/center + "kne_distance": 1.0e-4, # distance between apex + "kne_angle": 1.0e-4, # angle between semiangles/axis + "tor_distance": 1.0e-4, # distance between Major/Minor radii/center + "tor_angle": 1.0e-4, # angle between axis + "min_area": 1.0e-2, # minimun face area to consider in cell definition +} + +typeDict = { + "relativeTol": bool, + "relativePrecision": float, # relative precision + "value": float, # Tolerance in single value comparison + "distance": float, # General Distance Tolerance + "angle": float, # General Angle Tolerance + "pln_distance": float, # distance between planes equal planes if distance between parallel planes < 1e-4 cm + "pln_angle": float, # angle between axis. 1e-4 : planes separate each other 0.1mm each 1m + "cyl_distance": float, # distance between radius/center + "cyl_angle": float, # angle between axis + "sph_distance": float, # distance between radius/center + "kne_distance": float, # distance between apex + "kne_angle": float, # angle between semiangles/axis + "tor_distance": float, # distance between Major/Minor radii/center + "tor_angle": float, # angle between axis + "min_area": float, # minimun face area to consider in cell definition +} + +KwrdEquiv = { + "relativeTolerance": "relativeTol", + "relativePrecision": "relativePrecision", + "singleValue": "value", + "generalDistance": "distance", + "generalAngle": "angle", + "planeDistance": "pln_distance", + "planeAngle": "pln_angle", + "cylinderDistance": "cyl_distance", + "cylinderAngle": "cyl_angle", + "sphereDistance": "sph_distance", + "coneDistance": "kne_distance", + "coneAngle": "kne_angle", + "torusDistance": "tor_distance", + "torusAngle": "tor_angle", + "minArea": "min_area", +} \ No newline at end of file diff --git a/src/geouned/GEOUNED/__init__.py b/src/geouned/GEOUNED/__init__.py index 87ef7e86..686dead2 100644 --- a/src/geouned/GEOUNED/__init__.py +++ b/src/geouned/GEOUNED/__init__.py @@ -152,61 +152,18 @@ def __init__( self.cellSummaryFile = cellSummaryFile self.sortEnclosure = sortEnclosure - def SetOptions(self): - toleranceKwrd = ( - "relativeTolerance", - "relativePrecision", - "singleValue", - "generalDistance", - "generalAngle", - "planeDistance", - "planeAngle", - "cylinderDistance", - "cylinderAngle", - "sphereDistance", - "coneDistance", - "coneAngle", - "torusDistance", - "torusAngle", - "minArea", - ) - numericKwrd = ( - "P_abc", - "P_d", - "P_xyz", - "S_r", - "S_xyz", - "C_r", - "C_xyz", - "K_tan2", - "K_xyz", - "T_r", - "T_xyz", - "GQ_1to6", - "GQ_7to9", - "GQ_10", - ) - tolKwrdEquiv = { - "relativeTolerance": "relativeTol", - "relativePrecision": "relativePrecision", - "singleValue": "value", - "generalDistance": "distance", - "generalAngle": "angle", - "planeDistance": "pln_distance", - "planeAngle": "pln_angle", - "cylinderDistance": "cyl_distance", - "cylinderAngle": "cyl_angle", - "sphereDistance": "sph_distance", - "coneDistance": "kne_distance", - "coneAngle": "kne_angle", - "torusDistance": "tor_distance", - "torusAngle": "tor_angle", - "minArea": "min_area", - } + Options.setDefaultAttribute() + McnpNumericFormat.setDefaultAttribute() + Tolerances.setDefaultAttribute() + + def SetConfiguration(self,configFile=None): + if configFile is None : + return + config = configparser.ConfigParser() config.optionxform = str - config.read(self.__dict__["title"]) + config.read(configFile) for section in config.sections(): if section == "Files": for key in config["Files"].keys(): @@ -277,43 +234,28 @@ def SetOptions(self): elif section == "Options": for key in config["Options"].keys(): - if key in ( - "forceCylinder", - "newSplitPlane", - "delLastNumber", - "verbose", - "scaleUP", - "quadricPY", - "Facets", - "prnt3PPlane", - "forceNoOverlap", - ): - setattr(Options, key, config.getboolean("Options", key)) - elif key in ("enlargeBox", "nPlaneReverse", "splitTolerance"): - setattr(Options, key, config.getfloat("Options", key)) + if key in Options.defaultValues.keys(): + if Options.typeDict[key] is bool : + Options.setAttribute(key,config.getboolean("Options", key)) + elif Options.typeDict[key] is float or Options.typeDict[key] is int: + Options.setAttribute(key,config.getfloat("Options", key)) elif section == "Tolerances": for key in config["Tolerances"].keys(): - if key == "relativeTolerance": - setattr(Tolerances, key, config.getboolean("Tolerances", key)) - elif key in toleranceKwrd: - setattr( - Tolerances, - tolKwrdEquiv[key], - config.getfloat("Tolerances", key), - ) + eqvKey = Tolerances.KwrdEquiv[key] + if eqvKey in Tolerances.defaultValues.keys(): + if Tolerances.typeDict[eqvKey] is bool : + Tolerances.setAttribute(eqvKey,config.getboolean("Tolerances", key)) + elif Tolerances.typeDict[eqvKey] is float: + Tolerances.setAttribute(eqvKey,config.getfloat("Tolerances", key)) elif section == "MCNP_Numeric_Format": PdEntry = False for key in config["MCNP_Numeric_Format"].keys(): - if key in numericKwrd: - setattr( - McnpNumericFormat, - key, - config.get("MCNP_Numeric_Format", key), - ) - if key == "P_d": - PdEntry = True + if key in McnpNumericFormat.defaultValues.keys(): + McnpNumericFormat.setAttribute(key,config.get("MCNP_Numeric_Format", key)) + if key == "P_d": + PdEntry = True else: print("bad section name : {}".format(section)) @@ -328,7 +270,16 @@ def SetOptions(self): def set(self, kwrd, value): - if kwrd not in self.__dict__.keys(): + if kwrd in McnpNumericFormat.defaultValues.keys(): + McnpNumericFormat.setAttribute(kwrd,value) + return + elif kwrd in Tolerances.defaultValues.keys(): + Tolerances.setAttribute(kwrd,value) + return + elif kwrd in Options.defaultValues.keys(): + Options.setAttribute(kwrd,value) + return + elif kwrd not in self.__dict__.keys(): print("Bad entry : {}".format(kwrd)) return diff --git a/testing/test.py b/testing/test.py index 474ea178..901641d5 100644 --- a/testing/test.py +++ b/testing/test.py @@ -157,8 +157,8 @@ def printResults(f, res, lost): def mkGEOInp(inpDir, outDir): for f in getInputList(inpDir, ("stp", "step")): setInput(f, inpDir, outDir) - GEO = CadToCsg(inifile) - GEO.SetOptions() + GEO = CadToCsg() + GEO.SetConfiguration(inifile) GEO.Start() del GEO diff --git a/tests/test_convert.py b/tests/test_convert.py index d4cab35a..ce569b1d 100644 --- a/tests/test_convert.py +++ b/tests/test_convert.py @@ -18,41 +18,37 @@ def test_conversion(input_step_file): output_filename_stem = output_dir / input_step_file.stem # creates the config file contents - template = ( - "[Files]\n" - "title = 'Input Test'\n" - f"stepFile = {input_step_file.resolve()}\n" - f"geometryName = {output_filename_stem.resolve()}\n" - "outFormat = ('mcnp', 'openMC_XML')\n" - "[Parameters]\n" - "compSolids = False\n" - "volCARD = False\n" - "volSDEF = True\n" - "voidGen = True\n" - "dummyMat = True\n" - "minVoidSize = 100\n" - "cellSummaryFile = False\n" - "cellCommentFile = False\n" - "debug = False\n" - "simplify = no\n" - "[Options]\n" - "forceCylinder = False\n" - "splitTolerance = 0\n" - "newSplitPlane = True\n" - "nPlaneReverse = 0\n" - ) - - with open(output_dir / "config.ini", mode="w") as file: - file.write(template) + template = { + "title" : 'Input Test' , + "stepFile" : f"{input_step_file.resolve()}" , + "geometryName" : f"{output_filename_stem.resolve()}" , + "outFormat" : ('mcnp', 'openMC_XML') , + "compSolids" : False , + "volCARD" : False , + "volSDEF" : True , + "voidGen" : True , + "dummyMat" : True , + "minVoidSize" : 100 , + "cellSummaryFile" : False , + "cellCommentFile" : False , + "debug" : False , + "simplify" : 'no' , + "forceCylinder" : False , + "splitTolerance" : 0 , + "newSplitPlane" : True , + "nPlaneReverse" : 0 , + } # deletes the output openmc and mcnp output files if it already exists output_filename_stem.with_suffix(".mcnp").unlink(missing_ok=True) output_filename_stem.with_suffix(".xml").unlink(missing_ok=True) - inifile = f"{output_dir/'config.ini'}" - GEO = CadToCsg(inifile) - GEO.SetOptions() - GEO.outFormat = ("mcnp", "openMC_XML") + GEO = CadToCsg('Input Test') + + # set parameters values stored in template dictionary + for key,value in template.items(): + GEO.set(key, value) + GEO.Start() assert output_filename_stem.with_suffix(".mcnp").exists()