Skip to content

Commit 4f15f37

Browse files
Merge pull request #9 from polyfem/zhongshi/improve
update python for polyfem
2 parents 5cf3dbc + c6a2f20 commit 4f15f37

File tree

11 files changed

+679
-626
lines changed

11 files changed

+679
-626
lines changed

.clang-format

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
33
Language: Cpp
44
BasedOnStyle: LLVM
5-
# ColumnLimit: 80
6-
ColumnLimit: 0
7-
UseTab: ForContinuationAndIndentation
8-
IndentWidth: 4
5+
ColumnLimit: 80
6+
UseTab: Never
7+
IndentWidth: 2
98
TabWidth: 4
109
BreakBeforeBraces: Custom
1110
BraceWrapping:

.github/workflows/continuous.yml

-3
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,3 @@ jobs:
6868
if: matrix.name == 'Linux' || matrix.name == 'MacOS' || (matrix.config == 'Debug' && runner.os == 'Windows')
6969
run: |
7070
python test/test_bending.py
71-
python test/test_gravity.py
72-
python test/test_inflation.py
73-
python test/test_plane_hole.py

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ __pycache__
1919
temp-plot.html
2020
data*
2121
*libTracyClient.*
22+
.cache/

cmake/recipes/polyfem.cmake

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ include(FetchContent)
1111
FetchContent_Declare(
1212
polyfem
1313
GIT_REPOSITORY https://github.com/polyfem/polyfem.git
14-
GIT_TAG ffb1d130e70fc913ec4546c8683d6d22bd58a700
14+
GIT_TAG 12ac634833f91a3946cff26db01972fdb2ec3214
1515
GIT_SHALLOW FALSE
1616
)
1717
FetchContent_MakeAvailable(polyfem)

cmake/recipes/polyfem_data.cmake

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ include(FetchContent)
77
FetchContent_Declare(
88
polyfem_data
99
GIT_REPOSITORY https://github.com/polyfem/polyfem-data
10-
GIT_TAG 56e70d2d7199fe4822b259c47fada97f70e32a72
10+
GIT_TAG 29a46df1fd90c237a82c219f346a956e72bd17d3
1111
GIT_SHALLOW FALSE
12-
SOURCE_DIR ${POLYFEMPY_DATA_ROOT}/data
12+
SOURCE_DIR ${POLYFEMPY_DATA_ROOT}
1313
)
1414
FetchContent_GetProperties(polyfem_data)
1515
if(NOT polyfem_data_POPULATED)

polyfempy/Settings.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
2+
from logging import raiseExceptions
23
import polyfempy
3-
4+
import sys
45

