FEM-Design 0.0.6__tar.gz → 0.0.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fem_design-0.0.6/src → fem_design-0.0.8}/FEM_Design.egg-info/PKG-INFO +8 -7
- fem_design-0.0.8/FEM_Design.egg-info/SOURCES.txt +19 -0
- fem_design-0.0.8/FEM_Design.egg-info/requires.txt +1 -0
- {fem_design-0.0.6 → fem_design-0.0.8}/PKG-INFO +8 -7
- {fem_design-0.0.6 → fem_design-0.0.8}/README.md +1 -2
- fem_design-0.0.8/femdesign/__init__.py +1 -0
- {fem_design-0.0.6/src → fem_design-0.0.8}/femdesign/calculate/command.py +92 -1
- {fem_design-0.0.6/src → fem_design-0.0.8}/femdesign/calculate/fdscript.py +12 -2
- {fem_design-0.0.6/src → fem_design-0.0.8}/femdesign/comunication.py +82 -9
- {fem_design-0.0.6 → fem_design-0.0.8}/pyproject.toml +16 -5
- fem_design-0.0.8/test/test_analysis.py +29 -0
- fem_design-0.0.8/test/test_command.py +169 -0
- fem_design-0.0.8/test/test_pipe.py +37 -0
- fem_design-0.0.6/src/FEM_Design.egg-info/SOURCES.txt +0 -16
- fem_design-0.0.6/src/femdesign/__init__.py +0 -1
- fem_design-0.0.6/src/femdesign/database.py +0 -63
- {fem_design-0.0.6/src → fem_design-0.0.8}/FEM_Design.egg-info/dependency_links.txt +0 -0
- {fem_design-0.0.6/src → fem_design-0.0.8}/FEM_Design.egg-info/top_level.txt +0 -0
- {fem_design-0.0.6 → fem_design-0.0.8}/LICENSE +0 -0
- {fem_design-0.0.6/src → fem_design-0.0.8}/femdesign/calculate/__init__.py +0 -0
- {fem_design-0.0.6/src → fem_design-0.0.8}/femdesign/calculate/analysis.py +0 -0
- {fem_design-0.0.6/src → fem_design-0.0.8}/femdesign/utilities/__init__.py +0 -0
- {fem_design-0.0.6/src → fem_design-0.0.8}/femdesign/utilities/filehelper.py +0 -0
- {fem_design-0.0.6 → fem_design-0.0.8}/setup.cfg +0 -0
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: FEM-Design
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.8
|
|
4
4
|
Summary: The FEM-Design API package
|
|
5
5
|
Author-email: FEM-Design <femdesign.api@strusoft.com>
|
|
6
6
|
Maintainer-email: Marco Pellegrino <marco.pellegrino@strusoft.com>, Illyés Zoltán <sinnach@strusoft.hu>
|
|
7
|
+
License: MIT
|
|
7
8
|
Project-URL: Homepage, https://femdesign-api-docs.onstrusoft.com
|
|
8
|
-
Project-URL: Repository, https://github.com/strusoft/femdesign-api
|
|
9
|
+
Project-URL: Repository, https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Python
|
|
9
10
|
Project-URL: Issues, https://github.com/strusoft/femdesign-api/issues
|
|
10
11
|
Keywords: fem,fea,structures,strusoft,FEM-Design API
|
|
11
12
|
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Classifier:
|
|
13
|
-
Classifier: Operating System :: Microsoft
|
|
13
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
14
14
|
Requires-Python: >=3.8
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
+
Requires-Dist: pywin32>=306
|
|
18
|
+
Dynamic: license-file
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
|
|
@@ -61,9 +63,8 @@ except Exception as err:
|
|
|
61
63
|
raise err
|
|
62
64
|
```
|
|
63
65
|
|
|
64
|
-
A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Python
|
|
66
|
+
A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Examples/Python)
|
|
65
67
|
|
|
66
68
|
## Documentation
|
|
67
69
|
|
|
68
|
-
|
|
69
70
|
https://femdesign-api-docs.onstrusoft.com/docs/intro
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
FEM_Design.egg-info/PKG-INFO
|
|
5
|
+
FEM_Design.egg-info/SOURCES.txt
|
|
6
|
+
FEM_Design.egg-info/dependency_links.txt
|
|
7
|
+
FEM_Design.egg-info/requires.txt
|
|
8
|
+
FEM_Design.egg-info/top_level.txt
|
|
9
|
+
femdesign/__init__.py
|
|
10
|
+
femdesign/comunication.py
|
|
11
|
+
femdesign/calculate/__init__.py
|
|
12
|
+
femdesign/calculate/analysis.py
|
|
13
|
+
femdesign/calculate/command.py
|
|
14
|
+
femdesign/calculate/fdscript.py
|
|
15
|
+
femdesign/utilities/__init__.py
|
|
16
|
+
femdesign/utilities/filehelper.py
|
|
17
|
+
test/test_analysis.py
|
|
18
|
+
test/test_command.py
|
|
19
|
+
test/test_pipe.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pywin32>=306
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: FEM-Design
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.8
|
|
4
4
|
Summary: The FEM-Design API package
|
|
5
5
|
Author-email: FEM-Design <femdesign.api@strusoft.com>
|
|
6
6
|
Maintainer-email: Marco Pellegrino <marco.pellegrino@strusoft.com>, Illyés Zoltán <sinnach@strusoft.hu>
|
|
7
|
+
License: MIT
|
|
7
8
|
Project-URL: Homepage, https://femdesign-api-docs.onstrusoft.com
|
|
8
|
-
Project-URL: Repository, https://github.com/strusoft/femdesign-api
|
|
9
|
+
Project-URL: Repository, https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Python
|
|
9
10
|
Project-URL: Issues, https://github.com/strusoft/femdesign-api/issues
|
|
10
11
|
Keywords: fem,fea,structures,strusoft,FEM-Design API
|
|
11
12
|
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Classifier:
|
|
13
|
-
Classifier: Operating System :: Microsoft
|
|
13
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
14
14
|
Requires-Python: >=3.8
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
+
Requires-Dist: pywin32>=306
|
|
18
|
+
Dynamic: license-file
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
|
|
@@ -61,9 +63,8 @@ except Exception as err:
|
|
|
61
63
|
raise err
|
|
62
64
|
```
|
|
63
65
|
|
|
64
|
-
A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Python
|
|
66
|
+
A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Examples/Python)
|
|
65
67
|
|
|
66
68
|
## Documentation
|
|
67
69
|
|
|
68
|
-
|
|
69
70
|
https://femdesign-api-docs.onstrusoft.com/docs/intro
|
|
@@ -44,9 +44,8 @@ except Exception as err:
|
|
|
44
44
|
raise err
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Python
|
|
47
|
+
A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Examples/Python)
|
|
48
48
|
|
|
49
49
|
## Documentation
|
|
50
50
|
|
|
51
|
-
|
|
52
51
|
https://femdesign-api-docs.onstrusoft.com/docs/intro
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.7"
|
|
@@ -383,6 +383,30 @@ class CmdSaveDocx(Command):
|
|
|
383
383
|
return cmd_save_docx
|
|
384
384
|
|
|
385
385
|
|
|
386
|
+
class CmdChild(Command):
|
|
387
|
+
"""class to represent the fdscript cmdsavedocx command
|
|
388
|
+
"""
|
|
389
|
+
def __init__(self, file_name : str):
|
|
390
|
+
"""Constructor for the CmdChild class
|
|
391
|
+
|
|
392
|
+
Args:
|
|
393
|
+
file_name (str): path to the file to save
|
|
394
|
+
"""
|
|
395
|
+
if not file_name.endswith(".dsc"):
|
|
396
|
+
raise ValueError("file_name must have suffix .dsc")
|
|
397
|
+
|
|
398
|
+
self.file_name = os.path.abspath(file_name)
|
|
399
|
+
|
|
400
|
+
def to_xml_element(self) -> ET.Element:
|
|
401
|
+
"""Convert the CmdChild object to an xml element
|
|
402
|
+
|
|
403
|
+
Returns:
|
|
404
|
+
ET.Element: xml element representing the CmdChild object
|
|
405
|
+
"""
|
|
406
|
+
cmd_child = ET.Element("cmdchild")
|
|
407
|
+
cmd_child.text = self.file_name
|
|
408
|
+
|
|
409
|
+
return cmd_child
|
|
386
410
|
|
|
387
411
|
|
|
388
412
|
class CmdListGen:
|
|
@@ -442,4 +466,71 @@ class CmdListGen:
|
|
|
442
466
|
guid_elem = ET.SubElement(cmd_listgen, "GUID")
|
|
443
467
|
guid_elem.text = str(guid)
|
|
444
468
|
|
|
445
|
-
return cmd_listgen
|
|
469
|
+
return cmd_listgen
|
|
470
|
+
|
|
471
|
+
class CmdConfig(Command):
|
|
472
|
+
"""class to represent the fdscript cmdconfig command
|
|
473
|
+
"""
|
|
474
|
+
def __init__(self, file_name : str):
|
|
475
|
+
"""Constructor for the CmdConfig class
|
|
476
|
+
|
|
477
|
+
Args:
|
|
478
|
+
file_name (str): path to the config file
|
|
479
|
+
"""
|
|
480
|
+
if not file_name.endswith(".xml"):
|
|
481
|
+
raise ValueError("file_name must have suffix .xml")
|
|
482
|
+
|
|
483
|
+
self.file_name = os.path.abspath(file_name)
|
|
484
|
+
|
|
485
|
+
def to_xml_element(self) -> ET.Element:
|
|
486
|
+
"""Convert the CmdConfig object to an xml element
|
|
487
|
+
|
|
488
|
+
Returns:
|
|
489
|
+
ET.Element: xml element representing the CmdConfig object
|
|
490
|
+
"""
|
|
491
|
+
cmd_config = ET.Element("cmdconfig")
|
|
492
|
+
|
|
493
|
+
attributes = {
|
|
494
|
+
"command": "$ MODULECOM APPLYCFG",
|
|
495
|
+
"file": self.file_name
|
|
496
|
+
}
|
|
497
|
+
cmd_config.attrib = attributes
|
|
498
|
+
|
|
499
|
+
return cmd_config
|
|
500
|
+
|
|
501
|
+
# <cmdinteractionsurface command="$ CODE_COM INTERACTIONSURFACE" guid="2e290437-e86a-4e36-af7d-acde6a6146c8" offset="0.0" fUlt="false" outfile="e:\res\a.txt" />
|
|
502
|
+
class CmdInteractionSurface(Command):
|
|
503
|
+
"""class to represent the fdscript cmdinteraction surface command
|
|
504
|
+
"""
|
|
505
|
+
def __init__(self, guid : uuid.UUID, outfile : str, offset : float = 0.0, fUlt : bool = False):
|
|
506
|
+
"""Constructor for the CmdInteractionSurface class
|
|
507
|
+
|
|
508
|
+
Args:
|
|
509
|
+
guid (uuid.UUID): guid of an existing bar. make sure you pass the analytical bar!
|
|
510
|
+
outfile (str): path to the output file
|
|
511
|
+
offset (float): offset is cross-section position, measured along the bar from the starting point [m]
|
|
512
|
+
fUlt (bool): fUlt is true for Ultimate, false for Accidental or Seismic combination (different gammaC)
|
|
513
|
+
"""
|
|
514
|
+
self.guid = guid
|
|
515
|
+
self.offset = offset
|
|
516
|
+
self.fUlt = fUlt
|
|
517
|
+
self.outfile = os.path.abspath(outfile)
|
|
518
|
+
|
|
519
|
+
def to_xml_element(self) -> ET.Element:
|
|
520
|
+
"""Convert the CmdInteractionSurface object to an xml element
|
|
521
|
+
|
|
522
|
+
Returns:
|
|
523
|
+
ET.Element: xml element representing the CmdInteractionSurface object
|
|
524
|
+
"""
|
|
525
|
+
cmd_interaction_surface = ET.Element("cmdinteractionsurface")
|
|
526
|
+
|
|
527
|
+
attributes = {
|
|
528
|
+
"command": "$ CODE_COM INTERACTIONSURFACE",
|
|
529
|
+
"guid": str(self.guid),
|
|
530
|
+
"offset": str(self.offset),
|
|
531
|
+
"fUlt": str(self.fUlt).lower(),
|
|
532
|
+
"outfile": self.outfile
|
|
533
|
+
}
|
|
534
|
+
cmd_interaction_surface.attrib = attributes
|
|
535
|
+
|
|
536
|
+
return cmd_interaction_surface
|
|
@@ -12,6 +12,9 @@ class FdscriptHeader:
|
|
|
12
12
|
self.version = str(version)
|
|
13
13
|
self.module = module
|
|
14
14
|
self.logfile = os.path.abspath(log_file)
|
|
15
|
+
|
|
16
|
+
self.continue_on_error = True
|
|
17
|
+
self.ignore_Parse_error = True
|
|
15
18
|
|
|
16
19
|
|
|
17
20
|
def to_xml_element(self) -> ET.Element:
|
|
@@ -21,7 +24,7 @@ class FdscriptHeader:
|
|
|
21
24
|
ET.Element: xml element representing the FdscriptHeader object
|
|
22
25
|
"""
|
|
23
26
|
fdscript_header = ET.Element("fdscriptheader")
|
|
24
|
-
|
|
27
|
+
|
|
25
28
|
title_elem = ET.SubElement(fdscript_header, "title")
|
|
26
29
|
title_elem.text = self.title
|
|
27
30
|
|
|
@@ -34,6 +37,13 @@ class FdscriptHeader:
|
|
|
34
37
|
logfile_elem = ET.SubElement(fdscript_header, "logfile")
|
|
35
38
|
logfile_elem.text = self.logfile
|
|
36
39
|
|
|
40
|
+
## add attributes
|
|
41
|
+
attributes = {
|
|
42
|
+
"fContinueOnError" : int(self.continue_on_error).__str__(),
|
|
43
|
+
"fIgnoreParseError" : int(self.ignore_Parse_error).__str__()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
fdscript_header.attrib = attributes
|
|
37
47
|
|
|
38
48
|
return fdscript_header
|
|
39
49
|
|
|
@@ -74,7 +84,7 @@ class Fdscript:
|
|
|
74
84
|
fdscript.append(command.to_xml_element())
|
|
75
85
|
|
|
76
86
|
return fdscript
|
|
77
|
-
|
|
87
|
+
|
|
78
88
|
def serialise_to_file(self, file_name : str):
|
|
79
89
|
"""Serialise the Fdscript object to a file
|
|
80
90
|
|
|
@@ -6,7 +6,7 @@ from enum import Enum
|
|
|
6
6
|
from femdesign.calculate.analysis import Analysis, Design
|
|
7
7
|
from femdesign.calculate.fdscript import Fdscript
|
|
8
8
|
from femdesign.utilities.filehelper import OutputFileHelper
|
|
9
|
-
from femdesign.calculate.command import
|
|
9
|
+
from femdesign.calculate.command import *
|
|
10
10
|
|
|
11
11
|
import win32file
|
|
12
12
|
import win32pipe
|
|
@@ -14,6 +14,8 @@ import win32pipe
|
|
|
14
14
|
import os
|
|
15
15
|
import shutil
|
|
16
16
|
|
|
17
|
+
import uuid
|
|
18
|
+
|
|
17
19
|
"""
|
|
18
20
|
FEM - Design usage with pipe
|
|
19
21
|
|
|
@@ -294,12 +296,9 @@ class Verbosity(Enum):
|
|
|
294
296
|
PROGRESS_WINDOW_TITLE = 32
|
|
295
297
|
|
|
296
298
|
|
|
297
|
-
## define a private class
|
|
298
|
-
|
|
299
|
-
|
|
300
299
|
class FemDesignConnection(_FdConnect):
|
|
301
300
|
def __init__(self,
|
|
302
|
-
fd_path : str = r"C:\Program Files\StruSoft\FEM-Design
|
|
301
|
+
fd_path : str = r"C:\Program Files\StruSoft\FEM-Design 24\fd3dstruct.exe",
|
|
303
302
|
pipe_name : str ="FdPipe1",
|
|
304
303
|
verbose : Verbosity = Verbosity.SCRIPT_LOG_LINES,
|
|
305
304
|
output_dir : str = None,
|
|
@@ -338,7 +337,6 @@ class FemDesignConnection(_FdConnect):
|
|
|
338
337
|
self._output_dir = os.path.abspath(value)
|
|
339
338
|
if not os.path.exists(value):
|
|
340
339
|
os.makedirs(os.path.abspath(value))
|
|
341
|
-
|
|
342
340
|
|
|
343
341
|
def RunScript(self, fdscript : Fdscript, file_name : str = "script"):
|
|
344
342
|
"""
|
|
@@ -440,7 +438,7 @@ class FemDesignConnection(_FdConnect):
|
|
|
440
438
|
log = OutputFileHelper.GetLogFilePath(self.output_dir)
|
|
441
439
|
|
|
442
440
|
if not file_name.endswith(".struxml") and not file_name.endswith(".str"):
|
|
443
|
-
raise ValueError(f"
|
|
441
|
+
raise ValueError(f"file_name must have extension .struxml or .str")
|
|
444
442
|
if not os.path.exists(file_name):
|
|
445
443
|
raise FileNotFoundError(f"File {file_name} not found")
|
|
446
444
|
|
|
@@ -458,11 +456,86 @@ class FemDesignConnection(_FdConnect):
|
|
|
458
456
|
fdscript = Fdscript(log, [cmd_results])
|
|
459
457
|
self.RunScript(fdscript, "generate_list_tables")
|
|
460
458
|
|
|
459
|
+
def SaveDocx(self, file_name : str, template_file : str = None):
|
|
460
|
+
"""Save the project as docx
|
|
461
|
+
|
|
462
|
+
Args:
|
|
463
|
+
file_name (str): name of the file to save
|
|
464
|
+
|
|
465
|
+
Examples
|
|
466
|
+
--------
|
|
467
|
+
>>> pipe = FemDesignConnection()
|
|
468
|
+
>>> pipe.SaveDocx(r"outputFile.docx")
|
|
469
|
+
"""
|
|
470
|
+
log = OutputFileHelper.GetLogFilePath(self.output_dir)
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
if template_file:
|
|
474
|
+
self.ApplyDocumentationTemplate(template_file)
|
|
475
|
+
|
|
476
|
+
cmd_save_docx = CmdSaveDocx(file_name)
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
fdscript = Fdscript(log, [cmd_save_docx])
|
|
480
|
+
self.RunScript(fdscript, "save_docx")
|
|
481
|
+
|
|
482
|
+
def ApplyDocumentationTemplate(self, template_file : str):
|
|
483
|
+
"""Apply documentation template
|
|
484
|
+
|
|
485
|
+
Args:
|
|
486
|
+
template_file (str): template file path
|
|
487
|
+
"""
|
|
488
|
+
log = OutputFileHelper.GetLogFilePath(self.output_dir)
|
|
489
|
+
|
|
490
|
+
cmd_child = CmdChild(template_file)
|
|
491
|
+
fdscript = Fdscript(log, [cmd_child])
|
|
492
|
+
self.RunScript(fdscript, "apply_documentation_template")
|
|
493
|
+
|
|
494
|
+
def GenerateInteractionSurface(self, guid : uuid.UUID, outfile : str, offset : float = 0.0, fUlt : bool = True):
|
|
495
|
+
"""Generate interaction surface
|
|
496
|
+
|
|
497
|
+
Args:
|
|
498
|
+
guid (uuid.UUID): guid of an existing bar. make sure you pass the analytical bar!
|
|
499
|
+
outfile (str): path to the output file
|
|
500
|
+
offset (float): offset is cross-section position, measured along the bar from the starting point [m]
|
|
501
|
+
fUlt (bool): fUlt is true for Ultimate, false for Accidental or Seismic combination (different gammaC)
|
|
502
|
+
"""
|
|
503
|
+
log = OutputFileHelper.GetLogFilePath(self.output_dir)
|
|
504
|
+
|
|
505
|
+
cmd_interaction_surface = CmdInteractionSurface(guid, outfile, offset, fUlt)
|
|
506
|
+
fdscript = Fdscript(log, [cmd_interaction_surface])
|
|
507
|
+
self.RunScript(fdscript, "generate_interaction_surface")
|
|
508
|
+
|
|
509
|
+
def SetDesignParameters(self, file_path : str):
|
|
510
|
+
"""Set design parameters
|
|
511
|
+
|
|
512
|
+
Args:
|
|
513
|
+
file_path (str): path to the file
|
|
514
|
+
"""
|
|
515
|
+
log = OutputFileHelper.GetLogFilePath(self.output_dir)
|
|
516
|
+
|
|
517
|
+
cmd_design_parameters = CmdConfig(file_path)
|
|
518
|
+
fdscript = Fdscript(log, [cmd_design_parameters])
|
|
519
|
+
self.RunScript(fdscript, "set_design_parameters")
|
|
461
520
|
|
|
462
521
|
## it does not work
|
|
463
|
-
def
|
|
522
|
+
# def DumpDesignParameters(self, file_path : str):
|
|
523
|
+
# """Dump calculation and design parameters
|
|
524
|
+
|
|
525
|
+
# Args:
|
|
526
|
+
# file_path (str): xml file path where the design and calculation parameters will be dumped
|
|
527
|
+
# """
|
|
528
|
+
# if not file_path.endswith(".xml"):
|
|
529
|
+
# raise ValueError("file_name must have suffix .xml")
|
|
530
|
+
|
|
531
|
+
# file_path = os.path.abspath(file_path)
|
|
532
|
+
# message = f"; CXL MODULECOM WXMLCFG:{file_path}"
|
|
533
|
+
# self.Send(message)
|
|
534
|
+
|
|
535
|
+
# ## it does not work
|
|
536
|
+
# def Disconnect(self):
|
|
464
537
|
super().Detach()
|
|
465
538
|
win32pipe.DisconnectNamedPipe(self.pipe_send)
|
|
466
539
|
|
|
467
540
|
def Close(self):
|
|
468
|
-
self.__exit__()
|
|
541
|
+
self.__exit__()
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
1
5
|
[project]
|
|
2
6
|
name = "FEM-Design"
|
|
3
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.8"
|
|
4
8
|
authors = [
|
|
5
9
|
{ name="FEM-Design", email="femdesign.api@strusoft.com" },
|
|
6
10
|
]
|
|
@@ -11,14 +15,21 @@ maintainers = [
|
|
|
11
15
|
description = "The FEM-Design API package"
|
|
12
16
|
readme = "README.md"
|
|
13
17
|
requires-python = ">=3.8"
|
|
18
|
+
dependencies = [
|
|
19
|
+
"pywin32>=306",
|
|
20
|
+
]
|
|
14
21
|
classifiers = [
|
|
15
22
|
"Programming Language :: Python :: 3",
|
|
16
|
-
"
|
|
17
|
-
"Operating System :: Microsoft",
|
|
23
|
+
"Operating System :: Microsoft :: Windows",
|
|
18
24
|
]
|
|
25
|
+
license = {text = "MIT"}
|
|
19
26
|
keywords = ["fem", "fea", "structures", "strusoft", "FEM-Design API"]
|
|
20
27
|
|
|
21
28
|
[project.urls]
|
|
22
29
|
Homepage = "https://femdesign-api-docs.onstrusoft.com"
|
|
23
|
-
Repository = "https://github.com/strusoft/femdesign-api"
|
|
24
|
-
Issues = "https://github.com/strusoft/femdesign-api/issues"
|
|
30
|
+
Repository = "https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Python"
|
|
31
|
+
Issues = "https://github.com/strusoft/femdesign-api/issues"
|
|
32
|
+
|
|
33
|
+
[tool.setuptools.packages.find]
|
|
34
|
+
include = ["femdesign*"]
|
|
35
|
+
exclude = ["test*", "packaging*"]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from femdesign.calculate.command import *
|
|
2
|
+
from femdesign.calculate.analysis import Analysis, CombSettings, Design
|
|
3
|
+
|
|
4
|
+
def test_design():
|
|
5
|
+
xmlDesign = Design(True, True, True).to_xml_element()
|
|
6
|
+
|
|
7
|
+
assert xmlDesign.tag == "design"
|
|
8
|
+
assert xmlDesign.attrib == {}
|
|
9
|
+
assert xmlDesign.text == None
|
|
10
|
+
|
|
11
|
+
assert xmlDesign.find("autodesign") != None
|
|
12
|
+
assert xmlDesign.find("autodesign").text == "true"
|
|
13
|
+
assert xmlDesign.find("check").text == "true"
|
|
14
|
+
assert xmlDesign.find("gmax") == None
|
|
15
|
+
assert xmlDesign.find("cmax") != None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
xmlDesign = Design(False, False, False).to_xml_element()
|
|
19
|
+
|
|
20
|
+
assert xmlDesign.tag == "design"
|
|
21
|
+
assert xmlDesign.attrib == {}
|
|
22
|
+
assert xmlDesign.text == None
|
|
23
|
+
|
|
24
|
+
assert xmlDesign.find("autodesign") != None
|
|
25
|
+
assert xmlDesign.find("autodesign").text == "false"
|
|
26
|
+
assert xmlDesign.find("check").text == "false"
|
|
27
|
+
|
|
28
|
+
assert xmlDesign.find("gmax") != None
|
|
29
|
+
assert xmlDesign.find("cmax") == None
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
from femdesign.calculate.command import *
|
|
2
|
+
from femdesign.calculate.analysis import Analysis, CombSettings
|
|
3
|
+
|
|
4
|
+
def test_cmd_open():
|
|
5
|
+
file_path = "myFilePath.str"
|
|
6
|
+
xmlCmdOpen = CmdOpen(file_path).to_xml_element()
|
|
7
|
+
|
|
8
|
+
assert xmlCmdOpen.tag == "cmdopen"
|
|
9
|
+
assert xmlCmdOpen.attrib.get("command") == "; CXL CS2SHELL OPEN"
|
|
10
|
+
|
|
11
|
+
filename = xmlCmdOpen.find("filename")
|
|
12
|
+
assert filename.text == os.path.join( os.getcwd(), file_path )
|
|
13
|
+
|
|
14
|
+
def test_cmd_child():
|
|
15
|
+
file_path = "template.dsc"
|
|
16
|
+
xmlCmdChild = CmdChild("template.dsc").to_xml_element()
|
|
17
|
+
|
|
18
|
+
assert xmlCmdChild.tag == "cmdchild"
|
|
19
|
+
assert xmlCmdChild.text == os.path.join( os.getcwd(), file_path)
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
xmlCmdChild = CmdChild("template.3dm").to_xml_element()
|
|
23
|
+
except Exception as e:
|
|
24
|
+
assert isinstance(e, ValueError)
|
|
25
|
+
assert str(e) == "file_name must have suffix .dsc"
|
|
26
|
+
|
|
27
|
+
def test_cmd_save():
|
|
28
|
+
file_path = "myFilePath.str"
|
|
29
|
+
xmlCmdSave = CmdSave(file_path).to_xml_element()
|
|
30
|
+
|
|
31
|
+
assert xmlCmdSave.tag == "cmdsave"
|
|
32
|
+
assert xmlCmdSave.attrib.get("command") == "; CXL CS2SHELL SAVE"
|
|
33
|
+
|
|
34
|
+
filename = xmlCmdSave.find("filename")
|
|
35
|
+
assert filename.text == os.path.join( os.getcwd(), file_path )
|
|
36
|
+
|
|
37
|
+
def test_cmd_user():
|
|
38
|
+
for user in User:
|
|
39
|
+
xmlCmdUser = CmdUser(user).to_xml_element()
|
|
40
|
+
|
|
41
|
+
assert xmlCmdUser.attrib.get("command") == f"; CXL $MODULE {user.name}"
|
|
42
|
+
assert xmlCmdUser.tag == "cmduser"
|
|
43
|
+
|
|
44
|
+
def test_cmd_end_session():
|
|
45
|
+
xmlCmdEndSession = CmdEndSession().to_xml_element()
|
|
46
|
+
|
|
47
|
+
assert xmlCmdEndSession.tag == "cmdendsession"
|
|
48
|
+
assert xmlCmdEndSession.text == None
|
|
49
|
+
assert xmlCmdEndSession.attrib == {}
|
|
50
|
+
|
|
51
|
+
def test_analysis():
|
|
52
|
+
xmlAnalysis = Analysis.StaticAnalysis().to_xml_element()
|
|
53
|
+
|
|
54
|
+
assert xmlAnalysis.tag == "analysis"
|
|
55
|
+
|
|
56
|
+
assert xmlAnalysis.attrib.get("calcCase") == "1"
|
|
57
|
+
assert xmlAnalysis.attrib.get("calcComb") == "1"
|
|
58
|
+
assert xmlAnalysis.find("Comb") is None
|
|
59
|
+
assert xmlAnalysis.attrib.get("calcStab") == "0"
|
|
60
|
+
|
|
61
|
+
xmlAnalysis = Analysis.StaticAnalysis(True, True).to_xml_element()
|
|
62
|
+
assert xmlAnalysis.attrib.get("calcCase") == "1"
|
|
63
|
+
assert xmlAnalysis.attrib.get("calcComb") == "1"
|
|
64
|
+
assert xmlAnalysis.find("comb") is None
|
|
65
|
+
|
|
66
|
+
xmlAnalysis = Analysis.StaticAnalysis(True, False).to_xml_element()
|
|
67
|
+
assert xmlAnalysis.attrib.get("calcCase") == "1"
|
|
68
|
+
assert xmlAnalysis.attrib.get("calcComb") == "0"
|
|
69
|
+
assert xmlAnalysis.find("comb") is None
|
|
70
|
+
|
|
71
|
+
xmlAnalysis = Analysis.FrequencyAnalysis().to_xml_element()
|
|
72
|
+
assert xmlAnalysis.attrib.get("calcFreq") == "1"
|
|
73
|
+
assert xmlAnalysis.find("comb") is None
|
|
74
|
+
assert xmlAnalysis.find("freq") is not None
|
|
75
|
+
|
|
76
|
+
def test_cmd_proj_descr():
|
|
77
|
+
xmlCmdProjDescr = CmdProjDescr("Test project", "Test project description", "Test designer", "Test signature", "Comment", None).to_xml_element()
|
|
78
|
+
|
|
79
|
+
xmlCmdProjDescr.tag == "cmdprojdescr"
|
|
80
|
+
|
|
81
|
+
assert xmlCmdProjDescr.attrib.get("szProject") == "Test project"
|
|
82
|
+
assert xmlCmdProjDescr.attrib.get("szDescription") == "Test project description"
|
|
83
|
+
assert xmlCmdProjDescr.attrib.get("szDesigner") == "Test designer"
|
|
84
|
+
assert xmlCmdProjDescr.attrib.get("szSignature") == "Test signature"
|
|
85
|
+
assert xmlCmdProjDescr.attrib.get("szComment") == "Comment"
|
|
86
|
+
|
|
87
|
+
assert xmlCmdProjDescr.attrib.get("read") == "0"
|
|
88
|
+
assert xmlCmdProjDescr.attrib.get("reset") == "0"
|
|
89
|
+
|
|
90
|
+
assert xmlCmdProjDescr.find("item") is None
|
|
91
|
+
|
|
92
|
+
items = {"a": "a_txt", "b": "b_txt"}
|
|
93
|
+
xmlCmdProjDescr = CmdProjDescr(None, None, None, None, None, items, 0, 0).to_xml_element()
|
|
94
|
+
|
|
95
|
+
xmlCmdProjDescr.tag == "cmdprojdescr"
|
|
96
|
+
|
|
97
|
+
assert xmlCmdProjDescr.attrib.get("szProject") == None
|
|
98
|
+
assert xmlCmdProjDescr.attrib.get("szDescription") == None
|
|
99
|
+
assert xmlCmdProjDescr.attrib.get("szDesigner") == None
|
|
100
|
+
assert xmlCmdProjDescr.attrib.get("szSignature") == None
|
|
101
|
+
assert xmlCmdProjDescr.attrib.get("szComment") == None
|
|
102
|
+
|
|
103
|
+
assert xmlCmdProjDescr.attrib.get("read") == "0"
|
|
104
|
+
assert xmlCmdProjDescr.attrib.get("reset") == "0"
|
|
105
|
+
|
|
106
|
+
assert xmlCmdProjDescr.find("item") is not None
|
|
107
|
+
assert len( xmlCmdProjDescr.findall("item") ) == 2
|
|
108
|
+
|
|
109
|
+
def test_cmd_listgen():
|
|
110
|
+
xmlCmdListGen = CmdListGen("bscfile.bsc", "outfile.csv", None, True, True, True).to_xml_element()
|
|
111
|
+
|
|
112
|
+
assert xmlCmdListGen.tag == "cmdlistgen"
|
|
113
|
+
assert xmlCmdListGen.attrib.get("bscfile") == os.path.join( os.getcwd(), "bscfile.bsc" )
|
|
114
|
+
assert xmlCmdListGen.attrib.get("outfile") == os.path.join( os.getcwd(), "outfile.csv" )
|
|
115
|
+
assert xmlCmdListGen.attrib.get("regional") == "1"
|
|
116
|
+
assert xmlCmdListGen.attrib.get("fillcells") == "1"
|
|
117
|
+
assert xmlCmdListGen.attrib.get("headers") == "1"
|
|
118
|
+
assert xmlCmdListGen.find("GUID") is None
|
|
119
|
+
assert len( xmlCmdListGen.findall("GUID") ) == 0
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
guids = [uuid.uuid4(), uuid.uuid4()]
|
|
123
|
+
xmlCmdListGen = CmdListGen("result.bsc", "outfile.csv", guids, False, False, False).to_xml_element()
|
|
124
|
+
|
|
125
|
+
assert xmlCmdListGen.tag == "cmdlistgen"
|
|
126
|
+
assert xmlCmdListGen.attrib.get("bscfile") == os.path.join( os.getcwd(), "result.bsc" )
|
|
127
|
+
assert xmlCmdListGen.attrib.get("outfile") == os.path.join( os.getcwd(), "outfile.csv" )
|
|
128
|
+
assert xmlCmdListGen.attrib.get("regional") == "0"
|
|
129
|
+
assert xmlCmdListGen.attrib.get("fillcells") == "0"
|
|
130
|
+
assert xmlCmdListGen.attrib.get("headers") == "0"
|
|
131
|
+
assert xmlCmdListGen.find("GUID") is not None
|
|
132
|
+
assert len( xmlCmdListGen.findall("GUID") ) == 2
|
|
133
|
+
|
|
134
|
+
xmlCmdListGen = CmdListGen("result.bsc").to_xml_element()
|
|
135
|
+
|
|
136
|
+
assert xmlCmdListGen.tag == "cmdlistgen"
|
|
137
|
+
assert xmlCmdListGen.attrib.get("bscfile") == os.path.join( os.getcwd(), "result.bsc" )
|
|
138
|
+
assert xmlCmdListGen.attrib.get("outfile") == os.path.join( os.getcwd(), "result.csv" )
|
|
139
|
+
assert xmlCmdListGen.attrib.get("regional") == "1"
|
|
140
|
+
assert xmlCmdListGen.attrib.get("fillcells") == "1"
|
|
141
|
+
assert xmlCmdListGen.attrib.get("headers") == "1"
|
|
142
|
+
assert xmlCmdListGen.find("GUID") is None
|
|
143
|
+
assert len( xmlCmdListGen.findall("GUID") ) == 0
|
|
144
|
+
|
|
145
|
+
def test_cmd_config():
|
|
146
|
+
file_path = "config.xml"
|
|
147
|
+
xmlCmdConfig = CmdConfig(file_path).to_xml_element()
|
|
148
|
+
|
|
149
|
+
assert xmlCmdConfig.tag == "cmdconfig"
|
|
150
|
+
assert xmlCmdConfig.attrib.get("file") == os.path.join( os.getcwd(), file_path )
|
|
151
|
+
|
|
152
|
+
def test_cmd_interaction_surface():
|
|
153
|
+
guid = uuid.uuid4()
|
|
154
|
+
|
|
155
|
+
xmlCmdInteractionSurface = CmdInteractionSurface(guid, "surface.txt", 0.0, False).to_xml_element()
|
|
156
|
+
|
|
157
|
+
assert xmlCmdInteractionSurface.tag == "cmdinteractionsurface"
|
|
158
|
+
assert xmlCmdInteractionSurface.attrib.get("guid") == str(guid)
|
|
159
|
+
assert xmlCmdInteractionSurface.attrib.get("outfile") == os.path.join( os.getcwd(), "surface.txt" )
|
|
160
|
+
assert xmlCmdInteractionSurface.attrib.get("offset") == "0.0"
|
|
161
|
+
assert xmlCmdInteractionSurface.attrib.get("fUlt") == "false"
|
|
162
|
+
|
|
163
|
+
xmlCmdInteractionSurface = CmdInteractionSurface(guid, "surface.txt", 5.2, True).to_xml_element()
|
|
164
|
+
|
|
165
|
+
assert xmlCmdInteractionSurface.tag == "cmdinteractionsurface"
|
|
166
|
+
assert xmlCmdInteractionSurface.attrib.get("guid") == str(guid)
|
|
167
|
+
assert xmlCmdInteractionSurface.attrib.get("outfile") == os.path.join( os.getcwd(), "surface.txt" )
|
|
168
|
+
assert xmlCmdInteractionSurface.attrib.get("offset") == "5.2"
|
|
169
|
+
assert xmlCmdInteractionSurface.attrib.get("fUlt") == "true"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from femdesign.calculate.command import *
|
|
2
|
+
from femdesign.calculate.analysis import Analysis, CombSettings, Design
|
|
3
|
+
from femdesign.comunication import FemDesignConnection
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
def test_pipe():
|
|
7
|
+
connection = FemDesignConnection(output_dir="test", minimized=True)
|
|
8
|
+
assert connection.output_dir == os.path.join( os.getcwd(), "test" )
|
|
9
|
+
|
|
10
|
+
connection._output_dir = None
|
|
11
|
+
assert connection.output_dir == os.path.join( os.getcwd(), "FEM-Design API" )
|
|
12
|
+
|
|
13
|
+
## assert that connection.open() raises an error
|
|
14
|
+
try:
|
|
15
|
+
connection.Open("myModel.str")
|
|
16
|
+
except Exception as e:
|
|
17
|
+
assert isinstance(e, FileNotFoundError)
|
|
18
|
+
assert str(e) == "File myModel.str not found"
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
connection.Open("myModel.3dm")
|
|
22
|
+
except Exception as e:
|
|
23
|
+
assert isinstance(e, ValueError)
|
|
24
|
+
assert str(e) == "file_name must have extension .struxml or .str"
|
|
25
|
+
|
|
26
|
+
connection.__exit__()
|
|
27
|
+
|
|
28
|
+
def test_interaction_surface():
|
|
29
|
+
connection = FemDesignConnection(minimized=True)
|
|
30
|
+
connection.Open(r"test/assets/concrete_beam.struxml")
|
|
31
|
+
guid = "c71d1619-420a-46fe-bbb7-423bf20fdcda"
|
|
32
|
+
connection.GenerateInteractionSurface(guid, "test/assets/interaction_surface.txt", 0.5, True)
|
|
33
|
+
|
|
34
|
+
assert os.path.exists("test/assets/interaction_surface.txt")
|
|
35
|
+
assert os.path.getsize("test/assets/interaction_surface.txt") > 0
|
|
36
|
+
|
|
37
|
+
os.remove("test/assets/interaction_surface.txt")
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
pyproject.toml
|
|
4
|
-
src/FEM_Design.egg-info/PKG-INFO
|
|
5
|
-
src/FEM_Design.egg-info/SOURCES.txt
|
|
6
|
-
src/FEM_Design.egg-info/dependency_links.txt
|
|
7
|
-
src/FEM_Design.egg-info/top_level.txt
|
|
8
|
-
src/femdesign/__init__.py
|
|
9
|
-
src/femdesign/comunication.py
|
|
10
|
-
src/femdesign/database.py
|
|
11
|
-
src/femdesign/calculate/__init__.py
|
|
12
|
-
src/femdesign/calculate/analysis.py
|
|
13
|
-
src/femdesign/calculate/command.py
|
|
14
|
-
src/femdesign/calculate/fdscript.py
|
|
15
|
-
src/femdesign/utilities/__init__.py
|
|
16
|
-
src/femdesign/utilities/filehelper.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
version = "0.0.6"
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import xml.etree.ElementTree as ET
|
|
2
|
-
import uuid
|
|
3
|
-
import datetime
|
|
4
|
-
|
|
5
|
-
namespace = {'': 'urn:strusoft'}
|
|
6
|
-
|
|
7
|
-
class Database:
|
|
8
|
-
def __init__(self, country):
|
|
9
|
-
self.struxml_version = "01.00.000"
|
|
10
|
-
self.source_software = f"FEM-Design API SDK {self.get_version()}"
|
|
11
|
-
self.start_time = "1970-01-01T00:00:00.000"
|
|
12
|
-
self.end_time = datetime.datetime.now(datetime.UTC).strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3]
|
|
13
|
-
self.guid = str(uuid.uuid4())
|
|
14
|
-
self.convert_id = "00000000-0000-0000-0000-000000000000"
|
|
15
|
-
self.standard = "EC"
|
|
16
|
-
self.country = country
|
|
17
|
-
self.end = ""
|
|
18
|
-
|
|
19
|
-
def get_version(self):
|
|
20
|
-
return "0.1.0"
|
|
21
|
-
|
|
22
|
-
@property
|
|
23
|
-
def eurocode(self):
|
|
24
|
-
return self._root.attrib["standard"]
|
|
25
|
-
|
|
26
|
-
@property
|
|
27
|
-
def country(self):
|
|
28
|
-
return self._root.attrib["country"]
|
|
29
|
-
|
|
30
|
-
@property
|
|
31
|
-
def source_software(self):
|
|
32
|
-
return self._root.attrib["source_software"]
|
|
33
|
-
|
|
34
|
-
@property
|
|
35
|
-
def entities(self):
|
|
36
|
-
return self._root.findall(".//entities", namespace)
|
|
37
|
-
|
|
38
|
-
@property
|
|
39
|
-
def sections(self):
|
|
40
|
-
return self._root.findall(".//sections", namespace)
|
|
41
|
-
|
|
42
|
-
@property
|
|
43
|
-
def materials(self):
|
|
44
|
-
return self._root.findall(".//materials", namespace)
|
|
45
|
-
|
|
46
|
-
@property
|
|
47
|
-
def bars(self):
|
|
48
|
-
return self._root.findall(".//bar", namespace)
|
|
49
|
-
|
|
50
|
-
def serialise_to_xml(self):
|
|
51
|
-
return ET.tostring(self._root, encoding="UTF-8")
|
|
52
|
-
|
|
53
|
-
# private void Initialize(Country country)
|
|
54
|
-
# {
|
|
55
|
-
# this.StruxmlVersion = "01.00.000";
|
|
56
|
-
# this.SourceSoftware = $"FEM-Design API SDK {Assembly.GetExecutingAssembly().GetName().Version.ToString()}";
|
|
57
|
-
# this.StartTime = "1970-01-01T00:00:00.000";
|
|
58
|
-
# this.EndTime = System.DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fff", CultureInfo.InvariantCulture);
|
|
59
|
-
# this.Guid = System.Guid.NewGuid();
|
|
60
|
-
# this.ConvertId = "00000000-0000-0000-0000-000000000000";
|
|
61
|
-
# this.Standard = "EC";
|
|
62
|
-
# this.Country = country;
|
|
63
|
-
# this.End = "";
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|