33Currently hardcoded for 2D-single-patch-splines.
44"""
55
6+ from ast import literal_eval
7+
68import gustaf as _gus
79import numpy as _np
810
3133def load (fname ):
3234 """Reads mfem spline and returns a spline.
3335
34- Again, only supports 2D single patch.
36+ Supports 2D/3D single patch.
3537
3638 Parameters
3739 -----------
@@ -86,30 +88,45 @@ def load(fname):
8688
8789 # parse nurbs_dict
8890 # kvs
89- knot_vectors = nurbs_dict ["knotvectors" ][1 :]
90- knot_vectors [0 ] = eval ("[" + knot_vectors [0 ].replace (" " , "," ) + "]" )
91- knot_vectors [1 ] = eval ("[" + knot_vectors [1 ].replace (" " , "," ) + "]" )
92- # pop some values
93- # ds
94- degrees = [knot_vectors [0 ].pop (0 ), knot_vectors [1 ].pop (0 )]
95- ncps = knot_vectors [0 ].pop (0 ) * knot_vectors [1 ].pop (0 )
91+ knot_vectors_sec = nurbs_dict ["knotvectors" ][1 :]
92+ knot_vectors = []
93+ for kvs in knot_vectors_sec :
94+ knot_vectors .append (literal_eval ("[" + kvs .replace (" " , "," ) + "]" ))
95+
96+ # parse degrees and get number of control points for consistency checks
97+ degrees = []
98+ ncps = 1
99+ for kv in knot_vectors :
100+ # first value in kv is degrees
101+ degrees .append (kv .pop (0 ))
102+ # second value is number of control points
103+ ncps *= kv .pop (0 )
104+
96105 # ws
97106 weights = nurbs_dict ["weights" ]
98- weights = [eval (w ) for w in weights ] # hopefully not too slow
107+ weights = [literal_eval (w ) for w in weights ] # hopefully not too slow
99108 # cps
100109 control_points = nurbs_dict ["Ordering" ]
101110 control_points = [
102- eval (f"[{ cp .replace (' ' , ',' )} ]" ) for cp in control_points
111+ literal_eval (f"[{ cp .replace (' ' , ',' )} ]" ) for cp in control_points
103112 ]
104113
105114 # double check
106115 # maybe separate them
107116 if (
108117 ncps != len (control_points )
109118 or ncps != len (weights )
110- or int (nurbs_dict ["knotvectors" ][0 ]) != 2
119+ or int (nurbs_dict ["knotvectors" ][0 ]) != len (degrees )
120+ or len (degrees ) != len (knot_vectors )
111121 ):
112- raise ValueError ("Inconsistent spline info in " + fname )
122+ raise ValueError (
123+ f"Inconsistent spline info in { fname } : "
124+ f"ncps = { ncps } , "
125+ f"len(control_points) = { len (control_points )} , "
126+ f"len(weights) = { len (weights )} , "
127+ f"len(degrees) = { len (degrees )} , "
128+ f"len(knot_vectors) = { len (knot_vectors )} "
129+ )
113130
114131 mfem_dict_spline = {
115132 "degrees" : degrees ,
@@ -152,7 +169,7 @@ def read_solution(
152169 collect = False
153170 while line is not None :
154171 if collect : # check this first. should be true most time
155- solution .append (eval (f"[{ line .replace (' ' , ',' )} ]" ))
172+ solution .append (literal_eval (f"[{ line .replace (' ' , ',' )} ]" ))
156173 elif hotkey in line :
157174 collect = True
158175
@@ -579,51 +596,68 @@ def export(fname, nurbs, precision=10):
579596 "4" ,
580597 "" ,
581598 )
599+ elif nurbs .para_dim == 3 :
600+ elements_sec = _form_lines ("elements" , "1" , "1 5 0 1 2 3 4 5 6 7" , "" )
601+ boundary_sec = _form_lines (
602+ "boundary" ,
603+ "6" ,
604+ "1 3 3 2 1 0" ,
605+ "2 3 4 5 6 7" ,
606+ "3 3 0 1 5 4" ,
607+ "4 3 1 2 6 5" ,
608+ "5 3 2 3 7 6" ,
609+ "6 3 3 0 4 7" ,
610+ "" ,
611+ )
612+ edges_sec = _form_lines (
613+ "edges" ,
614+ "12" ,
615+ "0 0 1" ,
616+ "0 3 2" ,
617+ "0 4 5" ,
618+ "0 7 6" ,
619+ "1 0 3" ,
620+ "1 1 2" ,
621+ "1 4 7" ,
622+ "1 5 6" ,
623+ "2 0 4" ,
624+ "2 1 5" ,
625+ "2 2 6" ,
626+ "2 3 7" ,
627+ "" ,
628+ )
629+ vertices_sec = _form_lines (
630+ "vertices" ,
631+ "8" ,
632+ "" ,
633+ )
634+ else :
635+ raise ValueError ("mfem output support 2D and 3D splines." )
582636
583- # I am not sure if mixed order is allowed, but in case not, let's
584- # match orders
585- max_degree = max (nurbs .degrees )
586- for i , d in enumerate (nurbs .degrees ):
587- d_diff = int (max_degree - d )
588- if d_diff > 0 :
589- for _ in range (d_diff ):
590- nurbs .elevate_degrees (i )
591-
592- cnr = nurbs .control_mesh_resolutions
593-
594- # double-check
595- if not (nurbs .degrees == nurbs .degrees [0 ]).all ():
596- raise RuntimeError (
597- "Something went wrong trying to match degrees of nurbs "
598- + "before export."
599- )
637+ cnr = nurbs .control_mesh_resolutions
600638
601- # This is reusable
602- def kv_sec (spline ):
603- kvs = _form_lines (
604- "knotvectors" ,
605- str (len (spline .knot_vectors )),
639+ # This is reusable
640+ def kv_sec (spline ):
641+ kvs = _form_lines (
642+ "knotvectors" ,
643+ str (len (spline .knot_vectors )),
644+ )
645+ kvs2 = ""
646+ for i in range (spline .para_dim ):
647+ kvs2 += _form_lines (
648+ str (spline .degrees [i ])
649+ + " "
650+ + str (cnr [i ])
651+ + " "
652+ + str (list (spline .knot_vectors [i ]))[1 :- 1 ].replace ("," , "" )
606653 )
607- kvs2 = ""
608- for i in range (spline .para_dim ):
609- kvs2 += _form_lines (
610- str (spline .degrees [i ])
611- + " "
612- + str (cnr [i ])
613- + " "
614- + str (list (spline .knot_vectors [i ]))[1 :- 1 ].replace ("," , "" )
615- )
616654
617- kvs = kvs + kvs2
655+ kvs = kvs + kvs2
618656
619- kvs += "\n " # missing empty line
657+ kvs += "\n " # missing empty line
658+ return kvs
620659
621- return kvs
622-
623- knotvectors_sec = kv_sec (nurbs )
624-
625- else :
626- raise NotImplementedError
660+ knotvectors_sec = kv_sec (nurbs )
627661
628662 # disregard inverse
629663 reorder_ids , _ = dof_mapping (nurbs )
@@ -649,7 +683,7 @@ def kv_sec(spline):
649683
650684 fe_space_sec = _form_lines (
651685 "FiniteElementSpace" ,
652- "FiniteElementCollection: NURBS" + str ( nurbs . degrees [ 0 ]) ,
686+ "FiniteElementCollection: NURBS" ,
653687 "VDim: " + str (nurbs .dim ),
654688 "Ordering: 1" ,
655689 "" ,
0 commit comments