Skip to content

update python for polyfem #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
update json
  • Loading branch information
jiangzhongshi committed Jun 17, 2022
commit db097e96f9e2ba840d80576dabc54279a37f5f51
125 changes: 125 additions & 0 deletions polyfempy/autoclass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
from dataclasses import make_dataclass
import typing
import dataclasses
import json
import polyfempy

def getter(contain, key):
if key not in contain:
return []
return contain[key]

def parse_tree(rules, mark_required = False):
tree = dict()
for r in rules:
pt = r['pointer']
pt = pt.replace('/*','')

path = pt.split('/')
if pt == '/':
path = ['']

subtree = tree
for k in path:
if k not in subtree:
subtree[k] = dict()
subtree = subtree[k]
req, opt = (getter(r,'required'), getter(r, 'optional'))
for k in req:
if k not in subtree:
subtree[k] = {}
if mark_required:
subtree[k]['R'] = '0'
for k in opt:
if k not in subtree:
subtree[k] = {}
return tree


def snake_to_camel(name):
if name == '':
return 'PolyFEM'
return ''.join([n.capitalize() for n in name.split('_')])

def print_script():
# deprecated to the make_dataclasses interface
key = ''
node = tree[key]
indent = 4
repre = 'from dataclasses import dataclass\nimport typing\n'

def rec(key, val, h):
global repre
if key == 'lambda':
return
if key !='':
repre += (' '*h*indent + f'{key} : typing.Any = None\n')

if len(val) == 0:
return
classname = snake_to_camel(key)
repre += (' '*h*indent + f'@dataclass\n')
repre += (' '*h*indent + f'class {classname}:\n')
for k,v in (val.items()):
rec(k,v, h+1)

rec(key, node, 0)

repre += """
if __name__ == '__main__':
print(PolyFEM(geometry='mesh.obj'))
"""

with open('test.py', 'w') as fp:
fp.write(repre)



def recursive_data_class_builder(node, name):
fields = []
namespace = dict()
for k, v in node.items():
if k == 'lambda':
continue
fields.append((k,typing.Any,None))
if isinstance(v, dict) and len(v) != 0:
name0 = snake_to_camel(k)
namespace[name0] = recursive_data_class_builder(v, name0)
return make_dataclass(name, fields=fields, namespace = namespace)


def prune_none_entry(node):
if not isinstance(node, dict):
if isinstance(node, list):
for v in node:
prune_none_entry(v)
else:
for k, v in list(node.items()):
prune_none_entry(v)
if v is None or (hasattr(v, '__len__') and len(v) == 0):
node.pop(k)

def generate_input_dict(config):
output = dataclasses.asdict(config)
prune_none_entry(output)
return output


with open('data/default_rules.json')as fp:
rules = json.load(fp)

tree = parse_tree(rules)
pf = recursive_data_class_builder(tree[''], '')

geometry = pf.Geometry(mesh='import.obj')
matnu = pf.Materials(id = 0, nu=0.1)
matE = pf.Materials(id = 1,E=10)

config = pf(geometry = geometry, materials = [matnu, matE])

def solve(**kwargs):
d = generate_input_dict(config)
polyfempy.solve(**d)

if __name__ == '__main__':

3 changes: 0 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ def __init__(self, name, sourcedir=''):

class CMakeBuild(build_ext):
def run(self):
if platform.system() == 'Darwin':
self.build_temp = self.build_temp.replace("build", "build.nosync")

try:
out = subprocess.check_output(['cmake', '--version'])
except OSError:
Expand Down
43 changes: 16 additions & 27 deletions src/binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,38 +342,30 @@ PYBIND11_MODULE(polyfempy, m)
"load_mesh_from_settings", [](polyfem::State &s, const bool normalize_mesh, const double vismesh_rel_area, const int n_refs, const double boundary_id_threshold) {
init_globals(s);
// py::scoped_ostream_redirect output;
throw std::runtime_error("Need to convert JSON");
s.args["normalize_mesh"] = normalize_mesh;
s.args["n_refs"] = n_refs;
s.args["boundary_id_threshold"] = boundary_id_threshold;
s.args["vismesh_rel_area"] = vismesh_rel_area;
s.args["geometry"]["advanced"]["normalize_mesh"] = normalize_mesh;
s.args["output"]["paraview"]["vismesh_rel_area"] = vismesh_rel_area;
s.load_mesh(); },
"Loads a mesh from the 'mesh' field of the json and 'bc_tag' if any bc tags", py::arg("normalize_mesh") = bool(false), py::arg("vismesh_rel_area") = double(0.00001), py::arg("n_refs") = int(0), py::arg("boundary_id_threshold") = double(-1))

.def(
"load_mesh_from_path", [](polyfem::State &s, const std::string &path, const bool normalize_mesh, const double vismesh_rel_area, const int n_refs, const double boundary_id_threshold) {
init_globals(s);
// py::scoped_ostream_redirect output;
throw std::runtime_error("Need to convert JSON");
s.args["mesh"] = path;
s.args["normalize_mesh"] = normalize_mesh;
s.args["n_refs"] = n_refs;
s.args["boundary_id_threshold"] = boundary_id_threshold;
s.args["vismesh_rel_area"] = vismesh_rel_area;
s.args["geometry"]["advanced"]["normalize_mesh"] = normalize_mesh;
s.args["output"]["paraview"]["vismesh_rel_area"] = vismesh_rel_area;
s.load_mesh(); },
"Loads a mesh from the path and 'bc_tag' from the json if any bc tags", py::arg("path"), py::arg("normalize_mesh") = bool(false), py::arg("vismesh_rel_area") = double(0.00001), py::arg("n_refs") = int(0), py::arg("boundary_id_threshold") = double(-1))

