patme 0.4.4__py3-none-any.whl
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.
Potentially problematic release.
This version of patme might be problematic. Click here for more details.
- patme/__init__.py +52 -0
- patme/buildtools/__init__.py +7 -0
- patme/buildtools/rce_releasecreator.py +336 -0
- patme/buildtools/release.py +26 -0
- patme/femtools/__init__.py +5 -0
- patme/femtools/abqmsgfilechecker.py +137 -0
- patme/femtools/fecall.py +1092 -0
- patme/geometry/__init__.py +0 -0
- patme/geometry/area.py +124 -0
- patme/geometry/coordinatesystem.py +635 -0
- patme/geometry/intersect.py +284 -0
- patme/geometry/line.py +183 -0
- patme/geometry/misc.py +420 -0
- patme/geometry/plane.py +464 -0
- patme/geometry/rotate.py +244 -0
- patme/geometry/scale.py +152 -0
- patme/geometry/shape2d.py +50 -0
- patme/geometry/transformations.py +1831 -0
- patme/geometry/translate.py +139 -0
- patme/mechanics/__init__.py +4 -0
- patme/mechanics/loads.py +435 -0
- patme/mechanics/material.py +1260 -0
- patme/service/__init__.py +7 -0
- patme/service/decorators.py +85 -0
- patme/service/duration.py +96 -0
- patme/service/exceptionhook.py +104 -0
- patme/service/exceptions.py +36 -0
- patme/service/io/__init__.py +3 -0
- patme/service/io/basewriter.py +122 -0
- patme/service/logger.py +375 -0
- patme/service/mathutils.py +108 -0
- patme/service/misc.py +71 -0
- patme/service/moveimports.py +217 -0
- patme/service/stringutils.py +419 -0
- patme/service/systemutils.py +290 -0
- patme/sshtools/__init__.py +3 -0
- patme/sshtools/cara.py +435 -0
- patme/sshtools/clustercaller.py +420 -0
- patme/sshtools/facluster.py +350 -0
- patme/sshtools/sshcall.py +168 -0
- patme-0.4.4.dist-info/LICENSE +21 -0
- patme-0.4.4.dist-info/LICENSES/MIT.txt +9 -0
- patme-0.4.4.dist-info/METADATA +168 -0
- patme-0.4.4.dist-info/RECORD +46 -0
- patme-0.4.4.dist-info/WHEEL +4 -0
- patme-0.4.4.dist-info/entry_points.txt +3 -0
patme/__init__.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Copyright (C) 2020 Deutsches Zentrum fuer Luft- und Raumfahrt(DLR, German Aerospace Center) <www.dlr.de>
|
|
2
|
+
# SPDX-FileCopyrightText: 2022 German Aerospace Center (DLR)
|
|
3
|
+
#
|
|
4
|
+
# SPDX-License-Identifier: MIT
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
Utilities for software builds, documentation, cluster interaction, calling fem tools, logging, exceptions and simple geometric and mechanical operations.
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import importlib_metadata
|
|
13
|
+
import tomlkit
|
|
14
|
+
|
|
15
|
+
name = Path(__file__).parent.name
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def getPyprojectMeta(initPath):
|
|
19
|
+
"""Returns project data from pyproject.toml
|
|
20
|
+
|
|
21
|
+
:param initPath: path to the packages main __init__.py file
|
|
22
|
+
:return: dict with entries from tool.poetry in pyproject.toml
|
|
23
|
+
"""
|
|
24
|
+
with open(Path(Path(initPath).parents[2], "pyproject.toml")) as pyproject:
|
|
25
|
+
file_contents = pyproject.read()
|
|
26
|
+
|
|
27
|
+
contents_dict = tomlkit.parse(file_contents)
|
|
28
|
+
try:
|
|
29
|
+
return contents_dict["project"]
|
|
30
|
+
except:
|
|
31
|
+
return contents_dict["tool"]["poetry"]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
# package is installed
|
|
36
|
+
version = importlib_metadata.version(name)
|
|
37
|
+
programDir = str(Path(__file__).parent)
|
|
38
|
+
except importlib_metadata.PackageNotFoundError:
|
|
39
|
+
# package is not installed, read pyproject.toml
|
|
40
|
+
try:
|
|
41
|
+
# We have the full GitLab repository
|
|
42
|
+
pkgMeta = getPyprojectMeta(__file__)
|
|
43
|
+
version = str(pkgMeta["version"])
|
|
44
|
+
programDir = str(Path(__file__).parents[3])
|
|
45
|
+
except FileNotFoundError:
|
|
46
|
+
# We have only the source code
|
|
47
|
+
version = str("version not provided")
|
|
48
|
+
programDir = str(Path(__file__).parent)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# Variables
|
|
52
|
+
epsilon = 1e-8
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# Copyright (C) 2013 Deutsches Zentrum fuer Luft- und Raumfahrt(DLR, German Aerospace Center) <www.dlr.de>
|
|
2
|
+
# SPDX-FileCopyrightText: 2022 German Aerospace Center (DLR)
|
|
3
|
+
#
|
|
4
|
+
# SPDX-License-Identifier: MIT
|
|
5
|
+
|
|
6
|
+
"""Create RCE components and publish them on an rce toolserver.
|
|
7
|
+
|
|
8
|
+
This script is meant for the deployment of tools in various versions and configuration variants.
|
|
9
|
+
To create all inputs to the main function, one must create one tool configuration using the rce- "integrate tool" wizard first.
|
|
10
|
+
Then, extract all neccessary information (toolInput, toolOutput, preScript, postScript, runCmd) from the configuration file.
|
|
11
|
+
|
|
12
|
+
Perform the following
|
|
13
|
+
|
|
14
|
+
- Create documentation pdf
|
|
15
|
+
- Clone the respective git tag
|
|
16
|
+
- Create the RCE-Component:
|
|
17
|
+
- Create the configuration folder, file and documentation
|
|
18
|
+
- Upload configuration to the toolserver (using file shares)
|
|
19
|
+
- Publish the component in RCE to "public"
|
|
20
|
+
|
|
21
|
+
Prerequisites and restrictions:
|
|
22
|
+
|
|
23
|
+
- The RCE-toolserver must be accessible via ssh
|
|
24
|
+
- The Configuration (in the rc-profile dir) of the RCE-toolserver must be accessible via file share
|
|
25
|
+
- Only "common" components creatable - no "cpacs" components
|
|
26
|
+
- In the folder "toolDirToolserver" (parameter of releaseCreatorMain), there should be a subdirectory called "programName"
|
|
27
|
+
for the nightly version. This folder must be created by the user when createNightly=True.
|
|
28
|
+
In "toolDirToolserver", tag folders will be created using "versionString" as folder name.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
import os
|
|
32
|
+
import shutil
|
|
33
|
+
import subprocess
|
|
34
|
+
import sys
|
|
35
|
+
|
|
36
|
+
from patme.buildtools.release import hasTag
|
|
37
|
+
from patme.service.exceptions import ImproperParameterError
|
|
38
|
+
from patme.service.logger import log
|
|
39
|
+
from patme.sshtools.sshcall import callSSH
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def releaseCreatorMain(
|
|
43
|
+
# program settings
|
|
44
|
+
versionString,
|
|
45
|
+
programDir,
|
|
46
|
+
programName,
|
|
47
|
+
gitRepo,
|
|
48
|
+
iconPath,
|
|
49
|
+
description,
|
|
50
|
+
# rce tool settings
|
|
51
|
+
runCmd,
|
|
52
|
+
preScript,
|
|
53
|
+
postScript,
|
|
54
|
+
rceInputs,
|
|
55
|
+
rceOutputs,
|
|
56
|
+
toolProperties,
|
|
57
|
+
# doc settings
|
|
58
|
+
docCommand,
|
|
59
|
+
docResultPdfPath,
|
|
60
|
+
# remote settings
|
|
61
|
+
username,
|
|
62
|
+
privateKeyFile,
|
|
63
|
+
hostnameRce10,
|
|
64
|
+
hostKeyStringRce10,
|
|
65
|
+
portRce10,
|
|
66
|
+
toolDirToolserver,
|
|
67
|
+
toolDirToolserverRemote,
|
|
68
|
+
configDirToolserver,
|
|
69
|
+
# run behavior
|
|
70
|
+
createDoc=True,
|
|
71
|
+
cloneTag=True,
|
|
72
|
+
createRceConfig=True,
|
|
73
|
+
createNightly=False,
|
|
74
|
+
):
|
|
75
|
+
"""Main function for creating the whole configuration
|
|
76
|
+
|
|
77
|
+
:param versionString: version
|
|
78
|
+
:param programDir: directory of the local program
|
|
79
|
+
:param programName: name of the program
|
|
80
|
+
:param gitRepo: https address of git repository
|
|
81
|
+
:param icoPath: name and path (relative to programDir) to the programs icon. May be None
|
|
82
|
+
:param description: description of the program
|
|
83
|
+
|
|
84
|
+
:param runCmd: command to run the tool on the rce toolserver
|
|
85
|
+
:param preScript: pre command on rce toolserver
|
|
86
|
+
:param postScript: post command on rce toolserver
|
|
87
|
+
:param rceInputs: inputs of the rce component
|
|
88
|
+
:param rceOutputs: outputs of the rce component
|
|
89
|
+
:param toolProperties: string, section toolProperties in rce configuration
|
|
90
|
+
|
|
91
|
+
:param docCommand: setup.py command to create doc
|
|
92
|
+
:param docResultPdfPath: name and path (relative to programDir) with the created pdf file. If None, no documentation will be included.
|
|
93
|
+
|
|
94
|
+
:param username: username to login to rce using ssh
|
|
95
|
+
:param privateKeyFile: path to the private key for ssh access
|
|
96
|
+
:param hostnameRce10: hostname of the computer running the toolserver
|
|
97
|
+
:param hostKeyStringRce10: ssh host key for authentication
|
|
98
|
+
:param portRce10: port of the rce server
|
|
99
|
+
:param toolDirToolserver: local path to tool on toolserver.
|
|
100
|
+
:param toolDirToolserverRemote: remote path to tool on toolserver
|
|
101
|
+
:param configDirToolserver: tool directory on toolserver (local path to remote machine)
|
|
102
|
+
|
|
103
|
+
:param createDoc: flag if the documentation should be created. Otherwise, the documentaion must be created manually.
|
|
104
|
+
:param cloneTag: flag if the tag folder should be created. Otherwise the folder must be created manually.
|
|
105
|
+
:param createRceConfig: flag if the rce configuration folder/file should be created
|
|
106
|
+
:param createNightly: flag if the nightly configuration should be created. Has only effect, if createRceConfig=True
|
|
107
|
+
"""
|
|
108
|
+
if not hasTag(versionString, programDir):
|
|
109
|
+
raise ImproperParameterError(f'There is no tag "{versionString}" in {programName} in folder {programDir}')
|
|
110
|
+
|
|
111
|
+
connectInfo = (username, privateKeyFile, hostnameRce10, hostKeyStringRce10, portRce10)
|
|
112
|
+
rceInfo = description, runCmd, preScript, postScript, rceInputs, rceOutputs, docResultPdfPath, toolProperties
|
|
113
|
+
|
|
114
|
+
# ===============================================================================================
|
|
115
|
+
# create documentation
|
|
116
|
+
# ===============================================================================================
|
|
117
|
+
if createDoc:
|
|
118
|
+
log.infoHeadline("Making documentation")
|
|
119
|
+
subprocess.call([sys.executable, "setup.py", docCommand], cwd=programDir)
|
|
120
|
+
|
|
121
|
+
# ===========================================================================
|
|
122
|
+
# create a clone of the tag on the toolserver
|
|
123
|
+
# ===========================================================================
|
|
124
|
+
tagPath = os.path.join(toolDirToolserverRemote, versionString)
|
|
125
|
+
if cloneTag:
|
|
126
|
+
if os.path.exists(tagPath):
|
|
127
|
+
log.info(f"Not performing git clone: tag already exists at: {tagPath}")
|
|
128
|
+
else:
|
|
129
|
+
os.makedirs(tagPath)
|
|
130
|
+
gitBin = shutil.which("git")
|
|
131
|
+
cloneCmd = [gitBin, "clone", "--depth", "1", "--branch", versionString, gitRepo, tagPath]
|
|
132
|
+
subprocess.run(cloneCmd, stdout=sys.stdout)
|
|
133
|
+
|
|
134
|
+
# ===========================================================================
|
|
135
|
+
# rce tool configuration
|
|
136
|
+
# ===========================================================================
|
|
137
|
+
if createRceConfig:
|
|
138
|
+
createToolConfigurations(
|
|
139
|
+
toolDirToolserver,
|
|
140
|
+
versionString,
|
|
141
|
+
programName,
|
|
142
|
+
programDir,
|
|
143
|
+
connectInfo,
|
|
144
|
+
configDirToolserver,
|
|
145
|
+
iconPath,
|
|
146
|
+
rceInfo,
|
|
147
|
+
createNightly,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def createToolConfigurations(
|
|
152
|
+
toolDirToolserver,
|
|
153
|
+
versionString,
|
|
154
|
+
programName,
|
|
155
|
+
programDir,
|
|
156
|
+
connectInfo,
|
|
157
|
+
configDirToolserver,
|
|
158
|
+
iconPath,
|
|
159
|
+
rceInfo,
|
|
160
|
+
createNightly,
|
|
161
|
+
rceVersion="rce10",
|
|
162
|
+
):
|
|
163
|
+
"""Creates the configuration files for RCE"""
|
|
164
|
+
if rceVersion == "rce10":
|
|
165
|
+
createToolConfiguration = createRCE10ToolConfiguration
|
|
166
|
+
else:
|
|
167
|
+
raise Exception(f'RCE version "{rceVersion}" not supported')
|
|
168
|
+
|
|
169
|
+
toolDir = os.path.join(toolDirToolserver, versionString).replace(
|
|
170
|
+
"\\", "\\\\"
|
|
171
|
+
) # using 4backslashes since it is parsed by python 2 times
|
|
172
|
+
createToolConfiguration(
|
|
173
|
+
versionString, programName, programDir, toolDir, connectInfo, configDirToolserver, iconPath, rceInfo
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
if createNightly:
|
|
177
|
+
toolDir = os.path.join(toolDirToolserver, programName).replace("\\", "\\\\")
|
|
178
|
+
createToolConfiguration(
|
|
179
|
+
"nightly", programName, programDir, toolDir, connectInfo, configDirToolserver, iconPath, rceInfo
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def createRCE10ToolConfiguration(
|
|
184
|
+
versionString, programName, programDir, toolDir, connectInfo, configDirToolserver, iconPath, rceInfo
|
|
185
|
+
):
|
|
186
|
+
"""Create the RCE8 configuration folder and all necessary files"""
|
|
187
|
+
|
|
188
|
+
username, privateKeyFile, hostnameRce10, hostKeyStringRce10, portRce10 = connectInfo
|
|
189
|
+
# create configuration dir
|
|
190
|
+
versionName = programName + "_" + versionString # e.g. results in str: DELiS_14.7.2
|
|
191
|
+
rceConfigToolserver = os.path.join(configDirToolserver, versionName)
|
|
192
|
+
log.info(f"Create rce tool configurations in folder {rceConfigToolserver}")
|
|
193
|
+
if not os.path.exists(os.path.join(rceConfigToolserver, "docs")):
|
|
194
|
+
os.makedirs(os.path.join(rceConfigToolserver, "docs"))
|
|
195
|
+
|
|
196
|
+
# ===========================================================================
|
|
197
|
+
# create conf dir, write conf
|
|
198
|
+
# ===========================================================================
|
|
199
|
+
docResultPdfPath = rceInfo[-2]
|
|
200
|
+
if docResultPdfPath is not None:
|
|
201
|
+
docFile = os.path.join(programDir, docResultPdfPath)
|
|
202
|
+
if os.path.exists(docFile):
|
|
203
|
+
shutil.copy2(docFile, os.path.join(rceConfigToolserver, "docs"))
|
|
204
|
+
else:
|
|
205
|
+
log.warning("The documentation pdf is not existing: " + docFile)
|
|
206
|
+
docResultPdfPath = ""
|
|
207
|
+
else:
|
|
208
|
+
docResultPdfPath = ""
|
|
209
|
+
shutil.copy2(os.path.join(programDir, iconPath), rceConfigToolserver)
|
|
210
|
+
# write Config
|
|
211
|
+
configString = getRCE10ConfigString(versionName, versionString, toolDir, os.path.basename(iconPath), rceInfo)
|
|
212
|
+
with open(rceConfigToolserver + "/configuration.json", "w") as f:
|
|
213
|
+
f.write(configString)
|
|
214
|
+
|
|
215
|
+
# ===========================================================================
|
|
216
|
+
# publish RCE component
|
|
217
|
+
# ===========================================================================
|
|
218
|
+
log.info(f"publish RCE component {versionName}")
|
|
219
|
+
remoteCommand = f"components set-auth common/{versionName} public"
|
|
220
|
+
output = callSSH(hostnameRce10, remoteCommand, privateKeyFile, username, hostKeyStringRce10, port=portRce10)
|
|
221
|
+
if not "Set access authorization for component id" in output:
|
|
222
|
+
log.error("Publish component failed")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def getRCE10ConfigString(versionName, versionString, toolDir, iconFilename, rceInfo):
|
|
226
|
+
description, runCmd, preScript, postScript, rceInputs, rceOutputs, docResultPdfPath, toolProperties = rceInfo
|
|
227
|
+
|
|
228
|
+
return (
|
|
229
|
+
'''{
|
|
230
|
+
"commandScriptLinux" : "",
|
|
231
|
+
"commandScriptWindows" : "'''
|
|
232
|
+
+ runCmd
|
|
233
|
+
+ '''",
|
|
234
|
+
"copyToolBehavior" : "never",
|
|
235
|
+
"deleteWorkingDirectoriesNever" : true,
|
|
236
|
+
"documentationFilePath" : "'''
|
|
237
|
+
+ os.path.basename(docResultPdfPath)
|
|
238
|
+
+ """",
|
|
239
|
+
"enableCommandScriptWindows" : true,
|
|
240
|
+
"groupName" : "DLR-FA",
|
|
241
|
+
"iconHash" : "bbca83a88b19e9c05524ec3f5df1553b",
|
|
242
|
+
"iconModified" : 1482484234043,
|
|
243
|
+
"imitationScript" : "",
|
|
244
|
+
"imitationToolOutputFilename" : "",
|
|
245
|
+
"inputs" : [ """
|
|
246
|
+
+ rceInputs
|
|
247
|
+
+ """ ],
|
|
248
|
+
"isActive" : true,
|
|
249
|
+
"launchSettings" : [ {
|
|
250
|
+
"limitInstallationInstancesNumber" : "10",
|
|
251
|
+
"limitInstallationInstances" : "true",
|
|
252
|
+
"rootWorkingDirectory" : "D:\\\\DELiS_tools\\\\tmp\\\\"""
|
|
253
|
+
+ versionName
|
|
254
|
+
+ '''",
|
|
255
|
+
"host" : "RCE",
|
|
256
|
+
"toolDirectory" : "'''
|
|
257
|
+
+ toolDir
|
|
258
|
+
+ '''",
|
|
259
|
+
"version" : "'''
|
|
260
|
+
+ versionString
|
|
261
|
+
+ """"
|
|
262
|
+
} ],
|
|
263
|
+
"outputs" : [ """
|
|
264
|
+
+ rceOutputs
|
|
265
|
+
+ ''' ],
|
|
266
|
+
"postScript" : "'''
|
|
267
|
+
+ postScript
|
|
268
|
+
+ '''",
|
|
269
|
+
"preScript" : "'''
|
|
270
|
+
+ preScript
|
|
271
|
+
+ '''",
|
|
272
|
+
"toolDescription" : "'''
|
|
273
|
+
+ description
|
|
274
|
+
+ '''",
|
|
275
|
+
"toolIconPath" : "'''
|
|
276
|
+
+ iconFilename
|
|
277
|
+
+ '''",
|
|
278
|
+
"toolIntegrationVersion" : 1,
|
|
279
|
+
"toolIntegratorE-Mail" : "sebastian.freund@dlr.de",
|
|
280
|
+
"toolIntegratorName" : "Sebastian Freund",
|
|
281
|
+
"toolName" : "'''
|
|
282
|
+
+ versionName
|
|
283
|
+
+ """",
|
|
284
|
+
"toolProperties" : {"""
|
|
285
|
+
+ toolProperties
|
|
286
|
+
+ """},
|
|
287
|
+
"uploadIcon" : true,
|
|
288
|
+
"useIterationDirectories" : true
|
|
289
|
+
}"""
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
if __name__ == "__main__":
|
|
294
|
+
from patme import name, programDir, version
|
|
295
|
+
|
|
296
|
+
iconPath = "doc/icon.png"
|
|
297
|
+
rceRunCommand = 'rem setting paths \\r\\nD:\\\\DELiS_tools\\\\delis_3rd_party\\\\64\\\\delis_vars.bat \\r\\nC:\\\\Miniconda3\\\\envs\\\\py36\\\\python.exe src\\\\delis\\\\main\\\\aircraftmain.py --configFile=\\"${in:optionalConfigFileName}\\"'
|
|
298
|
+
|
|
299
|
+
username = "default"
|
|
300
|
+
password = "default"
|
|
301
|
+
hostnameRce10 = "fa-jenkins2.intra.dlr.de"
|
|
302
|
+
portRce10 = 31008
|
|
303
|
+
hostKeyStringRce10 = "AAAAB3NzaC1yc2EAAAADAQABAAABAQCI1DvxZ3gC9437WjXebxZ5HOjru51ur0OlTgHAbHiPpIue\ng0F231NpRs/4Q8TvhkJpepb83EfE2xMyaZNIW6vf8BoKB+Jz7VEi609pI5aNzLdnrRCPXXUIdcLv\neMOvS1vez+KREp+5rLbvPvUfFwkOk0jvT95aFFgFnqoLu/zxIEvKN7TIR9z1S1Gy98Y7h4UHHYrV\nn156nvbnU2sMhwH7Lzl7zGbn+nYPki5oFXxloSJiwHbjPIYGqKGp0tzuV8bCmJUTt9q9SknCi3jY\n40TlXl25vRjjF7oLuIaFFWcYPSBp0nSgkJyGK3Cc3zv1hkztrZ19yzD8a6tDCZFzV+ht"
|
|
304
|
+
|
|
305
|
+
docCommand = "doc_latex"
|
|
306
|
+
docResultPdfPath = f"build/sphinx/latex/{name}.pdf"
|
|
307
|
+
|
|
308
|
+
toolDirToolserver = "D:\\DELiS_tools\\DELiS_git"
|
|
309
|
+
configDirToolserver = (
|
|
310
|
+
"\\\\fa-jenkins2\\DELiS_tools\\RCE\\Profiles\\RCE10_stm_toolserver\\integration\\tools\\common"
|
|
311
|
+
)
|
|
312
|
+
# configDirToolserver = 'C:\\RCE\\Profiles\\RCE10_client\\integration\\tools\\common'
|
|
313
|
+
|
|
314
|
+
toolDirToolserverRemote = "\\\\fa-jenkins2\\DELiS_tools\\DELiS_git"
|
|
315
|
+
|
|
316
|
+
releaseCreatorMain(
|
|
317
|
+
version,
|
|
318
|
+
programDir,
|
|
319
|
+
name,
|
|
320
|
+
"https://gitlab.dlr.de/fa_sw/patme.git",
|
|
321
|
+
iconPath,
|
|
322
|
+
"description",
|
|
323
|
+
rceRunCommand,
|
|
324
|
+
# doc settings
|
|
325
|
+
docCommand,
|
|
326
|
+
docResultPdfPath,
|
|
327
|
+
# remote settings
|
|
328
|
+
username,
|
|
329
|
+
password,
|
|
330
|
+
hostnameRce10,
|
|
331
|
+
hostKeyStringRce10,
|
|
332
|
+
portRce10,
|
|
333
|
+
toolDirToolserver,
|
|
334
|
+
toolDirToolserverRemote,
|
|
335
|
+
configDirToolserver,
|
|
336
|
+
)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2022 German Aerospace Center (DLR)
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Provides functions for release automation
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import subprocess
|
|
10
|
+
|
|
11
|
+
from patme.service.logger import log
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def hasTag(tagName, runDir="."):
|
|
15
|
+
"""Returns True if tagName is a tag in the loacal git"""
|
|
16
|
+
output = subprocess.check_output(["git", "tag", "-l"], encoding="utf_8", cwd=runDir)
|
|
17
|
+
return tagName in output
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def gitTagAndPush(tagName):
|
|
21
|
+
"""create and push git tag"""
|
|
22
|
+
if hasTag(tagName):
|
|
23
|
+
log.error(f"Tag {tagName} already exists")
|
|
24
|
+
return
|
|
25
|
+
subprocess.call(["git", "tag", tagName])
|
|
26
|
+
subprocess.call(["git", "push", "--tags"])
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2022 German Aerospace Center (DLR)
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
"""Checks for the abaqus message file"""
|
|
6
|
+
|
|
7
|
+
from patme.service.logger import log
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def getElementsWithLargestResForces(msgString):
|
|
11
|
+
"""Check Abq message file for largest residual force
|
|
12
|
+
|
|
13
|
+
ABAQUS prints information to the msg-file which could be useful to identify the reasons
|
|
14
|
+
for divergence. One kind of information is at which node of which instance the highes
|
|
15
|
+
residual force occurs per iteration. The script extracts all nodes (and their instances)
|
|
16
|
+
which are at least once the nodes with the highest residual force. The result is plotted
|
|
17
|
+
to a txt-file of the form:
|
|
18
|
+
|
|
19
|
+
Input Example:
|
|
20
|
+
|
|
21
|
+
.. code-block:: none
|
|
22
|
+
|
|
23
|
+
<Instance_Name 2>
|
|
24
|
+
<Node nr 1>, <node nr 2>, ...
|
|
25
|
+
<Instance_Name 2>
|
|
26
|
+
<Node nr 1>, <node nr 2>, ...
|
|
27
|
+
|
|
28
|
+
:param msgString: string of the message file
|
|
29
|
+
:return: string, overview about elements with largest residual forces
|
|
30
|
+
"""
|
|
31
|
+
lines = msgString.split("\n")
|
|
32
|
+
|
|
33
|
+
elementList = list(list())
|
|
34
|
+
instanceList = list()
|
|
35
|
+
|
|
36
|
+
lineNo = -1
|
|
37
|
+
for line in lines:
|
|
38
|
+
lineNo = lineNo + 1
|
|
39
|
+
if "LARGEST RESIDUAL FORCE" in line:
|
|
40
|
+
words = line.split()
|
|
41
|
+
element = list()
|
|
42
|
+
element.append(int(words[6]))
|
|
43
|
+
|
|
44
|
+
nextLine = lines[lineNo + 1]
|
|
45
|
+
words = nextLine.split()
|
|
46
|
+
instanceName = words[1]
|
|
47
|
+
|
|
48
|
+
if instanceName in instanceList:
|
|
49
|
+
index = instanceList.index(instanceName)
|
|
50
|
+
if element[0] not in elementList[index]:
|
|
51
|
+
elementList[index].append(element[0])
|
|
52
|
+
else:
|
|
53
|
+
instanceList.append(instanceName)
|
|
54
|
+
elementList.append(element)
|
|
55
|
+
|
|
56
|
+
outString = ""
|
|
57
|
+
for instanceName in instanceList:
|
|
58
|
+
outString += instanceName + "\n"
|
|
59
|
+
index = instanceList.index(instanceName)
|
|
60
|
+
outString += "\n".join(["%s, " % item for item in elementList[index]] + [""])
|
|
61
|
+
log.info("Elements with largest residual force:\n" + outString)
|
|
62
|
+
return outString
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def getOverconstrainedNodes(msgString):
|
|
66
|
+
""" "Check abq message file for overconstrained nodes
|
|
67
|
+
|
|
68
|
+
ABAQUS prints information to the msg-file which could be useful to identify the reasons
|
|
69
|
+
for divergence. Sometimes overconstraints exists in the model (nodes are constrains by
|
|
70
|
+
too many constraints). These overconstraints are identified by PIVOT messages. This scripts
|
|
71
|
+
extracts all nodes (and the instances they belong to) for which pivots are idendified.
|
|
72
|
+
|
|
73
|
+
Input Example:
|
|
74
|
+
|
|
75
|
+
.. code-block:: none
|
|
76
|
+
|
|
77
|
+
***WARNING: SOLVER PROBLEM. ZERO PIVOT WHEN PROCESSING A (TIED) CONTACT
|
|
78
|
+
CONSTRAINT D.O.F. 1 FOR SLAVE NODE 3288 INSTANCE MANDREL1_LAYER_9.
|
|
79
|
+
THIS MAY BE DUE TO THE UNIT USED FOR THE DISPLACEMENT DIFFERS BY
|
|
80
|
+
MORE THAN 10 ORDER OF MAGNITUDE THAN THE UNIT USED FOR THE
|
|
81
|
+
MATERIAL STIFFNESS. IF THIS IS THE CASE, PLEASE USE A DIFFERENT
|
|
82
|
+
UNIT SYSTEM.
|
|
83
|
+
|
|
84
|
+
:param msgString: string of the message file
|
|
85
|
+
:return: string, overview about overconstraint nodes
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
lines = msgString.split("\n")
|
|
89
|
+
|
|
90
|
+
nodeList = list(list())
|
|
91
|
+
instanceList = list()
|
|
92
|
+
|
|
93
|
+
lineNo = -1
|
|
94
|
+
for line in lines:
|
|
95
|
+
lineNo = lineNo + 1
|
|
96
|
+
if "PIVOT" in line:
|
|
97
|
+
nextLine = lines[lineNo + 1]
|
|
98
|
+
if "D.O.F." in nextLine and "NODE" in nextLine and "INSTANCE" in nextLine:
|
|
99
|
+
words = nextLine.split()
|
|
100
|
+
node = words[6]
|
|
101
|
+
try: # instance name mentioned in next line; maybe too long for current line --> take first word of next line
|
|
102
|
+
instanceName = words[8]
|
|
103
|
+
except IndexError:
|
|
104
|
+
overNextLine = lines[lineNo + 2]
|
|
105
|
+
overNextWords = overNextLine.split()
|
|
106
|
+
instanceName = overNextWords[0]
|
|
107
|
+
|
|
108
|
+
if instanceName in instanceList:
|
|
109
|
+
index = instanceList.index(instanceName)
|
|
110
|
+
if node not in nodeList[index]:
|
|
111
|
+
nodeList[index].append(node)
|
|
112
|
+
else:
|
|
113
|
+
instanceList.append(instanceName)
|
|
114
|
+
nodeList.append([node])
|
|
115
|
+
|
|
116
|
+
outString = ""
|
|
117
|
+
# nodes and their instances are written to the given file
|
|
118
|
+
for instanceName in instanceList:
|
|
119
|
+
outString += instanceName + "\n"
|
|
120
|
+
index = instanceList.index(instanceName)
|
|
121
|
+
outString += "\n".join(["%s, " % item for item in nodeList[index]] + [""])
|
|
122
|
+
log.info("Overconstrained nodes:\n" + outString)
|
|
123
|
+
return outString
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
if __name__ == "__main__":
|
|
127
|
+
# please provide name of abaqus message file
|
|
128
|
+
filename = "Job_NGT-BIT-small_Solid3D_C3D8R_noDamage_TiedContact.msg"
|
|
129
|
+
with open(filename) as f:
|
|
130
|
+
msgString = f.read()
|
|
131
|
+
getElementsWithLargestResForces(msgString)
|
|
132
|
+
|
|
133
|
+
# please provide name of abaqus message file
|
|
134
|
+
filename = "Job_NGT-BIT-small_Solid3D_C3D8R_noDamage_TiedContact.msg"
|
|
135
|
+
with open(filename) as f:
|
|
136
|
+
msgString = f.read()
|
|
137
|
+
getOverconstrainedNodes(msgString)
|