Пример #1
0
def remove_dim(mesh, remove):
    """
    Remove elements by given dimensions from a mesh.

    Parameters
    ----------
    mesh : dict
        dictionary that contains one '#FEM_MSH' block each
        with at least the following information
            elements : dictionary
                contains array of nodes for elements sorted by element types
            material_id : dictionary
                contains material ids for each element sorted by element types
            element_id : dictionary
                contains element ids for each element sorted by element types
    remove : iterable of int or single int
        State which elements should be removed by dimensionality (1, 2, 3).

    Notes
    -----
    This will keep the element ids order.
    """
    if not isinstance(remove, (set, list, tuple)):
        remove = [remove]
    edited = False
    ele_no = no_of_elements(mesh)
    removed_ele_id = []
    for i in remove:
        if i not in range(1, 4):
            continue
        for elem in ELEM_DIM[i - 1]:
            if elem in mesh["elements"]:
                edited = True
                del mesh["elements"][elem]
                removed_ele_id.append(mesh["element_id"][elem])
                del mesh["element_id"][elem]
                del mesh["material_id"][elem]
    if edited:
        removed_ele_id = np.concatenate(removed_ele_id)
        ids = np.arange(ele_no)
        del_id = np.setdiff1d(np.arange(ele_no), removed_ele_id)
        new_id = np.argsort(del_id)
        # trick: replace old IDs with new ones
        ids[del_id] = new_id
        for elem in mesh["element_id"]:
            mesh["element_id"][elem] = ids[mesh["element_id"][elem]]
