FEM-Design 0.0.5__tar.gz → 0.0.7__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.
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: FEM-Design
3
- Version: 0.0.5
3
+ Version: 0.0.7
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
7
  Project-URL: Homepage, https://femdesign-api-docs.onstrusoft.com
8
- Project-URL: Repository, https://github.com/strusoft/femdesign-api
8
+ Project-URL: Repository, https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Python
9
9
  Project-URL: Issues, https://github.com/strusoft/femdesign-api/issues
10
10
  Keywords: fem,fea,structures,strusoft,FEM-Design API
11
11
  Classifier: Programming Language :: Python :: 3
@@ -48,17 +48,20 @@ pipe = FemDesignConnection()
48
48
  try:
49
49
  pipe.SetVerbosity(Verbosity.SCRIPT_LOG_LINES)
50
50
  pipe.Open(r"simple_beam.str")
51
+
52
+ static_analysis = Analysis.StaticAnalysis()
53
+ pipe.RunAnalysis(static_analysis)
54
+
51
55
  pipe.RunAnalysis(Analysis.FrequencyAnalysis(num_shapes=5))
52
- pipe.Save(r"simple_beam_out.str")
53
- pipe.GenerateListTables(bsc_file=r"quantity-estimation-steel.bsc",
54
- csv_file=r"quantity-estimation-steel.csv")
56
+ pipe.Save(r"simple_beam_out_2.str")
57
+
55
58
  pipe.Exit()
56
59
  except Exception as err:
57
60
  pipe.KillProgramIfExists()
58
61
  raise err
59
62
  ```
60
63
 
61
- A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Examples/Python).
64
+ A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Examples/Python)
62
65
 
63
66
  ## Documentation
64
67
 
@@ -31,17 +31,20 @@ pipe = FemDesignConnection()
31
31
  try:
32
32
  pipe.SetVerbosity(Verbosity.SCRIPT_LOG_LINES)
33
33
  pipe.Open(r"simple_beam.str")
34
+
35
+ static_analysis = Analysis.StaticAnalysis()
36
+ pipe.RunAnalysis(static_analysis)
37
+
34
38
  pipe.RunAnalysis(Analysis.FrequencyAnalysis(num_shapes=5))
35
- pipe.Save(r"simple_beam_out.str")
36
- pipe.GenerateListTables(bsc_file=r"quantity-estimation-steel.bsc",
37
- csv_file=r"quantity-estimation-steel.csv")
39
+ pipe.Save(r"simple_beam_out_2.str")
40
+
38
41
  pipe.Exit()
39
42
  except Exception as err:
40
43
  pipe.KillProgramIfExists()
41
44
  raise err
42
45
  ```
43
46
 
44
- A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Examples/Python).
47
+ A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Examples/Python)
45
48
 
46
49
  ## Documentation
47
50
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "FEM-Design"
3
- version = "0.0.5"
3
+ version = "0.0.7"
4
4
  authors = [
5
5
  { name="FEM-Design", email="femdesign.api@strusoft.com" },
6
6
  ]
@@ -20,5 +20,5 @@ keywords = ["fem", "fea", "structures", "strusoft", "FEM-Design API"]
20
20
 
21
21
  [project.urls]
22
22
  Homepage = "https://femdesign-api-docs.onstrusoft.com"
23
- Repository = "https://github.com/strusoft/femdesign-api"
23
+ Repository = "https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Python"
24
24
  Issues = "https://github.com/strusoft/femdesign-api/issues"
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: FEM-Design
3
- Version: 0.0.5
3
+ Version: 0.0.7
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
7
  Project-URL: Homepage, https://femdesign-api-docs.onstrusoft.com
8
- Project-URL: Repository, https://github.com/strusoft/femdesign-api
8
+ Project-URL: Repository, https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Python
9
9
  Project-URL: Issues, https://github.com/strusoft/femdesign-api/issues
10
10
  Keywords: fem,fea,structures,strusoft,FEM-Design API
11
11
  Classifier: Programming Language :: Python :: 3
@@ -48,17 +48,20 @@ pipe = FemDesignConnection()
48
48
  try:
49
49
  pipe.SetVerbosity(Verbosity.SCRIPT_LOG_LINES)