56
class Settings:
67
"""Class that encodes the settings of the solver, it models the input json file"""
@@ -38,6 +39,7 @@ def __init__(self, discr_order=1, pressure_discr_order=1, pde=polyfempy.PDEs.Lap
3839
self.pde = pde
3940

4041
self.selection = None
42+
raise RuntimeError("Old Version Deprecated. Use version <0.5.2 on conda for the old interface")
4143

4244
def get_problem(self):
4345
"""Get the problem"""
@@ -141,7 +143,9 @@ def __str__(self):
141143
tmp["problem"] = self.problem
142144
tmp.update(self.advanced_options)
143145

144-
return json.dumps(tmp, sort_keys=True, indent=4)
146+
json_str = json.dumps(tmp, sort_keys=True, indent=4)
147+
148+
return json_str
145149

146150
def serialize(self):
147151
"""stringyfied json description of this class, used to run the solver"""

polyfempy/autoclass.py

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
from dataclasses import make_dataclass
2+
import typing
3+
import dataclasses
4+
import json
5+
import polyfempy
6+
7+
def getter(contain, key):
8+
if key not in contain:
9+
return []
10+
return contain[key]
11+
12+
def parse_tree(rules, mark_required = False):
13+
tree = dict()
14+
for r in rules:
15+
pt = r['pointer']
16+
pt = pt.replace('/*','')
17+
18+
path = pt.split('/')
19+
if pt == '/':
20+
path = ['']
21+
22+
subtree = tree
23+
for k in path:
24+
if k not in subtree:
25+
subtree[k] = dict()
26+
subtree = subtree[k]
27+
req, opt = (getter(r,'required'), getter(r, 'optional'))
28+
for k in req:
29+
if k not in subtree:
30+
subtree[k] = {}
31+
if mark_required:
32+
subtree[k]['R'] = '0'
33+
for k in opt:
34+
if k not in subtree:
35+
subtree[k] = {}
36+
return tree
37+
38+
39+
def snake_to_camel(name):
40+
if name == '':
41+
return 'PolyFEM'
42+
return ''.join([n.capitalize() for n in name.split('_')])
43+
44+
def print_script():
45+
# deprecated to the make_dataclasses interface
46+
key = ''
47+
node = tree[key]
48+
indent = 4
49+
repre = 'from dataclasses import dataclass\nimport typing\n'
50+
51+
def rec(key, val, h):
52+
global repre
53+
if key == 'lambda':
54+
return
55+
if key !='':
56+
repre += (' '*h*indent + f'{key} : typing.Any = None\n')
57+
58+
if len(val) == 0:
59+
return
60+
classname = snake_to_camel(key)
61+
repre += (' '*h*indent + f'@dataclass\n')
62+
repre += (' '*h*indent + f'class {classname}:\n')
63+
for k,v in (val.items()):
64+
rec(k,v, h+1)
65+
66+
rec(key, node, 0)
67+
68+
repre += """
69+
if __name__ == '__main__':
70+
print(PolyFEM(geometry='mesh.obj'))
71+
"""
72+
73+
with open('test.py', 'w') as fp:
74+
fp.write(repre)
75+
76+
77+
78+
def recursive_data_class_builder(node, name):
79+
fields = []
80+
namespace = dict()
81+
for k, v in node.items():
82+
if k == 'lambda':
83+
continue
84+
fields.append((k,typing.Any,None))
85+
if isinstance(v, dict) and len(v) != 0:
86+
name0 = snake_to_camel(k)
87+
namespace[name0] = recursive_data_class_builder(v, name0)
88+
return make_dataclass(name, fields=fields, namespace = namespace)
89+
90+
91+
def prune_none_entry(node):
92+
if not isinstance(node, dict):
93+
if isinstance(node, list):
94+
for v in node:
95+
prune_none_entry(v)
96+
else:
97+
for k, v in list(node.items()):
98+
prune_none_entry(v)
99+
if v is None or (hasattr(v, '__len__') and len(v) == 0):
100+
node.pop(k)
101+
102+
def generate_input_dict(config):
103+
output = dataclasses.asdict(config)
104+
prune_none_entry(output)
105+
return output
106+
107+
108+
with open('data/default_rules.json')as fp:
109+
rules = json.load(fp)
110+
111+
tree = parse_tree(rules)
112+
pf = recursive_data_class_builder(tree[''], '')
113+
114+
geometry = pf.Geometry(mesh='import.obj')
115+
matnu = pf.Materials(id = 0, nu=0.1)
116+
matE = pf.Materials(id = 1,E=10)
117+
118+
config = pf(geometry = geometry, materials = [matnu, matE])
119+
120+
def solve(**kwargs):
121+
d = generate_input_dict(config)
122+
polyfempy.solve(**d)

polyfempy/test/test_pythonic.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@ def sideset(p):
3535
vertices=pts,
3636
cells=faces,
3737
sidesets_func=sideset,
38-
diriclet_bc=[{"id": 4, "value": [0, 0]}],
39-
materials=[{"id": 0, "E": 2100, "nu": 0.3}],
40-
rhs=[0, 0.1],
41-
pde=pf.PDEs.LinearElasticity,
42-
discr_order=1
38+
boundary_conditions=dict(
39+
dirichlet_boundary=[dict(id=4, value=[0, 0])],
40+
rhs=[0, 0.1],
41+
),
42+
geometry="",
43+
materials=[dict(type="NeoHookean", id=0, E=2100, nu=0.3)],
44+
space=dict(discr_order=1),
4345
)
4446

4547
log = solver.get_log()

setup.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ def __init__(self, name, sourcedir=''):
2020

2121
class CMakeBuild(build_ext):
2222
def run(self):
23-
if platform.system() == 'Darwin':
24-
self.build_temp = self.build_temp.replace("build", "build.nosync")
25-
2623
try:
2724
out = subprocess.check_output(['cmake', '--version'])
2825
except OSError:
@@ -78,8 +75,9 @@ def build_extension(self, ext):
7875
build_args += ['--', '-j{}'.format(n_threads)]
7976

8077
env = os.environ.copy()
81-
env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(
82-
env.get('CXXFLAGS', ''), self.distribution.get_version())
78+
# env['CXXFLAGS'] = '{} -DVERSION_INFO=\"{}\"'.format(
79+
# env.get('CXXFLAGS', ''), self.distribution.get_version())
80+
# print(env['CXXFLAGS'])
8381

8482
if not os.path.exists(self.build_temp):
8583
os.makedirs(self.build_temp)
@@ -98,7 +96,7 @@ def build_extension(self, ext):
9896

9997
setup(
10098
name="polyfempy",
101-
version="0.6",
99+
version="0.7",
102100
author="Teseo Schneider",
103101
author_email="",
104102
description="Polyfem Python Bindings",

0 commit comments

Comments
 (0)