Пример #2
0
def check_mesh_dict(mesh, verbose=True):
    """
    Check if a given mesh dictonary is valid in the sence, that the
    contained data is consistent.
    Checks for correct element definitions or Node duplicates
    are not carried out.

    Parameters
    ----------
    mesh : dict
        dictionary contains one '#FEM_MSH' block from the mesh file
        with the following information
            mesh_data : dictionary containing information about
                AXISYMMETRY (bool)
                CROSS_SECTION (bool)
                PCS_TYPE (str)
                GEO_TYPE (str)
                GEO_NAME (str)
                LAYER (int)
            nodes : ndarray
                Array with all node postions
            elements : dictionary
                contains nodelists for elements sorted by element types
            material_id : dictionary
                contains material ids for each element sorted by element types
            element_id : dictionary
                contains element ids for each element sorted by element types
    verbose : bool, optional
        Print information for the executed checks. Default: True

    Returns
    -------
    result : bool
        Validity of the given mesh.
    """
    if verbose:
        print("")
        print("checking mesh for validity")
        print("--------------------------")
    # check if dict
    if not isinstance(mesh, dict):
        if verbose:
            print(" mesh is not of type dict")
        return False

    in_mesh_keys = set(mesh)
    # check for keys in mesh dict
    if in_mesh_keys == MESH_KEYS:
        if verbose:
            print(" mesh keys are valid")
            print("")
    else:
        if verbose:
            print(" mesh keys are not valid!")
            print(" needs: " + " ".join(MESH_KEYS))
            print(" found: " + " ".join(map(str, in_mesh_keys)))
            print(" missing: " + " ".join(map(str, MESH_KEYS - in_mesh_keys)))
            print(" corrupted: " +
                  " ".join(map(str, in_mesh_keys - MESH_KEYS)))
        return False
    # check if mesh_data is dict
    if not isinstance(mesh["mesh_data"], dict):
        if verbose:
            print(" mesh['mesh_data'] is not of type dict")
        return False
    # check if elements is dict
    if not isinstance(mesh["elements"], dict):
        if verbose:
            print(" mesh['elements'] is not of type dict")
        return False
    # check if material_id is dict
    if not isinstance(mesh["material_id"], dict):
        if verbose:
            print(" mesh['material_id'] is not of type dict")
        return False
    # check if element_id is dict
    if not isinstance(mesh["element_id"], dict):
        if verbose:
            print(" mesh['element_id'] is not of type dict")
        return False
    # get all keys
    in_mesh_data_keys = set(mesh["mesh_data"])
    in_element_keys = set(mesh["elements"])
    in_material_keys = set(mesh["material_id"])
    in_elementid_keys = set(mesh["element_id"])
    # check for keys in mesh_data dict
    if in_mesh_data_keys <= MESH_DATA_KEYS:
        if verbose:
            print(" mesh['mesh_data'] keys are valid")
            print("")
    else:
        if verbose:
            print(" mesh['mesh_data'] keys are not valid!")
            print(" only allowed: " + " ".join(MESH_DATA_KEYS))
            print(" found: " + " ".join(map(str, in_mesh_data_keys)))
            corrupt = in_mesh_data_keys - MESH_DATA_KEYS
            print(" corrupted: " + " ".join(map(str, corrupt)))
        return False
    # check AXISYMMETRY
    if "AXISYMMETRY" in in_mesh_data_keys:
        if isinstance(mesh["mesh_data"]["AXISYMMETRY"], bool):
            if verbose:
                print(" mesh['mesh_data']['AXISYMMETRY'] valid")
                print("")
        else:
            if verbose:
                print(" mesh['mesh_data']['AXISYMMETRY'] not valid.")
                print(" Should be bool.")
            return False
    # check CROSS_SECTION
    if "CROSS_SECTION" in in_mesh_data_keys:
        if isinstance(mesh["mesh_data"]["CROSS_SECTION"], bool):
            if verbose:
                print(" mesh['mesh_data']['CROSS_SECTION'] valid")
                print("")
        else:
            if verbose:
                print(" mesh['mesh_data']['CROSS_SECTION'] not valid.")
                print(" Should be bool.")
            return False
    # check PCS_TYPE
    if "PCS_TYPE" in in_mesh_data_keys:
        if (isinstance(mesh["mesh_data"]["PCS_TYPE"], STRTYPE)
                and " " not in mesh["mesh_data"]["PCS_TYPE"]):
            if verbose:
                print(" mesh['mesh_data']['PCS_TYPE'] valid")
                print("")
        else:
            if verbose:
                print(" mesh['mesh_data']['PCS_TYPE'] not valid.")
                print(" Should be str not containing spaces.")
            return False
    # check GEO_TYPE
    if "GEO_TYPE" in in_mesh_data_keys:
        if (isinstance(mesh["mesh_data"]["GEO_TYPE"], STRTYPE)
                and " " not in mesh["mesh_data"]["GEO_TYPE"]):
            if verbose:
                print(" mesh['mesh_data']['GEO_TYPE'] valid")
                print("")
        else:
            if verbose:
                print(" mesh['mesh_data']['GEO_TYPE'] not valid.")
                print(" Should be str not containing spaces.")
            return False
    # check GEO_NAME
    if "GEO_NAME" in in_mesh_data_keys:
        if (isinstance(mesh["mesh_data"]["GEO_NAME"], STRTYPE)
                and " " not in mesh["mesh_data"]["GEO_NAME"]):
            if verbose:
                print(" mesh['mesh_data']['GEO_NAME'] valid")
                print("")
        else:
            if verbose:
                print(" mesh['mesh_data']['GEO_NAME'] not valid.")
                print(" Should be str not containing spaces.")
            return False
    # check LAYER
    if "LAYER" in in_mesh_data_keys:
        if (isinstance(mesh["mesh_data"]["LAYER"], int)
                and mesh["mesh_data"]["LAYER"] >= 0):
            if verbose:
                print(" mesh['mesh_data']['LAYER'] valid")
                print("")
        else:
            if verbose:
                print(" mesh['mesh_data']['LAYER'] not valid.")
                print(" Should be non-negativ int.")
            return False
    # check for keys in elements dict
    if in_element_keys <= ELEMENT_KEYS:
        if verbose:
            print(" mesh['elements'] keys are valid")
            print("")
    else:
        if verbose:
            print(" mesh['elements'] keys are not valid!")
            print(" only allowed: " + " ".join(ELEMENT_KEYS))
            print(" found: " + " ".join(map(str, in_element_keys)))
            corrupt = in_element_keys - ELEMENT_KEYS
            print(" corrupted: " + " ".join(map(str, corrupt)))
        return False
    # check for keys in material_id dict
    if in_material_keys == in_element_keys:
        if verbose:
            print(" mesh['material_id'] keys are valid")
            print("")
    else:
        if verbose:
            print(" mesh['material_id'] keys are not valid!")
            print(" need to match 'elements' keys: " +
                  " ".join(in_element_keys))
            print(" found: " + " ".join(map(str, in_material_keys)))
            missing = in_element_keys - in_material_keys
            corrupt = in_material_keys - in_element_keys
            print(" missing: " + " ".join(map(str, missing)))
            print(" corrupted: " + " ".join(map(str, corrupt)))
        return False
    # check for keys in element_id dict
    if in_elementid_keys == in_element_keys:
        if verbose:
            print(" mesh['element_id'] keys are valid")
            print("")
    else:
        if verbose:
            print(" mesh['element_id'] keys are not valid!")
            print(" need to match 'elements' keys: " +
                  " ".join(in_element_keys))
            print(" found: " + " ".join(map(str, in_elementid_keys)))
            missing = in_element_keys - in_elementid_keys
            corrupt = in_elementid_keys - in_element_keys
            print(" missing: " + " ".join(map(str, missing)))
            print(" corrupted: " + " ".join(map(str, corrupt)))
        return False
    # check nodes
    if mesh["nodes"] is None and len(in_element_keys) == 0:
        node_cnt = 0
        if verbose:
            print(" mesh['nodes'] are none, " +
                  " which is valid since no elements are given")
            print("")
    elif mesh["nodes"] is None and len(in_element_keys) > 0:
        if verbose:
            print(" mesh['nodes'] are none, " +
                  " which is not valid since there are elements given")
        return False
    else:
        # see https://github.com/numpy/numpy/pull/9505 for issubdtype
        if (isinstance(mesh["nodes"], np.ndarray)
                and np.issubdtype(mesh["nodes"].dtype, np.floating)
                and mesh["nodes"].ndim == 2 and mesh["nodes"].shape[1] == 3):
            node_cnt = mesh["nodes"].shape[0]
            if verbose:
                print(" mesh['nodes'] valid")
                print("")
        else:
            if verbose:
                print(" mesh['nodes'] not valid")
            return False
    # check elements, material_id and element_id
    element_id_stack = np.array([], dtype=int)
    material_id_stack = np.array([], dtype=int)
    for elem in in_element_keys:
        # see https://github.com/numpy/numpy/pull/9505 for issubdtype
        if (isinstance(mesh["elements"][elem], np.ndarray)
                and np.issubdtype(mesh["elements"][elem].dtype, np.integer)
                and mesh["elements"][elem].ndim == 2
                and mesh["elements"][elem].shape[1] == NODE_NO[elem]
                and np.min(mesh["elements"][elem]) >= 0
                and np.max(mesh["elements"][elem]) < node_cnt):
            if verbose:
                print(" mesh['elements']['" + elem + "'] valid")
        else:
            if verbose:
                print(" mesh['elements']['" + elem + "'] not valid")
            return False
        # see https://github.com/numpy/numpy/pull/9505 for issubdtype
        if (isinstance(mesh["material_id"][elem], np.ndarray)
                and np.issubdtype(mesh["material_id"][elem].dtype, np.integer)
                and mesh["material_id"][elem].ndim == 1
                and mesh["material_id"][elem].shape[0]
                == mesh["elements"][elem].shape[0]
                and np.min(mesh["material_id"][elem]) >= -1):
            if verbose:
                print(" mesh['material_id']['" + elem + "'] valid")
        else:
            if verbose:
                print(" mesh['material_id']['" + elem + "'] not valid")
            return False
        # see https://github.com/numpy/numpy/pull/9505 for issubdtype
        if (isinstance(mesh["element_id"][elem], np.ndarray)
                and np.issubdtype(mesh["element_id"][elem].dtype, np.integer)
                and mesh["element_id"][elem].ndim == 1
                and mesh["element_id"][elem].shape[0]
                == mesh["elements"][elem].shape[0]):
            if verbose:
                print(" mesh['element_id']['" + elem + "'] valid")
        else:
            if verbose:
                print(" mesh['element_id']['" + elem + "'] not valid")
            return False
        # stack material_id and element_id for checking
        material_id_stack = np.hstack(
            (material_id_stack, mesh["material_id"][elem]))
        element_id_stack = np.hstack(
            (element_id_stack, mesh["element_id"][elem]))
    # check ranges of material_id and element_id
    if len(material_id_stack) > 0:
        if set(material_id_stack) == set(
                np.arange(np.max(material_id_stack) + 1)):
            if verbose:
                print(" mesh['material_id'] has valid range")
        else:
            if verbose:
                print(" mesh['material_id'] range has gaps, which is ignored")
            # return False
    if len(element_id_stack) > 0:
        if (len(element_id_stack) == no_of_elements(mesh)
                and len(np.unique(element_id_stack)) == no_of_elements(mesh)
                and np.min(element_id_stack) == 0
                and np.max(element_id_stack) == no_of_elements(mesh) - 1):
            if verbose:
                print(" mesh['element_id'] has valid range")
        else:
            if verbose:
                print(" mesh['element_id'] has no valid range")
            return False
    # finally
    if verbose:
        print("-------------")
        print("mesh is valid")
        print("")
    return True
