├── tests ├── __init__.py ├── test_app │ ├── __init__.py │ ├── test_prop_section │ │ └── __init__.py │ └── test_viz │ │ └── viewer.py ├── test_core │ ├── __init__.py │ ├── test_csys │ │ ├── __init__.py │ │ └── test_cartesian.py │ ├── test_load │ │ ├── __init__.py │ │ └── test_beam_load.py │ ├── test_node │ │ ├── __init__.py │ │ └── test_node.py │ ├── test_post │ │ ├── __init__.py │ │ ├── test_structure.py │ │ ├── test_beam.py │ │ └── test_node.py │ ├── test_assembly │ │ ├── __init__.py │ │ └── assembly.py │ ├── test_core_api │ │ ├── __init__.py │ │ └── test_api.py │ ├── test_elm_line │ │ ├── __init__.py │ │ ├── test_line.py │ │ ├── test_simple_beam.py │ │ └── test_beam.py │ ├── test_elm_quad │ │ └── __init__.py │ ├── test_elm_tria │ │ ├── __init__.py │ │ └── test_DKT.py │ ├── test_loadcase │ │ ├── __init__.py │ │ ├── test_timehistory.py │ │ ├── test_spectrum.py │ │ └── test_basic.py │ ├── test_section │ │ ├── __init__.py │ │ └── test_beamsection.py │ └── test_solver │ │ ├── __init__.py │ │ └── test_modal_solver.py └── test_common │ └── __init__.py ├── example ├── core │ ├── static │ │ ├── frame.py │ │ ├── cantilerver_beam.py │ │ └── simply_supported_beam.py │ └── dynamic │ │ └── cantilever_beam.py └── app │ └── ghscripts │ └── scripts.gh ├── hyperstatic ├── app │ ├── __init__.py │ ├── scripts │ │ ├── __init__.py │ │ ├── io │ │ │ └── __init__.py │ │ └── grasshopper │ │ │ ├── load │ │ │ ├── beam_load.py │ │ │ └── node_load.py │ │ │ ├── run │ │ │ ├── gencode.py │ │ │ ├── runcode.py │ │ │ └── genviz.py │ │ │ ├── cross_section │ │ │ ├── beam_section_I.py │ │ │ ├── beam_section_box.py │ │ │ ├── beam_section_rectangle.py │ │ │ └── beam_section_general.py │ │ │ ├── element │ │ │ ├── node.py │ │ │ └── beam.py │ │ │ ├── material │ │ │ └── material_isotropic.py │ │ │ └── boundary │ │ │ └── node_restraint.py │ ├── seismic │ │ ├── __init__.py │ │ ├── wave_selection.py │ │ ├── spec2wave.py │ │ └── wave2spec.py │ ├── viz │ │ ├── diagram │ │ │ ├── curve.py │ │ │ └── time_history.py │ │ ├── __init__.py │ │ └── viz_core │ │ │ ├── model_basic.py │ │ │ └── model_load.py │ ├── general │ │ ├── load │ │ │ ├── __init__.py │ │ │ ├── loadcase.py │ │ │ └── pattern.py │ │ ├── object │ │ │ └── __init__.py │ │ ├── post │ │ │ ├── __init__.py │ │ │ └── combination.py │ │ ├── result │ │ │ ├── __init__.py │ │ │ └── result.py │ │ ├── solve │ │ │ └── __init__.py │ │ ├── environment │ │ │ ├── __init__.py │ │ │ ├── curve.py │ │ │ └── project.py │ │ ├── property │ │ │ ├── __init__.py │ │ │ ├── area_section.py │ │ │ └── material.py │ │ ├── io │ │ │ ├── __init__.py │ │ │ └── dxf.py │ │ ├── db.py │ │ └── __init__.py │ └── design │ │ └── GB │ │ ├── steel │ │ └── chinese_steel.py │ │ ├── material │ │ └── quick_material.py │ │ └── seismic │ │ └── spectrum.py ├── common │ ├── __init__.py │ ├── tolerance.py │ ├── logger.py │ └── curve.py ├── core │ ├── fe_model │ │ ├── meta │ │ │ ├── __init__.py │ │ │ ├── beams │ │ │ │ ├── __init__.py │ │ │ │ ├── beam_eular_shear │ │ │ │ │ └── __init__.py │ │ │ │ └── beam_eular │ │ │ │ │ └── __init__.py │ │ │ ├── interpolate │ │ │ │ ├── Serendipity.py │ │ │ │ ├── __init__.py │ │ │ │ ├── Lagrange.py │ │ │ │ └── Hermite.py │ │ │ ├── shells │ │ │ │ └── MITC4 │ │ │ │ │ └── __init__.py │ │ │ ├── membranes │ │ │ │ ├── __init__.py │ │ │ │ ├── T9 │ │ │ │ │ ├── metaT9.pyx │ │ │ │ │ ├── setup.py │ │ │ │ │ ├── wrapped_code_0.h │ │ │ │ │ └── __init__.py │ │ │ │ └── GQ12 │ │ │ │ │ ├── metaGQ12.pyx │ │ │ │ │ ├── wrapped_code_0.h │ │ │ │ │ └── __init__.py │ │ │ ├── plates │ │ │ │ ├── __init__.py │ │ │ │ ├── metaDKQ │ │ │ │ │ ├── setup.py │ │ │ │ │ ├── metaDKQ.pyx │ │ │ │ │ ├── wrapped_code_0.h │ │ │ │ │ └── __init__.py │ │ │ │ ├── metaDKT │ │ │ │ │ ├── setup.py │ │ │ │ │ ├── metaDKT.pyx │ │ │ │ │ ├── wrapped_code_0.h │ │ │ │ │ └── __init__.py │ │ │ │ ├── TMQ copy │ │ │ │ │ ├── setup.py │ │ │ │ │ ├── wrapper_module_0.pyx │ │ │ │ │ ├── wrapper_module_1.pyx │ │ │ │ │ ├── wrapped_code_0.h │ │ │ │ │ └── wrapped_code_1.h │ │ │ │ └── TMQ │ │ │ │ │ ├── metaTMQb.pyx │ │ │ │ │ ├── metaTMQs.pyx │ │ │ │ │ ├── wrapped_code_0.h │ │ │ │ │ └── wrapped_code_1.h │ │ │ ├── jacobi.py │ │ │ ├── isotropy.py │ │ │ └── operator.py │ │ ├── material │ │ │ ├── orthotropy.py │ │ │ ├── __init__.py │ │ │ └── isotropy.py │ │ ├── section │ │ │ ├── __init__.py │ │ │ └── shell_section.py │ │ ├── __init__.py │ │ ├── element │ │ │ ├── tria │ │ │ │ ├── __init__.py │ │ │ │ ├── T9.py │ │ │ │ ├── GT9.py │ │ │ │ └── DKT.py │ │ │ ├── line │ │ │ │ ├── link.py │ │ │ │ └── __init__.py │ │ │ ├── quad │ │ │ │ ├── __init__.py │ │ │ │ ├── TMQ.py │ │ │ │ ├── GQ12.py │ │ │ │ ├── DKGQ.py │ │ │ │ └── TMGQ.py │ │ │ └── __init__.py │ │ └── node.py │ ├── fe_post │ │ ├── __init__.py │ │ ├── structure.py │ │ ├── node.py │ │ └── beam.py │ └── fe_solver │ │ └── __init__.py └── __init__.py ├── doc ├── requirements.txt ├── source │ ├── changelog.md │ ├── principles │ │ └── index.rst │ ├── index.rst │ ├── quickstart.md │ └── conf.py ├── Makefile └── make.bat ├── .vscode └── settings.json ├── LICENSE ├── .gitignore ├── Changelog.md ├── .github └── workflows │ └── python-publish.yml ├── README.md └── setup.py /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/core/static/frame.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/common/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_common/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/io/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/seismic/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/viz/diagram/curve.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_csys/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_load/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_node/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_post/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/general/load/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/general/object/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/general/post/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/general/result/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/general/solve/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/viz/diagram/time_history.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_assembly/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_assembly/assembly.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_core_api/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_elm_line/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_elm_quad/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_elm_tria/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_loadcase/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_section/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_core/test_solver/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/general/environment/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/general/property/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/material/orthotropy.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/beams/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/section/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_app/test_prop_section/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/grasshopper/load/beam_load.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/grasshopper/load/node_load.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/grasshopper/run/gencode.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/interpolate/Serendipity.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/interpolate/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/shells/MITC4/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/grasshopper/cross_section/beam_section_I.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/beams/beam_eular_shear/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/grasshopper/cross_section/beam_section_box.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/grasshopper/cross_section/beam_section_rectangle.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx 2 | sphinx-autobuild 3 | sphinx_rtd_theme 4 | recommonmark 5 | sphinx_markdown_tables -------------------------------------------------------------------------------- /example/app/ghscripts/scripts.gh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuoju36/Hyperstatic/HEAD/example/app/ghscripts/scripts.gh -------------------------------------------------------------------------------- /doc/source/changelog.md: -------------------------------------------------------------------------------- 1 | # 更新日志 2 | 3 | ## v0.1.10 4 | - 增加梁集中荷载设置 core.api.set_beam_load_concentrated 5 | - 增加梁局部荷载设置 core.api.set_beam_load_distributed -------------------------------------------------------------------------------- /hyperstatic/app/general/environment/curve.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Mar 29 10:01:56 2018 4 | 5 | @author: Dell 6 | """ 7 | 8 | -------------------------------------------------------------------------------- /tests/test_app/test_viz/viewer.py: -------------------------------------------------------------------------------- 1 | from hyperstatic.app.viz.viz_core.viz_core_model import Viewer 2 | 3 | path=r"G:\testghsep" 4 | viewer=Viewer(path,"assembly") 5 | viewer.run() 6 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/membranes/__init__.py: -------------------------------------------------------------------------------- 1 | import sympy as syp 2 | 3 | x1,y1=syp.symbols("x1 y1") 4 | x2,y2=syp.symbols("x2 y2") 5 | x3,y3=syp.symbols("x3 y3") 6 | x4,y4=syp.symbols("x4 y4") 7 | 8 | E,mu,t=syp.symbols("E mu t") 9 | xi,eta=syp.symbols("xi eta") -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/__init__.py: -------------------------------------------------------------------------------- 1 | import sympy as syp 2 | 3 | x1,y1=syp.symbols("x1 y1") 4 | x2,y2=syp.symbols("x2 y2") 5 | x3,y3=syp.symbols("x3 y3") 6 | x4,y4=syp.symbols("x4 y4") 7 | 8 | E,mu,t=syp.symbols("E mu t") 9 | xi,eta=syp.symbols("xi eta") 10 | 11 | -------------------------------------------------------------------------------- /tests/test_core/test_loadcase/test_timehistory.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from pytest import approx,raises 3 | 4 | import numpy as np 5 | from hyperstatic.core.fe_model.load.loadcase import ResponseSpectrumCase 6 | 7 | class TestSDOFSystem(): 8 | def test_spectrum(self): 9 | pass -------------------------------------------------------------------------------- /tests/test_core/test_loadcase/test_spectrum.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from pytest import approx,raises 3 | 4 | import numpy as np 5 | from hyperstatic.core.fe_model.load.loadcase import ResponseSpectrumCase 6 | 7 | class TestResponseSpectrumCase(): 8 | def test_spectrum(self): 9 | pass 10 | -------------------------------------------------------------------------------- /hyperstatic/app/general/io/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Mar 28 21:38:08 2018 4 | 5 | @author: Dell 6 | """ 7 | 8 | __all__=['dxf','s2k'] 9 | 10 | import sys 11 | import os 12 | curdir=os.path.dirname(__file__) 13 | parentdir=os.path.dirname(curdir) 14 | sys.path.append(parentdir) -------------------------------------------------------------------------------- /hyperstatic/app/design/GB/steel/chinese_steel.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon Jan 2 17:13:19 2017 4 | 5 | @author: zhuoj 6 | """ 7 | 8 | def tension(): 9 | pass 10 | 11 | def shear(): 12 | pass 13 | 14 | def bending(): 15 | pass 16 | 17 | def compressive_bending(): 18 | pass 19 | 20 | def tensional_bending(): 21 | pass -------------------------------------------------------------------------------- /tests/test_core/test_node/test_node.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import pytest 3 | from pytest import approx,raises 4 | 5 | import numpy as np 6 | from hyperstatic.core.fe_model.node import Node 7 | 8 | class TestNode(): 9 | def test_T(self): 10 | node=Node("1",0.2,1.3,1.2) 11 | assert node.transform_matrix[2,2]==1 12 | assert node.transform_matrix[5,5]==1 -------------------------------------------------------------------------------- /doc/source/principles/index.rst: -------------------------------------------------------------------------------- 1 | .. Hyperstatic documentation master file, created by 2 | sphinx-quickstart on Tue Jun 21 11:26:58 2022. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | 底层原理 7 | ======================================= 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | :caption: 目录 12 | 13 | -------------------------------------------------------------------------------- /hyperstatic/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Sat Mar 10 14:43:43 2018 5 | 6 | @author: hzj 7 | """ 8 | 9 | import sys 10 | import os 11 | cwd=os.getcwd() 12 | sys.path.append(cwd) 13 | sys.path.append(os.path.join(cwd,'object_model')) 14 | sys.path.append(os.path.join(cwd,'fe_model')) 15 | sys.path.append(os.path.join(cwd,'fe_solver')) 16 | 17 | 18 | -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. Hyperstatic documentation master file, created by 2 | sphinx-quickstart on Tue Jun 21 11:26:58 2022. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | 欢迎使用Hyperstatic文档! 7 | ======================================= 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | :caption: 目录 12 | 13 | quickstart 14 | changelog 15 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/interpolate/Lagrange.py: -------------------------------------------------------------------------------- 1 | import sympy as syp 2 | 3 | l=syp.symbols("l") 4 | xi,eta=syp.symbols("xi eta") 5 | 6 | l1=lambda x: 0.5*(1-x) 7 | l2=lambda x: 0.5*(1+x) 8 | 9 | #n=2 linear 10 | def N1D(): 11 | N1=l1(xi) 12 | N2=l2(xi) 13 | return [N1,N2] 14 | 15 | def N2D(): 16 | #n=4 double linear 17 | N1=l1(xi)*l1(eta) 18 | N2=l1(xi)*l2(eta) 19 | N3=l2(xi)*l1(eta) 20 | N4=l2(xi)*l2(eta) 21 | return [N1,N2,N3,N4] -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "arange", 4 | "autowrap", 5 | "casename", 6 | "condensated", 7 | "csys", 8 | "eigen", 9 | "eigsh", 10 | "hids", 11 | "lgmres", 12 | "linalg", 13 | "loadcase", 14 | "loadcases", 15 | "ndarray", 16 | "precase", 17 | "scipy", 18 | "spmatrix", 19 | "hyperstatic", 20 | "toarray", 21 | "tocoo", 22 | "tocsr", 23 | "tria", 24 | "vedo", 25 | "workpath" 26 | ] 27 | } -------------------------------------------------------------------------------- /hyperstatic/common/tolerance.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | class Tolerance(object): 3 | __abs_tol = 1e-9 4 | __rel_tol = 1e-6 5 | 6 | @classmethod 7 | def abs_tol(cls): 8 | return cls.__abs_tol 9 | 10 | @classmethod 11 | def rel_tol(cls): 12 | return cls.__rel_tol 13 | 14 | @classmethod 15 | def set_abs_tol(cls,val): 16 | cls.__abs_tol=val 17 | 18 | @classmethod 19 | def set_rel_tol(cls,val): 20 | cls.__rel_tol=val 21 | 22 | if __name__ == '__main__': 23 | Tolerance.set_abs_tol(42) 24 | print(Tolerance.abs_tol()) -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/membranes/T9/metaT9.pyx: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | cimport numpy as np 3 | 4 | cdef extern from 'wrapped_code_0.h': 5 | void autofunc(double E, double mu, double t, double x1, double y1, double x2, double y2, double x3, double y3, double *out_1383753678444021021) 6 | 7 | def autofunc_c(double E, double mu, double t, double x1, double y1, double x2, double y2, double x3, double y3): 8 | 9 | cdef np.ndarray[np.double_t, ndim=2] out_1383753678444021021 = np.empty((6,6)) 10 | autofunc(E, mu, t, x1, y1, x2, y2, x3, y3, out_1383753678444021021.data) 11 | return out_1383753678444021021 -------------------------------------------------------------------------------- /hyperstatic/core/fe_post/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | import numpy as np 5 | import pickle 6 | from hyperstatic.core.fe_model.assembly import Assembly 7 | 8 | class ResultResolver(object): 9 | def __init__(self,workpath:str,filename:str): 10 | self.__workpath=workpath 11 | filename=os.path.join(workpath,filename) 12 | with open(filename,"rb") as f: 13 | self.__assembly:Assembly=pickle.load(f) 14 | 15 | @property 16 | def workpath(self): 17 | return self.__workpath 18 | 19 | @property 20 | def assembly(self): 21 | return self.__assembly -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/membranes/T9/setup.py: -------------------------------------------------------------------------------- 1 | try: 2 | from setuptools import setup 3 | from setuptools import Extension 4 | except ImportError: 5 | from distutils.core import setup 6 | from distutils.extension import Extension 7 | from Cython.Build import cythonize 8 | cy_opts = {} 9 | import numpy as np 10 | 11 | ext_mods = [Extension( 12 | 'wrapper_module_0', ['wrapper_module_0.pyx', 'wrapped_code_0.c'], 13 | include_dirs=[np.get_include()], 14 | library_dirs=[], 15 | libraries=[], 16 | extra_compile_args=['-std=c99'], 17 | extra_link_args=[] 18 | )] 19 | setup(ext_modules=cythonize(ext_mods, **cy_opts)) 20 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/metaDKQ/setup.py: -------------------------------------------------------------------------------- 1 | try: 2 | from setuptools import setup 3 | from setuptools import Extension 4 | except ImportError: 5 | from distutils.core import setup 6 | from distutils.extension import Extension 7 | from Cython.Build import cythonize 8 | cy_opts = {} 9 | import numpy as np 10 | 11 | ext_mods = [Extension( 12 | 'wrapper_module_0', ['wrapper_module_0.pyx', 'wrapped_code_0.c'], 13 | include_dirs=[np.get_include()], 14 | library_dirs=[], 15 | libraries=[], 16 | extra_compile_args=['-std=c99'], 17 | extra_link_args=[] 18 | )] 19 | setup(ext_modules=cythonize(ext_mods, **cy_opts)) 20 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/metaDKT/setup.py: -------------------------------------------------------------------------------- 1 | try: 2 | from setuptools import setup 3 | from setuptools import Extension 4 | except ImportError: 5 | from distutils.core import setup 6 | from distutils.extension import Extension 7 | from Cython.Build import cythonize 8 | cy_opts = {} 9 | import numpy as np 10 | 11 | ext_mods = [Extension( 12 | 'wrapper_module_0', ['wrapper_module_0.pyx', 'wrapped_code_0.c'], 13 | include_dirs=[np.get_include()], 14 | library_dirs=[], 15 | libraries=[], 16 | extra_compile_args=['-std=c99'], 17 | extra_link_args=[] 18 | )] 19 | setup(ext_modules=cythonize(ext_mods, **cy_opts)) 20 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/material/__init__.py: -------------------------------------------------------------------------------- 1 | class Material(object): 2 | def __init__(self,name:str,rho:float,mat_model:str): 3 | self.__name=name 4 | self.__rho=rho #density 5 | self.__mat_model=mat_model #material model 6 | 7 | @property 8 | def name(self): 9 | return self.__name 10 | 11 | @property 12 | def rho(self): 13 | return self.__rho 14 | 15 | @property 16 | def mat_model(self): 17 | return self.__mat_model 18 | 19 | @property 20 | def C(self): 21 | raise NotImplementedError 22 | 23 | @property 24 | def D(self): 25 | raise NotImplementedError -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/TMQ copy/setup.py: -------------------------------------------------------------------------------- 1 | try: 2 | from setuptools import setup 3 | from setuptools import Extension 4 | except ImportError: 5 | from distutils.core import setup 6 | from distutils.extension import Extension 7 | from Cython.Build import cythonize 8 | cy_opts = {} 9 | import numpy as np 10 | 11 | ext_mods = [Extension( 12 | 'wrapper_module_1', ['wrapper_module_1.pyx', 'wrapped_code_1.c'], 13 | include_dirs=[np.get_include()], 14 | library_dirs=[], 15 | libraries=[], 16 | extra_compile_args=['-std=c99'], 17 | extra_link_args=[] 18 | )] 19 | setup(ext_modules=cythonize(ext_mods, **cy_opts)) 20 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_solver/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | __all__=['static','dynamic'] 4 | 5 | import os 6 | import pickle 7 | 8 | from hyperstatic.core.fe_model.assembly import Assembly 9 | 10 | class Solver(object): 11 | def __init__(self,workpath:str,filename:str): 12 | self.__workpath=workpath 13 | filename=os.path.join(workpath,filename) 14 | with open(filename,"rb") as f: 15 | self.__assembly:Assembly=pickle.load(f) 16 | 17 | @property 18 | def assembly(self): 19 | return self.__assembly 20 | 21 | @property 22 | def workpath(self): 23 | return self.__workpath 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/metaDKT/metaDKT.pyx: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | cimport numpy as np 3 | 4 | cdef extern from 'wrapped_code_0.h': 5 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double *out_6903487286308824837) 6 | 7 | def autofunc_c(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3): 8 | 9 | cdef np.ndarray[np.double_t, ndim=2] out_6903487286308824837 = np.empty((9,9)) 10 | autofunc(E, mu, t, xi, eta, x1, y1, x2, y2, x3, y3, out_6903487286308824837.data) 11 | return out_6903487286308824837 -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/TMQ/metaTMQb.pyx: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | cimport numpy as np 3 | 4 | cdef extern from 'wrapped_code_0.h': 5 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_5968647638870972662) 6 | 7 | def autofunc_c(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4): 8 | 9 | cdef np.ndarray[np.double_t, ndim=2] out_5968647638870972662 = np.empty((12,12)) 10 | autofunc(E, mu, t, xi, eta, x1, y1, x2, y2, x3, y3, x4, y4, out_5968647638870972662.data) 11 | return out_5968647638870972662 -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/TMQ/metaTMQs.pyx: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | cimport numpy as np 3 | 4 | cdef extern from 'wrapped_code_1.h': 5 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_6223542351519831598) 6 | 7 | def autofunc_c(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4): 8 | 9 | cdef np.ndarray[np.double_t, ndim=2] out_6223542351519831598 = np.empty((12,12)) 10 | autofunc(E, mu, t, xi, eta, x1, y1, x2, y2, x3, y3, x4, y4, out_6223542351519831598.data) 11 | return out_6223542351519831598 -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/membranes/GQ12/metaGQ12.pyx: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | cimport numpy as np 3 | 4 | cdef extern from 'wrapped_code_0.h': 5 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_3632328274305231304) 6 | 7 | def autofunc_c(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4): 8 | 9 | cdef np.ndarray[np.double_t, ndim=2] out_3632328274305231304 = np.empty((12,12)) 10 | autofunc(E, mu, t, xi, eta, x1, y1, x2, y2, x3, y3, x4, y4, out_3632328274305231304.data) 11 | return out_3632328274305231304 -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/metaDKQ/metaDKQ.pyx: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | cimport numpy as np 3 | 4 | cdef extern from 'wrapped_code_0.h': 5 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_3370079445872163030) 6 | 7 | def autofunc_c(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4): 8 | 9 | cdef np.ndarray[np.double_t, ndim=2] out_3370079445872163030 = np.empty((12,12)) 10 | autofunc(E, mu, t, xi, eta, x1, y1, x2, y2, x3, y3, x4, y4, out_3370079445872163030.data) 11 | return out_3370079445872163030 -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/TMQ copy/wrapper_module_0.pyx: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | cimport numpy as np 3 | 4 | cdef extern from 'wrapped_code_0.h': 5 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_7628163811227061874) 6 | 7 | def autofunc_c(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4): 8 | 9 | cdef np.ndarray[np.double_t, ndim=2] out_7628163811227061874 = np.empty((12,12)) 10 | autofunc(E, mu, t, xi, eta, x1, y1, x2, y2, x3, y3, x4, y4, out_7628163811227061874.data) 11 | return out_7628163811227061874 -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/TMQ copy/wrapper_module_1.pyx: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | cimport numpy as np 3 | 4 | cdef extern from 'wrapped_code_1.h': 5 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_8019317812011686532) 6 | 7 | def autofunc_c(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4): 8 | 9 | cdef np.ndarray[np.double_t, ndim=2] out_8019317812011686532 = np.empty((12,12)) 10 | autofunc(E, mu, t, xi, eta, x1, y1, x2, y2, x3, y3, x4, y4, out_8019317812011686532.data) 11 | return out_8019317812011686532 -------------------------------------------------------------------------------- /hyperstatic/app/design/GB/material/quick_material.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Sun Mar 11 13:14:15 2018 5 | 6 | @author: hzj 7 | """ 8 | 9 | from hyperstatic.app.general.material import Metal,Concrete 10 | 11 | def quick_material(name): 12 | """ 13 | Get params of common materials. 14 | 15 | params: 16 | name: str, name of material. 17 | return: 18 | dictionary of material parameters. 19 | """ 20 | if name=='GB_Q345': 21 | return{ 22 | 'gamma':7849, 23 | 'E':2e11, 24 | 'mu':0.3, 25 | 'alpha':1.17e-5, 26 | 'fy':345e6 27 | } 28 | elif name=='GB_Q235': 29 | pass 30 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/grasshopper/run/runcode.py: -------------------------------------------------------------------------------- 1 | """Provides a scripting component. 2 | Inputs: 3 | name: The x script variable 4 | E: The y script variable 5 | mu: The y script variable 6 | A: The y script variable 7 | I2: The y script variable 8 | I3: The y script variable 9 | J: The y script variable 10 | Output: 11 | section: The a output variable""" 12 | 13 | __author__ = "Zhuoju Huang" 14 | __version__ = "2022.07.12" 15 | 16 | import rhinoscriptsyntax as rs 17 | 18 | class Section(): 19 | def __init__(self,name,E,mu,A,I2,I3,J): 20 | self.name=name 21 | self.E=E 22 | self.mu=mu 23 | self.A=A 24 | self.I2=I2 25 | self.I3=I3 26 | self.J=J 27 | 28 | section=Section(name,E,mu,A,I2,I3,J) -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/jacobi.py: -------------------------------------------------------------------------------- 1 | import sympy as syp 2 | import numpy as np 3 | 4 | l=syp.symbols("l") 5 | xi,eta,zeta=syp.symbols("xi eta zeta") 6 | x,y,z=syp.symbols("x y z") 7 | ddx=lambda f : syp.diff(f,x) 8 | ddy=lambda f : syp.diff(f,y) 9 | ddz=lambda f : syp.diff(f,z) 10 | ddxi=lambda f : syp.diff(f,xi) 11 | ddeta=lambda f : syp.diff(f,eta) 12 | ddzeta=lambda f : syp.diff(f,zeta) 13 | 14 | def J2D(N:list,X:np.array): 15 | """Jacobi 2D matrix 16 | 17 | Args: 18 | N (list): n functions of xi and eta 19 | X (np.array): nx2 array 20 | 21 | Returns: 22 | syp.Matrix: Jacobi 2D matrix 23 | """ 24 | n=len(N) 25 | J=syp.zeros(2,n) 26 | for i in range(n): 27 | J[0,i]=ddxi(N[i]) 28 | J[1,i]=ddeta(N[i]) 29 | return J*X 30 | 31 | def J3D(): 32 | pass -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/membranes/T9/wrapped_code_0.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Code generated with SymPy 1.10.1 * 3 | * * 4 | * See http://www.sympy.org/ for more information. * 5 | * * 6 | * This file is part of 'autowrap' * 7 | ******************************************************************************/ 8 | 9 | 10 | #ifndef AUTOWRAP__WRAPPED_CODE_0__H 11 | #define AUTOWRAP__WRAPPED_CODE_0__H 12 | 13 | void autofunc(double E, double mu, double t, double x1, double y1, double x2, double y2, double x3, double y3, double *out_1383753678444021021); 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /doc/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /hyperstatic/common/logger.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from time import ctime 4 | import threading 5 | 6 | def info(log:str,target='console'): 7 | """ 8 | log: text to record. 9 | target: 'console' to print log on screen or file to write in. 10 | """ 11 | if target=='console': 12 | thd=threading.Thread(target=print,args=(ctime(),':',log)) 13 | thd.setDaemon(True) 14 | thd.start() 15 | thd.join() 16 | else: 17 | try: 18 | thd=threading.Thread(target=print,args=(ctime(),':',log)) 19 | thd.setDaemon(True) 20 | thd.start() 21 | thd.join() 22 | except Exception as e: 23 | print(e) 24 | 25 | def write_file(text,target): 26 | try: 27 | f=open(target) 28 | f.write(text) 29 | except Exception as e: 30 | print(e) 31 | finally: 32 | f.close() -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/metaDKT/wrapped_code_0.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Code generated with SymPy 1.10.1 * 3 | * * 4 | * See http://www.sympy.org/ for more information. * 5 | * * 6 | * This file is part of 'autowrap' * 7 | ******************************************************************************/ 8 | 9 | 10 | #ifndef AUTOWRAP__WRAPPED_CODE_0__H 11 | #define AUTOWRAP__WRAPPED_CODE_0__H 12 | 13 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double *out_6903487286308824837); 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/membranes/GQ12/wrapped_code_0.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Code generated with SymPy 1.10.1 * 3 | * * 4 | * See http://www.sympy.org/ for more information. * 5 | * * 6 | * This file is part of 'autowrap' * 7 | ******************************************************************************/ 8 | 9 | 10 | #ifndef AUTOWRAP__WRAPPED_CODE_0__H 11 | #define AUTOWRAP__WRAPPED_CODE_0__H 12 | 13 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_3632328274305231304); 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/TMQ/wrapped_code_0.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Code generated with SymPy 1.10.1 * 3 | * * 4 | * See http://www.sympy.org/ for more information. * 5 | * * 6 | * This file is part of 'autowrap' * 7 | ******************************************************************************/ 8 | 9 | 10 | #ifndef AUTOWRAP__WRAPPED_CODE_0__H 11 | #define AUTOWRAP__WRAPPED_CODE_0__H 12 | 13 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_5968647638870972662); 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/TMQ/wrapped_code_1.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Code generated with SymPy 1.10.1 * 3 | * * 4 | * See http://www.sympy.org/ for more information. * 5 | * * 6 | * This file is part of 'autowrap' * 7 | ******************************************************************************/ 8 | 9 | 10 | #ifndef AUTOWRAP__WRAPPED_CODE_1__H 11 | #define AUTOWRAP__WRAPPED_CODE_1__H 12 | 13 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_6223542351519831598); 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/metaDKQ/wrapped_code_0.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Code generated with SymPy 1.10.1 * 3 | * * 4 | * See http://www.sympy.org/ for more information. * 5 | * * 6 | * This file is part of 'autowrap' * 7 | ******************************************************************************/ 8 | 9 | 10 | #ifndef AUTOWRAP__WRAPPED_CODE_0__H 11 | #define AUTOWRAP__WRAPPED_CODE_0__H 12 | 13 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_3370079445872163030); 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/TMQ copy/wrapped_code_0.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Code generated with SymPy 1.10.1 * 3 | * * 4 | * See http://www.sympy.org/ for more information. * 5 | * * 6 | * This file is part of 'autowrap' * 7 | ******************************************************************************/ 8 | 9 | 10 | #ifndef AUTOWRAP__WRAPPED_CODE_0__H 11 | #define AUTOWRAP__WRAPPED_CODE_0__H 12 | 13 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_7628163811227061874); 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/TMQ copy/wrapped_code_1.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Code generated with SymPy 1.10.1 * 3 | * * 4 | * See http://www.sympy.org/ for more information. * 5 | * * 6 | * This file is part of 'autowrap' * 7 | ******************************************************************************/ 8 | 9 | 10 | #ifndef AUTOWRAP__WRAPPED_CODE_1__H 11 | #define AUTOWRAP__WRAPPED_CODE_1__H 12 | 13 | void autofunc(double E, double mu, double t, double xi, double eta, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *out_8019317812011686532); 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /hyperstatic/common/curve.py: -------------------------------------------------------------------------------- 1 | 2 | from os import curdir 3 | import numpy as np 4 | 5 | class Curve(object): 6 | def __init__(self,name:str,x:list,y:list): 7 | self.__name=name 8 | self.__x=np.array(x,dtype=float) 9 | self.__y=np.array(y,dtype=float) 10 | 11 | @property 12 | def name(self): 13 | return self.__name 14 | 15 | @property 16 | def x(self): 17 | return self.__x 18 | 19 | @property 20 | def y(self): 21 | return self.__y 22 | 23 | def to_array(self): 24 | return np.vstack([self.__x,self.__y]) 25 | 26 | @staticmethod 27 | def sin(name:str,A:float,w:float,phi:float,dt:float,n:int): 28 | x=np.arange(0,n*dt,dt) 29 | y=A*np.sin(w*x+phi) 30 | return Curve(name,x,y) 31 | 32 | @staticmethod 33 | def cos(name:str,A:float,w:float,phi:float,dt:float,n:int): 34 | x=np.arange(0,n*dt,dt) 35 | y=A*np.cos(w*x+phi) 36 | return Curve(name,x,y) -------------------------------------------------------------------------------- /example/core/dynamic/cantilever_beam.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 导入包 4 | import sys 5 | from hyperstatic.core import Api 6 | 7 | # 工作路径 8 | path="./wkdir" 9 | if sys.platform=="win32": 10 | path="c:\\wkdir" 11 | 12 | # 初始化API 13 | api=Api(path) 14 | 15 | # 定义结点 16 | api.add_node("A",0,0,0) 17 | api.add_node("B",10,0,0) 18 | 19 | # 定义单元 20 | api.add_simple_beam("b","A","B",E=2e11,mu=0.3,A=0.0188,I2=4.023e-5,I3=4.771e-4,J=4.133e-6,rho=7.85e10) 21 | 22 | # 定义荷载样式 23 | api.add_loadpattern("pat1") 24 | 25 | # 指定结点荷载到样式 26 | api.set_nodal_force("pat1","B",f3=-1e4) 27 | 28 | # 定义静力荷载工况 29 | api.add_static_case("case1") 30 | 31 | # 向工况添加荷载样式及乘数 32 | api.add_case_pattern("case1","pat1",1.0) 33 | 34 | # 向工况添加结点约束 35 | api.set_loadcase_nodal_restraint("case1","A",True,True,True,True,True,True) 36 | 37 | # 集成求解数据 38 | api.assemble() 39 | 40 | # 求解模态工况 41 | api.solve_modal("case1") 42 | 43 | # 解析位移结果 44 | d=api.result_get_nodal_displacement("B","case1") 45 | print("Deflection at node B is %4.6f m"%d[2]) -------------------------------------------------------------------------------- /example/core/static/cantilerver_beam.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 导入包 4 | import sys 5 | from hyperstatic.core import Api 6 | 7 | # 工作路径 8 | path="./wkdir" 9 | if sys.platform=="win32": 10 | path="c:\\wkdir" 11 | 12 | # 初始化API 13 | api=Api(path) 14 | 15 | # 定义结点 16 | api.add_node("A",0,0,0) 17 | api.add_node("B",10,0,0) 18 | 19 | # 定义单元 20 | api.add_simple_beam("b","A","B",E=2e11,mu=0.3,A=0.0188,I2=4.023e-5,I3=4.771e-4,J=4.133e-6,rho=7.85e10) 21 | 22 | # 定义荷载样式 23 | api.add_loadpattern("pat1") 24 | 25 | # 指定结点荷载到样式 26 | api.set_nodal_force("pat1","B",f3=-1e4) 27 | 28 | # 定义静力荷载工况 29 | api.add_static_case("case1") 30 | 31 | # 向工况添加荷载样式及乘数 32 | api.add_case_pattern("case1","pat1",1.0) 33 | 34 | # 向工况添加结点约束 35 | api.set_loadcase_nodal_restraint("case1","A",True,True,True,True,True,True) 36 | 37 | # 集成求解数据 38 | api.assemble() 39 | 40 | # 求解静力工况 41 | api.solve_static("case1") 42 | 43 | # 解析位移结果 44 | d=api.result_get_nodal_displacement("B","case1") 45 | print("Deflection at node B is %4.6f m"%d[2]) -------------------------------------------------------------------------------- /hyperstatic/app/general/post/combination.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Mar 22 19:19:33 2017 4 | 5 | @author: Dell 6 | """ 7 | import uuid 8 | 9 | from sqlalchemy.sql import and_ 10 | 11 | from hyperstatic.app.general.orm import Config, AreaSection, Joint, Area 12 | import logging 13 | 14 | class Combination(object): 15 | def __init__(self,name,lc_factor,method='linear_add'): 16 | """ 17 | name: name of the combination 18 | lc_factor: a dictionary about lc:factor 19 | method: linear_add, enveloped 20 | """ 21 | self.__name=name 22 | self.__method=method 23 | self.__loadcase={} 24 | 25 | @property 26 | def name(self): 27 | return self.__name 28 | 29 | @name.setter 30 | def name(self,name): 31 | self.__name=name 32 | 33 | @property 34 | def method(self): 35 | return self.__method 36 | 37 | def add_load(self,load,factor): 38 | self.__loadcase[load]=factor 39 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/isotropy.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import sympy as syp 3 | from sympy import tensor as syt 4 | from sympy.utilities.autowrap import autowrap 5 | 6 | 7 | kdelta=syp.KroneckerDelta 8 | E,nu=syp.symbols("E nu") 9 | G=E/2/(1+nu) 10 | lamda=E*nu/(1+nu)/(1-2*nu) 11 | 12 | D_ijkl=lambda i,j,k,l:2*G*kdelta(i,k)*kdelta(j,l)+lamda*kdelta(i,j)*kdelta(k,l) 13 | 14 | D=syt.Array.zeros(3,3,3,3) 15 | D=D.as_mutable() 16 | for i in range(3): 17 | for j in range(3): 18 | for k in range(3): 19 | for l in range(3): 20 | D[i,j,k,l] = 2*G*kdelta(i,k)*kdelta(j,l)+lamda*kdelta(i,j)*kdelta(k,l) 21 | 22 | # eps=syp.zeros(3,3) 23 | eps=syt.Array.zeros(3,3).as_mutable() 24 | exx,eyy,ezz,gxy,gyz,gzx=syp.symbols("\epsilon_{xx},\epsilon_{yy},\epsilon_{zz},\gamma_{xy},\gamma_{yz},\gamma_{zx}") 25 | eps[0,0],eps[1,1],eps[2,2],eps[0,1],eps[1,2],eps[2,0]=exx,eyy,ezz,gxy/2,gyz/2,gzx/2 26 | eps[1,0],eps[2,1],eps[0,2]=eps[0,1],eps[1,2],eps[2,0] 27 | eps 28 | 29 | sig=np.tensordot(D,eps) 30 | sig=syt.Array(sig) 31 | sig -------------------------------------------------------------------------------- /hyperstatic/app/scripts/grasshopper/element/node.py: -------------------------------------------------------------------------------- 1 | from ghpythonlib.componentbase import executingcomponent as component 2 | import Grasshopper, GhPython 3 | import System 4 | import Rhino 5 | import rhinoscriptsyntax as rs 6 | 7 | class MyComponent(component): 8 | 9 | def RunScript(self, pts): 10 | """Provides a scripting component. 11 | Inputs: 12 | pts: list of point objects 13 | Output: 14 | nodes: list of wrapped node objects""" 15 | 16 | __author__ = "Zhuoju Huang" 17 | __version__ = "2022.07.12" 18 | 19 | import rhinoscriptsyntax as rs 20 | 21 | class Node(): 22 | def __init__(self,name, pt): 23 | self.name=name 24 | self.point=pt 25 | 26 | nodes=[Node(str(i+1),pt) for i,pt in zip(range(len(pts)),pts)] 27 | 28 | 29 | # return outputs if you have them; here I try it for you: 30 | return nodes 31 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/interpolate/Hermite.py: -------------------------------------------------------------------------------- 1 | import sympy as syp 2 | 3 | l=syp.symbols("l") 4 | xi,eta=syp.symbols("xi eta") 5 | 6 | #H0 H1 is the order of the function in 0,1 7 | H01=lambda x:1-3*x**2+2*x**3 8 | H02=lambda x:(x-2*x**2+x**3)*l 9 | H11=lambda x:3*x**2-2*x**3 10 | H12=lambda x:(x**3-x**2)*l 11 | 12 | #linear 13 | def N1D(): 14 | N1=H01(xi) 15 | N2=H02(xi) 16 | N3=H11(xi) 17 | N4=H12(xi) 18 | return [N1,N2,N3,N4] 19 | 20 | #double linear 21 | def N2D(): 22 | N1=H01(xi)*H01(eta) 23 | N2=H11(xi)*H01(eta) 24 | N3=H01(xi)*H11(eta) 25 | N4=H11(xi)*H11(eta) 26 | N5=H02(xi)*H01(eta) 27 | N6=H12(xi)*H01(eta) 28 | N7=H02(xi)*H11(eta) 29 | N8=H12(xi)*H11(eta) 30 | N9=H01(xi)*H02(eta) 31 | N10=H11(xi)*H02(eta) 32 | N11=H01(xi)*H12(eta) 33 | N12=H11(xi)*H12(eta) 34 | N13=H02(xi)*H02(eta) 35 | N14=H12(xi)*H02(eta) 36 | N15=H02(xi)*H12(eta) 37 | N16=H12(xi)*H12(eta) 38 | return [N1,N2,N3,N4, 39 | N5,N6,N7,N8, 40 | N9,N10,N11,N12, 41 | N13,N14,N15,N16,] 42 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/operator.py: -------------------------------------------------------------------------------- 1 | import sympy as syp 2 | import numpy as np 3 | from inspect import isfunction 4 | 5 | x,y,z=syp.symbols("x y z") 6 | ddx=lambda f : syp.diff(f,x) 7 | ddy=lambda f : syp.diff(f,y) 8 | ddz=lambda f : syp.diff(f,z) 9 | 10 | L3=np.array([ 11 | [ddx,0,0], 12 | [0,ddy,0], 13 | [0,0,ddz], 14 | [ddy,ddx,0], 15 | [0,ddz,ddy], 16 | [ddz,0,ddx]]) 17 | 18 | def L2(x:syp.Symbol,y:syp.Symbol): 19 | ddx=lambda f : syp.diff(f,x) 20 | ddy=lambda f : syp.diff(f,y) 21 | return np.array([ 22 | [ddx,0], 23 | [0,ddy], 24 | [ddy,ddx]]) 25 | 26 | def operator_dot(A,f): 27 | assert A.shape[1]==f.shape[0] 28 | res=syp.zeros(A.shape[0],f.shape[1]) 29 | for i in range(A.shape[0]): 30 | for j in range(f.shape[1]): 31 | for k in range(A.shape[1]): 32 | if A[i,k]!=0: 33 | if isfunction(A[i,k]): 34 | res[i,j]+=A[i,k](f[k,j]) 35 | else: 36 | res[i,j]+=A[i,k]*f[k,j] 37 | return res -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/section/shell_section.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from sympy import re 3 | from hyperstatic.core.fe_model.material.isotropy import IsotropicMaterial 4 | 5 | class ShellSection(object): 6 | def __init__(self,name:str,material:IsotropicMaterial,t:float,ele_type:str="shell"): 7 | self.__name=name 8 | self.__material=material 9 | self.__t=t 10 | self.__ele_type=ele_type 11 | 12 | @property 13 | def name(self): 14 | return self.__name 15 | 16 | @property 17 | def material(self): 18 | return self.__material.name 19 | 20 | @property 21 | def rho(self): 22 | return self.__material.rho 23 | 24 | @property 25 | def E(self): 26 | return self.__material.E 27 | 28 | @property 29 | def mu(self): 30 | return self.__material.mu 31 | 32 | @property 33 | def G(self): 34 | return self.__material.G 35 | 36 | @property 37 | def t(self): 38 | return self.__t 39 | 40 | @property 41 | def ele_type(self): 42 | return self.__ele_type 43 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/grasshopper/element/beam.py: -------------------------------------------------------------------------------- 1 | from ghpythonlib.componentbase import executingcomponent as component 2 | import Grasshopper, GhPython 3 | import System 4 | import Rhino 5 | import rhinoscriptsyntax as rs 6 | 7 | class MyComponent(component): 8 | 9 | def RunScript(self, crvs, section): 10 | """Provides a scripting component. 11 | Inputs: 12 | crvs: list of crvs to wrapped as beams 13 | section: beam section object 14 | Output: 15 | beams: list of beam objects""" 16 | 17 | __author__ = "Zhuoju Huang" 18 | __version__ = "2022.07.12" 19 | 20 | class Beam(): 21 | def __init__(self,name,crv,section): 22 | self.name=name 23 | self.curve=crv 24 | self.section=section 25 | 26 | names=range(len(crvs)) 27 | beams=[Beam(name,crv,section) for crv,name in zip(crvs,names)] 28 | 29 | # return outputs if you have them; here I try it for you: 30 | return beams 31 | -------------------------------------------------------------------------------- /doc/source/quickstart.md: -------------------------------------------------------------------------------- 1 | # 快速开始 2 | 3 | ## 安装 4 | ```bash 5 | pip install -U hyperstatic 6 | ``` 7 | 8 | ## Core API使用 9 | 10 | 10m悬臂梁,A端固定,B端施加10kN竖直向下荷载 11 | 12 | ```python 13 | # -*- coding: utf-8 -*- 14 | 15 | # 导入包 16 | import sys 17 | from hyperstatic.core import Api 18 | 19 | # 工作路径 20 | path="./wkdir" 21 | if sys.platform=="win32": 22 | path="c:\\wkdir" 23 | 24 | # 初始化API 25 | api=Api(path) 26 | 27 | # 定义结点 28 | api.add_node("A",0,0,0) 29 | api.add_node("B",10,0,0) 30 | 31 | # 定义单元 32 | api.add_simple_beam("b","A","B",E=2e11,mu=0.3,A=0.0188,I2=4.023e-5,I3=4.771e-4,J=4.133e-6,rho=7.85e10) 33 | 34 | # 定义荷载样式 35 | api.add_loadpattern("pat1") 36 | 37 | # 指定结点荷载到样式 38 | api.set_nodal_force("pat1","B",f3=-1e4) 39 | 40 | # 定义静力荷载工况 41 | api.add_static_case("case1") 42 | 43 | # 向工况添加荷载样式及乘数 44 | api.add_case_pattern("case1","pat1",1.0) 45 | 46 | # 向工况添加结点约束 47 | api.set_loadcase_nodal_restraint("case1","A",True,True,True,True,True,True) 48 | 49 | # 求解静力工况 50 | api.solve_static("case1") 51 | 52 | # 解析位移结果 53 | d=api.result_get_nodal_displacement("case1","B") 54 | print("Deflection at node B is %4.6f m"%d[2]) 55 | ``` 56 | -------------------------------------------------------------------------------- /tests/test_core/test_elm_line/test_line.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import pytest 3 | from pytest import approx,raises 4 | 5 | import numpy as np 6 | from hyperstatic.core.fe_model.node import Node 7 | from hyperstatic.core.fe_model.element.line import Line 8 | 9 | class TestLine(): 10 | def test_construction(self): 11 | n1=Node("1",0,0,0) 12 | n2=Node("2",1,0,0) 13 | l=Line("myLine",n1,n2,12) 14 | assert l.length==approx(1,rel=1e-9) 15 | 16 | def test_direction(self): 17 | n1=Node("1",0,0,0) 18 | n2=Node("2",1,0,0) 19 | l=Line("myLine",n1,n2,12) 20 | assert l.local_csys.x==approx(np.array([1,0,0]),rel=1e-6) 21 | assert l.local_csys.y==approx(np.array([0,0,1]),rel=1e-6) 22 | assert l.local_csys.z==approx(np.array([0,-1,0]),rel=1e-6) 23 | 24 | n1=Node("1",0,0,0) 25 | n2=Node("2",0,0,1) 26 | l=Line("myLine",n1,n2,12) 27 | assert l.local_csys.x==approx(np.array([0,0,1]),rel=1e-6) 28 | assert l.local_csys.y==approx(np.array([1,0,0]),rel=1e-6) 29 | assert l.local_csys.z==approx(np.array([0,1,0]),rel=1e-6) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 zhuoju36 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/test_core/test_loadcase/test_basic.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from pytest import approx,raises 3 | 4 | import numpy as np 5 | from hyperstatic.core.fe_model.load.loadcase import LoadCase,LoadPattern 6 | from hyperstatic.common.curve import Curve 7 | 8 | class TestBasic(): 9 | def test_loadcase(self): 10 | lc=LoadCase("lc") 11 | lp1=LoadPattern("lp1") 12 | lp2=LoadPattern("lp2") 13 | lp1.set_nodal_load("1",1,1,1,0,0,0) 14 | lp2.set_nodal_load("1",2,2,2,0,0,0) 15 | lc.add_pattern(lp1,1) 16 | lc.add_pattern(lp2,2) 17 | f=lc.get_nodal_f("1") 18 | assert f[0]==5 19 | assert f[2]==5 20 | 21 | def test_time_history(self): 22 | lc=LoadCase("lc") 23 | lp1=LoadPattern("lp1") 24 | lp2=LoadPattern("lp2") 25 | lp1.set_nodal_load("1",1,2,3,0,0,0) 26 | lp2.set_nodal_load("1",2,2,2,0,0,0) 27 | c1=Curve.sin("sine",1,1,0,0.2,100).to_array() 28 | c2=Curve.sin("sine",1,2,0,0.2,100).to_array() 29 | lc.add_pattern_time_history(lp1,1,c1) 30 | lc.add_pattern_time_history(lp2,1,c2) 31 | f=lc.get_nodal_f_time_history("1") 32 | assert f[10,2]==approx(1.2142872898611885,rel=1e-3) 33 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/grasshopper/material/material_isotropic.py: -------------------------------------------------------------------------------- 1 | from ghpythonlib.componentbase import executingcomponent as component 2 | import Grasshopper, GhPython 3 | import System 4 | import Rhino 5 | import rhinoscriptsyntax as rs 6 | 7 | class MyComponent(component): 8 | 9 | def RunScript(self, name, rho,E,mu): 10 | """General sotropic material for Hyperstatic 11 | Inputs: 12 | name: (str) name 13 | rho: (float) desity 14 | E: (float) elastic modulus 15 | mu: (float) Poisson ratio 16 | Output: 17 | material: The a output variable""" 18 | 19 | __author__ = "Zhuoju Huang" 20 | __version__ = "2022.07.12" 21 | 22 | class IsotropicMaterial(): 23 | def __init__(self,name,rho,E,mu): 24 | self.name=name 25 | self.rho=rho 26 | self.E=E 27 | self.mu=mu 28 | 29 | material=IsotropicMaterial(str(name), 30 | float(rho), 31 | float(E), 32 | float(mu), 33 | ) 34 | 35 | # return outputs if you have them; here I try it for you: 36 | return material 37 | -------------------------------------------------------------------------------- /tests/test_core/test_csys/test_cartesian.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from pytest import approx,raises 3 | 4 | import numpy as np 5 | import numpy.linalg as nl 6 | 7 | from hyperstatic.common.csys import Cartesian 8 | 9 | class TestCartesian(): 10 | def test_vec(self): 11 | csys=Cartesian((0,0,1),(1,1,0),(0,1,0)) 12 | assert csys.origin==approx((0,0,1)) 13 | assert nl.norm(csys.x,2)==approx(1,rel=1e-8) 14 | assert nl.norm(csys.y,2)==approx(1,rel=1e-8) 15 | assert nl.norm(csys.z,2)==approx(1,rel=1e-8) 16 | 17 | def test_T(self): 18 | csys=Cartesian((0,0,0),(1,1,0),(0,1,0)) 19 | assert csys.transform_matrix[0,0]==approx(2**0.5/2,rel=1e-3) 20 | 21 | def test_inline(self): 22 | with pytest.raises(Exception): 23 | csys=Cartesian((10,10,0),(1,1,0),(2,2,0)) 24 | 25 | def test_rotate(self): 26 | csys=Cartesian((0,0,0),(1,0,0),(0,1,0)) 27 | csys.rotate_about_z(np.pi/4) 28 | assert csys.transform_matrix[0,0]==approx(2**0.5/2,rel=1e-3) 29 | assert csys.transform_matrix[1,0]==approx(-2**0.5/2,rel=1e-3) 30 | csys=Cartesian((0,0,0),(1,0,0),(0,1,0)) 31 | csys.rotate_about_x(np.pi/2) 32 | assert csys.transform_matrix[1]==approx(np.array([0,0,1]),rel=1e-3) 33 | assert csys.transform_matrix[2]==approx(np.array([0,-1,0]),rel=1e-3) -------------------------------------------------------------------------------- /hyperstatic/core/fe_post/structure.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | import numpy as np 5 | 6 | from hyperstatic.core.fe_post import ResultResolver 7 | 8 | 9 | class StructureResultResolver(ResultResolver): 10 | def __init__(self,workpath:str,filename:str): 11 | super().__init__(workpath,filename) 12 | self.__workpath=super().workpath 13 | self.__assembly=super().assembly 14 | 15 | def resolve_modal_frequency(self,casename:str)->dict: 16 | path=self.__workpath 17 | omega=np.load(os.path.join(path,casename+".o.npy")) 18 | T=2*np.pi/omega 19 | f=1/T 20 | return { 21 | "omega":omega.reshape(omega.size), 22 | "f":f.reshape(omega.size), 23 | "T":T.reshape(omega.size) 24 | } 25 | 26 | def resolve_structural_reaction(self,casename:str)->float: 27 | path=self.__workpath 28 | k=np.load(os.path.join(path,casename+".k.npy")) 29 | d=np.load(os.path.join(path,casename+".d.npy")) 30 | f=np.dot(k,d) 31 | restraints=self.__assembly.restraintDOF(casename) 32 | res=0 33 | for i in restraints: 34 | res+=f[i] 35 | return res 36 | 37 | 38 | if __name__=="__main__": 39 | resolver=StructureResultResolver("c:\\test") 40 | res=resolver.get_modal_frequency("eigen") 41 | print(res) 42 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/element/tria/__init__.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from hyperstatic.common.csys import Cartesian 3 | from hyperstatic.core.fe_model.node import Node 4 | from hyperstatic.core.fe_model.element import Element 5 | from hyperstatic.common.tolerance import Tolerance 6 | 7 | class Tria(Element): 8 | def __init__(self,name,node_i:Node,node_j:Node,node_k:Node,dof): 9 | self._nodes=[node_i,node_j,node_k] 10 | #Initialize local CSys 11 | o=[(node_i.x+node_j.x+node_k.x)/3, 12 | (node_i.y+node_j.y+node_k.y)/3, 13 | (node_i.z+node_j.z+node_k.z)/3] 14 | vec1=node_i.loc-node_j.loc 15 | vec2=node_j.loc-node_k.loc 16 | n=np.cross(vec1,vec2) 17 | n=n/np.linalg.norm(n) 18 | tol=Tolerance.abs_tol() 19 | if np.linalg.norm(n-np.array([0,0,1]))np.array: 46 | return np.array([[exx, gxy/2, gzx/2], 47 | [gxy/2, eyy, gyz/2], 48 | [gzx/2, gyz/2, ezz]]) 49 | 50 | @property 51 | def D(self,exx,eyy,ezz,gxy,gyz,gzx)->np.array: 52 | E=self.__E 53 | nu=self.__m 54 | return np.array([[E*eyy*nu/((1 - 2*nu)*(nu + 1)) + E*ezz*nu/((1 - 2*nu)*(nu + 1)) + exx*(E*nu/((1 - 2*nu)*(nu + 1)) + E/(nu + 1)), E*gxy/(2*(nu + 1)), E*gzx/(2*(nu + 1))], [E*gxy/(2*(nu + 1)), E*exx*nu/((1 - 2*nu)*(nu + 1)) + E*ezz*nu/((1 - 2*nu)*(nu + 1)) + eyy*(E*nu/((1 - 2*nu)*(nu + 1)) + E/(nu + 1)), E*gyz/(2*(nu + 1))], [E*gzx/(2*(nu + 1)), E*gyz/(2*(nu + 1)), E*exx*nu/((1 - 2*nu)*(nu + 1)) + E*eyy*nu/((1 - 2*nu)*(nu + 1)) + ezz*(E*nu/((1 - 2*nu)*(nu + 1)) + E/(nu + 1))]]) 55 | 56 | 57 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/element/line/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import numpy as np 3 | import scipy.sparse as spr 4 | 5 | from hyperstatic.common.csys import Cartesian 6 | from hyperstatic.core.fe_model.node import Node 7 | from hyperstatic.core.fe_model.element import Element 8 | from hyperstatic.common.tolerance import Tolerance 9 | 10 | class Line(Element): 11 | def __init__(self,name,start:Node,end:Node,dof:int): 12 | #Initialize local CSys 13 | tol=Tolerance.abs_tol() 14 | o = (start.loc+end.loc)/2 15 | pt1 = end.loc 16 | pt2 = o + np.array([0,0,1]) 17 | if np.max(np.abs((start.loc-end.loc)[:2])) < tol: 18 | pt2 = o + np.array([1,0,0]) 19 | csys=Cartesian(o, pt1, pt2) 20 | super().__init__(name,[start,end],1,dof,csys) 21 | 22 | @property 23 | def start(self): 24 | return super().nodes[0].loc 25 | 26 | @property 27 | def end(self): 28 | return super().nodes[1].loc 29 | 30 | @property 31 | def length(self): 32 | A=self.nodes[0].loc 33 | B=self.nodes[1].loc 34 | return np.linalg.norm(A-B) 35 | 36 | @property 37 | def transform_matrix(self): 38 | T=np.zeros((12,12)) 39 | V=super(Line,self).local_csys.transform_matrix 40 | T[:3,:3]=T[3:6,3:6]=T[6:9,6:9]=T[9:,9:]= V 41 | return spr.csr_matrix(T) 42 | 43 | def integrate_K(self): 44 | raise NotImplementedError() 45 | 46 | def integrate_M(self): 47 | raise NotImplementedError() 48 | 49 | def get_shape_function(self): 50 | raise NotImplementedError() 51 | 52 | def interpolate(self,loc): 53 | raise NotImplementedError() 54 | 55 | if __name__=="__main__": 56 | n1=Node(0,1,0) 57 | n2=Node(1,1,0) 58 | l=Line(n1,n2,6) 59 | print(l.length) 60 | print(l.transform_matrix) 61 | -------------------------------------------------------------------------------- /hyperstatic/app/scripts/grasshopper/cross_section/beam_section_general.py: -------------------------------------------------------------------------------- 1 | from ghpythonlib.componentbase import executingcomponent as component 2 | import Grasshopper, GhPython 3 | import System 4 | import Rhino 5 | import rhinoscriptsyntax as rs 6 | 7 | class MyComponent(component): 8 | 9 | def RunScript(self, name, material, A, As2, As3, J, I2, I3): 10 | """General Section for Hyperstatic 11 | Inputs: 12 | name: (str) name 13 | material: (obj): material object 14 | A: (float) cross section area 15 | As2: (float) shear area of 2 axis 16 | As3: (float) shear area of 3 axis 17 | J: (float) torsion constaint 18 | I2: (float) moment of inertia around 2 axis 19 | I3: (float) moment of inertia around 3 axis 20 | Output: 21 | section: The a output variable""" 22 | 23 | __author__ = "Zhuoju Huang" 24 | __version__ = "2022.07.12" 25 | class Section(): 26 | def __init__(self,name,mat,A,As2,As3,J,I2,I3): 27 | self.name=name 28 | self.shape="general" 29 | self.material=mat 30 | self.rho=material.rho 31 | self.E=material.E 32 | self.mu=material.mu 33 | self.A=A 34 | self.As2=As2 35 | self.As3=As3 36 | self.J=J 37 | self.I2=I2 38 | self.I3=I3 39 | 40 | section=Section(str(name), 41 | material, 42 | float(A), 43 | float(As2), 44 | float(As3), 45 | float(J), 46 | float(I2), 47 | float(I3) 48 | ) 49 | 50 | # return outputs if you have them; here I try it for you: 51 | return section 52 | -------------------------------------------------------------------------------- /tests/test_core/test_post/test_beam.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from pydoc import resolve 3 | import pytest 4 | from pytest import approx,raises 5 | import numpy as np 6 | 7 | import logging 8 | import sys 9 | import os 10 | 11 | from hyperstatic.core.fe_model.assembly import Assembly 12 | from hyperstatic.core.fe_model.model import Model 13 | from hyperstatic.core.fe_model.load.pattern import LoadPattern 14 | from hyperstatic.core.fe_model.load.loadcase import ModalCase, StaticCase 15 | from hyperstatic.core.fe_solver.dynamic import ModalSolver 16 | from hyperstatic.core.fe_post.beam import BeamResultResolver 17 | from hyperstatic.core.fe_solver.static import StaticSolver 18 | 19 | 20 | class TestBeamResult(): 21 | def test_cantilever(self): 22 | path="./test" 23 | if sys.platform=="win32": 24 | path="c:\\test" 25 | 26 | model=Model() 27 | model.add_node("1",0,0,0) 28 | model.add_node("2",6,0,0) 29 | model.add_simple_beam("A","1","2",E=1.999e11,mu=0.3,A=4.265e-3,I3=6.572e-5,I2=3.301e-6,J=9.651e-8,rho=7849.0474) 30 | 31 | patt1=LoadPattern("pat1") 32 | patt1.set_nodal_load("2",0,0,-1e4,0,0,0) 33 | 34 | lc=StaticCase("case1") 35 | lc.add_pattern(patt1,1.0) 36 | lc.set_nodal_restraint("1",True,True,True,True,True,True) 37 | asb=Assembly(model,[lc]) 38 | asb.save(path,"test.asb") 39 | solver=StaticSolver(path,"test.asb") 40 | solver.solve_linear("case1") 41 | 42 | resolver=BeamResultResolver(path,"test.asb") 43 | d=resolver.resolve_beam_deformation("A",1,"case1") 44 | assert d[1]==approx(-0.05519,rel=2e-2) 45 | assert d[4]==approx(-0.0137,rel=2e-2) 46 | d=resolver.resolve_beam_deformation("A",0.5,"case1") 47 | assert d[1]==approx(-0.0173,rel=2e-2) 48 | assert d[4]==approx(-0.01027,rel=2e-2) 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Upload Python Package 10 | 11 | on: push 12 | 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | deploy: 19 | 20 | runs-on: ubuntu-18.04 21 | 22 | steps: 23 | - uses: actions/checkout@master 24 | 25 | - name: Set up Python 26 | uses: actions/setup-python@master 27 | with: 28 | python-version: '3.8' 29 | 30 | - name: Install dependencies 31 | run: | 32 | python -m pip install --upgrade pip 33 | python -m pip install -U pythran pytest cython numpy pybind11 34 | python -m pip install -U coverage codecov pytest-cov 35 | 36 | - name: Build package 37 | run: python setup.py build install 38 | 39 | - name: Install and test 40 | run: py.test --cov 41 | 42 | - name: Upload coverage to Codecov 43 | uses: codecov/codecov-action@master 44 | 45 | - name: Publish package to Test PyPI 46 | if: startsWith(github.ref, 'refs/tags') 47 | uses: pypa/gh-action-pypi-publish@master 48 | with: 49 | user: __token__ 50 | password: ${{ secrets.TEST_PYPI_API_TOKEN }} 51 | repository_url: https://test.pypi.org/legacy/ 52 | 53 | - name: Publish package to PyPI 54 | if: startsWith(github.ref, 'refs/tags') 55 | uses: pypa/gh-action-pypi-publish@master 56 | with: 57 | user: __token__ 58 | password: ${{ secrets.PYPI_API_TOKEN }} 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hyperstatic:开放自由的工程结构分析框架 2 | 3 | ![GitHub](https://img.shields.io/github/license/zhuoju36/hyperstatic) [![codecov](https://codecov.io/gh/zhuoju36/Hyperstatic/branch/master/graph/badge.svg?token=4C6a6QwvKA)](https://codecov.io/gh/zhuoju36/Hyperstatic) ![PyPI](https://img.shields.io/pypi/v/hyperstatic) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/hyperstatic) 4 | [![Documentation Status](https://readthedocs.org/projects/hyperstatic/badge/?version=latest)](https://hyperstatic.readthedocs.io/zh_CN/latest/?badge=latest) 5 | ## 简介 6 | 基于Python语言,采用面向对象方式开发,针对建筑领域特点开发的结构分析框架,提供完全开放的基础结构数值分析,可供高校师生、研究院所参考,也可自由用于相关结构工程设计。 7 | 8 | ## 当前版本支持功能(v0.2) 9 | 10 | - 各向同性单轴材料 11 | - 考虑剪切的梁单元 12 | - 三角形、四边形薄壳,支持平板及薄膜刚度 13 | - 线性静力分析,支持多种稀疏矩阵求解器 14 | - 自振模态分析 15 | - 直接积分法时程分析 16 | - 后处理 17 | - 分析结果的可视化 18 | 19 | ## 快速开始 20 | ### 安装 21 | ```bash 22 | pip install -U hyperstatic 23 | ``` 24 | 25 | ### Core API使用 26 | 27 | 10m悬臂梁,A端固定,B端施加10kN竖直向下荷载 28 | 29 | ```python 30 | # -*- coding: utf-8 -*- 31 | 32 | # 导入包 33 | import sys 34 | from hyperstatic.core import Api 35 | 36 | # 工作路径 37 | path="./wkdir" 38 | if sys.platform=="win32": 39 | path="c:\\wkdir" 40 | 41 | # 初始化API 42 | api=Api(path) 43 | 44 | # 定义结点 45 | api.add_node("A",0,0,0) 46 | api.add_node("B",10,0,0) 47 | 48 | # 定义单元 49 | api.add_simple_beam("b","A","B",E=2e11,mu=0.3,A=0.0188,I2=4.023e-5,I3=4.771e-4,J=4.133e-6,rho=7.85e10) 50 | 51 | # 定义荷载样式 52 | api.add_loadpattern("pat1") 53 | 54 | # 指定结点荷载到样式 55 | api.set_nodal_force("pat1","B",f3=-1e4) 56 | 57 | # 定义静力荷载工况 58 | api.add_static_case("case1") 59 | 60 | # 向工况添加荷载样式及乘数 61 | api.add_case_pattern("case1","pat1",1.0) 62 | 63 | # 向工况添加结点约束 64 | api.set_loadcase_nodal_restraint("case1","A",True,True,True,True,True,True) 65 | 66 | # 集成求解数据 67 | api.assemble() 68 | 69 | # 求解静力工况 70 | api.solve_static("case1") 71 | 72 | # 解析位移结果 73 | d=api.result_get_nodal_displacement("B","case1") 74 | print("Deflection at node B is %4.6f m"%d[2]) 75 | ``` 76 | 77 | ## 留言讨论 78 | - [github](https://github.com/zhuoju36) 79 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/element/quad/__init__.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from hyperstatic.common.csys import Cartesian 4 | from hyperstatic.core.fe_model.element import Element 5 | from hyperstatic.common.tolerance import Tolerance 6 | 7 | class Quad(Element): 8 | def __init__(self,name,node_i,node_j,node_k,node_l,dof): 9 | #Initialize local CSys 10 | o=(node_i.loc+node_j.loc+node_k.loc+node_l.loc)/4 11 | vec1=node_i.loc-node_j.loc 12 | vec2=node_j.loc-node_k.loc 13 | n=np.cross(vec1,vec2) 14 | n=n/np.linalg.norm(n) 15 | tol=Tolerance.abs_tol() 16 | if np.linalg.norm(n-np.array([0,0,1]))np.ndarray: 62 | """获取结点的变换矩阵 63 | 64 | Returns: 65 | np.ndarray: 6x6变换矩阵 66 | """ 67 | V=self.__local_csys.transform_matrix 68 | V_=np.zeros((6,6)) 69 | V_[:3,:3]=V_[3:,3:]=V 70 | return V_ 71 | 72 | def initialize_csys(self): 73 | self.__local_csys.align_with_global() 74 | 75 | def rotate_about_1axis(self,theta): 76 | self.__local_csys.rotate_about_x(theta) 77 | 78 | def rotate_about_2axis(self,theta): 79 | self.__local_csys.rotate_about_y(theta) 80 | 81 | def rotate_about_3axis(self,theta): 82 | self.__local_csys.rotate_about_z(theta) 83 | 84 | def integrate_M(self)->spr.coo_matrix: 85 | return spr.diags(self.mass,format="coo") 86 | 87 | # @property 88 | # def fn(self): 89 | # return self.__load 90 | 91 | # @fn.setter 92 | # def fn(self,load): 93 | # assert(len(load)==6) 94 | # self.__load=np.array(load).reshape((6,1)) 95 | 96 | # @property 97 | # def dn(self): 98 | # return self.__disp 99 | # @dn.setter 100 | # def dn(self,disp): 101 | # assert(len(disp)==6) 102 | # self.__disp=disp 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/metaDKT/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sympy as syp 3 | from sympy.utilities.autowrap import autowrap 4 | import numpy as np 5 | from hyperstatic.core.fe_model.meta.plates import x1,y1,x2,y2,x3,y3,E,mu,t,xi,eta 6 | 7 | x12=x1-x2 8 | x23=x2-x3 9 | x31=x3-x1 10 | y12=y1-y2 11 | y23=y2-y3 12 | y31=y3-y1 13 | 14 | x=[x23,x31,x12] #xij 15 | y=[y23,y31,y12] #yij 16 | 17 | l=[syp.sqrt(x23**2+y23**2),syp.sqrt(x31**2+y31**2),syp.sqrt(x12**2+y12**2),] 18 | 19 | P=syp.zeros(1,3) 20 | tt=syp.zeros(1,3) 21 | q=syp.zeros(1,3) 22 | r=syp.zeros(1,3) 23 | 24 | for ij,k in zip([0,1,2],[0,1,2]): 25 | P[k]= -6*x[ij]/l[ij]**2 26 | tt[k]= -6*y[ij]/l[ij]**2 27 | q[k]=3*x[ij]*y[ij]/l[ij]**2 28 | r[k]= 3*y[ij]**2/l[ij]**2 29 | 30 | P4,P5,P6=tuple(P) 31 | t4,t5,t6=tuple(tt) 32 | q4,q5,q6=tuple(q) 33 | r4,r5,r6=tuple(r) 34 | 35 | Hxxi=syp.Matrix([ 36 | P6*(1-2*xi)+(P5-P6)*eta, 37 | q6*(1-2*xi)-(q5+q6)*eta, 38 | -4+6*(xi+eta)+r6*(1-2*xi)-eta*(r5+r6), 39 | -P6*(1-2*xi)+eta*(P4+P6), 40 | q6*(1-2*xi)-eta*(q6-q4), 41 | -2+6*xi+r6*(1-2*xi)+eta*(r4-r6), 42 | -eta*(P5+P4), 43 | eta*(q4-q5), 44 | -eta*(r5-r4)]) 45 | 46 | Hyxi=syp.Matrix([ 47 | t6*(1-2*xi)+eta*(t5-t6), 48 | 1+r6*(1-2*xi)-eta*(r5+r6), 49 | -q6*(1-2*xi)+eta*(q5+q6), 50 | -t6*(1-2*xi)+eta*(t4+t6), 51 | -1+r6*(1-2*xi)+eta*(r4-r6), 52 | -q6*(1-2*xi)-eta*(q4-q6), 53 | -eta*(t4+t5), 54 | eta*(r4-r5), 55 | -eta*(q4-q5) 56 | ]) 57 | 58 | Hxeta=syp.Matrix([ 59 | -P5*(1-2*eta)-xi*(P6-P5), 60 | q5*(1-2*eta)-xi*(q5+q6), 61 | -4+6*(xi+eta)+r5*(1-2*eta)-xi*(r5+r6), 62 | xi*(P4+P6), 63 | xi*(q4-q6), 64 | -xi*(r6-r4), 65 | P5*(1-2*eta)-xi*(P4+P5), 66 | q5*(1-2*eta)+xi*(q4-q5), 67 | -2+6*eta+r5*(1-2*eta)+xi*(r4-r5), 68 | ]) 69 | 70 | Hyeta=syp.Matrix([ 71 | -t5*(1-2*eta)-xi*(t6-t5), 72 | 1+r5*(1-2*eta)-xi*(r5+r6), 73 | -q5*(1-2*eta)+xi*(q5+q6), 74 | xi*(t4+t6), 75 | xi*(r4-r6), 76 | -xi*(q4-q6), 77 | t5*(1-2*eta)-xi*(t4+t5), 78 | -1+r5*(1-2*eta)+xi*(r4-r5), 79 | -q5*(1-2*eta)-xi*(q4-q5), 80 | ]) 81 | 82 | B=syp.Matrix([y31*Hxxi.T+y12*Hxeta.T, 83 | -x31*Hyxi.T-x12*Hyeta.T, 84 | -x31*Hxxi.T-x12*Hxeta.T+y31*Hyxi.T+y12*Hyeta.T]) 85 | 86 | B/=(x31*y12-x12*y31) #2A=x31*y12-x12*y31 87 | 88 | D=syp.eye(3,3) 89 | D[0,0]=D[1,1]=1 90 | D[2,2]=(1-mu)/2 91 | D[0,1]=D[1,0]=mu 92 | D*=E*t**3/12/(1-mu**2) 93 | 94 | BDB=B.T*D*B 95 | 96 | def get_binary_BDB(): 97 | try: 98 | import metaDKT 99 | bBDB=metaDKT.autofunc_c 100 | except: 101 | raise Exception("Complile the cython code first!") 102 | return bBDB 103 | 104 | def generate_code(): 105 | tmp=os.path.dirname(os.path.realpath(__file__)) 106 | bBDB=autowrap(BDB,args=[E,mu,t,xi,eta,x1,y1,x2,y2,x3,y3],backend='cython',tempdir=tmp) 107 | 108 | if __name__=='__main__': 109 | generate_code() -------------------------------------------------------------------------------- /hyperstatic/app/general/result/result.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Mar 29 10:22:39 2018 4 | 5 | @author: Dell 6 | """ 7 | 8 | from hyperstatic.app.general.orm import ResultJointDisplacement,ResultJointReaction,ResultFrameForce,ResultModalPeriod 9 | 10 | def get_result_joint_displacement(self,name,loadcase): 11 | """ 12 | Get the result in the database. 13 | 14 | params: 15 | name: str, name of joint 16 | loadcase: str, name of loadcase 17 | return: list of float, displacement u1,u2,u3,r1,r2,r3 18 | """ 19 | res=self.session.query(ResultJointDisplacement).filter_by(joint_name=name,loadcase_name=loadcase).first() 20 | if res==None: 21 | return None 22 | else: 23 | scale=self.scale() 24 | return [res.u1/scale['L'],res.u2/scale['L'],res.u3/scale['L'], 25 | res.r1,res.r2,res.r3] 26 | 27 | def get_result_joint_reaction(self,name,loadcase): 28 | """ 29 | Get the result in the database. 30 | 31 | params: 32 | name: str, name of joint 33 | loadcase: str, name of loadcase 34 | return: list of float, reaction in u1,u2,u3,r1,r2,r3 35 | """ 36 | res=self.session.query(ResultJointReaction).filter_by(joint_name=name,loadcase_name=loadcase).first() 37 | if res==None: 38 | return None 39 | else: 40 | scale=self.scale() 41 | return [res.p1/scale['F'],res.p2/scale['F'],res.p3/scale['F'], 42 | res.m1/scale['F']/scale['L'],res.m2/scale['F']/scale['L'],res.m3/scale['F']/scale['L']] 43 | 44 | def get_result_frame_force(self,name,loadcase): 45 | """ 46 | Get the result in the database. 47 | 48 | params: 49 | name: str, name of frame 50 | loadcase: str, name of loadcase 51 | return: list of float, forces in both ends. 52 | """ 53 | reses=self.session.query(ResultFrameForce).filter_by(frame_name=name,loadcase_name=loadcase).all() 54 | if len(reses)==0: 55 | return None 56 | else: 57 | scale=self.scale() 58 | forces=[] 59 | for res in reses: 60 | forces.append([res.p01/scale['F'],res.p02/scale['F'],res.p03/scale['F'], 61 | res.m01/scale['F']/scale['L'],res.m02/scale['F']/scale['L'],res.m03/scale['F']/scale['L'], 62 | res.p11/scale['F'],res.p12/scale['F'],res.p13/scale['F'], 63 | res.m11/scale['F']/scale['L'],res.m12/scale['F']/scale['L'],res.m13/scale['F']/scale['L']]) 64 | return forces 65 | 66 | def get_result_period(self,loadcase,order='all'): 67 | """ 68 | Get the result in the database. 69 | 70 | params: 71 | loadcase: str, name of loadcase 72 | order: 'all' or int. order to find. 73 | return: list of period 74 | """ 75 | res=self.session.query(ResultModalPeriod).filter_by(loadcase_name=loadcase) 76 | if order=='all': 77 | return [r.period for r in res.all()] 78 | elif type(order)==int: 79 | res=res.filter_by(order=order).all() 80 | return [r.period for r in res.all()] -------------------------------------------------------------------------------- /hyperstatic/app/seismic/spec2wave.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy as sp 3 | from scipy.signal import convolve 4 | from scipy.fftpack import fft,ifft,fftfreq 5 | from matplotlib import pyplot as plt 6 | import os 7 | from wave2spec import GB50011_spectrum 8 | from random import random 9 | 10 | dω=0.02*2*np.pi#Hz 频率间隔 11 | ωk=np.arange(2*np.pi/6,2*np.pi/0.02,dω) #第k个谐波分量的圆频率,共n个 max(ωk)<1 12 | Ψk=np.random.random(len(ωk))*np.pi*2 13 | 14 | dt=0.01#s 时间间隔 15 | t=np.arange(0.1,40,dt) #时间点 16 | 17 | r=0.15 #超越概率 18 | ζ=0.05 #阻尼比 19 | td=20#s 持续时间 20 | 21 | PGA=70 #cm/s^2 22 | 23 | S=GB50011_spectrum(PGA/440,0.45,ζ,dt) #目标谱 24 | 25 | def f(t): 26 | t1=10 27 | t2=20 28 | c=0.1 29 | if 0 m/s2 72 | T=np.arange(dt,6.0+dt,dt) 73 | nex2pow=lambda x: int(round(2**np.ceil(np.log(x)/np.log(2.)))) #求采样点 74 | im=np.lib.scimath.sqrt(-1) 75 | Sa=[] 76 | n=256#采样点不是太精确,最好取到采样点数 77 | Nfft=nex2pow(n)*16 78 | f=fftfreq(Nfft,d=dt) 79 | ω=2*np.pi*f 80 | def max_response(_T): 81 | ωₙ=2*np.pi/_T 82 | ωd=(1-ξ)**0.5*ωₙ 83 | af=fft(ag,Nfft)/Nfft 84 | # H=1/((1-(ω/ωₙ)**2)+2*ξ*(ω/ωₙ)*im) #ωd? 85 | H=1/((1-(ω/ωd)**2)+2*ξ*(ω/ωd)*im) 86 | u=ifft(af*H,Nfft).real*Nfft 87 | return np.max(u)/9.8 88 | Sa=[max_response(t) for t in T] 89 | return T,Sa 90 | 91 | 92 | T,Sa=fft2spec(A(t),dt,ζ,PGA) 93 | plt.plot(T,Sa) 94 | 95 | def A_fit(t): 96 | s=Sτ(ωk) #功率谱 97 | st=ST(ωk) #目标反应谱 98 | for i in range(10): 99 | Ck=np.sqrt(4*s*dω) 100 | alpha = lambda t: Ck.dot(np.cos(ωk*t+Ψk)) 101 | A = np.vectorize(lambda t: f(t)*alpha(t) ) 102 | accel=A(t) 103 | T,Sa_=fft2spec(accel,dt,ζ,PGA) 104 | def Sa(ωk): 105 | xp=2*np.pi/np.array(T) 106 | fp=np.array(Sa_) 107 | return np.interp(ωk,xp,fp) 108 | sa=Sa(ωk) #时程反应谱 109 | s*=(st/sa) 110 | return A(t) 111 | 112 | accel=A_fit(t) 113 | PGA=70 114 | T,Sa=fft2spec(accel,dt,ζ,PGA) 115 | plt.plot(T,Sa) 116 | plt.plot(list(S.keys()),list(S.values())) 117 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/element/quad/TMQ.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy.sparse as spr 3 | 4 | from hyperstatic.core.fe_model.meta.plates.TMQ import get_binary_BDB 5 | from hyperstatic.core.fe_model.node import Node 6 | from hyperstatic.core.fe_model.element.quad import Quad 7 | from hyperstatic.core.fe_model.section.shell_section import ShellSection 8 | import quadpy 9 | 10 | class TMQ(Quad): 11 | def __init__(self,name:str,section:ShellSection,node_i:Node, node_j:Node, node_k:Node, node_l:Node): 12 | self.__section=section 13 | super(TMQ,self).__init__(name,node_i, node_j, node_k, node_l,12) 14 | 15 | def integrate_K(self): 16 | bBDBb,bBDBs=get_binary_BDB() 17 | # X=np.array([ 18 | # self.nodes[2].loc, 19 | # self.nodes[3].loc, 20 | # self.nodes[0].loc, 21 | # self.nodes[1].loc] 22 | # ) 23 | X=np.array([ 24 | self.nodes[0].loc, 25 | self.nodes[1].loc, 26 | self.nodes[2].loc, 27 | self.nodes[3].loc] 28 | ) 29 | X_=X.dot(self.local_csys.transform_matrix.T)[:,:2] 30 | print(*tuple(X_.reshape(X_.size))) 31 | E=self.__section.E 32 | mu=self.__section.mu 33 | t=self.__section.t 34 | def func(x): 35 | res=[] 36 | for xi,eta in zip(x[0],x[1]): 37 | res.append(bBDBb(E,mu,t,xi,eta,*tuple(X_.reshape(X_.size)))) 38 | return np.stack(res,axis=2) 39 | scheme = quadpy.c2.get_good_scheme(2) 40 | Kb = scheme.integrate( 41 | func, 42 | quadpy.c2.rectangle_points([-1.0, 1.0], [-1.0, 1.0]), 43 | ) 44 | def func(x): 45 | res=[] 46 | for xi,eta in zip(x[0],x[1]): 47 | res.append(bBDBs(E,mu,t,xi,eta,*tuple(X_.reshape(X_.size)))) 48 | return np.stack(res,axis=2) 49 | scheme = quadpy.c2.get_good_scheme(2) 50 | Ks = scheme.integrate( 51 | func, 52 | quadpy.c2.rectangle_points([-1.0, 1.0], [-1.0, 1.0]), 53 | ) 54 | return spr.csr_matrix(Ks+Kb) 55 | 56 | @property 57 | def transform_matrix(self): 58 | T=np.zeros((12,12)) 59 | T[:3,:3]=T[3:6,3:6]=T[6:9,6:9]=T[9:,9:]=self.local_csys.transform_matrix 60 | return spr.csr_matrix(T) 61 | 62 | if __name__=='__main__': 63 | from hyperstatic.core.fe_model.node import Node 64 | from hyperstatic.core.fe_model.material.isotropy import IsotropicMaterial 65 | from hyperstatic.core.fe_model.node import Node 66 | from time import time 67 | n1=Node("1",1,-1,0) 68 | n2=Node("2",1,1,0) 69 | n3=Node("3",-1,1,0) 70 | n4=Node("4",-1,-1,0) 71 | 72 | # n1=Node("1",-1,-1,0) 73 | # n2=Node("2",1,-1,0) 74 | # n3=Node("3",1,1,0) 75 | # n4=Node("4",-1,1,0) 76 | 77 | steel=IsotropicMaterial('mat',7.849e3,2e11,0.3,1.17e-5) #Q345 78 | section=ShellSection('sec',steel,0.25) 79 | ele=TMQ("ele",section,n1,n2,n3,n4) 80 | beg=time() 81 | K=ele.integrate_K() 82 | print(time()-beg) 83 | assert K.shape==(12,12) 84 | i=1 85 | print(K.toarray()[3*i,:]/1e8) 86 | 87 | -------------------------------------------------------------------------------- /tests/test_core/test_core_api/test_api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import sys 4 | import pytest 5 | from pytest import approx,raises 6 | 7 | import numpy as np 8 | import numpy.linalg as nl 9 | 10 | from hyperstatic.core import Api 11 | import logging 12 | 13 | class TestApi(): 14 | def test_cantilever_beam(self): 15 | path="./test" 16 | if sys.platform=="win32": 17 | path="c:\\test" 18 | 19 | api=Api(path) 20 | api.add_node("A",0,0,0) 21 | api.add_node("B",6,0,0) 22 | api.add_simple_beam("b","A","B",E=1.999e11,mu=0.3,A=4.265e-3,I3=6.572e-5,I2=3.301e-6,J=9.651e-8,rho=7849.0474) 23 | 24 | api.add_loadpattern("pat1") 25 | api.set_nodal_load("pat1","B",f3=-1e4) 26 | 27 | api.add_static_case("case1") 28 | api.add_case_pattern("case1","pat1",1.0) 29 | 30 | api.set_loadcase_nodal_restraint("case1","A",True,True,True,True,True,True) 31 | 32 | api.assemble() 33 | 34 | api.solve_static("case1") 35 | d=api.result_get_nodal_displacement("B","case1") 36 | 37 | assert d[2]==approx(-0.05519,rel=5e-2) 38 | assert d[4]==approx(0.0137,rel=5e-2) 39 | 40 | d=api.result_get_beam_deformation("b",1,"case1") 41 | assert d[1]==approx(-0.05519,rel=2e-2) 42 | assert d[4]==approx(-0.0137,rel=2e-2) 43 | d=api.result_get_beam_deformation("b",0.5,"case1") 44 | assert d[1]==approx(-0.0173,rel=2e-2) 45 | assert d[4]==approx(-0.01027,rel=2e-2) 46 | 47 | def test_cantilever_beam_with_distributed_load(self): 48 | path="./test" 49 | if sys.platform=="win32": 50 | path="c:\\test" 51 | 52 | api=Api(path) 53 | api.add_node("A",0,0,0) 54 | api.add_node("B",6,0,0) 55 | api.add_simple_beam("b","A","B",E=2e11,mu=0.3,A=0.0188,I2=4.023e-5,I3=4.771e-4,J=4.133e-6,rho=7.85e10) 56 | 57 | api.add_loadpattern("pat1") 58 | api.set_beam_load_distributed("pat1","b",qi2=-1e4) 59 | 60 | api.add_static_case("case1") 61 | api.add_case_pattern("case1","pat1",1.0) 62 | 63 | api.set_loadcase_nodal_restraint("case1","A",True,True,True,True,True,True) 64 | 65 | api.assemble() 66 | api.solve_static("case1") 67 | d=api.result_get_nodal_displacement("B","case1") 68 | 69 | assert d[2]==approx(-0.0046,rel=5e-2) 70 | 71 | def test_cantilever_beam_with_concentrated_load(self): 72 | path="./test" 73 | if sys.platform=="win32": 74 | path="c:\\test" 75 | 76 | api=Api(path) 77 | api.add_node("A",0,0,0) 78 | api.add_node("B",6,0,0) 79 | api.add_simple_beam("b","A","B",E=2e11,mu=0.3,A=0.0188,I2=4.023e-5,I3=4.771e-4,J=4.133e-6,rho=7.85e10) 80 | 81 | api.add_loadpattern("pat1") 82 | api.set_beam_load_concentrated("pat1","b",M3=1e4,r=0.75) 83 | 84 | api.add_static_case("case1") 85 | api.add_case_pattern("case1","pat1",1.0) 86 | 87 | api.set_loadcase_nodal_restraint("case1","A",True,True,True,True,True,True) 88 | 89 | api.assemble() 90 | 91 | api.solve_static("case1") 92 | d=api.result_get_nodal_displacement("B","case1") 93 | assert d[2]==approx(0.0018,rel=5e-2) 94 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/membranes/GQ12/__init__.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import sys 4 | 5 | import numpy as np 6 | import sympy as syp 7 | from sympy.utilities.autowrap import autowrap 8 | from hyperstatic.core.fe_model.meta.interpolate import Lagrange 9 | from hyperstatic.core.fe_model.meta.jacobi import J2D 10 | from hyperstatic.core.fe_model.meta.operator import L2,operator_dot 11 | from hyperstatic.core.fe_model.meta.plates import x1,y1,x2,y2,x3,y3,x4,y4,E,mu,t,xi,eta 12 | 13 | xi0=[1,1,-1,-1] 14 | eta0=[-1,1,1,-1] 15 | x0=[x1,x2,x3,x4] 16 | y0=[y1,y2,y3,y4] 17 | N0=[] 18 | Nut=[] 19 | Nvt=[] 20 | 21 | a1=sum([xi0[i]*x0[i] for i in range(4)])/4 22 | a2=sum([eta0[i]*x0[i] for i in range(4)])/4 23 | a3=sum([xi0[i]*eta0[i]*x0[i] for i in range(4)])/4 24 | b1=sum([xi0[i]*y0[i] for i in range(4)])/4 25 | b2=sum([eta0[i]*y0[i] for i in range(4)])/4 26 | b3=sum([xi0[i]*eta0[i]*y0[i] for i in range(4)])/4 27 | 28 | for i in range(4): 29 | N0.append(0.25*(1+xi0[i]*xi)*(1+eta0[i]*eta)) 30 | Nut.append((xi*(1-xi**2)*(b1+b3*eta0[i])*(1+eta0[i]*eta)+eta0[i]*(1-eta**2)*(b2+b3*xi0[i])*(1+xi0[i]*xi))/8) 31 | Nvt.append(-(xi*(1-xi**2)*(a1+a3*eta0[i])*(1+eta0[i]*eta)+eta0[i]*(1-eta**2)*(a2+a3*xi0[i])*(1+xi0[i]*xi))/8) 32 | 33 | N=syp.zeros(2,3*4) 34 | for i in range(4): 35 | N[0,i*3]=N0[i] 36 | N[1,i*3+1]=N0[i] 37 | N[0,i*3+2]=Nut[i] 38 | N[1,i*3+2]=Nvt[i] 39 | # N[0,i*3+2]=0 40 | # N[1,i*3+2]=0 41 | 42 | # E0=E/(1-mu**2) 43 | # mu0=mu/(1-mu) 44 | E0,mu0=E,mu 45 | D=syp.eye(3,3) 46 | D[0,0]=D[1,1]=1 47 | D[2,2]=(1-mu0)/2 48 | D[0,1]=D[1,0]=mu0 49 | D*=E0/(1-mu0**2) 50 | 51 | X=np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4],]) 52 | J=J2D(N0,X) 53 | 54 | # def L2iso(xi,eta): 55 | # x=[x1,x2,x3,x4] 56 | # y=[y1,y2,y3,y4] 57 | # x=sum([N0[i]*x[i] for i in range(4)]) 58 | # y=sum([N0[i]*y[i] for i in range(4)]) 59 | # dds=lambda f: syp.diff(f,xi) 60 | # ddt=lambda f: syp.diff(f,eta) 61 | # ddx=lambda f: ddt(y)*dds(f)-dds(y)*ddt(f) 62 | # ddy=lambda f: dds(x)*ddt(f)-ddt(x)*dds(f) 63 | # return np.array([ 64 | # [ddx,0], 65 | # [0,ddy], 66 | # [ddy,ddx]])/syp.det(J) 67 | 68 | def L2iso(xi,eta): 69 | x=[x1,x2,x3,x4] 70 | y=[y1,y2,y3,y4] 71 | x=sum([N0[i]*x[i] for i in range(4)]) 72 | y=sum([N0[i]*y[i] for i in range(4)]) 73 | diso= lambda f:syp.Matrix([[syp.diff(f,xi),syp.diff(f,eta)]]).T 74 | dnat= lambda f:syp.inv_quick(J)*diso(f) 75 | ddx=lambda f:dnat(f)[0] 76 | ddy=lambda f:dnat(f)[1] 77 | return np.array([ 78 | [ddx,0], 79 | [0,ddy], 80 | [ddy,ddx]]) 81 | 82 | B=operator_dot(L2iso(xi,eta),N) 83 | BDB=(B.T)*D*B 84 | BDB_=t*BDB*syp.det(J) 85 | 86 | def get_binary_BDB(): 87 | try: 88 | import metaGQ12 89 | bBDB=metaGQ12.autofunc_c 90 | except: 91 | raise Exception("Complile the cython code first!") 92 | return bBDB 93 | 94 | def generate_code(): 95 | tmp=os.path.dirname(os.path.realpath(__file__)) 96 | logging.info("first time calling, compiling ") 97 | autowrap(BDB_,args=[E,mu,t,xi,eta,x1,y1,x2,y2,x3,y3,x4,y4],backend='cython',tempdir=tmp,) 98 | 99 | if __name__=='__main__': 100 | generate_code() -------------------------------------------------------------------------------- /hyperstatic/app/design/GB/seismic/spectrum.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon Apr 10 14:02:33 2017 4 | 5 | @author: Dell 6 | """ 7 | import numpy as np 8 | #from matplotlib.font_manager import FontProperties 9 | from matplotlib import pyplot as plt 10 | 11 | class GB50010(object): 12 | def __init__(self,alpha_max,Tg,xi): 13 | gamma=0.9+(0.05-xi)/(0.3+6*xi) 14 | eta1=0.02+(0.05-xi)/(4+32*xi) 15 | eta1=eta1 if eta1>0 else 0 16 | eta2=1+(0.05-xi)/(0.08+1.6*xi) 17 | eta2=eta2 if eta2>0.55 else 0.55 18 | T=np.linspace(0,6,601) 19 | alpha=[] 20 | for t in T: 21 | if t<0.1: 22 | alpha.append(np.interp(t,[0,0.1],[0.45*alpha_max,eta2*alpha_max])) 23 | elif tnp.array: 29 | """Resolve beam deformation 30 | 31 | Args: 32 | name (str): name of beam 33 | loc (float): relative location, between [0,1] 34 | casename (str): name of loadcase 35 | step (int, optional): step. Defaults to 1. 36 | 37 | Returns: 38 | np.array: [x,w2,w3,theta] 39 | """ 40 | path=self.__workpath 41 | d=np.load(os.path.join(path,casename+".d.npy"))[step-1,:] # row-first 42 | hids=self.__assembly.get_beam_node_hids(name) 43 | mask=[] 44 | for i in hids: 45 | mask.extend(list(range(i*6,i*6+6))) 46 | N=self.__assembly.get_beam_interpolate(name,loc) 47 | N_=self.__assembly.get_beam_interpolate1(name,loc) 48 | dd=d[np.in1d(range(len(d)),mask)] 49 | T=self.__assembly.get_beam_transform_matrix(name) 50 | dd=T.dot(dd) 51 | axial=dd[np.in1d(range(12),[0,6])] 52 | shear2bend3=dd[np.in1d(range(12),[1,5,7,11])] 53 | shear3bend2=dd[np.in1d(range(12),[2,4,8,10])] 54 | bend3=dd[np.in1d(range(12),[5,11])] 55 | bend2=dd[np.in1d(range(12),[4,10])] 56 | torsion=dd[np.in1d(range(12),[3,9])] 57 | x=np.dot(N[:2],axial) 58 | w2=np.dot(N[2:6],shear2bend3) 59 | w3=np.dot(N[6:10],shear3bend2) 60 | theta=np.dot(N[10:],torsion) 61 | phi2=np.dot(N_[2:6],shear2bend3) 62 | phi3=np.dot(N_[6:10],shear3bend2) 63 | print(N_[2:6]) 64 | print(shear2bend3[2:]) 65 | return np.array([x,w2,w3,theta,phi2,phi3]) 66 | 67 | if __name__=="__main__": 68 | import logging 69 | import sys 70 | import os 71 | 72 | from hyperstatic.core.fe_model.assembly import Assembly 73 | from hyperstatic.core.fe_model.model import Model 74 | from hyperstatic.core.fe_model.load.pattern import LoadPattern 75 | from hyperstatic.core.fe_model.load.loadcase import ModalCase, StaticCase 76 | from hyperstatic.core.fe_solver.dynamic import ModalSolver 77 | from hyperstatic.core.fe_solver.static import StaticSolver 78 | path="./test" 79 | if sys.platform=="win32": 80 | path="c:\\test" 81 | 82 | model=Model() 83 | model.add_node("1",0,0,0) 84 | model.add_node("2",6,0,0) 85 | model.add_simple_beam("A","1","2",E=1.999e11,mu=0.3,A=4.265e-3,I3=6.572e-5,I2=3.301e-6,J=9.651e-8,rho=7849.0474) 86 | 87 | patt1=LoadPattern("pat1") 88 | patt1.set_nodal_load("2",0,0,-1e4,0,0,0) 89 | 90 | lc=StaticCase("case1") 91 | lc.add_pattern(patt1,1.0) 92 | lc.set_nodal_restraint("1",True,True,True,True,True,True) 93 | asb=Assembly(model,[lc]) 94 | asb.save(path,"test.asb") 95 | solver=StaticSolver(path,"test.asb") 96 | solver.solve_linear("case1") 97 | 98 | resolver=BeamResultResolver(path,"test.asb") 99 | d=resolver.resolve_beam_deformation("A",0.75,"case1") 100 | print(d) 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /hyperstatic/app/general/load/loadcase.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Mar 22 19:09:47 2017 4 | 5 | @author: Dell 6 | """ 7 | import uuid 8 | 9 | from hyperstatic.app.general.orm import LoadCase,LoadCaseStaticLinearSetting,LoadCase2ndSetting,LoadCase3ndSetting,\ 10 | LoadCaseModalSetting,LoadCaseResponseSpectrumSetting,LoadCaseTimeHistorySetting,LoadCaseBucklingSetting 11 | import logging 12 | 13 | def add_loadcase(self,name,case_type,weight_factor=0,**kwargs): 14 | """ 15 | Add material to model, if the name already exists, an exception will be raised 16 | 17 | param: 18 | name: name of material. 19 | type: 'static-linear','2nd','3rd','modal','response-spectrum','time-history','buckling' 20 | return: 21 | boolean, status of success. 22 | optional: 23 | [weight_factor]: factor of self weight. 24 | **kwargs: 25 | if type is '1st', the following parameters are available: 26 | E: float, elastic modulus 27 | mu: float, Poisson ratio 28 | """ 29 | try: 30 | if self.session.query(LoadCase).filter_by(name=name).first()!=None: 31 | raise Exception('Name already exists!') 32 | lc=LoadCase() 33 | lc.name=name 34 | lc.uuid=str(uuid.uuid1()) 35 | lc.case_type=case_type 36 | lc.weight_factor=weight_factor 37 | if case_type=='static-linear': 38 | setting=LoadCaseStaticLinearSetting() 39 | setting.loadcase_name=lc.name 40 | self.session.add(setting) 41 | if case_type=='2nd': 42 | setting=LoadCase2ndSetting() 43 | setting.loadcase_name=lc.name 44 | self.session.add(setting) 45 | if case_type=='3nd': 46 | setting=LoadCase3ndSetting() 47 | setting.loadcase_name=lc.name 48 | self.session.add(setting) 49 | if case_type=='modal': 50 | setting=LoadCaseModalSetting() 51 | setting.loadcase_name=lc.name 52 | self.session.add(setting) 53 | if case_type=='response-spectrum': 54 | setting=LoadCaseResponseSpectrumSetting() 55 | setting.loadcase_name=lc.name 56 | self.session.add(setting) 57 | if case_type=='time-history': 58 | setting=LoadCaseTimeHistorySetting() 59 | setting.loadcase_name=lc.name 60 | self.session.add(setting) 61 | if case_type=='buckling': 62 | setting=LoadCaseBucklingSetting() 63 | setting.loadcase_name=lc.name 64 | self.session.add(setting) 65 | self.session.add(lc) 66 | return lc.name 67 | except Exception as e: 68 | logging.info(str(e)) 69 | self.session.rollback() 70 | return False 71 | 72 | def set_loadcase_static_linear(self): 73 | pass 74 | 75 | def set_loadcase_2nd(self): 76 | pass 77 | 78 | def set_loadcase_3rd(self): 79 | pass 80 | 81 | def set_loadcase_modal(self,loadcase_name): 82 | pass 83 | 84 | def set_loadcase_response_spectrum(self): 85 | pass 86 | 87 | def set_loadcase_time_history(self): 88 | pass 89 | 90 | def set_loadcase_buckling(self): 91 | pass 92 | 93 | def get_loadcase_names(self): 94 | """ 95 | Get all the name of loadcases in the database 96 | 97 | returns: 98 | boolean, status of success, and list of loadcase names if successful. 99 | """ 100 | try: 101 | lcs=self.session.query(LoadCase) 102 | names=[lc.name for lc in lcs.all()] 103 | return names 104 | except Exception as e: 105 | logging.info(str(e)) 106 | self.session.rollback() 107 | return False 108 | 109 | def delete_loadcase(self,name): 110 | try: 111 | lc=self.session.query(LoadCase).filter_by(name=name) 112 | if lc is None: 113 | raise Exception("Loadcase section doen't exist!") 114 | self.session.delete(lc) 115 | except Exception as e: 116 | log.info(str(e)) 117 | self.session.rollback() 118 | return False -------------------------------------------------------------------------------- /hyperstatic/app/general/load/pattern.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Mar 22 19:09:47 2017 4 | 5 | @author: Dell 6 | """ 7 | import uuid 8 | 9 | from hyperstatic.app.general.orm import LoadCase,LoadCaseStaticLinearSetting,LoadCase2ndSetting,LoadCase3ndSetting,\ 10 | LoadCaseModalSetting,LoadCaseResponseSpectrumSetting,LoadCaseTimeHistorySetting,LoadCaseBucklingSetting 11 | import logging 12 | 13 | def add_loadcase(self,name,case_type,weight_factor=0,**kwargs): 14 | """ 15 | Add material to model, if the name already exists, an exception will be raised 16 | 17 | param: 18 | name: name of material. 19 | type: 'static-linear','2nd','3rd','modal','response-spectrum','time-history','buckling' 20 | return: 21 | boolean, status of success. 22 | optional: 23 | [weight_factor]: factor of self weight. 24 | **kwargs: 25 | if type is '1st', the following parameters are available: 26 | E: float, elastic modulus 27 | mu: float, Poisson ratio 28 | """ 29 | try: 30 | if self.session.query(LoadCase).filter_by(name=name).first()!=None: 31 | raise Exception('Name already exists!') 32 | lc=LoadCase() 33 | lc.name=name 34 | lc.uuid=str(uuid.uuid1()) 35 | lc.case_type=case_type 36 | lc.weight_factor=weight_factor 37 | if case_type=='static-linear': 38 | setting=LoadCaseStaticLinearSetting() 39 | setting.loadcase_name=lc.name 40 | self.session.add(setting) 41 | if case_type=='2nd': 42 | setting=LoadCase2ndSetting() 43 | setting.loadcase_name=lc.name 44 | self.session.add(setting) 45 | if case_type=='3nd': 46 | setting=LoadCase3ndSetting() 47 | setting.loadcase_name=lc.name 48 | self.session.add(setting) 49 | if case_type=='modal': 50 | setting=LoadCaseModalSetting() 51 | setting.loadcase_name=lc.name 52 | self.session.add(setting) 53 | if case_type=='response-spectrum': 54 | setting=LoadCaseResponseSpectrumSetting() 55 | setting.loadcase_name=lc.name 56 | self.session.add(setting) 57 | if case_type=='time-history': 58 | setting=LoadCaseTimeHistorySetting() 59 | setting.loadcase_name=lc.name 60 | self.session.add(setting) 61 | if case_type=='buckling': 62 | setting=LoadCaseBucklingSetting() 63 | setting.loadcase_name=lc.name 64 | self.session.add(setting) 65 | self.session.add(lc) 66 | return lc.name 67 | except Exception as e: 68 | logging.info(str(e)) 69 | self.session.rollback() 70 | return False 71 | 72 | def set_loadcase_static_linear(self): 73 | pass 74 | 75 | def set_loadcase_2nd(self): 76 | pass 77 | 78 | def set_loadcase_3rd(self): 79 | pass 80 | 81 | def set_loadcase_modal(self,loadcase_name): 82 | pass 83 | 84 | def set_loadcase_response_spectrum(self): 85 | pass 86 | 87 | def set_loadcase_time_history(self): 88 | pass 89 | 90 | def set_loadcase_buckling(self): 91 | pass 92 | 93 | def get_loadcase_names(self): 94 | """ 95 | Get all the name of loadcases in the database 96 | 97 | returns: 98 | boolean, status of success, and list of loadcase names if successful. 99 | """ 100 | try: 101 | lcs=self.session.query(LoadCase) 102 | names=[lc.name for lc in lcs.all()] 103 | return names 104 | except Exception as e: 105 | logging.info(str(e)) 106 | self.session.rollback() 107 | return False 108 | 109 | def delete_loadcase(self,name): 110 | try: 111 | lc=self.session.query(LoadCase).filter_by(name=name) 112 | if lc is None: 113 | raise Exception("Loadcase section doen't exist!") 114 | self.session.delete(lc) 115 | except Exception as e: 116 | log.info(str(e)) 117 | self.session.rollback() 118 | return False -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/element/quad/TMGQ.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy.sparse as spr 3 | from hyperstatic.core.fe_model.meta.membranes import GQ12 4 | from hyperstatic.core.fe_model.meta.plates import TMQ 5 | from hyperstatic.core.fe_model.node import Node 6 | from hyperstatic.core.fe_model.element.quad import Quad 7 | from hyperstatic.core.fe_model.section.shell_section import ShellSection 8 | import quadpy 9 | 10 | class TMGQ(Quad): 11 | def __init__(self,name:str,section:ShellSection,node_i:Node, node_j:Node, node_k:Node, node_l:Node): 12 | self.__section=section 13 | super(TMGQ,self).__init__(name,node_i, node_j, node_k, node_l,24) 14 | 15 | def integrate_K(self): 16 | X=np.array([ 17 | self.nodes[0].loc, 18 | self.nodes[1].loc, 19 | self.nodes[2].loc, 20 | self.nodes[3].loc] 21 | ) 22 | X_=X-self.local_csys.origin #not necessary 23 | X_=X_.dot(self.local_csys.transform_matrix.T)[:,:2] 24 | E=self.__section.E 25 | mu=self.__section.mu 26 | t=self.__section.t 27 | Km=np.zeros((12,12)) 28 | Kp=np.zeros((12,12)) 29 | if self.__section.ele_type=="membrane" or self.__section.ele_type=="shell": 30 | BDB=GQ12.get_binary_BDB() 31 | def func_m(x): 32 | res=[] 33 | for xi,eta in zip(x[0],x[1]): 34 | res.append(BDB(E,mu,t,xi,eta,*tuple(X_.reshape(X_.size)))) 35 | res=np.stack(res,axis=2) 36 | return res 37 | scheme = quadpy.c2.get_good_scheme(2) 38 | Km = scheme.integrate( 39 | func_m, 40 | quadpy.c2.rectangle_points([-1.0, 1.0], [-1.0, 1.0]), 41 | ) #12x12 42 | 43 | if self.__section.ele_type=="plate" or self.__section.ele_type=="shell": 44 | bBDBb,bBDBs=TMQ.get_binary_BDB() 45 | def func_b(x): 46 | res=[] 47 | for xi,eta in zip(x[0],x[1]): 48 | res.append(bBDBb(E,mu,t,xi,eta,*tuple(X_.reshape(X_.size)))) 49 | return np.stack(res,axis=2) 50 | scheme = quadpy.c2.get_good_scheme(2) 51 | Kb = scheme.integrate( 52 | func_b, 53 | quadpy.c2.rectangle_points([-1.0, 1.0], [-1.0, 1.0]), 54 | ) 55 | def func_s(x): 56 | res=[] 57 | for xi,eta in zip(x[0],x[1]): 58 | res.append(bBDBs(E,mu,t,xi,eta,*tuple(X_.reshape(X_.size)))) 59 | return np.stack(res,axis=2) 60 | scheme = quadpy.c2.get_good_scheme(2) 61 | Ks = scheme.integrate( 62 | func_s, 63 | quadpy.c2.rectangle_points([-1.0, 1.0], [-1.0, 1.0]), 64 | ) 65 | Kp=Ks+Kb 66 | 67 | K=np.zeros((24,24)) 68 | for i in range(4): 69 | for j in range(4): 70 | K[i*6+2:i*6+5,j*6+2:j*6+5]=Kp[i*3:i*3+3,j*3:j*3+3] 71 | K[ i*6:i*6+2, j*6:j*6+2]=Km[i*3:i*3+2,j*3:j*3+2] 72 | K[ i*6+5, j*6:j*6+2]=Km[ i*3+2,j*3:j*3+2] 73 | K[ i*6:i*6+2, j*6+5]=Km[i*3:i*3+2, j*3+2] 74 | K[ i*6+5, j*6+5]=Km[ i*3+2, j*3+2] 75 | return spr.csr_matrix(K) 76 | 77 | @property 78 | def transform_matrix(self): 79 | T=np.zeros((24,24)) 80 | for i in range(8): 81 | T[3*i:3*i+3,3*i:3*i+3]=self.local_csys.transform_matrix 82 | return spr.csr_matrix(T) 83 | 84 | if __name__=='__main__': 85 | from hyperstatic.core.fe_model.node import Node 86 | from hyperstatic.core.fe_model.material.isotropy import IsotropicMaterial 87 | from hyperstatic.core.fe_model.section.shell_section import ShellSection 88 | from hyperstatic.core.fe_model.node import Node 89 | 90 | # n1=Node("1",1,-1,0) 91 | # n2=Node("2",1,1,0) 92 | # n3=Node("3",-1,1,0) 93 | # n4=Node("4",-1,-1,0) 94 | 95 | n1=Node("1",1,-1,0) 96 | n2=Node("2",1,1,0) 97 | n3=Node("3",-1,1,0) 98 | n4=Node("4",-1,-1,0) 99 | 100 | steel=IsotropicMaterial('mat',7.849e3,2e11,0.3,1.17e-5) #Q345 101 | section=ShellSection('sec',steel,0.25,'shell') 102 | ele=TMGQ("ele",section,n1,n2,n3,n4) 103 | K=ele.integrate_K() 104 | assert K.shape==(24,24) 105 | print(K[14,12:18]/1e10) 106 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/beams/beam_eular/__init__.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import sympy as syp 3 | from sympy.utilities.autowrap import autowrap 4 | import scipy.sparse as spr 5 | 6 | #Axial 7 | xi=syp.symbols("xi") 8 | rho,E,A,l=syp.symbols("rho E A l") 9 | N1=0.5*(1-xi) 10 | N2=0.5*(1+xi) 11 | N=np.array([N1,N2]).reshape((1,2)) 12 | d_dxi=np.vectorize(lambda N:syp.diff(N,xi)) 13 | K=syp.Matrix(np.dot(d_dxi(N).T,d_dxi(N))) 14 | K=2*E*A/l*syp.integrate(K,xi) 15 | K=K.replace(xi,1)-K.replace(xi,-1) 16 | M=syp.Matrix(np.dot(N.T,N)) 17 | M=2*rho*A/l*syp.integrate(M,xi) 18 | M=M.replace(xi,1)-M.replace(xi,-1) 19 | 20 | bfuncK1=autowrap(K,args=[E,A,l],backend="cython") 21 | bfuncM1=autowrap(M,args=[rho,A,l],backend="cython") 22 | 23 | #Bending 24 | #2-axis 25 | xi=syp.symbols("xi") 26 | E,l,I=syp.symbols("E l I") 27 | N1=1-3*xi**2+2*xi**3 28 | N2=(xi-2*xi**2+xi**3)*l 29 | N3=3*xi**2-2*xi**3 30 | N4=(xi**3-xi**2)*l 31 | N=np.array([N1,N2,N3,N4]).reshape((1,4)) 32 | d2_dxi2=np.vectorize(lambda N:syp.diff(syp.diff(N,xi),xi)) 33 | K=np.dot(d2_dxi2(N).T,d2_dxi2(N)) 34 | K=syp.Matrix(K) 35 | K=E*I/l**3*syp.integrate(K,xi) 36 | K=K.replace(xi,1)-K.replace(xi,0) 37 | M=np.dot(N.T,N) 38 | M=syp.Matrix(M) 39 | M=rho*I/l**3*syp.integrate(M,xi) 40 | M=M.replace(xi,1)-M.replace(xi,0) 41 | bfuncK22=autowrap(K,args=[E,I,l],backend="cython") 42 | bfuncM22=autowrap(M,args=[rho,I,l],backend="cython") 43 | 44 | #3-axis 45 | N=np.array([-N1,N2,-N3,N4]).reshape((1,4)) #note the deflection w direction are different. 46 | d2_dxi2=np.vectorize(lambda N:syp.diff(syp.diff(N,xi),xi)) 47 | K=np.dot(d2_dxi2(N).T,d2_dxi2(N)) 48 | K=syp.Matrix(K) 49 | K=E*I/l**3*syp.integrate(K,xi) 50 | K=K.replace(xi,1)-K.replace(xi,0) 51 | M=np.dot(N.T,N) 52 | M=syp.Matrix(M) 53 | M=rho*I/l**3*syp.integrate(M,xi) 54 | M=M.replace(xi,1)-M.replace(xi,0) 55 | bfuncK23=autowrap(K,args=[E,I,l],backend="cython") 56 | bfuncM23=autowrap(M,args=[rho,I,l],backend="cython") 57 | 58 | #Torsion 59 | xi=syp.symbols("xi") 60 | G,J,l=syp.symbols("G J l") 61 | N1=0.5*(1-xi) 62 | N2=0.5*(1+xi) 63 | N=np.array([N1,N2]).reshape((1,2)) 64 | d_dxi=np.vectorize(lambda N:syp.diff(N,xi)) 65 | K=syp.Matrix(np.dot(d_dxi(N).T,d_dxi(N))) 66 | K=syp.integrate(2*G*J/l*K,xi) 67 | K=K.replace(xi,1)-K.replace(xi,-1) 68 | M=syp.Matrix(np.dot(N.T,N)) 69 | M=2*rho*J/l*syp.integrate(M,xi) 70 | M=M.replace(xi,1)-M.replace(xi,-1) 71 | bfuncK3=autowrap(K,args=[G,J,l],backend="cython") 72 | bfuncM3=autowrap(M,args=[rho,J,l],backend="cython") 73 | 74 | def K(E,G,A,I2,I3,J,l): 75 | Kdata=[] 76 | Krow=[] 77 | Kcol=[] 78 | K1=bfuncK1(E,A,l) 79 | K22=bfuncK22(E,I2,l) 80 | K23=bfuncK23(E,I3,l) 81 | K3=bfuncK3(G,J,l) 82 | for i in range(2): 83 | for j in range(2): 84 | Kdata.append(K1[i,j]) 85 | Krow.append(i*6) 86 | Kcol.append(j*6) 87 | for i in range(4): 88 | for j in range(4): 89 | Kdata.append(K22[i,j]) 90 | Krow.append(i//2*6+i%2*4+1) 91 | Kcol.append(j//2*6+j%2*4+1) 92 | for i in range(4): 93 | for j in range(4): 94 | Kdata.append(K23[i,j]) 95 | Krow.append(i//2*6+i%2*2+2) 96 | Kcol.append(j//2*6+j%2*2+2) 97 | for i in range(2): 98 | for j in range(2): 99 | Kdata.append(K3[i,j]) 100 | Krow.append(i*6+3) 101 | Kcol.append(j*6+3) 102 | return spr.coo_matrix((Kdata,(Krow,Kcol)),shape=(12,12)) 103 | 104 | def M(rho,A,I2,I3,J,l): 105 | Mdata=[] 106 | Mrow=[] 107 | Mcol=[] 108 | M1=bfuncM1(rho,A,l) 109 | M22=bfuncM22(rho,I2,l) 110 | M23=bfuncM23(rho,I3,l) 111 | M3=bfuncM3(rho,J,l) 112 | for i in range(2): 113 | for j in range(2): 114 | Mdata.append(M1[i,j]) 115 | Mrow.append(i*6) 116 | Mcol.append(j*6) 117 | for i in range(4): 118 | for j in range(4): 119 | Mdata.append(M22[i,j]) 120 | Mrow.append(i//2*6+i%2*4+1) 121 | Mcol.append(j//2*6+j%2*4+1) 122 | for i in range(4): 123 | for j in range(4): 124 | Mdata.append(M23[i,j]) 125 | Mrow.append(i//2*6+i%2*2+2) 126 | Mcol.append(j//2*6+j%2*2+2) 127 | for i in range(2): 128 | for j in range(2): 129 | Mdata.append(M3[i,j]) 130 | Mrow.append(i*6+3) 131 | Mcol.append(j*6+3) 132 | return spr.coo_matrix((Mdata,(Mrow,Mcol)),shape=(12,12)) -------------------------------------------------------------------------------- /hyperstatic/app/viz/viz_core/model_basic.py: -------------------------------------------------------------------------------- 1 | 2 | from datetime import datetime 3 | import pickle 4 | import numpy as np 5 | 6 | from hyperstatic.core import Api 7 | from random import uniform as u 8 | from vedo import Points, Line, Lines, Arrows, Plotter, Cone,Text2D,Mesh 9 | from vedo.pyplot import histogram 10 | import os 11 | from hyperstatic.app.viz.viz_core import ViewerBase 12 | 13 | class BasicViewer(ViewerBase): 14 | def __init__(self,workpath,filename,qtWidget=None): 15 | super(BasicViewer, self).__init__(workpath,filename,qtWidget) 16 | self.setup_gui() 17 | self.__scale=1 18 | 19 | ##GUI 20 | def setup_gui(self): 21 | plt=self.plotter 22 | self.__btn_node=plt.addButton( 23 | self.toggle_node, 24 | bc=("b6","r6"), 25 | pos=(0.6,0.15), 26 | states=("show_node","hide_node"), 27 | font="Normografo", 28 | size=12, 29 | ) 30 | self.__btn_beam=plt.addButton( 31 | self.toggle_beam, 32 | bc=("r6","b6"), 33 | pos=(0.6,0.1), 34 | states=("hide_beam","show_beam"), 35 | font="Normografo", 36 | size=12, 37 | ) 38 | self.__btn_shell=plt.addButton( 39 | self.toggle_shell, 40 | bc=("r6","b6"), 41 | pos=(0.6,0.05), 42 | states=("hide_shell","show_shell"), 43 | font="Normografo", 44 | size=12, 45 | ) 46 | 47 | def slide_scale(self,widget,event): 48 | self.__scale=widget.GetRepresentation().GetValue() 49 | 50 | def toggle_node(self): 51 | if not self.vnodes==None: 52 | if self.__btn_node.status()=="hide_node": 53 | self.vnodes.off() 54 | else: 55 | self.vnodes.on() 56 | self.__btn_node.switch() 57 | 58 | def toggle_beam(self): 59 | if not self.vbeams==None: 60 | if self.__btn_beam.status()=="hide_beam": 61 | 62 | self.vbeams.off() 63 | else: 64 | self.vbeams.on() 65 | self.__btn_beam.switch() 66 | 67 | def toggle_shell(self): 68 | if not self.vshells==None: 69 | if self.__btn_shell.status()=="hide_shell": 70 | self.vshells.off() 71 | else: 72 | self.vshells.on() 73 | self.__btn_shell.switch() 74 | 75 | def toggle_node_name(self): 76 | self.reset() 77 | 78 | def toggle_node_csys(self): 79 | self.reset() 80 | 81 | def toggle_beam_name(self): 82 | self.reset() 83 | 84 | def toggle_beam_release(self): 85 | self.reset() 86 | 87 | def toggle_beam_section(self): 88 | self.reset() 89 | 90 | def toggle_beam_csys(self): 91 | self.reset() 92 | 93 | def toggle_beam_load(self): 94 | self.reset() 95 | 96 | def init_nodal_load(self): 97 | api=self.api 98 | arrow_starts=[] 99 | arrow_ends=[] 100 | loads=[] 101 | f_scals=[] 102 | m_scals=[] 103 | f_value=[] 104 | m_value=[] 105 | load_dict=api.get_all_nodal_load("pat1") 106 | for n in api.get_node_names(): 107 | if n in api.get_all_nodal_load("pat1").keys(): 108 | x,y,z=api.get_node_location(n) 109 | f1,f2,f3,m1,m2,m3=tuple(load_dict[n]) 110 | f=(f1**2+f2**2+f3**2)**0.5 111 | [f_value.append(f) for i in range(16)] 112 | m_value.append((m1**2+m2**2+m3**2)**0.5) 113 | f_scals.append(f) 114 | loads.append([f1,f2,f3,m1,m2,m3]) 115 | arrow_ends.append((x,y,z)) 116 | scale=self.scale/max(f_scals)*0.1 117 | for e,l in zip(arrow_ends,loads): 118 | arrow_starts.append((e[0]-l[0]*scale,e[1]-l[1]*scale,e[2]-l[2]*scale)) 119 | 120 | self.__vnodeload=Arrows(arrow_starts,arrow_ends,s=0.5,res=3) 121 | self.__vnodeload.cmap('viridis', f_value).addScalarBar(title="Nodal load(N)",pos=(0.8,0.4)) #"jet", "PuOr", "viridis" 122 | self.__vnodeload.off() 123 | self.__vnodeload.scalarbar.VisibilityOff() 124 | self.actors+=[self.__vnodeload] 125 | 126 | if __name__=="__main__": 127 | path=r"C:\Users\HZJ\Desktop\ghdev\analysis" 128 | viewer=BasicViewer(path,"assembly") 129 | viewer.run() 130 | -------------------------------------------------------------------------------- /hyperstatic/app/general/environment/project.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Mar 29 13:43:53 2018 4 | 5 | @author: Dell 6 | """ 7 | from hyperstatic.app.general.orm import Config 8 | import logging 9 | 10 | def get_project_name(self): 11 | """ 12 | return: 13 | status of success. 14 | """ 15 | try: 16 | config=self.session.query(Config).first() 17 | return config.project_name 18 | except Exception as e: 19 | logging.info(str(e)) 20 | return None 21 | 22 | def get_author(self): 23 | """ 24 | return: 25 | status of success. 26 | """ 27 | try: 28 | config=self.session.query(Config).first() 29 | return config.author 30 | except Exception as e: 31 | logging.info(str(e)) 32 | return False 33 | 34 | def get_unit(self): 35 | """ 36 | return: 37 | status of success. 38 | """ 39 | try: 40 | config=self.session.query(Config).first() 41 | return config.unit 42 | except Exception as e: 43 | logging.info(str(e)) 44 | return False 45 | 46 | def get_description(self): 47 | """ 48 | return: 49 | status of success. 50 | """ 51 | try: 52 | config=self.session.query(Config).first() 53 | return config.description 54 | except Exception as e: 55 | logging.info(str(e)) 56 | return False 57 | 58 | def get_tolerance(self): 59 | """ 60 | return: 61 | status of success. 62 | """ 63 | try: 64 | scale=self.scale() 65 | config=self.session.query(Config).first() 66 | return config.tolerance/scale['L'] 67 | except Exception as e: 68 | logging.info(str(e)) 69 | return False 70 | 71 | def set_project_name(self,name): 72 | """ 73 | params: 74 | name: str, project name, no more than 32 chars 75 | return: 76 | status of success. 77 | """ 78 | try: 79 | assert(type(name)==str and len(name)<32) 80 | config=self.session.query(Config).first() 81 | config.project_name=name 82 | self.session.add(config) 83 | return True 84 | except Exception as e: 85 | logging.info(str(e)) 86 | self.session.rollback() 87 | return False 88 | 89 | def set_author(self,author): 90 | """ 91 | params: 92 | author: str, project name, no more than 32 chars 93 | return: 94 | status of success. 95 | """ 96 | try: 97 | assert(type(author)==str and len(author)<32) 98 | config=self.session.query(Config).first() 99 | config.author=author 100 | self.session.add(config) 101 | return True 102 | except Exception as e: 103 | logging.info(str(e)) 104 | self.session.rollback() 105 | return False 106 | 107 | def set_unit(self,unit): 108 | """ 109 | params: 110 | unit: str, should be 'N_m_C','N_mm_C','kN_m_C' or 'kN_mm_C' 111 | return: 112 | status of success. 113 | """ 114 | try: 115 | assert(unit in ['N_m_C','N_mm_C','kN_m_C','kN_mm_C']) 116 | config=self.session.query(Config).first() 117 | config.unit=unit 118 | self.session.add(config) 119 | return True 120 | except Exception as e: 121 | logging.info(str(e)) 122 | self.session.rollback() 123 | return False 124 | 125 | def set_description(self,text): 126 | """ 127 | params: 128 | text: str, description. 129 | return: 130 | status of success. 131 | """ 132 | try: 133 | assert(type(text)==str) 134 | config=self.session.query(Config).first() 135 | config.description=text 136 | self.session.add(config) 137 | return True 138 | except Exception as e: 139 | logging.info(str(e)) 140 | self.session.rollback() 141 | return False 142 | 143 | def set_tolerance(self,tol): 144 | """ 145 | Set model tolerance, related to current unit configuration 146 | 147 | params: 148 | tol: float, tolerance. 149 | return: 150 | status of success. 151 | """ 152 | try: 153 | assert(type(tol)==float) 154 | scale=self.scale() 155 | config=self.session.query(Config).first() 156 | config.tolerance=tol*scale['L'] 157 | self.session.add(config) 158 | return True 159 | except Exception as e: 160 | logging.info(str(e)) 161 | self.session.rollback() 162 | return False -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | try: 3 | from setuptools import setup 4 | from setuptools import find_packages 5 | from setuptools import Extension 6 | except ImportError: 7 | from distutils.core import setup 8 | from distutils.extension import Extension 9 | from Cython.Build import cythonize,build_ext 10 | from Cython.Distutils import build_ext 11 | 12 | cy_opts = {} 13 | import numpy as np 14 | 15 | VERSION = '0.2.0' 16 | 17 | elm_path=os.path.dirname(os.path.realpath(__file__)) 18 | elm_path=os.path.join(elm_path,'hyperstatic') 19 | elm_path=os.path.join(elm_path,'core') 20 | elm_path=os.path.join(elm_path,'fe_model') 21 | elm_path=os.path.join(elm_path,'meta') 22 | 23 | ext_mods = [ 24 | Extension('metaT9', [ 25 | os.path.join(elm_path,'membranes','T9','metaT9.pyx'), 26 | os.path.join(elm_path,'membranes','T9','wrapped_code_0.c') 27 | ], 28 | include_dirs=[np.get_include()], 29 | library_dirs=[], 30 | libraries=[], 31 | extra_compile_args=['-std=c99'], 32 | extra_link_args=[] 33 | ), 34 | Extension('metaGQ12', [ 35 | os.path.join(elm_path,'membranes','GQ12','metaGQ12.pyx'), 36 | os.path.join(elm_path,'membranes','GQ12','wrapped_code_0.c') 37 | ], 38 | include_dirs=[np.get_include()], 39 | library_dirs=[], 40 | libraries=[], 41 | extra_compile_args=['-std=c99'], 42 | extra_link_args=[] 43 | ), 44 | Extension('metaDKT', [ 45 | os.path.join(elm_path,'plates','metaDKT','metaDKT.pyx'), 46 | os.path.join(elm_path,'plates','metaDKT','wrapped_code_0.c') 47 | ], 48 | include_dirs=[np.get_include()], 49 | library_dirs=[], 50 | libraries=[], 51 | extra_compile_args=['-std=c99'], 52 | extra_link_args=[] 53 | ), 54 | Extension('metaDKQ', [ 55 | os.path.join(elm_path,'plates','metaDKQ','metaDKQ.pyx'), 56 | os.path.join(elm_path,'plates','metaDKQ','wrapped_code_0.c') 57 | ], 58 | include_dirs=[np.get_include()], 59 | library_dirs=[], 60 | libraries=[], 61 | extra_compile_args=['-std=c99'], 62 | extra_link_args=[] 63 | ), 64 | Extension('metaTMQb', [ 65 | os.path.join(elm_path,'plates','TMQ','metaTMQb.pyx'), 66 | os.path.join(elm_path,'plates','TMQ','wrapped_code_0.c') 67 | ], 68 | include_dirs=[np.get_include()], 69 | library_dirs=[], 70 | libraries=[], 71 | extra_compile_args=['-std=c99'], 72 | extra_link_args=[] 73 | ), 74 | Extension('metaTMQs', [ 75 | os.path.join(elm_path,'plates','TMQ','metaTMQs.pyx'), 76 | os.path.join(elm_path,'plates','TMQ','wrapped_code_1.c') 77 | ], 78 | include_dirs=[np.get_include()], 79 | library_dirs=[], 80 | libraries=[], 81 | extra_compile_args=['-std=c99'], 82 | extra_link_args=[] 83 | ), 84 | ] 85 | 86 | setup( 87 | name='Hyperstatic', 88 | version=VERSION, 89 | author='Zhuoju Huang', 90 | author_email='zhuoju36@hotmail.com', 91 | license='MIT', 92 | description='package for structural engineering', 93 | packages=find_packages(), 94 | zip_safe=False, 95 | python_requires=">=3.6", 96 | install_requires=[ 97 | 'numpy>=1.21', 98 | 'scipy>=1.7', 99 | 'quadpy>=0.16', 100 | 'vedo>=2022.2.3', 101 | 'cython>=0.29' 102 | ], 103 | classifiers=[ 104 | # How mature is this project? Common values are 105 | # 3 - Alpha 106 | # 4 - Beta 107 | # 5 - Production/Stable 108 | 'Development Status :: 3 - Alpha', 109 | 110 | # Indicate who your project is intended for 111 | 'Intended Audience :: Developers', 112 | 'Intended Audience :: Education', 113 | 'Intended Audience :: Manufacturing', 114 | 'Topic :: Education', 115 | 'Topic :: Scientific/Engineering', 116 | 117 | # Pick your license as you wish (should match "license" above) 118 | 'License :: OSI Approved :: MIT License', 119 | 120 | # Specify the Python versions you support here. In particular, ensure 121 | # that you indicate whether you support Python 2, Python 3 or both. 122 | 'Programming Language :: Python :: 3', 123 | 'Programming Language :: Python :: 3.6', 124 | 'Programming Language :: Python :: 3.7', 125 | 'Programming Language :: Python :: 3.8', 126 | 'Programming Language :: Python :: 3.9', 127 | 'Programming Language :: Python :: 3.10', 128 | ], 129 | url='https://github.com/zhuoju36/Hyperstatic', 130 | cmdclass={'build_ext': build_ext}, 131 | ext_modules=cythonize(ext_mods, **cy_opts), 132 | ) -------------------------------------------------------------------------------- /hyperstatic/app/viz/viz_core/model_load.py: -------------------------------------------------------------------------------- 1 | 2 | from datetime import datetime 3 | import pickle 4 | import numpy as np 5 | 6 | from hyperstatic.core import Api 7 | from random import uniform as u 8 | from vedo import Points, Line, Lines, Arrows, Plotter, Cone,Text2D,Mesh 9 | from vedo.pyplot import histogram 10 | import os 11 | from hyperstatic.app.viz.viz_core import ViewerBase 12 | 13 | class LoadViewer(ViewerBase): 14 | def __init__(self,workpath,filename): 15 | super(LoadViewer, self).__init__(workpath,filename) 16 | self.init_nodal_load() 17 | self.setup_gui() 18 | 19 | ##GUI 20 | def setup_gui(self): 21 | plt=self.plotter 22 | self.__btn_node=plt.addButton( 23 | self.toggle_node, 24 | bc=("b6","r6"), 25 | pos=(0.6,0.15), 26 | states=("show_node","hide_node"), 27 | font="san-serif", 28 | size=12, 29 | ) 30 | self.__btn_nodal_load=plt.addButton( 31 | self.toggle_nodal_load, 32 | bc=("b6","r6"), 33 | pos=(0.75,0.15), 34 | states=("show_nodal_load","hide_nodal_load"), 35 | font="san-serif", 36 | size=12, 37 | ) 38 | self.__btn_beam=plt.addButton( 39 | self.toggle_beam, 40 | bc=("r6","b6"), 41 | pos=(0.6,0.1), 42 | states=("hide_beam","show_beam"), 43 | font="san-serif", 44 | size=12, 45 | ) 46 | self.__btn_shell=plt.addButton( 47 | self.toggle_shell, 48 | bc=("r6","b6"), 49 | pos=(0.6,0.05), 50 | states=("hide_shell","show_shell"), 51 | font="san-serif", 52 | size=12, 53 | ) 54 | 55 | def slide_scale(self,widget,event): 56 | self.__scale=widget.GetRepresentation().GetValue() 57 | 58 | def toggle_node(self): 59 | if self.__btn_node.status()=="hide_node": 60 | self.vnodes.off() 61 | else: 62 | self.vnodes.on() 63 | self.__btn_node.switch() 64 | 65 | def toggle_beam(self): 66 | if self.__btn_beam.status()=="hide_beam": 67 | self.vbeams.off() 68 | else: 69 | self.vshells.on() 70 | self.__btn_beam.switch() 71 | 72 | def toggle_shell(self): 73 | if self.__btn_shell.status()=="hide_shell": 74 | self.vshells.off() 75 | else: 76 | self.vshells.on() 77 | self.__btn_shell.switch() 78 | 79 | def toggle_node_name(self): 80 | self.reset() 81 | 82 | def toggle_node_csys(self): 83 | self.reset() 84 | 85 | def toggle_nodal_load(self): 86 | if self.__btn_nodal_load.status()=="hide_nodal_load": 87 | self.__vnodeload.off() 88 | self.__vnodeload.scalarbar.VisibilityOff() 89 | else: 90 | self.__vnodeload.on() 91 | self.__vnodeload.scalarbar.VisibilityOn() 92 | self.__btn_nodal_load.switch() 93 | 94 | def toggle_beam_name(self): 95 | self.reset() 96 | 97 | def toggle_beam_release(self): 98 | self.reset() 99 | 100 | def toggle_beam_section(self): 101 | self.reset() 102 | 103 | def toggle_beam_csys(self): 104 | self.reset() 105 | 106 | def toggle_beam_load(self): 107 | self.reset() 108 | 109 | def init_nodal_load(self): 110 | api=self.api 111 | arrow_starts=[] 112 | arrow_ends=[] 113 | loads=[] 114 | f_scals=[] 115 | m_scals=[] 116 | f_value=[] 117 | m_value=[] 118 | load_dict=api.get_all_nodal_load("pat1") 119 | for n in api.get_node_names(): 120 | if n in api.get_all_nodal_load("pat1").keys(): 121 | x,y,z=api.get_node_location(n) 122 | f1,f2,f3,m1,m2,m3=tuple(load_dict[n]) 123 | f=(f1**2+f2**2+f3**2)**0.5 124 | [f_value.append(f) for i in range(16)] 125 | m_value.append((m1**2+m2**2+m3**2)**0.5) 126 | f_scals.append(f) 127 | loads.append([f1,f2,f3,m1,m2,m3]) 128 | arrow_ends.append((x,y,z)) 129 | if max(f_scals)==0: 130 | scale=1 131 | else: 132 | scale=abs(self.scale/max(f_scals)*0.2) 133 | for e,l in zip(arrow_ends,loads): 134 | arrow_starts.append((e[0]-l[0]*scale,e[1]-l[1]*scale,e[2]-l[2]*scale)) 135 | 136 | self.__vnodeload=Arrows(arrow_starts,arrow_ends,s=0.5,res=3) 137 | self.__vnodeload.cmap('viridis', f_value).addScalarBar(title="Nodal load(N)",pos=(0.8,0.4)) #"jet", "PuOr", "viridis" 138 | self.__vnodeload.off() 139 | self.__vnodeload.scalarbar.VisibilityOff() 140 | self.actors['node_loads']=self.__vnodeload 141 | 142 | if __name__=="__main__": 143 | path=r"C:\Users\HZJ\Desktop\ghdev\analysis" 144 | viewer=LoadViewer(path,"assembly") 145 | viewer.run() 146 | -------------------------------------------------------------------------------- /hyperstatic/core/fe_model/meta/plates/metaDKQ/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sympy as syp 3 | from sympy.utilities.autowrap import autowrap 4 | import numpy as np 5 | from hyperstatic.core.fe_model.meta.plates import x1,y1,x2,y2,x3,y3,x4,y4,E,mu,t,xi,eta 6 | from hyperstatic.core.fe_model.meta.operator import operator_dot 7 | from hyperstatic.core.fe_model.meta.jacobi import J2D 8 | 9 | x12=x1-x2 10 | x23=x2-x3 11 | x34=x3-x4 12 | x41=x4-x1 13 | y12=y1-y2 14 | y23=y2-y3 15 | y34=y3-y4 16 | y41=y4-y1 17 | 18 | x=[x12,x23,x34,x41] #xij 19 | y=[y12,y23,y34,y41] #yij 20 | l2=[x12**2+y12**2,x23**2+y23**2,x34**2+y34**2,x41**2+y41**2] 21 | 22 | a=syp.zeros(1,4) 23 | b=syp.zeros(1,4) 24 | c=syp.zeros(1,4) 25 | d=syp.zeros(1,4) 26 | e=syp.zeros(1,4) 27 | 28 | for ij,k in zip([0,1,2,3],[0,1,2,3]): 29 | a[k]= -x[ij]/l2[ij] 30 | b[k]= 0.75*x[ij]*y[ij]/l2[ij] 31 | c[k]= (0.25*x[ij]**2-0.5*y[ij]**2)/l2[ij] 32 | d[k]= -y[ij]/l2[ij] 33 | e[k]= (-0.5*x[ij]**2+0.25*y[ij]**2)/l2[ij] 34 | 35 | a5,a6,a7,a8=tuple(a) 36 | b5,b6,b7,b8=tuple(b) 37 | c5,c6,c7,c8=tuple(c) 38 | d5,d6,d7,d8=tuple(d) 39 | e5,e6,e7,e8=tuple(e) 40 | 41 | # xi0 =[-1,1,1,-1] 42 | # eta0=[-1,-1,1,1] 43 | N1=-0.25*(1-xi)*(1-eta)*(1+xi+eta) 44 | N2=-0.25*(1+xi)*(1-eta)*(1-xi+eta) 45 | N3=-0.25*(1+xi)*(1+eta)*(1-xi-eta) 46 | N4=-0.25*(1-xi)*(1+eta)*(1+xi-eta) 47 | # N5=0.5*(1-eta**2)*(1+xi) 48 | # N6=0.5*(1-xi**2)*(1+eta) 49 | # N7=0.5*(1-eta**2)*(1-xi) 50 | # N8=0.5*(1-xi**2)*(1-eta) 51 | N5=0.5*(1-xi**2)*(1-eta) 52 | N6=0.5*(1-eta**2)*(1+xi) 53 | N7=0.5*(1-xi**2)*(1+eta) 54 | N8=0.5*(1-eta**2)*(1-xi) 55 | 56 | Hx1=1.5*(a5*N5-a8*N8) 57 | Hx2=b5*N5+b8*N8 58 | Hx3=N1-c5*N5-c8*N8 59 | Hy1=1.5*(d5*N5-d8*N8) 60 | Hy2=-N1+e5*N5+e8*N8 61 | Hy3=-b5*N5-b8*N8 62 | 63 | Hx4=1.5*(a6*N6-a5*N5) 64 | Hx5=b6*N6+b5*N5 65 | Hx6=N2-c6*N6-c5*N5 66 | Hy4=1.5*(d6*N6-d5*N5) 67 | Hy5=-N2+e6*N6+e5*N5 68 | Hy6=-b6*N6-b5*N5 69 | 70 | Hx7=1.5*(a7*N7-a6*N6) 71 | Hx8=b7*N7+b6*N6 72 | Hx9=N3-c7*N7-c6*N6 73 | Hy7=1.5*(d7*N7-d6*N6) 74 | Hy8=-N3+e7*N7+e6*N6 75 | Hy9=-b7*N7-b6*N6 76 | 77 | Hx10=1.5*(a8*N8-a7*N7) 78 | Hx11=b8*N8+b7*N7 79 | Hx12=N4-c8*N8-c7*N7 80 | Hy10=1.5*(d8*N8-d7*N7) 81 | Hy11=-N4+e8*N8+e7*N7 82 | Hy12=-b8*N8-b7*N7 83 | 84 | Hx=syp.Array([Hx1,Hx2,Hx3,Hx4,Hx5,Hx6,Hx7,Hx8,Hx9,Hx10,Hx11,Hx12]) 85 | Hy=syp.Array([Hy1,Hy2,Hy3,Hy4,Hy5,Hy6,Hy7,Hy8,Hy9,Hy10,Hy11,Hy12]) 86 | H=syp.Array([Hx,Hy]) 87 | 88 | x21=x2-x1 89 | y21=y2-y1 90 | x32=x3-x2 91 | y32=y3-y2 92 | x42=x4-x2 93 | x31=x3-x1 94 | y42=y4-y2 95 | y31=y3-y1 96 | 97 | J11=0.25*(x21+x34+eta*(x12+x34)) 98 | J12=0.25*(y21+y34+eta*(y12+y34)) 99 | J21=0.25*(x32+x41+xi*(x12+x34)) 100 | J22=0.25*(y32+y41+xi*(y12+y34)) 101 | 102 | J=syp.Matrix([[J11,J12],[J21,J22]]) 103 | 104 | detJ=1/8*(y42*x31-y31*x42)+xi/8*(y34*x21-y21*x34)+eta/8*(y41*x32-y32*x41) 105 | j11=J11/detJ 106 | j12=-J12/detJ 107 | j21=-J21/detJ 108 | j22=J22/detJ 109 | 110 | ddx=lambda f : syp.diff(f,xi) 111 | ddy=lambda f : syp.diff(f,eta) 112 | B=syp.Matrix( 113 | [j11*ddx(Hx)+j12*ddy(Hx), 114 | j21*ddx(Hy)+j22*ddy(Hy), 115 | j11*ddx(Hy)+j12*ddy(Hy)+j21*ddx(Hx)+j22*ddy(Hx)]) 116 | 117 | D=syp.eye(3,3) 118 | D[0,0]=D[1,1]=1 119 | D[2,2]=(1-mu)/2 120 | D[0,1]=D[1,0]=mu 121 | D*=E*t**3/12/(1-mu**2) 122 | 123 | # X=np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4],]) 124 | # J=J2D([N1,N2,N3,N4],X) 125 | 126 | # def L0iso(xi,eta): 127 | # # _x=[x1,x2,x3,x4,(x1+x2)/2,(x2+x3)/2,(x3+x4)/2,(x4+x1)/2] 128 | # # _y=[y1,y2,y3,y4,(y1+y2)/2,(y2+y3)/2,(y3+y4)/2,(y4+y1)/2] 129 | # # _x=sum([H[i]*x[i] for i in range(8)]) 130 | # # _y=sum([H[i]*y[i] for i in range(8)]) 131 | # diso= lambda f:syp.Matrix([[syp.diff(f,xi),syp.diff(f,eta)]]).T 132 | # dnat= lambda f:syp.inv_quick(J)*diso(f) 133 | # ddx=lambda f:dnat(f)[0] 134 | # ddy=lambda f:dnat(f)[1] 135 | # return np.array([ 136 | # [ddx,0], 137 | # [0,ddy], 138 | # [ddy,ddx]]) 139 | 140 | # N=syp.zeros(3,12) 141 | # N[:,:3]=syp.eye(3,3)*N1 142 | # N[:,3:6]=syp.eye(3,3)*N2 143 | # N[:,6:9]=syp.eye(3,3)*N3 144 | # N[:,9:12]=syp.eye(3,3)*N4 145 | # B=operator_dot(L0iso(xi,eta),H) 146 | 147 | BDB=B.T*D*B*syp.det(J) 148 | 149 | def get_binary_BDB(): 150 | try: 151 | import metaDKQ 152 | bBDB=metaDKQ.autofunc_c 153 | except: 154 | raise Exception("Complile the cython code first!") 155 | return bBDB 156 | 157 | def generate_code(): 158 | tmp=os.path.dirname(os.path.realpath(__file__)) 159 | autowrap(BDB,args=[E,mu,t,xi,eta,x1,y1,x2,y2,x3,y3,x4,y4],backend='cython',tempdir=tmp) 160 | name='metaDKQ' 161 | os.rename(os.path.join(tmp,'wrapper_module_0.c'),os.path.join(tmp,name+'.c')) 162 | os.rename(os.path.join(tmp,'wrapper_module_0.pyx'),os.path.join(tmp,name+'.pyx')) 163 | search_text = "wrapper_module_0" 164 | replace_text = name 165 | with open(os.path.join(tmp,name+'.c'), 'r',encoding='UTF-8') as file: 166 | data = file.read() 167 | data = data.replace(search_text, replace_text) 168 | with open(os.path.join(tmp,name+'.c'), 'w',encoding='UTF-8') as file: 169 | file.write(data) 170 | 171 | if __name__=='__main__': 172 | generate_code() -------------------------------------------------------------------------------- /hyperstatic/app/seismic/wave2spec.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue May 19 11:58:29 2020 4 | 5 | @author: Dell 6 | """ 7 | 8 | import numpy as np 9 | import scipy as sp 10 | from scipy.signal import convolve 11 | from scipy.fftpack import fft,ifft,fftfreq 12 | from matplotlib import pyplot as plt 13 | import os 14 | 15 | #设置rc参数显示中文标题 16 | #设置字体为SimHei显示中文 17 | plt.rcParams['font.sans-serif'] = 'SimHei' 18 | #设置正常显示字符 19 | plt.rcParams['axes.unicode_minus'] = False 20 | 21 | def read_wave(filename,startline=0): 22 | a=[] 23 | flag=False 24 | with open(filename,"r") as f: 25 | # a=[] 26 | # for l in f: 27 | # if "'''" in l: 28 | # flag=not flag 29 | # continue 30 | # if flag: 31 | # continue 32 | # a.append(l.split()[1]) 33 | 34 | # ag=[float(i) for i in a] 35 | ag=[float(i) for i in f] 36 | return list(ag) 37 | 38 | def amptitude(wave,a_max): 39 | m=max(wave) 40 | return [i*a_max/m for i in wave] 41 | 42 | def wave2spectrum(file,dt,ξ,a_max,startline=1): 43 | """ 44 | file: file 45 | dt: length of time step 46 | ξ: damping ratio 47 | a_max: design peak acceleration 48 | return: 49 | T in s, a in g, v in m/s, d in m 50 | """ 51 | ag=read_wave(os.path.join(file),startline) 52 | ag=np.array(ag) 53 | ag=0.01*ag*a_max/np.max(ag) 54 | # ag=amptitude(ag,a_max) 55 | # ag=[0.01*i for i in ag] 56 | T=np.arange(dt,6.0+dt,dt) 57 | t=np.arange(len(ag))*dt 58 | β=[] 59 | sa=[] 60 | sv=[] 61 | sd=[] 62 | for _T in T: 63 | _ω=2*np.pi/_T 64 | Sa,Sv,Sd=duhamel(_ω,ξ,t,ag) 65 | sa.append(max(Sa)/9.8) 66 | sv.append(max(Sv)) 67 | sd.append(max(Sd)) 68 | return T,sa,sv,sd 69 | 70 | def duhamel(ω,ζ,t,p): 71 | """ 72 | ω: frequency 73 | ζ: damping 74 | t: total time 75 | p: excitation 76 | """ 77 | dt=(t[-1]-t[0])/(len(t)-1) 78 | ω_=ω*np.sqrt(1-ζ**2) 79 | q=np.exp(-ζ*ω_*t)*np.sin(ω_*t) 80 | Sd=1/ω_*convolve(p,q)[:len(t)]*dt 81 | Sv=Sd*ω_ 82 | Sa=Sv*ω_ 83 | return Sa,Sv,Sd 84 | 85 | 86 | def fft2spec(file,dt,ξ,a_max): 87 | """ 88 | file: file 89 | dt: length of time step 90 | ξ: damping ratio 91 | a_max: design peak acceleration, in cm/s2 92 | return: 93 | T in s, a in g 94 | """ 95 | ag=read_wave(os.path.join(file)) 96 | ag=np.array(ag) 97 | ag=0.01*ag*a_max/np.max(ag) #cm/s2 -> m/s2 98 | T=np.arange(dt,6.0+dt,dt) 99 | nex2pow=lambda x: int(round(2**np.ceil(np.log(x)/np.log(2.)))) #求采样点 100 | im=np.lib.scimath.sqrt(-1) 101 | Sa=[] 102 | # for _T in T: 103 | # ωₙ=2*np.pi/_T 104 | # ωd=(1-ξ)**0.5*ωₙ 105 | # n=256#采样点不是太精确,最好取到采样点数 106 | # Nfft=nex2pow(n)*16 107 | # af=fft(ag,Nfft)/Nfft 108 | # f=fftfreq(Nfft,d=dt) 109 | # ω=2*np.pi*f 110 | # H=1/((1-(ω/ωₙ)**2)+2*ξ*(ω/ωₙ)*im) 111 | # u=ifft(af*H,Nfft).real*Nfft 112 | # Sa.append(max(u)/9.8) 113 | n=256#采样点不是太精确,最好取到采样点数 114 | Nfft=nex2pow(n)*16 115 | f=fftfreq(Nfft,d=dt) 116 | ω=2*np.pi*f 117 | def max_response(_T): 118 | ωₙ=2*np.pi/_T 119 | ωd=(1-ξ)**0.5*ωₙ 120 | af=fft(ag,Nfft)/Nfft 121 | # H=1/((1-(ω/ωₙ)**2)+2*ξ*(ω/ωₙ)*im) #ωd? 122 | H=1/((1-(ω/ωd)**2)+2*ξ*(ω/ωd)*im) 123 | u=ifft(af*H,Nfft).real*Nfft 124 | return np.max(u)/9.8 125 | Sa=[max_response(t) for t in T] 126 | return T,Sa 127 | 128 | 129 | 130 | def GB50011_spectrum(αₘₐₓ,Tg,ζ,dt): 131 | T=np.arange(0,6,dt) 132 | γ=0.9+(0.05-ζ)/(0.3+6*ζ) 133 | η1=0.02+(0.05-ζ)/(4+32*ζ) 134 | η1= η1 if η1>0 else 0 135 | η2= 1+(0.05-ζ)/(0.08+1.6*ζ) 136 | η2= η2 if η2>0.55 else 0.55 137 | def f(t): 138 | if t<0.1: 139 | return 0.45*αₘₐₓ+(η2-0.45)*αₘₐₓ/0.1*t 140 | elif t m/s2 195 | print(file,'MSE=%4.5f'%square_err(Sa,s['alpha'])) 196 | MSE.append((file,square_err(Sa,s['alpha']))) 197 | MSE.sort(key=lambda x:x[1]) 198 | champions=MSE[:num_wave] 199 | [print("*",end='') for i in range(99)] 200 | print("\nChampions:") 201 | [print(file,'MSE=%4.5f'%err) for file,err in champions] 202 | for file,err in champions: 203 | dt=0.02 204 | a_max=35 205 | T,Sa=fft2spec(file,dt,damp,a_max) 206 | avg.append([i for i in Sa]) #cm/s2 -> m/s2 207 | name=file.split('\\')[-1] 208 | if name=='Ofunato_131': 209 | name='ArtWav' 210 | plt.plot(T,np.array(Sa),linewidth=0.5,label=name) 211 | avg=np.array(avg).mean(0) 212 | plt.plot(T,avg,label='均值',color='b') 213 | plt.xlabel('周期/s') 214 | plt.ylabel('影响系数') 215 | plt.legend() 216 | plt.show() --------------------------------------------------------------------------------