.def(
"load_mesh_from_path_and_tags", [](polyfem::State &s, const std::string &path, const std::string &bc_tag, const bool normalize_mesh, const double vismesh_rel_area, const int n_refs, const double boundary_id_threshold) {
init_globals(s);
// py::scoped_ostream_redirect output;
throw std::runtime_error("Need to convert JSON");
s.args["mesh"] = path;
s.args["bc_tag"] = bc_tag;
s.args["normalize_mesh"] = normalize_mesh;
s.args["geometry"]["advanced"]["normalize_mesh"] = normalize_mesh;
s.args["n_refs"] = n_refs;
s.args["boundary_id_threshold"] = boundary_id_threshold;
s.args["vismesh_rel_area"] = vismesh_rel_area;
s.args["output"]["paraview"]["vismesh_rel_area"] = vismesh_rel_area;
s.load_mesh(); },
"Loads a mesh and bc_tags from path", py::arg("path"), py::arg("bc_tag_path"), py::arg("normalize_mesh") = bool(false), py::arg("vismesh_rel_area") = double(0.00001), py::arg("n_refs") = int(0), py::arg("boundary_id_threshold") = double(-1))

Expand All @@ -388,11 +380,10 @@ PYBIND11_MODULE(polyfempy, m)
s.mesh = std::make_unique<polyfem::mesh::CMesh3D>();
s.mesh->build_from_matrices(V, F);

throw std::runtime_error("Need to convert JSON");
s.args["normalize_mesh"] = normalize_mesh;
s.args["n_refs"] = n_refs;
s.args["geometry"]["advanced"]["normalize_mesh"] = normalize_mesh;
s.args["geometry"]["n_refs"] = n_refs;
s.args["boundary_id_threshold"] = boundary_id_threshold;
s.args["vismesh_rel_area"] = vismesh_rel_area;
s.args["output"]["paraview"]["vismesh_rel_area"] = vismesh_rel_area;

s.load_mesh(); },
"Loads a mesh from vertices and connectivity", py::arg("vertices"), py::arg("connectivity"), py::arg("normalize_mesh") = bool(false), py::arg("vismesh_rel_area") = double(0.00001), py::arg("n_refs") = int(0), py::arg("boundary_id_threshold") = double(-1))
Expand All @@ -408,12 +399,11 @@ PYBIND11_MODULE(polyfempy, m)
s.mesh = std::make_unique<polyfem::mesh::CMesh3D>();
s.mesh->build_from_matrices(V, F);
s.mesh->attach_higher_order_nodes(nodes_pos, nodes_indices);
throw std::runtime_error("Need to convert JSON");

s.args["normalize_mesh"] = normalize_mesh;
s.args["n_refs"] = n_refs;
s.args["geometry"]["advanced"]["normalize_mesh"] = normalize_mesh;
s.args["geometry"]["n_refs"] = n_refs;
s.args["boundary_id_threshold"] = boundary_id_threshold;
s.args["vismesh_rel_area"] = vismesh_rel_area;
s.args["output"]["paraview"]["vismesh_rel_area"] = vismesh_rel_area;

s.load_mesh(); },
"Loads an high order mesh from vertices, connectivity, nodes, and node indices mapping element to nodes", py::arg("vertices"), py::arg("connectivity"), py::arg("nodes_pos"), py::arg("nodes_indices"), py::arg("normalize_mesh") = bool(false), py::arg("vismesh_rel_area") = double(0.00001), py::arg("n_refs") = int(0), py::arg("boundary_id_threshold") = double(-1))
Expand Down Expand Up @@ -441,8 +431,7 @@ PYBIND11_MODULE(polyfempy, m)
"set_rhs_from_path", [](polyfem::State &s, std::string &path) {
init_globals(s);
// py::scoped_ostream_redirect output;
throw std::runtime_error("Need to convert JSON");
s.args["rhs_path"] = path; },
throw std::runtime_error("No RHS path"); },
"Loads the rhs from a file", py::arg("path"))
.def(
"set_rhs", [](polyfem::State &s, const Eigen::MatrixXd &rhs) {
Expand Down Expand Up @@ -898,7 +887,7 @@ PYBIND11_MODULE(polyfempy, m)
in_args["n_refs"] = n_refs;
if (!problem_name.empty())
in_args["problem"] = problem_name;
in_args["normalize_mesh"] = !skip_normalization;
in_args["geometry"]["advanced"]["normalize_mesh"] = !skip_normalization;
in_args["project_to_psd"] = project_to_psd;

if (!scalar_formulation.empty())
Expand Down Expand Up @@ -927,7 +916,7 @@ PYBIND11_MODULE(polyfempy, m)
in_args["solver_type"] = solver;

if (vis_mesh_res > 0)
in_args["vismesh_rel_area"] = vis_mesh_res;
in_args["output"]["paraview"]["vismesh_rel_area"] = vis_mesh_res;

if (export_material_params)
in_args["export"]["material_params"] = true;
Expand Down Expand Up @@ -982,7 +971,7 @@ PYBIND11_MODULE(polyfempy, m)
in_args.contains("discr_order") ? int(in_args["discr_order"]) : 1;

if (discr_order == 1 && !in_args.contains("vismesh_rel_area"))
in_args["vismesh_rel_area"] = 1e10;
in_args["output"]["paraview"]["vismesh_rel_area"] = 1e10;

polyfem::State state;
state.init_logger("", log_level, false);
Expand Down