Skip to content

Commit

Permalink
update to v0.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
yexiang1992 committed Mar 24, 2023
1 parent 0fd8f4f commit 75faae5
Show file tree
Hide file tree
Showing 17 changed files with 251 additions and 56 deletions.
2 changes: 1 addition & 1 deletion build/lib/opstool/__about__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.5.0"
__version__ = "0.6.0"
2 changes: 2 additions & 0 deletions build/lib/opstool/preprocessing/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from .load import gen_grav_load
from .tcl2py import tcl2py
from .unit_system import UnitSystem
from .section import (Rebars, SecMesh, add_circle, add_material,
add_polygon, offset, var_line_string, vis_var_sec)

__all__ = ["gen_grav_load",
"tcl2py",
"UnitSystem",
# -----------
"SecMesh",
"Rebars",
Expand Down
110 changes: 82 additions & 28 deletions build/lib/opstool/preprocessing/tcl2py.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import tkinter

from rich import print


def tcl2py(input_file: str,
output_file: str,
prefix: str = "ops"):
prefix: str = "ops",
encoding: str = "utf-8"):
"""Convert tcl code of opensees to openseespy code.
.. tip::
Expand All @@ -29,6 +32,8 @@ def tcl2py(input_file: str,
i.e., ``import openseespy.opensees as ops``.
If None or void str '', the prefix is not used.
i.e., ``from openseespy.opensees import *``.
encoding: str, optional
file encoding format, by default "utf-8".
"""
if not input_file.endswith(".tcl"):
input_file += ".tcl"
Expand All @@ -40,18 +45,19 @@ def tcl2py(input_file: str,
else:
import_txt = "from openseespy.opensees import *\n\n"
prefix = ''

with open(input_file, 'r', encoding="utf-8") as f:
with open(input_file, 'r', encoding=encoding) as f:
tcl_src = f.read()
tcl_src = tcl_src.replace("{", " { ")
tcl_src = tcl_src.replace("}", " } ")
interp, contents = _TclInterp(prefix)
interp.eval(tcl_src)

with open(output_file, mode='w', encoding="utf-8") as fw:
fw.write(import_txt)
for line in contents:
fw.write(line + "\n")
try:
interp.eval(tcl_src)
finally:
with open(output_file, mode='w', encoding=encoding) as fw:
fw.write(import_txt)
for line in contents:
fw.write(line + "\n")


def _TclInterp(prefix):
Expand Down Expand Up @@ -135,8 +141,14 @@ def _beamIntegration(*args):
def _section(*args):
args = _remove_commit(args)
args = tuple([_type_convert(i) for i in args])
if args[0] in ('NDFiber', 'Fiber'):
contents.append(f"{prefix}section{args[:-1]}")
if args[0].lower() in ('ndfiber', 'fiber'):
if args[0].lower() == "fiber" and ('-GJ' not in args or '-torsion' not in args):
print("[bold #d20962]Warning[/bold #d20962]: "
"-GJ or -torsion not used for fiber section, GJ=10000 is assumed!")
new_args = (args[0], args[1], '-GJ', 1.E4)
else:
new_args = args[:-1]
contents.append(f"{prefix}section{new_args}")
txt = args[-1]
txt.replace("\\n", '')
interp.eval(txt)
Expand Down Expand Up @@ -232,26 +244,33 @@ def _timeSeries(*args):
txt = f"{prefix}timeSeries('Path', {args[1]}, *{args[2:]})"
contents.append(txt)
else:
args = tuple([_type_convert(i) for i in args])
contents.append(f"{prefix}timeSeries{args}")
contents.append(f"{prefix}timeSeries{tuple(args)}")
else:
args = tuple([_type_convert(i) for i in args])
contents.append(f"{prefix}timeSeries{args}")
contents.append(f"{prefix}timeSeries{tuple(args)}")

def _pattern(*args):
args = _remove_commit(args)
args = tuple([_type_convert(i) for i in args])
if args[0].lower() == "plain" and isinstance(args[2], str):
contents.append(f"{prefix}timeSeries('{args[2]}', {args[1]})")
args = list(args)
args[2] = args[1]
args = tuple(args)
contents.append(f"{prefix}pattern{args[:-1]}")
if args[0].lower() != "uniformexcitation":
if args[0].lower() == "plain" and isinstance(args[2], str):
print(
f"[bold #d20962]Warning[/bold #d20962]: OpenSeesPy not support a str [bold #0099e5]{args[2]}[/bold #0099e5] "
f"followed [bold #ff4c4c]plain[/bold #ff4c4c], "
f"and a new [bold #f47721]timeSeries[/bold #f47721] is created with tag "
f"[bold #34bf49]{args[1]}[/bold #34bf49], "
f"please check this [bold #34bf49]pattern tag={args[1]}[/bold #34bf49]!")
contents.append(f"{prefix}timeSeries('{args[2]}', {args[1]})")
args = list(args)
args[2] = args[1]
args = tuple(args)
contents.append(f"{prefix}pattern{args[:-1]}")
else:
contents.append(f"{prefix}pattern{args[:-1]}")
txt = args[-1]
txt.replace("\\n", '')
interp.eval(txt)
else:
contents.append(f"{prefix}pattern{args[:-1]}")
txt = args[-1]
txt.replace("\\n", '')
interp.eval(txt)
contents.append(f"{prefix}pattern{args}")

def _load(*args):
args = _remove_commit(args)
Expand Down Expand Up @@ -305,13 +324,47 @@ def _rayleigh(*args):

def _block2D(*args):
args = _remove_commit(args)
args = tuple([_type_convert(i) for i in args])
contents.append(f"{prefix}block2D{args}")
args = [_type_convert(i) for i in args]
txt = args[-1]
txt = txt.replace("\n", "").replace("\t", " ")
crds = txt.split()
crds = [_type_convert(i) for i in crds]
contents.append(f"crds = {crds}")
if isinstance(args[-2], str):
eleargs = args[-2].split()
eleargs = [_type_convert(i) for i in eleargs]
args = args[:-2] + eleargs
args = [f"'{i}'" if isinstance(i, str) else str(i)
for i in args]
args.append("*crds")
else:
args = [f"'{i}'" if isinstance(i, str) else str(i)
for i in args[:-1]]
args.append("*crds")
txt = f"{prefix}block2D(" + ", ".join(args) + ")"
contents.append(txt)

def _block3D(*args):
args = _remove_commit(args)
args = tuple([_type_convert(i) for i in args])
contents.append(f"{prefix}block3D{args}")
args = [_type_convert(i) for i in args]
txt = args[-1]
txt = txt.replace("\n", "").replace("\t", " ")
crds = txt.split()
crds = [_type_convert(i) for i in crds]
contents.append(f"crds = {crds}")
if isinstance(args[-2], str):
eleargs = args[-2].split()
eleargs = [_type_convert(i) for i in eleargs]
args = args[:-2] + eleargs
args = [f"'{i}'" if isinstance(i, str) else str(i)
for i in args]
args.append("*crds")
else:
args = [f"'{i}'" if isinstance(i, str) else str(i)
for i in args[:-1]]
args.append("*crds")
txt = f"{prefix}block3D(" + ", ".join(args) + ")"
contents.append(txt)

def _ShallowFoundationGen(*args):
args = _remove_commit(args)
Expand Down Expand Up @@ -1104,6 +1157,7 @@ def _domainCommitTag(*args):
interp.createcommand('rigidLink', _rigidLink)
interp.createcommand('element', _element)
interp.createcommand('timeSeries', _timeSeries)
# interp.createcommand('Series', _timeSeries)
interp.createcommand('pattern', _pattern)
interp.createcommand('load', _load)
interp.createcommand('eleLoad', _eleLoad)
Expand Down
126 changes: 126 additions & 0 deletions build/lib/opstool/preprocessing/unit_system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import re
import rich

ratio_length = dict(inch2m=0.0254, inch2dm=0.254, inch2cm=2.54, inch2mm=25.4,
inch2km=2.54e-5, inch2ft=0.0833333333,
ft2mm=304.8, ft2cm=30.48, ft2dm=3.048, ft2m=0.3048, ft2km=3.048e-4,
mm2cm=0.1, mm2dm=0.01, mm2m=0.001, mm2km=1e-6,
cm2dm=0.1, cm2m=0.01, cm2km=1e-5, m2km=1e-3)
ratio_force = dict(lb2lbf=1, lb2kip=0.001, lb2n=4.4482216282509,
lb2kn=4.4482216282509e-3, lb2mn=4.448e-6,
lb2kgf=0.45359236844386, lb2tonf=0.0004535923699994,
lbf2kip=0.001, lbf2n=4.4482216282509,
lbf2kn=4.4482216282509e-3, lbf2mn=4.448e-6,
lbf2kgf=0.45359236844386, lbf2tonf=0.0004535923699994,
kip2n=4448.2216, kip2kn=4448.2216e-3, kip2mn=4448.2216e-6,
kip2kgf=453.59236844386, kip2tonf=0.4535923699994,
n2kn=1e-3, n2mn=1e-6, n2kgf=0.10197162129779283,
n2tonf=0.0001019716212978, kn2mn=1e-3, kn2kgf=101.9716212978,
kn2tonf=0.1019716212978, mn2kgf=101971.6212978,
mn2tonf=101.9716212978, kgf2tonf=0.001)
ratio_time = dict(sec2msec=0.001)


def ratio_update(ratio_dict):
temp_dict = dict()
for key, value in ratio_dict.items():
idx = key.index("2")
new_key = key[idx+1:] + "2" + key[:idx]
temp_dict[new_key] = 1 / value
new_key = key[:idx] + "2" + key[:idx]
temp_dict[new_key] = 1
ratio_dict.update(temp_dict)


ratio_update(ratio_length)
ratio_update(ratio_force)
ratio_update(ratio_time)

unit_length = ["inch", "ft", "mm", "cm", "m"]
unit_force = ["lb", "lbf", "kip", "n", "kn", "mn", "kgf", "tonf"]
unit_time = ["sec", "msec"]
unit_mass = ["mg", "g", "kg", "ton", "t", "slug"]
unit_stress = ["pa", "kpa", "mpa", "gpa", "bar", "psi", "ksi", "psf", "ksf"]


class UnitSystem:
"""A class for unit conversion.
Parameters
-----------
length: str, default="m"
Length unit base. Optional ["inch", "ft", "mm", "cm", "m"].
force: str, default="kN"
Force unit base. Optional ["lb"("lbf"), "kip", "n", "kn", "mn", "kgf", "tonf"].
time: str, default="sec"
Time unit base. Optional ["sec", "msec"].
.. note::
* `Mass` and `stress` units can be automatically determined based on `length` and `force` units,
optional mass units include ["mg", "g", "kg", "ton"("t"), "slug"],
and optional stress units include ["pa", "kpa", "mpa", "gpa", "bar", "psi", "ksi", "psf", "ksf"].
* You can enter any uppercase and lowercase forms, such as ``kn`` and ``kN``, ``mpa`` and ``MPa`` are equivalent.
* You can add a number after the unit to indicate a power, such as ``m3`` for ``m*m*m``.
"""

def __init__(self,
length: str = "m",
force: str = "kn",
time: str = "sec") -> None:
for unit in unit_length:
setattr(self, unit, ratio_length[unit + "2" + length.lower()])
for unit in unit_force:
setattr(self, unit, ratio_force[unit + "2" + force.lower()])
for unit in unit_time:
setattr(self, unit, ratio_time[unit + "2" + time.lower()])
# mass
self.kg = self.n * self.sec**2 / self.m
self.mg, self.g, self.ton = 1e-6 * self.kg, 1e-3 * self.kg, 1e3 * self.kg
self.t, self.slug = 1e3 * self.kg, 14.593902937 * self.kg
# stress
self.pa = self.n / (self.m * self.m)
self.kpa, self.mpa, self.gpa = 1000 * self.pa, 1e6 * self.pa, 1e9 * self.pa
self.bar = 1e5 * self.pa
self.psi, self.ksi = 6894.7572932 * self.pa, 6894757.2932 * self.pa
self.psf, self.ksf = 47.880208 * self.pa, 47880.2468616010 * self.pa

def __getattr__(self, item):
v = re.findall(r'-?\d+\.?\d*e?E?-?\d*?', item)
if v:
v = float(v[0])
else:
return getattr(self, item.lower())
s = ''.join([x for x in item if x.isalpha()])
base = getattr(self, s)
return base ** v

def __repr__(self):
txt = "\n[bold #d20962]Length unit:[/bold #d20962]\n"
for i, unit in enumerate(unit_length):
txt += f"{unit}={getattr(self, unit)}; "
if i > 1 and (i + 1) % 5 == 0:
txt += "\n"
txt += "\n\n[bold #f47721]Force unit:[/bold #f47721]\n"
for i, unit in enumerate(unit_force):
txt += f"{unit}={getattr(self, unit)}; "
if i > 1 and (i + 1) % 5 == 0:
txt += "\n"
txt += "\n\n[bold #7ac143]Time unit:[/bold #7ac143]\n"
for i, unit in enumerate(unit_time):
txt += f"{unit}={getattr(self, unit)}; "
if i > 1 and (i + 1) % 5 == 0:
txt += "\n"
txt += "\n\n[bold #00bce4]Mass unit:[/bold #00bce4]\n"
for i, unit in enumerate(unit_mass):
txt += f"{unit}={getattr(self, unit)}; "
if i > 1 and (i + 1) % 5 == 0:
txt += "\n"
txt += "\n\n[bold #7d3f98]Pressure unit:[/bold #7d3f98]\n"
for i, unit in enumerate(unit_stress):
txt += f"{unit}={getattr(self, unit)}; "
if i > 1 and (i + 1) % 5 == 0:
txt += "\n"
rich.print(txt)
return ""
19 changes: 10 additions & 9 deletions build/lib/opstool/vis/_plotly_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ def _model_vis(
show_ele_label: bool = False,
show_local_crd: bool = False,
show_fix_node: bool = True,
show_constrain_dof: bool = False,
label_size: float = 8,
show_outline: bool = True,
opacity: float = 1.0,
Expand Down Expand Up @@ -359,7 +360,7 @@ def _model_vis(
hovertemplate='<b>z</b>')
plotter.extend([plotter1, plotter2, plotter3])
# mp constraint lines
plotter = _show_mp_constraint(obj, plotter, model_info)
_show_mp_constraint(obj, plotter, model_info, show_constrain_dof)

fig.add_traces(plotter)

Expand Down Expand Up @@ -397,7 +398,7 @@ def _model_vis(
fig.show()


def _show_mp_constraint(obj, plotter, model_info):
def _show_mp_constraint(obj, plotter, model_info, show_dofs):
points = model_info["ConstrainedCoords"]
cells = model_info["ConstrainedCells"]
cells = _reshape_cell(cells)
Expand All @@ -412,13 +413,13 @@ def _show_mp_constraint(obj, plotter, model_info):
width=obj.line_width / 3),
mode="lines", name="mp constraint",
connectgaps=False, hoverinfo="skip"))
x, y, z = [line_mid_points[:, j] for j in range(3)]
txt_plot = go.Scatter3d(x=x, y=y, z=z, text=dofs,
textfont=dict(color=obj.color_constraint,
size=12),
mode="text", name="constraint dofs")
plotter.append(txt_plot)
return plotter
if show_dofs:
x, y, z = [line_mid_points[:, j] for j in range(3)]
txt_plot = go.Scatter3d(x=x, y=y, z=z, text=dofs,
textfont=dict(color=obj.color_constraint,
size=12),
mode="text", name="constraint dofs")
plotter.append(txt_plot)


def _eigen_vis(
Expand Down
Loading

0 comments on commit 75faae5

Please sign in to comment.