50
50
  pipe.Open(r"simple_beam.str")
51
+
52
+ static_analysis = Analysis.StaticAnalysis()
53
+ pipe.RunAnalysis(static_analysis)
54
+
51
55
  pipe.RunAnalysis(Analysis.FrequencyAnalysis(num_shapes=5))
52
- pipe.Save(r"simple_beam_out.str")
53
- pipe.GenerateListTables(bsc_file=r"quantity-estimation-steel.bsc",
54
- csv_file=r"quantity-estimation-steel.csv")
56
+ pipe.Save(r"simple_beam_out_2.str")
57
+
55
58
  pipe.Exit()
56
59
  except Exception as err:
57
60
  pipe.KillProgramIfExists()
58
61
  raise err
59
62
  ```
60
63
 
61
- A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Examples/Python).
64
+ A wider list of examples can be found in [example](https://github.com/strusoft/femdesign-api/tree/master/FemDesign.Examples/Python)
62
65
 
63
66
  ## Documentation
64
67
 
@@ -0,0 +1 @@
1
+ __version__ = "0.0.7"
@@ -304,7 +304,7 @@ class Analysis:
304
304
  elemfine : bool = True,
305
305
  diaphragm : bool = False,
306
306
  peaksmoothings : bool = False,
307
- comb : CombSettings = None,
307
+ combSettings : CombSettings = None,
308
308
  stage : Stage = None,
309
309
  freq : Freq = None,
310
310
  footfall : Footfall = None,
@@ -334,7 +334,7 @@ class Analysis:
334
334
  self.peaksmoothings = peaksmoothings
335
335
 
336
336
  self.stage = stage
337
- self.comb = comb
337
+ self.comb = combSettings
338
338
  self.freq = freq
339
339
  self.footfall = footfall
340
340
  #self.bedding = bedding
@@ -388,8 +388,12 @@ class Analysis:
388
388
  return analysis
389
389
 
390
390
  @classmethod
391
- def StaticAnalysis(cls, comb : CombSettings = CombSettings.Default(), calcCase : bool = True, calcComb : bool = True):
392
- return cls(calcCase = calcCase, calcComb = calcComb, comb = comb)
391
+ def StaticAnalysis(cls, calcCase : bool = True, calcComb : bool = True):
392
+ return cls(calcCase = calcCase, calcComb = calcComb)
393
+
394
+ def SetCombinations(self, combSettings : CombSettings, combitems : list[CombItem]):
395
+ self.comb = combSettings
396
+ self.comb.combitems = combitems
393
397
 
394
398
  @classmethod
395
399
  def FrequencyAnalysis(cls, num_shapes : int = 5, auto_iter : int = 0, max_sturm : int = 0, norm_unit : Freq.ShapeNormalization = Freq.ShapeNormalization.MassMatrix, x : bool = True, y : bool = True, z : bool = True, top : bool = -0.01):
@@ -397,8 +401,20 @@ class Analysis:
397
401
  return cls(calcFreq = True, freq = freq)
398
402
 
399
403
  @classmethod
400
- def FootfallAnalysis(cls, footfall : Footfall, calcFootfall : bool = True):
401
- return cls(calcFootfall = calcFootfall, footfall = footfall)
404
+ def FootfallAnalysis(cls, footfall : Footfall):
405
+ return cls(calcFootfall = True, footfall = footfall)
406
+
407
+ @classmethod
408
+ def GroundAcceleration(cls, thgroundacc : ThGroundAcc):
409
+ return cls(calcThGrounAcc = True, thgroundacc = thgroundacc)
410
+
411
+ @classmethod
412
+ def ExcitationForce(cls, thexforce : ThExForce):
413
+ return cls(calcThExforce = True, thexforce = thexforce)
414
+
415
+ @classmethod
416
+ def PeriodicExcitation(cls, periodicexc : PeriodicExc):
417
+ return cls(calcPeriodicExc = True, periodicexc = periodicexc)
402
418
 
403
419
  # class Bedding:
404
420
  # def __init__(self, Ldcomb="a", Meshprep=0, Stiff_X=0.5, Stiff_Y=0.5):
@@ -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:
@@ -406,7 +430,7 @@ class CmdListGen:
406
430
  raise ValueError("outfile must have suffix .csv")
407
431
 
408
432
  if not outfile:
409
- outfile = pathlib.Path(self.bscfile).with_suffix(".csv")
433
+ outfile = pathlib.Path(bscfile).with_suffix(".csv")
410
434
 
411
435
  if not os.path.exists(os.path.dirname(os.path.abspath(outfile))):
412
436
  os.makedirs(os.path.dirname(os.path.abspath(outfile)))
@@ -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,12 +6,15 @@ 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 DesignModule, CmdUser, CmdCalculation, CmdListGen, CmdOpen, CmdProjDescr, CmdSave
9
+ from femdesign.calculate.command import *
10
10
 
11
11
  import win32file
12
12
  import win32pipe
13
13
 
14
14
  import os
15
+ import shutil
16
+
17
+ import uuid
15
18
 
16
19
  """
17
20
  FEM - Design usage with pipe
@@ -98,7 +101,7 @@ def GetElapsedTime(start_time):
98
101
 
99
102
  class _FdConnect:
100
103
 
101
- def __exit__(self, exc_type, exc_value, traceback):
104
+ def __exit__(self):
102
105
  self.Detach()
103
106
  self.ClosePipe()
104
107
 
@@ -293,18 +296,17 @@ class Verbosity(Enum):
293
296
  PROGRESS_WINDOW_TITLE = 32
294
297
 
295
298
 
296
- ## define a private class
297
-
298
-
299
299
  class FemDesignConnection(_FdConnect):
300
300
  def __init__(self,
301
301
  fd_path : str = r"C:\Program Files\StruSoft\FEM-Design 23\fd3dstruct.exe",
302
302
  pipe_name : str ="FdPipe1",
303
303
  verbose : Verbosity = Verbosity.SCRIPT_LOG_LINES,
304
304
  output_dir : str = None,
305
- minimized : bool = False,):
305
+ minimized : bool = False,
306
+ delete_dir : bool = True):
306
307
  super().__init__(pipe_name)
307
308
 
309
+ self.delete_dir = delete_dir
308
310
  self._output_dir = output_dir
309
311
 
310
312
  os.environ["FD_NOLOGO"] = "1"
@@ -315,6 +317,14 @@ class FemDesignConnection(_FdConnect):
315
317
  self.Start(fd_path)
316
318
  self.LogLevel(verbose)
317
319
 
320
+ def __exit__(self):
321
+ super().__exit__()
322
+ if(self.delete_dir):
323
+ try:
324
+ shutil.rmtree(os.path.join(self.output_dir, "scripts"))
325
+ except:
326
+ pass
327
+
318
328
  @property
319
329
  def output_dir(self):
320
330
  if self._output_dir == None:
@@ -327,7 +337,6 @@ class FemDesignConnection(_FdConnect):
327
337
  self._output_dir = os.path.abspath(value)
328
338
  if not os.path.exists(value):
329
339
  os.makedirs(os.path.abspath(value))
330
-
331
340
 
332
341
  def RunScript(self, fdscript : Fdscript, file_name : str = "script"):
333
342
  """
@@ -429,7 +438,7 @@ class FemDesignConnection(_FdConnect):
429
438
  log = OutputFileHelper.GetLogFilePath(self.output_dir)
430
439
 
431
440
  if not file_name.endswith(".struxml") and not file_name.endswith(".str"):
432
- raise ValueError(f"File {file_name} must have extension .struxml or .str")
441
+ raise ValueError(f"file_name must have extension .struxml or .str")
433
442
  if not os.path.exists(file_name):
434
443
  raise FileNotFoundError(f"File {file_name} not found")
435
444
 
@@ -447,8 +456,86 @@ class FemDesignConnection(_FdConnect):
447
456
  fdscript = Fdscript(log, [cmd_results])
448
457
  self.RunScript(fdscript, "generate_list_tables")
449
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")
450
520
 
451
521
  ## it does not work
452
- def Disconnect(self):
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):
453
537
  super().Detach()
454
538
  win32pipe.DisconnectNamedPipe(self.pipe_send)
539
+
540
+ def Close(self):
541
+ self.__exit__()
File without changes
File without changes
File without changes