11import json
22import tomllib as tl
3+ from collections import namedtuple
34
45import jax .numpy as jnp
5- import numpy as np
66
77from diffmpm import element as mpel
88from diffmpm import material as mpmat
99from diffmpm import mesh as mpmesh
1010from diffmpm .constraint import Constraint
11- from diffmpm .node import Nodes
11+ from diffmpm .forces import NodalForce , ParticleTraction
12+ from diffmpm .functions import Unit , Linear
1213from diffmpm .particle import Particles
1314
1415
1516class Config :
1617 def __init__ (self , filepath ):
1718 self ._filepath = filepath
18- self .config = {}
19+ self .parsed_config = {}
1920 self .parse ()
2021
2122 def parse (self ):
@@ -26,14 +27,16 @@ def parse(self):
2627 self ._parse_output (self ._fileconfig )
2728 self ._parse_materials (self ._fileconfig )
2829 self ._parse_particles (self ._fileconfig )
30+ self ._parse_math_functions (self ._fileconfig )
31+ self ._parse_external_loading (self ._fileconfig )
2932 mesh = self ._parse_mesh (self ._fileconfig )
3033 return mesh
3134
3235 def _parse_meta (self , config ):
33- self .config ["meta" ] = config ["meta" ]
36+ self .parsed_config ["meta" ] = config ["meta" ]
3437
3538 def _parse_output (self , config ):
36- self .config ["output" ] = config ["output" ]
39+ self .parsed_config ["output" ] = config ["output" ]
3740
3841 def _parse_materials (self , config ):
3942 materials = []
@@ -42,21 +45,67 @@ def _parse_materials(self, config):
4245 mat_cls = getattr (mpmat , mat_type )
4346 mat = mat_cls (mat_config )
4447 materials .append (mat )
45- self .config ["materials" ] = materials
48+ self .parsed_config ["materials" ] = materials
4649
4750 def _parse_particles (self , config ):
4851 particle_sets = []
4952 for pset_config in config ["particles" ]:
50- pmat = self .config ["materials" ][pset_config ["material_id" ]]
53+ pmat = self .parsed_config ["materials" ][pset_config ["material_id" ]]
5154 with open (pset_config ["file" ], "r" ) as f :
5255 ploc = jnp .asarray (json .load (f ))
5356 peids = jnp .zeros (ploc .shape [0 ], dtype = jnp .int32 )
5457 pset = Particles (ploc , pmat , peids )
55- pset .velocity = pset .velocity .at [:].set (
56- pset_config ["init_velocity" ]
57- )
58+ pset .velocity = pset .velocity .at [:].set (pset_config ["init_velocity" ])
5859 particle_sets .append (pset )
59- self .config ["particles" ] = particle_sets
60+ self .parsed_config ["particles" ] = particle_sets
61+
62+ def _parse_math_functions (self , config ):
63+ flist = []
64+ for i , fnconfig in enumerate (config ["math_functions" ]):
65+ if fnconfig ["type" ] == "Linear" :
66+ fn = Linear (
67+ i ,
68+ jnp .array (fnconfig ["xvalues" ]),
69+ jnp .array (fnconfig ["fxvalues" ]),
70+ )
71+ flist .append (fn )
72+ else :
73+ raise NotImplementedError (
74+ "Function type other than `Linear` not yet supported"
75+ )
76+ self .parsed_config ["math_functions" ] = flist
77+
78+ def _parse_external_loading (self , config ):
79+ external_loading = {}
80+ external_loading ["gravity" ] = jnp .array (config ["external_loading" ]["gravity" ])
81+ cnf_list = []
82+ for cnfconfig in config ["external_loading" ]["concentrated_nodal_forces" ]:
83+ if "math_function_id" in cnfconfig :
84+ fn = self .parsed_config ["math_functions" ][cnfconfig ["math_function_id" ]]
85+ else :
86+ fn = Unit (- 1 )
87+ cnf = NodalForce (
88+ node_ids = jnp .array (cnfconfig ["node_ids" ]),
89+ math_function = fn ,
90+ dir = cnfconfig ["dir" ],
91+ force = cnfconfig ["force" ],
92+ )
93+ cnf_list .append (cnf )
94+
95+ pst_list = []
96+ for pstconfig in config ["external_loading" ]["particle_surface_traction" ]:
97+ pst = ParticleTraction (
98+ pset = jnp .array (cnfconfig ["pset" ]),
99+ math_function = self .parsed_config ["math_functions" ][
100+ pstconfig ["math_function_id" ]
101+ ],
102+ dir = cnfconfig ["dir" ],
103+ traction = cnfconfig ["traction" ],
104+ )
105+ pst_list .append (pst )
106+ external_loading ["concentrated_nodal_forces" ] = cnf_list
107+ external_loading ["particle_surface_traction" ] = pst_list
108+ self .parsed_config ["external_loading" ] = external_loading
60109
61110 def _parse_mesh (self , config ):
62111 element_cls = getattr (mpel , config ["mesh" ]["element" ])
@@ -65,16 +114,19 @@ def _parse_mesh(self, config):
65114 (jnp .asarray (c ["node_ids" ]), Constraint (c ["dir" ], c ["velocity" ]))
66115 for c in config ["mesh" ]["constraints" ]
67116 ]
68- if config ["mesh" ]["type" ] == "file" :
69- nodes_loc = jnp .asarray (np .loadtxt (config ["mesh" ]["file" ]))
70- # nodes = Nodes(len(nodes_loc), nodes_loc)
71- # elements = element_cls(nelements, el_len, boundary_nodes)
72- elif config ["mesh" ]["type" ] == "generator" :
117+ if config ["mesh" ]["type" ] == "generator" :
73118 elements = element_cls (
74119 config ["mesh" ]["nelements" ],
75120 config ["mesh" ]["element_length" ],
76121 constraints ,
122+ concentrated_nodal_forces = self .parsed_config ["external_loading" ][
123+ "concentrated_nodal_forces"
124+ ],
125+ )
126+ else :
127+ raise NotImplementedError (
128+ "Mesh type other than `generator` not yet supported."
77129 )
78- self .config ["elements" ] = elements
79- mesh = mesh_cls (self .config )
130+ self .parsed_config ["elements" ] = elements
131+ mesh = mesh_cls (self .parsed_config )
80132 return mesh
0 commit comments