3939from cubitpy .cubit_wrapper .cubit_wrapper_host import CubitConnect
4040
4141
42+ def _get_and_check_ids (name , container , id_list , given_id ):
43+ """Perform checks for the block and node set IDs used in CubitPy."""
44+
45+ # Check that the IDs stored in container are the same as created with this function.
46+ if not set (container .keys ()) == set (id_list ):
47+ raise ValueError (
48+ f"The existing { name } ids in CubitPy ({ set (container .keys ())} ) don't match the ones in Cubit ({ id_list } )"
49+ )
50+
51+ # Get the id of the block to create.
52+ if given_id is None :
53+ if len (id_list ) > 0 :
54+ given_id = max (id_list ) + 1
55+ else :
56+ given_id = 1
57+ elif given_id in id_list :
58+ raise ValueError (f"The provided { name } id { given_id } already exists { id_list } " )
59+ return given_id
60+
61+
4262class CubitPy (object ):
4363 """A wrapper class with additional functionality for cubit."""
4464
@@ -69,12 +89,10 @@ def __init__(self, *, cubit_exe=None, **kwargs):
6989 # Set lists and counters for blocks and sets
7090 self ._default_cubit_variables ()
7191
72- self .fourc_input = FourCInput ()
73-
7492 def _default_cubit_variables (self ):
7593 """Set the default values for the lists and counters used in cubit."""
76- self .blocks = []
77- self .node_sets = []
94+ self .blocks = {}
95+ self .node_sets = {}
7896 self .fourc_input = FourCInput ()
7997
8098 def __getattr__ (self , key , * args , ** kwargs ):
@@ -128,7 +146,14 @@ def _name_created_set(self, set_type, set_id, name, item):
128146 self .cubit .cmd ('{} {} name "{}"' .format (set_type , set_id , rename_name ))
129147
130148 def add_element_type (
131- self , item , el_type , * , name = None , material = None , bc_description = None
149+ self ,
150+ item ,
151+ el_type ,
152+ * ,
153+ name = None ,
154+ material = None ,
155+ bc_description = None ,
156+ block_id : int | None = None ,
132157 ):
133158 """Add a block to cubit that contains the geometry in item. Also set
134159 the element type of block.
@@ -147,6 +172,9 @@ def add_element_type(
147172 bc_description: dict
148173 Will be written after the material string. If this is not set, the
149174 default values for the given element type will be used.
175+ block_id:
176+ Optionally the block ID can be given by the user. If this ID already exists
177+ an error will be raised.
150178 """
151179
152180 # default values
@@ -155,19 +183,15 @@ def add_element_type(
155183 if bc_description is None :
156184 bc_description = {}
157185
158- # Check that all blocks in cubit are created with this function.
159- n_blocks = len (self .blocks )
160- if not len (self .cubit .get_block_id_list ()) == n_blocks :
161- raise ValueError (
162- "The block counter is {1}, but the number of blocks in cubit is {0}, all blocks should be created with this function!" .format (
163- len (self .cubit .get_block_id_list ()), n_blocks
164- )
165- )
186+ # Check and get the block id for the new block.
187+ block_id = _get_and_check_ids (
188+ "block" , self .blocks , self .cubit .get_block_id_list (), block_id
189+ )
166190
167191 # Get element type of item.
168192 geometry_type = item .get_geometry_type ()
169193
170- self .cubit .cmd ("create block {}" .format (n_blocks + 1 ))
194+ self .cubit .cmd ("create block {}" .format (block_id ))
171195
172196 if not isinstance (item , CubitGroup ):
173197 cubit_scheme , cubit_element_type = el_type .get_cubit_names ()
@@ -181,30 +205,30 @@ def add_element_type(
181205
182206 self .cubit .cmd (
183207 "block {} {} {}" .format (
184- n_blocks + 1 , geometry_type .get_cubit_string (), item .id ()
208+ block_id , geometry_type .get_cubit_string (), item .id ()
185209 )
186210 )
187211 self .cubit .cmd (
188- "block {} element type {}" .format (n_blocks + 1 , cubit_element_type )
212+ "block {} element type {}" .format (block_id , cubit_element_type )
189213 )
190214 else :
191- item .add_to_block (n_blocks + 1 , el_type )
215+ item .add_to_block (block_id , el_type )
192216
193- self ._name_created_set ("block" , n_blocks + 1 , name , item )
217+ self ._name_created_set ("block" , block_id , name , item )
194218
195219 # If the user does not give a bc_description, load the default one.
196220 if not bc_description :
197221 bc_description = el_type .get_default_four_c_description ()
198222
199223 # Add data that will be written to bc file.
200- self .blocks . append ([ el_type , material | bc_description ])
224+ self .blocks [ block_id ] = [ el_type , material | bc_description ]
201225
202226 def reset_blocks (self ):
203227 """This method deletes all blocks in Cubit and resets the counter in
204228 this object."""
205229
206230 # Reset the block list of this object.
207- self .blocks = []
231+ self .blocks = {}
208232
209233 # Delete all blocks.
210234 for block_id in self .get_block_id_list ():
@@ -219,6 +243,7 @@ def add_node_set(
219243 bc_description = None ,
220244 bc_section = None ,
221245 geometry_type = None ,
246+ node_set_id : int | None = None ,
222247 ):
223248 """Add a node set to cubit. This node set can have a boundary
224249 condition.
@@ -239,34 +264,33 @@ def add_node_set(
239264 geometry_type: cupy.geometry
240265 Directly set the geometry type, instead of obtaining it from the
241266 given item.
267+ node_set_id:
268+ Optionally the node set ID can be given by the user. If this ID
269+ already exists an error will be raised.
242270 """
243271
244- # Check that all node sets in cubit are created with this function.
245- n_node_sets = len (self .node_sets )
246- if not len (self .cubit .get_nodeset_id_list ()) == n_node_sets :
247- raise ValueError (
248- "The node set counter is {1}, but the number of node sets in cubit is {0}, all node sets should be created with this function!" .format (
249- len (self .cubit .get_nodeset_id_list ()), n_node_sets
250- )
251- )
272+ # Check and get the node set id for the new node set.
273+ node_set_id = _get_and_check_ids (
274+ "nodeset" , self .node_sets , self .cubit .get_nodeset_id_list (), node_set_id
275+ )
252276
253277 # Get element type of item if it was not explicitly given.
254278 if geometry_type is None :
255279 geometry_type = item .get_geometry_type ()
256280
257- self .cubit .cmd ("create nodeset {}" .format (n_node_sets + 1 ))
281+ self .cubit .cmd ("create nodeset {}" .format (node_set_id ))
258282 if not isinstance (item , CubitGroup ):
259283 # Add the geometries to the node set in cubit.
260284 self .cubit .cmd (
261285 "nodeset {} {} {}" .format (
262- n_node_sets + 1 , geometry_type .get_cubit_string (), item .id ()
286+ node_set_id , geometry_type .get_cubit_string (), item .id ()
263287 )
264288 )
265289 else :
266290 # Add the group to the node set in cubit.
267- item .add_to_nodeset (n_node_sets + 1 )
291+ item .add_to_nodeset (node_set_id )
268292
269- self ._name_created_set ("nodeset" , n_node_sets + 1 , name , item )
293+ self ._name_created_set ("nodeset" , node_set_id , name , item )
270294
271295 # Add data that will be written to bc file.
272296 if (
@@ -282,7 +306,7 @@ def add_node_set(
282306 bc_section = bc_type .get_dat_bc_section_header (geometry_type )
283307 if bc_description is None :
284308 bc_description = {}
285- self .node_sets . append ([ bc_section , bc_description , geometry_type ])
309+ self .node_sets [ node_set_id ] = [ bc_section , bc_description , geometry_type ]
286310
287311 def get_ids (self , geometry_type ):
288312 """Get a list with all available ids of a certain geometry type."""
@@ -367,7 +391,13 @@ def dump(self, yaml_path, mesh_in_exo=False):
367391 # create a deep copy of the input_file
368392 input_file = self .fourc_input .copy ()
369393 # Add the node sets
370- add_node_sets (self , exo , input_file , write_topology_information = False )
394+ add_node_sets (
395+ self ,
396+ exo ,
397+ input_file ,
398+ write_topology_information = False ,
399+ use_exo_ids = True ,
400+ )
371401 # Add the problem geometry section
372402 rel_exo_path = os .path .relpath (exo_path , start = yaml_dir )
373403 add_exodus_geometry_section (self , input_file , rel_exo_path )
0 commit comments