Пример #3
0
def save_ogs5msh(filepath,
                 mesh,
                 top_com=None,
                 bot_com=None,
                 verbose=True,
                 **kwargs):
    r"""
    Save a given OGS5 mesh file.

    Parameters
    ----------
    filepath : string
        path to the '\*.msh' OGS5 mesh file to save
    mesh : list of dictionaries or single dict
        each dictionary contains one '#FEM_MSH' block of the mesh file
        with the following information (sorted by keys):

            mesh_data : dict
                dictionary containing information about

                - AXISYMMETRY (bool)
                - CROSS_SECTION (bool)
                - PCS_TYPE (str)
                - GEO_TYPE (str)
                - GEO_NAME (str)
                - LAYER (int)

            nodes : ndarray
                Array with all node postions
            elements : dict
                contains nodelists for elements sorted by element types
            material_id : dict
                contains material ids for each element sorted by element types
            element_id : dict
                contains element ids for each element sorted by element types

    top_com : str, optional
        Comment to be added as header to the file, Default: None
        (The MSH file doesn't allow comments as header)
    bot_com : str, optional
        Comment to be added at the bottom to the file, Default: None
    verbose : bool, optional
        Print information of the writing process. Default: True
    **kwargs
        These can contain ``sub_ind`` and ``con_ind`` for indentation
        definition for sub-keys and content
    """
    import pandas as pd
    from ogs5py import SUB_IND, CON_IND

    sub_ind = kwargs.get("sub_ind", SUB_IND)
    con_ind = kwargs.get("con_ind", CON_IND)

    if not isinstance(mesh, (list, tuple)):
        mesh = [mesh]

    # top comment not allowed in .msh files.
    top_com = None

    with open(filepath, "w") as msh:
        if top_com:
            if verbose:
                print("write top comment")
            print(str(top_com), file=msh)

        for i, mesh_i in enumerate(mesh):

            if verbose:
                print("write 'FEM_MSH' number: " + str(i))
            msh.write("#FEM_MSH\n")

            for key in mesh_i["mesh_data"]:
                if verbose:
                    print("write " + key)
                if (key in ["AXISYMMETRY", "CROSS_SECTION"]
                        and mesh_i["mesh_data"][key]):
                    msh.write(sub_ind + "$" + key + "\n")
                elif key == "GEO_TYPE":
                    msh.write(sub_ind + "$" + key + "\n")
                    geo_type = mesh_i["mesh_data"]["GEO_TYPE"]
                    geo_name = mesh_i["mesh_data"]["GEO_NAME"]
                    msh.write(geo_type + " " + geo_name + "\n")
                else:
                    msh.write(sub_ind + "$" + key + "\n")
                    msh.write(con_ind + str(mesh_i["mesh_data"][key]) + "\n")

            if verbose:
                print("write NODES")
            msh.write(sub_ind + "$NODES\n")
            no_nodes = mesh_i["nodes"].shape[0]
            msh.write(con_ind + str(no_nodes) + "\n")
            data = pd.DataFrame(index=np.arange(no_nodes),
                                columns=np.arange(4))
            data[0] = np.arange(no_nodes)
            data[np.arange(1, 4)] = mesh_i["nodes"]
            data.to_csv(msh, header=None, index=None, sep=" ", mode="a")

            if verbose:
                print("write ELEMENTS")
            msh.write(sub_ind + "$ELEMENTS\n")
            no_el = no_of_elements(mesh_i)
            msh.write(con_ind + str(no_el) + "\n")
            data = pd.DataFrame(index=np.arange(no_el),
                                columns=np.arange(8 + 3))
            # initialize the offset for each element-type
            o_s = 0
            for elem in ELEM_NAMES:
                if elem not in mesh_i["elements"]:
                    continue
                no_el = mesh_i["elements"][elem].shape[0]
                data.loc[np.arange(o_s, o_s + no_el),
                         0] = mesh_i["element_id"][elem]
                data.loc[np.arange(o_s, o_s + no_el),
                         1] = mesh_i["material_id"][elem]
                data.loc[np.arange(o_s, o_s + no_el), 2] = elem
                data.loc[np.arange(o_s, o_s + no_el),
                         np.arange(3, 3 +
                                   NODE_NO[elem]), ] = mesh_i["elements"][elem]
                o_s += no_el
            # sort the elements by their ID
            data.sort_values(by=0, inplace=True)
            data.to_csv(msh, header=None, index=None, sep=" ", mode="a")

            # add lines between LAYERS
            if i < len(mesh) - 1:
                msh.write("\n")

        if verbose:
            print("writing finished: STOP")
        if bot_com:
            print("#STOP", file=msh)
            print(bot_com, end="", file=msh)
        else:
            print("#STOP", end="", file=msh)
Пример #4
0
 def ELEMENT_NO(self):
     """int: number of ELEMENTS."""
     return no_of_elements(self._dict)