diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5460588b6..f0c49dbf8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,13 +31,13 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.20 + rev: v0.16.1 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v22.1.5 + rev: v22.1.8 hooks: - id: clang-format types_or: [c, c++] @@ -48,7 +48,7 @@ repos: - id: cmake-format - repo: https://github.com/codespell-project/codespell - rev: v2.4.2 + rev: v2.4.3 hooks: - id: codespell args: [-w] diff --git a/docs/source/conf.py b/docs/source/conf.py index c86207e02..2c26a5d50 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -48,7 +48,7 @@ "icon_links": [ { "name": "GitHub", - "url": "https://github.com/tataratat/splinepy", + "url": "https://github.com/isosuite/splinepy", "icon": "fa-brands fa-square-github", }, { diff --git a/pyproject.toml b/pyproject.toml index c5a1d0521..3fe0be6fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -105,10 +105,12 @@ lint.ignore = [ [tool.ruff.lint.per-file-ignores] "setup.py" = ["T201"] "examples/*.py" = ["T201"] +"tests/**" = ["PLR0917"] "tests/common.py" = ["T201"] "splinepy/cli.py" = ["T201"] "splinepy/io/**" = ["A001"] + [tool.codespell] ignore-words-list = "connec,tye,ned" skip="./docs/source/_generated/**,./docs/build/*,./build/*,./third_party/*,./tests/data/*.svg,*.html,*.js" diff --git a/splinepy/helpme/create.py b/splinepy/helpme/create.py index 7ba756846..4874cb61f 100644 --- a/splinepy/helpme/create.py +++ b/splinepy/helpme/create.py @@ -119,7 +119,7 @@ def extruded(spline, extrusion_vector=None): def revolved( - spline, axis=None, center=None, angle=None, n_knot_spans=None, degree=True + spline, *, axis=None, center=None, angle=None, n_knot_spans=None, degree=True ): """Revolve spline around an axis and extend its parametric dimension. @@ -284,6 +284,7 @@ def revolved( def swept( cross_section, trajectory, + *, cross_section_normal=None, anchor="auto", set_on_trajectory=False, @@ -1153,6 +1154,7 @@ def disk( def torus( torus_radius, section_outer_radius, + *, section_inner_radius=None, torus_angle=None, section_angle=None, @@ -1310,6 +1312,7 @@ def surface_circle(outer_radius): def cone( outer_radius, height, + *, inner_radius=None, volumetric=True, angle=360.0, diff --git a/splinepy/helpme/fit.py b/splinepy/helpme/fit.py index 3450dd96a..942a4a56e 100644 --- a/splinepy/helpme/fit.py +++ b/splinepy/helpme/fit.py @@ -79,9 +79,7 @@ def parametrize_to_line(reorganized_queries, axis, centripetal): reorganized = fitting_points[mi._raveled_indices] parametric_coordinates = [] for k in range(len(size)): - parametric_coordinates.append( - parametrize_to_line(reorganized, k, centripetal) - ) + parametric_coordinates.append(parametrize_to_line(reorganized, k, centripetal)) return parametric_coordinates @@ -133,9 +131,9 @@ def compute_knot_vector(degree, n_control_points, u_k, n_fitting_points): for j in range(1, n_control_points - degree): i = int(j * d) alpha = (j * d) - i - knot_vector[j + degree] = (1 - alpha) * u_k_flat[ - i - 1 - ] + alpha * u_k_flat[i] + knot_vector[j + degree] = (1 - alpha) * u_k_flat[i - 1] + alpha * u_k_flat[ + i + ] return knot_vector @@ -181,8 +179,7 @@ def solve_for_control_points( if fitting_spline.control_points.shape[0] == 2: # control points equal to endpoints (straight line) residual = _np.linalg.norm( - coefficient_matrix @ fitting_spline.control_points - - fitting_points + coefficient_matrix @ fitting_spline.control_points - fitting_points ) elif _has_scipy: # move known values to RHS @@ -236,9 +233,7 @@ def _validate_specifications(n_query, degree, n_control_points, knot_vector): if degree is not None and knot_vector is not None: expected_ncps = len(knot_vector) - degree - 1 if n_control_points is not None and n_control_points != expected_ncps: - _log.error( - f"n_control_points should be {expected_ncps}. Overwriting." - ) + _log.error(f"n_control_points should be {expected_ncps}. Overwriting.") n_control_points = expected_ncps @@ -251,9 +246,7 @@ def _validate_specifications(n_query, degree, n_control_points, knot_vector): # we need degree if degree is None: - raise ValueError( - "Not enough input to determine degree. Please set degree." - ) + raise ValueError("Not enough input to determine degree. Please set degree.") # no n_control point -> same as query and this will be interpolation if n_control_points is None: @@ -277,7 +270,7 @@ def _validate_specifications(n_query, degree, n_control_points, knot_vector): return degree, n_control_points -def _prepare_default_bspline1pd( +def _prepare_default_bspline1pd( # noqa: PLR0917 n_queries, dim, degree, n_control_points, knot_vector, u_k ): # validate values. may raise if there's conflict. @@ -304,6 +297,7 @@ def _prepare_default_bspline1pd( def curve( fitting_points, + *, degree=None, n_control_points=None, knot_vector=None, @@ -368,9 +362,7 @@ def curve( if fitting_spline is not None: # spline dimension check if fitting_spline.para_dim != 1: - raise ValueError( - "parametric dimension of fitting_spline must be 1!" - ) + raise ValueError("parametric dimension of fitting_spline must be 1!") # some values maybe ignored. _log.debug( @@ -411,6 +403,7 @@ def curve( def surface( fitting_points, size, + *, degrees=None, n_control_points=None, knot_vectors=None, @@ -465,10 +458,7 @@ def surface( knot_vectors is not None or fitting_spline is not None ): # check dimensions of queries - if ( - associated_queries[0].shape[1] != 1 - or associated_queries[1].shape[1] != 1 - ): + if associated_queries[0].shape[1] != 1 or associated_queries[1].shape[1] != 1: raise ValueError( "Associated queries in each direction must have dimension 1!" ) @@ -548,9 +538,7 @@ def surface( interpolate_endpoints=interpolate_endpoints, ) # cps in u direction (later fitted in v direction) - interim_control_points[mi_interim_cps[:, v]] = ( - fitted_spline_u.control_points - ) + interim_control_points[mi_interim_cps[:, v]] = fitted_spline_u.control_points # loop second dim # curve fit for every k in n_control_points_u diff --git a/splinepy/io/cats.py b/splinepy/io/cats.py index 51f3e8ce9..5105cc845 100644 --- a/splinepy/io/cats.py +++ b/splinepy/io/cats.py @@ -56,19 +56,12 @@ def load(fname): def _read_spline(xml_element): spline_dict = {} if not xml_element.tag.startswith(CATS_XML_KEY_WORDS["patch"]): - _debug( - f"Found unexpected keyword {xml_element.tag}, which will be " - f"ignored" - ) + _debug(f"Found unexpected keyword {xml_element.tag}, which will be ignored") # Read required information from Header in xml element dim = int(xml_element.attrib.get(CATS_XML_KEY_WORDS["dim"], -1)) - para_dim = int( - xml_element.attrib.get(CATS_XML_KEY_WORDS["para_dim"], -1) - ) - ctps_dim = int( - xml_element.attrib.get(CATS_XML_KEY_WORDS["field_dim"], -1) - ) + para_dim = int(xml_element.attrib.get(CATS_XML_KEY_WORDS["para_dim"], -1)) + ctps_dim = int(xml_element.attrib.get(CATS_XML_KEY_WORDS["field_dim"], -1)) n_ctps = int(xml_element.attrib.get(CATS_XML_KEY_WORDS["n_ctps"], -1)) periodic_keys = xml_element.attrib.get( CATS_XML_KEY_WORDS["periodic"], "" @@ -76,8 +69,7 @@ def _read_spline(xml_element): any_is_periodic = any(int(key) == 1 for key in periodic_keys) if -1 in [dim, para_dim, ctps_dim, n_ctps]: raise ValueError( - f"Not enough information provided for xml-element " - f"{xml_element}" + f"Not enough information provided for xml-element {xml_element}" ) if ctps_dim > dim: _debug( @@ -129,9 +121,7 @@ def _read_spline(xml_element): if CATS_XML_KEY_WORDS["knot_vector"] not in child_info.tag: _debug("Redundant item in knot_vectors block of xml") spline_dict["knot_vectors"].append( - _np.fromstring( - child_info.text.replace("\n", " "), sep=" " - ) + _np.fromstring(child_info.text.replace("\n", " "), sep=" ") ) # All other keywords will be ignored for the moment @@ -148,8 +138,7 @@ def _read_spline(xml_element): if root.tag.startswith(CATS_XML_KEY_WORDS["spline_list"]): if root.attrib.get(CATS_XML_KEY_WORDS["spline_type"], "1") != "1": raise ValueError( - f"Unknown SplineType " - f"{root.attrib[CATS_XML_KEY_WORDS['spline_type']]}" + f"Unknown SplineType {root.attrib[CATS_XML_KEY_WORDS['spline_type']]}" ) n_patches = int(root.attrib.get(CATS_XML_KEY_WORDS["n_patches"], 0)) for patch_element in root: @@ -158,7 +147,7 @@ def _read_spline(xml_element): _debug(f"Unused xml-keyword {root.tag}") return [] - _debug(f"Found a total of {len(list_of_splines)} " f"BSplines and NURBS") + _debug(f"Found a total of {len(list_of_splines)} BSplines and NURBS") if len(list_of_splines) != n_patches: raise ValueError( f"Found {len(list_of_splines)} splines, but expected to find " @@ -204,9 +193,7 @@ def export(fname, spline_list, indent=True, make_rational=True): spline_list = spline_list.patches if not isinstance(spline_list, list): - raise ValueError( - "export Function expects list for multipatch argument" - ) + raise ValueError("export Function expects list for multipatch argument") # Start a list of a list of patches spline_list_element = _ET.Element( @@ -218,9 +205,7 @@ def export(fname, spline_list, indent=True, make_rational=True): # licked it so its ours spline_list_element.insert( 1, - _ET.Comment( - "generated by splinepy https://github.com/tataratat/splinepy" - ), + _ET.Comment("generated by splinepy https://github.com/isosuite/splinepy"), ) new_line_char = "\n" if indent else " " @@ -228,11 +213,7 @@ def export(fname, spline_list, indent=True, make_rational=True): # All Splines (patches) are written into the spline list as entries for spline in spline_list: # Convert to non-bezier type (might make unnecessary copy) - patch = ( - spline.nurbs - if spline.is_rational or make_rational - else spline.bspline - ) + patch = spline.nurbs if spline.is_rational or make_rational else spline.bspline # Write spline header patch_element = _ET.SubElement( @@ -281,9 +262,7 @@ def export(fname, spline_list, indent=True, make_rational=True): patch_element, CATS_XML_KEY_WORDS["degrees"], ) - degrees_elements.text = new_line_char.join( - str(deg) for deg in patch.degrees - ) + degrees_elements.text = new_line_char.join(str(deg) for deg in patch.degrees) # knot-vectors knot_vectors_elements = _ET.SubElement( diff --git a/splinepy/io/gismo.py b/splinepy/io/gismo.py index 9b1405540..6e808415d 100644 --- a/splinepy/io/gismo.py +++ b/splinepy/io/gismo.py @@ -26,6 +26,7 @@ def add_boundary_conditions( dim, function_list, bc_list, + *, cv_list=None, unknown_id=0, multipatch_id=0, @@ -89,9 +90,7 @@ def add_boundary_conditions( "attributes": {"index": str(component_index)}, "text": single_func_text, } - for component_index, single_func_text in enumerate( - func_text - ) + for component_index, single_func_text in enumerate(func_text) ] children_list.append(function_dict) @@ -178,6 +177,7 @@ def add_function(self, dim, block_id, function_string, comment=None): def add_assembly_options( self, block_id, + *, dirichlet_strategy=11, dirichlet_values=101, interface_strategy=1, @@ -306,6 +306,7 @@ def _spline_to_ET( root, multipatch, index_offset, + *, fields_only=False, as_base64=False, field_mask=None, @@ -347,9 +348,7 @@ def _spline_to_ET( ) # Check if range is valid - if (field_mask.min() < 0) or ( - field_mask.max() >= len(multipatch.fields) - ): + if (field_mask.min() < 0) or (field_mask.max() >= len(multipatch.fields)): raise ValueError( "field_mask contains unsupported range, must be within " f"(0, {len(multipatch.fields)})" @@ -360,9 +359,7 @@ def _array_to_text(array, is_matrix, as_b64): array = _enforce_contiguous(array, dtype=_np.float64, asarray=True) return _base64.b64encode(array).decode("ascii") elif is_matrix: - return "\n".join( - [" ".join([str(x) for x in row]) for row in array] - ) + return "\n".join([" ".join([str(x) for x in row]) for row in array]) else: return " ".join(str(x) for x in array) @@ -424,10 +421,7 @@ def _array_to_text(array, is_matrix, as_b64): if support.size == 0: continue coefs = _np.hstack( - [ - multipatch.fields[j].patches[id].control_points - for j in support - ] + [multipatch.fields[j].patches[id].control_points for j in support] ) if "weights" in spline.required_properties: weights = _np.hstack( @@ -525,6 +519,7 @@ def _array_to_text(array, is_matrix, as_b64): def export( fname, multipatch=None, + *, indent=True, labeled_boundaries=True, additional_blocks=None, @@ -585,9 +580,7 @@ def export( ) if not isinstance(multipatch, _Multipatch): - raise ValueError( - "export Function expects list for multipatch argument" - ) + raise ValueError("export Function expects list for multipatch argument") if not isinstance(fname, str): raise ValueError("fname argument must be string") @@ -599,18 +592,14 @@ def export( # licked it so its ours xml_data.insert( 1, - _ET.Comment( - "generated by splinepy https://github.com/tataratat/splinepy" - ), + _ET.Comment("generated by splinepy https://github.com/isosuite/splinepy"), ) # First export Multipatch information multipatch_element = _ET.SubElement( xml_data, "MultiPatch", id=str(0), parDim=str(multipatch.para_dim) ) - patch_range = _ET.SubElement( - multipatch_element, "patches", type="id_range" - ) + patch_range = _ET.SubElement(multipatch_element, "patches", type="id_range") # Retrieve all interfaces (negative numbers refer to boundaries) interface_data = _ET.SubElement(multipatch_element, "interfaces") @@ -633,9 +622,7 @@ def export( if labeled_boundaries: # Export geometric boundaries and set a label - for boundary_id, face_id_list in enumerate( - multipatch.boundaries, start=1 - ): + for boundary_id, face_id_list in enumerate(multipatch.boundaries, start=1): boundary_data = _ET.SubElement( multipatch_element, "boundary", @@ -644,9 +631,7 @@ def export( boundary_data.text = "\n".join( [ str(patch_id + index_offset) + " " + str(local_face_id + 1) - for (patch_id, local_face_id) in zip( - *face_id_list, strict=True - ) + for (patch_id, local_face_id) in zip(*face_id_list, strict=True) ] ) else: @@ -659,9 +644,7 @@ def export( boundary_data.text = "\n".join( [ str(sid + index_offset) + " " + str(bid + 1) - for (sid, bid) in zip( - boundary_spline, boundary_face, strict=True - ) + for (sid, bid) in zip(boundary_spline, boundary_face, strict=True) ] ) ### @@ -679,19 +662,13 @@ def export( id=str(1), multipatch=str(len(multipatch.patches)), ) - bcs_data.insert( - 0, _ET.Comment(text="Please fill boundary conditions here") - ) + bcs_data.insert(0, _ET.Comment(text="Please fill boundary conditions here")) for bc_data_i in boundary_condition_list: - bc = _ET.SubElement( - bcs_data, "bc", type="Dirichlet", unknown="0" - ) + bc = _ET.SubElement(bcs_data, "bc", type="Dirichlet", unknown="0") bc.text = "\n".join( [ str(sid) + " " + str(bid + 1) - for (sid, bid) in zip( - bc_data_i[0], bc_data_i[1], strict=True - ) + for (sid, bid) in zip(bc_data_i[0], bc_data_i[1], strict=True) ] ) @@ -831,9 +808,7 @@ def _matrix_from_node(xml_node): format = type_from_keyword.get(format_flag.lower()) if format is None: - raise ValueError( - "Unknown format in xml file: " + format_flag.lower() - ) + raise ValueError("Unknown format in xml file: " + format_flag.lower()) return _np.frombuffer( _base64.b64decode(xml_node.text.strip().encode("ascii")), @@ -894,9 +869,7 @@ def make_dictionary(ETelement): if patch_element is None: _debug("Unsupported format") if patch_element.attrib.get("type") != "id_range": - _debug( - f"Invalid patch type {patch_element.attrib.get('type')}" - ) + _debug(f"Invalid patch type {patch_element.attrib.get('type')}") patch_range = _matrix_from_node(patch_element).astype(_np.int64) offset = patch_range[0] n_splines = patch_range[1] - patch_range[0] + 1 @@ -942,9 +915,7 @@ def make_dictionary(ETelement): if boundary_elements is None: _debug("No boundary information found") else: - for id, boundary_element in enumerate( - boundary_elements, start=1 - ): + for id, boundary_element in enumerate(boundary_elements, start=1): if boundary_element.text is None: continue boundary_information = ( @@ -967,23 +938,17 @@ def make_dictionary(ETelement): retrieve_from_basis_(info, spline_dict) elif info.tag.startswith("coef"): dim = int(info.attrib.get("geoDim")) - spline_dict["control_points"] = _matrix_from_node( - info - ).reshape(-1, dim) + spline_dict["control_points"] = _matrix_from_node(info).reshape( + -1, dim + ) if spline_dict.get("weights") is None: - list_of_splines.append( - _settings.NAME_TO_TYPE["BSpline"](**spline_dict) - ) + list_of_splines.append(_settings.NAME_TO_TYPE["BSpline"](**spline_dict)) else: - list_of_splines.append( - _settings.NAME_TO_TYPE["NURBS"](**spline_dict) - ) + list_of_splines.append(_settings.NAME_TO_TYPE["NURBS"](**spline_dict)) elif load_options: list_of_options.append(make_dictionary(child)) else: - _debug( - f"Found unsupported keyword {child.tag}, which will be ignored" - ) + _debug(f"Found unsupported keyword {child.tag}, which will be ignored") continue _debug(f"Found a total of {len(list_of_splines)} BSplines and NURBS") diff --git a/splinepy/io/svg.py b/splinepy/io/svg.py index 93d704f2a..c8c0c67ad 100644 --- a/splinepy/io/svg.py +++ b/splinepy/io/svg.py @@ -171,9 +171,7 @@ def _export_spline_field(spline, svg_element, box_min_x, box_max_y, **kwargs): # Check if data is None: - raise ValueError( - "There is no data provided, although data plot is requested" - ) + raise ValueError("There is no data provided, although data plot is requested") # Process the scalar field _process_scalar_field(spline, data, sampled_spline, res=resolution) @@ -213,8 +211,7 @@ def _export_spline_field(spline, svg_element, box_min_x, box_max_y, **kwargs): if bitmap.shape[2] == 3: alpha_layer = ( - _np.ones((bitmap.shape[0], bitmap.shape[1]), dtype=bitmap.dtype) - * 255 + _np.ones((bitmap.shape[0], bitmap.shape[1]), dtype=bitmap.dtype) * 255 ) alpha_layer[_np.all(bitmap == 255, axis=-1)] = 0 bitmap = _np.concatenate( @@ -311,9 +308,7 @@ def _export_gustaf_object( svg_labels.attrib["font-family"] = kwargs["font_family"] svg_labels.attrib["font-size"] = str(kwargs.get("font_size", 0.1)) - svg_labels.attrib["text-anchor"] = kwargs.get( - "text_anchor", "middle" - ) + svg_labels.attrib["text-anchor"] = kwargs.get("text_anchor", "middle") svg_labels.attrib["fill"] = _rgb_2_hex( *_get_color(kwargs.get("text_color", "k")) ) @@ -338,9 +333,7 @@ def _export_gustaf_object( ) -def _export_control_mesh( - spline, svg_spline_element, box_min_x, box_max_y, **kwargs -): +def _export_control_mesh(spline, svg_spline_element, box_min_x, box_max_y, **kwargs): """ Export a spline's control mesh in svg format using polylines for the mesh lines, circles for the control points. @@ -480,9 +473,7 @@ def _export_control_mesh( # Set text options if kwargs.get("font_family") is not None: svg_control_point_ids.attrib["font-family"] = kwargs["font_family"] - svg_control_point_ids.attrib["font-size"] = str( - kwargs.get("font_size", 0.1) - ) + svg_control_point_ids.attrib["font-size"] = str(kwargs.get("font_size", 0.1)) svg_control_point_ids.attrib["text-anchor"] = kwargs.get( "text_anchor", "middle" ) @@ -642,9 +633,7 @@ def _quiver_plot( points=" ".join( [ str(xx - box_min_x) + "," + str(box_max_y - xy) - for (xx, xy) in ( - arrow_control_points_[i, :, :] + positions[i, :] - ) + for (xx, xy) in (arrow_control_points_[i, :, :] + positions[i, :]) ] ), style=(f"fill:{_rgb_2_hex(*colors[i])};stroke:none"), @@ -842,8 +831,7 @@ def _export_spline( # Set tolerance for export to default if no user data if tolerance is None: tolerance = 0.01 * _np.linalg.norm( - spline.control_point_bounds[0, :] - - spline.control_point_bounds[1, :] + spline.control_point_bounds[0, :] - spline.control_point_bounds[1, :] ) # Sanity check @@ -869,9 +857,7 @@ def _approximate_curve(original_spline, tolerance): original_spline.is_rational and original_spline.degrees[0] > 1 ): spline_approximation = original_spline.copy() - spline_approximation.elevate_degrees( - [0] * (3 - original_spline.degrees[0]) - ) + spline_approximation.elevate_degrees([0] * (3 - original_spline.degrees[0])) else: # Use fit tool to approximate curve _debug( @@ -885,9 +871,7 @@ def _approximate_curve(original_spline, tolerance): ) # For rational splines this might be insufficient - if original_spline.is_rational and ( - original_spline.degrees[0] < 3 - ): + if original_spline.is_rational and (original_spline.degrees[0] < 3): para_queries = _np.sort( _np.vstack( ( @@ -904,9 +888,7 @@ def _approximate_curve(original_spline, tolerance): # Create knot-vector k_mult = original_spline.knot_multiplicities[0] - k_mult[1:-1] = _np.maximum( - 1, 3 - original_spline.degrees[0] + k_mult[1:-1] - ) + k_mult[1:-1] = _np.maximum(1, 3 - original_spline.degrees[0] + k_mult[1:-1]) k_mult[0] = 4 k_mult[-1] = 4 new_knot_vector = _np.repeat(original_spline.unique_knots, k_mult) @@ -966,9 +948,7 @@ def _approximate_curve(original_spline, tolerance): if not ( (spline_approximation.degrees[0] == 3) or (not spline_approximation.is_rational) - or ( - original_spline.is_rational and original_spline.degrees[0] <= 1 - ) + or (original_spline.is_rational and original_spline.degrees[0] <= 1) ): raise RuntimeError( "Spline Approximation returned unexpected result that is " @@ -987,9 +967,7 @@ def _approximate_curve(original_spline, tolerance): # Check if a field is to be plotted if spline.show_options.get("data", None) is not None: # spline.show() - _export_spline_field( - spline, svg_spline, box_min_x, box_max_y, **kwargs - ) + _export_spline_field(spline, svg_spline, box_min_x, box_max_y, **kwargs) else: # Export is done in 2 stages @@ -1040,9 +1018,7 @@ def _approximate_curve(original_spline, tolerance): bezier_elements = [] for i in [2, 1, 3, 0]: - spline_copy = _approximate_curve( - spline_boundaries[i], tolerance - ) + spline_copy = _approximate_curve(spline_boundaries[i], tolerance) bezier_elements += spline_copy.extract.beziers() path_d = ( @@ -1099,9 +1075,7 @@ def _approximate_curve(original_spline, tolerance): y=str(box_max_y - y - 0.5 * lw), height=str(lw), width=str(lw), - style=( - f"fill:{_rgb_2_hex(r, g, b)};stroke:none;fill-opacity:{a};" - ), + style=(f"fill:{_rgb_2_hex(r, g, b)};stroke:none;fill-opacity:{a};"), ) else: @@ -1299,9 +1273,7 @@ def export( kwargs["scalarbar_offset"] = kwargs.get("scalarbar_offset", 0.1) scalarbar_offset = kwargs["scalarbar_offset"] # Check if required arguments have been passed - if scalarbar and ( - (kwargs.get("vmin") is None) or (kwargs.get("vmax") is None) - ): + if scalarbar and ((kwargs.get("vmin") is None) or (kwargs.get("vmax") is None)): raise ValueError( "`vmin` and `vmax` must be passed alon with scalarbar to ensure" " same color scheme for all splines" @@ -1313,9 +1285,7 @@ def export( # licked it so its ours svg_data.insert( 1, - _ET.Comment( - "generated by splinepy https://github.com/tataratat/splinepy" - ), + _ET.Comment("generated by splinepy https://github.com/isosuite/splinepy"), ) # Set the box margins and svg options globally @@ -1365,9 +1335,7 @@ def export( if isinstance(object, Spline): # Put every spline and its dedicated information into a new # dedicated group - spline_group = _ET.SubElement( - splines_group, "g", id="spline" + str(i) - ) + spline_group = _ET.SubElement(splines_group, "g", id="spline" + str(i)) _export_spline( object, spline_group, @@ -1376,9 +1344,7 @@ def export( tolerance=tolerance, **kwargs, ) - _export_control_mesh( - object, spline_group, box_min_x, box_max_y, **kwargs - ) + _export_control_mesh(object, spline_group, box_min_x, box_max_y, **kwargs) _quiver_plot( spline=object, svg_spline_element=quiver_list, @@ -1388,9 +1354,7 @@ def export( ) else: gus_grounp = _ET.SubElement(svg_data, "g", id="gus_obj_" + str(i)) - _export_gustaf_object( - object, gus_grounp, box_min_x, box_max_y, **kwargs - ) + _export_gustaf_object(object, gus_grounp, box_min_x, box_max_y, **kwargs) # set original options back if orig_show_options is not None: diff --git a/splinepy/microstructure/tiles/inverse_cross_3d.py b/splinepy/microstructure/tiles/inverse_cross_3d.py index 43e5ed632..63c81f9f6 100644 --- a/splinepy/microstructure/tiles/inverse_cross_3d.py +++ b/splinepy/microstructure/tiles/inverse_cross_3d.py @@ -35,7 +35,7 @@ class InverseCross3D(_TileBase): # TODO: implemented sensitivities are not correct _sensitivities_implemented = True _closure_directions = ["z_min", "z_max"] - _parameter_bounds = [[0.2, 0.3]] * 6 # For default values + _parameter_bounds = [[0.1, 0.3]] * 6 # For default values _parameters_shape = (6, 1) _default_parameter_value = 0.21 @@ -47,6 +47,7 @@ def _closing_tile( self, parameters=None, parameter_sensitivities=None, + *, closure=None, boundary_width=0.1, filling_height=0.5, @@ -1068,9 +1069,7 @@ def create_tile( parameter_sensitivities=parameter_sensitivities, ) - if _np.any(parameters < min_radius) or _np.any( - parameters > max_radius - ): + if _np.any(parameters < min_radius) or _np.any(parameters > max_radius): raise ValueError( f"Radii must be in ({min_radius},{max_radius}) for " f"center_expansion {center_expansion}" @@ -1118,9 +1117,7 @@ def create_tile( sep_distance = separator_distance else: - sensitivities_i = parameter_sensitivities[ - :, 0, i_derivative - 1 - ] + sensitivities_i = parameter_sensitivities[:, 0, i_derivative - 1] [ x_min_r, x_max_r, diff --git a/splinepy/microstructure/tiles/snappy.py b/splinepy/microstructure/tiles/snappy.py index 24a910e0d..0704fa2df 100644 --- a/splinepy/microstructure/tiles/snappy.py +++ b/splinepy/microstructure/tiles/snappy.py @@ -34,6 +34,7 @@ def _closing_tile( self, parameters=None, # noqa: ARG002 parameter_sensitivities=None, # TODO + *, closure=None, contact_length=0.1, a=0.1, @@ -94,9 +95,7 @@ def _closing_tile( ] ) - spline_list.append( - _Bezier(degrees=[1, 1], control_points=spline_1) - ) + spline_list.append(_Bezier(degrees=[1, 1], control_points=spline_1)) spline_2 = _np.array( [ [cl_2_inv, v_zero], @@ -106,9 +105,7 @@ def _closing_tile( ] ) - spline_list.append( - _Bezier(degrees=[1, 1], control_points=spline_2) - ) + spline_list.append(_Bezier(degrees=[1, 1], control_points=spline_2)) spline_3 = _np.array( [ [v_zero, a_inv], @@ -118,9 +115,7 @@ def _closing_tile( ] ) - spline_list.append( - _Bezier(degrees=[1, 1], control_points=spline_3) - ) + spline_list.append(_Bezier(degrees=[1, 1], control_points=spline_3)) spline_4 = _np.array( [ [cl_2_inv, a_inv], @@ -130,9 +125,7 @@ def _closing_tile( ] ) - spline_list.append( - _Bezier(degrees=[1, 1], control_points=spline_4) - ) + spline_list.append(_Bezier(degrees=[1, 1], control_points=spline_4)) spline_5 = _np.array( [ @@ -143,9 +136,7 @@ def _closing_tile( ] ) - spline_list.append( - _Bezier(degrees=[1, 1], control_points=spline_5) - ) + spline_list.append(_Bezier(degrees=[1, 1], control_points=spline_5)) spline_6 = _np.array( [ @@ -156,9 +147,7 @@ def _closing_tile( ] ) - spline_list.append( - _Bezier(degrees=[1, 1], control_points=spline_6) - ) + spline_list.append(_Bezier(degrees=[1, 1], control_points=spline_6)) spline_7 = _np.array( [ @@ -173,9 +162,7 @@ def _closing_tile( ] ) - spline_list.append( - _Bezier(degrees=[3, 1], control_points=spline_7) - ) + spline_list.append(_Bezier(degrees=[3, 1], control_points=spline_7)) spline_8 = _np.array( [ @@ -190,9 +177,7 @@ def _closing_tile( ] ) + [v_one_half, v_zero] - spline_list.append( - _Bezier(degrees=[3, 1], control_points=spline_8) - ) + spline_list.append(_Bezier(degrees=[3, 1], control_points=spline_8)) spline_9 = _np.array( [ @@ -207,9 +192,7 @@ def _closing_tile( ] ) - spline_list.append( - _Bezier(degrees=[3, 1], control_points=spline_9) - ) + spline_list.append(_Bezier(degrees=[3, 1], control_points=spline_9)) spline_10 = _np.array( [ @@ -224,9 +207,7 @@ def _closing_tile( ] ) + [v_one_half, v_zero] - spline_list.append( - _Bezier(degrees=[3, 1], control_points=spline_10) - ) + spline_list.append(_Bezier(degrees=[3, 1], control_points=spline_10)) elif closure == "y_max": spline_1 = _np.array( [ @@ -236,9 +217,7 @@ def _closing_tile( [cl_2, v_one], ] ) - spline_list.append( - _Bezier(degrees=[1, 1], control_points=spline_1) - ) + spline_list.append(_Bezier(degrees=[1, 1], control_points=spline_1)) spline_2 = _np.array( [ [cl_2_inv, v_zero], @@ -247,9 +226,7 @@ def _closing_tile( [v_one, v_one], ] ) - spline_list.append( - _Bezier(degrees=[1, 1], control_points=spline_2) - ) + spline_list.append(_Bezier(degrees=[1, 1], control_points=spline_2)) spline_3 = _np.array( [ [v_one_half - cl_2, v_one_half - b], @@ -258,9 +235,7 @@ def _closing_tile( [v_one_half + cl_2, v_one], ] ) - spline_list.append( - _Bezier(degrees=[1, 1], control_points=spline_3) - ) + spline_list.append(_Bezier(degrees=[1, 1], control_points=spline_3)) spline_4 = _np.array( [ [cl_2, v_zero], @@ -273,9 +248,7 @@ def _closing_tile( [v_one_half - cl_2, v_one], ] ) - spline_list.append( - _Bezier(degrees=[3, 1], control_points=spline_4) - ) + spline_list.append(_Bezier(degrees=[3, 1], control_points=spline_4)) spline_5 = _np.array( [ [cl_2, v_one_half - b], @@ -289,9 +262,7 @@ def _closing_tile( ] ) + [v_one_half, v_zero] - spline_list.append( - _Bezier(degrees=[3, 1], control_points=spline_5) - ) + spline_list.append(_Bezier(degrees=[3, 1], control_points=spline_5)) else: raise NotImplementedError( "Closing tile is only implemented for y-enclosure" @@ -303,6 +274,7 @@ def create_tile( self, parameters=None, parameter_sensitivities=None, # TODO + *, contact_length=0.1, a=0.1, b=0.2, @@ -347,9 +319,7 @@ def create_tile( for param in [a, b, c, r, contact_length]: if not isinstance(param, (int, float)): - raise TypeError( - f"Invalid Type, {param} is neither int nor float" - ) + raise TypeError(f"Invalid Type, {param} is neither int nor float") if param < 0: raise ValueError("Invalid parameter, must be > 0.") @@ -360,15 +330,12 @@ def create_tile( # Check horizontal parameters if not ((r + contact_length) < 0.5): raise ValueError( - "Inconsistent parameters, must fulfill : 2*r + contact_length" - " < 0.5" + "Inconsistent parameters, must fulfill : 2*r + contact_length < 0.5" ) # Check vertical parameters if not ((2 * c + b) < 1.0) or a > c: - raise ValueError( - "Inconsistent parameters, must be 2*c<1-c and a """ if "Bezier" in self.name: - self._logd( - "Returning multiplicities of knots if Bezier was BSpline" - ) + self._logd("Returning multiplicities of knots if Bezier was BSpline") return [_np.array([d + 1, d + 1]) for d in self.degrees] else: @@ -954,9 +942,7 @@ def control_points(self): """ cps = self._data.get("control_points", None) - if _core.has_core(self) and not isinstance( - cps, _utils.data.PhysicalSpaceArray - ): + if _core.has_core(self) and not isinstance(cps, _utils.data.PhysicalSpaceArray): _prepare_coordinates(self) return self._data.get("control_points", None) @@ -981,9 +967,7 @@ def control_points(self, control_points): return None # set - copies if it is not the same value - if not _safe_array_copy( - self, control_points, "control_points", "weights" - ): + if not _safe_array_copy(self, control_points, "control_points", "weights"): return None _safe_new_core(self, exclude="control_points") @@ -1100,9 +1084,7 @@ def weights(self): """ ws = self._data.get("weights", None) - if _core.has_core(self) and not isinstance( - ws, _utils.data.PhysicalSpaceArray - ): + if _core.has_core(self) and not isinstance(ws, _utils.data.PhysicalSpaceArray): _prepare_coordinates(self) return self._data.get("weights", None) @@ -1392,6 +1374,7 @@ def basis_derivative_and_support(self, queries, orders, nthreads=None): def proximities( self, queries, + *, initial_guess_sample_resolutions=None, tolerance=None, max_iterations=-1, @@ -1473,8 +1456,7 @@ def proximities( return verbose_info else: if _np.any( - verbose_info[4] - > _default_if_none(tolerance, _settings.TOLERANCE) + verbose_info[4] > _default_if_none(tolerance, _settings.TOLERANCE) ): self._logw( "Proximity search did not converge within the tolerance " @@ -1499,9 +1481,7 @@ def elevate_degrees(self, parametric_dimensions): self.check.clamped_knot_vectors(warning=True) super().elevate_degrees(para_dims=parametric_dimensions) - self._logd( - f"Elevated {parametric_dimensions}.-dim. " "degree of the spline." - ) + self._logd(f"Elevated {parametric_dimensions}.-dim. degree of the spline.") self._data = {} def reduce_degrees(self, parametric_dimensions, tolerance=None): @@ -1530,8 +1510,7 @@ def meaningful(r): return "reduced" if r else "failed" self._logd( - f"Tried to reduce degrees for {parametric_dimensions}.-dims. " - "Results: ", + f"Tried to reduce degrees for {parametric_dimensions}.-dims. Results: ", f"{[meaningful(r) for r in reduced]}.", ) diff --git a/tests/io/test_cats.py b/tests/io/test_cats.py index dd06cda7a..02a18804f 100644 --- a/tests/io/test_cats.py +++ b/tests/io/test_cats.py @@ -5,7 +5,7 @@ cats_no_indent_export = [ 'x y0.0 0.0' " 0.5 0.0 1.0 0.0 0.0 1.0 0.5 1.0 1.0 1.02 1\n', - " \n", + " \n", ' \n', " x y\n", @@ -174,9 +174,7 @@ def test_cats_export(to_tmpf, are_items_same, are_stripped_lines_same): nur_el3.insert_knots(1, [0.5]) # Init multipatch - multipatch = splinepy.Multipatch( - splines=[bez_el0, rbz_el1, bsp_el2, nur_el3] - ) + multipatch = splinepy.Multipatch(splines=[bez_el0, rbz_el1, bsp_el2, nur_el3]) # Test Output with tempfile.TemporaryDirectory() as tmpd: