Ejemplo n.º 1
0
def ugrid3d_to_nastran(ugrid_filename, bdf_filename, include_shells=True, include_solids=True,
                       convert_pyram_to_penta=False, encoding=None, size=16, is_double=False):
    """
    Converts a UGRID to a BDF.

    Parameters
    ----------
    ugrid_filename : str
        the input UGRID filename
    bdf_filename : str
        the output BDF filename
    include_shells : bool; default=True
        should the shells be written
    include_solids : bool; default=True
        should the solids be written
    convert_pyram_to_penta : bool; default=False
        False : NX Nastran
        True : MSC Nastran
    size : int; {8, 16}; default=16
        the bdf write precision
    is_double : bool; default=False
        the field precision to write

    Returns
    -------
    ugrid_model : UGRID()
        the ugrid model
    """
    model = UGRID(log=None, debug=False)
    assert os.path.exists(ugrid_filename), '%r doesnt exist' % ugrid_filename
    model.read_ugrid(ugrid_filename)
    model.write_bdf(bdf_filename, include_shells=include_shells, include_solids=include_solids,
                    convert_pyram_to_penta=convert_pyram_to_penta,
                    encoding=encoding, size=size, is_double=is_double)
    return model
Ejemplo n.º 2
0
def process_ugrid(ugrid_filename, fmt2, fname2, data=None):
    """
    Converts UGRID to Nastran/Cart3d/STL/Tecplot
    """
    assert fmt2 in ['stl', 'nastran', 'cart3d', 'tecplot'], 'format2=%s' % fmt2
    model = UGRID()
    model.read_ugrid(ugrid_filename)
    if fmt2 == 'nastran':
        # ugrid_to_nastran(model, fname2
        include_shells = True
        include_solids = True
        bdf_filename = fname2
        model.write_bdf(bdf_filename, include_shells=include_shells, include_solids=include_solids)
    elif fmt2 == 'cart3d':
        include_shells = False
        include_solids = True
        bdf_filename = fname2 + '.bdf'
        model.write_bdf(bdf_filename, include_shells=include_shells, include_solids=include_solids)
        # ugrid_to_cart3d(model, fname2)
        process_nastran(bdf_filename, 'cart3d', fname2, data=None)
    elif fmt2 == 'stl':
        include_shells = False
        include_solids = True
        bdf_filename = fname2 + '.bdf'
        model.write_bdf(bdf_filename, include_shells=include_shells, include_solids=include_solids)
        process_nastran(bdf_filename, 'cart3d', fname2, data=None)
        # ugrid_to_stl(model, fname2)
    elif fmt2 == 'tecplot':
        # ugrid_to_tecplot(model, fname2)
        tecplot = ugrid_to_tecplot(model)
        element_slice(tecplot, data)
        tecplot_filename = fname2
        tecplot.write_tecplot(tecplot_filename)
    else:
        raise NotImplementedError(fmt2)
Ejemplo n.º 3
0
def ugrid3d_to_tecplot_filename(ugrid_filename, tecplot_filename, log=None):
    """
    Converts a UGRID to a Tecplot ASCII file.

    Parameters
    ----------
    ugrid_filename : str
        the input UGRID filename
    bdf_filename : str
        the output Tecplot filename
    """
    model = UGRID(log=log)
    assert os.path.exists(ugrid_filename), '%r doesnt exist' % ugrid_filename
    model.read_ugrid(ugrid_filename)
    model.write_tecplot(tecplot_filename)
Ejemplo n.º 4
0
def process_ugrid(ugrid_filename, fmt2, fname2, data=None):
    """
    Converts UGRID to Nastran/Cart3d/STL/Tecplot
    """
    assert fmt2 in ['stl', 'nastran', 'cart3d', 'tecplot'], 'format2=%s' % fmt2
    read_shells = True
    read_solids = True
    if fmt2 in ['stl', 'cart3d']:
        read_shells = True
        read_solids = False
    model = UGRID(read_shells=read_shells, read_solids=read_solids)
    model.read_ugrid(ugrid_filename)
    if fmt2 == 'nastran':
        # ugrid_to_nastran(model, fname2
        include_shells = True
        include_solids = True
        bdf_filename = fname2
        model.write_bdf(bdf_filename,
                        include_shells=include_shells,
                        include_solids=include_solids)
    elif fmt2 == 'cart3d':
        include_shells = True
        include_solids = False
        bdf_filename = fname2 + '.bdf'
        model.write_bdf(bdf_filename,
                        include_shells=include_shells,
                        include_solids=include_solids)
        # ugrid_to_cart3d(model, fname2)
        process_nastran(bdf_filename, 'cart3d', fname2, data=None)
    elif fmt2 == 'stl':
        include_shells = True
        include_solids = False
        bdf_filename = fname2 + '.bdf'
        model.write_bdf(bdf_filename,
                        include_shells=include_shells,
                        include_solids=include_solids)
        process_nastran(bdf_filename, 'cart3d', fname2, data=None)
        # ugrid_to_stl(model, fname2)
    elif fmt2 == 'tecplot':
        # ugrid_to_tecplot(model, fname2)
        tecplot = ugrid_to_tecplot(model)
        element_slice(tecplot, data)
        tecplot_filename = fname2
        tecplot.write_tecplot(tecplot_filename)
    else:
        raise NotImplementedError(fmt2)
Ejemplo n.º 5
0
def ugrid3d_to_tecplot_filename(ugrid_filename, tecplot_filename, log=None):
    """
    Converts a UGRID to a Tecplot ASCII file.

    Parameters
    ----------
    ugrid_filename : varies
        str : the input UGRID filename
        UGRID : the UGRID object
    bdf_filename : str
        the output Tecplot filename
    log : logger; default=None
        a logger object
    """
    if isinstance(ugrid_filename, str):
        #assert os.path.exists(ugrid_filename), '%r doesnt exist' % ugrid_filename
        model = UGRID(log=log)
        model.read_ugrid(ugrid_filename)
    else:
        model = ugrid_filename
    model.write_tecplot(tecplot_filename)
Ejemplo n.º 6
0
def ugrid3d_to_nastran(ugrid_filename,
                       bdf_filename,
                       include_shells=True,
                       include_solids=True,
                       convert_pyram_to_penta=False,
                       encoding=None,
                       size=16,
                       is_double=False):
    """
    Converts a UGRID to a BDF.

    Parameters
    ----------
    ugrid_filename : str
        the input UGRID filename
    bdf_filename : str
        the output BDF filename
    include_shells : bool; default=True
        should the shells be written
    include_solids : bool; default=True
        should the solids be written
    convert_pyram_to_penta : bool; default=False
        False : NX Nastran
        True : MSC Nastran
    size : int; {8, 16}; default=16
        the bdf write precision
    is_double : bool; default=False
        the field precision to write

    Returns
    -------
    ugrid_model : UGRID()
        the ugrid model
    """
    model = UGRID(log=None, debug=False)
    assert os.path.exists(ugrid_filename), '%r doesnt exist' % ugrid_filename
    model.read_ugrid(ugrid_filename)
    model.write_bdf(bdf_filename,
                    include_shells=include_shells,
                    include_solids=include_solids,
                    convert_pyram_to_penta=convert_pyram_to_penta,
                    encoding=encoding,
                    size=size,
                    is_double=is_double)
    return model
Ejemplo n.º 7
0
def ugrid3d_to_tecplot_filename(ugrid_filename, tecplot_filename,
                                log=None, debug=False):
    """
    Converts a UGRID to a Tecplot ASCII file.

    Parameters
    ----------
    ugrid_filename : varies
        str : the input UGRID filename
        UGRID : the UGRID object
    tecplot_filename : str
        the output Tecplot filename
    log : logger; default=None
        a logger object
    debug : bool; default=False
        developer debug
    """
    if isinstance(ugrid_filename, str):
        #assert os.path.exists(ugrid_filename), '%r doesnt exist' % ugrid_filename
        model = UGRID(log=log, debug=debug)
        model.read_ugrid(ugrid_filename)
    else:
        model = ugrid_filename
    model.write_tecplot(tecplot_filename)
Ejemplo n.º 8
0
def nastran_to_ugrid(bdf_model, ugrid_filename_out=None, properties=None,
                     check_shells=True, check_solids=True):
    """
    set xref=False
    """
    # pids_to_inlcude = []
    # for pid, prop in iteritems(model.properties):
        # if prop.type == 'PSHELL':
            # pids_to_include.append(pid)
    if properties is not None:
        for pid, pid_new in iteritems(properties):
            bdf_model.properties[pid].pid = pid_new

    card_types = ['CQUAD4', 'CTRIA3', 'CTETRA', 'CHEXA', 'GRID', 'CPENTA', 'CPYRAM']
    out = bdf_model.get_card_ids_by_card_types(card_types)
    node_ids = out['GRID']
    ctria3 = out['CTRIA3']
    cquad4 = out['CQUAD4']

    ctetra = out['CTETRA']
    cpyram = out['CPYRAM']
    cpenta = out['CPENTA']
    chexa = out['CHEXA']

    nnodes = len(node_ids)
    ntris = len(ctria3)
    nquads = len(cquad4)
    nshells = ntris + nquads
    ntetra = len(ctetra)
    npyram = len(cpyram)
    npenta = len(cpenta)
    nhexa = len(chexa)
    nsolids = ntetra + npyram + npenta + nhexa
    if nnodes == 0:
        raise RuntimeError('nnodes=%i nshells=%i nsolids=%i' % (nnodes, nshells, nsolids))
    if nshells == 0 and check_shells:
        raise RuntimeError('nnodes=%i nshells=%i nsolids=%i' % (nnodes, nshells, nsolids))
    if nsolids == 0 and check_solids:
        raise RuntimeError('nnodes=%i nshells=%i nsolids=%i' % (nnodes, nshells, nsolids))

    nodes = bdf_model.nodes
    elements = bdf_model.elements
    xyz_cid0 = array([nodes[nid].xyz for nid in node_ids], dtype='float64')

    pids = []
    model = UGRID()
    model.nodes = xyz_cid0
    if ntris:
        model.tris = array([elements[eid].node_ids for eid in ctria3], dtype='int32')
        ptris = array([elements[eid].Pid() for eid in ctria3], dtype='int32')
        pids.append(ptris)
    if nquads:
        model.quads = array([elements[eid].node_ids for eid in cquad4], dtype='int32')
        pquads = array([elements[eid].Pid() for eid in cquad4], dtype='int32')
        pids.append(pquads)
    if len(pids) == 1:
        model.pids = pids[0]
    elif len(pids) == 2:
        model.pids = hstack(pids)
    else:
        raise RuntimeError(pids)

    if ntetra:
        model.tets = array([elements[eid].node_ids for eid in ctetra], dtype='int32')
    if npyram:
        model.penta5s = array([elements[eid].node_ids for eid in cpyram], dtype='int32')
    if nhexa:
        model.penta6s = array([elements[eid].node_ids for eid in cpenta], dtype='int32')
    if nhexa:
        model.hexas = array([elements[eid].node_ids for eid in chexa], dtype='int32')

    if ugrid_filename_out is not None:
        model.write_ugrid(ugrid_filename_out)
    return model
Ejemplo n.º 9
0
    def load_ugrid_geometry(self, ugrid_filename, dirname, name='main', plot=True):
        #skip_reading = self.remove_old_openfoam_geometry(openfoam_filename)
        #if skip_reading:
        #    return
        if is_binary_file(ugrid_filename):
            model = UGRID(log=self.log, debug=True)
            base, fmt, ext = os.path.basename(ugrid_filename).split('.')
            is_2d = False
        else:
            base, ext = os.path.basename(ugrid_filename).split('.')
            model = UGRID2D_Reader(log=self.log, debug=True)
            is_2d = True

        self.model_type = 'ugrid'
        print('ugrid_filename = %s' % ugrid_filename)


        assert ext == 'ugrid', ugrid_filename
        model.read_ugrid(ugrid_filename)

        if is_2d:
            tris = model.tris
            quads = model.quads
        else:
            tris = model.tris - 1
            quads = model.quads - 1

        #self.nodes = nodes
        #self.tris  = tris
        #self.quads = quads
        #self.pids = pids

        #self.tets = tets
        #self.penta5s = penta5s
        #self.penta6s = penta6s
        #self.hexas = hexas

        nnodes = model.nodes.shape[0]
        ntris = model.tris.shape[0]
        nquads = model.quads.shape[0]
        nelements = ntris + nquads

        nodes = model.nodes
        self.nElements = nelements
        self.nNodes = nnodes

        print("nNodes = %s" % self.nNodes)
        print("nElements = %s" % self.nElements)
        assert nelements > 0, nelements

        self.grid.Allocate(self.nElements, 1000)

        points = vtk.vtkPoints()
        points.SetNumberOfPoints(self.nNodes)

        mmax = amax(nodes, axis=0)
        mmin = amin(nodes, axis=0)
        dim_max = (mmax - mmin).max()
        self.create_global_axes(dim_max)
        self.log.info('max = %s' % mmax)
        self.log.info('min = %s' % mmin)

        diff_node_ids = model.check_hanging_nodes(stop_on_diff=False)
        if len(diff_node_ids):
            red = (1., 0., 0.)
            self.create_alternate_vtk_grid('hanging_nodes', color=red, line_width=5, opacity=1., point_size=10, representation='point')
            self._add_ugrid_nodes_to_grid('hanging_nodes', diff_node_ids, nodes)
            self._add_alt_actors(self.alt_grids)


        for inode, node in enumerate(nodes):
            points.InsertPoint(inode, node)

        if ntris:
            for eid, element in enumerate(tris):
                elem = vtkTriangle()
                elem.GetPointIds().SetId(0, element[0])
                elem.GetPointIds().SetId(1, element[1])
                elem.GetPointIds().SetId(2, element[2])
                self.grid.InsertNextCell(elem.GetCellType(),
                                         elem.GetPointIds())
        if nquads:
            for eid, element in enumerate(quads):
                elem = vtkQuad()
                elem.GetPointIds().SetId(0, element[0])
                elem.GetPointIds().SetId(1, element[1])
                elem.GetPointIds().SetId(2, element[2])
                elem.GetPointIds().SetId(3, element[3])
                self.grid.InsertNextCell(elem.GetCellType(),
                                         elem.GetPointIds())

        self.nElements = nelements
        self.grid.SetPoints(points)
        self.grid.Modified()
        print('update...')
        if hasattr(self.grid, 'Update'):
            self.grid.Update()
        #print("updated grid")

        # loadCart3dResults - regions/loads
        self. turn_text_on()
        self.scalarBar.VisibilityOn()
        self.scalarBar.Modified()

        self.iSubcaseNameMap = {1: ['AFLR UGRID Surface', '']}
        cases = {}
        ID = 1

        if hasattr(model, 'pids'):
            form, cases = self._fill_ugrid3d_case(ugrid_filename, cases, ID, nnodes, nelements, model)
        else:
            form, cases = self._fill_ugrid2d_case(ugrid_filename, cases, ID, nnodes, nelements, model)

        if plot:
            self._finish_results_io2(form, cases)
Ejemplo n.º 10
0
    def load_ugrid_geometry(self, ugrid_filename, dirname, name='main', plot=True):
        #skip_reading = self.remove_old_openfoam_geometry(openfoam_filename)
        #if skip_reading:
        #    return
        if is_binary_file(ugrid_filename):
            model = UGRID(log=self.log, debug=True)
            base, fmt, ext = os.path.basename(ugrid_filename).split('.')
            is_2d = False
        else:
            base, ext = os.path.basename(ugrid_filename).split('.')
            model = UGRID2D_Reader(log=self.log, debug=True)
            is_2d = True

        self.model_type = 'ugrid'
        self.log.debug('ugrid_filename = %s' % ugrid_filename)


        assert ext == 'ugrid', ugrid_filename
        model.read_ugrid(ugrid_filename)

        if is_2d:
            tris = model.tris
            quads = model.quads
        else:
            tris = model.tris - 1
            quads = model.quads - 1

        #self.nodes = nodes
        #self.tris  = tris
        #self.quads = quads
        #self.pids = pids

        #self.tets = tets
        #self.penta5s = penta5s
        #self.penta6s = penta6s
        #self.hexas = hexas

        nnodes = model.nodes.shape[0]
        ntris = model.tris.shape[0]
        nquads = model.quads.shape[0]
        nelements = ntris + nquads

        nodes = model.nodes
        self.nElements = nelements
        self.nNodes = nnodes

        self.log.info("nnodes=%s nelements=%s" % (self.nNodes, self.nElements))
        assert nelements > 0, nelements

        self.grid.Allocate(self.nElements, 1000)

        points = vtk.vtkPoints()
        points.SetNumberOfPoints(self.nNodes)

        mmax = amax(nodes, axis=0)
        mmin = amin(nodes, axis=0)
        dim_max = (mmax - mmin).max()
        self.create_global_axes(dim_max)
        self.log.info('max = %s' % mmax)
        self.log.info('min = %s' % mmin)

        diff_node_ids = model.check_hanging_nodes(stop_on_diff=False)
        if len(diff_node_ids):
            red = (1., 0., 0.)
            self.create_alternate_vtk_grid('hanging_nodes', color=red, line_width=5, opacity=1.,
                                           point_size=10, representation='point')
            self._add_ugrid_nodes_to_grid('hanging_nodes', diff_node_ids, nodes)
            self._add_alt_actors(self.alt_grids)


        data_type = vtk.VTK_FLOAT
        points_array = numpy_to_vtk(
            num_array=nodes,
            deep=True,
            array_type=data_type
        )
        points.SetData(points_array)

        if ntris:
            for eid, element in enumerate(tris):
                elem = vtkTriangle()
                elem.GetPointIds().SetId(0, element[0])
                elem.GetPointIds().SetId(1, element[1])
                elem.GetPointIds().SetId(2, element[2])
                self.grid.InsertNextCell(elem.GetCellType(),
                                         elem.GetPointIds())
        if nquads:
            for eid, element in enumerate(quads):
                elem = vtkQuad()
                elem.GetPointIds().SetId(0, element[0])
                elem.GetPointIds().SetId(1, element[1])
                elem.GetPointIds().SetId(2, element[2])
                elem.GetPointIds().SetId(3, element[3])
                self.grid.InsertNextCell(elem.GetCellType(),
                                         elem.GetPointIds())

        self.nElements = nelements
        self.grid.SetPoints(points)
        self.grid.Modified()
        self.log.info('update...')
        if hasattr(self.grid, 'Update'):
            self.grid.Update()
        #self.log.info("updated grid")

        # loadCart3dResults - regions/loads
        self. turn_text_on()
        self.scalarBar.VisibilityOn()
        self.scalarBar.Modified()

        self.iSubcaseNameMap = {1: ['AFLR UGRID Surface', '']}
        cases = {}
        ID = 1

        if hasattr(model, 'pids'):
            form, cases = self._fill_ugrid3d_case(
                ugrid_filename, cases, ID, nnodes, nelements, model)
        else:
            form, cases = self._fill_ugrid2d_case(
                ugrid_filename, cases, ID, nnodes, nelements, model)

        if plot:
            self._finish_results_io2(form, cases)
Ejemplo n.º 11
0
def nastran_to_ugrid(bdf_filename, ugrid_filename_out=None, properties=None,
                     check_shells=True, check_solids=True):
    """
    set xref=False

    Parameters
    ----------
    bdf_filename : varies
        str : a bdf filename
        BDF() : a BDF object
    ugrid_filename_out : str (default=None -> ???)
        the path to the ugrid_filename
    properties : dict???
        ???
    check_shells : bool (default=True)
        verify that there is at least one shell element
    check_solids : bool (default=True)
        verify that there is at least one solid element
    """
    if isinstance(bdf_filename, str):
        bdf_model = read_bdf(bdf_filename)
    else:
        bdf_model = bdf_filename

    # pids_to_inlcude = []
    # for pid, prop in iteritems(model.properties):
        # if prop.type == 'PSHELL':
            # pids_to_include.append(pid)
    if properties is not None:
        for pid, pid_new in iteritems(properties):
            bdf_model.properties[pid].pid = pid_new

    card_types = ['CQUAD4', 'CTRIA3', 'CTETRA', 'CHEXA', 'GRID', 'CPENTA', 'CPYRAM']
    out = bdf_model.get_card_ids_by_card_types(card_types)
    node_ids = out['GRID']
    ctria3 = out['CTRIA3']
    cquad4 = out['CQUAD4']

    ctetra = out['CTETRA']
    cpyram = out['CPYRAM']
    cpenta = out['CPENTA']
    chexa = out['CHEXA']

    nnodes = len(node_ids)
    ntris = len(ctria3)
    nquads = len(cquad4)
    nshells = ntris + nquads
    ntetra = len(ctetra)
    npyram = len(cpyram)
    npenta = len(cpenta)
    nhexa = len(chexa)
    nsolids = ntetra + npyram + npenta + nhexa
    if nnodes == 0:
        raise RuntimeError('nnodes=%i nshells=%i nsolids=%i' % (nnodes, nshells, nsolids))
    if nshells == 0 and check_shells:
        raise RuntimeError('nnodes=%i nshells=%i nsolids=%i' % (nnodes, nshells, nsolids))
    if nsolids == 0 and check_solids:
        raise RuntimeError('nnodes=%i nshells=%i nsolids=%i' % (nnodes, nshells, nsolids))

    nodes = bdf_model.nodes
    elements = bdf_model.elements
    xyz_cid0 = array([nodes[nid].xyz for nid in node_ids], dtype='float64')

    pids = []
    model = UGRID()
    model.nodes = xyz_cid0
    if ntris:
        model.tris = array([elements[eid].node_ids for eid in ctria3], dtype='int32')
        ptris = array([elements[eid].Pid() for eid in ctria3], dtype='int32')
        pids.append(ptris)
    if nquads:
        model.quads = array([elements[eid].node_ids for eid in cquad4], dtype='int32')
        pquads = array([elements[eid].Pid() for eid in cquad4], dtype='int32')
        pids.append(pquads)

    if check_shells:
        if len(pids) == 1:
            model.pids = pids[0]
        elif len(pids) == 2:
            model.pids = hstack(pids)
        else:
            raise RuntimeError(pids)

    if ntetra:
        model.tets = array([elements[eid].node_ids for eid in ctetra], dtype='int32')
    if npyram:
        model.penta5s = array([elements[eid].node_ids for eid in cpyram], dtype='int32')
    if nhexa:
        model.penta6s = array([elements[eid].node_ids for eid in cpenta], dtype='int32')
    if nhexa:
        model.hexas = array([elements[eid].node_ids for eid in chexa], dtype='int32')

    model.log.debug('ugrid_filename_out = %r' % ugrid_filename_out)
    if ugrid_filename_out is not None:
        model.write_ugrid(ugrid_filename_out, check_shells=check_shells)
    return model
Ejemplo n.º 12
0
def nastran_to_ugrid(bdf_filename,
                     ugrid_filename_out=None,
                     properties=None,
                     check_shells=True,
                     check_solids=True):
    """
    set xref=False

    Parameters
    ----------
    bdf_filename : varies
        str : a bdf filename
        BDF() : a BDF object
    ugrid_filename_out : str (default=None -> ???)
        the path to the ugrid_filename
    properties : dict???
        ???
    check_shells : bool (default=True)
        verify that there is at least one shell element
    check_solids : bool (default=True)
        verify that there is at least one solid element
    """
    if isinstance(bdf_filename, str):
        bdf_model = read_bdf(bdf_filename)
    else:
        bdf_model = bdf_filename

    # pids_to_inlcude = []
    # for pid, prop in iteritems(model.properties):
    # if prop.type == 'PSHELL':
    # pids_to_include.append(pid)
    if properties is not None:
        for pid, pid_new in iteritems(properties):
            bdf_model.properties[pid].pid = pid_new

    card_types = [
        'CQUAD4', 'CTRIA3', 'CTETRA', 'CHEXA', 'GRID', 'CPENTA', 'CPYRAM'
    ]
    out = bdf_model.get_card_ids_by_card_types(card_types)
    node_ids = out['GRID']
    ctria3 = out['CTRIA3']
    cquad4 = out['CQUAD4']

    ctetra = out['CTETRA']
    cpyram = out['CPYRAM']
    cpenta = out['CPENTA']
    chexa = out['CHEXA']

    nnodes = len(node_ids)
    ntris = len(ctria3)
    nquads = len(cquad4)
    nshells = ntris + nquads
    ntetra = len(ctetra)
    npyram = len(cpyram)
    npenta = len(cpenta)
    nhexa = len(chexa)
    nsolids = ntetra + npyram + npenta + nhexa
    if nnodes == 0:
        raise RuntimeError('nnodes=%i nshells=%i nsolids=%i' %
                           (nnodes, nshells, nsolids))
    if nshells == 0 and check_shells:
        raise RuntimeError('nnodes=%i nshells=%i nsolids=%i' %
                           (nnodes, nshells, nsolids))
    if nsolids == 0 and check_solids:
        raise RuntimeError('nnodes=%i nshells=%i nsolids=%i' %
                           (nnodes, nshells, nsolids))

    nodes = bdf_model.nodes
    elements = bdf_model.elements
    xyz_cid0 = array([nodes[nid].xyz for nid in node_ids], dtype='float64')

    pids = []
    model = UGRID()
    model.nodes = xyz_cid0
    if ntris:
        model.tris = array([elements[eid].node_ids for eid in ctria3],
                           dtype='int32')
        ptris = array([elements[eid].Pid() for eid in ctria3], dtype='int32')
        pids.append(ptris)
    if nquads:
        model.quads = array([elements[eid].node_ids for eid in cquad4],
                            dtype='int32')
        pquads = array([elements[eid].Pid() for eid in cquad4], dtype='int32')
        pids.append(pquads)

    if check_shells:
        if len(pids) == 1:
            model.pids = pids[0]
        elif len(pids) == 2:
            model.pids = hstack(pids)
        else:
            raise RuntimeError(pids)

    if ntetra:
        model.tets = array([elements[eid].node_ids for eid in ctetra],
                           dtype='int32')
    if npyram:
        model.penta5s = array([elements[eid].node_ids for eid in cpyram],
                              dtype='int32')
    if nhexa:
        model.penta6s = array([elements[eid].node_ids for eid in cpenta],
                              dtype='int32')
    if nhexa:
        model.hexas = array([elements[eid].node_ids for eid in chexa],
                            dtype='int32')

    model.log.debug('ugrid_filename_out = %r' % ugrid_filename_out)
    if ugrid_filename_out is not None:
        model.write_ugrid(ugrid_filename_out, check_shells=check_shells)
    return model